forked from wolfSSL/wolfssl
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:
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
55
wolfssl/wolfcrypt/port/st/stm32.h
Normal file
55
wolfssl/wolfcrypt/port/st/stm32.h
Normal 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_ */
|
229
wolfssl/wolfcrypt/port/st/stm32_hash.h
Normal file
229
wolfssl/wolfcrypt/port/st/stm32_hash.h
Normal 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_ */
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user