Browse Source

wolfcrypt/src/aes.c: fix WOLFSSL_AESGCM_STREAM && WC_AES_C_DYNAMIC_FALLBACK: establish AESNI status dynamically at time of wc_AesGcmSetKey(), and stick to it (or return failure) until the next wc_AesGcmSetKey(). this matches the semantics of the Linux kernel in-tree implementation, allowing safe registration of the wolfCrypt AESNI implementation with the LKCAPI.

configure.ac: move enable_aesgcm_stream=yes clauses in enable-all and enable-all-crypto to the main section, from the !ENABLED_LINUXKM_DEFAULTS section, and in ENABLED_LINUXKM_LKCAPI_REGISTER setup, remove the !ENABLED_AESNI from the condition for forcing on ENABLED_AESGCM_STREAM.

linuxkm/lkcapi_glue.c:
* remove all special-casing for AES-GCM with AESNI.
* add support for a LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING macro.

wolfssl/wolfcrypt/memory.h: add missing definition of SAVE_VECTOR_REGISTERS2() when DEBUG_VECTOR_REGISTER_ACCESS_FUZZING && !DEBUG_VECTOR_REGISTER_ACCESS.

wolfcrypt/src/memory.c:
* define SAVE_VECTOR_REGISTERS2_fuzzer() if DEBUG_VECTOR_REGISTER_ACCESS_FUZZING, regardless of DEBUG_VECTOR_REGISTER_ACCESS.
* add a DEBUG_VECTOR_REGISTER_ACCESS clause to the !HAVE_THREAD_LS version of SAVE_VECTOR_REGISTERS2_fuzzer().

wolfcrypt/test/test.c: remove several errant wc_AesFree()s in aes256_test().
Daniel Pouzzner 3 months ago
parent
commit
63fe12efe3
6 changed files with 101 additions and 99 deletions
  1. 3 3
      configure.ac
  2. 58 54
      linuxkm/lkcapi_glue.c
  3. 16 22
      wolfcrypt/src/aes.c
  4. 19 11
      wolfcrypt/src/memory.c
  5. 0 9
      wolfcrypt/test/test.c
  6. 5 0
      wolfssl/wolfcrypt/memory.h

+ 3 - 3
configure.ac

@@ -720,6 +720,7 @@ then
     # this set is also enabled by enable-all-crypto:
     test "$enable_atomicuser" = "" && enable_atomicuser=yes
     test "$enable_aesgcm" = "" && enable_aesgcm=yes
+    test "$enable_aesgcm_stream" = "" && test "$enable_aesgcm" = "yes" && enable_aesgcm_stream=yes
     test "$enable_aesccm" = "" && enable_aesccm=yes
     test "$enable_aesctr" = "" && enable_aesctr=yes
     test "$enable_aeseax" = "" && enable_aeseax=yes
@@ -796,7 +797,6 @@ then
 
     if test "$ENABLED_LINUXKM_DEFAULTS" != "yes"
     then
-        test "$enable_aesgcm_stream" = "" && test "$enable_aesgcm" = "yes" && enable_aesgcm_stream=yes
         test "$enable_compkey" = "" && enable_compkey=yes
         test "$enable_quic" = "" && test "$enable_cryptonly" != "yes" && enable_quic=yes
         AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL_IO -DHAVE_IO_TIMEOUT"
@@ -909,6 +909,7 @@ if test "$ENABLED_ALL_CRYPT" = "yes"
 then
     test "$enable_atomicuser" = "" && enable_atomicuser=yes
     test "$enable_aesgcm" = "" && enable_aesgcm=yes
+    test "$enable_aesgcm_stream" = "" && test "$enable_aesgcm" = "yes" && enable_aesgcm_stream=yes
     test "$enable_aesccm" = "" && enable_aesccm=yes
     test "$enable_aesctr" = "" && enable_aesctr=yes
     test "$enable_aeseax" = "" && enable_aeseax=yes
@@ -969,7 +970,6 @@ then
 
     if test "$ENABLED_LINUXKM_DEFAULTS" != "yes"
     then
-        test "$enable_aesgcm_stream" = "" && test "$enable_aesgcm" = "yes" && enable_aesgcm_stream=yes
         test "$enable_compkey" = "" && enable_compkey=yes
     fi
 
