diff --git a/wolfcrypt/src/port/st/README.md b/wolfcrypt/src/port/st/README.md index baad5e66880..b48f85e57c3 100644 --- a/wolfcrypt/src/port/st/README.md +++ b/wolfcrypt/src/port/st/README.md @@ -83,6 +83,26 @@ The TinyAES IP exposes a single key-size bit (128/256 only), so wolfSSL auto-def Some newer families (H5/H7S/U3/U5/WBA/C5/N6, plus the L562 sub-variant) expose a Secure AES (SAES) instance in addition to (or instead of) a regular AES block. Define `WOLFSSL_STM32_USE_SAES` to route all wolfcrypt AES traffic through SAES via the `WC_STM32_AES_INST` indirection macro. This is required when the regular AES block is TrustZone-gated (H7S3) and is also a prerequisite for DHUK key-wrap on the families in the `WC_STM32_HAS_DHUK` gate (U3/U5/H5/WBA/C5). +### HW crypto via crypto callback (`WOLF_CRYPTO_CB_ONLY_AES` / `_ECC`) + +`WOLF_CRYPTO_CB_ONLY_AES` and `WOLF_CRYPTO_CB_ONLY_ECC` strip the software AES / ECC cores (to shrink code) and route those operations through the `WOLF_CRYPTO_CB` framework. On the CubeMX/HAL build the STM32 crypto-callback device services them in hardware: + +- **AES** (ECB, and GCM via the HAL GCM engine) with the normal plaintext key. +- **ECDSA sign + verify** on the HW PKA (`WOLFSSL_STM32_PKA`), plus CCB-protected sign (`WOLFSSL_STM32_CCB`) via `HAL_CCB`. This makes `WOLF_CRYPTO_CB_ONLY_ECC` usable on CubeMX -- that macro compiles out the direct `ecc.c` PKA path, so the callback provides HW ECDSA instead. + +``` +#define WOLFSSL_STM32_CUBEMX +#define WOLFSSL_STM32_PKA /* HW ECC sign/verify */ +#define WOLF_CRYPTO_CB +#define WOLFSSL_STM32_CCB /* optional: CCB-protected ECDSA */ +#define WOLF_CRYPTO_CB_ONLY_AES +#define WOLF_CRYPTO_CB_ONLY_ECC +... +wc_Stm32_DhukRegister(devId); /* once; serves AES + ECDSA (+ CCB) */ +``` + +(For a build without CCB, `wc_Stm32_CubeAesRegister(devId)` registers the same CubeMX device: AES, plus ECDSA sign/verify on the HW PKA when `WOLFSSL_STM32_PKA` is enabled -- so it also satisfies `WOLF_CRYPTO_CB_ONLY_ECC` without CCB. It falls back to cipher-only when the PKA is not built in.) HW PKA on the HAL build requires the application to build/link ST's `stm32XXxx_hal_pka.c` and provide a `PKA_HandleTypeDef hpka;` initialized with `HAL_PKA_Init(&hpka)` (a CubeMX `MX_PKA_Init`); wolfSSL references `hpka` as `extern`. Note: CCB key *provisioning* (`wc_ecc_make_key`) derives the scalar in software, so it needs a build without `WOLF_CRYPTO_CB_ONLY_ECC` -- provision the CCB blob there, after which CCB *sign* runs under the stripped config. Worked examples in [`STM32_Bare_Test`](https://github.com/wolfSSL/wolfssl-examples-stm32): `main_cubeaes.c` (AES) and `main_cubecrypto.c` (ECC + CCB + AES), validated on NUCLEO-U385RG-Q. + ### Coding Include `` before any other wolfSSL headers. If building the sources directly we recommend defining `WOLFSSL_USER_SETTINGS` and adding your own `user_settings.h`. A reference is in `IDE/GCC-ARM/Header/user_settings.h`. diff --git a/wolfcrypt/src/port/st/stm32.c b/wolfcrypt/src/port/st/stm32.c index 6902039b6a7..5753a5ba132 100644 --- a/wolfcrypt/src/port/st/stm32.c +++ b/wolfcrypt/src/port/st/stm32.c @@ -39,6 +39,12 @@ #endif #endif +/* The CubeMX AES crypto-callback device needs cryptocb.h on any WOLF_CRYPTO_CB + * build, not only WOLFSSL_DHUK. */ +#if defined(WOLF_CRYPTO_CB) && !defined(WOLFSSL_DHUK) + #include +#endif + #ifdef NO_INLINE #include #else @@ -75,6 +81,9 @@ #elif defined(WOLFSSL_STM32U5) #include #include +#elif defined(WOLFSSL_STM32U3) +#include +#include #elif defined(WOLFSSL_STM32WB) #include #include @@ -5046,6 +5055,226 @@ void wc_Stm32_Aes_Cleanup(void) #endif /* WOLFSSL_STM32_BARE / WOLFSSL_STM32_CUBEMX / StdPeriph */ +/* CubeMX/HAL AES crypto-callback device -- makes WOLF_CRYPTO_CB_ONLY_AES work on + * the HAL build. That mode strips the software AES core and routes AES through + * the crypto callback; wc_AesGcmSetKey derives the GHASH subkey H via + * wc_CryptoCb_AesEcbEncrypt, so an AES-ECB handler is required just to key GCM. + * Providing it here lets AES-GCM be keyed, after which wc_AesGcmEncrypt runs on + * the native HAL GCM engine (wc_AesGcmEncrypt_STM32) via its CRYPTOCB_UNAVAILABLE + * fall-through. Uses the plaintext key on the Aes (aes->key) and the plain CRYP + * (AES/TinyAES) instance -- no DHUK/SAES. */ +#if defined(WOLFSSL_STM32_CUBEMX) && defined(WOLF_CRYPTO_CB) + +#if defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT) || \ + defined(WOLF_CRYPTO_CB_ONLY_AES) +/* One or more whole AES blocks through the HAL in ECB mode. enc != 0 selects + * encrypt. Mirrors the HAL ECB sequence in wc_AesEncrypt/wc_AesDecrypt (aes.c) + * that WOLF_CRYPTO_CB_ONLY_AES compiles out. */ +static int Stm32Cube_AesEcb(struct Aes* aes, byte* out, const byte* in, + word32 sz, int enc) +{ + CRYP_HandleTypeDef hcryp; + int ret; + + if (aes == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + if (sz == 0 || (sz % WC_AES_BLOCK_SIZE) != 0) { + return BAD_FUNC_ARG; + } + + ret = wc_Stm32_Aes_Init(aes, &hcryp, 0); + if (ret != 0) { + return ret; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret != 0) { + /* wc_Stm32_Aes_Init enabled the CRYP clock (STM32_HW_CLOCK_AUTO); + * release it before bailing out. */ + wc_Stm32_Aes_Cleanup(); + return ret; + } + +#if defined(STM32_HAL_V2) + hcryp.Init.Algorithm = CRYP_AES_ECB; +#elif defined(STM32_CRYPTO_AES_ONLY) + hcryp.Init.OperatingMode = enc ? + CRYP_ALGOMODE_ENCRYPT : CRYP_ALGOMODE_KEYDERIVATION_DECRYPT; + hcryp.Init.ChainingMode = CRYP_CHAINMODE_AES_ECB; + hcryp.Init.KeyWriteFlag = CRYP_KEY_WRITE_ENABLE; +#endif + if (HAL_CRYP_Init(&hcryp) != HAL_OK) { + wolfSSL_CryptHwMutexUnLock(); + wc_Stm32_Aes_Cleanup(); + return WC_HW_E; + } + +#if defined(STM32_HAL_V2) + if (enc) { + ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out, + STM32_HAL_TIMEOUT); + } + else { + ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out, + STM32_HAL_TIMEOUT); + } +#elif defined(STM32_CRYPTO_AES_ONLY) + ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, sz, out, STM32_HAL_TIMEOUT); +#else + if (enc) { + ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)in, sz, out, + STM32_HAL_TIMEOUT); + } + else { + ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)in, sz, out, + STM32_HAL_TIMEOUT); + } +#endif + if (ret != HAL_OK) { + /* Keep HAL_TIMEOUT distinct from HAL_ERROR/HAL_BUSY so callers and + * debugging can tell a real timeout from a HW fault. */ + ret = (ret == HAL_TIMEOUT) ? WC_TIMEOUT_E : WC_HW_E; + } + + HAL_CRYP_DeInit(&hcryp); + wolfSSL_CryptHwMutexUnLock(); + wc_Stm32_Aes_Cleanup(); + return ret; +} +#endif /* HAVE_AES_ECB || WOLFSSL_AES_DIRECT || WOLF_CRYPTO_CB_ONLY_AES */ + +/* Cipher dispatch (shared with the CCB device below). Services AES-ECB; other + * modes return CRYPTOCB_UNAVAILABLE so the caller falls through to the native + * HAL path (e.g. wc_AesGcmEncrypt_STM32) or another provider. */ +static int Stm32Cube_Cipher(struct wc_CryptoInfo* info) +{ + if (info == NULL) { + return CRYPTOCB_UNAVAILABLE; + } + + switch (info->cipher.type) { +#if defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT) || \ + defined(WOLF_CRYPTO_CB_ONLY_AES) + case WC_CIPHER_AES_ECB: + return Stm32Cube_AesEcb(info->cipher.aesecb.aes, + info->cipher.aesecb.out, info->cipher.aesecb.in, + info->cipher.aesecb.sz, info->cipher.enc); +#endif + default: + return CRYPTOCB_UNAVAILABLE; + } +} + +#if defined(WOLFSSL_STM32_PKA) && defined(HAVE_ECC) +/* HW ECDSA sign/verify via the STM32 PKA, dispatched through the crypto + * callback. Needed on CubeMX under WOLF_CRYPTO_CB_ONLY_ECC, where ecc.c compiles + * out the direct PKA path and routes ECDSA through the callback instead. The + * PKA workers (stm32_ecc_*_hash_ex) run on the HAL PKA driver; the application + * must provide/init the PKA (extern hpka + HAL_PKA_Init). */ +#if defined(HAVE_ECC_VERIFY) && !defined(WC_STM32_PKA_SIGN_ONLY) +static int Stm32Cube_EccVerify(struct wc_CryptoInfo* info) +{ + ecc_key* key = info->pk.eccverify.key; + mp_int r; + mp_int s; + int ret; + + if (key == NULL || info->pk.eccverify.sig == NULL || + info->pk.eccverify.res == NULL) { + return CRYPTOCB_UNAVAILABLE; + } + XMEMSET(&r, 0, sizeof(r)); + XMEMSET(&s, 0, sizeof(s)); + + /* DecodeECC_DSA_Sig() mp_init's r and s (mirrors the ecc.c verify path). */ + ret = DecodeECC_DSA_Sig(info->pk.eccverify.sig, + info->pk.eccverify.siglen, &r, &s); + if (ret == 0) { + ret = stm32_ecc_verify_hash_ex(&r, &s, info->pk.eccverify.hash, + info->pk.eccverify.hashlen, + info->pk.eccverify.res, key); + } + mp_free(&r); + mp_free(&s); + return ret; +} +#endif /* HAVE_ECC_VERIFY && !WC_STM32_PKA_SIGN_ONLY */ + +#if defined(HAVE_ECC_SIGN) && !defined(WC_STM32_PKA_VERIFY_ONLY) +static int Stm32Cube_EccSign(struct wc_CryptoInfo* info) +{ + ecc_key* key = info->pk.eccsign.key; + mp_int r; + mp_int s; + int ret; + + if (key == NULL) { + return CRYPTOCB_UNAVAILABLE; + } + XMEMSET(&r, 0, sizeof(r)); + XMEMSET(&s, 0, sizeof(s)); + ret = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL); + if (ret != 0) { + return ret; + } + ret = stm32_ecc_sign_hash_ex(info->pk.eccsign.in, info->pk.eccsign.inlen, + info->pk.eccsign.rng, key, &r, &s); + if (ret == 0) { + ret = StoreECC_DSA_Sig(info->pk.eccsign.out, info->pk.eccsign.outlen, + &r, &s); + } + mp_free(&r); + mp_free(&s); + return ret; +} +#endif /* HAVE_ECC_SIGN && !WC_STM32_PKA_VERIFY_ONLY */ +#endif /* WOLFSSL_STM32_PKA && HAVE_ECC */ + +/* Standalone AES(+PKA-ECC) device for CubeMX builds without the CCB/DHUK ECDSA + * device. Register at a devId, then wc_AesInit(aes, heap, devId). (With + * WOLFSSL_STM32_CCB the CCB device dispatches ciphers here too.) */ +static int Stm32Cube_AesCryptoDevCb(int devId, struct wc_CryptoInfo* info, + void* ctx) +{ + (void)devId; + (void)ctx; + + if (info == NULL) { + return CRYPTOCB_UNAVAILABLE; + } + if (info->algo_type == WC_ALGO_TYPE_CIPHER) { + return Stm32Cube_Cipher(info); + } +#if defined(WOLFSSL_STM32_PKA) && defined(HAVE_ECC) + if (info->algo_type == WC_ALGO_TYPE_PK) { +#if defined(HAVE_ECC_VERIFY) && !defined(WC_STM32_PKA_SIGN_ONLY) + if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { + return Stm32Cube_EccVerify(info); + } +#endif +#if defined(HAVE_ECC_SIGN) && !defined(WC_STM32_PKA_VERIFY_ONLY) + if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { + return Stm32Cube_EccSign(info); + } +#endif + } +#endif /* WOLFSSL_STM32_PKA && HAVE_ECC */ + return CRYPTOCB_UNAVAILABLE; +} + +int wc_Stm32_CubeAesRegister(int devId) +{ + return wc_CryptoCb_RegisterDevice(devId, Stm32Cube_AesCryptoDevCb, NULL); +} + +void wc_Stm32_CubeAesUnRegister(int devId) +{ + wc_CryptoCb_UnRegisterDevice(devId); +} + +#endif /* WOLFSSL_STM32_CUBEMX && WOLF_CRYPTO_CB */ + /* CubeMX/HAL CCB ECDSA port -- placed after the build-branch structure and * guarded on WOLFSSL_STM32_CUBEMX so it compiles only for the HAL build (the * BARE build provides its own wc_Stm32_Ccb_* above). */ @@ -5217,12 +5446,11 @@ int wc_Stm32_Ccb_EccSign(int curveId, const byte* iv, const byte* tag, } #if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) -/* CubeMX CCB crypto-callback device. Transparent DHUK AES/GMAC is bare-only, so - * under the HAL build the CCB-protected ECDSA sign is the only transparent DHUK - * operation. This minimal device routes WC_PK_TYPE_ECDSA_SIGN for a CCB key - * (key->dhuk_is_ccb) to the HAL CCB sign and returns the DER-encoded (r,s); it - * mirrors the bare-metal device's CCB branch so the same wc_ecc_sign_hash flow - * works on both build paths. */ +/* CubeMX/HAL crypto-callback device. Routes AES (Stm32Cube_Cipher), ECDSA sign + * (CCB key -> HAL_CCB; normal key -> HW PKA), ECDSA verify -> HW PKA, and CCB + * keygen -- giving full HW ECC + AES through the callback on the HAL build, so + * WOLF_CRYPTO_CB_ONLY_ECC / _AES work here as they do on the bare device. + * (Transparent DHUK-derived AES/GMAC remains bare-only.) */ static int Stm32Ccb_CryptoDevCb(int devId, struct wc_CryptoInfo* info, void* ctx) { @@ -5234,7 +5462,17 @@ static int Stm32Ccb_CryptoDevCb(int devId, struct wc_CryptoInfo* info, (void)devId; (void)ctx; - if (info == NULL || info->algo_type != WC_ALGO_TYPE_PK) { + if (info == NULL) { + return CRYPTOCB_UNAVAILABLE; + } + /* Route ciphers to the shared CubeMX AES handler so one devId serves both + * CCB ECDSA and HAL AES (lets WOLF_CRYPTO_CB_ONLY_AES work here). */ +#ifndef NO_AES + if (info->algo_type == WC_ALGO_TYPE_CIPHER) { + return Stm32Cube_Cipher(info); + } +#endif + if (info->algo_type != WC_ALGO_TYPE_PK) { return CRYPTOCB_UNAVAILABLE; } /* Transparent provisioning: wc_ecc_make_key() on a WC_DHUK_DEVID key binds @@ -5243,13 +5481,30 @@ static int Stm32Ccb_CryptoDevCb(int devId, struct wc_CryptoInfo* info, return wc_ecc_dev_make_key(info->pk.eckg.rng, info->pk.eckg.size, info->pk.eckg.key, info->pk.eckg.curveId); } +#if defined(WOLFSSL_STM32_PKA) && defined(HAVE_ECC_VERIFY) && \ + !defined(WC_STM32_PKA_SIGN_ONLY) + /* ECDSA verify -> HW PKA (public key). */ + if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { + return Stm32Cube_EccVerify(info); + } +#endif if (info->pk.type != WC_PK_TYPE_ECDSA_SIGN) { return CRYPTOCB_UNAVAILABLE; } key = info->pk.eccsign.key; - if (key == NULL || key->dhuk_is_ccb == 0u) { + if (key == NULL) { return CRYPTOCB_UNAVAILABLE; } + if (key->dhuk_is_ccb == 0u) { + /* Normal (non-CCB) key: HW PKA sign. */ +#if defined(WOLFSSL_STM32_PKA) && defined(HAVE_ECC_SIGN) && \ + !defined(WC_STM32_PKA_VERIFY_ONLY) + return Stm32Cube_EccSign(info); +#else + return CRYPTOCB_UNAVAILABLE; +#endif + } + /* CCB-protected key: scalar unwrapped SAES->PKA in HW, returns raw (r,s). */ sz = (word32)wc_ecc_size(key); ret = wc_Stm32_Ccb_EccSign(ECC_SECP256R1, key->ccb_iv, key->ccb_tag, key->dhuk_wrapped_priv, diff --git a/wolfssl/wolfcrypt/port/st/stm32.h b/wolfssl/wolfcrypt/port/st/stm32.h index 87faa30afcc..111674fc4b3 100644 --- a/wolfssl/wolfcrypt/port/st/stm32.h +++ b/wolfssl/wolfcrypt/port/st/stm32.h @@ -471,8 +471,11 @@ #endif #endif -/* HAL-legacy macros that the existing direct-register HASH path depends on. - * Without HAL these aren't otherwise visible. */ +/* HAL-legacy macros the direct-register HASH path depends on. ST's + * stm32XXxx_hal_hash.h also defines these HASH_ALGOSELECTION_* / HASH_ALGOMODE_* + * / HASH_DATATYPE_8B names, so each is wrapped in #ifndef: when the Cube HAL + * headers reach this TU (e.g. a Zephyr build) the HAL's copy wins (same register + * bits) instead of causing a redefinition; otherwise we define our own. */ #if defined(WOLFSSL_STM32H5) || defined(WOLFSSL_STM32MP13) || \ defined(WOLFSSL_STM32N6) || defined(WOLFSSL_STM32H7S) || \ defined(WOLFSSL_STM32U3) || defined(WOLFSSL_STM32C5) @@ -486,16 +489,30 @@ #define WC_STM32_HASH_INSTANCE_HRA #endif /* 4-bit ALGO field at bits 20:17 */ - #define HASH_ALGOSELECTION_SHA1 0u - #define HASH_ALGOSELECTION_SHA224 HASH_CR_ALGO_1 - #define HASH_ALGOSELECTION_SHA256 (HASH_CR_ALGO_0 | HASH_CR_ALGO_1) - #define HASH_ALGOSELECTION_SHA384 (HASH_CR_ALGO_2 | HASH_CR_ALGO_3) - #define HASH_ALGOSELECTION_SHA512 (HASH_CR_ALGO_0 | HASH_CR_ALGO_1 | \ - HASH_CR_ALGO_2 | HASH_CR_ALGO_3) - #define HASH_ALGOSELECTION_SHA512_224 (HASH_CR_ALGO_0 | HASH_CR_ALGO_2 | \ - HASH_CR_ALGO_3) - #define HASH_ALGOSELECTION_SHA512_256 (HASH_CR_ALGO_1 | HASH_CR_ALGO_2 | \ - HASH_CR_ALGO_3) + #ifndef HASH_ALGOSELECTION_SHA1 + #define HASH_ALGOSELECTION_SHA1 0u + #endif + #ifndef HASH_ALGOSELECTION_SHA224 + #define HASH_ALGOSELECTION_SHA224 HASH_CR_ALGO_1 + #endif + #ifndef HASH_ALGOSELECTION_SHA256 + #define HASH_ALGOSELECTION_SHA256 (HASH_CR_ALGO_0 | HASH_CR_ALGO_1) + #endif + #ifndef HASH_ALGOSELECTION_SHA384 + #define HASH_ALGOSELECTION_SHA384 (HASH_CR_ALGO_2 | HASH_CR_ALGO_3) + #endif + #ifndef HASH_ALGOSELECTION_SHA512 + #define HASH_ALGOSELECTION_SHA512 (HASH_CR_ALGO_0 | HASH_CR_ALGO_1 | \ + HASH_CR_ALGO_2 | HASH_CR_ALGO_3) + #endif + #ifndef HASH_ALGOSELECTION_SHA512_224 + #define HASH_ALGOSELECTION_SHA512_224 (HASH_CR_ALGO_0 | HASH_CR_ALGO_2 | \ + HASH_CR_ALGO_3) + #endif + #ifndef HASH_ALGOSELECTION_SHA512_256 + #define HASH_ALGOSELECTION_SHA512_256 (HASH_CR_ALGO_1 | HASH_CR_ALGO_2 | \ + HASH_CR_ALGO_3) + #endif #else /* Older HASH IP (F4/F7/L4 family) ALGO bit mapping (per HAL): * SHA1 = 0 @@ -503,49 +520,63 @@ * SHA224 = ALGO_1 * SHA256 = ALGO_0 | ALGO_1 */ - #define HASH_ALGOSELECTION_SHA1 0u - #define HASH_ALGOSELECTION_MD5 HASH_CR_ALGO_0 + #ifndef HASH_ALGOSELECTION_SHA1 + #define HASH_ALGOSELECTION_SHA1 0u + #endif + #ifndef HASH_ALGOSELECTION_MD5 + #define HASH_ALGOSELECTION_MD5 HASH_CR_ALGO_0 + #endif #ifdef HASH_CR_ALGO_1 - #define HASH_ALGOSELECTION_SHA224 HASH_CR_ALGO_1 - #define HASH_ALGOSELECTION_SHA256 (HASH_CR_ALGO_0 | HASH_CR_ALGO_1) + #ifndef HASH_ALGOSELECTION_SHA224 + #define HASH_ALGOSELECTION_SHA224 HASH_CR_ALGO_1 + #endif + #ifndef HASH_ALGOSELECTION_SHA256 + #define HASH_ALGOSELECTION_SHA256 (HASH_CR_ALGO_0 | HASH_CR_ALGO_1) + #endif #endif #endif /* Legacy CamelCase aliases */ -#ifdef HASH_ALGOSELECTION_SHA1 +#if defined(HASH_ALGOSELECTION_SHA1) && !defined(HASH_AlgoSelection_SHA1) #define HASH_AlgoSelection_SHA1 HASH_ALGOSELECTION_SHA1 #endif -#ifdef HASH_ALGOSELECTION_SHA224 +#if defined(HASH_ALGOSELECTION_SHA224) && !defined(HASH_AlgoSelection_SHA224) #define HASH_AlgoSelection_SHA224 HASH_ALGOSELECTION_SHA224 #endif -#ifdef HASH_ALGOSELECTION_SHA256 +#if defined(HASH_ALGOSELECTION_SHA256) && !defined(HASH_AlgoSelection_SHA256) #define HASH_AlgoSelection_SHA256 HASH_ALGOSELECTION_SHA256 #endif -#ifdef HASH_ALGOSELECTION_SHA384 +#if defined(HASH_ALGOSELECTION_SHA384) && !defined(HASH_AlgoSelection_SHA384) #define HASH_AlgoSelection_SHA384 HASH_ALGOSELECTION_SHA384 #endif -#ifdef HASH_ALGOSELECTION_SHA512 +#if defined(HASH_ALGOSELECTION_SHA512) && !defined(HASH_AlgoSelection_SHA512) #define HASH_AlgoSelection_SHA512 HASH_ALGOSELECTION_SHA512 #endif -#ifdef HASH_ALGOSELECTION_SHA512_224 +#if defined(HASH_ALGOSELECTION_SHA512_224) && \ + !defined(HASH_AlgoSelection_SHA512_224) #define HASH_AlgoSelection_SHA512_224 HASH_ALGOSELECTION_SHA512_224 #endif -#ifdef HASH_ALGOSELECTION_SHA512_256 +#if defined(HASH_ALGOSELECTION_SHA512_256) && \ + !defined(HASH_AlgoSelection_SHA512_256) #define HASH_AlgoSelection_SHA512_256 HASH_ALGOSELECTION_SHA512_256 #endif -#ifdef HASH_ALGOSELECTION_MD5 +#if defined(HASH_ALGOSELECTION_MD5) && !defined(HASH_AlgoSelection_MD5) #define HASH_AlgoSelection_MD5 HASH_ALGOSELECTION_MD5 #endif -#define HASH_ALGOMODE_HASH 0u -#ifdef HASH_CR_MODE - #define HASH_ALGOMODE_HMAC HASH_CR_MODE +#ifndef HASH_ALGOMODE_HASH + #define HASH_ALGOMODE_HASH 0u +#endif +#if defined(HASH_CR_MODE) && !defined(HASH_ALGOMODE_HMAC) + #define HASH_ALGOMODE_HMAC HASH_CR_MODE #endif /* Byte-stream input (auto byte-swap) */ -#ifdef HASH_CR_DATATYPE_1 - #define HASH_DATATYPE_8B HASH_CR_DATATYPE_1 -#elif defined(HASH_CR_DATATYPE_0) - #define HASH_DATATYPE_8B HASH_CR_DATATYPE_0 +#ifndef HASH_DATATYPE_8B + #ifdef HASH_CR_DATATYPE_1 + #define HASH_DATATYPE_8B HASH_CR_DATATYPE_1 + #elif defined(HASH_CR_DATATYPE_0) + #define HASH_DATATYPE_8B HASH_CR_DATATYPE_0 + #endif #endif #endif /* WOLFSSL_STM32_BARE */ @@ -969,6 +1000,18 @@ int stm32_ecc_sign_hash_ex(const byte* hash, word32 hashlen, struct WC_RNG* rng, void wc_Stm32_DhukUnRegister(int devId); #endif +/* CubeMX/HAL crypto-callback device. Register at a devId, then init an Aes + * with it (wc_AesInit) to run AES on the HAL through the crypto callback -- + * this makes WOLF_CRYPTO_CB_ONLY_AES work on the HAL build. When + * WOLFSSL_STM32_PKA && HAVE_ECC are also enabled it additionally routes ECDSA + * sign/verify to the HW PKA, so it satisfies WOLF_CRYPTO_CB_ONLY_ECC too (no + * CCB required). With WOLFSSL_STM32_CCB enabled, wc_Stm32_DhukRegister already + * covers AES + ECDSA (same devId). */ +#if defined(WOLFSSL_STM32_CUBEMX) && defined(WOLF_CRYPTO_CB) + int wc_Stm32_CubeAesRegister(int devId); + void wc_Stm32_CubeAesUnRegister(int devId); +#endif + /* CCB (Coupling and Chaining Bridge) HW-protected DHUK->PKA ECDSA -- STM32U3 * (e.g. U385). Available on both build paths: WOLFSSL_STM32_BARE (direct * register driver) and WOLFSSL_STM32_CUBEMX (ST HAL_CCB_* driver). The blob is