Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 71 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3752,6 +3752,72 @@ then
fi


# wolfHAL hardware abstraction layer crypto-callback port.
# Include-path only: wolfHAL builds no archive (its drivers compile per-board),
# so the application compiles and links wolfHAL itself.
# Example:
# "./configure --with-wolfhal=../wolfHAL --with-wolfhal-board=stm32wb_nucleo"
ENABLED_WOLFHAL="no"
ENABLED_WOLFHAL_BOARD=""
trywolfhaldir=""
AC_ARG_WITH([wolfhal],
[AS_HELP_STRING([--with-wolfhal=PATH],[PATH to the wolfHAL source tree (default ../wolfHAL)])],
[
AC_MSG_CHECKING([for wolfHAL])
if test "x$withval" != "xno" ; then
trywolfhaldir=$withval
fi
if test "x$withval" = "xyes" ; then
trywolfhaldir="../wolfHAL"
fi
if test -e "$trywolfhaldir/wolfHAL/crypto/crypto.h"
then
AM_CFLAGS="$AM_CFLAGS -I\"$trywolfhaldir\""
else
AC_MSG_ERROR([Could not find wolfHAL headers under $trywolfhaldir])
fi
# wolfHAL objects are compiled by the application, so the library is
# left with unresolved whal_* references. A shared object cannot carry
# those, and the bundled examples/tests cannot link them either.
enable_shared=no
enable_static=yes
ENABLED_WOLFHAL="yes"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WOLFHAL"
AC_MSG_RESULT([yes])
]
)

AC_ARG_WITH([wolfhal-board],
[AS_HELP_STRING([--with-wolfhal-board=PATH],
[PATH to the directory holding your wolfHAL_board.h. Required with
--with-wolfhal.])],
[
if test "x$withval" != "xno" ; then
ENABLED_WOLFHAL_BOARD=$withval
fi
]
)

if test "x$ENABLED_WOLFHAL" = "xyes"
then
if test "x$ENABLED_WOLFHAL_BOARD" = "x"
then
AC_MSG_ERROR([--with-wolfhal requires --with-wolfhal-board=PATH to the directory holding your wolfHAL_board.h])
fi
AC_MSG_CHECKING([for wolfHAL_board.h in $ENABLED_WOLFHAL_BOARD])
if test -e "$ENABLED_WOLFHAL_BOARD/wolfHAL_board.h"
then
AC_MSG_RESULT([yes])
else
AC_MSG_ERROR([No wolfHAL_board.h in $ENABLED_WOLFHAL_BOARD])
fi
AM_CFLAGS="$AM_CFLAGS -I\"$ENABLED_WOLFHAL_BOARD\""
elif test "x$ENABLED_WOLFHAL_BOARD" != "x"
then
AC_MSG_ERROR([--with-wolfhal-board requires --with-wolfhal=PATH])
fi


