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
2 changes: 2 additions & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,8 @@ WOLFSSL_NUVOTON_NSC_IMPL
WOLFSSL_NUVOTON_RNG_OFFLOAD
WOLFSSL_NXP_CASPER_ECC_MUL2ADD
WOLFSSL_NXP_CASPER_ECC_MULMOD
WOLFSSL_NXP_ELE_NO_DEVID
WOLFSSL_NXP_ELE_NO_TRNG
WOLFSSL_NXP_LPC55S6X
WOLFSSL_OCSP_SCREEN_RESPONDER
WOLFSSL_OLDTLS_AEAD_CIPHERSUITES
Expand Down
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3581,6 +3581,18 @@ if (WOLFSSL_SEC_QORIQ AND NOT WOLFSSL_SEC_QORIQ STREQUAL "no")
endif()
endif()

# NXP EdgeLock Secure Enclave, the security subsystem that replaces CAAM on
# i.MX 8ULP / 93 / 95. Implemented as a crypto callback device, so enabling it
# turns callbacks on the way --enable-ele does.
add_option("WOLFSSL_ELE"
"Enable NXP EdgeLock Secure Enclave support (default: disabled)"
"no" "yes;no")
if (WOLFSSL_ELE)
override_cache(WOLFSSL_CRYPTOCB "yes")
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_NXP_ELE")
set(WOLFSSL_NXP_ELE "yes")
endif()

if (WOLFSSL_ARIA)
list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_ARIA")
endif()
Expand Down
7 changes: 7 additions & 0 deletions cmake/functions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ function(generate_build_flags)
set(BUILD_INTELASM ${WOLFSSL_INTEL_ASM} PARENT_SCOPE)
set(BUILD_AFALG ${WOLFSSL_AFALG} PARENT_SCOPE)
set(BUILD_DEVCRYPTO ${WOLFSSL_DEVCRYPTO} PARENT_SCOPE)
set(BUILD_ELE ${WOLFSSL_ELE} PARENT_SCOPE)
if(WOLFSSL_CAMELLIA OR WOLFSSL_USER_SETTINGS)
set(BUILD_CAMELLIA "yes" PARENT_SCOPE)
endif()
Expand Down Expand Up @@ -1427,6 +1428,12 @@ function(generate_lib_src_list LIB_SOURCES)
wolfcrypt/src/port/devcrypto/wc_devcrypto.c)
endif()

if(BUILD_ELE)
list(APPEND LIB_SOURCES
wolfcrypt/src/port/nxp/ele_rng.c
wolfcrypt/src/port/nxp/ele_cryptocb.c)
endif()