@@ -8050,7 +8050,7 @@ if test "$ENABLED_LINUXKM_LKCAPI_REGISTER" != "none"
 then
     AM_CFLAGS="$AM_CFLAGS -DLINUXKM_LKCAPI_REGISTER"
 
-    if test "$ENABLED_AESGCM" != "no" && test "$ENABLED_AESGCM_STREAM" = "no" && test "$ENABLED_AESNI" = "no" && test "$ENABLED_ARMASM" = "no" && test "$ENABLED_FIPS" = "no"; then
+    if test "$ENABLED_AESGCM" != "no" && test "$ENABLED_AESGCM_STREAM" = "no" && test "$ENABLED_ARMASM" = "no" && test "$ENABLED_FIPS" = "no"; then
         ENABLED_AESGCM_STREAM=yes
     fi
 

+ 58 - 54
linuxkm/lkcapi_glue.c

@@ -24,12 +24,6 @@
     #error lkcapi_glue.c included in non-LINUXKM_LKCAPI_REGISTER project.
 #endif
 
-#if defined(LINUXKM_LKCAPI_REGISTER_AESGCM) && defined(WOLFSSL_AESNI) && \
-    defined(WC_AES_C_DYNAMIC_FALLBACK)
-    /* xxx temporary */
-    #error LINUXKM_LKCAPI_REGISTER_AESGCM is incompatible with WOLFSSL_AESNI && WC_AES_C_DYNAMIC_FALLBACK
-#endif
-
 #ifndef WOLFSSL_LINUXKM_LKCAPI_PRIORITY
 /* Larger number means higher priority.  The highest in-tree priority is 4001,
  * in the Cavium driver.
@@ -88,8 +82,7 @@ static int  linuxkm_test_aescfb(void);
 #endif
 #if defined(HAVE_AESGCM) && \
     (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
-     defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \
-    (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK)))
+     defined(LINUXKM_LKCAPI_REGISTER_AESGCM))
 static int  linuxkm_test_aesgcm(void);
 #endif
 #if defined(WOLFSSL_AES_XTS) && \
@@ -503,8 +496,7 @@ static int cfbAesAlg_loaded = 0;
 
 #if defined(HAVE_AESGCM) && \
     (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
-     defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \
-    (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK)))
+     defined(LINUXKM_LKCAPI_REGISTER_AESGCM))
 
 #ifndef WOLFSSL_AESGCM_STREAM
     #error LKCAPI registration of AES-GCM requires WOLFSSL_AESGCM_STREAM (--enable-aesgcm-stream).
@@ -790,7 +782,6 @@ static int gcmAesAead_loaded = 0;
 
 #endif /* HAVE_AESGCM &&
         * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESGCM) &&
-        * (! (WOLFSSL_AESNI && WC_AES_C_DYNAMIC_FALLBACK))
         */
 
 #if defined(WOLFSSL_AES_XTS) && \
@@ -1009,8 +1000,6 @@ static int linuxkm_test_aescbc(void)
     u8 *    enc2 = NULL;
     u8 *    dec2 = NULL;
 
-    const char *driver_name;
-
     XMEMSET(enc, 0, sizeof(enc));
     XMEMSET(dec, 0, sizeof(enc));
 
@@ -1086,13 +1075,18 @@ static int linuxkm_test_aescbc(void)
         goto test_cbc_end;
     }
 
-    driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
-    if (strcmp(driver_name, WOLFKM_AESCBC_DRIVER)) {
-        pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
-               WOLFKM_AESCBC_NAME, driver_name, WOLFKM_AESCBC_DRIVER);
-        ret = -ENOENT;
-        goto test_cbc_end;
+#ifndef LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING
+    {
+        const char *driver_name =
+            crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
+        if (strcmp(driver_name, WOLFKM_AESCBC_DRIVER)) {
+            pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
+                   WOLFKM_AESCBC_NAME, driver_name, WOLFKM_AESCBC_DRIVER);
+            ret = -ENOENT;
+            goto test_cbc_end;
+        }
     }
+#endif
 
     ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2);
     if (ret) {
@@ -1199,7 +1193,6 @@ static int linuxkm_test_aescfb(void)
     byte    dec[sizeof(p_vector)];
     u8 *    enc2 = NULL;
     u8 *    dec2 = NULL;
-    const char *driver_name;
 
     XMEMSET(enc, 0, sizeof(enc));
     XMEMSET(dec, 0, sizeof(enc));
@@ -1276,13 +1269,18 @@ static int linuxkm_test_aescfb(void)
         goto test_cfb_end;
     }
 
