From 7a936d731d3e85dd68784487d187de93365125ac Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 12 May 2025 12:19:20 -0700 Subject: [PATCH 1/3] Fix edge case issue with STM32 AES GCM auth padding. Issue introduced in PR #8584. Fixes ZD 19783 Added way to override STM_CRYPT_HEADER_WIDTH. --- wolfcrypt/src/aes.c | 48 +++++++++++++++++-------------- wolfssl/wolfcrypt/port/st/stm32.h | 15 ++++++---- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 6e7f104dd..d67295f77 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -8345,19 +8345,22 @@ static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32( } XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */ - /* Authentication buffer - must be 4-byte multiple zero padded */ - authPadSz = authInSz % sizeof(word32); + /* Authentication buffer */ +#if STM_CRYPT_HEADER_WIDTH == 1 + authPadSz = 0; /* CubeHAL supports byte mode */ +#else + authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH; +#endif #ifdef WOLFSSL_STM32MP13 /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a - * minimum of 16 bytes for the auth - */ + * minimum of 16 bytes for the auth */ if ((authInSz > 0) && (authInSz < 16)) { authPadSz = 16 - authInSz; } #endif if (authPadSz != 0) { - if (authPadSz < authInSz + sizeof(word32)) { - authPadSz = authInSz + sizeof(word32) - authPadSz; + if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) { + authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz; } if (authPadSz <= sizeof(authhdr)) { authInPadded = (byte*)authhdr; @@ -8385,7 +8388,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32( /* or hardware that does not support partial block */ || sz == 0 || partial != 0 #endif - #if !defined(STM_CRYPT_HEADER_WIDTH) || STM_CRYPT_HEADER_WIDTH == 4 + #if STM_CRYPT_HEADER_WIDTH == 4 /* or authIn is not a multiple of 4 */ || authPadSz != authInSz #endif @@ -8444,7 +8447,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32( /* Set the CRYP parameters */ hcryp.Init.HeaderSize = authPadSz; if (authPadSz == 0) - hcryp.Init.Header = NULL; /* cannot pass pointer here when authIn == 0 */ + hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */ hcryp.Init.ChainingMode = CRYP_CHAINMODE_AES_GCM_GMAC; hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT; hcryp.Init.GCMCMACPhase = CRYP_INIT_PHASE; @@ -8884,23 +8887,25 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( * 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; - } - + /* Authentication buffer */ +#if STM_CRYPT_HEADER_WIDTH == 1 + authPadSz = 0; /* CubeHAL supports byte mode */ +#else + authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH; +#endif #ifdef WOLFSSL_STM32MP13 /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a - * minimum of 16 bytes for the auth - */ + * minimum of 16 bytes for the auth */ if ((authInSz > 0) && (authInSz < 16)) { authPadSz = 16 - authInSz; } #endif + if (authPadSz != 0) { + authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz; + } + else { + authPadSz = authInSz; + } /* for cases where hardware cannot be used for authTag calculate it */ /* if IV is not 12 calculate GHASH using software */ @@ -8909,7 +8914,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( /* or hardware that does not support partial block */ || sz == 0 || partial != 0 #endif - #if !defined(STM_CRYPT_HEADER_WIDTH) || STM_CRYPT_HEADER_WIDTH == 4 + #if STM_CRYPT_HEADER_WIDTH == 4 /* or authIn is not a multiple of 4 */ || authPadSz != authInSz #endif @@ -8949,6 +8954,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( if (ret != 0) { return ret; } + #ifdef WOLFSSL_STM32_CUBEMX hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr; hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded; @@ -8956,7 +8962,6 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( #if defined(STM32_HAL_V2) hcryp.Init.Algorithm = CRYP_AES_GCM; hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH; - #ifdef CRYP_KEYIVCONFIG_ONCE /* allows repeated calls to HAL_CRYP_Decrypt */ hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE; @@ -8966,6 +8971,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( HAL_CRYP_Init(&hcryp); #ifndef CRYP_KEYIVCONFIG_ONCE + /* GCM payload phase - can handle partial blocks */ status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT); #else diff --git a/wolfssl/wolfcrypt/port/st/stm32.h b/wolfssl/wolfcrypt/port/st/stm32.h index 94195f60e..b3768ae7b 100644 --- a/wolfssl/wolfcrypt/port/st/stm32.h +++ b/wolfssl/wolfcrypt/port/st/stm32.h @@ -188,12 +188,15 @@ int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo, #define STM_CRYPT_TYPE uint8_t #endif - /* newer crypt HAL requires auth header size as 4 bytes (word) */ - #if defined(CRYP_HEADERWIDTHUNIT_BYTE) && \ - !defined(WOLFSSL_STM32MP13) && !defined(WOLFSSL_STM32H7S) - #define STM_CRYPT_HEADER_WIDTH 1 - #else - #define STM_CRYPT_HEADER_WIDTH 4 + /* Determine minimum AES GCM alignment supported */ + #ifndef STM_CRYPT_HEADER_WIDTH + /* newer crypt HAL requires auth header size as 4 bytes (word) */ + #if defined(CRYP_HEADERWIDTHUNIT_BYTE) && \ + !defined(WOLFSSL_STM32MP13) && !defined(WOLFSSL_STM32H7S) + #define STM_CRYPT_HEADER_WIDTH 1 + #else + #define STM_CRYPT_HEADER_WIDTH 4 + #endif #endif /* CRYPT_AES_GCM starts the IV with 2 */ From 4fd76dae95d15548b642c650070f4d9978a6c24b Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 12 May 2025 12:19:38 -0700 Subject: [PATCH 2/3] Add portability fix for new INT_MAX required on all TLS limit checking (added in 91aad90c59 Jan 24, 2025). --- wolfssl/internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 23ed5f09c..56fbc7e0c 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -249,8 +249,8 @@ #endif #endif -#if !defined(CHAR_BIT) || (defined(OPENSSL_EXTRA) && !defined(INT_MAX)) - /* Needed for DTLS without big math and INT_MAX */ +#if !defined(WOLFCRYPT_ONLY) && !defined(INT_MAX) + /* Needed for TLS/DTLS limit checking (Added in 91aad90c59 Jan 24, 2025) */ #include #endif From 6270429089f75a6da6a8d84cc227d67db73ab9ac Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 13 May 2025 07:15:04 -0700 Subject: [PATCH 3/3] Fix STM32MP13x STM32 AES GCM. --- wolfcrypt/src/aes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index d67295f77..5acacc5cb 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -8899,13 +8899,14 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( if ((authInSz > 0) && (authInSz < 16)) { authPadSz = 16 - authInSz; } -#endif +#else if (authPadSz != 0) { authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz; } else { authPadSz = authInSz; } +#endif /* for cases where hardware cannot be used for authTag calculate it */ /* if IV is not 12 calculate GHASH using software */