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

View File

@ -192,9 +192,22 @@
static void DesCrypt(Des* des, byte* out, const byte* in, word32 sz, static void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
int dir, int mode) int dir, int mode)
{ {
int ret;
#ifdef WOLFSSL_STM32_CUBEMX #ifdef WOLFSSL_STM32_CUBEMX
CRYP_HandleTypeDef hcryp; 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)); XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
hcryp.Instance = CRYP; hcryp.Instance = CRYP;
hcryp.Init.KeySize = CRYP_KEYSIZE_128B; hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
@ -204,8 +217,7 @@
HAL_CRYP_Init(&hcryp); HAL_CRYP_Init(&hcryp);
while (sz > 0) while (sz > 0) {
{
/* if input and output same will overwrite input iv */ /* if input and output same will overwrite input iv */
XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE); XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
@ -240,11 +252,6 @@
HAL_CRYP_DeInit(&hcryp); HAL_CRYP_DeInit(&hcryp);
#else #else
word32 *dkey, *iv;
CRYP_InitTypeDef DES_CRYP_InitStructure;
CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
dkey = des->key; dkey = des->key;
iv = des->reg; iv = des->reg;
@ -286,8 +293,7 @@
/* enable crypto processor */ /* enable crypto processor */
CRYP_Cmd(ENABLE); CRYP_Cmd(ENABLE);
while (sz > 0) while (sz > 0) {
{
/* flush IN/OUT FIFOs */ /* flush IN/OUT FIFOs */
CRYP_FIFOFlush(); CRYP_FIFOFlush();
@ -314,6 +320,7 @@
/* disable crypto processor */ /* disable crypto processor */
CRYP_Cmd(DISABLE); CRYP_Cmd(DISABLE);
#endif /* WOLFSSL_STM32_CUBEMX */ #endif /* WOLFSSL_STM32_CUBEMX */
wolfSSL_CryptHwMutexUnLock();
} }
int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) 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 #ifdef WOLFSSL_STM32_CUBEMX
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{ {
int ret;
RNG_HandleTypeDef hrng; RNG_HandleTypeDef hrng;
word32 i = 0; word32 i = 0;
(void)os; (void)os;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* enable RNG clock source */ /* enable RNG clock source */
__HAL_RCC_RNG_CLK_ENABLE(); __HAL_RCC_RNG_CLK_ENABLE();
@ -1839,6 +1845,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
/* Single byte at a time */ /* Single byte at a time */
uint32_t tmpRng = 0; uint32_t tmpRng = 0;
if (HAL_RNG_GenerateRandomNumber(&hrng, &tmpRng) != HAL_OK) { if (HAL_RNG_GenerateRandomNumber(&hrng, &tmpRng) != HAL_OK) {
wolfSSL_CryptHwMutexUnLock();
return RAN_BLOCK_E; return RAN_BLOCK_E;
} }
output[i++] = (byte)tmpRng; output[i++] = (byte)tmpRng;
@ -1846,12 +1853,15 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
else { else {
/* Use native 32 instruction */ /* Use native 32 instruction */
if (HAL_RNG_GenerateRandomNumber(&hrng, (uint32_t*)&output[i]) != HAL_OK) { if (HAL_RNG_GenerateRandomNumber(&hrng, (uint32_t*)&output[i]) != HAL_OK) {
wolfSSL_CryptHwMutexUnLock();
return RAN_BLOCK_E; return RAN_BLOCK_E;
} }
i += sizeof(word32); i += sizeof(word32);
} }
} }
wolfSSL_CryptHwMutexUnLock();
return 0; return 0;
} }
#elif defined(WOLFSSL_STM32F427_RNG) || defined(WOLFSSL_STM32_RNG_NOLIB) #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. */ * Manual (Chapter 24) for STM32F4xx family. */
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{ {
int i; int ret;
word32 i;
(void)os; (void)os;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* enable RNG peripheral clock */ /* enable RNG peripheral clock */
RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; 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 /* verify no errors, make sure SEIS and CEIS bits are 0
* in RNG->SR register */ * 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; return RNG_FAILURE_E;
}
for (i = 0; i < (int)sz; i++) { for (i = 0; i < sz; i++) {
/* wait until RNG number is ready */ /* wait until RNG number is ready */
while ((RNG->SR & RNG_SR_DRDY) == 0) { } 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; output[i] = RNG->DR;
} }
wolfSSL_CryptHwMutexUnLock();
return 0; 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 */ /* Generate a RNG seed using the STM32 Standard Peripheral Library */
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
{ {
int i; int ret;
word32 i;
(void)os; (void)os;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
/* enable RNG clock source */ /* enable RNG clock source */
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
@ -1908,10 +1934,12 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
RNG_Cmd(ENABLE); RNG_Cmd(ENABLE);
/* verify no errors with RNG_CLK or Seed */ /* 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; return RNG_FAILURE_E;
}
for (i = 0; i < (int)sz; i++) { for (i = 0; i < sz; i++) {
/* wait until RNG number is ready */ /* wait until RNG number is ready */
while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET) { } 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(); output[i] = RNG_GetRandomNumber();
} }
wolfSSL_CryptHwMutexUnLock();
return 0; return 0;
} }
#endif /* WOLFSSL_STM32_CUBEMX */ #endif /* WOLFSSL_STM32_CUBEMX */

View File

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