diff --git a/wolfcrypt/src/md5.c b/wolfcrypt/src/md5.c index ab710aa9e..5754fa983 100644 --- a/wolfcrypt/src/md5.c +++ b/wolfcrypt/src/md5.c @@ -46,157 +46,58 @@ #endif -static INLINE void AddLength(wc_Md5* md5, word32 len); - /* Hardware Acceleration */ #if defined(STM32_HASH) - /* - * STM32F2/F4/F7 hardware MD5 support through the HASH_* API's from the - * Standard Peripheral Library or CubeMX (See note in README). - */ - + /* Supports CubeMX HAL or Standard Peripheral Library */ + #include #define HAVE_MD5_CUST_API - /* STM32 register size, bytes */ - #ifdef WOLFSSL_STM32_CUBEMX - #define MD5_REG_SIZE WC_MD5_BLOCK_SIZE - #else - #define MD5_REG_SIZE 4 - /* STM32 struct notes: - * md5->buffer = first 4 bytes used to hold partial block if needed - * md5->buffLen = num bytes currently stored in md5->buffer - * md5->loLen = num bytes that have been written to STM32 FIFO - */ - #endif - #define MD5_HW_TIMEOUT 0xFF - int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId) { - if (md5 == NULL) + if (md5 == NULL) { return BAD_FUNC_ARG; - - (void)heap; - (void)devId; - - md5->heap = heap; - XMEMSET(md5->buffer, 0, sizeof(md5->buffer)); - md5->buffLen = 0; - md5->loLen = 0; - md5->hiLen = 0; - - /* initialize HASH peripheral */ - #ifdef WOLFSSL_STM32_CUBEMX - HAL_HASH_DeInit(&md5->hashHandle); - md5->hashHandle.Init.DataType = HASH_DATATYPE_8B; - if (HAL_HASH_Init(&md5->hashHandle) != HAL_OK) { - return ASYNC_INIT_E; } - /* reset the hash control register */ - /* required because Cube MX is not clearing algo bits */ - HASH->CR &= ~HASH_CR_ALGO; - #else - HASH_DeInit(); - /* reset the control register */ - HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); + (void)devId; + (void)heap; - /* configure algo used, algo mode, datatype */ - HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HASH - | HASH_DataType_8b); - - /* reset HASH processor */ - HASH->CR |= HASH_CR_INIT; - #endif + wc_Stm32_Hash_Init(&md5->stmCtx); return 0; } int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len) { - int ret = 0; - byte* local; + int ret; if (md5 == NULL || (data == NULL && len > 0)) { return BAD_FUNC_ARG; } - /* do block size increments */ - local = (byte*)md5->buffer; - - /* check that internal buffLen is valid */ - if (md5->buffLen >= MD5_REG_SIZE) - return BUFFER_E; - - while (len) { - word32 add = min(len, MD5_REG_SIZE - md5->buffLen); - XMEMCPY(&local[md5->buffLen], data, add); - - md5->buffLen += add; - data += add; - len -= add; - - if (md5->buffLen == MD5_REG_SIZE) { - #ifdef WOLFSSL_STM32_CUBEMX - if (HAL_HASH_MD5_Accumulate( - &md5->hashHandle, local, MD5_REG_SIZE) != HAL_OK) { - ret = ASYNC_OP_E; - } - #else - HASH_DataIn(*(uint32_t*)local); - #endif - - AddLength(md5, MD5_REG_SIZE); - md5->buffLen = 0; - } + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&md5->stmCtx, HASH_AlgoSelection_MD5, + data, len); + wolfSSL_CryptHwMutexUnLock(); } return ret; } int wc_Md5Final(wc_Md5* md5, byte* hash) { - int ret = 0; + int ret; - if (md5 == NULL || hash == NULL) + if (md5 == NULL || hash == NULL) { return BAD_FUNC_ARG; - - #ifdef WOLFSSL_STM32_CUBEMX - if (HAL_HASH_MD5_Start(&md5->hashHandle, - (byte*)md5->buffer, md5->buffLen, - (byte*)md5->digest, MD5_HW_TIMEOUT) != HAL_OK) { - ret = ASYNC_OP_E; - } - #else - __IO uint16_t nbvalidbitsdata = 0; - - /* finish reading any trailing bytes into FIFO */ - if (md5->buffLen > 0) { - HASH_DataIn(*(uint32_t*)md5->buffer); - AddLength(md5, md5->buffLen); } - /* calculate number of valid bits in last word of input data */ - nbvalidbitsdata = 8 * (md5->loLen % MD5_REG_SIZE); - - /* configure number of valid bits in last word of the data */ - HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); - - /* start HASH processor */ - HASH_StartDigest(); - - /* wait until Busy flag == RESET */ - while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} - - /* read message digest */ - md5->digest[0] = HASH->HR[0]; - md5->digest[1] = HASH->HR[1]; - md5->digest[2] = HASH->HR[2]; - md5->digest[3] = HASH->HR[3]; - - ByteReverseWords(md5->digest, md5->digest, WC_MD5_DIGEST_SIZE); - #endif /* WOLFSSL_STM32_CUBEMX */ - - XMEMCPY(hash, md5->digest, WC_MD5_DIGEST_SIZE); + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&md5->stmCtx, HASH_AlgoSelection_MD5, + hash, WC_MD5_DIGEST_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } (void)wc_InitMd5(md5); /* reset state */ @@ -332,7 +233,8 @@ static INLINE void AddLength(wc_Md5* md5, word32 len); } #endif /* NEED_SOFT_MD5 */ -#if !defined(HAVE_MD5_CUST_API) || defined(STM32_HASH) +#ifndef HAVE_MD5_CUST_API + static INLINE void AddLength(wc_Md5* md5, word32 len) { word32 tmp = md5->loLen; @@ -340,9 +242,7 @@ static INLINE void AddLength(wc_Md5* md5, word32 len) md5->hiLen++; /* carry low to high */ } } -#endif -#ifndef HAVE_MD5_CUST_API static int _InitMd5(wc_Md5* md5) { int ret = 0; diff --git a/wolfcrypt/src/port/caam/caam_driver.c b/wolfcrypt/src/port/caam/caam_driver.c index ddab72dfc..5f1679350 100644 --- a/wolfcrypt/src/port/caam/caam_driver.c +++ b/wolfcrypt/src/port/caam/caam_driver.c @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#if defined(__INTEGRITY) || defined(INTEGRITY) + /* build into Integrity kernel */ #include #include "wolfssl/wolfcrypt/port/caam/caam_driver.h" @@ -1707,3 +1709,5 @@ void InitCAAM(void) } void (*__ghsentry_bspuserinit_InitCAAM)(void) = &InitCAAM; + +#endif /* INTEGRITY */ diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 1c94f708e..9f9364284 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -87,8 +87,6 @@ #include #endif -static INLINE void AddLength(wc_Sha* sha, word32 len); - /* Hardware Acceleration */ #if defined(WOLFSSL_PIC32MZ_HASH) @@ -96,152 +94,55 @@ static INLINE void AddLength(wc_Sha* sha, word32 len); #elif defined(STM32_HASH) - /* - * STM32F2/F4/F7 hardware SHA1 support through the HASH_* API's from the - * Standard Peripheral Library or CubeMX (See note in README). - */ - - /* STM32 register size, bytes */ - #ifdef WOLFSSL_STM32_CUBEMX - #define SHA_REG_SIZE WC_SHA_BLOCK_SIZE - #else - #define SHA_REG_SIZE 4 - /* STM32 struct notes: - * sha->buffer = first 4 bytes used to hold partial block if needed - * sha->buffLen = num bytes currently stored in sha->buffer - * sha->loLen = num bytes that have been written to STM32 FIFO - */ - #endif - #define SHA_HW_TIMEOUT 0xFF - - int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) + /* Supports CubeMX HAL or Standard Peripheral Library */ + #include + int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) { - if (sha == NULL) - return BAD_FUNC_ARG; - - sha->heap = heap; - XMEMSET(sha->buffer, 0, sizeof(sha->buffer)); - sha->buffLen = 0; - sha->loLen = 0; - sha->hiLen = 0; - - /* initialize HASH peripheral */ - #ifdef WOLFSSL_STM32_CUBEMX - HAL_HASH_DeInit(&sha->hashHandle); - sha->hashHandle.Init.DataType = HASH_DATATYPE_8B; - if (HAL_HASH_Init(&sha->hashHandle) != HAL_OK) { - return ASYNC_INIT_E; + if (sha == NULL) { + return BAD_FUNC_ARG; } - /* reset the hash control register */ - /* required because Cube MX is not clearing algo bits */ - HASH->CR &= ~HASH_CR_ALGO; - #else - HASH_DeInit(); + (void)devId; + (void)heap; - /* reset the hash control register */ - HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); - - /* configure algo used, algo mode, datatype */ - HASH->CR |= (HASH_AlgoSelection_SHA1 | HASH_AlgoMode_HASH - | HASH_DataType_8b); - - /* reset HASH processor */ - HASH->CR |= HASH_CR_INIT; - #endif + wc_Stm32_Hash_Init(&sha->stmCtx); return 0; } int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len) { - int ret = 0; - byte* local; + int ret; if (sha == NULL || (data == NULL && len > 0)) { return BAD_FUNC_ARG; } - /* do block size increments */ - local = (byte*)sha->buffer; - - /* check that internal buffLen is valid */ - if (sha->buffLen >= SHA_REG_SIZE) - return BUFFER_E; - - while (len) { - word32 add = min(len, SHA_REG_SIZE - sha->buffLen); - XMEMCPY(&local[sha->buffLen], data, add); - - sha->buffLen += add; - data += add; - len -= add; - - if (sha->buffLen == SHA_REG_SIZE) { - #ifdef WOLFSSL_STM32_CUBEMX - if (HAL_HASH_SHA1_Accumulate( - &sha->hashHandle, local, SHA_REG_SIZE) != HAL_OK) { - ret = ASYNC_OP_E; - } - #else - HASH_DataIn(*(uint32_t*)local); - #endif - - AddLength(sha, SHA_REG_SIZE); - sha->buffLen = 0; - } + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&sha->stmCtx, HASH_AlgoSelection_SHA1, + data, len); + wolfSSL_CryptHwMutexUnLock(); } return ret; } int wc_ShaFinal(wc_Sha* sha, byte* hash) { - int ret = 0; + int ret; - if (sha == NULL || hash == NULL) + if (sha == NULL || hash == NULL) { return BAD_FUNC_ARG; - - #ifdef WOLFSSL_STM32_CUBEMX - if (HAL_HASH_SHA1_Start(&sha->hashHandle, - (byte*)sha->buffer, sha->buffLen, - (byte*)sha->digest, SHA_HW_TIMEOUT) != HAL_OK) { - ret = ASYNC_OP_E; - } - HAL_HASH_DeInit(&sha->hashHandle); - #else - __IO uint16_t nbvalidbitsdata = 0; - - /* finish reading any trailing bytes into FIFO */ - if (sha->buffLen > 0) { - HASH_DataIn(*(uint32_t*)sha->buffer); - AddLength(sha, sha->buffLen); } - /* calculate number of valid bits in last word of input data */ - nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE); + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&sha->stmCtx, HASH_AlgoSelection_SHA1, + hash, WC_SHA_DIGEST_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } - /* configure number of valid bits in last word of the data */ - HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); - - /* start HASH processor */ - HASH_StartDigest(); - - /* wait until Busy flag == RESET */ - while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} - - /* read message digest */ - sha->digest[0] = HASH->HR[0]; - sha->digest[1] = HASH->HR[1]; - sha->digest[2] = HASH->HR[2]; - sha->digest[3] = HASH->HR[3]; - sha->digest[4] = HASH->HR[4]; - - ByteReverseWords(sha->digest, sha->digest, WC_SHA_DIGEST_SIZE); - #endif /* WOLFSSL_STM32_CUBEMX */ - - XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE); - - (void)wc_InitSha_ex(sha, sha->heap, INVALID_DEVID); /* reset state */ + (void)wc_InitSha(sha); /* reset state */ return ret; } @@ -250,8 +151,15 @@ static INLINE void AddLength(wc_Sha* sha, word32 len); #elif defined(FREESCALE_LTC_SHA) #include "fsl_ltc.h" - static int InitSha(wc_Sha* sha) + int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) { + if (sha == NULL) { + return BAD_FUNC_ARG; + } + + (void)devId; + (void)heap; + LTC_HASH_Init(LTC_BASE, &sha->ctx, kLTC_Sha1, NULL, 0); return 0; } @@ -343,18 +251,15 @@ static INLINE void AddLength(wc_Sha* sha, word32 len); #endif /* End Hardware Acceleration */ -#if defined(USE_SHA_SOFTWARE_IMPL) || defined(STM32_HASH) +/* Software implementation */ +#ifdef USE_SHA_SOFTWARE_IMPL + static INLINE void AddLength(wc_Sha* sha, word32 len) { word32 tmp = sha->loLen; if ((sha->loLen += len) < tmp) sha->hiLen++; /* carry low to high */ } -#endif - - -/* Software implementation */ -#ifdef USE_SHA_SOFTWARE_IMPL /* Check if custom wc_Sha transform is used */ #ifndef XTRANSFORM diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index e43b14859..68d80d166 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -121,9 +121,7 @@ #endif -static INLINE void AddLength(wc_Sha256* sha256, word32 len); - -#if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH) && \ +#if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH_SHA2) && \ (!defined(WOLFSSL_IMX6_CAAM) || defined(NO_IMX6_CAAM_HASH)) static int InitSha256(wc_Sha256* sha256) { @@ -373,106 +371,36 @@ static int InitSha256(wc_Sha256* sha256) #elif defined(WOLFSSL_PIC32MZ_HASH) #include -#elif defined(STM32_HASH) +#elif defined(STM32_HASH_SHA2) - /* - * STM32F2/F4/F7 hardware SHA256 support through the HASH_* API's from the - * Standard Peripheral Library or CubeMX (See note in README). - */ - - /* STM32 register size, bytes */ - #ifdef WOLFSSL_STM32_CUBEMX - #define SHA256_REG_SIZE SHA256_BLOCK_SIZE - #else - #define SHA256_REG_SIZE 4 - /* STM32 struct notes: - * sha256->buffer = first 4 bytes used to hold partial block if needed - * sha256->buffLen = num bytes currently stored in sha256->buffer - * sha256->loLen = num bytes that have been written to STM32 FIFO - */ - #endif - #define SHA256_HW_TIMEOUT 0xFF + /* Supports CubeMX HAL or Standard Peripheral Library */ + #include int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId) { if (sha256 == NULL) return BAD_FUNC_ARG; - sha256->heap = heap; - XMEMSET(sha256->buffer, 0, sizeof(sha256->buffer)); - sha256->buffLen = 0; - sha256->loLen = 0; - sha256->hiLen = 0; - - /* initialize HASH peripheral */ - #ifdef WOLFSSL_STM32_CUBEMX - HAL_HASH_DeInit(&sha256->hashHandle); - sha256->hashHandle.Init.DataType = HASH_DATATYPE_8B; - if (HAL_HASH_Init(&sha256->hashHandle) != HAL_OK) { - return ASYNC_INIT_E; - } - /* reset the hash control register */ - /* required because Cube MX is not clearing algo bits */ - HASH->CR &= ~HASH_CR_ALGO; - #else - HASH_DeInit(); - - /* reset the hash control register */ - HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); - - /* configure algo used, algo mode, datatype */ - HASH->CR |= (HASH_AlgoSelection_SHA256 | HASH_AlgoMode_HASH - | HASH_DataType_8b); - - /* reset HASH processor */ - HASH->CR |= HASH_CR_INIT; - #endif + (void)devId; + (void)heap; + wc_Stm32_Hash_Init(&sha256->stmCtx); return 0; } int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len) { int ret = 0; - byte* local; if (sha256 == NULL || (data == NULL && len > 0)) { return BAD_FUNC_ARG; } - if (data == NULL && len == 0) { - /* valid arguments, but do nothing */ - return 0; - } - - /* do block size increments */ - local = (byte*)sha256->buffer; - - /* check that internal buffLen is valid */ - if (sha256->buffLen >= SHA256_REG_SIZE) - return BUFFER_E; - - while (len) { - word32 add = min(len, SHA256_REG_SIZE - sha256->buffLen); - XMEMCPY(&local[sha256->buffLen], data, add); - - sha256->buffLen += add; - data += add; - len -= add; - - if (sha256->buffLen == SHA256_REG_SIZE) { - #ifdef WOLFSSL_STM32_CUBEMX - if (HAL_HASHEx_SHA256_Accumulate( - &sha256->hashHandle, local, SHA256_REG_SIZE) != HAL_OK) { - ret = ASYNC_OP_E; - } - #else - HASH_DataIn(*(uint32_t*)local); - #endif - - AddLength(sha256, SHA256_REG_SIZE); - sha256->buffLen = 0; - } + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&sha256->stmCtx, + HASH_AlgoSelection_SHA256, data, len); + wolfSSL_CryptHwMutexUnLock(); } return ret; } @@ -481,55 +409,22 @@ static int InitSha256(wc_Sha256* sha256) { int ret = 0; - if (sha256 == NULL || hash == NULL) + if (sha256 == NULL || hash == NULL) { return BAD_FUNC_ARG; - - #ifdef WOLFSSL_STM32_CUBEMX - if (HAL_HASHEx_SHA256_Start(&sha256->hashHandle, - (byte*)sha256->buffer, sha256->buffLen, - (byte*)sha256->digest, SHA256_HW_TIMEOUT) != HAL_OK) { - ret = ASYNC_OP_E; - } - #else - __IO uint16_t nbvalidbitsdata = 0; - - /* finish reading any trailing bytes into FIFO */ - if (sha256->buffLen > 0) { - HASH_DataIn(*(uint32_t*)sha256->buffer); - AddLength(sha256, sha256->buffLen); } - /* calculate number of valid bits in last word of input data */ - nbvalidbitsdata = 8 * (sha256->loLen % SHA256_REG_SIZE); + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&sha256->stmCtx, + HASH_AlgoSelection_SHA256, hash, WC_SHA256_DIGEST_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } - /* configure number of valid bits in last word of the data */ - HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); - - /* start HASH processor */ - HASH_StartDigest(); - - /* wait until Busy flag == RESET */ - while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} - - /* read message digest */ - sha256->digest[0] = HASH->HR[0]; - sha256->digest[1] = HASH->HR[1]; - sha256->digest[2] = HASH->HR[2]; - sha256->digest[3] = HASH->HR[3]; - sha256->digest[4] = HASH->HR[4]; - sha256->digest[5] = HASH_DIGEST->HR[5]; - sha256->digest[6] = HASH_DIGEST->HR[6]; - sha256->digest[7] = HASH_DIGEST->HR[7]; - - ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE); - #endif /* WOLFSSL_STM32_CUBEMX */ - - XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE); - - (void)wc_InitSha256_ex(sha256, sha256->heap, INVALID_DEVID); + (void)wc_InitSha256(sha256); /* reset state */ return ret; } + #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */ #else @@ -663,18 +558,15 @@ static int InitSha256(wc_Sha256* sha256) /* End wc_ software implementation */ -#if defined(XTRANSFORM) || defined(STM32_HASH) -static INLINE void AddLength(wc_Sha256* sha256, word32 len) -{ - word32 tmp = sha256->loLen; - if ((sha256->loLen += len) < tmp) - sha256->hiLen++; /* carry low to high */ -} -#endif - - #ifdef XTRANSFORM + static INLINE void AddLength(wc_Sha256* sha256, word32 len) + { + word32 tmp = sha256->loLen; + if ((sha256->loLen += len) < tmp) + sha256->hiLen++; /* carry low to high */ + } + static INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 len) { int ret = 0; @@ -2581,145 +2473,56 @@ SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256, #ifdef WOLFSSL_SHA224 -#ifdef STM32_HASH +#ifdef STM32_HASH_SHA2 - #define Sha256Update Sha224Update - #define Sha256Final Sha224Final + /* Supports CubeMX HAL or Standard Peripheral Library */ + #include - /* - * STM32F2/F4/F7 hardware SHA224 support through the HASH_* API's from the - * Standard Peripheral Library or CubeMX (See note in README). - */ - - /* STM32 register size, bytes */ - #ifdef WOLFSSL_STM32_CUBEMX - #define SHA224_REG_SIZE WC_SHA224_BLOCK_SIZE - #else - #define SHA224_REG_SIZE 4 - /* STM32 struct notes: - * sha224->buffer = first 4 bytes used to hold partial block if needed - * sha224->buffLen = num bytes currently stored in sha256->buffer - * sha224->loLen = num bytes that have been written to STM32 FIFO - */ - #endif - #define SHA224_HW_TIMEOUT 0xFF - - static int InitSha224(wc_Sha224* sha224) + int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId) { if (sha224 == NULL) return BAD_FUNC_ARG; - XMEMSET(sha224->buffer, 0, sizeof(sha224->buffer)); - sha224->buffLen = 0; - sha224->loLen = 0; - sha224->hiLen = 0; - - /* initialize HASH peripheral */ - #ifdef WOLFSSL_STM32_CUBEMX - HAL_HASH_DeInit(&sha224->hashHandle); - sha224->hashHandle.Init.DataType = HASH_DATATYPE_8B; - if (HAL_HASH_Init(&sha224->hashHandle) != HAL_OK) { - return ASYNC_INIT_E; - } - /* required because Cube MX is not clearing algo bits */ - HASH->CR &= ~HASH_CR_ALGO; - #else - HASH_DeInit(); - - /* reset the hash control register */ - /* required because Cube MX is not clearing algo bits */ - HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); - - /* configure algo used, algo mode, datatype */ - HASH->CR |= (HASH_AlgoSelection_SHA224 | HASH_AlgoMode_HASH - | HASH_DataType_8b); - - /* reset HASH processor */ - HASH->CR |= HASH_CR_INIT; - #endif + (void)devId; + (void)heap; + wc_Stm32_Hash_Init(&sha224->stmCtx); return 0; } - static int Sha224Update(wc_Sha256* sha224, const byte* data, word32 len) + int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len) { int ret = 0; - byte* local; - /* do block size increments */ - local = (byte*)sha224->buffer; + if (sha224 == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } - /* check that internal buffLen is valid */ - if (sha224->buffLen >= SHA224_REG_SIZE) - return BUFFER_E; - - while (len) { - word32 add = min(len, SHA224_REG_SIZE - sha224->buffLen); - XMEMCPY(&local[sha224->buffLen], data, add); - - sha224->buffLen += add; - data += add; - len -= add; - - if (sha224->buffLen == SHA224_REG_SIZE) { - #ifdef WOLFSSL_STM32_CUBEMX - if (HAL_HASHEx_SHA224_Accumulate( - &sha224->hashHandle, local, SHA224_REG_SIZE) != HAL_OK) { - ret = ASYNC_OP_E; - } - #else - HASH_DataIn(*(uint32_t*)local); - #endif - - AddLength(sha224, SHA224_REG_SIZE); - sha224->buffLen = 0; - } + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Update(&sha224->stmCtx, + HASH_AlgoSelection_SHA224, data, len); + wolfSSL_CryptHwMutexUnLock(); } return ret; } - static int Sha224Final(wc_Sha256* sha224) + int wc_Sha224Final(wc_Sha224* sha224, byte* hash) { int ret = 0; - #ifdef WOLFSSL_STM32_CUBEMX - if (HAL_HASHEx_SHA224_Start(&sha224->hashHandle, - (byte*)sha224->buffer, sha224->buffLen, - (byte*)sha224->digest, SHA224_HW_TIMEOUT) != HAL_OK) { - ret = ASYNC_OP_E; - } - #else - __IO uint16_t nbvalidbitsdata = 0; - - /* finish reading any trailing bytes into FIFO */ - if (sha224->buffLen > 0) { - HASH_DataIn(*(uint32_t*)sha224->buffer); - AddLength(sha224, sha224->buffLen); + if (sha224 == NULL || hash == NULL) { + return BAD_FUNC_ARG; } - /* calculate number of valid bits in last word of input data */ - nbvalidbitsdata = 8 * (sha224->loLen % SHA224_REG_SIZE); + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + ret = wc_Stm32_Hash_Final(&sha224->stmCtx, + HASH_AlgoSelection_SHA224, hash, WC_SHA224_DIGEST_SIZE); + wolfSSL_CryptHwMutexUnLock(); + } - /* configure number of valid bits in last word of the data */ - HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); - - /* start HASH processor */ - HASH_StartDigest(); - - /* wait until Busy flag == RESET */ - while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} - - /* read message digest */ - sha224->digest[0] = HASH->HR[0]; - sha224->digest[1] = HASH->HR[1]; - sha224->digest[2] = HASH->HR[2]; - sha224->digest[3] = HASH->HR[3]; - sha224->digest[4] = HASH->HR[4]; - sha224->digest[5] = HASH_DIGEST->HR[5]; - sha224->digest[6] = HASH_DIGEST->HR[6]; - - ByteReverseWords(sha224->digest, sha224->digest, SHA224_DIGEST_SIZE); - #endif /* WOLFSSL_STM32_CUBEMX */ + (void)wc_InitSha224(sha224); /* reset state */ return ret; } @@ -2760,9 +2563,9 @@ SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256, return ret; } -#endif /* STM32_HASH */ +#endif -#if defined(NEED_SOFT_SHA224) || defined(STM32_HASH) +#ifdef NEED_SOFT_SHA224 int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId) { int ret = 0; @@ -2828,7 +2631,7 @@ SHA256_NOINLINE static int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256, if (ret != 0) return ret; - #if defined(LITTLE_ENDIAN_ORDER) && !defined(STM32_HASH) + #if defined(LITTLE_ENDIAN_ORDER) ByteReverseWords(sha224->digest, sha224->digest, WC_SHA224_DIGEST_SIZE); #endif XMEMCPY(hash, sha224->digest, WC_SHA224_DIGEST_SIZE); diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 956ed84a1..e768b749c 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -74,7 +74,9 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/xilinx/xil-sha3.h \ wolfssl/wolfcrypt/port/caam/caam_driver.h \ wolfssl/wolfcrypt/port/caam/wolfcaam.h \ - wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h + wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \ + wolfssl/wolfcrypt/port/st/stm32.h \ + wolfssl/wolfcrypt/port/st/stm32_hash.h if BUILD_ASYNCCRYPT nobase_include_HEADERS+= wolfssl/wolfcrypt/async.h diff --git a/wolfssl/wolfcrypt/md5.h b/wolfssl/wolfcrypt/md5.h index c0db601e2..6ab7c5f82 100644 --- a/wolfssl/wolfcrypt/md5.h +++ b/wolfssl/wolfcrypt/md5.h @@ -57,6 +57,9 @@ enum { #ifdef WOLFSSL_MICROCHIP_PIC32MZ #include #endif +#ifdef STM32_HASH + #include +#endif #ifdef WOLFSSL_ASYNC_CRYPT #include #endif @@ -69,6 +72,9 @@ enum { /* MD5 digest */ typedef struct wc_Md5 { +#ifdef STM32_HASH + STM32_HASH_Context stmCtx; +#else word32 buffLen; /* in bytes */ word32 loLen; /* length in bytes */ word32 hiLen; /* length in bytes */ @@ -82,9 +88,7 @@ typedef struct wc_Md5 { #ifdef WOLFSSL_PIC32MZ_HASH hashUpdCache cache; /* cache for updates */ #endif -#if defined(STM32_HASH) && defined(WOLFSSL_STM32_CUBEMX) - HASH_HandleTypeDef hashHandle; -#endif +#endif /* STM32_HASH */ #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ diff --git a/wolfssl/wolfcrypt/port/st/stm32.h b/wolfssl/wolfcrypt/port/st/stm32.h new file mode 100644 index 000000000..1f011820a --- /dev/null +++ b/wolfssl/wolfcrypt/port/st/stm32.h @@ -0,0 +1,55 @@ +#ifndef _WOLFPORT_STM32_H_ +#define _WOLFPORT_STM32_H_ + +#ifdef STM32_HASH + +/* Generic STM32 Hashing Function */ +/* Supports CubeMX HAL or Standard Peripheral Library */ + +#include + +#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 +#else + #define HASH_CR_SIZE 50 + #define HASH_MAX_DIGEST 20 +#endif + +/* Handle hash differences between CubeMX and StdPeriLib */ +#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 +#endif + +#ifndef STM32_HASH_TIMEOUT + #define STM32_HASH_TIMEOUT 0xFFFF +#endif + + +/* STM32 register size in bytes */ +#define STM32_HASH_REG_SIZE 4 + +/* STM32 Hash Context */ +typedef struct { + /* Context switching registers */ + uint32_t HASH_IMR; + uint32_t HASH_STR; + uint32_t HASH_CR; + uint32_t HASH_CSR[HASH_CR_SIZE]; + + /* Hash state / buffers */ + word32 buffer[STM32_HASH_REG_SIZE / sizeof(word32)]; /* 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) */ +} STM32_HASH_Context; + + +#endif /* STM32_HASH */ + +#endif /* _WOLFPORT_STM32_H_ */ diff --git a/wolfssl/wolfcrypt/port/st/stm32_hash.h b/wolfssl/wolfcrypt/port/st/stm32_hash.h new file mode 100644 index 000000000..7796e9163 --- /dev/null +++ b/wolfssl/wolfcrypt/port/st/stm32_hash.h @@ -0,0 +1,229 @@ +#ifndef _WOLFPORT_STM32_HASH_H_ +#define _WOLFPORT_STM32_HASH_H_ + +#ifdef STM32_HASH + +/* Generic STM32 Hashing Function */ +/* Supports CubeMX HAL or Standard Peripheral Library */ + +#include +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + + +/* User can override STM32_HASH_CLOCK_ENABLE and STM32_HASH_CLOCK_DISABLE */ +#ifndef STM32_HASH_CLOCK_ENABLE + static inline void wc_Stm32_Hash_Clock_Enable(STM32_HASH_Context* stmCtx) + { + #ifdef WOLFSSL_STM32_CUBEMX + __HAL_RCC_HASH_CLK_ENABLE(); + #else + RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE); + #endif + (void)stmCtx; + } + #define STM32_HASH_CLOCK_ENABLE(ctx) wc_Stm32_Hash_Clock_Enable(ctx) +#endif + +#ifndef STM32_HASH_CLOCK_DISABLE + static inline void wc_Stm32_Hash_Clock_Disable(STM32_HASH_Context* stmCtx) + { + #ifdef WOLFSSL_STM32_CUBEMX + __HAL_RCC_HASH_CLK_DISABLE(); + #else + RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, DISABLE); + #endif + (void)stmCtx; + } + #define STM32_HASH_CLOCK_DISABLE(ctx) wc_Stm32_Hash_Clock_Disable(ctx) +#endif + +/* STM32 Port Internal Functions */ +static inline void wc_Stm32_Hash_SaveContext(STM32_HASH_Context* ctx) +{ + int i; + + /* save context registers */ + ctx->HASH_IMR = HASH->IMR; + ctx->HASH_STR = HASH->STR; + ctx->HASH_CR = HASH->CR; + for (i=0; iHASH_CSR[i] = HASH->CSR[i]; + } +} + +static inline int wc_Stm32_Hash_RestoreContext(STM32_HASH_Context* ctx) +{ + int i; + + if (ctx->HASH_CR != 0) { + /* restore context registers */ + HASH->IMR = ctx->HASH_IMR; + HASH->STR = ctx->HASH_STR; + HASH->CR = ctx->HASH_CR; + + /* Initialize the hash processor */ + HASH->CR |= HASH_CR_INIT; + + /* continue restoring context registers */ + for (i=0; iCSR[i] = ctx->HASH_CSR[i]; + } + return 1; + } + return 0; +} + +static inline void wc_Stm32_Hash_GetDigest(byte* hash, int digestSize) +{ + word32 digest[HASH_MAX_DIGEST/sizeof(word32)]; + + /* 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]; + #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]; + } + #endif + } + + ByteReverseWords(digest, digest, digestSize); + + XMEMCPY(hash, digest, digestSize); +} + + +/* STM32 Port Exposed Functions */ +static inline int wc_Stm32_Hash_WaitDone(void) +{ + /* wait until hash hardware is not busy */ + int timeout = 0; + while ((HASH->SR & HASH_SR_BUSY) && ++timeout < STM32_HASH_TIMEOUT) { + + } + /* verify timeout did not occur */ + if (timeout >= STM32_HASH_TIMEOUT) { + return WC_TIMEOUT_E; + } + return 0; +} + +static inline void wc_Stm32_Hash_Init(STM32_HASH_Context* stmCtx) +{ + /* clear context */ + XMEMSET(stmCtx, 0, sizeof(STM32_HASH_Context)); +} + +static int wc_Stm32_Hash_Update(STM32_HASH_Context* stmCtx, word32 algo, + const byte* data, int len) +{ + int ret = 0; + byte* local = (byte*)stmCtx->buffer; + int wroteToFifo = 0; + + /* check that internal buffLen is valid */ + if (stmCtx->buffLen >= STM32_HASH_REG_SIZE) { + return BUFFER_E; + } + + /* turn on hash clock */ + 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); + + /* 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 */ + while (len) { + word32 add = min(len, STM32_HASH_REG_SIZE - stmCtx->buffLen); + XMEMCPY(&local[stmCtx->buffLen], data, add); + + stmCtx->buffLen += add; + data += add; + len -= add; + + if (stmCtx->buffLen == STM32_HASH_REG_SIZE) { + wroteToFifo = 1; + HASH->DIN = *(word32*)stmCtx->buffer; + + stmCtx->loLen += STM32_HASH_REG_SIZE; + stmCtx->buffLen = 0; + } + } + + if (wroteToFifo) { + /* save hash state for next operation */ + wc_Stm32_Hash_SaveContext(stmCtx); + } + + /* turn off hash clock */ + STM32_HASH_CLOCK_DISABLE(stmCtx); + + return ret; +} + +static inline int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, + byte* hash, int digestSize) +{ + int ret = 0; + word32 nbvalidbitsdata = 0; + + /* turn on hash clock */ + STM32_HASH_CLOCK_ENABLE(stmCtx); + + /* restore hash state */ + wc_Stm32_Hash_RestoreContext(stmCtx); + + /* finish reading any trailing bytes into FIFO */ + if (stmCtx->buffLen > 0) { + HASH->DIN = *(word32*)stmCtx->buffer; + stmCtx->loLen += 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; + + /* start hash processor */ + HASH->STR |= HASH_STR_DCAL; + + /* wait for hash done */ + ret = wc_Stm32_Hash_WaitDone(); + if (ret == 0) { + /* read message digest */ + wc_Stm32_Hash_GetDigest(hash, digestSize); + } + + /* turn off hash clock */ + STM32_HASH_CLOCK_DISABLE(stmCtx); + + return ret; +} + +#endif /* STM32_HASH */ + +#endif /* _WOLFPORT_STM32_HASH_H_ */ diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index 7b742f0cc..c5eadfec7 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -51,6 +51,9 @@ #ifdef WOLFSSL_MICROCHIP_PIC32MZ #include #endif +#ifdef STM32_HASH + #include +#endif #ifdef WOLFSSL_ASYNC_CRYPT #include #endif @@ -81,9 +84,11 @@ enum { #else /* Sha digest */ typedef struct wc_Sha { - #ifdef FREESCALE_LTC_SHA +#ifdef FREESCALE_LTC_SHA ltc_hash_ctx_t ctx; - #else +#elif defined(STM32_HASH) + STM32_HASH_Context stmCtx; +#else word32 buffLen; /* in bytes */ word32 loLen; /* length in bytes */ word32 hiLen; /* length in bytes */ @@ -97,13 +102,10 @@ typedef struct wc_Sha { #ifdef WOLFSSL_PIC32MZ_HASH hashUpdCache cache; /* cache for updates */ #endif - #if defined(STM32_HASH) && defined(WOLFSSL_STM32_CUBEMX) - HASH_HandleTypeDef hashHandle; - #endif #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ -#endif /* FREESCALE_LTC_SHA */ +#endif } wc_Sha; #endif /* WOLFSSL_TI_HASH */ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 7fb3a696c..0be24798e 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -62,6 +62,9 @@ #ifdef WOLFSSL_MICROCHIP_PIC32MZ #include #endif +#ifdef STM32_HASH + #include +#endif #ifdef WOLFSSL_ASYNC_CRYPT #include #endif @@ -99,6 +102,8 @@ enum { typedef struct wc_Sha256 { #ifdef FREESCALE_LTC_SHA ltc_hash_ctx_t ctx; +#elif defined(STM32_HASH) + STM32_HASH_Context stmCtx; #else /* alignment on digest and buffer speeds up ARMv8 crypto operations */ ALIGN16 word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)]; @@ -113,13 +118,10 @@ typedef struct wc_Sha256 { #ifdef WOLFSSL_PIC32MZ_HASH hashUpdCache cache; /* cache for updates */ #endif -#if defined(STM32_HASH) && defined(WOLFSSL_STM32_CUBEMX) - HASH_HandleTypeDef hashHandle; -#endif #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ -#endif /* FREESCALE_LTC_SHA */ +#endif } wc_Sha256; #endif diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 6a5443108..2445f91c3 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -186,7 +186,7 @@ /* Define stubs, since HW mutex is disabled */ #define wolfSSL_CryptHwMutexInit() 0 /* Success */ #define wolfSSL_CryptHwMutexLock() 0 /* Success */ - #define wolfSSL_CryptHwMutexUnLock() 0 /* Success */ + #define wolfSSL_CryptHwMutexUnLock() (void)0 /* Success */ #endif /* WOLFSSL_CRYPT_HW_MUTEX */ /* Mutex functions */