Adds new STM32 Bare support for Hash, SAES/AES and PKA#10395
Draft
dgarske wants to merge 1 commit intowolfSSL:masterfrom
Draft
Adds new STM32 Bare support for Hash, SAES/AES and PKA#10395dgarske wants to merge 1 commit intowolfSSL:masterfrom
dgarske wants to merge 1 commit intowolfSSL:masterfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a new STM32 “bare-metal” crypto port flavor (WOLFSSL_STM32_BARE) that uses CMSIS device-header register access (no HAL/StdPeriph dependency) and wires it into wolfCrypt’s AES/HASH/RNG paths, plus a direct-register PKA implementation used by the existing STM32 PKA integration.
Changes:
- Add
WOLFSSL_STM32_BAREselection in settings to include only CMSIS device headers and auto-enable the no-lib RNG path. - Add per-family bare-metal clock-enable macros and HAL/PKA stand-in types to support a direct-register PKA driver.
- Add bare-metal AES (CRYP + TinyAES), HASH clock enable override, and bare PKA shims/driver, plus AES dispatcher updates in
aes.cand RNG clock-enable macro use inrandom.c.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
wolfssl/wolfcrypt/settings.h |
Adds WOLFSSL_STM32_BARE selection, CMSIS header includes, and mutual exclusion with CubeMX. |
wolfssl/wolfcrypt/port/st/stm32.h |
Adds BARE clock-enable macros, HASH ALGO defines for new IP, and PKA stand-in types. |
wolfcrypt/src/port/st/stm32.c |
Implements bare-metal AES (CRYP/TinyAES), HASH clock enable override, and bare-metal PKA shims/driver. |
wolfcrypt/src/aes.c |
Routes ECB/CBC/CTR and GCM-encrypt through the BARE STM32 implementation with SW fallback behavior. |
wolfcrypt/src/random.c |
Uses a per-family RNG clock-enable macro (for BARE) instead of a fixed RCC register bit. |
wolfcrypt/src/ecc.c |
Adjusts STM32 PKA guards so BARE uses SW ECDSA paths while still leveraging HW scalar mul. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+32
to
+52
| #ifdef WOLFSSL_STM32_BARE | ||
| /* Per-family direct-register clock-enable macros. CMSIS device header is | ||
| * already included via settings.h. RCC->...ENR bit names come from CMSIS. */ | ||
| #if defined(WOLFSSL_STM32H5) | ||
| #define WC_STM32_AES_CLK_ENABLE() \ | ||
| do { RCC->AHB2ENR |= RCC_AHB2ENR_AESEN; (void)RCC->AHB2ENR; } while (0) | ||
| #define WC_STM32_AES_CLK_DISABLE() \ | ||
| do { RCC->AHB2ENR &= ~RCC_AHB2ENR_AESEN; } while (0) | ||
| #define WC_STM32_HASH_CLK_ENABLE() \ | ||
| do { RCC->AHB2ENR |= RCC_AHB2ENR_HASHEN; (void)RCC->AHB2ENR; } while (0) | ||
| #define WC_STM32_HASH_CLK_DISABLE() \ | ||
| do { RCC->AHB2ENR &= ~RCC_AHB2ENR_HASHEN; } while (0) | ||
| #define WC_STM32_RNG_CLK_ENABLE() \ | ||
| do { RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; (void)RCC->AHB2ENR; } while (0) | ||
| #elif defined(WOLFSSL_STM32F4) || defined(WOLFSSL_STM32F7) || \ | ||
| defined(WOLFSSL_STM32H7) | ||
| #define WC_STM32_AES_CLK_ENABLE() \ | ||
| do { RCC->AHB2ENR |= RCC_AHB2ENR_CRYPEN; (void)RCC->AHB2ENR; } while (0) | ||
| #define WC_STM32_AES_CLK_DISABLE() \ | ||
| do { RCC->AHB2ENR &= ~RCC_AHB2ENR_CRYPEN; } while (0) | ||
| #define WC_STM32_HASH_CLK_ENABLE() \ |
Comment on lines
+142
to
+176
| /* Bare-metal stand-ins for the small subset of HAL types/values that | ||
| * wolfcrypt/src/port/st/stm32.c references in the PKA path. These mirror | ||
| * the ST HAL definitions; the bare-metal HAL_PKA_* shims in stm32.c | ||
| * implement the actual register sequence. */ | ||
| #ifdef WOLFSSL_STM32_PKA | ||
|
|
||
| #include <stdint.h> | ||
|
|
||
| typedef enum { | ||
| HAL_OK = 0x00U, | ||
| HAL_ERROR = 0x01U, | ||
| HAL_BUSY = 0x02U, | ||
| HAL_TIMEOUT = 0x03U | ||
| } HAL_StatusTypeDef; | ||
|
|
||
| #ifndef HAL_MAX_DELAY | ||
| #define HAL_MAX_DELAY 0xFFFFFFFFU | ||
| #endif | ||
|
|
||
| typedef struct { | ||
| PKA_TypeDef *Instance; | ||
| } PKA_HandleTypeDef; | ||
|
|
||
| typedef struct { | ||
| uint32_t modulusSize; | ||
| uint32_t coefSign; | ||
| const uint8_t *coefA; | ||
| const uint8_t *coefB; /* V2 only */ | ||
| const uint8_t *modulus; | ||
| const uint8_t *primeOrder; /* V2 only */ | ||
| uint32_t scalarMulSize; | ||
| const uint8_t *scalarMul; | ||
| const uint8_t *pointX; | ||
| const uint8_t *pointY; | ||
| } PKA_ECCMulInTypeDef; |
Comment on lines
+446
to
+448
| /* Note: under WOLFSSL_STM32_BARE the GCM HW phase machine is not yet | ||
| * implemented. GCM falls back to the software path which still uses HW | ||
| * AES (via wc_AesEncrypt -> wc_Stm32_Aes_Ecb) for the underlying blocks. */ |
Comment on lines
607
to
+611
| static WC_INLINE void wc_Stm32_Hash_Clock_Enable(STM32_HASH_Context* stmCtx) | ||
| { | ||
| #ifdef WOLFSSL_STM32_CUBEMX | ||
| #if defined(WOLFSSL_STM32_BARE) | ||
| WC_STM32_HASH_CLK_ENABLE(); | ||
| #elif defined(WOLFSSL_STM32_CUBEMX) |
Comment on lines
+233
to
+251
| HAL_StatusTypeDef HAL_PKA_Init(PKA_HandleTypeDef *hpkah) | ||
| { | ||
| if (hpkah == NULL) { | ||
| return HAL_ERROR; | ||
| } | ||
| if (hpkah->Instance == NULL) { | ||
| hpkah->Instance = PKA; | ||
| } | ||
|
|
||
| #ifdef WC_STM32_PKA_CLK_ENABLE | ||
| WC_STM32_PKA_CLK_ENABLE(); | ||
| #endif | ||
|
|
||
| /* Reset CR, enable the PKA, clear any pending flags. */ | ||
| hpkah->Instance->CR = PKA_CR_EN; | ||
| hpkah->Instance->CLRFR = PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | | ||
| PKA_CLRFR_ADDRERRFC; | ||
| return HAL_OK; | ||
| } |
Comment on lines
+297
to
+305
| /* Wait for end-of-operation flag. */ | ||
| while ((p->SR & PKA_SR_PROCENDF) == 0U) { | ||
| /* No timeout in BARE -- HAL_MAX_DELAY semantics. The hardware | ||
| * completes WB55 P-256 scalar multiplication in well under | ||
| * 100 ms; if we're here forever something is wrong upstream. */ | ||
| } | ||
|
|
||
| /* Clear all status flags. */ | ||
| p->CLRFR = PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
WOLFSSL_STM32_BARE, a third STM32 crypto port flavor that talks directly to CRYP/AES/HASH/RNG/PKA peripherals through CMSIS device-header registers, with nostm32xxxx_hal_*or Standard Peripheral Library dependency. SelectingWOLFSSL_STM32_BAREis mutually exclusive withWOLFSSL_STM32_CUBEMXand uses the existingWOLFSSL_STM32_RNG_NOLIBdirect-register RNG path.What's covered
RCC->...ENRdirectly when BARE is set.WOLFSSL_STM32_RNG_NOLIBpath; per-familyWC_STM32_RNG_CLK_ENABLE()so G0 (AHBENR) is correct alongside F4/F7/L4/U5/H5/H7.HAL_PKA_*symbolswc_ecc_mulmod_ex2()calls, so the existing PKA call sites compile unchanged. ECDSA sign/verify under BARE+PKA still go through the SW ECDSA helper paths (which call HW-acceleratedwc_ecc_mulmod_ex2()underneath); a!WOLFSSL_STM32_BAREguard keeps that behavior tidy.Files
wolfssl/wolfcrypt/settings.h: gate HAL-header includes on!WOLFSSL_STM32_BARE; pull in only the CMSIS device header (e.g.stm32h5xx.h); auto-defineWOLFSSL_STM32_RNG_NOLIB; mutex withWOLFSSL_STM32_CUBEMX.wolfssl/wolfcrypt/port/st/stm32.h: per-familyWC_STM32_AES/HASH/RNG/PKA_CLK_ENABLE()macros, HASHALGOvalue table for the new H5/U3/MP13/N6/H7S generation, BARE-only HAL_PKA stand-in typedefs.wolfcrypt/src/port/st/stm32.c: ~600 LOC bare-metal AES driver (CRYP + TinyAES), HASH clock-enable override, PKA driver (V1 + V2). Plus aSTM32_AES_CLEAR_CCF()macro that picksAES_ICR_CCForAES_CR_CCFCbased on which the device header defines (newer vs WB/WL/G0 TinyAES).wolfcrypt/src/aes.c:WOLFSSL_STM32_BAREarms next to the existingWOLFSSL_STM32_CUBEMXblocks in ECB / CBC / GCM-enc / GCM-dec dispatchers, and a smallwc_AesSetKeybyte-reverse so HW key registers see big-endian words.wolfcrypt/src/random.c: replace the hard-codedRCC->AHB2ENR |= RCC_AHB2ENR_RNGENwrite with the per-family macro fromport/st/stm32.h.wolfcrypt/src/ecc.c: existingWOLFSSL_STM32_PKA-> SW-helper-bypass guards become... && !WOLFSSL_STM32_BARE. v1 of the bare PKA driver only implements ECCMul HW; the SW ECDSA path then drives that HW underneath.Validated on hardware
wolfcrypt_testPASSES; bench shows BARE 11.4 MiB/s AES-CBC, 25.8 MiB/s SHA-256.wolfcrypt_testPASSES; bench 19.2 MiB/s AES-CBC, 25.9 MiB/s SHA-256.CONFIG=c(no BARE drivers); seeSTM32_BARE_BOARD_STATUS.mdin this repo for the full reproduction recipe.wolfcrypt_testPASSES with HASH+RNG via BARE.wolfcrypt_testPASSES; PKA HW path exercised end-to-end on P-256 ECDHE.wolfcrypt_testPASSES; PKA HW path validated. Note: WB55 PKA HW @ 64 MHz is slower per-op than SP-ECC software for P-256 (ST publishes the same observation); driver is correctness-validated, performance is silicon-bound.wolfcrypt_testPASSES in pure-software baseline; useful as a software baseline platform until G4A1 (which has the full crypto block) is brought up.Companion
Matching multi-board example: wolfSSL/wolfssl-examples-stm32 PR #13 -- wolfSSL/wolfssl-examples-stm32#13. Selectable per-board with
BOARD={h5,h7,u3,u5,wb55,g491,f439}andCONFIG={c,asm,bare}×TARGET={test,bench}at the make line. Reproduces every result in the test matrix below.Test matrix (validated on real hardware)
Run via
make BOARD=<x> CONFIG=bare TARGET=test(fullwolfcrypt_test) andmake BOARD=<x> CONFIG=bare TARGET=bench. Pass = wolfcrypt_test exits withResult: 0 (PASS). Bench numbers are from the wolfcrypt benchmark.c block-1024 default.