if(BUILD_CAVIUM)
list(APPEND LIB_SOURCES wolfcrypt/src/port/cavium/cavium_nitrox.c)
endif()
Expand Down
2 changes: 2 additions & 0 deletions cmake/options.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ extern "C" {
#cmakedefine WOLFSSL_PUBLIC_MP
#undef WOLFSSL_QUIC
#cmakedefine WOLFSSL_QUIC
#undef WOLFSSL_NXP_ELE
#cmakedefine WOLFSSL_NXP_ELE
#undef WOLFSSL_SEC_QORIQ
#cmakedefine WOLFSSL_SEC_QORIQ
#undef WOLFSSL_SEC_QORIQ_BAREMETAL
Expand Down
15 changes: 14 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5151,6 +5151,17 @@ then
done
fi

# NXP EdgeLock Secure Enclave (ELE) - i.MX8ULP / i.MX93 / i.MX95
AC_ARG_ENABLE([ele],
[AS_HELP_STRING([--enable-ele],[Enable NXP EdgeLock Secure Enclave support (default: disabled)])],
[ENABLED_ELE=$enableval],
[ENABLED_ELE=no])
Comment on lines +5155 to +5158

if test "$ENABLED_ELE" != "no"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NXP_ELE"
fi

AC_ARG_ENABLE([caam],
[AS_HELP_STRING([--enable-caam],[Enable wolfSSL support for CAAM (default: disabled)])],
[ ENABLED_CAAM=$enableval ],
Expand Down Expand Up @@ -12214,7 +12225,7 @@ then
fi
fi

if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" != "no" || test "$ENABLED_SEC_QORIQ" != "no" || test "x$ENABLED_RTL8735B" != "xno" || test "x$ENABLED_SILABS_CRYPTOCB" != "xno" || test "x$ENABLED_VAULTIC" = "xyes"
if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" != "no" || test "$ENABLED_SEC_QORIQ" != "no" || test "x$ENABLED_RTL8735B" != "xno" || test "x$ENABLED_SILABS_CRYPTOCB" != "xno" || test "x$ENABLED_VAULTIC" = "xyes" || test "x$ENABLED_ELE" != "xno"
then
ENABLED_CRYPTOCB=yes
fi
Expand Down Expand Up @@ -14372,6 +14383,7 @@ AM_CONDITIONAL([BUILD_CAAM_LINUX],[test "x$ENABLED_CAAM_LINUX" = "xyes"])
AM_CONDITIONAL([BUILD_IOTSAFE],[test "x$ENABLED_IOTSAFE" = "xyes"])
AM_CONDITIONAL([BUILD_IOTSAFE_HWRNG],[test "x$ENABLED_IOTSAFE_HWRNG" = "xyes"])
AM_CONDITIONAL([BUILD_VAULTIC],[test "x$ENABLED_VAULTIC" = "xyes"])
AM_CONDITIONAL([BUILD_ELE],[test "x$ENABLED_ELE" != "xno"])
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"])
Expand Down Expand Up @@ -15000,6 +15012,7 @@ echo " * PK callbacks: $ENABLED_PKCALLBACKS"
echo " * Crypto callbacks: $ENABLED_CRYPTOCB"
echo " * Crypto callbacks only: $ENABLED_CRYPTOCB_ONLY"
echo " * i.MX CAAM: $ENABLED_CAAM"
echo " * NXP EdgeLock Enclave: $ENABLED_ELE"
echo " * IoT-Safe: $ENABLED_IOTSAFE"
echo " * WISeKey/SealSQ VaultIC: $ENABLED_VAULTIC"
echo " * IoT-Safe HWRNG: $ENABLED_IOTSAFE_HWRNG"
Expand Down
7 changes: 7 additions & 0 deletions wolfcrypt/src/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
wolfcrypt/src/port/nxp/ksdk_port.c \
wolfcrypt/src/port/nxp/dcp_port.c \
wolfcrypt/src/port/nxp/se050_port.c \
wolfcrypt/src/port/nxp/ele_rng.c \
wolfcrypt/src/port/nxp/ele_cryptocb.c \
wolfcrypt/src/port/nxp/README.md \
wolfcrypt/src/port/nxp/sec_qoriq.c \
wolfcrypt/src/port/nxp/sec_qoriq_cb.c \
Expand Down Expand Up @@ -323,6 +325,11 @@ src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_rsa.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_hmac.c
endif

if BUILD_ELE
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/nxp/ele_rng.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/nxp/ele_cryptocb.c
endif

if BUILD_SE050
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/nxp/se050_port.c
endif
Expand Down
44 changes: 44 additions & 0 deletions wolfcrypt/src/port/nxp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,50 @@ move the crossover down toward small-record sizes.
GCM including a corrupted-tag rejection, RNG4, and ECDSA/ECDH cross-checked
against the software implementation.

## NXP EdgeLock Secure Enclave (ELE)

For i.MX 8ULP / 93 / 95, where NXP replaced CAAM with the EdgeLock Secure
Enclave. Implemented as a crypto callback device; TRNG only so far.

```sh
./configure --enable-ele
```

That defines `WOLFSSL_NXP_ELE` and turns on crypto callbacks. Register the
device before use:

```c
wolfCrypt_Init();
wc_EleCryptoCb_RegisterDevice(WOLFSSL_NXP_ELE_DEVID);
wc_InitRng_ex(&rng, NULL, WOLFSSL_NXP_ELE_DEVID);
```

Registration is left to the application rather than done in `wolfCrypt_Init()`:
the hwrng node is root-only by default, so registering unconditionally would
fail every RNG call in an unprivileged process instead of using software.

| Macro | Default | Purpose |
|---|---|---|
| `WOLFSSL_NXP_ELE` | off | Enable the port |
| `WOLFSSL_NXP_ELE_DEVID` | `0x454C45` | Crypto callback device id |
| `WOLFSSL_NXP_ELE_TRNG_DEVICE` | `/dev/hwrng` | Enclave TRNG character device |
| `WOLFSSL_NXP_ELE_TRNG_CURRENT` | `/sys/.../rng_current` | Where the active hwrng provider is named |
| `WOLFSSL_NXP_ELE_TRNG_NAME` | `ele-trng` | Provider name the test looks for |
| `WOLFSSL_NXP_ELE_TRNG` | on | Build the TRNG support |
| `WOLFSSL_NXP_ELE_NO_TRNG` | off | Do not build the TRNG support |
| `WOLFSSL_NXP_ELE_NO_DEVID` | off | Do not set `WC_USE_DEVID` |

Anything unimplemented returns `CRYPTOCB_UNAVAILABLE`, so wolfCrypt falls back
to software. The TRNG arrives through the Linux hwrng framework, so no NXP
userspace library is needed; confirm the backing source with
`cat /sys/class/misc/hw_random/rng_current` (expect `ele-trng`).

Hash, AES, HMAC/CMAC and public key need the enclave HSM interface
(`/dev/hsm0_ch0`), which requires NXP's `imx-secure-enclave` library and a
kernel carrying NXP's downstream `ele_mu` driver; the upstream `fsl-se` driver
rejects userspace SAB writes with `EINVAL`. The enclave exposes no post-quantum
algorithms, so ML-KEM and ML-DSA stay on the CPU.

## Support

For questions please email support@wolfssl.com
87 changes: 87 additions & 0 deletions wolfcrypt/src/port/nxp/ele_cryptocb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* ele_cryptocb.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

/* Crypto callback device for the NXP EdgeLock Secure Enclave (ELE). Only
* seeding is implemented; the rest needs the enclave HSM interface
* (/dev/hsm0_ch0) and NXP's imx-secure-enclave library, which not every BSP
* ships. Anything unimplemented returns CRYPTOCB_UNAVAILABLE so wolfCrypt uses
* its software implementation. The enclave exposes no post-quantum algorithms. */

#include <wolfssl/wolfcrypt/libwolfssl_sources.h>

#ifdef WOLFSSL_NXP_ELE

#include <wolfssl/wolfcrypt/port/nxp/ele.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>

int wc_EleCryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
{
int ret = CRYPTOCB_UNAVAILABLE;

(void)devId;
(void)ctx;

if (info == NULL) {
return BAD_FUNC_ARG;
}

switch (info->algo_type) {
#if defined(WOLFSSL_NXP_ELE_TRNG) && !defined(WC_NO_RNG)
case WC_ALGO_TYPE_SEED:
ret = wc_ele_trng_read(info->seed.seed, info->seed.sz);
break;
#endif

/* Falling through keeps the software fallback automatic. */
case WC_ALGO_TYPE_HASH:
case WC_ALGO_TYPE_CIPHER:
case WC_ALGO_TYPE_PK:
case WC_ALGO_TYPE_HMAC:
case WC_ALGO_TYPE_CMAC:
case WC_ALGO_TYPE_RNG:
default:
ret = CRYPTOCB_UNAVAILABLE;
break;
}

return ret;
}

int wc_EleCryptoCb_RegisterDevice(int devId)
{
if (devId == INVALID_DEVID) {
devId = WOLFSSL_NXP_ELE_DEVID;
}

return wc_CryptoCb_RegisterDevice(devId, wc_EleCryptoDevCb, NULL);
}

void wc_EleCryptoCb_UnRegisterDevice(int devId)
{
if (devId == INVALID_DEVID) {
devId = WOLFSSL_NXP_ELE_DEVID;
}

wc_CryptoCb_UnRegisterDevice(devId);
}

#endif /* WOLFSSL_NXP_ELE */
103 changes: 103 additions & 0 deletions wolfcrypt/src/port/nxp/ele_rng.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/* ele_rng.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/

/* TRNG of the NXP EdgeLock Secure Enclave. The in-kernel fsl-se driver
* registers it with the Linux hwrng framework, so it is reached as a character
* device and needs no NXP userspace library. */

#include <wolfssl/wolfcrypt/libwolfssl_sources.h>

#ifdef WOLFSSL_NXP_ELE

#include <wolfssl/wolfcrypt/port/nxp/ele.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>

#ifdef WOLFSSL_NXP_ELE_TRNG

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

/* Opened per read, not cached: seeding is rare and a file-scope fd would need
* locking against concurrent seeders. */
static int wc_ele_trng_open(void)
{
int fd = wc_open_cloexec(WOLFSSL_NXP_ELE_TRNG_DEVICE, O_RDONLY);
if (fd < 0) {
if (errno == EACCES) {
WOLFSSL_MSG("ELE TRNG: permission denied opening hwrng device; "
"the node is root-only unless a udev rule grants "
"access");
}
else {
WOLFSSL_MSG("ELE TRNG: unable to open hwrng device");
}
return WC_HW_E;
}

return fd;
}

int wc_ele_trng_read(byte* buf, word32 sz)
{
int fd;
ssize_t got;
word32 pos = 0;

if (buf == NULL) {
return BAD_FUNC_ARG;
}
if (sz == 0) {
return 0;
}

fd = wc_ele_trng_open();
if (fd < 0) {
return fd;
}

/* hwrng returns short reads while the entropy pool refills. */
while (pos < sz) {
got = read(fd, buf + pos, (size_t)(sz - pos));
if (got < 0) {
if (errno == EINTR) {
continue;
}
WOLFSSL_MSG("ELE TRNG: read failed");
close(fd);
return RNG_FAILURE_E;
}
if (got == 0) {
/* No progress: fail rather than spin. */
WOLFSSL_MSG("ELE TRNG: no entropy returned");
close(fd);
return RNG_FAILURE_E;
}
pos += (word32)got;
}

close(fd);
return 0;
}

#endif /* WOLFSSL_NXP_ELE_TRNG */
#endif /* WOLFSSL_NXP_ELE */
Loading
Loading