-    driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
-    if (strcmp(driver_name, WOLFKM_AESCFB_DRIVER)) {
-        pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
-               WOLFKM_AESCFB_NAME, driver_name, WOLFKM_AESCFB_DRIVER);
-        ret = -ENOENT;
-        goto test_cfb_end;
+#ifndef LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING
+    {
+        const char *driver_name =
+            crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
+        if (strcmp(driver_name, WOLFKM_AESCFB_DRIVER)) {
+            pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
+                   WOLFKM_AESCFB_NAME, driver_name, WOLFKM_AESCFB_DRIVER);
+            ret = -ENOENT;
+            goto test_cfb_end;
+        }
     }
+#endif
 
     ret = crypto_skcipher_setkey(tfm, key32, AES_BLOCK_SIZE * 2);
     if (ret) {
@@ -1352,8 +1350,7 @@ test_cfb_end:
 
 #if defined(HAVE_AESGCM) && \
     (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
-     defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) &&                        \
-    (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK)))
+     defined(LINUXKM_LKCAPI_REGISTER_AESGCM))
 
 static int linuxkm_test_aesgcm(void)
 {
@@ -1404,7 +1401,6 @@ static int linuxkm_test_aesgcm(void)
     u8 *    iv = NULL;
     size_t  encryptLen = sizeof(p_vector);
     size_t  decryptLen = sizeof(p_vector) + sizeof(authTag);
-    const char *driver_name;
 
     /* Init stack variables. */
     XMEMSET(enc, 0, sizeof(p_vector));
@@ -1525,13 +1521,17 @@ static int linuxkm_test_aesgcm(void)
         goto test_gcm_end;
     }
 
-    driver_name = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
-    if (strcmp(driver_name, WOLFKM_AESGCM_DRIVER)) {
-        pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
-               WOLFKM_AESGCM_NAME, driver_name, WOLFKM_AESGCM_DRIVER);
-        ret = -ENOENT;
-        goto test_gcm_end;
+#ifndef LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING
+    {
+        const char *driver_name = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
+        if (strcmp(driver_name, WOLFKM_AESGCM_DRIVER)) {
+            pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
+                   WOLFKM_AESGCM_NAME, driver_name, WOLFKM_AESGCM_DRIVER);
+            ret = -ENOENT;
+            goto test_gcm_end;
+        }
     }
+#endif
 
     ret = crypto_aead_setkey(tfm, key32, AES_BLOCK_SIZE * 2);
     if (ret) {
@@ -1628,7 +1628,6 @@ test_gcm_end:
 
 #endif /* HAVE_AESGCM &&
         * (LINUXKM_LKCAPI_REGISTER_ALL || LINUXKM_LKCAPI_REGISTER_AESGCM) &&
-        * (! (WOLFSSL_AESNI && WC_AES_C_DYNAMIC_FALLBACK))
         */
 
 #if defined(WOLFSSL_AES_XTS) && \
@@ -1654,7 +1653,6 @@ static int aes_xts_128_test(void)
     struct crypto_skcipher *tfm = NULL;
     struct skcipher_request *req = NULL;
     u8 iv[AES_BLOCK_SIZE];
-    const char *driver_name;
 
     /* 128 key tests */
     static const unsigned char k1[] = {
@@ -2024,13 +2022,18 @@ static int aes_xts_128_test(void)
         goto test_xts_end;
     }
 
-    driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
-    if (strcmp(driver_name, WOLFKM_AESXTS_DRIVER)) {
-        pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
-               WOLFKM_AESXTS_NAME, driver_name, WOLFKM_AESXTS_DRIVER);
-        ret = -ENOENT;
-        goto test_xts_end;
+#ifndef LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING
+    {
+        const char *driver_name =
+            crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
+        if (strcmp(driver_name, WOLFKM_AESXTS_DRIVER)) {
+            pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
+                   WOLFKM_AESXTS_NAME, driver_name, WOLFKM_AESXTS_DRIVER);
+            ret = -ENOENT;
+            goto test_xts_end;
+        }
     }
