Merge pull request #3951 from dgarske/stm32_aes_h7

Fix for AES GCM with STM32H7
This commit is contained in:
Chris Conlon
2021-04-20 10:14:13 -06:00
committed by GitHub
2 changed files with 77 additions and 17 deletions

View File

@@ -6987,10 +6987,14 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz
/* for cases where hardware cannot be used for authTag calculate it */ /* for cases where hardware cannot be used for authTag calculate it */
/* if IV is not 12 calculate GHASH using software */ /* if IV is not 12 calculate GHASH using software */
if (ivSz != GCM_NONCE_MID_SZ if (ivSz != GCM_NONCE_MID_SZ
#ifndef STM32_AESGCM_PARTIAL #ifndef CRYP_HEADERWIDTHUNIT_BYTE
/* or harware that does not support partial block */
|| sz == 0 || partial != 0
#endif
#ifndef STM32_AESGCM_PARTIAL
/* or authIn is not a multiple of 4 */ /* or authIn is not a multiple of 4 */
|| authPadSz != authInSz || sz == 0 || partial != 0 || authPadSz != authInSz
#endif #endif
) { ) {
useSwGhash = 1; useSwGhash = 1;
} }
@@ -7008,17 +7012,42 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz
#if defined(STM32_HAL_V2) #if defined(STM32_HAL_V2)
hcryp.Init.Algorithm = CRYP_AES_GCM; hcryp.Init.Algorithm = CRYP_AES_GCM;
#ifdef CRYP_HEADERWIDTHUNIT_BYTE
/* V2 with CRYP_HEADERWIDTHUNIT_BYTE uses byte size for header */
hcryp.Init.HeaderSize = authPadSz;
#else
hcryp.Init.HeaderSize = authPadSz/sizeof(word32); hcryp.Init.HeaderSize = authPadSz/sizeof(word32);
#endif
#ifdef STM32_AESGCM_PARTIAL #ifdef STM32_AESGCM_PARTIAL
hcryp.Init.HeaderPadSize = authPadSz - authInSz; hcryp.Init.HeaderPadSize = authPadSz - authInSz;
#endif #endif
ByteReverseWords(partialBlock, ctr, AES_BLOCK_SIZE); #ifdef CRYP_KEYIVCONFIG_ONCE
hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock; /* allows repeated calls to HAL_CRYP_Encrypt */
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
#endif
ByteReverseWords(ctr, ctr, AES_BLOCK_SIZE);
hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
HAL_CRYP_Init(&hcryp); HAL_CRYP_Init(&hcryp);
#ifndef CRYP_KEYIVCONFIG_ONCE
/* GCM payload phase - can handle partial blocks */ /* GCM payload phase - can handle partial blocks */
status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
(blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT); (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
#else
/* GCM payload phase - blocks */
if (blocks) {
status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
(blocks * AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
}
/* GCM payload phase - partial remainder */
if (status == HAL_OK && (partial != 0 || blocks == 0)) {
XMEMSET(partialBlock, 0, sizeof(partialBlock));
XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
(uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
}
#endif
if (status == HAL_OK && !useSwGhash) { if (status == HAL_OK && !useSwGhash) {
/* Compute the authTag */ /* Compute the authTag */
status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag, status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
@@ -7447,16 +7476,20 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
/* for cases where hardware cannot be used for authTag calculate it */ /* for cases where hardware cannot be used for authTag calculate it */
/* if IV is not 12 calculate GHASH using software */ /* if IV is not 12 calculate GHASH using software */
if (ivSz != GCM_NONCE_MID_SZ || sz == 0 || partial != 0 if (ivSz != GCM_NONCE_MID_SZ
#ifndef STM32_AESGCM_PARTIAL #ifndef CRYP_HEADERWIDTHUNIT_BYTE
/* or harware that does not support partial block */
|| sz == 0 || partial != 0
#endif
#ifndef STM32_AESGCM_PARTIAL
/* or authIn is not a multiple of 4 */ /* or authIn is not a multiple of 4 */
|| authPadSz != authInSz || authPadSz != authInSz
#endif #endif
) { ) {
GHASH(aes, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag)); GHASH(aes, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock); wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
xorbuf(tag, partialBlock, sizeof(tag)); xorbuf(tag, partialBlock, sizeof(tag));
tagComputed = 1; tagComputed = 1;
} }
/* if using hardware for authentication tag make sure its aligned and zero padded */ /* if using hardware for authentication tag make sure its aligned and zero padded */
@@ -7492,18 +7525,42 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
#if defined(STM32_HAL_V2) #if defined(STM32_HAL_V2)
hcryp.Init.Algorithm = CRYP_AES_GCM; hcryp.Init.Algorithm = CRYP_AES_GCM;
#ifdef CRYP_HEADERWIDTHUNIT_BYTE
/* V2 with CRYP_HEADERWIDTHUNIT_BYTE uses byte size for header */
hcryp.Init.HeaderSize = authPadSz;
#else
hcryp.Init.HeaderSize = authPadSz/sizeof(word32); hcryp.Init.HeaderSize = authPadSz/sizeof(word32);
#endif
#ifdef STM32_AESGCM_PARTIAL #ifdef STM32_AESGCM_PARTIAL
hcryp.Init.HeaderPadSize = authPadSz - authInSz; hcryp.Init.HeaderPadSize = authPadSz - authInSz;
#endif #endif
ByteReverseWords(partialBlock, ctr, AES_BLOCK_SIZE); #ifdef CRYP_KEYIVCONFIG_ONCE
hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock; /* allows repeated calls to HAL_CRYP_Decrypt */
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
#endif
ByteReverseWords(ctr, ctr, AES_BLOCK_SIZE);
hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
HAL_CRYP_Init(&hcryp); HAL_CRYP_Init(&hcryp);
/* GCM payload phase - can handle partial blocks */ #ifndef CRYP_KEYIVCONFIG_ONCE
status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
(blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT); (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
if (status == HAL_OK && tagComputed == 0) { #else
/* GCM payload phase - blocks */
if (blocks) {
status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
(blocks * AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
}
/* GCM payload phase - partial remainder */
if (status == HAL_OK && (partial != 0 || blocks == 0)) {
XMEMSET(partialBlock, 0, sizeof(partialBlock));
XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
( uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
}
#endif
if (status == HAL_OK && !tagComputed) {
/* Compute the authTag */ /* Compute the authTag */
status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag, status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
STM32_HAL_TIMEOUT); STM32_HAL_TIMEOUT);
@@ -7588,7 +7645,7 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
if (status != SUCCESS) if (status != SUCCESS)
ret = AES_GCM_AUTH_E; ret = AES_GCM_AUTH_E;
if (tagComputed == 0) if (tagComputed == 0)
XMEMCPY(tag, partialBlock, authTagSz); XMEMCPY(tag, partialBlock, authTagSz);
#endif /* WOLFSSL_STM32_CUBEMX */ #endif /* WOLFSSL_STM32_CUBEMX */
wolfSSL_CryptHwMutexUnLock(); wolfSSL_CryptHwMutexUnLock();

View File

@@ -294,6 +294,9 @@ int wc_Stm32_Aes_Init(Aes* aes, CRYP_HandleTypeDef* hcryp)
hcryp->Init.pKey = (STM_CRYPT_TYPE*)aes->key; hcryp->Init.pKey = (STM_CRYPT_TYPE*)aes->key;
#ifdef STM32_HAL_V2 #ifdef STM32_HAL_V2
hcryp->Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE; hcryp->Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
#ifdef CRYP_HEADERWIDTHUNIT_BYTE
hcryp->Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
#endif
#endif #endif
return 0; return 0;