diff --git a/wolfcrypt/src/port/st/stm32.c b/wolfcrypt/src/port/st/stm32.c index 4f8d651ed4..aedef554c8 100644 --- a/wolfcrypt/src/port/st/stm32.c +++ b/wolfcrypt/src/port/st/stm32.c @@ -137,6 +137,9 @@ static 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]; } @@ -184,6 +187,9 @@ static void wc_Stm32_Hash_RestoreContext(STM32_HASH_Context* ctx, int algo) 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; @@ -329,11 +335,11 @@ int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo, while (len) { word32 add; - /* fill the FIFO plus one additional to flush the block */ - chunkSz = ((STM32_HASH_FIFO_SIZE + 1) * STM32_HASH_REG_SIZE); - /* account for extra bytes in the FIFO (use mask 0x3F to get remain) */ - chunkSz -= (stmCtx->fifoBytes & - ((STM32_HASH_FIFO_SIZE * STM32_HASH_REG_SIZE)-1)); + 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); diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index c40afbd909..f6b8c2f03f 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -299,7 +299,7 @@ void BlockSha3(word64* s) */ #define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n)))) - +#if !defined(STM32_HASH_SHA3) /* An array of values to XOR for block operation. */ static const word64 hash_keccak_r[24] = { @@ -316,6 +316,7 @@ static const word64 hash_keccak_r[24] = W64LIT(0x8000000080008081), W64LIT(0x8000000000008080), W64LIT(0x0000000080000001), W64LIT(0x8000000080008008) }; +#endif /* Indices used in swap and rotate operation. */ #define KI_0 6 @@ -533,6 +534,7 @@ do { \ while (0) #endif /* SHA3_BY_SPEC */ +#if !defined(STM32_HASH_SHA3) /* The block operation performed on the state. * * s The state. @@ -562,8 +564,10 @@ void BlockSha3(word64* s) } } #endif /* WOLFSSL_SHA3_SMALL */ +#endif /* STM32_HASH_SHA3 */ #endif /* !WOLFSSL_ARMASM && !WOLFSSL_RISCV_ASM */ +#if !defined(STM32_HASH_SHA3) static WC_INLINE word64 Load64Unaligned(const unsigned char *a) { return ((word64)a[0] << 0) | @@ -617,6 +621,7 @@ static word64 Load64BitBigEndian(const byte* a) * sha3 wc_Sha3 object holding state. * returns 0 on success. */ + static int InitSha3(wc_Sha3* sha3) { int i; @@ -797,6 +802,84 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, word32 l) return 0; } +#endif +#if defined(STM32_HASH_SHA3) + + /* Supports CubeMX HAL or Standard Peripheral Library */ + + static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId) + { + if (sha3 == NULL) + return BAD_FUNC_ARG; + + (void)devId; + (void)heap; + + XMEMSET(sha3, 0, sizeof(wc_Sha3)); + wc_Stm32_Hash_Init(&sha3->stmCtx); + return 0; + } + + static int Stm32GetAlgo(byte p) + { + switch(p) { + case WC_SHA3_224_COUNT: + return HASH_ALGOSELECTION_SHA3_224; + case WC_SHA3_256_COUNT: + return HASH_ALGOSELECTION_SHA3_256; + case WC_SHA3_384_COUNT: + return HASH_ALGOSELECTION_SHA3_384; + case WC_SHA3_512_COUNT: + return HASH_ALGOSELECTION_SHA3_512; + } + /* Should never get here */ + return WC_SHA3_224_COUNT; + } + + static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) + { + int ret = 0; + + if (sha3 == NULL) { + return BAD_FUNC_ARG; + } + if (data == NULL && len == 0) { + /* valid, but do nothing */ + return 0; + } + if (data == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&sha3->stmCtx, + Stm32GetAlgo(p), data, len, p * 8); + wolfSSL_CryptHwMutexUnLock(); + } + return ret; + } + + static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) + { + int ret = 0; + + if (sha3 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&sha3->stmCtx, + Stm32GetAlgo(p), hash, len); + wolfSSL_CryptHwMutexUnLock(); + } + + (void)wc_InitSha3(sha3, NULL, 0); /* reset state */ + + return ret; + } +#else /* Initialize the state for a SHA-3 hash operation. * @@ -944,7 +1027,7 @@ static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) return InitSha3(sha3); /* reset state */ } - +#endif /* Dispose of any dynamically allocated data from the SHA3-384 operation. * (Required for async ops.) * diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 7f3e745c60..16c3c0f204 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -219,6 +219,66 @@ { se050_hash_free(&sha512->se050Ctx); } +#elif defined(STM32_HASH_SHA512) + + /* Supports CubeMX HAL or Standard Peripheral Library */ + + int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId) + { + if (sha512 == NULL) + return BAD_FUNC_ARG; + + (void)devId; + (void)heap; + + XMEMSET(sha512, 0, sizeof(wc_Sha512)); + wc_Stm32_Hash_Init(&sha512->stmCtx); + return 0; + } + + int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) + { + int ret = 0; + + if (sha512 == NULL) { + return BAD_FUNC_ARG; + } + if (data == NULL && len == 0) { + /* valid, but do nothing */ + return 0; + } + if (data == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&sha512->stmCtx, + HASH_ALGOSELECTION_SHA512, data, len, WC_SHA512_BLOCK_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } + return ret; + } + + int wc_Sha512Final(wc_Sha512* sha512, byte* hash) + { + int ret = 0; + + if (sha512 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&sha512->stmCtx, + HASH_ALGOSELECTION_SHA512, hash, WC_SHA512_DIGEST_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } + + (void)wc_InitSha512(sha512); /* reset state */ + + return ret; + } #else @@ -1174,7 +1234,7 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) #elif defined(MAX3266X_SHA) /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ - +#elif defined(STM32_HASH_SHA512) #else static WC_INLINE int Sha512Final(wc_Sha512* sha512) @@ -1337,7 +1397,7 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512) #elif defined(MAX3266X_SHA) /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ - +#elif defined(STM32_HASH_SHA512) #else static int Sha512FinalRaw(wc_Sha512* sha512, byte* hash, size_t digestSz) @@ -1407,10 +1467,12 @@ static int Sha512_Family_Final(wc_Sha512* sha512, byte* hash, size_t digestSz, return initfp(sha512); } +#ifndef STM32_HASH_SHA512 int wc_Sha512Final(wc_Sha512* sha512, byte* hash) { return Sha512_Family_Final(sha512, hash, WC_SHA512_DIGEST_SIZE, InitSha512); } +#endif #endif /* WOLFSSL_KCAPI_HASH */ @@ -1592,6 +1654,64 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) #elif defined(MAX3266X_SHA) /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ +#elif defined(STM32_HASH_SHA384) + + int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId) + { + if (sha384 == NULL) + return BAD_FUNC_ARG; + + (void)devId; + (void)heap; + + XMEMSET(sha384, 0, sizeof(wc_Sha384)); + wc_Stm32_Hash_Init(&sha384->stmCtx); + return 0; + } + + int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len) + { + int ret = 0; + + if (sha384 == NULL) { + return BAD_FUNC_ARG; + } + if (data == NULL && len == 0) { + /* valid, but do nothing */ + return 0; + } + if (data == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&sha384->stmCtx, + HASH_ALGOSELECTION_SHA384, data, len, WC_SHA384_BLOCK_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } + return ret; + } + + int wc_Sha384Final(wc_Sha384* sha384, byte* hash) + { + int ret = 0; + + if (sha384 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&sha384->stmCtx, + HASH_ALGOSELECTION_SHA384, hash, WC_SHA384_DIGEST_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } + + (void)wc_InitSha384(sha384); /* reset state */ + + return ret; + } #else @@ -2011,17 +2131,75 @@ int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags) #if !defined(WOLFSSL_NOSHA512_224) && \ (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) +#if defined(STM32_HASH_SHA512_224) +int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId) +{ + if (sha512 == NULL) + return BAD_FUNC_ARG; + + (void)devId; + (void)heap; + + XMEMSET(sha512, 0, sizeof(wc_Sha512)); + wc_Stm32_Hash_Init(&sha512->stmCtx); + return 0; +} + +int wc_Sha512_224Update(wc_Sha512* sha512, const byte* data, word32 len) +{ + int ret = 0; + + if (sha512 == NULL) { + return BAD_FUNC_ARG; + } + if (data == NULL && len == 0) { + /* valid, but do nothing */ + return 0; + } + if (data == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&sha512->stmCtx, + HASH_ALGOSELECTION_SHA512_224, data, len, WC_SHA512_224_BLOCK_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } + return ret; +} + +int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash) +{ + int ret = 0; + + if (sha512 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&sha512->stmCtx, + HASH_ALGOSELECTION_SHA512_224, hash, WC_SHA512_224_DIGEST_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } + + (void)wc_InitSha512_224(sha512); /* reset state */ + + return ret; +} +#endif int wc_InitSha512_224(wc_Sha512* sha) { return wc_InitSha512_224_ex(sha, NULL, INVALID_DEVID); } - +#if !defined(STM32_HASH_SHA512_224) int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len) { return wc_Sha512Update(sha, data, len); } - +#endif #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ #elif defined(WOLFSSL_RENESAS_RSIP) && \ @@ -2029,6 +2207,7 @@ int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len) /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ #elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) +#elif defined(STM32_HASH_SHA512_224) #else int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash) @@ -2091,16 +2270,75 @@ int wc_Sha512_224Transform(wc_Sha512* sha, const unsigned char* data) #if !defined(WOLFSSL_NOSHA512_256) && \ (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST) +#if defined(STM32_HASH_SHA512_256) + int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId) + { + if (sha512 == NULL) + return BAD_FUNC_ARG; + + (void)devId; + (void)heap; + + XMEMSET(sha512, 0, sizeof(wc_Sha512)); + wc_Stm32_Hash_Init(&sha512->stmCtx); + return 0; + } + + int wc_Sha512_256Update(wc_Sha512* sha512, const byte* data, word32 len) + { + int ret = 0; + + if (sha512 == NULL) { + return BAD_FUNC_ARG; + } + if (data == NULL && len == 0) { + /* valid, but do nothing */ + return 0; + } + if (data == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&sha512->stmCtx, + HASH_ALGOSELECTION_SHA512_256, data, len, WC_SHA512_256_BLOCK_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } + return ret; + } + + int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash) + { + int ret = 0; + + if (sha512 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&sha512->stmCtx, + HASH_ALGOSELECTION_SHA512_256, hash, WC_SHA512_256_DIGEST_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } + + (void)wc_InitSha512_256(sha512); /* reset state */ + + return ret; + } +#endif int wc_InitSha512_256(wc_Sha512* sha) { return wc_InitSha512_256_ex(sha, NULL, INVALID_DEVID); } - +#if !defined(STM32_HASH_SHA512_256) int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len) { return wc_Sha512Update(sha, data, len); } +#endif #if defined(WOLFSSL_KCAPI_HASH) /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */ #elif defined(WOLFSSL_RENESAS_RSIP) && \ @@ -2108,7 +2346,7 @@ int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len) /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ #elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) - +#elif defined(STM32_HASH_SHA512_256) #else int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash) { @@ -2176,6 +2414,7 @@ int wc_Sha512_256Transform(wc_Sha512* sha, const unsigned char* data) /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */ #elif defined(MAX3266X_SHA) /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ + #else int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash) diff --git a/wolfssl/wolfcrypt/port/st/stm32.h b/wolfssl/wolfcrypt/port/st/stm32.h index 6b8d76186f..0ff65fa7f1 100644 --- a/wolfssl/wolfcrypt/port/st/stm32.h +++ b/wolfssl/wolfcrypt/port/st/stm32.h @@ -35,13 +35,20 @@ #ifdef HASH_DIGEST /* The HASH_DIGEST register indicates SHA224/SHA256 support */ #define STM32_HASH_SHA2 - #if defined(WOLFSSL_STM32H5) + #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) + #define STM32_HASH_SHA512 + #define STM32_HASH_SHA512_224 + #define STM32_HASH_SHA512_256 + #define STM32_HASH_SHA384 + #define STM32_HASH_SHA3 + #endif #else #define HASH_CR_SIZE 50 #define HASH_MAX_DIGEST 20 @@ -69,7 +76,15 @@ /* STM32 register size in bytes */ #define STM32_HASH_REG_SIZE 4 -#define STM32_HASH_FIFO_SIZE 16 /* FIFO is 16 deep 32-bits wide */ +/* 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 { @@ -78,6 +93,9 @@ 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_FIFO_SIZE+1]; /* partial word buffer */ @@ -112,7 +130,6 @@ int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, #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 */ diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index f65c41d322..5e733a10e9 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -45,6 +45,10 @@ #include #endif +#ifdef STM32_HASH + #include +#endif + /* in bytes */ enum { /* SHAKE-128 */ @@ -140,6 +144,9 @@ struct wc_Sha3 { #ifdef WOLFSSL_HASH_FLAGS word32 flags; /* enum wc_HashFlags in hash.h */ #endif +#if defined(STM32_HASH_SHA3) + STM32_HASH_Context stmCtx; +#endif }; #ifndef WC_SHA3_TYPE_DEFINED diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index e971a8df13..cfc357ff1f 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -73,6 +73,10 @@ #include "fsl_caam.h" #endif +#ifdef STM32_HASH + #include +#endif + #if defined(_MSC_VER) #define SHA512_NOINLINE __declspec(noinline) #elif defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) @@ -202,6 +206,9 @@ struct wc_Sha512 { #ifdef HAVE_ARIA MC_HSESSION hSession; #endif +#if defined(STM32_HASH_SHA512) + STM32_HASH_Context stmCtx; +#endif #endif /* WOLFSSL_PSOC6_CRYPTO */ };