+#endif
 
     ret = crypto_skcipher_ivsize(tfm);
     if (ret != sizeof(iv)) {
@@ -2194,7 +2197,6 @@ static int aes_xts_256_test(void)
     struct crypto_skcipher *tfm = NULL;
     struct skcipher_request *req = NULL;
     u8 iv[AES_BLOCK_SIZE];
-    const char *driver_name;
 
     /* 256 key tests */
     static const unsigned char k1[] = {
@@ -2404,13 +2406,17 @@ static int aes_xts_256_test(void)
         goto test_xts_end;
     }
 
-    driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
-    if (strcmp(driver_name, WOLFKM_AESXTS_DRIVER)) {
-        pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
-               WOLFKM_AESXTS_NAME, driver_name, WOLFKM_AESXTS_DRIVER);
-        ret = -ENOENT;
-        goto test_xts_end;
+#ifndef LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING
+    {
+        const char *driver_name = crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
+        if (strcmp(driver_name, WOLFKM_AESXTS_DRIVER)) {
+            pr_err("error: unexpected implementation for %s: %s (expected %s)\n",
+                   WOLFKM_AESXTS_NAME, driver_name, WOLFKM_AESXTS_DRIVER);
+            ret = -ENOENT;
+            goto test_xts_end;
+        }
     }
+#endif
 
     ret = crypto_skcipher_ivsize(tfm);
     if (ret != sizeof(iv)) {
@@ -2640,8 +2646,7 @@ static int linuxkm_lkcapi_register(void)
 
 #if defined(HAVE_AESGCM) && \
     (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
-     defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) &&                        \
-    (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK)))
+     defined(LINUXKM_LKCAPI_REGISTER_AESGCM))
 
     REGISTER_ALG(gcmAesAead, crypto_register_aead, linuxkm_test_aesgcm);
 #endif
@@ -2681,8 +2686,7 @@ static void linuxkm_lkcapi_unregister(void)
 #endif
 #if defined(HAVE_AESGCM) && \
     (defined(LINUXKM_LKCAPI_REGISTER_ALL) || \
-     defined(LINUXKM_LKCAPI_REGISTER_AESGCM)) && \
-    (! (defined(WOLFSSL_AESNI) && defined(WC_AES_C_DYNAMIC_FALLBACK)))
+     defined(LINUXKM_LKCAPI_REGISTER_AESGCM))
 
     UNREGISTER_ALG(gcmAesAead, crypto_unregister_aead);
 #endif

+ 16 - 22
wolfcrypt/src/aes.c

@@ -8962,10 +8962,6 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
 
 #ifdef WOLFSSL_AESGCM_STREAM
 
-#if defined(WC_AES_C_DYNAMIC_FALLBACK) && defined(WOLFSSL_AESNI)
-    #error "AES-GCM streaming with AESNI is incompatible with WC_AES_C_DYNAMIC_FALLBACK."
-#endif
-
 /* Initialize the AES GCM cipher with an IV. C implementation.
  *
  * @param [in, out] aes   AES object.
@@ -8977,10 +8973,6 @@ static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz
     ALIGN32 byte counter[AES_BLOCK_SIZE];
     int ret;
 
-#ifdef WOLFSSL_AESNI
-    aes->use_aesni = 0;
-#endif
-
     if (ivSz == GCM_NONCE_MID_SZ) {
         /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
         XMEMCPY(counter, iv, ivSz);
@@ -9207,6 +9199,7 @@ static WARN_UNUSED_RESULT int AesGcmInit_aesni(
     ASSERT_SAVED_VECTOR_REGISTERS();
 
     /* Reset state fields. */
+    aes->over = 0;
     aes->aSz = 0;
     aes->cSz = 0;
     /* Set tag to all zeros as initial value. */
@@ -9234,8 +9227,6 @@ static WARN_UNUSED_RESULT int AesGcmInit_aesni(
             aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
     }
 
-    aes->use_aesni = 1;
-
     return 0;
 }
 
@@ -9861,11 +9852,12 @@ int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
 
         if (iv != NULL) {
             /* Initialize with the IV. */
-            VECTOR_REGISTERS_PUSH;
 
         #ifdef WOLFSSL_AESNI
             if (aes->use_aesni) {
+                SAVE_VECTOR_REGISTERS(return _svr_ret;);
                 ret = AesGcmInit_aesni(aes, iv, ivSz);
+                RESTORE_VECTOR_REGISTERS();
             }
             else
         #endif
@@ -9873,8 +9865,6 @@ int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
                 ret = AesGcmInit_C(aes, iv, ivSz);
             }
 
