Add mutex protection on STM32 RNG, AES/DES and Hashing crypto hardware calls for thread safety. Fixes #2580

pull/2586/head
David Garske 2019-11-15 12:08:11 -08:00
parent 2a9449182c
commit 27d95d1dfd
4 changed files with 133 additions and 22 deletions

View File

@ -369,6 +369,7 @@
/* disable crypto processor */
CRYP_Cmd(DISABLE);
#endif /* WOLFSSL_STM32_CUBEMX */
return ret;
}
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
@ -461,6 +462,7 @@
/* disable crypto processor */
CRYP_Cmd(DISABLE);
#endif /* WOLFSSL_STM32_CUBEMX */
return ret;
}
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESCCM */
@ -2456,19 +2458,39 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
#elif defined(WOLFSSL_DEVCRYPTO_AES)
/* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
#elif defined(STM32_CRYPTO)
/* Allow direct access to one block encrypt */
void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
{
if (wolfSSL_CryptHwMutexLock() == 0) {
wc_AesEncrypt(aes, in, out);
wolfSSL_CryptHwMutexUnLock();
}
}
#ifdef HAVE_AES_DECRYPT
/* Allow direct access to one block decrypt */
void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
{
if (wolfSSL_CryptHwMutexLock() == 0) {
wc_AesDecrypt(aes, in, out);
wolfSSL_CryptHwMutexUnLock();
}
}
#endif /* HAVE_AES_DECRYPT */
#else
/* Allow direct access to one block encrypt */
void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
{
wc_AesEncrypt(aes, in, out);
}
#ifdef HAVE_AES_DECRYPT
#ifdef HAVE_AES_DECRYPT
/* Allow direct access to one block decrypt */
void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
{
wc_AesDecrypt(aes, in, out);
}
#endif /* HAVE_AES_DECRYPT */
#endif /* HAVE_AES_DECRYPT */
#endif /* AES direct block */
#endif /* WOLFSSL_AES_DIRECT */
@ -2488,6 +2510,11 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
if (ret != 0)
return ret;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
#ifdef STM32_CRYPTO_AES_ONLY
hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
hcryp.Init.ChainingMode = CRYP_CHAINMODE_AES_CBC;
@ -2525,6 +2552,8 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
HAL_CRYP_DeInit(&hcryp);
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#ifdef HAVE_AES_DECRYPT
@ -2538,6 +2567,11 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
if (ret != 0)
return ret;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* if input and output same will overwrite input iv */
XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
@ -2577,6 +2611,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
}
HAL_CRYP_DeInit(&hcryp);
wolfSSL_CryptHwMutexUnLock();
return ret;
}
@ -2596,6 +2631,11 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
if (ret != 0)
return ret;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* reset registers to their default values */
CRYP_DeInit();
@ -2647,6 +2687,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
/* disable crypto processor */
CRYP_Cmd(DISABLE);
wolfSSL_CryptHwMutexUnLock();
return ret;
}
@ -2665,6 +2706,11 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
if (ret != 0)
return ret;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* if input and output same will overwrite input iv */
XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
@ -2727,6 +2773,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
/* disable crypto processor */
CRYP_Cmd(DISABLE);
wolfSSL_CryptHwMutexUnLock();
return ret;
}
@ -3245,10 +3292,17 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
CRYP_IVInitTypeDef ivInit;
#endif
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
#ifdef WOLFSSL_STM32_CUBEMX
ret = wc_Stm32_Aes_Init(aes, &hcryp);
if (ret != 0)
if (ret != 0) {
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#ifdef STM32_CRYPTO_AES_ONLY
hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
@ -3279,8 +3333,10 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
#else /* STD_PERI_LIB */
ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
if (ret != 0)
if (ret != 0) {
wolfSSL_CryptHwMutexUnLock();
return ret;
}
/* reset registers to their default values */
CRYP_DeInit();
@ -3325,6 +3381,8 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
CRYP_Cmd(DISABLE);
#endif /* WOLFSSL_STM32_CUBEMX */
wolfSSL_CryptHwMutexUnLock();
return ret;
}
@ -5432,6 +5490,11 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz
return ret;
#endif
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
XMEMSET(ctr, 0, AES_BLOCK_SIZE);
if (ivSz == GCM_NONCE_MID_SZ) {
XMEMCPY(ctr, iv, ivSz);
@ -5449,6 +5512,7 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz
authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (authInPadded == NULL) {
wolfSSL_CryptHwMutexUnLock();
return MEMORY_E;
}
XMEMSET(authInPadded, 0, authPadSz);
@ -5570,6 +5634,8 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz
XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
@ -5858,6 +5924,11 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
return ret;
#endif
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
XMEMSET(ctr, 0, AES_BLOCK_SIZE);
if (ivSz == GCM_NONCE_MID_SZ) {
XMEMCPY(ctr, iv, ivSz);
@ -5875,6 +5946,7 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (authInPadded == NULL) {
wolfSSL_CryptHwMutexUnLock();
return MEMORY_E;
}
XMEMSET(authInPadded, 0, authPadSz);
@ -5996,6 +6068,8 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}

View File

@ -192,9 +192,22 @@
static void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
int dir, int mode)
{
int ret;
#ifdef WOLFSSL_STM32_CUBEMX
CRYP_HandleTypeDef hcryp;
#else
word32 *dkey, *iv;
CRYP_InitTypeDef DES_CRYP_InitStructure;
CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
#endif
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
#ifdef WOLFSSL_STM32_CUBEMX
XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
hcryp.Instance = CRYP;
hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
@ -204,8 +217,7 @@
HAL_CRYP_Init(&hcryp);
while (sz > 0)
{
while (sz > 0) {
/* if input and output same will overwrite input iv */
XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
@ -240,11 +252,6 @@
HAL_CRYP_DeInit(&hcryp);
#else
word32 *dkey, *iv;
CRYP_InitTypeDef DES_CRYP_InitStructure;
CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
dkey = des->key;
iv = des->reg;
@ -286,8 +293,7 @@
/* enable crypto processor */
CRYP_Cmd(ENABLE);
while (sz > 0)
{
while (sz > 0) {
/* flush IN/OUT FIFOs */
CRYP_FIFOFlush();
@ -314,6 +320,7 @@
/* disable crypto processor */
CRYP_Cmd(DISABLE);
#endif /* WOLFSSL_STM32_CUBEMX */
wolfSSL_CryptHwMutexUnLock();
}
int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)

View File

@ -1819,10 +1819,16 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
#ifdef WOLFSSL_STM32_CUBEMX
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{
int ret;
RNG_HandleTypeDef hrng;
word32 i = 0;
(void)os;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* enable RNG clock source */
__HAL_RCC_RNG_CLK_ENABLE();
@ -1839,6 +1845,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
/* Single byte at a time */
uint32_t tmpRng = 0;
if (HAL_RNG_GenerateRandomNumber(&hrng, &tmpRng) != HAL_OK) {
wolfSSL_CryptHwMutexUnLock();
return RAN_BLOCK_E;
}
output[i++] = (byte)tmpRng;
@ -1846,12 +1853,15 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
else {
/* Use native 32 instruction */
if (HAL_RNG_GenerateRandomNumber(&hrng, (uint32_t*)&output[i]) != HAL_OK) {
wolfSSL_CryptHwMutexUnLock();
return RAN_BLOCK_E;
}
i += sizeof(word32);
}
}
wolfSSL_CryptHwMutexUnLock();
return 0;
}
#elif defined(WOLFSSL_STM32F427_RNG) || defined(WOLFSSL_STM32_RNG_NOLIB)
@ -1861,9 +1871,15 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
* Manual (Chapter 24) for STM32F4xx family. */
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{
int i;
int ret;
word32 i;
(void)os;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* enable RNG peripheral clock */
RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
@ -1876,10 +1892,12 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
/* verify no errors, make sure SEIS and CEIS bits are 0
* in RNG->SR register */
if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS))
if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS)) {
wolfSSL_CryptHwMutexUnLock();
return RNG_FAILURE_E;
}
for (i = 0; i < (int)sz; i++) {
for (i = 0; i < sz; i++) {
/* wait until RNG number is ready */
while ((RNG->SR & RNG_SR_DRDY) == 0) { }
@ -1887,6 +1905,8 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
output[i] = RNG->DR;
}
wolfSSL_CryptHwMutexUnLock();
return 0;
}
@ -1895,9 +1915,15 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
/* Generate a RNG seed using the STM32 Standard Peripheral Library */
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{
int i;
int ret;
word32 i;
(void)os;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* enable RNG clock source */
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
@ -1908,10 +1934,12 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
RNG_Cmd(ENABLE);
/* verify no errors with RNG_CLK or Seed */
if (RNG_GetFlagStatus(RNG_FLAG_SECS | RNG_FLAG_CECS) != RESET)
if (RNG_GetFlagStatus(RNG_FLAG_SECS | RNG_FLAG_CECS) != RESET) {
wolfSSL_CryptHwMutexUnLock();
return RNG_FAILURE_E;
}
for (i = 0; i < (int)sz; i++) {
for (i = 0; i < sz; i++) {
/* wait until RNG number is ready */
while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET) { }
@ -1919,6 +1947,8 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
output[i] = RNG_GetRandomNumber();
}
wolfSSL_CryptHwMutexUnLock();
return 0;
}
#endif /* WOLFSSL_STM32_CUBEMX */

View File

@ -229,8 +229,9 @@
#endif /* USE_WINDOWS_API */
#endif /* SINGLE_THREADED */
/* Enable crypt HW mutex for Freescale MMCAU or PIC32MZ */
#if defined(FREESCALE_MMCAU) || defined(WOLFSSL_MICROCHIP_PIC32MZ)
/* Enable crypt HW mutex for Freescale MMCAU, PIC32MZ or STM32 */
#if defined(FREESCALE_MMCAU) || defined(WOLFSSL_MICROCHIP_PIC32MZ) || \
defined(STM32_CRYPTO)
#ifndef WOLFSSL_CRYPT_HW_MUTEX
#define WOLFSSL_CRYPT_HW_MUTEX 1
#endif
@ -749,4 +750,3 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
#endif
#endif /* WOLF_CRYPT_PORT_H */