mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
nxp: document the MCUXpresso build for the EdgeLock port
An IDE/MCUEXPRESSO/RW612 directory with a known-good user_settings.h and the steps to build the port against the SDK rather than Zephyr, plus the port README's pointer to it. The README itself grew alongside the offloads it documents.
This commit is contained in:
105
IDE/MCUEXPRESSO/RW612/README.md
Normal file
105
IDE/MCUEXPRESSO/RW612/README.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# wolfSSL on NXP RW612 with EdgeLock (ELS)
|
||||
|
||||
This directory configures wolfSSL for the NXP RW612 with the EdgeLock crypto callback port, `wolfcrypt/src/port/nxp/els_pkc_port.c`, built from an MCUXpresso SDK project. It offloads SHA-256, AES, AES-GCM, CMAC and the DRBG to the ELS peripheral.
|
||||
|
||||
Zephyr users do not need any of this: the wolfSSL Zephyr module supplies the same port through `CONFIG_WOLFSSL_ELS_PKC=y`, and the `els_pkc` Zephyr module supplies the vendor headers. This is the path for a project that uses the MCUXpresso SDK directly.
|
||||
|
||||
## What els_pkc is
|
||||
|
||||
`els_pkc` is NXP's CLNS (Crypto Library NXP Secure) middleware. It ships as an MCUXpresso SDK component under `components/els_pkc/` and is also published at <https://github.com/NXP/els_pkc>. The Zephyr module it carries is an add-on; the SDK component is the primary form.
|
||||
|
||||
wolfSSL never builds or vendors CLNS. The port calls into it and the application links it, exactly as the SE050 port does. Take either route:
|
||||
|
||||
- build `els_pkc/src/comps` as part of your project, or
|
||||
- link the prebuilt `els_pkc/static_library/rw61x/libclns.a`.
|
||||
|
||||
**Licensing.** els_pkc is distributed under NXP's proprietary `LA_OPT_Online Code Hosting` license, not an open source license. Clause 3.7 forbids subjecting it to a license that would require source disclosure. Fetching it at build time is fine and is what both this setup and the Zephyr module do; copying it into a wolfSSL tree is not.
|
||||
|
||||
## MCUXpresso IDE setup
|
||||
|
||||
1. Create a project for your RW612 board (for example `frdm_rw612`).
|
||||
2. In the SDK component selector, add **els_pkc**. That brings in `src/comps`, the `rw61x` platform layer, and the bundled CMSIS.
|
||||
3. Add the wolfSSL sources to the project. `wolfcrypt/src/port/nxp/els_pkc_port.c` is compiled like every other wolfCrypt port and gates itself on `WOLFSSL_ELS_PKC`, so it costs nothing when the port is off.
|
||||
4. Copy `user_settings.h` from this directory into your project and define `WOLFSSL_USER_SETTINGS` for the build.
|
||||
5. Add these include paths, all inside the els_pkc component: `src/inc`, `src/compiler`, `src/comps/*/inc`, `src/comps/*/inc/internal`, `src/platforms/rw61x`, `src/platforms/rw61x/inc`, `src/platforms/rw61x/cmsis_cortex_m_5_5_1/inc`, `includes/platform/rw61x`.
|
||||
|
||||
### Compiler flags that matter
|
||||
|
||||
| Flag | Why |
|
||||
| --- | --- |
|
||||
| `-mcpu=cortex-m33+nodsp` | Without `+nodsp` the vendor CMSIS `core_cm33.h` aborts the build with "Compiler generates DSP (SIMD) instructions for a device without DSP extensions". `-D__DSP_PRESENT=1` does **not** work around it. |
|
||||
| `-DCPU_RW612ETA2I` | `fsl_device_registers.h` selects the register map from the part number. Use the macro matching your part; only the A2 parts appear in its selector. |
|
||||
| `-mcmse` | Matches how NXP builds CLNS. |
|
||||
| `-DNO_THREAD_LS` | Required on bare metal. See below. |
|
||||
| `-DWOLFSSL_NO_GETPID` | Required with newlib. See below. |
|
||||
|
||||
### wolfCrypt_Init() returning -1000
|
||||
|
||||
`wolfCrypt_Init()` guards against recursive entry with a `__thread` variable whenever the toolchain advertises thread-local storage. On bare metal nothing sets the thread pointer, so that read returns garbage, the guard fires, and the call returns `DEADLOCK_AVERTED_E` (-1000) before initialising anything. Define `NO_THREAD_LS` unless your runtime really does set up TLS.
|
||||
|
||||
### random.c and an implicit declaration of getpid()
|
||||
|
||||
`--specs=nosys.specs` gives the linker a stub for every syscall, which is what
|
||||
lets autoconf's link probes succeed without a board support package. It also
|
||||
makes the probe for `getpid()` succeed, so `HAVE_GETPID` ends up defined even
|
||||
though newlib's headers never declare the function, and `random.c` then fails
|
||||
to compile on an implicit declaration. Define `WOLFSSL_NO_GETPID`; a bare metal
|
||||
target has no processes to identify.
|
||||
|
||||
Toolchains shipping picolibc rather than newlib, such as the Zephyr SDK's
|
||||
`arm-zephyr-eabi`, declare `getpid()` and do not need this.
|
||||
|
||||
## Building with autoconf instead
|
||||
|
||||
The same result from a source tarball or checkout. Note that no CI job builds this port today - it needs the vendor library and the SoC headers, neither of which the CI images carry - so a green run says nothing about it:
|
||||
|
||||
```sh
|
||||
./autogen.sh
|
||||
./configure --host=arm-none-eabi --disable-shared --enable-static \
|
||||
--enable-cryptonly --enable-cryptocb \
|
||||
--enable-aesgcm --enable-cmac \
|
||||
--with-els-pkc=/path/to/els_pkc \
|
||||
--with-mcux-sdk=/path/to/mcux-sdk-ng \
|
||||
--disable-filesystem --enable-singlethreaded \
|
||||
CFLAGS="-mcpu=cortex-m33+nodsp -mthumb -Os --specs=nosys.specs" \
|
||||
CPPFLAGS="-DWOLFSSL_NO_SOCK -DWOLFSSL_USER_IO -DNO_WRITEV -DNO_DEV_RANDOM \
|
||||
-DNO_THREAD_LS -DWOLFSSL_NO_GETPID"
|
||||
make
|
||||
```
|
||||
|
||||
`--with-mcux-sdk` wants a tree holding `devices/Wireless/RW/RW612` and `drivers/common`: your MCUXpresso SDK install, or a checkout of NXP's `mcux-sdk-ng`. The els_pkc platform layer includes `fsl_common.h`, `fsl_device_registers.h` and `fsl_ocotp.h` from it.
|
||||
|
||||
The resulting `libwolfssl.a` carries unresolved `mcuxCl*` references. That is correct: the application links CLNS.
|
||||
|
||||
To confirm the port really made it into the archive, check for its symbols rather than for the object file. The port compiles to an empty translation unit when `WOLFSSL_ELS_PKC` is missing, so a build can succeed with the port silently absent:
|
||||
|
||||
```sh
|
||||
arm-none-eabi-nm src/.libs/libwolfssl.a | grep wc_ElsPkc
|
||||
```
|
||||
|
||||
## Using it
|
||||
|
||||
`wolfCrypt_Init()` brings the port up and registers its crypto callback, so there is nothing to call by hand, and `wc_CryptoCb_DefaultDevID()` answers `WOLFSSL_ELS_PKC_DEVID`, so a context created without an explicit device is offloaded too:
|
||||
|
||||
```c
|
||||
#include <wolfssl/wolfcrypt/port/nxp/els_pkc_port.h>
|
||||
|
||||
wolfCrypt_Init();
|
||||
|
||||
wc_Sha256 sha;
|
||||
wc_InitSha256(&sha); /* offloaded */
|
||||
wc_InitSha256_ex(&sha, NULL, WOLFSSL_ELS_PKC_DEVID); /* the same, explicitly */
|
||||
wc_InitSha256_ex(&sha, NULL, INVALID_DEVID); /* kept in software */
|
||||
```
|
||||
|
||||
Define `WC_NO_DEFAULT_DEVID` to switch the automatic routing off and require every context to name the device. Note it only reaches code that asks `wc_CryptoCb_DefaultDevID()` for a device: `wc_AesInit()` takes a `devId` argument directly, so pass `WOLFSSL_ELS_PKC_DEVID` there yourself.
|
||||
|
||||
The DRBG seed comes from the ELS too, through `wc_GenerateSeed()`, so call `wolfCrypt_Init()` before the first `wc_InitRng()`. Before it, and after `wolfCrypt_Cleanup()`, seeding fails with `BAD_STATE_E`. NXP rates the ELS DRBG at 128 bits of security strength, which caps wolfCrypt's Hash-DRBG at 128 bits as well.
|
||||
|
||||
Anything the hardware does not serve is *declined* with `CRYPTOCB_UNAVAILABLE` and completed in software, so an unsupported algorithm or key size is a performance question, never a failure. The exception is a key held in a slot, which has no software copy: there a shape the hardware cannot serve, such as a partial AES block, fails.
|
||||
|
||||
A hardware *failure* is treated differently on purpose: the port reports the error rather than quietly finishing in software, because a caller that ignores the return would otherwise receive a confident bad result. Declining and failing are not the same thing.
|
||||
|
||||
`wolfCrypt_Cleanup()` unregisters the callback and closes the port, keeping its mutex; `wc_ElsPkc_Init()` re-registers it if you need the port back afterwards. Finish or free every hash, CMAC and AES context the port has taken over before the last `wolfCrypt_Cleanup()`: with the device gone, wolfCrypt continues it in software from the engine's state, and a hash returns a wrong digest.
|
||||
|
||||
Keys resident in the ELS key store are referenced rather than exported: attach a reference to a key with `wc_ElsPkc_AesUseSlot()` or `wc_ElsPkc_CmacUseSlot()`. Those are the entry point - `wc_ElsPkc_MakeKeyRef()` is the primitive underneath them. See the port header for the reference format.
|
||||
83
IDE/MCUEXPRESSO/RW612/user_settings.h
Normal file
83
IDE/MCUEXPRESSO/RW612/user_settings.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* user_settings.h
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* wolfSSL settings for the RW612 EdgeLock port in an MCUXpresso SDK project.
|
||||
* See README.md. */
|
||||
|
||||
#ifndef USER_SETTINGS_H
|
||||
#define USER_SETTINGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WOLFSSL_GENERAL_ALIGNMENT 4
|
||||
#define SINGLE_THREADED
|
||||
|
||||
/* Bare-metal startup never sets the thread pointer wolfCrypt_Init() reads. */
|
||||
#define NO_THREAD_LS
|
||||
|
||||
/* newlib does not declare getpid(); nosys.specs hides that from configure. */
|
||||
#define WOLFSSL_NO_GETPID
|
||||
#define NO_FILESYSTEM
|
||||
#define NO_WRITEV
|
||||
#define WOLFSSL_NO_SOCK
|
||||
#define WOLFSSL_USER_IO
|
||||
#define NO_DEV_RANDOM /* entropy comes from the ELS DRBG, below */
|
||||
#define WOLFCRYPT_ONLY /* drop for TLS; then supply IO and time */
|
||||
|
||||
/* No RTC by default on this board. Supply a real time source and remove this
|
||||
* if certificate validity has to be checked. */
|
||||
#define NO_ASN_TIME
|
||||
|
||||
#define WOLFSSL_ELS_PKC
|
||||
|
||||
#define WOLF_CRYPTO_CB
|
||||
|
||||
/* Seed wolfCrypt's DRBG from the ELS hardware DRBG. */
|
||||
#define HAVE_HASHDRBG
|
||||
|
||||
/* Anything not listed here falls back to software through the normal
|
||||
* CRYPTOCB_UNAVAILABLE path. */
|
||||
|
||||
#define WOLFSSL_SHA256
|
||||
#define WOLFSSL_SHA384
|
||||
#define WOLFSSL_SHA512
|
||||
|
||||
#define HAVE_AESGCM
|
||||
#define WOLFSSL_AES_DIRECT
|
||||
#define HAVE_AES_ECB
|
||||
#define WOLFSSL_AES_COUNTER
|
||||
#define WOLFSSL_CMAC
|
||||
|
||||
#define NO_DSA
|
||||
#define NO_RC4
|
||||
#define NO_MD4
|
||||
#define NO_DES3
|
||||
#define NO_PSK
|
||||
#define NO_OLD_TLS
|
||||
#define WOLFSSL_SMALL_STACK
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USER_SETTINGS_H */
|
||||
@@ -716,7 +716,10 @@ into a wolfSSL tree.
|
||||
supplied through `CONFIG_WOLFSSL_SETTINGS_FILE`, the feature Kconfigs do
|
||||
not apply and `WOLFSSL_ELS_PKC` has to be defined in that file instead.
|
||||
- **MCUXpresso SDK / autoconf.** `--with-els-pkc=PATH` and
|
||||
`--with-mcux-sdk=PATH`.
|
||||
`--with-mcux-sdk=PATH`. See
|
||||
[IDE/MCUEXPRESSO/RW612](../../../IDE/MCUEXPRESSO/RW612) for the worked
|
||||
setup, the compiler flags that matter, a known-good `user_settings.h`, and
|
||||
the run-time API.
|
||||
|
||||
Everything in the port is gated on `WOLFSSL_ELS_PKC`. Without that macro the
|
||||
file compiles to an empty translation unit and reaches no vendor header,
|
||||
|
||||
Reference in New Issue
Block a user