Merge pull request #3320 from dgarske/stmcube

STM32 Cube Pack and AES GCM improvements
This commit is contained in:
toddouska
2020-09-23 14:39:53 -07:00
committed by GitHub
8 changed files with 632 additions and 31 deletions

View File

@@ -6347,12 +6347,12 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
word32 keySize;
word32 partial = sz % AES_BLOCK_SIZE;
word32 tag[AES_BLOCK_SIZE/sizeof(word32)];
word32 tagExpected[AES_BLOCK_SIZE/sizeof(word32)];
word32 partialBlock[AES_BLOCK_SIZE/sizeof(word32)];
word32 ctr[AES_BLOCK_SIZE/sizeof(word32)];
word32 ctrInit[AES_BLOCK_SIZE/sizeof(word32)];
word32 authhdr[AES_BLOCK_SIZE/sizeof(word32)];
byte* authInPadded = NULL;
int authPadSz, wasAlloc = 0;
int authPadSz, wasAlloc = 0, tagComputed = 0;
ret = wc_AesGetKeySize(aes, &keySize);
if (ret != 0)
@@ -6373,7 +6373,19 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
else {
GHASH(aes, NULL, 0, iv, ivSz, (byte*)ctr, AES_BLOCK_SIZE);
}
XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
/* Make copy of expected authTag, which could get corrupted in some
* Cube HAL versions without proper partial block support.
* For TLS blocks the authTag is after the output buffer, so save it */
XMEMCPY(tagExpected, authTag, authTagSz);
/* for cases where hardware cannot be used for authTag calculate it */
if (sz == 0 || partial != 0 || ivSz != GCM_NONCE_MID_SZ) {
GHASH(aes, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
xorbuf(tag, partialBlock, sizeof(tag));
tagComputed = 1;
}
/* Authentication buffer - must be 4-byte multiple zero padded */
authPadSz = authInSz % sizeof(word32);
@@ -6419,7 +6431,7 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
/* GCM payload phase - can handle partial blocks */
status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
(blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
if (status == HAL_OK) {
if (status == HAL_OK && tagComputed == 0) {
/* Compute the authTag */
status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
STM32_HAL_TIMEOUT);
@@ -6457,7 +6469,7 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
(byte*)partialBlock, STM32_HAL_TIMEOUT);
XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
}
if (status == HAL_OK) {
if (status == HAL_OK && tagComputed == 0) {
/* GCM final phase */
hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
@@ -6478,7 +6490,7 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
(byte*)partialBlock, STM32_HAL_TIMEOUT);
XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
}
if (status == HAL_OK) {
if (status == HAL_OK && tagComputed == 0) {
/* Compute the authTag */
status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
}
@@ -6495,25 +6507,21 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out,
/* Input size and auth size need to be the actual sizes, even though
* they are not block aligned, because this length (in bits) is used
* in the final GHASH. */
XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
(uint8_t*)keyCopy, keySize * 8,
(uint8_t*)in, sz,
(uint8_t*)authInPadded, authInSz,
(uint8_t*)out, (uint8_t*)tag);
(uint8_t*)out, (uint8_t*)partialBlock);
if (status != SUCCESS)
ret = AES_GCM_AUTH_E;
if (tagComputed == 0)
XMEMCPY(tag, partialBlock, authTagSz);
#endif /* WOLFSSL_STM32_CUBEMX */
wolfSSL_CryptHwMutexUnLock();
/* For STM32 GCM fallback to software if partial AES block or IV != 12 */
if (sz == 0 || partial != 0 || ivSz != GCM_NONCE_MID_SZ) {
GHASH(aes, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)partialBlock);
xorbuf(tag, partialBlock, sizeof(tag));
}
/* Check authentication tag */
if (ConstantCompare(authTag, (byte*)tag, authTagSz) != 0) {
if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
ret = AES_GCM_AUTH_E;
}