Skip to content

Commit 6aa9360

Browse files
committed
make AES Offload fallback to SW
Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>
1 parent f9ee825 commit 6aa9360

File tree

1 file changed

+63
-47
lines changed

1 file changed

+63
-47
lines changed

wolfcrypt/src/aes.c

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
132132
}
133133
#endif
134134

135+
/* TLS-safe default:
136+
* When TLS is enabled, AES-GCM must always retain software fallback.
137+
* CryptoCB may accelerate, but must not remove fallback implicitly.
138+
*/
139+
#if !defined(NO_TLS)
140+
#define WOLFSSL_AES_GCM_TLS_SAFE
141+
#endif
142+
135143
/* Define AES implementation includes and functions */
136144
#if defined(STM32_CRYPTO)
137145
/* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
@@ -4366,31 +4374,37 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(
43664374
ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen, &capabilities);
43674375

43684376
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
4369-
/* Callback handled it (success or error) */
4370-
if (ret == 0) {
4371-
/* Check if callback declared full GCM offload capability.
4372-
* If NOT, fall through to software path - we don't support
4373-
* key-import-only mode for GCM (need key for table generation). */
4374-
if (!(capabilities & WC_CRYPTOCB_AES_GCM)) {
4375-
/* Fall through to software path */
4376-
goto cryptocb_aes_setkey_sw_fallback;
4377-
}
4378-
4379-
/* Full GCM offload mode */
4377+
if (ret != 0) {
4378+
/* real error from callback */
4379+
return ret;
4380+
}
4381+
4382+
/* Callback handled SetKey */
4383+
if (capabilities & WC_CRYPTOCB_AES_GCM) {
43804384
aes->gcmCryptoCbOffload = 1;
43814385
aes->keylen = (int)keylen;
4382-
4386+
4387+
#ifdef WOLFSSL_AES_GCM_TLS_SAFE
4388+
/* TLS-safe: DO NOT return
4389+
* We must still set up software AES key for fallback.
4390+
*/
4391+
goto cryptocb_aes_setkey_fallback;
4392+
#else
4393+
/* Cryptonly build: full offload allowed */
43834394
/* Set IV if provided */
43844395
if (iv != NULL) {
43854396
XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
43864397
} else {
43874398
XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
43884399
}
4400+
return 0;
4401+
#endif
43894402
}
4390-
return ret;
4403+
4404+
/* Key-import-only or partial support → fallback */
43914405
}
4392-
/* CRYPTOCB_UNAVAILABLE: fall through to software path */
4393-
cryptocb_aes_setkey_sw_fallback: (void)0;
4406+
/* Either UNAVAILABLE or TLS-safe fallback */
4407+
cryptocb_aes_setkey_fallback: (void)0;
43944408
#else
43954409
/* Standard CryptoCB path - copy key to devKey */
43964410
if (keylen > sizeof(aes->devKey)) {
@@ -4830,31 +4844,37 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
48304844
ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen, &capabilities);
48314845