# NXP SE050
# Example: "./configure --with-se050=/home/pi/simw_top"
ENABLED_SE050="no"
Expand Down Expand Up @@ -10615,6 +10681,7 @@ AC_ARG_ENABLE([examples],

AS_IF([test "x$ENABLED_FILESYSTEM" = "xno"], [ENABLED_EXAMPLES="no"])
AS_IF([test "x$ENABLED_CRYPTONLY" = "xyes"], [ENABLED_EXAMPLES="no"])
AS_IF([test "x$ENABLED_WOLFHAL" = "xyes"], [ENABLED_EXAMPLES="no"])


# Enable wolfCrypt test and benchmark
Expand All @@ -10629,6 +10696,7 @@ AC_ARG_ENABLE([crypttests],
[ ENABLED_CRYPT_TESTS=$enableval ],
[ ENABLED_CRYPT_TESTS=$ENABLED_CRYPT_TESTS_DEFAULT ]
)
AS_IF([test "x$ENABLED_WOLFHAL" = "xyes"], [ENABLED_CRYPT_TESTS="no"])
AC_SUBST([ENABLED_CRYPT_TESTS])

if test "$ENABLED_CRYPT_TESTS" = "no"
Expand Down Expand Up @@ -11543,7 +11611,7 @@ then
fi
fi

if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" != "no" || test "x$ENABLED_RTL8735B" != "xno" || test "x$ENABLED_VAULTIC" = "xyes"
if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" != "no" || test "x$ENABLED_RTL8735B" != "xno" || test "x$ENABLED_VAULTIC" = "xyes" || test "x$ENABLED_WOLFHAL" = "xyes"
then
ENABLED_CRYPTOCB=yes
fi
Expand Down Expand Up @@ -13382,6 +13450,7 @@ AM_CONDITIONAL([BUILD_SE050],[test "x$ENABLED_SE050" = "xyes"])
AM_CONDITIONAL([BUILD_STSAFE],[test "x$ENABLED_STSAFE" != "xno"])
AM_CONDITIONAL([BUILD_RTL8735B],[test "x$ENABLED_RTL8735B" != "xno"])
AM_CONDITIONAL([BUILD_TROPIC01],[test "x$ENABLED_TROPIC01" = "xyes"])
AM_CONDITIONAL([BUILD_WOLFHAL],[test "x$ENABLED_WOLFHAL" = "xyes"])
AM_CONDITIONAL([BUILD_KDF],[test "x$ENABLED_KDF" = "xyes"])
AM_CONDITIONAL([BUILD_HMAC],[test "x$ENABLED_HMAC" = "xyes"])
AM_CONDITIONAL([BUILD_ERROR_STRINGS],[test "x$ENABLED_ERROR_STRINGS" = "xyes"])
Expand Down Expand Up @@ -13994,6 +14063,7 @@ echo " * NXP SE050: $ENABLED_SE050"
echo " * STMicro STSAFE: $ENABLED_STSAFE"
echo " * RealTek RTL8735B HUK: $ENABLED_RTL8735B"
echo " * TROPIC01: $ENABLED_TROPIC01"
echo " * wolfHAL: $ENABLED_WOLFHAL"
echo " * Maxim Integrated MAXQ10XX: $ENABLED_MAXQ10XX"
echo " * PSA: $ENABLED_PSA"
echo " * System CA certs: $ENABLED_SYS_CA_CERTS"
Expand Down
6 changes: 6 additions & 0 deletions wolfcrypt/src/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
wolfcrypt/src/port/realtek/README.md \
wolfcrypt/src/port/tropicsquare/tropic01.c \
wolfcrypt/src/port/tropicsquare/README.md \
wolfcrypt/src/port/wolfHAL/wolfhal.c \
wolfcrypt/src/port/wolfHAL/README.md \
wolfcrypt/src/port/af_alg/afalg_aes.c \
wolfcrypt/src/port/af_alg/afalg_hash.c \
wolfcrypt/src/port/kcapi/kcapi_aes.c \
Expand Down Expand Up @@ -272,6 +274,10 @@ if BUILD_RTL8735B
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/realtek/rtl8735b.c
endif

if BUILD_WOLFHAL
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/wolfHAL/wolfhal.c
endif

if BUILD_PSA
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/psa/psa.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/psa/psa_hash.c
Expand Down
103 changes: 103 additions & 0 deletions wolfcrypt/src/port/wolfHAL/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# wolfHAL port

Routes wolfCrypt AES (ECB/CBC/GCM/CCM) and RNG to a board's hardware through
[wolfHAL](https://github.com/wolfSSL/wolfHAL) and the wolfSSL crypto callback
framework. Anything the hardware does not cover returns `CRYPTOCB_UNAVAILABLE`
and falls back to software.

## Building

```sh
./configure --with-wolfhal=/path/to/wolfHAL \
--with-wolfhal-board=/path/to/your/board
make
```

`--with-wolfhal` points at the wolfHAL source tree; `--with-wolfhal-board`
points at the directory holding your `wolfHAL_board.h`. The port forces a
static-only build: wolfHAL's objects are compiled by your application, so
`libwolfssl.a` is left with unresolved `whal_*` references for your final link
to satisfy. That also means wolfSSL's bundled examples and crypt tests are
disabled.

## wolfHAL_board.h

`wolfHAL_board.h` is yours, not wolfSSL's, the same arrangement `settings.h` has
with `user_settings.h`. Both wolfHAL and wolfSSL find it by quoted include off
your `-I` path:

* wolfHAL's driver TUs (`src/crypto/stm32wb_aes.c`, `src/rng/stm32wb_rng.c`)
expand the `WHAL_CFG_*_DEV` initializers in it to define their device
singletons.
* wolfSSL's `wolfhal.c` reads it for the wolfHAL platform driver headers and
for one device macro per algorithm:
`WC_WOLFHAL_AES_{ECB,CBC,GCM,CCM}_DEV` and `WC_WOLFHAL_RNG_DEV`. The
`BOARD_AES_*_DEV` / `BOARD_RNG_DEV` names a stock `wolfHAL_board.h` already
uses are accepted directly, so an in-tree wolfHAL board needs no additions.

Only the modes `wolfHAL_board.h` names a device for are offloaded. A mode
wolfSSL is built with but `wolfHAL_board.h` does not name is left to wolfCrypt's
software implementation, so hardware that covers, say, only GCM needs just
`WC_WOLFHAL_AES_GCM_DEV`, and a build with CBC enabled still links and runs.

`WC_WOLFHAL_RNG_DEV` is the exception. The board's TRNG is the only entropy
source available, so there is nothing to decline to and defining
`WOLFSSL_WOLFHAL_RNG` without a device is a build error.

Because the `BOARD_*_DEV` names are accepted, a stock `wolfHAL_board.h` from
wolfHAL's `boards/` directory works as-is:

```sh
./configure --with-wolfhal=../wolfHAL \
--with-wolfhal-board=../wolfHAL/boards/stm32wb55xx_nucleo
```

Use one of those as the starting point for a board wolfHAL does not already
cover.

## Error contract

`wolfhal.c` translates wolfHAL status codes into wolfCrypt errors:

| wolfHAL | wolfCrypt | Effect |
|---|---|---|
| `WHAL_SUCCESS` | `0` | hardware handled the operation |
| `WHAL_ENOTSUP` | `CRYPTOCB_UNAVAILABLE` | falls back to software |
| `WHAL_EINVAL` | `BAD_FUNC_ARG` | fatal, returned to the caller |
| `WHAL_EHARDWARE` | `WC_HW_E` | fatal |
| `WHAL_ETIMEOUT` | `WC_TIMEOUT_E` | fatal |
| anything else | `WC_HW_E` | fatal |

When the wolfHAL driver returns `WHAL_ENOTSUP`, the arguments were valid but
the hardware itself cannot support the operation. As such it will fall back to
software implemented crypto.

`wolfHAL_board.h` gates whole modes, so this matters for what it cannot gate. An
AES engine limited to 128-bit keys must answer a 256-bit request with
`WHAL_ENOTSUP`, not `WHAL_EINVAL`, or the handshake fails instead of falling
back to software.

## Runtime

`wolfCrypt_Init()` registers the device at `WOLFSSL_WOLFHAL_DEVID` (default
`0x5748`), and `wolfhal_settings.h` maps `WC_USE_DEVID` to it so unmodified
wolfCrypt callers route through the hardware. Call `whal_Board_Init()`, which
brings up the peripherals, *before* `wolfCrypt_Init()`. To register at a
different or additional devId, call `wc_wolfHAL_RegisterDevice()` yourself.

Setting either devId macro alone makes the other follow it, so the two cannot
silently diverge. Setting both to different values is the multi-device case:
wolfHAL registers at `WOLFSSL_WOLFHAL_DEVID`, unqualified callers reach
`WC_USE_DEVID`.

Define `WOLFSSL_WOLFHAL_RNG` to draw entropy from the board's TRNG. Nothing
else is needed: `wolfhal_settings.h` wires `wc_wolfHAL_GenerateSeed()` in as
`CUSTOM_RAND_GENERATE_SEED`, seeding wolfCrypt's Hash-DRBG rather than
replacing it, so the DRBG, the repeated block check on the raw seed, and
periodic reseeding all stay in place. `whal_Rng_Generate()` is called once per
seed and reseed instead of for every byte of key material.

To use the wolfHAL RNG output directly, without the DRBG on top, define
`CUSTOM_RAND_GENERATE_BLOCK` in `user_settings.h`; the seed wiring backs off
when `CUSTOM_RAND_GENERATE_SEED` is already defined. This is correct only when
the wolfHAL backend is itself a conditioned DRBG rather than a raw TRNG.
Loading
Loading