From 9ea5041d9ded10adf21496abccc9745039fca94f Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Jan 2021 13:42:25 -0800 Subject: [PATCH 1/3] Benchmark for GMAC (AES GCM GHASH). --- wolfcrypt/benchmark/benchmark.c | 50 +++++++++++++++++++++++++++++++++ wolfcrypt/benchmark/benchmark.h | 1 + 2 files changed, 51 insertions(+) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 08c3b4ea5..122f3b7e4 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -888,7 +888,14 @@ static THREAD_LS_T int devId = INVALID_DEVID; #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) + #if !defined(AES_AUTH_ADD_SZ) && \ + defined(STM32_CRYPTO) && !defined(STM32_AESGCM_PARTIAL) + /* For STM32 use multiple of 4 to leverage crypto hardware */ + #define AES_AUTH_ADD_SZ 16 + #endif + #ifndef AES_AUTH_ADD_SZ #define AES_AUTH_ADD_SZ 13 + #endif #define AES_AUTH_TAG_SZ 16 #define BENCH_CIPHER_ADD AES_AUTH_TAG_SZ static word32 aesAuthAddSz = AES_AUTH_ADD_SZ; @@ -1474,6 +1481,8 @@ static void* benchmarks_do(void* args) !defined(NO_HW_BENCH) bench_aesgcm(1); #endif + + bench_gmac(); } #endif #ifdef WOLFSSL_AES_DIRECT @@ -2384,6 +2393,47 @@ void bench_aesgcm(int doAsync) "AES-256-GCM-enc", "AES-256-GCM-dec"); #endif } + +/* GMAC */ +void bench_gmac(void) +{ + int ret, count = 0; + Gmac gmac; + double start; + byte tag[AES_AUTH_TAG_SZ]; + + /* determine GCM GHASH method */ +#ifdef GCM_SMALL + const char* gmacStr = "GMAC Small"; +#elif defined(GCM_TABLE) + const char* gmacStr = "GMAC Table"; +#elif defined(GCM_TABLE_4BIT) + const char* gmacStr = "GMAC Table 4-bit"; +#elif defined(GCM_WORD32) + const char* gmacStr = "GMAC Word32"; +#else + const char* gmacStr = "GMAC Default"; +#endif + + /* init keys */ + XMEMSET(bench_plain, 0, bench_size); + XMEMSET(tag, 0, sizeof(tag)); + XMEMSET(&gmac, 0, sizeof(Gmac)); /* clear context */ + (void)wc_AesInit((Aes*)&gmac, HEAP_HINT, INVALID_DEVID); + wc_GmacSetKey(&gmac, bench_key, 16); + + bench_stats_start(&count, &start); + do { + ret = wc_GmacUpdate(&gmac, bench_iv, 12, bench_plain, bench_size, + tag, sizeof(tag)); + + count++; + } while (bench_stats_sym_check(start)); + wc_AesFree((Aes*)&gmac); + + bench_stats_sym_finish(gmacStr, 0, count, bench_size, start, ret); +} + #endif /* HAVE_AESGCM */ diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h index c2771bb59..4b07a685c 100644 --- a/wolfcrypt/benchmark/benchmark.h +++ b/wolfcrypt/benchmark/benchmark.h @@ -49,6 +49,7 @@ void bench_chacha(void); void bench_chacha20_poly1305_aead(void); void bench_aescbc(int); void bench_aesgcm(int); +void bench_gmac(void); void bench_aesccm(void); void bench_aesecb(int); void bench_aesxts(void); From ea5af87de35a480df40bf4195ad0ea4bad2cedba Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Jan 2021 13:54:26 -0800 Subject: [PATCH 2/3] Revert of uint32_t and uint8_t changes in PR #3658, which caused warnings. --- wolfcrypt/src/aes.c | 160 +++++++++++++++++++++---------------------- wolfcrypt/src/des3.c | 32 ++++----- 2 files changed, 96 insertions(+), 96 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 104f7d1f6..805d777d6 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -340,13 +340,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits HAL_CRYP_Init(&hcryp); #if defined(STM32_HAL_V2) - ret = HAL_CRYP_Encrypt(&hcryp, (word32*)inBlock, AES_BLOCK_SIZE, - (word32*)outBlock, STM32_HAL_TIMEOUT); + ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE, + (uint32_t*)outBlock, STM32_HAL_TIMEOUT); #elif defined(STM32_CRYPTO_AES_ONLY) - ret = HAL_CRYPEx_AES(&hcryp, (byte*)inBlock, AES_BLOCK_SIZE, + ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE, outBlock, STM32_HAL_TIMEOUT); #else - ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (byte*)inBlock, AES_BLOCK_SIZE, + ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE, outBlock, STM32_HAL_TIMEOUT); #endif if (ret != HAL_OK) { @@ -380,18 +380,18 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits /* flush IN/OUT FIFOs */ CRYP_FIFOFlush(); - CRYP_DataIn(*(word32*)&inBlock[0]); - CRYP_DataIn(*(word32*)&inBlock[4]); - CRYP_DataIn(*(word32*)&inBlock[8]); - CRYP_DataIn(*(word32*)&inBlock[12]); + CRYP_DataIn(*(uint32_t*)&inBlock[0]); + CRYP_DataIn(*(uint32_t*)&inBlock[4]); + CRYP_DataIn(*(uint32_t*)&inBlock[8]); + CRYP_DataIn(*(uint32_t*)&inBlock[12]); /* wait until the complete message has been processed */ while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - *(word32*)&outBlock[0] = CRYP_DataOut(); - *(word32*)&outBlock[4] = CRYP_DataOut(); - *(word32*)&outBlock[8] = CRYP_DataOut(); - *(word32*)&outBlock[12] = CRYP_DataOut(); + *(uint32_t*)&outBlock[0] = CRYP_DataOut(); + *(uint32_t*)&outBlock[4] = CRYP_DataOut(); + *(uint32_t*)&outBlock[8] = CRYP_DataOut(); + *(uint32_t*)&outBlock[12] = CRYP_DataOut(); /* disable crypto processor */ CRYP_Cmd(DISABLE); @@ -433,13 +433,13 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits HAL_CRYP_Init(&hcryp); #if defined(STM32_HAL_V2) - ret = HAL_CRYP_Decrypt(&hcryp, (word32*)inBlock, AES_BLOCK_SIZE, - (word32*)outBlock, STM32_HAL_TIMEOUT); + ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE, + (uint32_t*)outBlock, STM32_HAL_TIMEOUT); #elif defined(STM32_CRYPTO_AES_ONLY) - ret = HAL_CRYPEx_AES(&hcryp, (byte*)inBlock, AES_BLOCK_SIZE, + ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE, outBlock, STM32_HAL_TIMEOUT); #else - ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (byte*)inBlock, AES_BLOCK_SIZE, + ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE, outBlock, STM32_HAL_TIMEOUT); #endif if (ret != HAL_OK) { @@ -482,18 +482,18 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits /* flush IN/OUT FIFOs */ CRYP_FIFOFlush(); - CRYP_DataIn(*(word32*)&inBlock[0]); - CRYP_DataIn(*(word32*)&inBlock[4]); - CRYP_DataIn(*(word32*)&inBlock[8]); - CRYP_DataIn(*(word32*)&inBlock[12]); + CRYP_DataIn(*(uint32_t*)&inBlock[0]); + CRYP_DataIn(*(uint32_t*)&inBlock[4]); + CRYP_DataIn(*(uint32_t*)&inBlock[8]); + CRYP_DataIn(*(uint32_t*)&inBlock[12]); /* wait until the complete message has been processed */ while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - *(word32*)&outBlock[0] = CRYP_DataOut(); - *(word32*)&outBlock[4] = CRYP_DataOut(); - *(word32*)&outBlock[8] = CRYP_DataOut(); - *(word32*)&outBlock[12] = CRYP_DataOut(); + *(uint32_t*)&outBlock[0] = CRYP_DataOut(); + *(uint32_t*)&outBlock[4] = CRYP_DataOut(); + *(uint32_t*)&outBlock[8] = CRYP_DataOut(); + *(uint32_t*)&outBlock[12] = CRYP_DataOut(); /* disable crypto processor */ CRYP_Cmd(DISABLE); @@ -3085,13 +3085,13 @@ int wc_AesSetIV(Aes* aes, const byte* iv) HAL_CRYP_Init(&hcryp); #if defined(STM32_HAL_V2) - ret = HAL_CRYP_Encrypt(&hcryp, (word32*)in, blocks * AES_BLOCK_SIZE, - (word32*)out, STM32_HAL_TIMEOUT); + ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * AES_BLOCK_SIZE, + (uint32_t*)out, STM32_HAL_TIMEOUT); #elif defined(STM32_CRYPTO_AES_ONLY) - ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, blocks * AES_BLOCK_SIZE, + ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * AES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); #else - ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (byte*)in, blocks * AES_BLOCK_SIZE, + ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in, blocks * AES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); #endif if (ret != HAL_OK) { @@ -3139,13 +3139,13 @@ int wc_AesSetIV(Aes* aes, const byte* iv) HAL_CRYP_Init(&hcryp); #if defined(STM32_HAL_V2) - ret = HAL_CRYP_Decrypt(&hcryp, (word32*)in, blocks * AES_BLOCK_SIZE, - (word32*)out, STM32_HAL_TIMEOUT); + ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * AES_BLOCK_SIZE, + (uint32_t*)out, STM32_HAL_TIMEOUT); #elif defined(STM32_CRYPTO_AES_ONLY) - ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, blocks * AES_BLOCK_SIZE, + ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * AES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); #else - ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (byte*)in, blocks * AES_BLOCK_SIZE, + ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in, blocks * AES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); #endif if (ret != HAL_OK) { @@ -3209,18 +3209,18 @@ int wc_AesSetIV(Aes* aes, const byte* iv) /* flush IN/OUT FIFOs */ CRYP_FIFOFlush(); - CRYP_DataIn(*(word32*)&in[0]); - CRYP_DataIn(*(word32*)&in[4]); - CRYP_DataIn(*(word32*)&in[8]); - CRYP_DataIn(*(word32*)&in[12]); + CRYP_DataIn(*(uint32_t*)&in[0]); + CRYP_DataIn(*(uint32_t*)&in[4]); + CRYP_DataIn(*(uint32_t*)&in[8]); + CRYP_DataIn(*(uint32_t*)&in[12]); /* wait until the complete message has been processed */ while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - *(word32*)&out[0] = CRYP_DataOut(); - *(word32*)&out[4] = CRYP_DataOut(); - *(word32*)&out[8] = CRYP_DataOut(); - *(word32*)&out[12] = CRYP_DataOut(); + *(uint32_t*)&out[0] = CRYP_DataOut(); + *(uint32_t*)&out[4] = CRYP_DataOut(); + *(uint32_t*)&out[8] = CRYP_DataOut(); + *(uint32_t*)&out[12] = CRYP_DataOut(); /* store iv for next call */ XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); @@ -3296,18 +3296,18 @@ int wc_AesSetIV(Aes* aes, const byte* iv) /* flush IN/OUT FIFOs */ CRYP_FIFOFlush(); - CRYP_DataIn(*(word32*)&in[0]); - CRYP_DataIn(*(word32*)&in[4]); - CRYP_DataIn(*(word32*)&in[8]); - CRYP_DataIn(*(word32*)&in[12]); + CRYP_DataIn(*(uint32_t*)&in[0]); + CRYP_DataIn(*(uint32_t*)&in[4]); + CRYP_DataIn(*(uint32_t*)&in[8]); + CRYP_DataIn(*(uint32_t*)&in[12]); /* wait until the complete message has been processed */ while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - *(word32*)&out[0] = CRYP_DataOut(); - *(word32*)&out[4] = CRYP_DataOut(); - *(word32*)&out[8] = CRYP_DataOut(); - *(word32*)&out[12] = CRYP_DataOut(); + *(uint32_t*)&out[0] = CRYP_DataOut(); + *(uint32_t*)&out[4] = CRYP_DataOut(); + *(uint32_t*)&out[8] = CRYP_DataOut(); + *(uint32_t*)&out[12] = CRYP_DataOut(); /* store iv for next call */ XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); @@ -3618,11 +3618,11 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES) int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { - return SaSi_AesBlock(&aes->ctx.user_ctx, (byte* )in, sz, out); + return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out); } int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) { - return SaSi_AesBlock(&aes->ctx.user_ctx, (byte* )in, sz, out); + return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out); } #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) /* implemented in wolfcrypt/src/port/caam/caam_aes.c */ @@ -3898,8 +3898,8 @@ int wc_AesSetIV(Aes* aes, const byte* iv) HAL_CRYP_Init(&hcryp); #if defined(STM32_HAL_V2) - ret = HAL_CRYP_Encrypt(&hcryp, (word32*)in, AES_BLOCK_SIZE, - (word32*)out, STM32_HAL_TIMEOUT); + ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE, + (uint32_t*)out, STM32_HAL_TIMEOUT); #elif defined(STM32_CRYPTO_AES_ONLY) ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, AES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); @@ -3949,18 +3949,18 @@ int wc_AesSetIV(Aes* aes, const byte* iv) /* flush IN/OUT FIFOs */ CRYP_FIFOFlush(); - CRYP_DataIn(*(word32*)&in[0]); - CRYP_DataIn(*(word32*)&in[4]); - CRYP_DataIn(*(word32*)&in[8]); - CRYP_DataIn(*(word32*)&in[12]); + CRYP_DataIn(*(uint32_t*)&in[0]); + CRYP_DataIn(*(uint32_t*)&in[4]); + CRYP_DataIn(*(uint32_t*)&in[8]); + CRYP_DataIn(*(uint32_t*)&in[12]); /* wait until the complete message has been processed */ while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - *(word32*)&out[0] = CRYP_DataOut(); - *(word32*)&out[4] = CRYP_DataOut(); - *(word32*)&out[8] = CRYP_DataOut(); - *(word32*)&out[12] = CRYP_DataOut(); + *(uint32_t*)&out[0] = CRYP_DataOut(); + *(uint32_t*)&out[4] = CRYP_DataOut(); + *(uint32_t*)&out[8] = CRYP_DataOut(); + *(uint32_t*)&out[12] = CRYP_DataOut(); /* disable crypto processor */ CRYP_Cmd(DISABLE); @@ -4020,7 +4020,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv) return ret; LTC_AES_CryptCtr(LTC_BASE, in, out, sz, iv, enc_key, keySize, (byte*)aes->tmp, - (word32*)&aes->left); + (uint32_t*)&aes->left); wolfSSL_CryptHwMutexUnLock(); } @@ -6520,11 +6520,11 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz HAL_CRYP_Init(&hcryp); /* GCM payload phase - can handle partial blocks */ - status = HAL_CRYP_Encrypt(&hcryp, (word32*)in, - (blocks * AES_BLOCK_SIZE) + partial, (word32*)out, STM32_HAL_TIMEOUT); if (status == HAL_OK) { + status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, + (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT); /* Compute the authTag */ - status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (word32*)tag, + status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag, STM32_HAL_TIMEOUT); } #elif defined(STM32_CRYPTO_AES_ONLY) @@ -6556,14 +6556,14 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz /* GCM payload phase - partial remainder */ XMEMSET(partialBlock, 0, sizeof(partialBlock)); XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial); - status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial, - (byte*)partialBlock, STM32_HAL_TIMEOUT); + status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial, + (uint8_t*)partialBlock, STM32_HAL_TIMEOUT); XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial); } if (status == HAL_OK) { /* GCM final phase */ hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE; - status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT); + status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT); } #else hcryp.Init.HeaderSize = authPadSz; @@ -6577,13 +6577,13 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz /* GCM payload phase - partial remainder */ XMEMSET(partialBlock, 0, sizeof(partialBlock)); XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial); - status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)partialBlock, partial, - (byte*)partialBlock, STM32_HAL_TIMEOUT); + status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial, + (uint8_t*)partialBlock, STM32_HAL_TIMEOUT); XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial); } if (status == HAL_OK) { /* Compute the authTag */ - status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT); + status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT); } #endif @@ -6593,11 +6593,11 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz #else /* Standard Peripheral Library */ ByteReverseWords(keyCopy, (word32*)aes->key, keySize); - status = CRYP_AES_GCM(MODE_ENCRYPT, (byte*)ctr, - (byte*)keyCopy, keySize * 8, - (byte*)in, sz, - (byte*)authInPadded, authInSz, - (byte*)out, (byte*)tag); + status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr, + (uint8_t*)keyCopy, keySize * 8, + (uint8_t*)in, sz, + (uint8_t*)authInPadded, authInSz, + (uint8_t*)out, (uint8_t*)tag); if (status != SUCCESS) ret = AES_GCM_AUTH_E; #endif /* WOLFSSL_STM32_CUBEMX */ @@ -7068,11 +7068,11 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out, * 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, (byte*)ctr, - (byte*)keyCopy, keySize * 8, - (byte*)in, sz, - (byte*)authInPadded, authInSz, - (byte*)out, (byte*)partialBlock); + 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*)partialBlock); if (status != SUCCESS) ret = AES_GCM_AUTH_E; if (tagComputed == 0) diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index bc8971e82..a6548dc5d 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -216,8 +216,8 @@ hcryp.Instance = CRYP; hcryp.Init.KeySize = CRYP_KEYSIZE_128B; hcryp.Init.DataType = CRYP_DATATYPE_8B; - hcryp.Init.pKey = (byte*)des->key; - hcryp.Init.pInitVect = (byte*)des->reg; + hcryp.Init.pKey = (uint8_t*)des->key; + hcryp.Init.pInitVect = (uint8_t*)des->reg; HAL_CRYP_Init(&hcryp); @@ -227,21 +227,21 @@ if (mode == DES_CBC) { if (dir == DES_ENCRYPTION) { - HAL_CRYP_DESCBC_Encrypt(&hcryp, (byte*)in, + HAL_CRYP_DESCBC_Encrypt(&hcryp, (uint8_t*)in, DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); } else { - HAL_CRYP_DESCBC_Decrypt(&hcryp, (byte*)in, + HAL_CRYP_DESCBC_Decrypt(&hcryp, (uint8_t*)in, DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); } } else { if (dir == DES_ENCRYPTION) { - HAL_CRYP_DESECB_Encrypt(&hcryp, (byte*)in, + HAL_CRYP_DESECB_Encrypt(&hcryp, (uint8_t*)in, DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); } else { - HAL_CRYP_DESECB_Decrypt(&hcryp, (byte*)in, + HAL_CRYP_DESECB_Decrypt(&hcryp, (uint8_t*)in, DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); } } @@ -304,14 +304,14 @@ /* if input and output same will overwrite input iv */ XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE); - CRYP_DataIn(*(word32*)&in[0]); - CRYP_DataIn(*(word32*)&in[4]); + CRYP_DataIn(*(uint32_t*)&in[0]); + CRYP_DataIn(*(uint32_t*)&in[4]); /* wait until the complete message has been processed */ while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - *(word32*)&out[0] = CRYP_DataOut(); - *(word32*)&out[4] = CRYP_DataOut(); + *(uint32_t*)&out[0] = CRYP_DataOut(); + *(uint32_t*)&out[4] = CRYP_DataOut(); /* store iv for next call */ XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE); @@ -359,8 +359,8 @@ hcryp.Instance = CRYP; hcryp.Init.KeySize = CRYP_KEYSIZE_128B; hcryp.Init.DataType = CRYP_DATATYPE_8B; - hcryp.Init.pKey = (byte*)des->key; - hcryp.Init.pInitVect = (byte*)des->reg; + hcryp.Init.pKey = (uint8_t*)des->key; + hcryp.Init.pInitVect = (uint8_t*)des->reg; HAL_CRYP_Init(&hcryp); @@ -439,14 +439,14 @@ /* flush IN/OUT FIFOs */ CRYP_FIFOFlush(); - CRYP_DataIn(*(word32*)&in[0]); - CRYP_DataIn(*(word32*)&in[4]); + CRYP_DataIn(*(uint32_t*)&in[0]); + CRYP_DataIn(*(uint32_t*)&in[4]); /* wait until the complete message has been processed */ while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} - *(word32*)&out[0] = CRYP_DataOut(); - *(word32*)&out[4] = CRYP_DataOut(); + *(uint32_t*)&out[0] = CRYP_DataOut(); + *(uint32_t*)&out[4] = CRYP_DataOut(); /* store iv for next call */ XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE); From 9044f709c11ba20a679894a3cd6a34530ebf63cc Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Jan 2021 13:54:53 -0800 Subject: [PATCH 3/3] Add support for `STM32_AESGCM_PARTIAL` build option to speedup platforms that allow AAD header sizes that are not a multiple of 4 bytes. ZD 11364. --- IDE/STM32Cube/README.md | 31 ++++++++++++++++ IDE/STM32Cube/default_conf.ftl | 1 + wolfcrypt/src/aes.c | 66 +++++++++++++++++++++++++--------- 3 files changed, 81 insertions(+), 17 deletions(-) diff --git a/IDE/STM32Cube/README.md b/IDE/STM32Cube/README.md index 4f75f04ce..1109d5f45 100644 --- a/IDE/STM32Cube/README.md +++ b/IDE/STM32Cube/README.md @@ -42,6 +42,37 @@ To enable the latest Cube HAL support please define `STM32_HAL_V2`. If you'd like to use the older Standard Peripheral library undefine `WOLFSSL_STM32_CUBEMX`. +With STM32 Cube HAL v2 some AES GCM hardware has a limitation for the AAD header, which must be a multiple of 4 bytes. + +If using `STM32_AESGCM_PARTIAL` with the following patch it will enable use for all AAD header sizes. The `STM32Cube_FW_F7_V1.16.0` patch is: + +``` +diff --git a/Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_cryp.h b/Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_cryp.h +--- a/Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_cryp.h ++++ b/Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_cryp.h +@@ -63,6 +63,7 @@ typedef struct + GCM : also known as Additional Authentication Data + CCM : named B1 composed of the associated data length and Associated Data. */ + uint32_t HeaderSize; /*!< The size of header buffer in word */ ++ uint32_t HeaderPadSize; /*!< The size of padding in bytes added to actual header data to pad it to a multiple of 32 bits */ + uint32_t *B0; /*!< B0 is first authentication block used only in AES CCM mode */ + uint32_t DataWidthUnit; /*!< Data With Unit, this parameter can be value of @ref CRYP_Data_Width_Unit*/ + uint32_t KeyIVConfigSkip; /*!< CRYP peripheral Key and IV configuration skip, to config Key and Initialization + +diff --git a/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cryp_ex.c b/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cryp_ex.c +--- a/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cryp_ex.c ++++ b/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cryp_ex.c +@@ -132,6 +132,8 @@ HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, u + uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* input length in bits */ + uint32_t tagaddr = (uint32_t)AuthTag; + ++ headerlength -= ((uint64_t)(hcryp->Init.HeaderPadSize) * 8U); /* Decrement the header size removing the pad size */ ++ + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process locked */ +``` + If you are using FreeRTOS make sure your `FreeRTOSConfig.h` has its `configTOTAL_HEAP_SIZE` increased. The TLS client/server benchmark example requires about 76 KB for allocated tasks (with stack) and peak heap. This uses both a TLS client and server to test a TLS connection locally for each enabled TLS cipher suite. diff --git a/IDE/STM32Cube/default_conf.ftl b/IDE/STM32Cube/default_conf.ftl index 3b7cfcadc..3f67578e5 100644 --- a/IDE/STM32Cube/default_conf.ftl +++ b/IDE/STM32Cube/default_conf.ftl @@ -86,6 +86,7 @@ extern ${variable.value} ${variable.name}; #undef NO_STM32_CRYPTO #define STM32_HAL_V2 #define HAL_CONSOLE_UART huart2 + #define STM32_AESGCM_PARTIAL /* allow partial blocks and add auth info (header) */ #elif defined(STM32H753xx) #define WOLFSSL_STM32H7 #undef NO_STM32_HASH diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 805d777d6..3f24dfa52 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -6430,6 +6430,9 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, #ifdef STM32_CRYPTO_AES_GCM /* this function supports inline encrypt */ +/* define STM32_AESGCM_PARTIAL for newer STM Cube HAL's with workaround + for handling partial packets to improve auth tag calculation performance by + using hardware */ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz, @@ -6455,7 +6458,7 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz word32 ctr[AES_BLOCK_SIZE/sizeof(word32)]; word32 authhdr[AES_BLOCK_SIZE/sizeof(word32)]; byte* authInPadded = NULL; - int authPadSz, wasAlloc = 0; + int authPadSz, wasAlloc = 0, useSwGhash = 0; ret = wc_AesGetKeySize(aes, &keySize); if (ret != 0) @@ -6501,6 +6504,17 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz authInPadded = (byte*)authIn; } + /* for cases where hardware cannot be used for authTag calculate it */ + /* if IV is not 12 calculate GHASH using software */ + if (ivSz != GCM_NONCE_MID_SZ +#ifndef STM32_AESGCM_PARTIAL + /* or authIn is not a multiple of 4 */ + || authPadSz != authInSz || sz == 0 || partial != 0 +#endif + ) { + useSwGhash = 1; + } + /* Hardware requires counter + 1 */ IncrementGcmCounter((byte*)ctr); @@ -6513,16 +6527,19 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded; #if defined(STM32_HAL_V2) - hcryp.Init.Algorithm = CRYP_AES_GCM; + hcryp.Init.Algorithm = CRYP_AES_GCM; hcryp.Init.HeaderSize = authPadSz/sizeof(word32); + #ifdef STM32_AESGCM_PARTIAL + hcryp.Init.HeaderPadSize = authPadSz - authInSz; + #endif ByteReverseWords(partialBlock, ctr, AES_BLOCK_SIZE); hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock; HAL_CRYP_Init(&hcryp); /* GCM payload phase - can handle partial blocks */ - if (status == HAL_OK) { status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT); + if (status == HAL_OK && !useSwGhash) { /* Compute the authTag */ status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag, STM32_HAL_TIMEOUT); @@ -6560,7 +6577,7 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz (uint8_t*)partialBlock, STM32_HAL_TIMEOUT); XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial); } - if (status == HAL_OK) { + if (status == HAL_OK && !useSwGhash) { /* GCM final phase */ hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE; status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT); @@ -6581,7 +6598,7 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz (uint8_t*)partialBlock, STM32_HAL_TIMEOUT); XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial); } - if (status == HAL_OK) { + if (status == HAL_OK && !useSwGhash) { /* Compute the authTag */ status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT); } @@ -6606,13 +6623,13 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz if (ret == 0) { /* return authTag */ if (authTag) { - /* For STM32 GCM fallback to software if partial AES block or IV != 12 */ - if (sz == 0 || partial != 0 || ivSz != GCM_NONCE_MID_SZ) { + if (useSwGhash) { GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag); xorbuf(authTag, tag, authTagSz); } else { + /* use hardware calculated tag */ XMEMCPY(authTag, tag, authTagSz); } } @@ -6939,18 +6956,31 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out, * For TLS blocks the authTag is after the output buffer, so save it */ XMEMCPY(tagExpected, authTag, authTagSz); + /* Authentication buffer - must be 4-byte multiple zero padded */ + authPadSz = authInSz % sizeof(word32); + if (authPadSz != 0) { + authPadSz = authInSz + sizeof(word32) - authPadSz; + } + else { + authPadSz = authInSz; + } + /* for cases where hardware cannot be used for authTag calculate it */ - if (sz == 0 || partial != 0 || ivSz != GCM_NONCE_MID_SZ) { + /* if IV is not 12 calculate GHASH using software */ + if (ivSz != GCM_NONCE_MID_SZ || sz == 0 || partial != 0 +#ifndef STM32_AESGCM_PARTIAL + /* or authIn is not a multiple of 4 */ + || authPadSz != authInSz +#endif + ) { 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); - if (authPadSz != 0) { - authPadSz = authInSz + sizeof(word32) - authPadSz; + /* if using hardware for authentication tag make sure its aligned and zero padded */ + if (authPadSz != authInSz && !tagComputed) { if (authPadSz <= sizeof(authhdr)) { authInPadded = (byte*)authhdr; } @@ -6966,7 +6996,6 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out, XMEMSET(authInPadded, 0, authPadSz); XMEMCPY(authInPadded, authIn, authInSz); } else { - authPadSz = authInSz; authInPadded = (byte*)authIn; } @@ -6982,18 +7011,21 @@ static int wc_AesGcmDecrypt_STM32(Aes* aes, byte* out, hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded; #if defined(STM32_HAL_V2) - hcryp.Init.HeaderSize = authPadSz/sizeof(word32); hcryp.Init.Algorithm = CRYP_AES_GCM; + hcryp.Init.HeaderSize = authPadSz/sizeof(word32); + #ifdef STM32_AESGCM_PARTIAL + hcryp.Init.HeaderPadSize = authPadSz - authInSz; + #endif ByteReverseWords(partialBlock, ctr, AES_BLOCK_SIZE); hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)partialBlock; HAL_CRYP_Init(&hcryp); /* GCM payload phase - can handle partial blocks */ - status = HAL_CRYP_Decrypt(&hcryp, (word32*)in, - (blocks * AES_BLOCK_SIZE) + partial, (word32*)out, STM32_HAL_TIMEOUT); + status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, + (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT); if (status == HAL_OK && tagComputed == 0) { /* Compute the authTag */ - status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (word32*)tag, + status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag, STM32_HAL_TIMEOUT); } #elif defined(STM32_CRYPTO_AES_ONLY)