From d6dc9195bc5c26fb8354cb5753af44a7682b1f10 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 24 Jun 2026 14:46:10 -0600 Subject: [PATCH 1/5] https://fenrir.wolfssl.com/finding/6145 https://fenrir.wolfssl.com/finding/5384 https://fenrir.wolfssl.com/finding/4432 https://fenrir.wolfssl.com/finding/5392 https://fenrir.wolfssl.com/finding/5392 skoll fixes Changed type for keys for CAAM in ecc so it matches assignment with out cast to never truncate Added check to see if CAAM_ADDRESS is defined before using in ecc.h https://fenrir.wolfssl.com/finding/5994 https://fenrir.wolfssl.com/finding/4445 Fixed memory leaks for dev crypto and fixed https://fenrir.wolfssl.com/finding/4446 https://fenrir.wolfssl.com/finding/5418 https://fenrir.wolfssl.com/finding/5420 https://fenrir.wolfssl.com/finding/5411 https://fenrir.wolfssl.com/finding/5412 https://fenrir.wolfssl.com/finding/5413 Skoll Fixes github comment fix github review fixes skoll fixes skoll fixes spelling fix --- tests/api/test_aes.c | 3 +- wolfcrypt/src/des3.c | 12 ++-- wolfcrypt/src/dsa.c | 7 +++ wolfcrypt/src/ecc.c | 10 +--- .../Espressif/esp_crt_bundle/esp_crt_bundle.c | 8 +-- .../src/port/Renesas/renesas_fspsm_aes.c | 20 ++++--- .../src/port/Renesas/renesas_fspsm_sha.c | 2 +- wolfcrypt/src/port/devcrypto/devcrypto_aes.c | 2 +- wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 55 ++++++++++++------- wolfcrypt/src/random.c | 24 ++++++-- wolfcrypt/src/siphash.c | 8 +-- wolfcrypt/src/wc_mlkem_poly.c | 18 +++--- wolfssl/wolfcrypt/ecc.h | 13 ++++- 13 files changed, 116 insertions(+), 66 deletions(-) diff --git a/tests/api/test_aes.c b/tests/api/test_aes.c index ef03c20ce48..01a998466a4 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -3964,7 +3964,8 @@ int test_wc_AesGcmNonStdNonce(void) * and cannot exercise the GHASH-based counter derivation. */ #if !defined(NO_AES) && defined(HAVE_AESGCM) && \ !defined(HAVE_FIPS) && \ - !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_KCAPI) + !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_KCAPI) && \ + !defined(WOLFSSL_DEVCRYPTO_AES) /* ------------------------------------------------------------------ * Section 1: 1-byte IV, AES-128 diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index f1beae1b60c..841fc960f95 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -1571,10 +1571,14 @@ /* rotate left and right halves independently */ for (j = 0; j < 48; j++) { /* select bits individually */ - if (pcr[pc2[j] - 1]) { /* check bit that goes to ks[j] */ - l= j % 6; /* mask it in if it's there */ - ks[j/6] |= (byte)(bytebit[l] >> 2); - } + byte bit; + byte mask; + bit = + (byte)(pcr[pc2[j] - 1]); /* all pcr values are either 0 or 1 */ + mask = (byte)(0 - bit); /* mask is either 0xFF or 0x00 */ + /* only set to bytebit value if bit == 1*/ + ks[j/6] |= + (byte)((bytebit[j % 6] >> 2) & mask); } /* Now convert to odd/even interleaved form for use in F */ diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 3ee03876feb..779d0b2e6c8 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -1124,6 +1124,13 @@ int wc_DsaVerify_ex(const byte* digest, word32 digestSz, const byte* sig, if (digest == NULL || sig == NULL || key == NULL || answer == NULL) return BAD_FUNC_ARG; + /* assign default value so we return 0 on error */ + *answer = 0; + + /* Note the min allowed digestSz here is WC_SHA_DIGEST_SIZE, not + * WC_MIN_DIGEST_SIZE, to allow verify-only legacy DSA operations, as + * expressly allowed under FIPS 186-5, FIPS 140-3, and SP 800-131A. + */ if ((digestSz > WC_MAX_DIGEST_SIZE) || (digestSz < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) { diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 3920d7a0ee8..7b5cc668df1 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -256,10 +256,6 @@ ECC Curve Sizes: #include #endif -#if defined(WOLFSSL_CAAM) - #include -#endif - #if defined(WOLFSSL_KCAPI_ECC) #include #endif @@ -10111,7 +10107,7 @@ static int _ecc_export_x963(ecc_key* key, byte* out, word32* outLen) /* store byte point type */ out[0] = ECC_POINT_UNCOMP; - if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0) + if (caamReadPartition(key->securePubKey, out+1, keySz*2) != 0) return WC_HW_E; *outLen = 1 + 2*keySz; @@ -11734,7 +11730,7 @@ static int _ecc_import_private_key_ex(const byte* priv, word32 privSz, } key->partNum = part; - key->blackKey = (word32)vaddr; + key->blackKey = vaddr; if (caamWriteToPartition(vaddr, priv, privSz) != 0) return WC_HW_E; @@ -11742,7 +11738,7 @@ static int _ecc_import_private_key_ex(const byte* priv, word32 privSz, /* +1 to account for x963 compressed bit */ if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0) return WC_HW_E; - key->securePubKey = (word32)vaddr + privSz; + key->securePubKey = vaddr + privSz; } } else { diff --git a/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c b/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c index 76c8abdb1c4..6cad5fb5bb8 100644 --- a/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c +++ b/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c @@ -983,14 +983,12 @@ static CB_INLINE int wolfssl_ssl_conf_verify_cb_no_signer(int preverify, /* Clean up and exit */ if ((_crt_found == 0) && (bundle_cert != NULL)) { ESP_LOGW(TAG, "Cert not found, free bundle_cert"); + /* this_subject and this_issuer are apart of bundle_cert and will be + * freed here*/ wolfSSL_X509_free(bundle_cert); bundle_cert = NULL; - /* this_subject and this_issuer are pointers into cert used. - * Don't free if the cert was found. */ - wolfSSL_X509_NAME_free(this_subject); - this_subject = NULL; - wolfSSL_X509_NAME_free(this_issuer); this_issuer = NULL; + this_subject = NULL; } /* We don't clean up the store_cert and x509 as we are in a callback, diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c index d818ee00870..15bea8c4856 100644 --- a/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c +++ b/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c @@ -410,10 +410,13 @@ int wc_fspsm_AesGcmEncrypt(struct Aes* aes, byte* out, aes->heap, DYNAMIC_TYPE_AES); key_server_aes = (FSPSM_AES_PWKEY)XMALLOC(sizeof(FSPSM_AES_WKEY), aes->heap, DYNAMIC_TYPE_AES); - if (key_client_aes == NULL || key_server_aes == NULL) { - XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); - XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); - XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); + if (key_server_aes == NULL || key_client_aes == NULL) { + XFREE(key_client_aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(key_server_aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); + wc_fspsm_hw_unlock(); return MEMORY_E; } @@ -638,9 +641,12 @@ int wc_fspsm_AesGcmDecrypt(struct Aes* aes, byte* out, key_server_aes = (FSPSM_AES_PWKEY)XMALLOC(sizeof(FSPSM_AES_WKEY), aes->heap, DYNAMIC_TYPE_AES); if (key_client_aes == NULL || key_server_aes == NULL) { - XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); - XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); - XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(key_client_aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(key_server_aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); + wc_fspsm_hw_unlock(); return MEMORY_E; } diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c index c543946a164..8a263a63fd1 100644 --- a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c +++ b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c @@ -418,7 +418,7 @@ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) #endif wc_fspsm_hw_lock(); - if (Init(&handle) == FSP_SUCCESS) { + if ((ret = Init(&handle)) == FSP_SUCCESS) { ret = Update(&handle, (uint8_t*)hash->msg, hash->used); if (ret == FSP_SUCCESS) { ret = Final(&handle, out, (uint32_t*)&sz); diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c index 62cd624f017..371f7c3de84 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c @@ -110,7 +110,7 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const word32 max_key_len = (AES_MAX_KEY_SIZE / 8); #endif - if (aes == NULL || + if (aes == NULL || userKey == NULL || !((keylen == 16) || (keylen == 24) || (keylen == 32))) { return BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index 37f9763fc2f..f04b12df98e 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -120,6 +120,7 @@ int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId) (void)devId; /* no async for now */ XMEMSET(sha, 0, sizeof(wc_Sha256)); + sha->ctx.cfd = -1; /* Sentinel value matching aes */ sha->heap = heap; return HashInit((void*)sha, CRYPTO_SHA2_256, NULL, 0); @@ -135,20 +136,14 @@ int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP /* keep full message to hash at end instead of incremental updates */ if (sha->len < sha->used + sz) { - if (sha->msg == NULL) { - sha->msg = (byte*)XMALLOC(sha->used + sz, sha->heap, - DYNAMIC_TYPE_TMP_BUFFER); - } else { - byte* pt = (byte*)XREALLOC(sha->msg, sha->used + sz, sha->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (pt == NULL) { - return MEMORY_E; - } - sha->msg = pt; - } - if (sha->msg == NULL) { + byte* pt = (byte*)XREALLOC(sha->msg, sha->used + sz, sha->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (pt == NULL) { return MEMORY_E; } + + sha->msg = pt; + sha->len = sha->used + sz; } XMEMCPY(sha->msg + sha->used, in, sz); @@ -173,6 +168,7 @@ int wc_Sha256Final(wc_Sha256* sha, byte* hash) #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP /* keep full message to hash at end instead of incremental updates */ if ((ret = HashUpdate(sha, CRYPTO_SHA2_256, sha->msg, sha->used)) < 0) { + wc_Sha256Free(sha); return ret; } XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -180,7 +176,8 @@ int wc_Sha256Final(wc_Sha256* sha, byte* hash) #endif ret = GetDigest(sha, CRYPTO_SHA2_256, hash); if (ret != 0) { - return ret; + wc_Sha256Free(sha); + return ret; } wc_Sha256Free(sha); @@ -198,9 +195,15 @@ int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) { int ret; wc_Sha256 cpy; - wc_Sha256Copy(sha, &cpy); - - if ((ret = HashUpdate(&cpy, CRYPTO_SHA2_256, cpy.msg, cpy.used)) == 0) { + XMEMSET(&cpy, 0, sizeof(cpy)); /* ZII */ + /* mark as having no /dev/crypto session yet so the wc_Sha256Free() + * in wc_Sha256Copy() does not close fd 0 (cfd == -1 is the + * "no session" sentinel, matching wc_AesInit()) */ + cpy.ctx.cfd = -1; + ret = wc_Sha256Copy(sha, &cpy); + + if (ret == 0 && + (ret = HashUpdate(&cpy, CRYPTO_SHA2_256, cpy.msg, cpy.used)) == 0) { /* help static analysis tools out */ XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); ret = GetDigest(&cpy, CRYPTO_SHA2_256, hash); @@ -219,22 +222,36 @@ int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) { + int ret = 0; + if (src == NULL || dst == NULL) { return BAD_FUNC_ARG; } - wc_InitSha256_ex(dst, src->heap, 0); #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + /* Sha256Free checks that ctx.cfd is >= 0*/ + wc_Sha256Free(dst); + if ((ret = wc_InitSha256_ex(dst, src->heap, 0)) != 0) { + return ret; + } dst->len = src->len; dst->used = src->used; dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); if (dst->msg == NULL) { + wc_Sha256Free(dst); return MEMORY_E; } XMEMCPY(dst->msg, src->msg, src->len); -#endif - return 0; + return ret; +#else + (void)src; + (void)dst; + (void)ret; + + WOLFSSL_MSG("Compile with WOLFSSL_DEVCRYPTO_HASH_KEEP for this feature"); + return NOT_COMPILED_IN; +#endif } #endif /* !NO_SHA256 */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 5ca8ce20a13..0fa46fd520d 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -382,19 +382,29 @@ static int sha512DrbgDisabled = 0; static wolfSSL_Mutex drbgStateMutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(drbgStateMutex); #ifndef WOLFSSL_MUTEX_INITIALIZER +#ifdef WOLFSSL_ATOMIC_OPS +static wolfSSL_Atomic_Int drbgStateMutex_inited = WOLFSSL_ATOMIC_INITIALIZER(0); +#else static int drbgStateMutex_inited = 0; #endif +#endif #endif /* !SINGLE_THREADED */ int wc_DrbgState_MutexInit(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER - if (!drbgStateMutex_inited) { + int expected = 0; + /* Check if mutex is not inited and set it to true before init. + * This means that the mutex is marked as init before it actually is. + * Necessary to ensure that two threads don't init at the same time.*/ + if (wolfSSL_Atomic_Int_CompareExchange(&drbgStateMutex_inited, + &expected, 1)) { int ret = wc_InitMutex(&drbgStateMutex); - if (ret != 0) + if (ret != 0) { + (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, 0); return ret; - drbgStateMutex_inited = 1; + } } #endif #endif @@ -3718,9 +3728,13 @@ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), output += sizeof(word64)) { - ret = IntelRDseed64_r((word64*)output); - if (ret != 0) + word64 rndTmpLocal; + ret = IntelRDseed64_r(&rndTmpLocal); + if (ret != 0) { + ForceZero(&rndTmp, sizeof(rndTmp)); return ret; + } + writeUnalignedWord64(output, rndTmpLocal); } if (sz == 0) return 0; diff --git a/wolfcrypt/src/siphash.c b/wolfcrypt/src/siphash.c index 28047be30b5..b8159c2957c 100644 --- a/wolfcrypt/src/siphash.c +++ b/wolfcrypt/src/siphash.c @@ -411,8 +411,8 @@ int wc_SipHash(const unsigned char* key, const unsigned char* in, word32 inSz, return BAD_FUNC_ARG; } - k0 = ((const word64*)key)[0]; - k1 = ((const word64*)key)[1]; + k0 = GET_U64(key); + k1 = GET_U64(key + 8); __asm__ __volatile__ ( "xorq %[k0], %[v0]\n\t" "xorq %[k1], %[v1]\n\t" @@ -640,8 +640,8 @@ int wc_SipHash(const unsigned char* key, const unsigned char* in, word32 inSz, return BAD_FUNC_ARG; } - k0 = ((word64*)key)[0]; - k1 = ((word64*)key)[1]; + k0 = GET_U64(key + 0); + k1 = GET_U64(key + 8); __asm__ __volatile__ ( "eor %[v0], %[v0], %[k0]\n\t" "eor %[v1], %[v1], %[k1]\n\t" diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c index 2ab7299cfe1..66ef8e8b7d5 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -4375,13 +4375,16 @@ static int mlkem_get_noise_k4_avx2(MLKEM_PRF_T* prf, sword16* vec1, */ static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) { - word64* state = (word64*)rand; + word64 state[3 * 25]; state[0*25 + 4] = 0x1f00 + 0 + o; state[1*25 + 4] = 0x1f00 + 1 + o; state[2*25 + 4] = 0x1f00 + 2 + o; mlkem_shake256_blocksx3_seed_neon(state, seed); + XMEMCPY(rand + 0 * 25 * 8, state + 0*25, ETA2_RAND_SIZE); + XMEMCPY(rand + 1 * 25 * 8, state + 1*25, ETA2_RAND_SIZE); + XMEMCPY(rand + 2 * 25 * 8, state + 2*25, ETA2_RAND_SIZE); } #if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) @@ -4442,10 +4445,7 @@ static void mlkem_get_noise_eta3_aarch64(byte* rand, byte* seed, byte o) { word64 state[25]; - state[0] = ((word64*)seed)[0]; - state[1] = ((word64*)seed)[1]; - state[2] = ((word64*)seed)[2]; - state[3] = ((word64*)seed)[3]; + readUnalignedWords64(state, seed, 4); state[4] = 0x1f00 + o; XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); state[16] = W64LIT(0x8000000000000000); @@ -4510,17 +4510,15 @@ static int mlkem_get_noise_k2_aarch64(sword16* vec1, sword16* vec2, */ static void mlkem_get_noise_eta2_aarch64(byte* rand, byte* seed, byte o) { - word64* state = (word64*)rand; + word64 state[25]; - state[0] = ((word64*)seed)[0]; - state[1] = ((word64*)seed)[1]; - state[2] = ((word64*)seed)[2]; - state[3] = ((word64*)seed)[3]; + readUnalignedWords64(state, seed, 4); /* Transposed value same as not. */ state[4] = 0x1f00 + o; XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); state[16] = W64LIT(0x8000000000000000); BlockSha3(state); + XMEMCPY(rand, state, ETA2_RAND_SIZE); } /* Get the noise/error by calculating random bytes and sampling to a binomial diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index bfb4ba86791..41ce2ce923f 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -76,6 +76,10 @@ #endif +#if defined(WOLFSSL_CAAM) + #include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -528,8 +532,13 @@ struct ecc_key { #endif #ifdef WOLFSSL_CAAM - word32 blackKey; /* address of key encrypted and in secure memory */ - word32 securePubKey; /* address of public key in secure memory */ + #ifdef CAAM_ADDRESS + CAAM_ADDRESS blackKey; /* address of key encrypted and in secure memory */ + CAAM_ADDRESS securePubKey; /* address of public key in secure memory */ + #else + word32 blackKey; /* address of key encrypted and in secure memory */ + word32 securePubKey; /* address of public key in secure memory */ + #endif int partNum; /* partition number*/ #endif #ifdef WOLFSSL_SE050 From 5ada2970a7d59afb5e2d3c187ef36666fca6c331 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Tue, 7 Jul 2026 12:46:15 -0600 Subject: [PATCH 2/5] Added new field to WC_DEVCRYPTO that singals if the object has been inited. Also fixed bug in aes where the authTag was appended past the end of the cypher text --- wolfcrypt/src/aes.c | 4 +- wolfcrypt/src/hmac.c | 2 +- wolfcrypt/src/port/devcrypto/devcrypto_aes.c | 67 ++++++++++++------- wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 10 ++- wolfcrypt/src/port/devcrypto/devcrypto_hmac.c | 1 + wolfcrypt/src/port/devcrypto/devcrypto_rsa.c | 2 - wolfcrypt/src/port/devcrypto/wc_devcrypto.c | 5 +- wolfcrypt/src/random.c | 2 +- wolfcrypt/src/wc_mlkem_poly.c | 2 + .../wolfcrypt/port/devcrypto/wc_devcrypto.h | 1 + 10 files changed, 59 insertions(+), 37 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 86a4bb6dce8..d476661d1b6 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -5837,7 +5837,7 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) #if defined(WOLFSSL_DEVCRYPTO) && \ (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) - aes->ctx.cfd = -1; + aes->ctx.inited = 0; #endif #ifdef WOLFSSL_IMX6_CAAM_BLOB ForceZero(local, sizeof(local)); @@ -14885,7 +14885,7 @@ int wc_AesInit(Aes* aes, void* heap, int devId) #endif #if defined(WOLFSSL_DEVCRYPTO) && \ (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) - aes->ctx.cfd = -1; + aes->ctx.inited = 0; #endif #if defined(WOLFSSL_IMXRT_DCP) DCPAesInit(aes); diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 07ce9761008..198a6f554de 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1519,7 +1519,7 @@ int wc_HmacInit(Hmac* hmac, void* heap, int devId) hmac->devCtx = NULL; #endif #if defined(WOLFSSL_DEVCRYPTO_HMAC) - hmac->ctx.cfd = -1; + hmac->ctx.inited = 0; #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c index 371f7c3de84..06ec5a3b18f 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c @@ -49,7 +49,7 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) if (sz == 0) { return 0; } - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CBC, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -82,7 +82,7 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) } XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE); - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CBC, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -129,6 +129,7 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, aes->left = 0; #endif aes->ctx.cfd = -1; + aes->ctx.inited = 0; XMEMCPY(aes->devKey, userKey, keylen); (void)dir; @@ -151,7 +152,7 @@ static int wc_DevCrypto_AesDirect(Aes* aes, byte* out, const byte* in, return BAD_FUNC_ARG; } - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_ECB, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -221,7 +222,7 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) sz--; } - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CTR, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -295,39 +296,49 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, { struct crypt_auth_op crt = {0}; int ret; - byte scratch[WC_AES_BLOCK_SIZE]; + byte* buf; + word32 bufSz; /* argument checks */ if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } - /* Account for NULL in/out buffers. Up to tag size is still written into - * in/out buffers */ - if (out == NULL) - out = scratch; - if (in == NULL) - in = scratch; - - XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE); - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_GCM, (byte*)aes->devKey, aes->keylen); if (ret != 0) return ret; } - /* if decrypting then the tag is expected to be at the end of "in" buffer */ + /* cryptodev requires the ciphertext and tag to be contiguous: on encrypt + * the tag is appended after the ciphertext, and on decrypt the tag is read + * from the end of the input. The caller's in/out buffers only hold "sz" + * bytes, so use a temporary buffer with room for the tag to avoid writing + * past their bounds. */ + bufSz = sz + WC_AES_BLOCK_SIZE; + buf = (byte*)XMALLOC(bufSz, aes->heap, DYNAMIC_TYPE_AES_BUFFER); + if (buf == NULL) { + return MEMORY_E; + } + XMEMSET(buf, 0, bufSz); + if (dir == COP_DECRYPT) { - XMEMCPY(in + sz, authTag, authTagSz); - sz += authTagSz; + /* build "ciphertext || tag" for the device to verify */ + if (in != NULL && sz > 0) + XMEMCPY(buf, in, sz); + XMEMCPY(buf + sz, authTag, authTagSz); + wc_SetupCryptAead(&crt, &aes->ctx, buf, sz + authTagSz, buf, (byte*)iv, + ivSz, dir, (byte*)authIn, authInSz, authTag, authTagSz); } - else{ - /* get full tag from hardware */ - authTagSz = WC_AES_BLOCK_SIZE; + else { + if (in != NULL && sz > 0) + XMEMCPY(buf, in, sz); + /* device writes the full block-sized tag after the ciphertext */ + wc_SetupCryptAead(&crt, &aes->ctx, buf, sz, buf, (byte*)iv, ivSz, dir, + (byte*)authIn, authInSz, authTag, WC_AES_BLOCK_SIZE); } - wc_SetupCryptAead(&crt, &aes->ctx, (byte*)in, sz, out, (byte*)iv, ivSz, - dir, (byte*)authIn, authInSz, authTag, authTagSz); + ret = ioctl(aes->ctx.cfd, CIOCAUTHCRYPT, &crt); if (ret != 0) { #ifdef DEBUG_WOLFSSL @@ -335,6 +346,7 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, WOLFSSL_MSG("authIn Buffer greater than System Page Size"); } #endif + XFREE(buf, aes->heap, DYNAMIC_TYPE_AES_BUFFER); if (dir == COP_DECRYPT) { return AES_GCM_AUTH_E; } @@ -343,10 +355,17 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, } } - /* after encryption the tag has been placed at the end of "out" buffer */ + /* copy the resulting plaintext/ciphertext back into the caller's buffer */ + if (out != NULL && sz > 0) { + XMEMCPY(out, buf, sz); + } + + /* after encryption the tag has been placed at the end of the buffer */ if (dir == COP_ENCRYPT) { - XMEMCPY(authTag, out + sz, authTagSz); + XMEMCPY(authTag, buf + sz, authTagSz); } + + XFREE(buf, aes->heap, DYNAMIC_TYPE_AES_BUFFER); return 0; } diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index f04b12df98e..04612dad481 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -120,7 +120,6 @@ int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId) (void)devId; /* no async for now */ XMEMSET(sha, 0, sizeof(wc_Sha256)); - sha->ctx.cfd = -1; /* Sentinel value matching aes */ sha->heap = heap; return HashInit((void*)sha, CRYPTO_SHA2_256, NULL, 0); @@ -196,10 +195,6 @@ int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) int ret; wc_Sha256 cpy; XMEMSET(&cpy, 0, sizeof(cpy)); /* ZII */ - /* mark as having no /dev/crypto session yet so the wc_Sha256Free() - * in wc_Sha256Copy() does not close fd 0 (cfd == -1 is the - * "no session" sentinel, matching wc_AesInit()) */ - cpy.ctx.cfd = -1; ret = wc_Sha256Copy(sha, &cpy); if (ret == 0 && @@ -229,9 +224,12 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) } #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP - /* Sha256Free checks that ctx.cfd is >= 0*/ wc_Sha256Free(dst); if ((ret = wc_InitSha256_ex(dst, src->heap, 0)) != 0) { + /* make sure that any attempts to free dst + * dont accidentally close an unopened fd */ + dst->ctx.inited = 0; + dst->ctx.cfd = -1; return ret; } dst->len = src->len; diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c b/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c index 7032181a982..d33704bd258 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c @@ -50,6 +50,7 @@ int wc_DevCrypto_HmacSetKey(Hmac* hmac, int t, const byte* key, word32 keySz) { int hType; + hmac->ctx.inited = 0; hmac->ctx.cfd = -1; hType = InternalTypeToDevcrypto(t); if (hType < 0) { diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c b/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c index 4d118f80da8..a0fbd6c830e 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c @@ -264,7 +264,6 @@ static int _PublicOperation(const byte* in, word32 inlen, byte* out, dev = &key->ctx; - key->ctx.cfd = -1; if (wc_DevCryptoCreate(dev, CRYPTO_ASYM_RSA_PUBLIC, NULL, 0) != 0) { WOLFSSL_MSG("Error getting RSA public session"); return WC_DEVCRYPTO_E; @@ -439,7 +438,6 @@ int wc_DevCrypto_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) byte eBuf[8]; int eBufSz; - key->ctx.cfd = -1; nSz = dSz = bSz; cSz = pSz = qSz = dpSz = dqSz = bSz/2; diff --git a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c index e6d82dab4e6..f939311e2c2 100644 --- a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c +++ b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -178,6 +178,8 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) sesInfo.cipher_info.cra_driver_name); } #endif + /* successful init */ + ctx->inited = 1; (void)key; (void)keySz; @@ -188,12 +190,13 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) /* free up descriptor and session used with ctx */ void wc_DevCryptoFree(WC_CRYPTODEV* ctx) { - if (ctx != NULL && ctx->cfd >= 0) { + if (ctx != NULL && ctx->inited == 1) { if (ioctl(ctx->cfd, CIOCFSESSION, &ctx->sess.ses)) { WOLFSSL_MSG("Error stopping cryptodev session"); } (void)close(ctx->cfd); ctx->cfd = -1; + ctx->inited = 0; } } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 0fa46fd520d..14f7a527ac8 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3731,7 +3731,7 @@ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) word64 rndTmpLocal; ret = IntelRDseed64_r(&rndTmpLocal); if (ret != 0) { - ForceZero(&rndTmp, sizeof(rndTmp)); + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); return ret; } writeUnalignedWord64(output, rndTmpLocal); diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c index 66ef8e8b7d5..860d1a0dbf9 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -4385,6 +4385,7 @@ static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) XMEMCPY(rand + 0 * 25 * 8, state + 0*25, ETA2_RAND_SIZE); XMEMCPY(rand + 1 * 25 * 8, state + 1*25, ETA2_RAND_SIZE); XMEMCPY(rand + 2 * 25 * 8, state + 2*25, ETA2_RAND_SIZE); + ForceZero(state, sizeof(state)); } #if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) @@ -4519,6 +4520,7 @@ static void mlkem_get_noise_eta2_aarch64(byte* rand, byte* seed, byte o) state[16] = W64LIT(0x8000000000000000); BlockSha3(state); XMEMCPY(rand, state, ETA2_RAND_SIZE); + ForceZero(state, sizeof(state)); } /* Get the noise/error by calculating random bytes and sampling to a binomial diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h index 47ee1b3f520..def1b3eeb8e 100644 --- a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -38,6 +38,7 @@ typedef struct WC_CRYPTODEV { int cfd; + word8 inited : 1;/* is this object initialized (1) or not (0) */ struct session_op sess; } WC_CRYPTODEV; From 5fc8031441b655178e946ce4b2064e998730a65c Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Tue, 7 Jul 2026 16:27:00 -0600 Subject: [PATCH 3/5] atomic mutex init fix --- wolfcrypt/src/random.c | 86 +++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 17 deletions(-) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 14f7a527ac8..64ff7f87631 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -378,32 +378,55 @@ static int sha256DrbgDisabled = 0; static int sha512DrbgDisabled = 0; #endif +enum { + wc_DrbgState_Mutex_Uninited, + wc_DrbgState_Mutex_InitProgress, + wc_DrbgState_Mutex_FreeProgress, + wc_DrbgState_Mutex_Inited +}; + #ifndef SINGLE_THREADED static wolfSSL_Mutex drbgStateMutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(drbgStateMutex); #ifndef WOLFSSL_MUTEX_INITIALIZER #ifdef WOLFSSL_ATOMIC_OPS -static wolfSSL_Atomic_Int drbgStateMutex_inited = WOLFSSL_ATOMIC_INITIALIZER(0); +static wolfSSL_Atomic_Int drbgStateMutex_inited = + WOLFSSL_ATOMIC_INITIALIZER(wc_DrbgState_Mutex_Uninited); #else static int drbgStateMutex_inited = 0; #endif #endif #endif /* !SINGLE_THREADED */ + int wc_DrbgState_MutexInit(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER - int expected = 0; - /* Check if mutex is not inited and set it to true before init. - * This means that the mutex is marked as init before it actually is. - * Necessary to ensure that two threads don't init at the same time.*/ - if (wolfSSL_Atomic_Int_CompareExchange(&drbgStateMutex_inited, - &expected, 1)) { - int ret = wc_InitMutex(&drbgStateMutex); - if (ret != 0) { - (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, 0); - return ret; + /* State machine so the mutex isn't marked ready before it is. The CAS + * winner initializes and publishes Inited; losers spin (via their own + * 'expected', which the failed CAS updates) until they see Inited. */ + for (;;) { + int expected = wc_DrbgState_Mutex_Uninited; + if (wolfSSL_Atomic_Int_CompareExchange(&drbgStateMutex_inited, + &expected, wc_DrbgState_Mutex_InitProgress)) { + /* We own initialization (state moved Uninited -> InitProgress). */ + int ret = wc_InitMutex(&drbgStateMutex); + if (ret != 0) { + /* Init failed; release ownership so another thread may retry. */ + (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, + wc_DrbgState_Mutex_Uninited); + return ret; + } + /* Publish the fully initialized mutex. */ + (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, + wc_DrbgState_Mutex_Inited); + return 0; + } + /* Spin until drbgStateMutex is inited */ + if (expected == wc_DrbgState_Mutex_Inited) { + /* Mutex is fully initialized. */ + return 0; } } #endif @@ -415,10 +438,35 @@ int wc_DrbgState_MutexFree(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER - if (drbgStateMutex_inited) { - int ret = wc_FreeMutex(&drbgStateMutex); - drbgStateMutex_inited = 0; - return ret; + /* CAS the ready state (Inited -> FreeProgress) so exactly one caller frees. + * Losers spin until it settles: Uninited returns success; Inited (a free + * that failed and rolled back) lets a spinning thread retry. */ + for (;;) { + int expected = wc_DrbgState_Mutex_Inited; + if (wolfSSL_Atomic_Int_CompareExchange(&drbgStateMutex_inited, + &expected, wc_DrbgState_Mutex_FreeProgress)) { + /* We own teardown (state moved Inited -> FreeProgress). */ + int ret = wc_FreeMutex(&drbgStateMutex); + if (ret != 0) { + /* Free failed (e.g. mutex still in use); it remains a live, + * valid object, so restore the ready state rather than leaving + * the flag claiming it is uninitialized. */ + (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, + wc_DrbgState_Mutex_Inited); + return ret; + } + /* Mark the mutex as no longer initialized. */ + (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, + wc_DrbgState_Mutex_Uninited); + return 0; + } + /* CAS failed; 'expected' holds the observed state. */ + if (expected == wc_DrbgState_Mutex_Uninited) { + /* Already freed or never initialized; nothing to do. */ + return 0; + } + /* expected == InitProgress or FreeProgress: another thread is busy; + * spin until it settles. */ } #endif #endif @@ -3809,9 +3857,13 @@ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), output += sizeof(word64)) { - ret = IntelRDrand64_r((word64 *)output); - if (ret != 0) + word64 rndTmpLocal; + ret = IntelRDseed64_r(&rndTmpLocal); + if (ret != 0) { + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); return ret; + } + writeUnalignedWord64(output, rndTmpLocal); } if (sz == 0) return 0; From 2541f5e7d308eacbf8ba22b5419a45a15337c3ea Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 8 Jul 2026 10:58:00 -0600 Subject: [PATCH 4/5] aes test fix --- tests/api/test_aes.c | 4 +- wolfcrypt/src/port/devcrypto/devcrypto_aes.c | 59 +++++++------------- wolfcrypt/src/random.c | 2 +- 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/tests/api/test_aes.c b/tests/api/test_aes.c index 01a998466a4..1c9186609b9 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -3233,13 +3233,13 @@ int test_wc_AesGcmEncryptDecrypt_Sizes(void) int sz; int i; WC_DECLARE_VAR(plain, byte, GCM_LEN, NULL); - WC_DECLARE_VAR(cipher, byte, GCM_LEN, NULL); + WC_DECLARE_VAR(cipher, byte, GCM_LEN+WC_AES_BLOCK_SIZE, NULL); #ifdef HAVE_AES_DECRYPT WC_DECLARE_VAR(decrypted, byte, GCM_LEN, NULL); #endif WC_ALLOC_VAR(plain, byte, GCM_LEN, NULL); - WC_ALLOC_VAR(cipher, byte, GCM_LEN, NULL); + WC_ALLOC_VAR(cipher, byte, GCM_LEN+WC_AES_BLOCK_SIZE, NULL); #ifdef HAVE_AES_DECRYPT WC_ALLOC_VAR(decrypted, byte, GCM_LEN, NULL); #endif diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c index 06ec5a3b18f..d7972e9f179 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c @@ -285,8 +285,6 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) return wc_AesSetKey(aes, key, len, NULL, AES_ENCRYPTION); } - - /* common code for AES-GCM encrypt/decrypt */ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, const byte* iv, word32 ivSz, @@ -296,14 +294,21 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, { struct crypt_auth_op crt = {0}; int ret; - byte* buf; - word32 bufSz; + byte scratch[WC_AES_BLOCK_SIZE]; /* argument checks */ if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE) { return BAD_FUNC_ARG; } + /* Account for NULL in/out buffers. Up to tag size is still written into + * in/out buffers */ + if (out == NULL) + out = scratch; + if (in == NULL) + in = scratch; + + XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE); if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_GCM, (byte*)aes->devKey, aes->keylen); @@ -311,34 +316,17 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, return ret; } - /* cryptodev requires the ciphertext and tag to be contiguous: on encrypt - * the tag is appended after the ciphertext, and on decrypt the tag is read - * from the end of the input. The caller's in/out buffers only hold "sz" - * bytes, so use a temporary buffer with room for the tag to avoid writing - * past their bounds. */ - bufSz = sz + WC_AES_BLOCK_SIZE; - buf = (byte*)XMALLOC(bufSz, aes->heap, DYNAMIC_TYPE_AES_BUFFER); - if (buf == NULL) { - return MEMORY_E; - } - XMEMSET(buf, 0, bufSz); - + /* if decrypting then the tag is expected to be at the end of "in" buffer */ if (dir == COP_DECRYPT) { - /* build "ciphertext || tag" for the device to verify */ - if (in != NULL && sz > 0) - XMEMCPY(buf, in, sz); - XMEMCPY(buf + sz, authTag, authTagSz); - wc_SetupCryptAead(&crt, &aes->ctx, buf, sz + authTagSz, buf, (byte*)iv, - ivSz, dir, (byte*)authIn, authInSz, authTag, authTagSz); + XMEMCPY(in + sz, authTag, authTagSz); + sz += authTagSz; } - else { - if (in != NULL && sz > 0) - XMEMCPY(buf, in, sz); - /* device writes the full block-sized tag after the ciphertext */ - wc_SetupCryptAead(&crt, &aes->ctx, buf, sz, buf, (byte*)iv, ivSz, dir, - (byte*)authIn, authInSz, authTag, WC_AES_BLOCK_SIZE); + else{ + /* get full tag from hardware */ + authTagSz = WC_AES_BLOCK_SIZE; } - + wc_SetupCryptAead(&crt, &aes->ctx, (byte*)in, sz, out, (byte*)iv, ivSz, + dir, (byte*)authIn, authInSz, authTag, authTagSz); ret = ioctl(aes->ctx.cfd, CIOCAUTHCRYPT, &crt); if (ret != 0) { #ifdef DEBUG_WOLFSSL @@ -346,7 +334,6 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, WOLFSSL_MSG("authIn Buffer greater than System Page Size"); } #endif - XFREE(buf, aes->heap, DYNAMIC_TYPE_AES_BUFFER); if (dir == COP_DECRYPT) { return AES_GCM_AUTH_E; } @@ -355,17 +342,10 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, } } - /* copy the resulting plaintext/ciphertext back into the caller's buffer */ - if (out != NULL && sz > 0) { - XMEMCPY(out, buf, sz); - } - - /* after encryption the tag has been placed at the end of the buffer */ + /* after encryption the tag has been placed at the end of "out" buffer */ if (dir == COP_ENCRYPT) { - XMEMCPY(authTag, buf + sz, authTagSz); + XMEMCPY(authTag, out + sz, authTagSz); } - - XFREE(buf, aes->heap, DYNAMIC_TYPE_AES_BUFFER); return 0; } @@ -418,4 +398,3 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) #endif /* HAVE_AES_ECB */ #endif /* WOLFSSL_DEVCRYPTO_AES */ #endif /* !NO_AES && WOLFSSL_DEVCRYPTO */ - diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 64ff7f87631..bdaf9e01ae1 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3858,7 +3858,7 @@ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), output += sizeof(word64)) { word64 rndTmpLocal; - ret = IntelRDseed64_r(&rndTmpLocal); + ret = IntelRDrand64_r(&rndTmpLocal); if (ret != 0) { ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); return ret; From 1d990db63895048d5e0d13be37ef4f3396d8c562 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 8 Jul 2026 15:04:55 -0600 Subject: [PATCH 5/5] possible windows fix --- wolfcrypt/src/random.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index bdaf9e01ae1..bee9f49458d 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -428,6 +428,8 @@ int wc_DrbgState_MutexInit(void) /* Mutex is fully initialized. */ return 0; } + + continue; } #endif #endif @@ -467,7 +469,10 @@ int wc_DrbgState_MutexFree(void) } /* expected == InitProgress or FreeProgress: another thread is busy; * spin until it settles. */ + continue; } + + return 0; #endif #endif return 0;