STM32 refactor to move hashing code into wolfssl/wolfcrypt/port/stm32.h. Supports CubeMX HAL or StdPeriLib with MD5, SHA1, SHA224 and SHA256. Detects if hardware supports SHA2. Adds hashing context save/restore and hashing clock/power optimizations. Fix for building *.c in wolfcrypt/src/port for caam_driver.c. Fix for warning with wolfSSL_CryptHwMutexUnLock when no threading defined and return code not checked.

This commit is contained in:
David Garske
2018-01-31 11:25:20 -08:00
parent 640015ed5f
commit a4a5f4f27a
11 changed files with 426 additions and 520 deletions

View File

@ -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 <wolfssl/wolfcrypt/port/st/stm32_hash.h>
#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;

View File

@ -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 <bsp.h>
#include "wolfssl/wolfcrypt/port/caam/caam_driver.h"
@ -1707,3 +1709,5 @@ void InitCAAM(void)
}
void (*__ghsentry_bspuserinit_InitCAAM)(void) = &InitCAAM;
#endif /* INTEGRITY */

View File

@ -87,8 +87,6 @@
#include <wolfcrypt/src/misc.c>
#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
/* Supports CubeMX HAL or Standard Peripheral Library */
#include <wolfssl/wolfcrypt/port/st/stm32_hash.h>
int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
{
if (sha == NULL)
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;
}
/* 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

View File

@ -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 <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
#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 <wolfssl/wolfcrypt/port/st/stm32_hash.h>
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,17 +558,14 @@ 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)
{
#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 */
}
#endif
#ifdef XTRANSFORM
}
static INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
{
@ -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 <wolfssl/wolfcrypt/port/st/stm32_hash.h>
/*
* 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;
/* 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;
if (sha224 == NULL || (data == NULL && len > 0)) {
return BAD_FUNC_ARG;
}
#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);

View File

@ -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

View File

@ -57,6 +57,9 @@ enum {
#ifdef WOLFSSL_MICROCHIP_PIC32MZ
#include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
#endif
#ifdef STM32_HASH
#include <wolfssl/wolfcrypt/port/st/stm32.h>
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
#include <wolfssl/wolfcrypt/async.h>
#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 */

View File

@ -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 <wolfssl/wolfcrypt/types.h>
#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_ */

View File

@ -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 <wolfssl/wolfcrypt/port/st/stm32.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#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; i<HASH_CR_SIZE; i++) {
ctx->HASH_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; i<HASH_CR_SIZE; i++) {
HASH->CSR[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_ */

View File

@ -51,6 +51,9 @@
#ifdef WOLFSSL_MICROCHIP_PIC32MZ
#include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
#endif
#ifdef STM32_HASH
#include <wolfssl/wolfcrypt/port/st/stm32.h>
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
#include <wolfssl/wolfcrypt/async.h>
#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 */

View File

@ -62,6 +62,9 @@
#ifdef WOLFSSL_MICROCHIP_PIC32MZ
#include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
#endif
#ifdef STM32_HASH
#include <wolfssl/wolfcrypt/port/st/stm32.h>
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
#include <wolfssl/wolfcrypt/async.h>
#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

View File

@ -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 */