Skip to content

Commit 20988aa

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

File tree

2 files changed

+67
-51
lines changed

2 files changed

+67
-51
lines changed

tests/api/test_aes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5943,7 +5943,7 @@ int test_wc_CryptoCb_AesGcm_EncryptDecrypt(void)
59435943
/* Cleanup */
59445944
wc_CryptoCb_UnRegisterDevice(TEST_CRYPTOCB_AESGCM_OFFLOAD_DEVID);
59455945

5946-
/* Verify lifecycle: SetKey Encrypt Decrypt Free */
5946+
/* Verify lifecycle: SetKey -> Encrypt -> Decrypt -> Free */
59475947
ExpectIntEQ(cryptoCbAesGcmSetKeyCalled, 1);
59485948
ExpectIntEQ(cryptoCbAesGcmEncryptCalled, 1);
59495949
ExpectIntEQ(cryptoCbAesGcmDecryptCalled, 1);
@@ -6105,7 +6105,7 @@ int test_wc_CryptoCb_AesKeyImportOnly(void)
61056105

61066106
/* Verify keylen is set (software path sets this after falling through) */
61076107
ExpectIntEQ(aes->keylen, (int)sizeof(key));
6108-
6108+
61096109
/* Note: The callback sets devCtx, but since capability is not set, we fall through
61106110
* to software path. The software path will set up the key in aes->key for GCM
61116111
* table generation. devCtx may or may not be cleared by software path. */

wolfcrypt/src/aes.c

Lines changed: 65 additions & 49 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-
*/
7548-
if (aes->devId != INVALID_DEVID &&
7556+
#ifdef WOLFSSL_AES_GCM_TLS_SAFE
7557+
/* TLS-safe: always generate H for fallback */
7558+
#else
7559+
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. */
7566-
if (aes->devId != INVALID_DEVID &&
7576+
#ifdef WOLFSSL_AES_GCM_TLS_SAFE
7577+
/* TLS-safe: always generate M0 for fallback */
7578+
#else
7579+
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)