Bare-Metal STM32 Hardware Crypto with wolfCrypt: DHUK and CCB Device-Bound Keys

wolfCrypt now drives STM32 on-chip crypto hardware directly from the registers, with zero STMicroelectronics HAL dependency (wolfSSL PR #10395). On top of the bare drivers, the port adds DHUK and CCB: chip-bound keys that are derived and used entirely inside the silicon and never appear in software. It is validated across ~27 NUCLEO boards spanning the STM32 line.

Supported STM32 families: F2, F3, F4, F7, G0, G4, H5, H7, H7RS, L4, L5, U0, U3, U5, WB, WBA, WL, C0, C5, and N6 – Cortex-M0+ through Cortex-M55. wolfBoot, wolfSSL’s secure bootloader, also supports secure and measured boot across these same STM32 families, so the platform and its firmware-update chain are covered end to end.

Features

  • Bare-metal IP drivers (WOLFSSL_STM32_BARE): direct-register AES (TinyAES / CRYP / SAES), HASH, RNG, and PKA (V1 and V2 layouts: ECDSA sign/verify and ECC scalar-multiply). The same code drives the bare path and the HAL path.
  • DHUK (Device Hardware Unique Key): chip-bound keys through the standard crypto-callback framework. The working key is derived inside SAES from a per-key seed and the silicon’s unique key – it never enters software.
  • CCB (Coupling and Chaining Bridge): hardware-protected P-256 ECDSA on STM32U3 and STM32C5. The wrapped private scalar is unwrapped SAES -> PKA inside the CCB and never crosses the system bus or enters software, not even a stack buffer.
  • One tree, every family: the same source builds across all the STM32 families listed above (Cortex-M0+ through Cortex-M55), selected by a single family flag.

The Bare-Metal Port

The bare path talks to the IP blocks through direct MMIO – no HAL handles, no generated init. The caller owns clock-tree, UART, and peripheral-clock bring-up; wolfCrypt owns the crypto registers. Per-family arms in wolfssl/wolfcrypt/port/st/stm32.h absorb the register-name differences between silicon (for example RCC->AHB2ENR vs AHB2ENR1, or the SAES instance routing via WC_STM32_AES_INST). On parts whose PKA exposes only one ECDSA direction, the port auto-gates it: STM32H563 is verify-only (WC_STM32_PKA_VERIFY_ONLY), STM32C5 is sign-only (WC_STM32_PKA_SIGN_ONLY), each routing the other direction to software.

A typical user_settings.h for a bare STM32U3 build with hardware-protected keys:

#define WOLFSSL_STM32_BARE
#define WOLFSSL_STM32U3        /* family register layout */
#define STM32_CRYPTO           /* HW AES   */
#define STM32_HASH             /* HW HASH  */
#define STM32_RNG              /* HW RNG   */
#define WOLFSSL_STM32_PKA      /* HW ECC / ECDSA */
#define WOLFSSL_DHUK           /* device-bound keys */
#define WOLF_CRYPTO_CB
#define WOLFSSL_STM32_CCB      /* CCB-protected ECDSA */

Device-Bound Keys: DHUK and CCB

The differentiator is that a private key can be generated, stored, and used without ever existing as plaintext in MCU memory. Both DHUK and CCB route through wolfCrypt’s standard crypto-callback (WOLF_CRYPTO_CB) framework, so there is no special public API – you bind a key’s devId to the device and call the normal wc_ecc_* / wc_Aes* functions:

ecc_key key;
wc_Stm32_DhukRegister(WC_DHUK_DEVID);
wc_ecc_init_ex(&key, NULL, WC_DHUK_DEVID);

/* keygen: the CCB generates the scalar, wraps it into a device-bound
 * blob, and derives the public key - all in hardware, no CCB API. */
wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1);

/* sign: the scalar is unwrapped SAES -> PKA in hardware and signed;
 * it never enters software. Verify uses the in-clear public key. */
wc_ecc_sign_hash(hash, hashLen, sig, &sigLen, &rng, &key);

For symmetric work, the same pattern gives transparent DHUK AES and AES-GCM/GMAC: the SAES derives the device key from a per-key seed and runs the cipher, and the derived key is never readable. This is a drop-in for TLS and any other consumer of the standard wolfCrypt API.

Validation

The port ships with a companion multi-board test harness, STM32_Bare_Test (wolfssl-examples-stm32 PR #13), that builds, flashes, and benchmarks every family from one Makefile across three flavors (bare HW, asm SP-math, c software). The full wolfcrypt_test self-test passes to Result: 0 on real silicon, and the DHUK / CCB flows are validated on NUCLEO-U385RG-Q, NUCLEO-U545RE-Q, B-U585I-IOT02A, and NUCLEO-C5A3ZG across both the bare-metal and HAL build flavors, P-256, with the private scalar confirmed never present in software.

Getting Started

The library port is in wolfSSL PR #10395 and the board harness in wolfssl-examples-stm32 PR #13; see wolfcrypt/src/port/st/README.md for the per-family option matrix. Questions or a different STM32 target in mind? Reach the wolfSSL team at support@wolfssl.com.

If you have questions about any of the above, please contact us at +1 425 245 8247.

Download wolfSSL Now