-            VECTOR_REGISTERS_POP;
-
             if (ret == 0)
                 aes->nonceSet = 1;
         }
@@ -9988,11 +9978,12 @@ int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
 
     if (ret == 0) {
         /* Encrypt with AAD and/or plaintext. */
-        VECTOR_REGISTERS_PUSH;
 
     #ifdef WOLFSSL_AESNI
         if (aes->use_aesni) {
+            SAVE_VECTOR_REGISTERS(return _svr_ret;);
             ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
+            RESTORE_VECTOR_REGISTERS();
         }
         else
     #endif
@@ -10005,8 +9996,6 @@ int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
                 GHASH_UPDATE(aes, authIn, authInSz, out, sz);
             }
         }
-
-        VECTOR_REGISTERS_POP;
     }
 
     return ret;
@@ -10043,17 +10032,17 @@ int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
 
     if (ret == 0) {
         /* Calculate authentication tag. */
-        VECTOR_REGISTERS_PUSH;
     #ifdef WOLFSSL_AESNI
         if (aes->use_aesni) {
+            SAVE_VECTOR_REGISTERS(return _svr_ret;);
             ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
+            RESTORE_VECTOR_REGISTERS();
         }
         else
     #endif
         {
             ret = AesGcmFinal_C(aes, authTag, authTagSz);
         }
-        VECTOR_REGISTERS_POP;
     }
 
     if ((ret == 0) && aes->ctrSet) {
@@ -10126,10 +10115,11 @@ int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
 
     if (ret == 0) {
         /* Decrypt with AAD and/or cipher text. */
-        VECTOR_REGISTERS_PUSH;
     #ifdef WOLFSSL_AESNI
         if (aes->use_aesni) {
+            SAVE_VECTOR_REGISTERS(return _svr_ret;);
             ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
+            RESTORE_VECTOR_REGISTERS();
         }
         else
     #endif
@@ -10140,7 +10130,6 @@ int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
             /* Decrypt the cipher text. */
             ret = AesGcmCryptUpdate_C(aes, out, in, sz);
         }
-        VECTOR_REGISTERS_POP;
     }
 
     return ret;
@@ -10177,10 +10166,11 @@ int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
 
     if (ret == 0) {
         /* Calculate authentication tag and compare with one passed in.. */
-        VECTOR_REGISTERS_PUSH;
     #ifdef WOLFSSL_AESNI
         if (aes->use_aesni) {
+            SAVE_VECTOR_REGISTERS(return _svr_ret;);
             ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
+            RESTORE_VECTOR_REGISTERS();
         }
         else
     #endif
@@ -10195,7 +10185,6 @@ int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
                 }
             }
         }
-        VECTOR_REGISTERS_POP;
     }
 
     return ret;
@@ -11104,6 +11093,11 @@ int wc_AesInit(Aes* aes, void* heap, int devId)
     aes->heap = heap;
     aes->rounds = 0;
 
+#ifdef WOLFSSL_AESNI
+    /* clear here for the benefit of wc_AesGcmInit(). */
+    aes->use_aesni = 0;
+#endif
+
 #ifdef WOLF_CRYPTO_CB
     aes->devId = devId;
     aes->devCtx = NULL;

+ 19 - 11
wolfcrypt/src/memory.c

@@ -1508,16 +1508,21 @@ THREAD_LS_T const char *wc_svr_last_file = NULL;
 THREAD_LS_T int wc_svr_last_line = -1;
 THREAD_LS_T int wc_debug_vector_registers_retval =
     WC_DEBUG_VECTOR_REGISTERS_RETVAL_INITVAL;
+#endif
 
 #ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING
 
