Merge pull request #3649 from dgarske/stm_aesgcm_perf

STM32 AES GCM crypto hardware performance improvements
This commit is contained in:
toddouska
2021-01-21 15:55:58 -08:00
committed by GitHub
6 changed files with 228 additions and 113 deletions

View File

@@ -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; /*!< <PATCH> The size of padding in bytes added to actual header data to pad it to a multiple of 32 bits </PATCH> */
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); /* <PATCH> Decrement the header size removing the pad size </PATCH> */
+
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.

View File

@@ -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

View File

@@ -885,7 +885,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;
@@ -1471,6 +1478,8 @@ static void* benchmarks_do(void* args)
!defined(NO_HW_BENCH)
bench_aesgcm(1);
#endif
bench_gmac();
}
#endif
#ifdef WOLFSSL_AES_DIRECT
@@ -2381,6 +2390,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 */

View File

@@ -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);

View File

@@ -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();
}
@@ -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,18 +6527,21 @@ 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 */
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);
if (status == HAL_OK && !useSwGhash) {
/* 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 +6573,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) {
if (status == HAL_OK && !useSwGhash) {
/* 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 +6594,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) {
if (status == HAL_OK && !useSwGhash) {
/* 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 +6610,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 */
@@ -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)
@@ -7068,11 +7100,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)

View File

@@ -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);