48324846
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
4833-
/* Callback handled it (success or error) */
4834-
if (ret == 0) {
4835-
/* Check if callback declared full GCM offload capability.
4836-
* If NOT, fall through to software path - we don't support
4837-
* key-import-only mode for GCM (need key for table generation). */
4838-
if (!(capabilities & WC_CRYPTOCB_AES_GCM)) {
4839-
/* Fall through to software path */
4840-
goto cryptocb_aes_setkey_sw_fallback2;
4841-
}
4842-
4843-
/* Full GCM offload mode */
4847+
if (ret != 0) {
4848+
/* real error from callback */
4849+
return ret;
4850+
}
4851+
4852+
/* Callback handled SetKey */
4853+
if (capabilities & WC_CRYPTOCB_AES_GCM) {
48444854
aes->gcmCryptoCbOffload = 1;
48454855
aes->keylen = (int)keylen;
4846-
4856+
4857+
#ifdef WOLFSSL_AES_GCM_TLS_SAFE
4858+
/* TLS-safe: DO NOT return
4859+
* We must still set up software AES key for fallback.
4860+
*/
4861+
goto cryptocb_aes_setkey_fallback2;
4862+
#else
4863+
/* Cryptonly build: full offload allowed */
48474864
/* Set IV if provided */
48484865
if (iv != NULL) {
48494866
XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
48504867
} else {
48514868
XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
48524869
}
4870+
return 0;
4871+
#endif
48534872
}
4854-
return ret;
4873+
4874+
/* Key-import-only or partial support → fallback */
48554875
}
4856-
/* CRYPTOCB_UNAVAILABLE: fall through to software path */
4857-
cryptocb_aes_setkey_sw_fallback2: (void)0;
4876+
/* Either UNAVAILABLE or TLS-safe fallback */
4877+
cryptocb_aes_setkey_fallback2: (void)0;
48584878
#else
48594879
/* Copy key to devKey for standard CryptoCB path */
48604880
XMEMCPY(aes->devKey, userKey, keylen);
@@ -7533,24 +7553,16 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
75337553
#if !defined(FREESCALE_LTC_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO)
75347554
if (ret == 0) {
75357555
#ifdef WOLF_CRYPTO_CB_AES_SETKEY
7536-
/* CRITICAL FIX: Only skip H table if callback EXPLICITLY declared
7537-
* full AES-GCM offload capability via WC_CRYPTOCB_AES_GCM flag.
7538-
*
7539-
* Checking devCtx alone is NOT sufficient because:
7540-
* - Callback may only support key import, not GCM operations
7541-
* - If we skip tables and GCM ops return UNAVAILABLE, software fallback fails
7542-
* - This was a critical bug in the original implementation
7543-
*
7544-
* The callback must explicitly opt-in to GCM offload by setting the
7545-
* WC_CRYPTOCB_AES_GCM capability flag during SetKey. Only then do we
7546-
* skip table generation.
7547-
*/
7556+
#ifdef WOLFSSL_AES_GCM_TLS_SAFE
7557+
/* TLS-safe: always generate H for fallback */
7558+
#else
75487559
if (aes->devId != INVALID_DEVID &&
75497560
aes->devCtx != NULL &&
75507561
aes->gcmCryptoCbOffload) {
7551-
/* H table not needed - callback confirmed full GCM offload */
7562+
/* full offload allowed: skip H */
75527563
}
75537564
else
7565+
#endif
75547566
#endif
75557567
{
75567568
VECTOR_REGISTERS_PUSH;
@@ -7561,14 +7573,16 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
75617573
}
75627574
if (ret == 0) {
75637575
#ifdef WOLF_CRYPTO_CB_AES_SETKEY
7564-
/* CRITICAL FIX: Same logic as H table.
7565-
* Only skip M0 generation if callback explicitly declared full GCM offload. */
7576+
#ifdef WOLFSSL_AES_GCM_TLS_SAFE
7577+
/* TLS-safe: always generate M0 for fallback */
7578+
#else
75667579
if (aes->devId != INVALID_DEVID &&
75677580
aes->devCtx != NULL &&
75687581
aes->gcmCryptoCbOffload) {
7569-
/* M0 table not needed - callback confirmed full GCM offload */
7582+
/* full offload allowed: skip M0 */
75707583
}
75717584
else
7585+
#endif
75727586
#endif
75737587
{
75747588
#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
@@ -7610,14 +7624,16 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
76107624
#ifdef WOLF_CRYPTO_CB
76117625
if (aes->devId != INVALID_DEVID) {
76127626
#ifdef WOLF_CRYPTO_CB_AES_SETKEY
7627+
#if !defined(WOLFSSL_AES_GCM_TLS_SAFE)
76137628
/* In CryptoCB key import mode, key is in SE - devKey not used */
76147629
if (aes->devCtx != NULL) {
76157630
/* Skip - key handled by CryptoCB */
76167631
}
76177632
else
7633+
#endif
76187634
#endif
76197635
{
7620-
/* Copy key to devKey for standard CryptoCB path */
7636+
/* Copy key to devKey for standard CryptoCB path or TLS-safe fallback */
76217637
XMEMCPY(aes->devKey, key, len);
76227638
}
76237639
}

0 commit comments

Comments
 (0)