+#ifdef HAVE_THREAD_LS
+
 WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) {
     static THREAD_LS_T struct drand48_data wc_svr_fuzzing_state;
     static THREAD_LS_T int wc_svr_fuzzing_seeded = 0;
     long result;
 
+#ifdef DEBUG_VECTOR_REGISTER_ACCESS
     if (wc_debug_vector_registers_retval)
         return wc_debug_vector_registers_retval;
+#endif
 
     if (wc_svr_fuzzing_seeded == 0) {
         long seed = WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED;
@@ -1534,30 +1539,33 @@ WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) {
         return 0;
 }
 
-#endif /* DEBUG_VECTOR_REGISTER_ACCESS_FUZZING */
-
-#elif defined(DEBUG_VECTOR_REGISTER_ACCESS_FUZZING)
+#else /* !HAVE_THREAD_LS */
 
-/* DEBUG_VECTOR_REGISTER_ACCESS is undefined but fuzzing requested --
- * fuzz vector register access without the detailed debugging.
- * this is useful for testing in the kernel module build, where glibc and
- * thread-local storage are unavailable.
+/* alternate implementation useful for testing in the kernel module build, where
+ * glibc and thread-local storage are unavailable.
  *
  * note this is not a well-behaved PRNG, but is adequate for fuzzing purposes.
  * the prn sequence is incompressible according to ent and xz, and does not
  * cycle within 10M iterations with various seeds including zero, but the Chi
  * square distribution is poor, and the unconditioned lsb bit balance is ~54%
  * regardless of seed.
+ *
+ * deterministic only if access is single-threaded, but never degenerate.
  */
 
 WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) {
     static unsigned long prn = WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED;
     static int balance_bit = 0;
-    /* access to prn is racey, but it doesn't matter. */
     unsigned long new_prn = prn ^ 0xba86943da66ee701ul; /* note this magic
                                                          * random number is
                                                          * bit-balanced.
                                                          */
+
+#ifdef DEBUG_VECTOR_REGISTER_ACCESS
+    if (wc_debug_vector_registers_retval)
+        return wc_debug_vector_registers_retval;
+#endif
+
     /* barrel-roll using the bottom 6 bits. */
     if (new_prn & 0x3f)
         new_prn = (new_prn << (new_prn & 0x3f)) |
@@ -1569,9 +1577,9 @@ WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) {
     return ((prn & 1) ^ balance_bit) ? IO_FAILED_E : 0;
 }
 
-#endif /* DEBUG_VECTOR_REGISTER_ACCESS ||
-        * DEBUG_VECTOR_REGISTER_ACCESS_FUZZING
-        */
+#endif /* !HAVE_THREAD_LS */
+
+#endif /* DEBUG_VECTOR_REGISTER_ACCESS_FUZZING */
 
 #ifdef WOLFSSL_LINUXKM
     #include "../../linuxkm/linuxkm_memory.c"

+ 0 - 9
wolfcrypt/test/test.c

@@ -12097,10 +12097,6 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes256_test(void)
     if (XMEMCMP(cipher, verify, (int) sizeof(cipher)))
         ERROR_OUT(WC_TEST_RET_ENC_NC, out);
 #endif
-    wc_AesFree(enc);
-#ifdef HAVE_AES_DECRYPT
-    wc_AesFree(dec);
-#endif
 
 #if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_AES_C_DYNAMIC_FALLBACK)
     ret = wc_AesSetKey(enc, key, keySz, iv, AES_ENCRYPTION);
@@ -12140,11 +12136,6 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes256_test(void)
         ERROR_OUT(WC_TEST_RET_ENC_NC, out);
 #endif
 
-    wc_AesFree(enc);
-#ifdef HAVE_AES_DECRYPT
-    wc_AesFree(dec);
-#endif
-
     WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(SYSLIB_FAILED_E);
     ret = wc_AesSetKey(enc, key, keySz, iv, AES_ENCRYPTION);
     WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0);

+ 5 - 0
wolfssl/wolfcrypt/memory.h

@@ -434,6 +434,11 @@ WOLFSSL_LOCAL int wc_debug_CipherLifecycleFree(void **CipherLifecycleTag,
         wc_svr_last_file = __FILE__;                                \
         wc_svr_last_line = __LINE__;                                \
     } while(0)
+
+#else /* !DEBUG_VECTOR_REGISTER_ACCESS */
+    #if !defined(SAVE_VECTOR_REGISTERS2) && defined(DEBUG_VECTOR_REGISTER_ACCESS_FUZZING)
+        #define SAVE_VECTOR_REGISTERS2(...) SAVE_VECTOR_REGISTERS2_fuzzer()
+    #endif
 #endif
 
 #ifdef __cplusplus