diff --git a/wolfcrypt/src/port/st/stm32.c b/wolfcrypt/src/port/st/stm32.c index 3879ba177..8c56e0f8d 100644 --- a/wolfcrypt/src/port/st/stm32.c +++ b/wolfcrypt/src/port/st/stm32.c @@ -1,6 +1,6 @@ /* stm32.c * - * Copyright (C) 2006-2021 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -43,12 +43,58 @@ #include #endif +#ifdef WOLFSSL_STM32_PKA +#include + +#if defined(WOLFSSL_STM32L5) +#include +#include +#elif defined(WOLFSSL_STM32U5) +#include +#include +#elif defined(WOLFSSL_STM32WB) +#include +#include +#elif defined(WOLFSSL_STM32WL) +#include +#include +#elif defined(WOLFSSL_STM32MP13) +#include +#include +#elif defined(WOLFSSL_STM32H7S) +#include +#include +#elif defined(WOLFSSL_STM32WBA) +#include +#include +#elif defined(WOLFSSL_STM32N6) +#include +#include +#else +#error Please add the hal_pk.h include +#endif +extern PKA_HandleTypeDef hpka; + +#if !defined(WOLFSSL_STM32_PKA_V2) && defined(PKA_ECC_SCALAR_MUL_IN_B_COEFF) +/* PKA hardware like in U5 added coefB and primeOrder */ +#define WOLFSSL_STM32_PKA_V2 +#endif + +#ifdef HAVE_ECC +#include + +#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV + /* FIPS build has replaced ecc.h. */ + #define wc_ecc_key_get_priv(key) (&((key)->k)) + #define WOLFSSL_HAVE_ECC_KEY_GET_PRIV +#endif +#endif /* HAVE_ECC */ +#endif /* WOLFSSL_STM32_PKA */ + #ifdef STM32_HASH -#ifdef WOLFSSL_STM32L4 - #define HASH_STR_NBW HASH_STR_NBLW -#endif +/* #define DEBUG_STM32_HASH */ /* User can override STM32_HASH_CLOCK_ENABLE and STM32_HASH_CLOCK_DISABLE */ #ifndef STM32_HASH_CLOCK_ENABLE @@ -77,8 +123,22 @@ #define STM32_HASH_CLOCK_DISABLE(ctx) wc_Stm32_Hash_Clock_Disable(ctx) #endif + /* STM32 Port Internal Functions */ -static WC_INLINE void wc_Stm32_Hash_SaveContext(STM32_HASH_Context* ctx) +static void wc_Stm32_Hash_NumValidBits(word32 len) +{ + /* calculate number of valid bits in last word */ + /* NBLW = 0x00 (all 32-bits are valid) */ + word32 nbvalidbytesdata = (len % STM32_HASH_REG_SIZE); + HASH->STR &= ~HASH_STR_NBW; + HASH->STR |= (8 * nbvalidbytesdata) & HASH_STR_NBW; + +#ifdef DEBUG_STM32_HASH + printf("STM Valid Last bits (%d)\n", 8 * nbvalidbytesdata); +#endif +} + +static void wc_Stm32_Hash_SaveContext(STM32_HASH_Context* ctx) { int i; @@ -86,20 +146,60 @@ static WC_INLINE void wc_Stm32_Hash_SaveContext(STM32_HASH_Context* ctx) ctx->HASH_IMR = HASH->IMR; ctx->HASH_STR = HASH->STR; ctx->HASH_CR = HASH->CR; +#ifdef STM32_HASH_SHA3 + ctx->SHA3CFGR = HASH->SHA3CFGR; +#endif for (i=0; iHASH_CSR[i] = HASH->CSR[i]; } + +#ifdef DEBUG_STM32_HASH + printf("STM Save CR %lx, IMR %lx, STR %lx\n", + HASH->CR, HASH->IMR, HASH->STR); +#endif } -static WC_INLINE int wc_Stm32_Hash_RestoreContext(STM32_HASH_Context* ctx) +static void wc_Stm32_Hash_RestoreContext(STM32_HASH_Context* ctx, int algo) { int i; - if (ctx->HASH_CR != 0) { + if (ctx->HASH_CR == 0) { + /* init content */ + + #if defined(HASH_IMR_DINIE) && defined(HASH_IMR_DCIE) + /* Disable IRQ's - wolfSSL does not use the HASH/RNG IRQ + * If using the HAL hashing API's directly it will re-enable the IRQs */ + HASH->IMR &= ~(HASH_IMR_DINIE | HASH_IMR_DCIE); + #endif + + /* reset the control register */ + HASH->CR &= ~(HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_DATATYPE + #ifdef HASH_CR_LKEY + | HASH_CR_LKEY + #endif + ); + + /* configure algorithm, mode and data type */ + HASH->CR |= (algo | HASH_ALGOMODE_HASH | HASH_DATATYPE_8B); + + /* reset HASH processor */ + HASH->CR |= HASH_CR_INIT; + + /* by default mark all bits valid */ + wc_Stm32_Hash_NumValidBits(0); + +#ifdef DEBUG_STM32_HASH + printf("STM Init algo %x\n", algo); +#endif + } + else { /* restore context registers */ HASH->IMR = ctx->HASH_IMR; HASH->STR = ctx->HASH_STR; HASH->CR = ctx->HASH_CR; +#ifdef STM32_HASH_SHA3 + HASH->SHA3CFGR = ctx->SHA3CFGR; +#endif /* Initialize the hash processor */ HASH->CR |= HASH_CR_INIT; @@ -108,46 +208,70 @@ static WC_INLINE int wc_Stm32_Hash_RestoreContext(STM32_HASH_Context* ctx) for (i=0; iCSR[i] = ctx->HASH_CSR[i]; } - return 1; + +#ifdef DEBUG_STM32_HASH + printf("STM Restore CR %lx, IMR %lx, STR %lx\n", + HASH->CR, HASH->IMR, HASH->STR); +#endif } - return 0; } -static WC_INLINE void wc_Stm32_Hash_GetDigest(byte* hash, int digestSize) +static void wc_Stm32_Hash_GetDigest(byte* hash, int digestSize) { word32 digest[HASH_MAX_DIGEST/sizeof(word32)]; + int i = 0, sz; - /* get digest result */ - digest[0] = HASH->HR[0]; - digest[1] = HASH->HR[1]; - digest[2] = HASH->HR[2]; - digest[3] = HASH->HR[3]; - if (digestSize >= 20) { - digest[4] = HASH->HR[4]; + if (digestSize > HASH_MAX_DIGEST) + digestSize = HASH_MAX_DIGEST; + + sz = digestSize; + while (sz > 0) { + /* first 20 bytes come from instance HR */ + if (i < 5) { + digest[i] = HASH->HR[i]; + } #ifdef HASH_DIGEST - if (digestSize >= 28) { - digest[5] = HASH_DIGEST->HR[5]; - digest[6] = HASH_DIGEST->HR[6]; - if (digestSize == 32) - digest[7] = HASH_DIGEST->HR[7]; + /* reset comes from HASH_DIGEST */ + else { + digest[i] = HASH_DIGEST->HR[i]; } #endif + i++; + sz -= 4; } ByteReverseWords(digest, digest, digestSize); XMEMCPY(hash, digest, digestSize); + +#ifdef DEBUG_STM32_HASH + { + word32 ii; + printf("STM Digest %d\n", digestSize); + for (ii=0; iiSR & HASH_SR_BUSY) && ++timeout < STM32_HASH_TIMEOUT) { + (void)stmCtx; + + /* wait until not busy and data input buffer ready */ + while ((HASH->SR & HASH_SR_BUSY) + #ifdef HASH_IMR_DCIE + && (HASH->SR & HASH_SR_DCIS) == 0 + #endif + && ++timeout < STM32_HASH_TIMEOUT) { + }; + +#ifdef DEBUG_STM32_HASH + printf("STM Wait Data %d, HASH->SR %lx\n", timeout, HASH->SR); +#endif - } /* verify timeout did not occur */ if (timeout >= STM32_HASH_TIMEOUT) { return WC_TIMEOUT_E; @@ -155,22 +279,80 @@ static WC_INLINE int wc_Stm32_Hash_WaitDone(void) return 0; } +static int wc_Stm32_Hash_WaitCalcComp(STM32_HASH_Context* stmCtx) +{ + int timeout = 0; + (void)stmCtx; + /* wait until not busy and hash digest calculation complete */ + while (((HASH->SR & HASH_SR_BUSY) + #ifdef HASH_IMR_DINIE + || (HASH->SR & HASH_SR_DINIS) == 0 + #endif + ) && ++timeout < STM32_HASH_TIMEOUT) { + }; + +#ifdef DEBUG_STM32_HASH + printf("STM Wait Calc %d, HASH->SR %lx\n", timeout, HASH->SR); +#endif + + /* verify timeout did not occur */ + if (timeout >= STM32_HASH_TIMEOUT) { + return WC_TIMEOUT_E; + } + return 0; +} + +static void wc_Stm32_Hash_Data(STM32_HASH_Context* stmCtx, word32 len) +{ + word32 i, blocks; + + if (len > stmCtx->buffLen) + len = stmCtx->buffLen; + + /* calculate number of 32-bit blocks - round up */ + blocks = ((len + STM32_HASH_REG_SIZE-1) / STM32_HASH_REG_SIZE); +#ifdef DEBUG_STM32_HASH + printf("STM DIN %d blocks\n", blocks); +#endif + for (i=0; ibuffer[i]); + #endif + HASH->DIN = stmCtx->buffer[i]; + } + stmCtx->loLen += len; /* total */ + stmCtx->buffLen -= len; + if (stmCtx->buffLen > 0) { + XMEMMOVE(stmCtx->buffer, (byte*)stmCtx->buffer+len, stmCtx->buffLen); + } +} + + +/* STM32 Port Exposed Functions */ void wc_Stm32_Hash_Init(STM32_HASH_Context* stmCtx) { /* clear context */ + /* this also gets called after finish */ XMEMSET(stmCtx, 0, sizeof(STM32_HASH_Context)); } int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo, - const byte* data, int len) + const byte* data, word32 len, word32 blockSize) { int ret = 0; byte* local = (byte*)stmCtx->buffer; int wroteToFifo = 0; + word32 chunkSz; + +#ifdef DEBUG_STM32_HASH + printf("STM Hash Update: algo %x, len %d, buffLen %d, fifoBytes %d\n", + algo, len, stmCtx->buffLen, stmCtx->fifoBytes); +#endif + (void)blockSize; /* check that internal buffLen is valid */ - if (stmCtx->buffLen >= STM32_HASH_REG_SIZE) { + if (stmCtx->buffLen > (word32)sizeof(stmCtx->buffer)) { return BUFFER_E; } @@ -178,36 +360,36 @@ int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo, STM32_HASH_CLOCK_ENABLE(stmCtx); /* restore hash context or init as new hash */ - if (wc_Stm32_Hash_RestoreContext(stmCtx) == 0) { - /* reset the control register */ - HASH->CR &= ~(HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); + wc_Stm32_Hash_RestoreContext(stmCtx, algo); - /* configure algorithm, mode and data type */ - HASH->CR |= (algo | HASH_ALGOMODE_HASH | HASH_DATATYPE_8B); - - /* reset HASH processor */ - HASH->CR |= HASH_CR_INIT; - } - - /* write 4-bytes at a time into FIFO */ + /* write blocks to FIFO */ while (len) { - word32 add = min(len, STM32_HASH_REG_SIZE - stmCtx->buffLen); + word32 add; + + chunkSz = blockSize; + /* fill the FIFO plus one additional to flush the first block */ + if (!stmCtx->fifoBytes) { + chunkSz += STM32_HASH_REG_SIZE; + } + + add = min(len, chunkSz - stmCtx->buffLen); XMEMCPY(&local[stmCtx->buffLen], data, add); stmCtx->buffLen += add; data += add; len -= add; - if (stmCtx->buffLen == STM32_HASH_REG_SIZE) { + if (stmCtx->buffLen == chunkSz) { + wc_Stm32_Hash_Data(stmCtx, stmCtx->buffLen); wroteToFifo = 1; - HASH->DIN = *(word32*)stmCtx->buffer; - - stmCtx->loLen += STM32_HASH_REG_SIZE; - stmCtx->buffLen = 0; + stmCtx->fifoBytes += chunkSz; } } if (wroteToFifo) { + /* make sure hash operation is done */ + ret = wc_Stm32_Hash_WaitDataReady(stmCtx); + /* save hash state for next operation */ wc_Stm32_Hash_SaveContext(stmCtx); } @@ -219,33 +401,35 @@ int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo, } int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, - byte* hash, int digestSize) + byte* hash, word32 digestSize) { int ret = 0; - word32 nbvalidbitsdata = 0; + +#ifdef DEBUG_STM32_HASH + printf("STM Hash Final: algo %x, digestSz %d, buffLen %d, fifoBytes %d\n", + algo, digestSize, stmCtx->buffLen, stmCtx->fifoBytes); +#endif /* turn on hash clock */ STM32_HASH_CLOCK_ENABLE(stmCtx); - /* restore hash state */ - wc_Stm32_Hash_RestoreContext(stmCtx); + /* restore hash context or init as new hash */ + wc_Stm32_Hash_RestoreContext(stmCtx, algo); /* finish reading any trailing bytes into FIFO */ if (stmCtx->buffLen > 0) { - HASH->DIN = *(word32*)stmCtx->buffer; - stmCtx->loLen += stmCtx->buffLen; + /* send remainder of data */ + wc_Stm32_Hash_Data(stmCtx, stmCtx->buffLen); } /* calculate number of valid bits in last word */ - nbvalidbitsdata = 8 * (stmCtx->loLen % STM32_HASH_REG_SIZE); - HASH->STR &= ~HASH_STR_NBW; - HASH->STR |= nbvalidbitsdata; + wc_Stm32_Hash_NumValidBits(stmCtx->loLen + stmCtx->buffLen); /* start hash processor */ HASH->STR |= HASH_STR_DCAL; /* wait for hash done */ - ret = wc_Stm32_Hash_WaitDone(); + ret = wc_Stm32_Hash_WaitCalcComp(stmCtx); if (ret == 0) { /* read message digest */ wc_Stm32_Hash_GetDigest(hash, digestSize); @@ -269,7 +453,9 @@ int wc_Stm32_Aes_Init(Aes* aes, CRYP_HandleTypeDef* hcryp) int ret; word32 keySize; - ret = wc_AesGetKeySize(aes, &keySize); + __HAL_RCC_CRYP_CLK_ENABLE(); + + ret = wc_AesGetKeySize(aes, &keySize); if (ret != 0) return ret; @@ -311,6 +497,8 @@ int wc_Stm32_Aes_Init(Aes* aes, CRYP_InitTypeDef* cryptInit, word32 keySize; word32* aes_key; + + ret = wc_AesGetKeySize(aes, &keySize); if (ret != 0) return ret; @@ -365,34 +553,22 @@ int wc_Stm32_Aes_Init(Aes* aes, CRYP_InitTypeDef* cryptInit, #endif /* STM32_CRYPTO */ #ifdef WOLFSSL_STM32_PKA -#include - -#if defined(WOLFSSL_STM32L5) -#include -#include -#else -#include -#include -#endif -extern PKA_HandleTypeDef hpka; /* Reverse array in memory (in place) */ #ifdef HAVE_ECC -#include /* convert from mp_int to STM32 PKA HAL integer, as array of bytes of size sz. - * if mp_int has less bytes than sz, add zero bytes at most significant byte positions. + * if mp_int has less bytes than sz, add zero bytes at most significant byte + * positions. * This is when for example modulus is 32 bytes (P-256 curve) * and mp_int has only 31 bytes, we add leading zeros * so that result array has 32 bytes, same as modulus (sz). */ static int stm32_get_from_mp_int(uint8_t *dst, const mp_int *a, int sz) { - int res; - int szbin; - int offset; + int res, szbin, offset; - if (a == NULL || dst == NULL || sz < 0) + if (dst == NULL || a == NULL || sz < 0) return BAD_FUNC_ARG; /* check how many bytes are in the mp_int */ @@ -416,221 +592,104 @@ static int stm32_get_from_mp_int(uint8_t *dst, const mp_int *a, int sz) return res; } -/* ECC specs in lsbyte at lowest address format for direct use by STM32_PKA PKHA driver functions */ -#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) -#define ECC192 -#endif -#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) -#define ECC224 -#endif -#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) -#define ECC256 -#endif -#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) -#define ECC384 -#endif +static int stm32_getabs_from_mp_int(uint8_t *dst, const mp_int *a, int sz, + uint32_t* abs_sign) +{ + int res; + mp_int x; -/* STM32 PKA supports up to 640bit numbers */ + if (dst == NULL || a == NULL || sz < 0 || abs_sign == NULL) + return BAD_FUNC_ARG; + + res = mp_init(&x); + if (res == MP_OKAY) { + /* make abs(x) and capture sign */ + #if defined(USE_FAST_MATH) || defined(USE_INTEGER_HEAP_MATH) || \ + ((defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \ + defined(WOLFSSL_SP_INT_NEGATIVE)) + *abs_sign = x.sign; + #else + *abs_sign = 1; /* default to negative */ + #endif + res = mp_abs((mp_int*)a, &x); + if (res == MP_OKAY) + res = stm32_get_from_mp_int(dst, &x, sz); + mp_clear(&x); + } + return res; +} + +/* convert hex string to unsigned char */ +static int stm32_getabs_from_hexstr(const char* hex, uint8_t* dst, int sz, + uint32_t *abs_sign) +{ + int res; + mp_int x; + + if (hex == NULL || dst == NULL || sz < 0) + return BAD_FUNC_ARG; + + res = mp_init(&x); + if (res == MP_OKAY) { + res = mp_read_radix(&x, hex, MP_RADIX_HEX); + /* optionally make abs(x) and capture sign */ + if (res == MP_OKAY && abs_sign != NULL) { + #if defined(USE_FAST_MATH) || defined(USE_INTEGER_HEAP_MATH) || \ + ((defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \ + defined(WOLFSSL_SP_INT_NEGATIVE)) + *abs_sign = x.sign; + #else + *abs_sign = 1; /* default to negative */ + #endif + res = mp_abs(&x, &x); + } + if (res == MP_OKAY) + res = stm32_get_from_mp_int(dst, &x, sz); + mp_clear(&x); + } + return res; +} +static int stm32_get_from_hexstr(const char* hex, uint8_t* dst, int sz) +{ + return stm32_getabs_from_hexstr(hex, dst, sz, NULL); +} + +/* STM32 PKA supports up to 640-bit numbers */ #define STM32_MAX_ECC_SIZE (80) - -/* P-192 */ -#ifdef ECC192 -#define ECC192_KEYSIZE (24) -static const uint8_t stm32_ecc192_prime[ECC192_KEYSIZE] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; -static const uint32_t stm32_ecc192_coef_sign = 1U; -static const uint8_t stm32_ecc192_coef[ECC192_KEYSIZE] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 -}; -static const uint8_t stm32_ecc192_pointX[ECC192_KEYSIZE] = { - 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, - 0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00, - 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12 -}; -static const uint8_t stm32_ecc192_pointY[ECC192_KEYSIZE] = { - 0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78, - 0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5, - 0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11 -}; -static const uint8_t stm32_ecc192_order[ECC192_KEYSIZE] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36, - 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31 -}; -#endif /* ECC192 */ - -/* P-224 */ -#ifdef ECC224 -#define ECC224_KEYSIZE (28) -static const uint8_t stm32_ecc224_prime[ECC224_KEYSIZE] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01 -}; -static const uint32_t stm32_ecc224_coef_sign = 1U; -static const uint8_t stm32_ecc224_coef[ECC224_KEYSIZE] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03 -}; -static const uint8_t stm32_ecc224_pointX[ECC224_KEYSIZE] = { - 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, - 0x32, 0x13, 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, - 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, - 0x11, 0x5C, 0x1D, 0x21 -}; -static const uint8_t stm32_ecc224_pointY[ECC224_KEYSIZE] = { - 0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB, - 0x4C, 0x22, 0xDF, 0xE6, 0xCD, 0x43, 0x75, 0xA0, - 0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99, - 0x85, 0x00, 0x7E, 0x34 -}; -static const uint8_t stm32_ecc224_order[ECC224_KEYSIZE] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2, - 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, - 0x5C, 0x5C, 0x2A, 0x3D -}; -#endif /* ECC224 */ - -/* P-256 */ -#ifdef ECC256 -#define ECC256_KEYSIZE (32) -static const uint8_t stm32_ecc256_prime[ECC256_KEYSIZE] = { - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; -static const uint32_t stm32_ecc256_coef_sign = 1U; -static const uint8_t stm32_ecc256_coef[ECC256_KEYSIZE] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 -}; -static const uint8_t stm32_ecc256_pointX[ECC256_KEYSIZE] = { - 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, - 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, - 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, - 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96 -}; -static const uint8_t stm32_ecc256_pointY[ECC256_KEYSIZE] = { - 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, - 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, - 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, - 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5 -}; -static const uint8_t stm32_ecc256_order[ECC256_KEYSIZE] = { - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, - 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51 -}; -#endif /* ECC256 */ - -/* P-384 */ -#ifdef ECC384 -#define ECC384_KEYSIZE (48) -static const uint8_t stm32_ecc384_prime[ECC384_KEYSIZE] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF -}; -static const uint32_t stm32_ecc384_coef_sign = 1U; -static const uint8_t stm32_ecc384_coef[ECC384_KEYSIZE] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 -}; -static const uint8_t stm32_ecc384_pointX[ECC384_KEYSIZE] = { - 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, - 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74, - 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, - 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, - 0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C, - 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, -}; -static const uint8_t stm32_ecc384_pointY[ECC384_KEYSIZE] = { - 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, - 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29, - 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, - 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, - 0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D, - 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F, -}; -static const uint8_t stm32_ecc384_order[ECC384_KEYSIZE] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, - 0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, - 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 -}; -#endif /* ECC384 */ - -static int stm32_get_ecc_specs(const uint8_t **prime, const uint8_t **coef, - const uint32_t **coef_sign, const uint8_t **GenPointX, const uint8_t **GenPointY, - const uint8_t **order, int size) +#ifdef WOLFSSL_STM32_PKA_V2 +/* find curve based on prime/modulus and return order/coefB */ +static int stm32_get_curve_params(mp_int* modulus, + uint8_t* order, uint8_t* coefB) { - switch(size) { - case 32: - *prime = stm32_ecc256_prime; - *coef = stm32_ecc256_coef; - *GenPointX = stm32_ecc256_pointX; - *GenPointY = stm32_ecc256_pointY; - *coef_sign = &stm32_ecc256_coef_sign; - if (order) *order = stm32_ecc256_order; - break; -#ifdef ECC224 - case 28: - *prime = stm32_ecc224_prime; - *coef = stm32_ecc224_coef; - *GenPointX = stm32_ecc224_pointX; - *GenPointY = stm32_ecc224_pointY; - *coef_sign = &stm32_ecc224_coef; - if (order) *order = stm32_ecc224_order; - break; -#endif -#ifdef ECC192 - case 24: - *prime = stm32_ecc192_prime; - *coef = stm32_ecc192_coef; - *GenPointX = stm32_ecc192_pointX; - *GenPointY = stm32_ecc192_pointY; - *coef_sign = &stm32_ecc192_coef; - if (order) *order = stm32_ecc192_order; - break; -#endif -#ifdef ECC384 - case 48: - *prime = stm32_ecc384_prime; - *coef = stm32_ecc384_coef; - *GenPointX = stm32_ecc384_pointX; - *GenPointY = stm32_ecc384_pointY; - *coef_sign = &stm32_ecc384_coef; - if (order) *order = stm32_ecc384_order; - break; -#endif - default: - return NOT_COMPILED_IN; + int res, i, found = 0; + mp_int modulusChk; + res = mp_init(&modulusChk); + if (res != MP_OKAY) + return res; + for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++) { + const ecc_set_type* curve = &ecc_sets[i]; + /* match based on curve prime */ + if ((res = mp_read_radix(&modulusChk, curve->prime, MP_RADIX_HEX)) == + MP_OKAY && (mp_cmp(modulus, &modulusChk) == MP_EQ)) + { + found = 1; + if (order) { + res = stm32_get_from_hexstr(curve->order, order, curve->size); + } + if (coefB) { + res = stm32_get_from_hexstr(curve->Bf, coefB, curve->size); + } + break; + } } - return 0; + mp_clear(&modulusChk); + if (!found && res == MP_OKAY) { + res = MP_RANGE; + } + return res; } +#endif /* WOLFSSL_STM32_PKA_V2 */ /** @@ -638,19 +697,22 @@ static int stm32_get_ecc_specs(const uint8_t **prime, const uint8_t **coef, k The scalar to multiply by G The base point R [out] Destination for kG + a ECC curve parameter a modulus The modulus of the field the ECC curve is in + order curve order + rng Random Generator struct (not used) map Boolean whether to map back to affine or not - (1==map, 0 == leave in projective) + (1==map, 0 == leave in projective) return MP_OKAY on success */ -int wc_ecc_mulmod_ex(const mp_int *k, ecc_point *G, ecc_point *R, mp_int* a, - mp_int *modulus, int map, void* heap) + +int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, + mp_int* modulus, mp_int* o, WC_RNG* rng, int map, + void* heap) { PKA_ECCMulInTypeDef pka_mul; PKA_ECCMulOutTypeDef pka_mul_res; - uint8_t size; int szModulus; - int szkbin; int status; int res; uint8_t Gxbin[STM32_MAX_ECC_SIZE]; @@ -658,10 +720,16 @@ int wc_ecc_mulmod_ex(const mp_int *k, ecc_point *G, ecc_point *R, mp_int* a, uint8_t kbin[STM32_MAX_ECC_SIZE]; uint8_t PtXbin[STM32_MAX_ECC_SIZE]; uint8_t PtYbin[STM32_MAX_ECC_SIZE]; - const uint8_t *prime, *coef, *gen_x, *gen_y; - const uint32_t *coef_sign; - (void)a; - (void)heap; + uint8_t prime[STM32_MAX_ECC_SIZE]; + uint8_t coefA[STM32_MAX_ECC_SIZE]; +#ifdef WOLFSSL_STM32_PKA_V2 + uint8_t coefB[STM32_MAX_ECC_SIZE]; + uint8_t order[STM32_MAX_ECC_SIZE]; +#endif + uint32_t coefA_sign = 1; + + (void)rng; + XMEMSET(&pka_mul, 0x00, sizeof(PKA_ECCMulInTypeDef)); XMEMSET(&pka_mul_res, 0x00, sizeof(PKA_ECCMulOutTypeDef)); pka_mul_res.ptX = PtXbin; @@ -672,43 +740,64 @@ int wc_ecc_mulmod_ex(const mp_int *k, ecc_point *G, ecc_point *R, mp_int* a, } szModulus = mp_unsigned_bin_size(modulus); - szkbin = mp_unsigned_bin_size(k); - res = stm32_get_from_mp_int(kbin, k, szkbin); + res = stm32_get_from_mp_int(kbin, k, szModulus); if (res == MP_OKAY) res = stm32_get_from_mp_int(Gxbin, G->x, szModulus); if (res == MP_OKAY) res = stm32_get_from_mp_int(Gybin, G->y, szModulus); - + if (res == MP_OKAY) + res = stm32_get_from_mp_int(prime, modulus, szModulus); + if (res == MP_OKAY) + res = stm32_getabs_from_mp_int(coefA, a, szModulus, &coefA_sign); +#ifdef WOLFSSL_STM32_PKA_V2 + XMEMSET(order, 0, sizeof(order)); + XMEMSET(coefB, 0, sizeof(coefB)); + if (res == MP_OKAY) { + if (o != NULL) { + /* use provided order and get coefB */ + res = stm32_get_from_mp_int(order, o, szModulus); + if (res == MP_OKAY) { + res = stm32_get_curve_params(modulus, NULL, coefB); + } + } + else { + /* get order and coefB for matching prime */ + res = stm32_get_curve_params(modulus, order, coefB); + } + } +#endif if (res != MP_OKAY) return res; - size = (uint8_t)szModulus; - /* find STM32_PKA friendly parameters for the selected curve */ - if (0 != stm32_get_ecc_specs(&prime, &coef, &coef_sign, &gen_x, &gen_y, NULL, size)) { - return ECC_BAD_ARG_E; - } - pka_mul.modulusSize = szModulus; - pka_mul.coefSign = *coef_sign; - pka_mul.coefA = coef; + pka_mul.coefSign = coefA_sign; + pka_mul.coefA = coefA; pka_mul.modulus = prime; pka_mul.pointX = Gxbin; pka_mul.pointY = Gybin; - pka_mul.scalarMulSize = size; + pka_mul.scalarMulSize = szModulus; pka_mul.scalarMul = kbin; +#ifdef WOLFSSL_STM32_PKA_V2 + pka_mul.coefB = coefB; + pka_mul.primeOrder = order; +#endif status = HAL_PKA_ECCMul(&hpka, &pka_mul, HAL_MAX_DELAY); if (status != HAL_OK) { + HAL_PKA_RAMReset(&hpka); return WC_HW_E; } pka_mul_res.ptX = Gxbin; pka_mul_res.ptY = Gybin; HAL_PKA_ECCMul_GetResult(&hpka, &pka_mul_res); - res = mp_read_unsigned_bin(R->x, Gxbin, size); + res = mp_read_unsigned_bin(R->x, Gxbin, szModulus); if (res == MP_OKAY) { - res = mp_read_unsigned_bin(R->y, Gybin, size); -#ifndef WOLFSSL_SP_MATH + res = mp_read_unsigned_bin(R->y, Gybin, szModulus); + +#if defined(USE_FAST_MATH) || defined(USE_INTEGER_HEAP_MATH) || \ + ((defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \ + defined(WOLFSSL_SP_INT_NEGATIVE)) /* if k is negative, we compute the multiplication with abs(-k) * with result (x, y) and modify the result to (x, -y) */ @@ -718,16 +807,16 @@ int wc_ecc_mulmod_ex(const mp_int *k, ecc_point *G, ecc_point *R, mp_int* a, if (res == MP_OKAY) res = mp_set(R->z, 1); HAL_PKA_RAMReset(&hpka); + + (void)heap; + return res; } -int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, - mp_int* modulus, mp_int* order, WC_RNG* rng, int map, - void* heap) +int wc_ecc_mulmod_ex(const mp_int *k, ecc_point *G, ecc_point *R, mp_int* a, + mp_int *modulus, int map, void* heap) { - (void)order; - (void)rng; - return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, heap); + return wc_ecc_mulmod_ex2(k, G, R, a, modulus, NULL, NULL, map, heap); } int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct) @@ -744,62 +833,81 @@ int stm32_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, word32 hashlen, int* res, ecc_key* key) { PKA_ECDSAVerifInTypeDef pka_ecc; - uint8_t size; - int szModulus; - int szrbin; + int size; int status; uint8_t Rbin[STM32_MAX_ECC_SIZE]; uint8_t Sbin[STM32_MAX_ECC_SIZE]; uint8_t Qxbin[STM32_MAX_ECC_SIZE]; uint8_t Qybin[STM32_MAX_ECC_SIZE]; uint8_t Hashbin[STM32_MAX_ECC_SIZE]; - uint8_t privKeybin[STM32_MAX_ECC_SIZE]; - const uint8_t *prime, *coef, *gen_x, *gen_y, *order; - const uint32_t *coef_sign; + uint8_t prime[STM32_MAX_ECC_SIZE]; + uint8_t coefA[STM32_MAX_ECC_SIZE]; + uint8_t gen_x[STM32_MAX_ECC_SIZE]; + uint8_t gen_y[STM32_MAX_ECC_SIZE]; + uint8_t order[STM32_MAX_ECC_SIZE]; + uint32_t coefA_sign = 1; + XMEMSET(&pka_ecc, 0x00, sizeof(PKA_ECDSAVerifInTypeDef)); - if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) { + if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL || + key->dp == NULL) { return ECC_BAD_ARG_E; } - *res = 0; + *res = 0; /* default to failure */ + size = wc_ecc_size(key); /* get key size in bytes */ - szModulus = mp_unsigned_bin_size(key->pubkey.x); - szrbin = mp_unsigned_bin_size(r); - - status = stm32_get_from_mp_int(Rbin, r, szrbin); + /* load R/S and public X/Y using key size */ + status = stm32_get_from_mp_int(Rbin, r, size); if (status == MP_OKAY) - status = stm32_get_from_mp_int(Sbin, s, szrbin); + status = stm32_get_from_mp_int(Sbin, s, size); if (status == MP_OKAY) - status = stm32_get_from_mp_int(Qxbin, key->pubkey.x, szModulus); + status = stm32_get_from_mp_int(Qxbin, key->pubkey.x, size); if (status == MP_OKAY) - status = stm32_get_from_mp_int(Qybin, key->pubkey.y, szModulus); - if (status == MP_OKAY) - status = stm32_get_from_mp_int(privKeybin, &key->k, szModulus); + status = stm32_get_from_mp_int(Qybin, key->pubkey.y, size); if (status != MP_OKAY) return status; - size = (uint8_t)szModulus; - /* find parameters for the selected curve */ - if (0 != stm32_get_ecc_specs(&prime, &coef, &coef_sign, &gen_x, &gen_y, &order, size)) { - return ECC_BAD_ARG_E; - } + /* find parameters for the selected curve */ + status = stm32_get_from_hexstr(key->dp->prime, prime, size); + if (status == MP_OKAY) + status = stm32_get_from_hexstr(key->dp->order, order, size); + if (status == MP_OKAY) + status = stm32_get_from_hexstr(key->dp->Gx, gen_x, size); + if (status == MP_OKAY) + status = stm32_get_from_hexstr(key->dp->Gy, gen_y, size); + if (status == MP_OKAY) + status = stm32_getabs_from_hexstr(key->dp->Af, coefA, size, &coefA_sign); + if (status != MP_OKAY) + return status; pka_ecc.primeOrderSize = size; pka_ecc.modulusSize = size; - pka_ecc.coefSign = *coef_sign; - pka_ecc.coef = coef; + pka_ecc.coefSign = coefA_sign; + pka_ecc.coef = coefA; pka_ecc.modulus = prime; pka_ecc.basePointX = gen_x; pka_ecc.basePointY = gen_y; pka_ecc.primeOrder = order; - pka_ecc.pPubKeyCurvePtX = Qxbin; pka_ecc.pPubKeyCurvePtY = Qybin; pka_ecc.RSign = Rbin; pka_ecc.SSign = Sbin; + XMEMSET(Hashbin, 0, STM32_MAX_ECC_SIZE); - XMEMCPY(Hashbin + (size - hashlen), hash, hashlen); + if (hashlen > STM32_MAX_ECC_SIZE) { + return ECC_BAD_ARG_E; + } + else if (hashlen > size) { + /* in the case that hashlen is larger than key size place hash at + * beginning of buffer */ + XMEMCPY(Hashbin, hash, size); + } + else { + /* in all other cases where hashlen is equal to or less than the key + * size pad the Hashbin buffer with leading zero's */ + XMEMCPY(Hashbin + (size - hashlen), hash, hashlen); + } pka_ecc.hash = Hashbin; status = HAL_PKA_ECDSAVerif(&hpka, &pka_ecc, HAL_MAX_DELAY); @@ -826,48 +934,87 @@ int stm32_ecc_sign_hash_ex(const byte* hash, word32 hashlen, WC_RNG* rng, uint8_t Rbin[STM32_MAX_ECC_SIZE]; uint8_t Sbin[STM32_MAX_ECC_SIZE]; uint8_t Hashbin[STM32_MAX_ECC_SIZE]; - const uint8_t *prime, *coef, *gen_x, *gen_y, *order; - const uint32_t *coef_sign; + uint8_t prime[STM32_MAX_ECC_SIZE]; + uint8_t coefA[STM32_MAX_ECC_SIZE]; +#ifdef WOLFSSL_STM32_PKA_V2 + uint8_t coefB[STM32_MAX_ECC_SIZE]; +#endif + uint8_t gen_x[STM32_MAX_ECC_SIZE]; + uint8_t gen_y[STM32_MAX_ECC_SIZE]; + uint8_t order[STM32_MAX_ECC_SIZE]; + uint32_t coefA_sign = 1; + XMEMSET(&pka_ecc, 0x00, sizeof(PKA_ECDSASignInTypeDef)); XMEMSET(&pka_ecc_out, 0x00, sizeof(PKA_ECDSASignOutTypeDef)); - if (r == NULL || s == NULL || hash == NULL || key == NULL) { + if (r == NULL || s == NULL || hash == NULL || key == NULL || + key->dp == NULL) { return ECC_BAD_ARG_E; } - mp_init(&gen_k); - mp_init(&order_mp); + size = wc_ecc_size(key); - size = mp_unsigned_bin_size(key->pubkey.x); - - status = stm32_get_from_mp_int(Keybin, &key->k, size); + /* find parameters for the selected curve */ + status = stm32_get_from_hexstr(key->dp->prime, prime, size); + if (status == MP_OKAY) + status = stm32_get_from_hexstr(key->dp->order, order, size); + if (status == MP_OKAY) + status = stm32_get_from_hexstr(key->dp->Gx, gen_x, size); + if (status == MP_OKAY) + status = stm32_get_from_hexstr(key->dp->Gy, gen_y, size); + if (status == MP_OKAY) + status = stm32_getabs_from_hexstr(key->dp->Af, coefA, size, &coefA_sign); +#ifdef WOLFSSL_STM32_PKA_V2 + if (status == MP_OKAY) + status = stm32_get_from_hexstr(key->dp->Bf, coefB, size); +#endif if (status != MP_OKAY) return status; - /* find parameters for the selected curve */ - if (0 != stm32_get_ecc_specs(&prime, &coef, &coef_sign, &gen_x, &gen_y, &order, size)) { - return ECC_BAD_ARG_E; - } - + /* generate random part of "k" */ + mp_init(&gen_k); + mp_init(&order_mp); status = mp_read_unsigned_bin(&order_mp, order, size); if (status == MP_OKAY) status = wc_ecc_gen_k(rng, size, &gen_k, &order_mp); if (status == MP_OKAY) status = stm32_get_from_mp_int(Intbin, &gen_k, size); + mp_clear(&gen_k); + mp_clear(&order_mp); + if (status != MP_OKAY) + return status; + + /* get private part of "k" */ + status = stm32_get_from_mp_int(Keybin, wc_ecc_key_get_priv(key), size); if (status != MP_OKAY) return status; pka_ecc.primeOrderSize = size; pka_ecc.modulusSize = size; - pka_ecc.coefSign = *coef_sign; - pka_ecc.coef = coef; + pka_ecc.coefSign = coefA_sign; + pka_ecc.coef = coefA; +#ifdef WOLFSSL_STM32_PKA_V2 + pka_ecc.coefB = coefB; +#endif pka_ecc.modulus = prime; pka_ecc.basePointX = gen_x; pka_ecc.basePointY = gen_y; pka_ecc.primeOrder = order; XMEMSET(Hashbin, 0, STM32_MAX_ECC_SIZE); - XMEMCPY(Hashbin + (size - hashlen), hash, hashlen); + if (hashlen > STM32_MAX_ECC_SIZE) { + return ECC_BAD_ARG_E; + } + else if (hashlen > size) { + /* in the case that hashlen is larger than key size place hash at + * beginning of buffer */ + XMEMCPY(Hashbin, hash, size); + } + else { + /* in all other cases where hashlen is equal to or less than the key + * size pad the Hashbin buffer with leading zero's */ + XMEMCPY(Hashbin + (size - hashlen), hash, hashlen); + } pka_ecc.hash = Hashbin; pka_ecc.integer = Intbin; pka_ecc.privateKey = Keybin; diff --git a/wolfssl/wolfcrypt/port/st/stm32.h b/wolfssl/wolfcrypt/port/st/stm32.h index 78112328b..40f76ac75 100644 --- a/wolfssl/wolfcrypt/port/st/stm32.h +++ b/wolfssl/wolfcrypt/port/st/stm32.h @@ -1,6 +1,6 @@ /* stm32.h * - * Copyright (C) 2006-2021 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -26,7 +26,7 @@ /* Supports CubeMX HAL or Standard Peripheral Library */ #include -#include +#include /* for MATH_INT_T */ #ifdef STM32_HASH @@ -35,10 +35,24 @@ #ifdef HASH_DIGEST /* The HASH_DIGEST register indicates SHA224/SHA256 support */ #define STM32_HASH_SHA2 - #define HASH_CR_SIZE 54 - #define HASH_MAX_DIGEST 32 + #if defined(WOLFSSL_STM32H5) || defined(WOLFSSL_STM32MP13) + #define HASH_CR_SIZE 103 + #define HASH_MAX_DIGEST 64 /* Up to SHA512 */ + #else + #define HASH_CR_SIZE 54 + #define HASH_MAX_DIGEST 32 + #endif + #if defined(WOLFSSL_STM32MP13) || defined(WOLFSSL_STM32H7S) + #define STM32_HASH_SHA512 + #define STM32_HASH_SHA512_224 + #define STM32_HASH_SHA512_256 + #define STM32_HASH_SHA384 + #endif + #if defined(WOLFSSL_STM32MP13) + #define STM32_HASH_SHA3 + #endif #else - #define HASH_CR_SIZE 50 + #define HASH_CR_SIZE 50 #define HASH_MAX_DIGEST 20 #endif @@ -46,11 +60,15 @@ #if !defined(HASH_ALGOMODE_HASH) && defined(HASH_AlgoMode_HASH) #define HASH_ALGOMODE_HASH HASH_AlgoMode_HASH #endif -#if !defined(HASH_DATATYPE_8B) && defined(HASH_DataType_8b) - #define HASH_DATATYPE_8B HASH_DataType_8b +#if !defined(HASH_DATATYPE_8B) + #if defined(HASH_DataType_8b) + #define HASH_DATATYPE_8B HASH_DataType_8b + #elif defined(HASH_BYTE_SWAP) + #define HASH_DATATYPE_8B HASH_BYTE_SWAP + #endif #endif #ifndef HASH_STR_NBW - #define HASH_STR_NBW HASH_STR_NBLW + #define HASH_STR_NBW HASH_STR_NBLW #endif #ifndef STM32_HASH_TIMEOUT @@ -60,6 +78,15 @@ /* STM32 register size in bytes */ #define STM32_HASH_REG_SIZE 4 +/* Maximum FIFO buffer is 64 bits for SHA256, 128 bits for SHA512 and 144 bits + * for SHA3 */ +#if defined(STM32_HASH_SHA3) + #define STM32_HASH_FIFO_SIZE 36 +#elif defined(STM32_HASH_SHA512) || defined(STM32_HASH_SHA384) + #define STM32_HASH_FIFO_SIZE 32 +#else + #define STM32_HASH_FIFO_SIZE 16 +#endif /* STM32 Hash Context */ typedef struct { @@ -68,53 +95,90 @@ typedef struct { uint32_t HASH_STR; uint32_t HASH_CR; uint32_t HASH_CSR[HASH_CR_SIZE]; +#ifdef STM32_HASH_SHA3 + uint32_t SHA3CFGR; +#endif /* Hash state / buffers */ - word32 buffer[STM32_HASH_REG_SIZE / sizeof(word32)]; /* partial word buffer */ + word32 buffer[STM32_HASH_FIFO_SIZE+1]; /* partial word buffer */ word32 buffLen; /* partial word remain */ word32 loLen; /* total update bytes (only lsb 6-bits is used for nbr valid bytes in last word) */ + word32 fifoBytes; /* number of currently filled FIFO bytes */ } STM32_HASH_Context; /* API's */ void wc_Stm32_Hash_Init(STM32_HASH_Context* stmCtx); int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo, - const byte* data, int len); + const byte* data, word32 len, word32 blockSize); int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, - byte* hash, int digestSize); + byte* hash, word32 digestSize); #endif /* STM32_HASH */ #ifdef STM32_CRYPTO +#if defined(WOLFSSL_STM32MP13) + #define RNG RNG1 + #define CRYP CRYP1 + #define hcryp hcryp1 + #define FORMAT_BIN RTC_FORMAT_BIN + #define __HAL_RCC_RNG_CLK_ENABLE __HAL_RCC_RNG1_CLK_ENABLE + #define __HAL_RCC_HASH_CLK_ENABLE __HAL_RCC_HASH1_CLK_ENABLE + #define __HAL_RCC_HASH_CLK_DISABLE __HAL_RCC_HASH1_CLK_DISABLE + /* From stm32_hal_legacy.h, but that header has a bug in it */ + #define HASH_AlgoSelection_MD5 HASH_ALGOSELECTION_MD5 + #define HASH_AlgoSelection_SHA1 HASH_ALGOSELECTION_SHA1 + #define HASH_AlgoSelection_SHA224 HASH_ALGOSELECTION_SHA224 + #define HASH_AlgoSelection_SHA256 HASH_ALGOSELECTION_SHA256 + + #define STM32_NOMD5 /* The HASH HAL has no MD5 implementation */ +#endif + #ifndef NO_AES #if !defined(STM32_CRYPTO_AES_GCM) && (defined(WOLFSSL_STM32F4) || \ defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32L4) || \ - defined(WOLFSSL_STM32L5) || defined(WOLFSSL_STM32H7)) + defined(WOLFSSL_STM32L5) || defined(WOLFSSL_STM32H7) || \ + defined(WOLFSSL_STM32U5) || defined(WOLFSSL_STM32H5) || \ + defined(WOLFSSL_STM32MP13) || defined(WOLFSSL_STM32H7S) || \ + defined(WOLFSSL_STM32N6)) /* Hardware supports AES GCM acceleration */ #define STM32_CRYPTO_AES_GCM #endif - #if defined(WOLFSSL_STM32WB) + #if defined(WOLFSSL_STM32WB) || defined(WOLFSSL_STM32WL) || \ + defined(WOLFSSL_STM32WBA) #define STM32_CRYPTO_AES_ONLY /* crypto engine only supports AES */ - #define CRYP AES1 + #ifdef WOLFSSL_STM32WB + #define CRYP AES1 + #else + #define CRYP AES + #endif #define STM32_HAL_V2 #endif - #if defined(WOLFSSL_STM32L4) || defined(WOLFSSL_STM32L5) - #ifdef WOLFSSL_STM32L4 - #define STM32_CRYPTO_AES_ONLY /* crypto engine only supports AES */ - #endif + #if defined(WOLFSSL_STM32L4) || defined(WOLFSSL_STM32L5) || \ + defined(WOLFSSL_STM32U5) || defined(WOLFSSL_STM32H5) + #if defined(WOLFSSL_STM32L4) || defined(WOLFSSL_STM32U5) + #define STM32_CRYPTO_AES_ONLY /* crypto engine only supports AES */ + #endif + #if defined(WOLFSSL_STM32H5) + #define __HAL_RCC_CRYP_CLK_DISABLE __HAL_RCC_AES_CLK_DISABLE + #define __HAL_RCC_CRYP_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE + #endif #define CRYP AES - #ifndef CRYP_AES_GCM - #define CRYP_AES_GCM CRYP_AES_GCM_GMAC - #endif + #ifndef CRYP_AES_GCM + #define CRYP_AES_GCM CRYP_AES_GCM_GMAC + #endif #endif /* Detect newer CubeMX crypto HAL (HAL_CRYP_Encrypt / HAL_CRYP_Decrypt) */ #if !defined(STM32_HAL_V2) && defined(CRYP_AES_GCM) && \ - (defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32L5) || defined(WOLFSSL_STM32H7)) + (defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32L5) || \ + defined(WOLFSSL_STM32H7) || defined(WOLFSSL_STM32U5) || \ + defined(WOLFSSL_STM32H5) || defined(WOLFSSL_STM32MP13) || \ + defined(WOLFSSL_STM32H7S) || defined(WOLFSSL_STM32N6)) #define STM32_HAL_V2 #endif @@ -125,31 +189,34 @@ int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, #define STM_CRYPT_TYPE uint8_t #endif + /* Determine minimum AES GCM alignment supported */ + #ifndef STM_CRYPT_HEADER_WIDTH + /* newer crypt HAL requires auth header size as 4 bytes (word) */ + #if defined(CRYP_HEADERWIDTHUNIT_BYTE) && \ + !defined(WOLFSSL_STM32MP13) && !defined(WOLFSSL_STM32H7S) + #define STM_CRYPT_HEADER_WIDTH 1 + #else + #define STM_CRYPT_HEADER_WIDTH 4 + #endif + #endif + /* CRYPT_AES_GCM starts the IV with 2 */ #define STM32_GCM_IV_START 2 struct Aes; #ifdef WOLFSSL_STM32_CUBEMX int wc_Stm32_Aes_Init(struct Aes* aes, CRYP_HandleTypeDef* hcryp); + void wc_Stm32_Aes_Cleanup(void); #else /* Standard Peripheral Library */ int wc_Stm32_Aes_Init(struct Aes* aes, CRYP_InitTypeDef* cryptInit, CRYP_KeyInitTypeDef* keyInit); + void wc_Stm32_Aes_Cleanup(void); #endif /* WOLFSSL_STM32_CUBEMX */ #endif /* !NO_AES */ #endif /* STM32_CRYPTO */ #if defined(WOLFSSL_STM32_PKA) && defined(HAVE_ECC) -#ifdef WOLFSSL_SP_MATH - struct sp_int; - #define MATH_INT_T struct sp_int -#elif defined(USE_FAST_MATH) - struct fp_int; - #define MATH_INT_T struct fp_int -#else - struct mp_int; - #define MATH_INT_T struct mp_int -#endif struct ecc_key; struct WC_RNG;