From 786fdcc41be59459ead37c4134df7923a14d4125 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 24 Jun 2026 14:46:10 -0600 Subject: [PATCH 01/12] 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 ed4f762a610..a4c3501f9ee 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -3994,7 +3994,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 1561f2ad174..252e483bbe1 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -1151,6 +1151,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 ec0b5d5c460..bc5ff67bfc5 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -270,10 +270,6 @@ ECC Curve Sizes: #include #endif -#if defined(WOLFSSL_CAAM) - #include -#endif - #if defined(WOLFSSL_KCAPI_ECC) #include #endif @@ -10513,7 +10509,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; @@ -12136,7 +12132,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; @@ -12144,7 +12140,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 c0baed81807..a99387bc882 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 0dff415cbe6..b2c308b994e 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 83dd85c8e08..a8454537ebe 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -389,19 +389,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 @@ -3835,9 +3845,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 56528414773..12389fbe418 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -5110,13 +5110,16 @@ static int mlkem_get_noise_k4_avx512(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) @@ -5183,10 +5186,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); @@ -5263,17 +5263,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 d020523c09f..a0f8e944380 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 d363a19995377544e98ff8714ffb09952cc7e393 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Tue, 7 Jul 2026 12:46:15 -0600 Subject: [PATCH 02/12] 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 79a2b0517e3..85465376827 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -5971,7 +5971,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 #ifdef WOLFSSL_CHECK_MEM_ZERO @@ -15786,7 +15786,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 e5267c1cbb3..f73fa9caeda 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1536,7 +1536,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 a8454537ebe..df8492b8db9 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3848,7 +3848,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 12389fbe418..611171962db 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -5120,6 +5120,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) @@ -5272,6 +5273,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 b50a5dfbb4d42ef31e55d9490ff7464e836f4ec0 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Tue, 7 Jul 2026 16:27:00 -0600 Subject: [PATCH 03/12] 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 df8492b8db9..8f291966982 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -385,32 +385,55 @@ static int sha256DrbgDisabled = 0; static int sha512DrbgDisabled = 0; #endif /* WOLFSSL_DRBG_SHA512 */ +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 @@ -422,10 +445,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 @@ -3932,9 +3980,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 432b9957d1a2b7a9a01a9a9a9bbfdefe27eea0a1 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 8 Jul 2026 10:58:00 -0600 Subject: [PATCH 04/12] 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 a4c3501f9ee..0a1a8116b3d 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -3262,13 +3262,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 8f291966982..836f30fb0bd 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3981,7 +3981,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 10f6294d5d3342a18d58e8065ec63ee0813273d3 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 8 Jul 2026 15:04:55 -0600 Subject: [PATCH 05/12] 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 836f30fb0bd..5a31a264591 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -435,6 +435,8 @@ int wc_DrbgState_MutexInit(void) /* Mutex is fully initialized. */ return 0; } + + continue; } #endif #endif @@ -474,7 +476,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; From 7323dea41b2eaae2e9c7f045fc8f7ff1e982c72c Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Tue, 14 Jul 2026 16:33:38 -0600 Subject: [PATCH 06/12] Added new thread yield macro and added new header with CAAM_ADDRESS def and a couple loose fixes --- doc/dox_comments/header_files/sha256.h | 4 +- tests/api/test_aes.c | 7 +- wolfcrypt/src/aes.c | 2 + wolfcrypt/src/des3.c | 4 +- wolfcrypt/src/dsa.c | 2 +- wolfcrypt/src/ecc.c | 4 ++ wolfcrypt/src/hmac.c | 1 + .../Espressif/esp_crt_bundle/esp_crt_bundle.c | 2 +- .../src/port/Renesas/renesas_fspsm_sha.c | 6 +- wolfcrypt/src/port/caam/wolfcaam_ecdsa.c | 2 +- wolfcrypt/src/port/caam/wolfcaam_hmac.c | 2 +- wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 25 +++---- wolfcrypt/src/random.c | 65 ++++++++++++------- wolfcrypt/src/wc_mlkem_poly.c | 4 +- wolfssl/wolfcrypt/ecc.h | 18 ++--- wolfssl/wolfcrypt/include.am | 3 +- wolfssl/wolfcrypt/port/caam/caam_qnx.h | 3 +- wolfssl/wolfcrypt/port/caam/caam_type.h | 48 ++++++++++++++ wolfssl/wolfcrypt/port/caam/wolfcaam.h | 1 + .../wolfcrypt/port/caam/wolfcaam_fsl_nxp.h | 2 +- wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h | 2 +- wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h | 3 +- .../wolfcrypt/port/devcrypto/wc_devcrypto.h | 2 +- wolfssl/wolfcrypt/settings.h | 2 + wolfssl/wolfcrypt/wc_port.h | 24 +++++++ 25 files changed, 170 insertions(+), 68 deletions(-) create mode 100644 wolfssl/wolfcrypt/port/caam/caam_type.h diff --git a/doc/dox_comments/header_files/sha256.h b/doc/dox_comments/header_files/sha256.h index 3a94b797ba9..2fe62b57a08 100644 --- a/doc/dox_comments/header_files/sha256.h +++ b/doc/dox_comments/header_files/sha256.h @@ -366,11 +366,11 @@ int wc_Sha256_Grow(wc_Sha256* sha256, const byte* in, int inSz); \return negative on error \param src Source SHA256 structure - \param dst Destination SHA256 structure + \param dst Destination SHA256 structure; must be zeroed/initialized _Example_ \code - wc_Sha256 src, dst; + wc_Sha256 src, dst = {0}; int ret = wc_Sha256Copy(&src, &dst); \endcode diff --git a/tests/api/test_aes.c b/tests/api/test_aes.c index 0a1a8116b3d..874f6585172 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -3262,6 +3262,8 @@ int test_wc_AesGcmEncryptDecrypt_Sizes(void) int sz; int i; WC_DECLARE_VAR(plain, byte, GCM_LEN, NULL); + /* enlarged size is to accommodate devcrypto build which assumes + * space in buffer to append auth tag */ WC_DECLARE_VAR(cipher, byte, GCM_LEN+WC_AES_BLOCK_SIZE, NULL); #ifdef HAVE_AES_DECRYPT WC_DECLARE_VAR(decrypted, byte, GCM_LEN, NULL); @@ -3288,7 +3290,7 @@ int test_wc_AesGcmEncryptDecrypt_Sizes(void) ExpectIntEQ(wc_AesGcmSetKey(&aes, key32, sizeof(key32)/sizeof(byte)), 0); for (sz = 0; sz < WC_AES_BLOCK_SIZE; sz++) { - XMEMSET(cipher, 0, GCM_LEN); + XMEMSET(cipher, 0, GCM_LEN + WC_AES_BLOCK_SIZE); ExpectIntEQ(wc_AesGcmEncrypt(&aes, cipher, plain, sz, iv, ivLen, tag, sizeof(tag), NULL, 0), 0); ExpectBufEQ(cipher, expected, sz); @@ -3304,7 +3306,7 @@ int test_wc_AesGcmEncryptDecrypt_Sizes(void) i = 0; for (sz = WC_AES_BLOCK_SIZE; sz <= GCM_LEN; sz *= 2) { - XMEMSET(cipher, 0, GCM_LEN); + XMEMSET(cipher, 0, GCM_LEN + WC_AES_BLOCK_SIZE); ExpectIntEQ(wc_AesGcmEncrypt(&aes, cipher, plain, sz, iv, ivLen, tag, sizeof(tag), NULL, 0), 0); ExpectBufEQ(tag, expTagLong[i], WC_AES_BLOCK_SIZE); @@ -3996,6 +3998,7 @@ int test_wc_AesGcmNonStdNonce(void) !defined(HAVE_FIPS) && \ !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_KCAPI) && \ !defined(WOLFSSL_DEVCRYPTO_AES) + /* DEVCRYPTO does not support Non std Nonce */ /* ------------------------------------------------------------------ * Section 1: 1-byte IV, AES-128 diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 85465376827..db16c717c40 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -5972,6 +5972,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.inited = 0; + aes->ctx.cfd = -1; #endif #ifdef WOLFSSL_IMX6_CAAM_BLOB #ifdef WOLFSSL_CHECK_MEM_ZERO @@ -15787,6 +15788,7 @@ int wc_AesInit(Aes* aes, void* heap, int devId) #if defined(WOLFSSL_DEVCRYPTO) && \ (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) aes->ctx.inited = 0; + aes->ctx.cfd = -1; #endif #if defined(WOLFSSL_IMXRT_DCP) DCPAesInit(aes); diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index 841fc960f95..10f6288aec8 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -1570,13 +1570,13 @@ pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28]; /* rotate left and right halves independently */ - for (j = 0; j < 48; j++) { /* select bits individually */ + for (j = 0; j < 48; j++) { /* select bits individually */ 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*/ + /* only set to bytebit value if bit == 1 */ ks[j/6] |= (byte)((bytebit[j % 6] >> 2) & mask); } diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 252e483bbe1..c5343867888 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -1151,7 +1151,7 @@ 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 */ + /* assign default value so verification is always failed on error */ *answer = 0; /* Note the min allowed digestSz here is WC_SHA_DIGEST_SIZE, not diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index bc5ff67bfc5..ca2e9bca158 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -270,6 +270,10 @@ ECC Curve Sizes: #include #endif +#if defined(WOLFSSL_CAAM) + #include +#endif + #if defined(WOLFSSL_KCAPI_ECC) #include #endif diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index f73fa9caeda..0138fc13cc9 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1537,6 +1537,7 @@ int wc_HmacInit(Hmac* hmac, void* heap, int devId) #endif #if defined(WOLFSSL_DEVCRYPTO_HMAC) hmac->ctx.inited = 0; + hmac->ctx.cfd = -1; #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 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 a99387bc882..85fc1923700 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,7 +983,7 @@ 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 + /* this_subject and this_issuer are a part of bundle_cert and will be * freed here*/ wolfSSL_X509_free(bundle_cert); bundle_cert = NULL; diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c index 8a263a63fd1..976543583d0 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 ((ret = Init(&handle)) == FSP_SUCCESS) { + if (Init(&handle) == FSP_SUCCESS) { ret = Update(&handle, (uint8_t*)hash->msg, hash->used); if (ret == FSP_SUCCESS) { ret = Final(&handle, out, (uint32_t*)&sz); @@ -433,6 +433,10 @@ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) } } } + + if (ret != FSP_SUCCESS) + ret = WC_HW_E; + wc_fspsm_hw_unlock(); #elif defined(WOLFSSL_RENESAS_RSIP) diff --git a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c index 57b3da424b6..308cdd5a427 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c +++ b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c @@ -339,7 +339,7 @@ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, /* private key */ if (key->blackKey == CAAM_BLACK_KEY_SM) { - buf[idx].TheAddress = (CAAM_ADDRESS)key->blackKey; + buf[idx].TheAddress = key->blackKey; args[0] = CAAM_BLACK_KEY_SM; /* is a black key in sm */ buf[idx].Length = keySz; } diff --git a/wolfcrypt/src/port/caam/wolfcaam_hmac.c b/wolfcrypt/src/port/caam/wolfcaam_hmac.c index fb9c149a4d2..e6c54286aae 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_hmac.c +++ b/wolfcrypt/src/port/caam/wolfcaam_hmac.c @@ -54,7 +54,7 @@ int wc_CAAM_Hmac(Hmac* hmac, int macType, const byte* msg, int msgSz, { int ret = 0; - if (hmac->ctx.cfd == -1 && hmac->keyLen > 0) { + if (hmac->ctx.inited == 0 && hmac->keyLen > 0) { ret = wc_DevCrypto_HmacSetKey(hmac, macType, hmac->keyRaw, hmac->keyLen); if (ret != 0) { diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index 04612dad481..4c573a2a6ed 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -193,12 +193,11 @@ int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP { int ret; - wc_Sha256 cpy; - XMEMSET(&cpy, 0, sizeof(cpy)); /* ZII */ + wc_Sha256 cpy = {0}; ret = wc_Sha256Copy(sha, &cpy); - if (ret == 0 && - (ret = HashUpdate(&cpy, CRYPTO_SHA2_256, cpy.msg, cpy.used)) == 0) { + 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); @@ -226,25 +225,21 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP 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; 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; + if (src->len > 0) { + 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); } - XMEMCPY(dst->msg, src->msg, src->len); return ret; #else - (void)src; - (void)dst; (void)ret; WOLFSSL_MSG("Compile with WOLFSSL_DEVCRYPTO_HASH_KEEP for this feature"); diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 5a31a264591..f1d099e6494 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -386,10 +386,10 @@ static int sha512DrbgDisabled = 0; #endif /* WOLFSSL_DRBG_SHA512 */ enum { - wc_DrbgState_Mutex_Uninited, - wc_DrbgState_Mutex_InitProgress, - wc_DrbgState_Mutex_FreeProgress, - wc_DrbgState_Mutex_Inited + WC_DRBG_MUTEX_UNINITED, + WC_DRBG_MUTEX_INITPROGRESS, + WC_DRBG_MUTEX_FREEPROGRESS, + WC_DRBG_MUTEX_INITED }; #ifndef SINGLE_THREADED @@ -398,9 +398,9 @@ static wolfSSL_Mutex drbgStateMutex #ifndef WOLFSSL_MUTEX_INITIALIZER #ifdef WOLFSSL_ATOMIC_OPS static wolfSSL_Atomic_Int drbgStateMutex_inited = - WOLFSSL_ATOMIC_INITIALIZER(wc_DrbgState_Mutex_Uninited); + WOLFSSL_ATOMIC_INITIALIZER(WC_DRBG_MUTEX_UNINITED); #else -static int drbgStateMutex_inited = 0; +static volatile int drbgStateMutex_inited = 0; #endif #endif #endif /* !SINGLE_THREADED */ @@ -410,34 +410,45 @@ int wc_DrbgState_MutexInit(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER + #if defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_THREAD_YIELD) /* 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; + WC_ATOMIC_INT_ARG expected = WC_DRBG_MUTEX_UNINITED; if (wolfSSL_Atomic_Int_CompareExchange(&drbgStateMutex_inited, - &expected, wc_DrbgState_Mutex_InitProgress)) { + &expected, WC_DRBG_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); + WC_DRBG_MUTEX_UNINITED); return ret; } /* Publish the fully initialized mutex. */ (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, - wc_DrbgState_Mutex_Inited); + WC_DRBG_MUTEX_INITED); return 0; } /* Spin until drbgStateMutex is inited */ - if (expected == wc_DrbgState_Mutex_Inited) { + if (expected == WC_DRBG_MUTEX_INITED) { /* Mutex is fully initialized. */ return 0; } - continue; + WOLFSSL_THREAD_YIELD(); } + #else + if (drbgStateMutex_inited == WC_DRBG_MUTEX_UNINITED) { + int ret = wc_InitMutex(&drbgStateMutex); + if (ret != 0) { + return ret; + } + drbgStateMutex_inited = WC_DRBG_MUTEX_INITED; + } + #endif + #endif #endif return 0; @@ -447,13 +458,14 @@ int wc_DrbgState_MutexFree(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER + #if defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_THREAD_YIELD) /* 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; + WC_ATOMIC_INT_ARG expected = WC_DRBG_MUTEX_INITED; if (wolfSSL_Atomic_Int_CompareExchange(&drbgStateMutex_inited, - &expected, wc_DrbgState_Mutex_FreeProgress)) { + &expected, WC_DRBG_MUTEX_FREEPROGRESS)) { /* We own teardown (state moved Inited -> FreeProgress). */ int ret = wc_FreeMutex(&drbgStateMutex); if (ret != 0) { @@ -461,25 +473,31 @@ int wc_DrbgState_MutexFree(void) * 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); + WC_DRBG_MUTEX_INITED); return ret; } /* Mark the mutex as no longer initialized. */ (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, - wc_DrbgState_Mutex_Uninited); + WC_DRBG_MUTEX_UNINITED); return 0; } /* CAS failed; 'expected' holds the observed state. */ - if (expected == wc_DrbgState_Mutex_Uninited) { + if (expected == WC_DRBG_MUTEX_UNINITED) { /* Already freed or never initialized; nothing to do. */ return 0; } - /* expected == InitProgress or FreeProgress: another thread is busy; - * spin until it settles. */ - continue; - } - return 0; + WOLFSSL_THREAD_YIELD(); + } + #else + if (drbgStateMutex_inited == WC_DRBG_MUTEX_INITED) { + int ret = wc_FreeMutex(&drbgStateMutex); + if (ret != 0) { + return ret; + } + drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; + } + #endif #endif #endif return 0; @@ -3905,6 +3923,7 @@ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) return ret; } writeUnalignedWord64(output, rndTmpLocal); + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); } if (sz == 0) return 0; @@ -3992,6 +4011,7 @@ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) return ret; } writeUnalignedWord64(output, rndTmpLocal); + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); } if (sz == 0) return 0; @@ -4002,6 +4022,7 @@ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) return ret; XMEMCPY(output, &rndTmp, sz); + ForceZero(&rndTmp, sizeof(rndTmp)); return 0; } diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c index 611171962db..b939cfe22d1 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -5110,7 +5110,7 @@ static int mlkem_get_noise_k4_avx512(MLKEM_PRF_T* prf, sword16* vec1, */ static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) { - word64 state[3 * 25]; + word64 state[3 * 25] = {0}; state[0*25 + 4] = 0x1f00 + 0 + o; state[1*25 + 4] = 0x1f00 + 1 + o; @@ -5143,7 +5143,7 @@ static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) */ static void mlkem_get_noise_x3_eta3_aarch64(byte* rand, byte* seed, byte o) { - word64 state[3 * 25]; + word64 state[3 * 25] = {0}; state[0*25 + 4] = 0x1f00 + 0 + o; state[1*25 + 4] = 0x1f00 + 1 + o; diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index a0f8e944380..97c0e0859f6 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -67,6 +67,11 @@ #include #endif +#ifdef WOLFSSL_CAAM + /* for CAAM_ADDRESS, used by struct ecc_key below */ + #include +#endif + #if defined(WOLFSSL_XILINX_CRYPT_VERSAL) #include #endif @@ -76,10 +81,6 @@ #endif -#if defined(WOLFSSL_CAAM) - #include -#endif - #ifdef __cplusplus extern "C" { #endif @@ -532,13 +533,8 @@ struct ecc_key { #endif #ifdef WOLFSSL_CAAM - #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 + CAAM_ADDRESS blackKey; /* address of key encrypted and in secure memory */ + CAAM_ADDRESS securePubKey; /* address of public key in secure memory */ int partNum; /* partition number*/ #endif #ifdef WOLFSSL_SE050 diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index d10b3cb3dd4..86018af96e5 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -209,7 +209,8 @@ endif endif if BUILD_CAAM -nobase_include_HEADERS+= wolfssl/wolfcrypt/port/caam/wolfcaam.h \ +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/caam/caam_type.h \ + wolfssl/wolfcrypt/port/caam/wolfcaam.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_hash.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_rsa.h \ diff --git a/wolfssl/wolfcrypt/port/caam/caam_qnx.h b/wolfssl/wolfcrypt/port/caam/caam_qnx.h index 7e4f5676a1e..74117569f2c 100644 --- a/wolfssl/wolfcrypt/port/caam/caam_qnx.h +++ b/wolfssl/wolfcrypt/port/caam/caam_qnx.h @@ -41,10 +41,11 @@ #define CAAM_LOCK_MUTEX(x) pthread_mutex_lock((x)) #define CAAM_UNLOCK_MUTEX(x) pthread_mutex_unlock((x)) +#include + #define Error int #define Value int #define Boolean int -#define CAAM_ADDRESS uintptr_t #define Success 1 #define Failure 0 #define INTERRUPT_Panic() do {} while (0) diff --git a/wolfssl/wolfcrypt/port/caam/caam_type.h b/wolfssl/wolfcrypt/port/caam/caam_type.h new file mode 100644 index 00000000000..5b07d266fce --- /dev/null +++ b/wolfssl/wolfcrypt/port/caam/caam_type.h @@ -0,0 +1,48 @@ +/* caam_type.h + * + * Copyright (C) 2006-2026 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Single definition of CAAM_ADDRESS, the type used to hold an address handed to + * or returned from the CAAM. + * + * struct ecc_key stores CAAM addresses, so its layout depends on this type. + * Keep the definition here, selected only from build configuration macros, so + * that every translation unit in a build agrees on it no matter which of the + * CAAM headers it happens to include, and in which order. + * + * This header intentionally has no wolfSSL dependencies; the standalone QNX + * driver build includes it without settings.h. Whatever includes it is expected + * to have already pulled in settings.h if it needs the configuration macros. + */ + +#ifndef WOLF_CRYPT_CAAM_TYPE_H +#define WOLF_CRYPT_CAAM_TYPE_H + +#include + +#ifndef CAAM_ADDRESS + #ifdef WOLFSSL_SECO_CAAM + #define CAAM_ADDRESS intptr_t + #else + #define CAAM_ADDRESS uintptr_t + #endif +#endif + +#endif /* WOLF_CRYPT_CAAM_TYPE_H */ diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam.h b/wolfssl/wolfcrypt/port/caam/wolfcaam.h index d033054249b..4d7aa270aaf 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam.h @@ -24,6 +24,7 @@ #include #include +#include /* include for porting layer */ #ifdef WOLFSSL_QNX_CAAM diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h index 032c0f22f29..39a90e46a8f 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h @@ -50,7 +50,7 @@ #define NoActivityReady -1 #define MemoryOperationNotPerformed -1 -#define CAAM_ADDRESS uintptr_t +#include #ifndef WOLFSSL_CAAM_BUFFER #define WOLFSSL_CAAM_BUFFER typedef struct CAAM_BUFFER { diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h index 910d17db12d..b1f7b552097 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h @@ -41,7 +41,7 @@ #define NoActivityReady -1 #define MemoryOperationNotPerformed -1 -#define CAAM_ADDRESS uintptr_t +#include #ifndef WOLFSSL_CAAM_BUFFER #define WOLFSSL_CAAM_BUFFER typedef struct CAAM_BUFFER { diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h index 6d9004e9232..19be34e8478 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h @@ -44,8 +44,7 @@ #define NoActivityReady -1 #define MemoryOperationNotPerformed -1 -#include -#define CAAM_ADDRESS intptr_t +#include #ifndef WOLFSSL_CAAM_BUFFER #define WOLFSSL_CAAM_BUFFER typedef struct CAAM_BUFFER { diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h index def1b3eeb8e..c3387d76f7f 100644 --- a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -38,7 +38,7 @@ typedef struct WC_CRYPTODEV { int cfd; - word8 inited : 1;/* is this object initialized (1) or not (0) */ + unsigned int inited : 1;/* is this object initialized (1) or not (0) */ struct session_op sess; } WC_CRYPTODEV; diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 696ece03230..c3eded1b936 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -3153,6 +3153,7 @@ #endif #ifdef WOLFSSL_SECO_CAAM + #undef WOLFSSL_CAAM #define WOLFSSL_CAAM #define WOLFSSL_HASH_KEEP @@ -3160,6 +3161,7 @@ #endif #ifdef WOLFSSL_IMXRT1170_CAAM + #undef WOLFSSL_CAAM #define WOLFSSL_CAAM #endif diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 3d3faf24ac6..0709d162d43 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -773,6 +773,30 @@ } #endif +/* Yield the CPU to another runnable thread. Used by spin-wait loops that are + * waiting on another thread to finish a short critical section. Ports may + * override. */ +#ifndef WOLFSSL_THREAD_YIELD + #if defined(SINGLE_THREADED) + #define WOLFSSL_THREAD_YIELD() WC_DO_NOTHING + #elif defined(WOLFSSL_PTHREADS) + #include + #define WOLFSSL_THREAD_YIELD() (void)sched_yield() + #elif defined(USE_WINDOWS_API) && !defined(WOLFSSL_NOT_WINDOWS_API) + #define WOLFSSL_THREAD_YIELD() (void)SwitchToThread() + #elif defined(FREERTOS) + #define WOLFSSL_THREAD_YIELD() taskYIELD() + #elif defined(THREADX) + #define WOLFSSL_THREAD_YIELD() tx_thread_relinquish() + #elif defined(WOLFSSL_ZEPHYR) + #define WOLFSSL_THREAD_YIELD() k_yield() + #elif defined(WOLFSSL_VXWORKS) + #include + #include + #define WOLFSSL_THREAD_YIELD() (void)taskDelay(0) + #endif +#endif + /* Reference counting. */ typedef struct wolfSSL_RefWithMutex { #if !defined(SINGLE_THREADED) From 5151f5b81466469ffa6563baeab79348babeed15 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 15 Jul 2026 10:20:32 -0600 Subject: [PATCH 07/12] skoll fixes --- wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c | 2 +- wolfcrypt/src/random.c | 4 ++-- wolfssl/wolfcrypt/wc_port.h | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c index 976543583d0..0dbca3eccc5 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/random.c b/wolfcrypt/src/random.c index f1d099e6494..c088cdd7c73 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -396,11 +396,11 @@ enum { static wolfSSL_Mutex drbgStateMutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(drbgStateMutex); #ifndef WOLFSSL_MUTEX_INITIALIZER -#ifdef WOLFSSL_ATOMIC_OPS +#if defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_THREAD_YIELD) static wolfSSL_Atomic_Int drbgStateMutex_inited = WOLFSSL_ATOMIC_INITIALIZER(WC_DRBG_MUTEX_UNINITED); #else -static volatile int drbgStateMutex_inited = 0; +static volatile int drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; #endif #endif #endif /* !SINGLE_THREADED */ diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 0709d162d43..be47e9fc2c5 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -783,12 +783,16 @@ #include #define WOLFSSL_THREAD_YIELD() (void)sched_yield() #elif defined(USE_WINDOWS_API) && !defined(WOLFSSL_NOT_WINDOWS_API) + #include #define WOLFSSL_THREAD_YIELD() (void)SwitchToThread() #elif defined(FREERTOS) + #include #define WOLFSSL_THREAD_YIELD() taskYIELD() #elif defined(THREADX) + #include #define WOLFSSL_THREAD_YIELD() tx_thread_relinquish() #elif defined(WOLFSSL_ZEPHYR) + #include #define WOLFSSL_THREAD_YIELD() k_yield() #elif defined(WOLFSSL_VXWORKS) #include From 247c62a2e2cff1ef05325d54d8dea7c277ec1a0d Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 15 Jul 2026 10:28:20 -0600 Subject: [PATCH 08/12] freertos compile error --- wolfcrypt/src/random.c | 11 ++++++++--- wolfssl/wolfcrypt/wc_port.h | 5 +---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index c088cdd7c73..1a91bf82dc7 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -448,10 +448,12 @@ int wc_DrbgState_MutexInit(void) drbgStateMutex_inited = WC_DRBG_MUTEX_INITED; } #endif - -#endif +#else + return 0; #endif +#else return 0; +#endif } int wc_DrbgState_MutexFree(void) @@ -498,9 +500,12 @@ int wc_DrbgState_MutexFree(void) drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; } #endif +#else + return 0; #endif -#endif +#else return 0; +#endif } static int LockDrbgState(void) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index be47e9fc2c5..e0d86c1b3ab 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -786,13 +786,10 @@ #include #define WOLFSSL_THREAD_YIELD() (void)SwitchToThread() #elif defined(FREERTOS) - #include #define WOLFSSL_THREAD_YIELD() taskYIELD() #elif defined(THREADX) - #include #define WOLFSSL_THREAD_YIELD() tx_thread_relinquish() - #elif defined(WOLFSSL_ZEPHYR) - #include + #elif defined(WOLFSSL_ZEPHYR) && KERNEL_VERSION_NUMBER >= 0x30100 #define WOLFSSL_THREAD_YIELD() k_yield() #elif defined(WOLFSSL_VXWORKS) #include From b202fecd105f7ba57c4626f5a6347edd396df104 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 15 Jul 2026 15:43:54 -0600 Subject: [PATCH 09/12] zepher fix for when thread yeild is not present --- wolfcrypt/src/random.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 1a91bf82dc7..6fe31884193 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -447,6 +447,8 @@ int wc_DrbgState_MutexInit(void) } drbgStateMutex_inited = WC_DRBG_MUTEX_INITED; } + + return 0; #endif #else return 0; @@ -499,6 +501,7 @@ int wc_DrbgState_MutexFree(void) } drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; } + return 0; #endif #else return 0; From 009b9542b5c2d1d407cce11b9ef56cdf9a8f176b Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Tue, 4 Aug 2026 13:24:09 -0600 Subject: [PATCH 10/12] github reiview fixes and skoll fixes - Major change is I reverted the Mutex init thread safe attempt to just expect callers to call single threaded --- IDE/QNX/example-server/server-tls.c | 6 +- doc/dox_comments/header_files/sha.h | 6 +- doc/dox_comments/header_files/sha256.h | 16 +- doc/dox_comments/header_files/sha3.h | 12 ++ doc/dox_comments/header_files/sha512.h | 24 ++- doc/dox_comments/header_files/wc_port.h | 15 ++ wolfcrypt/src/aes.c | 8 +- wolfcrypt/src/des3.c | 13 +- wolfcrypt/src/dsa.c | 2 +- .../Espressif/esp_crt_bundle/esp_crt_bundle.c | 2 +- .../src/port/Renesas/renesas_fspsm_aes.c | 2 +- .../src/port/Renesas/renesas_fspsm_sha.c | 83 +++++++---- wolfcrypt/src/port/caam/wolfcaam_ecdsa.c | 30 ++-- wolfcrypt/src/port/caam/wolfcaam_init.c | 5 +- wolfcrypt/src/port/devcrypto/devcrypto_aes.c | 4 +- wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 15 +- wolfcrypt/src/port/devcrypto/devcrypto_hmac.c | 5 +- wolfcrypt/src/port/devcrypto/wc_devcrypto.c | 6 + wolfcrypt/src/random.c | 139 +++++------------- wolfcrypt/src/siphash.c | 2 +- wolfcrypt/src/wc_mlkem_poly.c | 102 +++++++------ wolfssl/wolfcrypt/include.am | 4 +- wolfssl/wolfcrypt/port/caam/caam_type.h | 9 +- .../wolfcrypt/port/devcrypto/wc_devcrypto.h | 5 +- wolfssl/wolfcrypt/wc_port.h | 45 +++--- 25 files changed, 304 insertions(+), 256 deletions(-) diff --git a/IDE/QNX/example-server/server-tls.c b/IDE/QNX/example-server/server-tls.c index 2f41b0d3891..50561c2b2fb 100644 --- a/IDE/QNX/example-server/server-tls.c +++ b/IDE/QNX/example-server/server-tls.c @@ -169,8 +169,10 @@ int cover(ecc_key* keyOut, const byte* der, word32 derSz) wc_ecc_free(keyOut); goto done; } - printf("blackKeySz = %d, virtual secure address ecc_key.blackKey = 0x%08X\n", - blackKeySz, keyOut->blackKey); + /* blackKey is CAAM_ADDRESS (uintptr_t), so cast up to a width that holds it + * on both armv7le and aarch64le rather than relying on int-sized varargs */ + printf("blackKeySz = %u, virtual secure address ecc_key.blackKey " + "= 0x%08lX\n", blackKeySz, (unsigned long)keyOut->blackKey); ret = 0; done: diff --git a/doc/dox_comments/header_files/sha.h b/doc/dox_comments/header_files/sha.h index e6368fa4a48..5d9ae5269de 100644 --- a/doc/dox_comments/header_files/sha.h +++ b/doc/dox_comments/header_files/sha.h @@ -193,11 +193,15 @@ int wc_ShaFinalRaw(wc_Sha* sha, byte* hash); \param src Source SHA structure \param dst Destination SHA structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha src, dst; - int ret = wc_ShaCopy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha(&src); + if (ret == 0) + ret = wc_ShaCopy(&src, &dst); \endcode \sa wc_InitSha diff --git a/doc/dox_comments/header_files/sha256.h b/doc/dox_comments/header_files/sha256.h index 2fe62b57a08..57f86be2dca 100644 --- a/doc/dox_comments/header_files/sha256.h +++ b/doc/dox_comments/header_files/sha256.h @@ -366,12 +366,16 @@ int wc_Sha256_Grow(wc_Sha256* sha256, const byte* in, int inSz); \return negative on error \param src Source SHA256 structure - \param dst Destination SHA256 structure; must be zeroed/initialized + \param dst Destination SHA256 structure; + (must be zeroed or previously initialized) _Example_ \code - wc_Sha256 src, dst = {0}; - int ret = wc_Sha256Copy(&src, &dst); + wc_Sha256 src, dst; + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha256(&src); + if (ret == 0) + ret = wc_Sha256Copy(&src, &dst); \endcode \sa wc_InitSha256 @@ -534,11 +538,15 @@ int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash); \param src Source SHA224 structure \param dst Destination SHA224 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha224 src, dst; - int ret = wc_Sha224Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha224(&src); + if (ret == 0) + ret = wc_Sha224Copy(&src, &dst); \endcode \sa wc_InitSha224 diff --git a/doc/dox_comments/header_files/sha3.h b/doc/dox_comments/header_files/sha3.h index 6389939f8ff..2707ee9aa10 100644 --- a/doc/dox_comments/header_files/sha3.h +++ b/doc/dox_comments/header_files/sha3.h @@ -162,11 +162,13 @@ int wc_Sha3_224_GetHash(wc_Sha3* sha3, byte* hash); \param sha3 pointer to the sha3 structure to copy \param dst pointer to the sha3 structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Sha3 sha3[1]; wc_Sha3 sha3_dup[1]; + memset(sha3_dup, 0, sizeof(*sha3_dup)); if ((ret = wc_InitSha3_224(sha3, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitSha3_224 failed"); } @@ -347,11 +349,13 @@ int wc_Sha3_256_GetHash(wc_Sha3* sha3, byte* hash); \param sha3 pointer to the sha3 structure to copy \param dst pointer to the sha3 structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Sha3 sha3[1]; wc_Sha3 sha3_dup[1]; + memset(sha3_dup, 0, sizeof(*sha3_dup)); if ((ret = wc_InitSha3_256(sha3, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitSha3_256 failed"); } @@ -532,11 +536,13 @@ int wc_Sha3_384_GetHash(wc_Sha3* sha3, byte* hash); \param sha3 pointer to the sha3 structure to copy \param dst pointer to the sha3 structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Sha3 sha3[1]; wc_Sha3 sha3_dup[1]; + memset(sha3_dup, 0, sizeof(*sha3_dup)); if ((ret = wc_InitSha3_384(sha3, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitSha3_384 failed"); } @@ -717,11 +723,13 @@ int wc_Sha3_512_GetHash(wc_Sha3* sha3, byte* hash); \param sha3 pointer to the sha3 structure to copy \param dst pointer to the sha3 structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Sha3 sha3[1]; wc_Sha3 sha3_dup[1]; + memset(sha3_dup, 0, sizeof(*sha3_dup)); if ((ret = wc_InitSha3_512(sha3, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitSha3_512 failed"); } @@ -972,11 +980,13 @@ int wc_Shake128_GetHash(wc_Shake* shake, byte* hash); \param shake pointer to the shake structure to copy \param dst pointer to the shake structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Shake shake[1]; wc_Shake shake_dup[1]; + memset(shake_dup, 0, sizeof(*shake_dup)); if ((ret = wc_InitShake128(shake, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitShake128 failed"); } @@ -1227,11 +1237,13 @@ int wc_Shake256_GetHash(wc_Shake* shake, byte* hash); \param shake pointer to the shake structure to copy \param dst pointer to the shake structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Shake shake[1]; wc_Shake shake_dup[1]; + memset(shake_dup, 0, sizeof(*shake_dup)); if ((ret = wc_InitShake256(shake, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitShake256 failed"); } diff --git a/doc/dox_comments/header_files/sha512.h b/doc/dox_comments/header_files/sha512.h index 0f9c129a479..84e43dbf66d 100644 --- a/doc/dox_comments/header_files/sha512.h +++ b/doc/dox_comments/header_files/sha512.h @@ -273,11 +273,15 @@ int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash); \param src Source SHA512 structure \param dst Destination SHA512 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha512 src, dst; - int ret = wc_Sha512Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha512(&src); + if (ret == 0) + ret = wc_Sha512Copy(&src, &dst); \endcode \sa wc_InitSha512 @@ -521,11 +525,15 @@ int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash); \param src Source SHA512 structure \param dst Destination SHA512 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha512 src, dst; - int ret = wc_Sha512_224Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha512_224(&src); + if (ret == 0) + ret = wc_Sha512_224Copy(&src, &dst); \endcode \sa wc_InitSha512_224 @@ -747,11 +755,15 @@ int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash); \param src Source SHA512 structure \param dst Destination SHA512 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha512 src, dst; - int ret = wc_Sha512_256Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha512_256(&src); + if (ret == 0) + ret = wc_Sha512_256Copy(&src, &dst); \endcode \sa wc_InitSha512_256 @@ -911,11 +923,15 @@ int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash); \param src Source SHA384 structure \param dst Destination SHA384 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha384 src, dst; - int ret = wc_Sha384Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha384(&src); + if (ret == 0) + ret = wc_Sha384Copy(&src, &dst); \endcode \sa wc_InitSha384 diff --git a/doc/dox_comments/header_files/wc_port.h b/doc/dox_comments/header_files/wc_port.h index 74db950f9a3..b90f6a76689 100644 --- a/doc/dox_comments/header_files/wc_port.h +++ b/doc/dox_comments/header_files/wc_port.h @@ -3,6 +3,16 @@ \brief Used to initialize resources used by wolfCrypt. + \note Concurrent calls are serialized by an internal atomic init-state + machine, so only the first caller runs the initialization body. That + protection depends on working atomics: in builds with WOLFSSL_NO_ATOMICS + (or any non-SINGLE_THREADED build where WOLFSSL_ATOMIC_OPS ends up + undefined), the atomic primitives fall back to thread-unsafe non-atomic + operations and two threads racing the first wolfCrypt_Init() can both run + the init body, double-creating internal resources. The recommended calling + convention in every build is to call wolfCrypt_Init() once during startup, + before starting any thread that uses wolfSSL or wolfCrypt. + \return 0 upon success. \return <0 upon failure of init resources. @@ -25,6 +35,11 @@ int wolfCrypt_Init(void); \brief Used to clean up resources used by wolfCrypt. + \note Concurrent calls are serialized by the same atomic init-state machine + used by wolfCrypt_Init(), with the same dependence on working atomics. Call + wolfCrypt_Cleanup() once during shutdown, after every thread that uses + wolfSSL or wolfCrypt has been joined. See the note on wolfCrypt_Init(). + \return 0 upon success. \return <0 upon failure of cleaning up resources. diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index db16c717c40..4c010fbf28b 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -5971,8 +5971,13 @@ 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)) + /* Release any session already held. The session was created with the + * previous key, so re-keying must tear it down rather than just mark + * the context uninitialized, which would orphan the descriptor and + * leave the stale key in use. */ + wc_DevCryptoFree(&aes->ctx); aes->ctx.inited = 0; - aes->ctx.cfd = -1; + aes->ctx.cfd = -1; /* not set when no session was open */ #endif #ifdef WOLFSSL_IMX6_CAAM_BLOB #ifdef WOLFSSL_CHECK_MEM_ZERO @@ -15787,7 +15792,6 @@ int wc_AesInit(Aes* aes, void* heap, int devId) #endif #if defined(WOLFSSL_DEVCRYPTO) && \ (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) - aes->ctx.inited = 0; aes->ctx.cfd = -1; #endif #if defined(WOLFSSL_IMXRT_DCP) diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index 10f6288aec8..a3560a4ecda 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -1565,16 +1565,19 @@ for (i = 0; i < 16; i++) { /* key chunk for each iteration */ XMEMSET(ks, 0, 8); /* Clear key schedule */ - for (j = 0; j < 56; j++) /* rotate pc1 the right amount */ - pcr[j] = - pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28]; - /* rotate left and right halves independently */ + for (j = 0; j < 28; j++) { /* rotate pc1 the right amount */ + l = (j + totrot[i]) % 28; + pcr[j] = pc1m[l]; + pcr[j + 28] = pc1m[l + 28]; + } + for (j = 0; j < 48; j++) { /* select bits individually */ byte bit; byte mask; bit = - (byte)(pcr[pc2[j] - 1]); /* all pcr values are either 0 or 1 */ + (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] |= diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index c5343867888..ae1a1a7a8a4 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -1154,7 +1154,7 @@ int wc_DsaVerify_ex(const byte* digest, word32 digestSz, const byte* sig, /* assign default value so verification is always failed on error */ *answer = 0; - /* Note the min allowed digestSz here is WC_SHA_DIGEST_SIZE, not + /* Note the min allowed digestSz here is WC_MIN_DIGEST_SIZE_FOR_VERIFY, 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. */ 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 85fc1923700..94ba64fe611 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 @@ -984,7 +984,7 @@ static CB_INLINE int wolfssl_ssl_conf_verify_cb_no_signer(int preverify, if ((_crt_found == 0) && (bundle_cert != NULL)) { ESP_LOGW(TAG, "Cert not found, free bundle_cert"); /* this_subject and this_issuer are a part of bundle_cert and will be - * freed here*/ + * freed here */ wolfSSL_X509_free(bundle_cert); bundle_cert = NULL; this_issuer = NULL; diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c index b2c308b994e..c9d9dae0b94 100644 --- a/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c +++ b/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c @@ -410,7 +410,7 @@ 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_server_aes == NULL || key_client_aes == NULL) { + if (key_client_aes == NULL || key_server_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); diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c index 0dbca3eccc5..e61b149bb50 100644 --- a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c +++ b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c @@ -281,6 +281,11 @@ static int FSPSM_HashInit(wolfssl_FSPSM_Hash* hash, void* heap, int devId, } wc_fspsm_hw_lock(); ret = Init(&hash->handle); + if (ret != FSP_SUCCESS) { + WOLFSSL_MSG("ShaInit operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } wc_fspsm_hw_unlock(); return ret; #endif @@ -370,6 +375,11 @@ static int FSPSM_HashUpdate(wolfssl_FSPSM_Hash* hash, } wc_fspsm_hw_lock(); ret = Update(&hash->handle, (byte*)data, sz); + if (ret != FSP_SUCCESS) { + WOLFSSL_MSG("ShaUpdate operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } wc_fspsm_hw_unlock(); return ret; #endif @@ -418,24 +428,29 @@ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) #endif wc_fspsm_hw_lock(); - 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); - if (ret != FSP_SUCCESS - #if defined(WOLFSSL_RENESAS_SCEPROTECT) - || sz != outSz - #endif - ) { - WOLFSSL_MSG("Sha operation failed"); - WOLFSSL_ERROR(WC_HW_E); - ret = WC_HW_E; - } - } + if ((ret = Init(&handle)) != FSP_SUCCESS) { + WOLFSSL_MSG("Sha init operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; } - - if (ret != FSP_SUCCESS) + else if ((ret = Update(&handle, (uint8_t*)hash->msg, hash->used)) + != FSP_SUCCESS) { + WOLFSSL_MSG("Sha update operation failed"); + WOLFSSL_ERROR(WC_HW_E); ret = WC_HW_E; + } + else { + ret = Final(&handle, out, (uint32_t*)&sz); + if (ret != FSP_SUCCESS + #if defined(WOLFSSL_RENESAS_SCEPROTECT) + || sz != outSz + #endif + ) { + WOLFSSL_MSG("Sha operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } + } wc_fspsm_hw_unlock(); @@ -523,19 +538,27 @@ static int FSPSM_HashGet(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) if (ret != 0) return ret; #endif wc_fspsm_hw_lock(); - if (Init(&handle) == FSP_SUCCESS) { - ret = Update(&handle, (uint8_t*)hash->msg, hash->used); - if (ret == FSP_SUCCESS) { - ret = Final(&handle, out, &sz); - if (ret != FSP_SUCCESS - #if defined(WOLFSSL_RENESAS_SCEPROTECT) - || sz != outSz - #endif - ) { - WOLFSSL_MSG("Sha operation failed"); - WOLFSSL_ERROR(WC_HW_E); - ret = WC_HW_E; - } + if ((ret = Init(&handle)) != FSP_SUCCESS) { + WOLFSSL_MSG("Sha init operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } + else if ((ret = Update(&handle, (uint8_t*)hash->msg, hash->used)) + != FSP_SUCCESS) { + WOLFSSL_MSG("Sha update operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } + else { + ret = Final(&handle, out, &sz); + if (ret != FSP_SUCCESS + #if defined(WOLFSSL_RENESAS_SCEPROTECT) + || sz != outSz + #endif + ) { + WOLFSSL_MSG("Sha operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; } } wc_fspsm_hw_unlock(); @@ -571,7 +594,7 @@ static int FSPSM_HashGet(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) if(FSPSM_HashCopy(hash, &hashCopy) != 0) { WOLFSSL_MSG("ShaCopy operation failed"); WOLFSSL_ERROR(WC_HW_E); - ret = WC_HW_E; + return WC_HW_E; } wc_fspsm_hw_lock(); ret = Final(&hashCopy.handle, out, (uint32_t*)&sz); diff --git a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c index 308cdd5a427..5034e6b7159 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c +++ b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c @@ -64,7 +64,7 @@ static int wc_CAAM_DevEccSign(const byte* in, int inlen, byte* out, word32* outlen, WC_RNG *rng, ecc_key *key) { const ecc_set_type* dp; - int ret, keySz; + int ret, keySz, isBlack; byte r[MAX_ECC_BYTES] = {0}; byte s[MAX_ECC_BYTES] = {0}; @@ -91,8 +91,13 @@ static int wc_CAAM_DevEccSign(const byte* in, int inlen, byte* out, return MP_TO_E; } - ret = wc_DevCryptoEccSign(dp->id, key->blackKey, pk, keySz, in, inlen, - r, keySz, s, keySz); + /* blackKey holds a sentinel describing the black key encoding, anything + * outside of that range is an address or not a black key */ + isBlack = (key->blackKey >= CAAM_BLACK_KEY_SM && + key->blackKey <= CAAM_BLACK_KEY_ECB); + + ret = wc_DevCryptoEccSign(dp->id, isBlack, pk, keySz, in, + inlen, r, keySz, s, keySz); /* convert signature from raw bytes to signature format */ if (ret == 0) { @@ -173,7 +178,7 @@ static int wc_CAAM_DevEcdh(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outlen) { const ecc_set_type* dp; - int ret, keySz; + int ret, keySz, isBlack; byte pk[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0}; byte qx[MAX_ECC_BYTES] = {0}; @@ -208,8 +213,13 @@ static int wc_CAAM_DevEcdh(ecc_key* private_key, ecc_key* public_key, byte* out, return MP_TO_E; } - ret = wc_DevCryptoEccEcdh(dp->id, private_key->blackKey, pk, keySz, - qxy, qxSz + qySz, out, *outlen); + /* blackKey holds a sentinel describing the black key encoding, anything + * outside of that range is an address or not a black key */ + isBlack = (private_key->blackKey >= CAAM_BLACK_KEY_SM && + private_key->blackKey <= CAAM_BLACK_KEY_ECB); + + ret = wc_DevCryptoEccEcdh(dp->id, isBlack, pk, keySz, qxy, qxSz + qySz, + out, *outlen); if (ret == 0) { *outlen = keySz; } @@ -361,7 +371,8 @@ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, buf[idx].Length = keySz; } buf[idx].TheAddress = (CAAM_ADDRESS)pk; - args[0] = key->blackKey; /* potential black key, not in sm */ + /* this value will always be word32 or less no risk in cast */ + args[0] = (word32)key->blackKey; /* potential black key, not in sm */ } idx++; @@ -638,7 +649,8 @@ int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out, } buf[idx].TheAddress = (CAAM_ADDRESS)pk; - args[0] = private_key->blackKey; /* potential black key, but not sm */ + args[0] = (word32)private_key->blackKey; /* potential black key, + but not sm */ } #if 0 @@ -725,7 +737,7 @@ int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId, } else { /* type of black key was already set in the ecc key struct */ - args[0] = key->blackKey; + args[0] = (word32)key->blackKey; } args[1] = ecdsel; diff --git a/wolfcrypt/src/port/caam/wolfcaam_init.c b/wolfcrypt/src/port/caam/wolfcaam_init.c index 16f05bc2b25..068ddd8efea 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_init.c +++ b/wolfcrypt/src/port/caam/wolfcaam_init.c @@ -806,7 +806,8 @@ int caamWriteToPartition(CAAM_ADDRESS addr, const unsigned char* in, int inSz) buf[0].TheAddress = (CAAM_ADDRESS)in; buf[0].Length = inSz; - arg[0] = addr; + /* this value will always be word32 or less no risk in cast */ + arg[0] = (word32)addr; arg[1] = inSz; if ((wc_caamAddAndWait(buf, 1, arg, CAAM_WRITE_PART)) != 0) { @@ -829,7 +830,7 @@ int caamReadPartition(CAAM_ADDRESS addr, unsigned char* out, int outSz) buf[0].TheAddress = (CAAM_ADDRESS)out; buf[0].Length = outSz; - arg[0] = addr; + arg[0] = (word32)addr; arg[1] = outSz; if ((wc_caamAddAndWait(buf, 1, arg, CAAM_READ_PART)) != 0) { diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c index d7972e9f179..fe53360d584 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c @@ -128,8 +128,10 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) aes->left = 0; #endif - aes->ctx.cfd = -1; + /* release any session already held so re-keying does not orphan it */ + wc_DevCryptoFree(&aes->ctx); aes->ctx.inited = 0; + aes->ctx.cfd = -1; /* not set when no session was open */ XMEMCPY(aes->devKey, userKey, keylen); (void)dir; diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index 4c573a2a6ed..ba8513eecfc 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -157,17 +157,23 @@ int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) int wc_Sha256Final(wc_Sha256* sha, byte* hash) { int ret; + void* heap; if (sha == NULL || hash == NULL) { return BAD_FUNC_ARG; } + /* Cache the heap hint so the re-init below does not read it back out of a + * struct that wc_Sha256Free() has already torn down. */ + heap = sha->heap; + /* help static analysis tools out */ XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); #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); + (void)wc_InitSha256_ex(sha, heap, 0); return ret; } XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -176,11 +182,12 @@ int wc_Sha256Final(wc_Sha256* sha, byte* hash) ret = GetDigest(sha, CRYPTO_SHA2_256, hash); if (ret != 0) { wc_Sha256Free(sha); + (void)wc_InitSha256_ex(sha, heap, 0); return ret; } wc_Sha256Free(sha); - return wc_InitSha256_ex(sha, sha->heap, 0); + return wc_InitSha256_ex(sha, heap, 0); } @@ -193,7 +200,8 @@ int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP { int ret; - wc_Sha256 cpy = {0}; + wc_Sha256 cpy; + XMEMSET(&cpy, 0, sizeof(cpy)); ret = wc_Sha256Copy(sha, &cpy); if (ret == 0 && (ret = HashUpdate(&cpy, @@ -240,6 +248,9 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) return ret; #else + /* dst is left untouched: nothing is copied or re-initialized here, so + * tearing it down would destroy a live caller object on a path that only + * reports "not supported". */ (void)ret; WOLFSSL_MSG("Compile with WOLFSSL_DEVCRYPTO_HASH_KEEP for this feature"); diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c b/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c index d33704bd258..e138b60ecfc 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c @@ -50,8 +50,9 @@ int wc_DevCrypto_HmacSetKey(Hmac* hmac, int t, const byte* key, word32 keySz) { int hType; - hmac->ctx.inited = 0; - hmac->ctx.cfd = -1; + /* Re-keying releases any session already held, so it is not orphaned by + * the wc_DevCryptoCreate() below. */ + wc_DevCryptoFree(&hmac->ctx); hType = InternalTypeToDevcrypto(t); if (hType < 0) { return hType; diff --git a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c index f939311e2c2..e13f8af1521 100644 --- a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c +++ b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -77,9 +77,15 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) return BAD_FUNC_ARG; } + /* Note: ctx is an out parameter and may be uninitialized stack memory, so + * it must not be inspected here. Callers that reuse a long lived ctx are + * responsible for calling wc_DevCryptoFree() before re-creating it. */ + /* sanity check on session type before creating descriptor */ XMEMSET(ctx, 0, sizeof(WC_CRYPTODEV)); + ctx->cfd = -1; + /* clone the master fd */ if (ioctl(fd, CRIOGET, &ctx->cfd) != 0) { WOLFSSL_MSG("Error cloning fd"); diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 6fe31884193..1ae63014882 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -385,130 +385,60 @@ static int sha256DrbgDisabled = 0; static int sha512DrbgDisabled = 0; #endif /* WOLFSSL_DRBG_SHA512 */ -enum { - WC_DRBG_MUTEX_UNINITED, - WC_DRBG_MUTEX_INITPROGRESS, - WC_DRBG_MUTEX_FREEPROGRESS, - WC_DRBG_MUTEX_INITED -}; #ifndef SINGLE_THREADED static wolfSSL_Mutex drbgStateMutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(drbgStateMutex); #ifndef WOLFSSL_MUTEX_INITIALIZER -#if defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_THREAD_YIELD) -static wolfSSL_Atomic_Int drbgStateMutex_inited = - WOLFSSL_ATOMIC_INITIALIZER(WC_DRBG_MUTEX_UNINITED); -#else +enum { + WC_DRBG_MUTEX_UNINITED, + WC_DRBG_MUTEX_INITED +}; +/* Ports with no static mutex initializer must create drbgStateMutex at run + * time, so its readiness is tracked here. + * + * wc_DrbgState_MutexInit and wc_DrbgState_MutexFree are called only from + * wolfCrypt_Init() and wolfCrypt_Cleanup(), inside the span serialized by the + * init-state machine, so this flag is not otherwise synchronized. */ static volatile int drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; #endif #endif -#endif /* !SINGLE_THREADED */ int wc_DrbgState_MutexInit(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER - #if defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_THREAD_YIELD) - /* 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 (;;) { - WC_ATOMIC_INT_ARG expected = WC_DRBG_MUTEX_UNINITED; - if (wolfSSL_Atomic_Int_CompareExchange(&drbgStateMutex_inited, - &expected, WC_DRBG_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_DRBG_MUTEX_UNINITED); - return ret; - } - /* Publish the fully initialized mutex. */ - (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, - WC_DRBG_MUTEX_INITED); - return 0; - } - /* Spin until drbgStateMutex is inited */ - if (expected == WC_DRBG_MUTEX_INITED) { - /* Mutex is fully initialized. */ - return 0; - } - - WOLFSSL_THREAD_YIELD(); - } - #else if (drbgStateMutex_inited == WC_DRBG_MUTEX_UNINITED) { int ret = wc_InitMutex(&drbgStateMutex); if (ret != 0) { + /* flag left unchanged because mutex was not inited */ return ret; } drbgStateMutex_inited = WC_DRBG_MUTEX_INITED; } - return 0; - #endif -#else - return 0; #endif -#else - return 0; #endif + return 0; } int wc_DrbgState_MutexFree(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER - #if defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_THREAD_YIELD) - /* 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 (;;) { - WC_ATOMIC_INT_ARG expected = WC_DRBG_MUTEX_INITED; - if (wolfSSL_Atomic_Int_CompareExchange(&drbgStateMutex_inited, - &expected, WC_DRBG_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_DRBG_MUTEX_INITED); - return ret; - } - /* Mark the mutex as no longer initialized. */ - (void)wolfSSL_Atomic_Int_Exchange(&drbgStateMutex_inited, - WC_DRBG_MUTEX_UNINITED); - return 0; - } - /* CAS failed; 'expected' holds the observed state. */ - if (expected == WC_DRBG_MUTEX_UNINITED) { - /* Already freed or never initialized; nothing to do. */ - return 0; - } - - WOLFSSL_THREAD_YIELD(); - } - #else if (drbgStateMutex_inited == WC_DRBG_MUTEX_INITED) { int ret = wc_FreeMutex(&drbgStateMutex); if (ret != 0) { + /* flag left unchanged because mutex was not freed */ return ret; } drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; } - return 0; - #endif -#else - return 0; + #endif -#else - return 0; #endif + return 0; } static int LockDrbgState(void) @@ -3877,7 +3807,7 @@ static WC_INLINE int IntelRDseed64_r(word64* rnd) /* return 0 on success */ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) { - int ret; + int ret = 0; word64 rndTmp; static int rdseed_sanity_status = 0; @@ -3921,18 +3851,23 @@ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) else if (rdseed_sanity_status < 0) { return -1; } - - for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), + { + word64 rndTmpLocal = 0; + for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), output += sizeof(word64)) { - word64 rndTmpLocal; - ret = IntelRDseed64_r(&rndTmpLocal); + ret = IntelRDseed64_r(&rndTmpLocal); + if (ret != 0) { + break; + } + writeUnalignedWord64(output, rndTmpLocal); + } + + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); if (ret != 0) { - ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); return ret; } - writeUnalignedWord64(output, rndTmpLocal); - ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); } + if (sz == 0) return 0; @@ -4002,24 +3937,28 @@ static WC_INLINE int IntelRDrand64_r(word64 *rnd) /* return 0 on success */ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) { - int ret; word64 rndTmp; + int ret = 0; (void)os; if (!IS_INTEL_RDRAND(intel_flags)) return -1; - for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), + { + word64 rndTmpLocal = 0; + for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), output += sizeof(word64)) { - word64 rndTmpLocal; - ret = IntelRDrand64_r(&rndTmpLocal); + ret = IntelRDrand64_r(&rndTmpLocal); + if (ret != 0) { + break; + } + writeUnalignedWord64(output, rndTmpLocal); + } + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); if (ret != 0) { - ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); return ret; } - writeUnalignedWord64(output, rndTmpLocal); - ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); } if (sz == 0) return 0; diff --git a/wolfcrypt/src/siphash.c b/wolfcrypt/src/siphash.c index b8159c2957c..eecdaf2a378 100644 --- a/wolfcrypt/src/siphash.c +++ b/wolfcrypt/src/siphash.c @@ -80,7 +80,7 @@ * @param [in] a Little-endian byte array. * @return 16-bit number. */ -#define GET_U16(a) (*(const word16*)(a)) +#define GET_U16(a) readUnalignedWord16(a) /** * Encode 64-bit number to a little-endian byte array. * diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c index b939cfe22d1..4e238cc3a97 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -5104,23 +5104,21 @@ static int mlkem_get_noise_k4_avx512(MLKEM_PRF_T* prf, sword16* vec1, * 17: e2 <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) * ... * - * @param [out] rand Random number byte array. + * @param [out] rand Random number word64 array. Used as the SHAKE-256 + * state - the random is squeezed into it in place. * @param [in] seed Seed to generate random from. * @param [in] o Offset of seed count. */ -static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) +static void mlkem_get_noise_x3_eta2_aarch64(word64 rand[3 * 25], byte* seed, + byte o) { - word64 state[3 * 25] = {0}; - - state[0*25 + 4] = 0x1f00 + 0 + o; - state[1*25 + 4] = 0x1f00 + 1 + o; - state[2*25 + 4] = 0x1f00 + 2 + o; + /* Only rand[i*25 + 4] is set here - the rest of the state is zeroed in + * registers by the assembly. */ + rand[0*25 + 4] = 0x1f00 + 0 + o; + rand[1*25 + 4] = 0x1f00 + 1 + o; + rand[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); - ForceZero(state, sizeof(state)); + mlkem_shake256_blocksx3_seed_neon(rand, seed); } #if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) @@ -5143,7 +5141,9 @@ static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) */ static void mlkem_get_noise_x3_eta3_aarch64(byte* rand, byte* seed, byte o) { - word64 state[3 * 25] = {0}; + /* Only state[i*25 + 4] is read by the assembly - the rest of the state is + * zeroed in registers there. */ + word64 state[3 * 25]; state[0*25 + 4] = 0x1f00 + 0 + o; state[1*25 + 4] = 0x1f00 + 1 + o; @@ -5185,6 +5185,8 @@ static void mlkem_get_noise_x3_eta3_aarch64(byte* rand, byte* seed, byte o) */ static void mlkem_get_noise_eta3_aarch64(byte* rand, byte* seed, byte o) { + /* ETA3_RAND_SIZE is larger than the SHAKE-256 rate - two squeezes are + * needed, so the state cannot be squeezed in place over the output. */ word64 state[25]; readUnalignedWords64(state, seed, 4); @@ -5219,21 +5221,21 @@ static int mlkem_get_noise_k2_aarch64(sword16* vec1, sword16* vec2, sword16* poly, byte* seed) { int ret = 0; - byte rand[3 * 25 * 8]; + word64 rand[3 * 25]; - mlkem_get_noise_x3_eta3_aarch64(rand, seed, 0); - mlkem_cbd_eta3(vec1 , rand + 0 * ETA3_RAND_SIZE); - mlkem_cbd_eta3(vec1 + MLKEM_N, rand + 1 * ETA3_RAND_SIZE); + mlkem_get_noise_x3_eta3_aarch64((byte*)rand, seed, 0); + mlkem_cbd_eta3(vec1 , (byte*)rand + 0 * ETA3_RAND_SIZE); + mlkem_cbd_eta3(vec1 + MLKEM_N, (byte*)rand + 1 * ETA3_RAND_SIZE); if (poly == NULL) { - mlkem_cbd_eta3(vec2 , rand + 2 * ETA3_RAND_SIZE); - mlkem_get_noise_eta3_aarch64(rand, seed, 3); - mlkem_cbd_eta3(vec2 + MLKEM_N, rand ); + mlkem_cbd_eta3(vec2 , (byte*)rand + 2 * ETA3_RAND_SIZE); + mlkem_get_noise_eta3_aarch64((byte*)rand, seed, 3); + mlkem_cbd_eta3(vec2 + MLKEM_N, (byte*)rand ); } else { mlkem_get_noise_x3_eta2_aarch64(rand, seed, 2); - mlkem_cbd_eta2(vec2 , rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec2 + MLKEM_N, rand + 1 * 25 * 8); - mlkem_cbd_eta2(poly , rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec2 , (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + MLKEM_N, (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(poly , (byte*)rand + 2 * 25 * 8); } /* rand holds secret noise. */ @@ -5258,22 +5260,18 @@ static int mlkem_get_noise_k2_aarch64(sword16* vec1, sword16* vec2, * 17: e2 <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) * ... * - * @param [out] rand Random number byte array. + * @param [out] rand Random number word64 array. * @param [in] seed Seed to generate random from. * @param [in] o Offset of seed count. */ -static void mlkem_get_noise_eta2_aarch64(byte* rand, byte* seed, byte o) +static void mlkem_get_noise_eta2_aarch64(word64 rand[25], byte* seed, byte o) { - word64 state[25]; - - readUnalignedWords64(state, seed, 4); + readUnalignedWords64(rand, 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); - ForceZero(state, sizeof(state)); + rand[4] = 0x1f00 + o; + XMEMSET(rand + 5, 0, sizeof(*rand) * (25 - 5)); + rand[16] = W64LIT(0x8000000000000000); + BlockSha3(rand); } /* Get the noise/error by calculating random bytes and sampling to a binomial @@ -5288,19 +5286,19 @@ static void mlkem_get_noise_eta2_aarch64(byte* rand, byte* seed, byte o) static int mlkem_get_noise_k3_aarch64(sword16* vec1, sword16* vec2, sword16* poly, byte* seed) { - byte rand[3 * 25 * 8]; + word64 rand[3 * 25]; mlkem_get_noise_x3_eta2_aarch64(rand, seed, 0); - mlkem_cbd_eta2(vec1 , rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, rand + 1 * 25 * 8); - mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec1 , (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, (byte*)rand + 2 * 25 * 8); mlkem_get_noise_x3_eta2_aarch64(rand, seed, 3); - mlkem_cbd_eta2(vec2 , rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, rand + 1 * 25 * 8); - mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec2 , (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, (byte*)rand + 2 * 25 * 8); if (poly != NULL) { mlkem_get_noise_eta2_aarch64(rand, seed, 6); - mlkem_cbd_eta2(poly , rand + 0 * 25 * 8); + mlkem_cbd_eta2(poly , (byte*)rand + 0 * 25 * 8); } /* rand holds secret noise. */ @@ -5329,21 +5327,21 @@ static int mlkem_get_noise_k4_aarch64(sword16* vec1, sword16* vec2, sword16* poly, byte* seed) { int ret = 0; - byte rand[3 * 25 * 8]; + word64 rand[3 * 25]; mlkem_get_noise_x3_eta2_aarch64(rand, seed, 0); - mlkem_cbd_eta2(vec1 , rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, rand + 1 * 25 * 8); - mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec1 , (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, (byte*)rand + 2 * 25 * 8); mlkem_get_noise_x3_eta2_aarch64(rand, seed, 3); - mlkem_cbd_eta2(vec1 + 3 * MLKEM_N, rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec2 , rand + 1 * 25 * 8); - mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec1 + 3 * MLKEM_N, (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 , (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, (byte*)rand + 2 * 25 * 8); mlkem_get_noise_x3_eta2_aarch64(rand, seed, 6); - mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec2 + 3 * MLKEM_N, rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + 3 * MLKEM_N, (byte*)rand + 1 * 25 * 8); if (poly != NULL) { - mlkem_cbd_eta2(poly, rand + 2 * 25 * 8); + mlkem_cbd_eta2(poly, (byte*)rand + 2 * 25 * 8); } /* rand holds secret noise. */ diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 86018af96e5..00f727a644f 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -209,8 +209,8 @@ endif endif if BUILD_CAAM -nobase_include_HEADERS+= wolfssl/wolfcrypt/port/caam/caam_type.h \ - wolfssl/wolfcrypt/port/caam/wolfcaam.h \ +nobase_include_HEADERS+= wolfssl/wolfcrypt/port/caam/wolfcaam.h \ + wolfssl/wolfcrypt/port/caam/caam_type.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_hash.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_rsa.h \ diff --git a/wolfssl/wolfcrypt/port/caam/caam_type.h b/wolfssl/wolfcrypt/port/caam/caam_type.h index 5b07d266fce..a75dbf36e35 100644 --- a/wolfssl/wolfcrypt/port/caam/caam_type.h +++ b/wolfssl/wolfcrypt/port/caam/caam_type.h @@ -35,14 +35,9 @@ #ifndef WOLF_CRYPT_CAAM_TYPE_H #define WOLF_CRYPT_CAAM_TYPE_H +/* unguarded intentionaly as targets should have libc */ #include -#ifndef CAAM_ADDRESS - #ifdef WOLFSSL_SECO_CAAM - #define CAAM_ADDRESS intptr_t - #else - #define CAAM_ADDRESS uintptr_t - #endif -#endif +#define CAAM_ADDRESS uintptr_t #endif /* WOLF_CRYPT_CAAM_TYPE_H */ diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h index c3387d76f7f..1b15fc230b2 100644 --- a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -38,7 +38,10 @@ typedef struct WC_CRYPTODEV { int cfd; - unsigned int inited : 1;/* is this object initialized (1) or not (0) */ + /* Placed here rather than appended so the bit-field lands in the padding + * after cfd - on LP64 this keeps sizeof and the offset of sess + * unchanged on LP32 the size of the struct grows. */ + unsigned int inited : 1; /* is this object initialized (1) or not (0) */ struct session_op sess; } WC_CRYPTODEV; diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index e0d86c1b3ab..ccbc146bfb6 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -773,31 +773,6 @@ } #endif -/* Yield the CPU to another runnable thread. Used by spin-wait loops that are - * waiting on another thread to finish a short critical section. Ports may - * override. */ -#ifndef WOLFSSL_THREAD_YIELD - #if defined(SINGLE_THREADED) - #define WOLFSSL_THREAD_YIELD() WC_DO_NOTHING - #elif defined(WOLFSSL_PTHREADS) - #include - #define WOLFSSL_THREAD_YIELD() (void)sched_yield() - #elif defined(USE_WINDOWS_API) && !defined(WOLFSSL_NOT_WINDOWS_API) - #include - #define WOLFSSL_THREAD_YIELD() (void)SwitchToThread() - #elif defined(FREERTOS) - #define WOLFSSL_THREAD_YIELD() taskYIELD() - #elif defined(THREADX) - #define WOLFSSL_THREAD_YIELD() tx_thread_relinquish() - #elif defined(WOLFSSL_ZEPHYR) && KERNEL_VERSION_NUMBER >= 0x30100 - #define WOLFSSL_THREAD_YIELD() k_yield() - #elif defined(WOLFSSL_VXWORKS) - #include - #include - #define WOLFSSL_THREAD_YIELD() (void)taskDelay(0) - #endif -#endif - /* Reference counting. */ typedef struct wolfSSL_RefWithMutex { #if !defined(SINGLE_THREADED) @@ -1112,7 +1087,25 @@ WOLFSSL_LOCAL int wc_local_InitDown(wc_init_state_t *s); /* wc_local_InitDownDone() closes the critical span of a cleanup sequence. */ WOLFSSL_LOCAL int wc_local_InitDownDone(wc_init_state_t *s); -/* main crypto initialization function */ +/* main crypto initialization function + * + * THREADING: wolfCrypt_Init() and wolfCrypt_Cleanup() serialize against each + * other through the atomic init-state machine above (wc_local_InitUp() et al), + * so a thread arriving while another is still running the init or cleanup body + * spins until that body completes. This holds only in builds with working + * atomics. With WOLFSSL_NO_ATOMICS (or any non-SINGLE_THREADED build where + * WOLFSSL_ATOMIC_OPS ends up undefined), the atomic primitives degrade to + * plain non-atomic fallbacks with thread-unsafe semantics, and the state + * machine can no longer serialize anything: two threads racing the first + * wolfCrypt_Init() can then both run the init body and double-create internal + * resources, such as mutexes on ports where WOLFSSL_MUTEX_INITIALIZER is not + * defined and mutexes must be created at run time. + * + * Regardless of build, the recommended calling convention is to call + * wolfCrypt_Init() once during startup before starting the threads that use + * the library, and wolfCrypt_Cleanup() once during shutdown after those + * threads have been joined. + */ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Init(void); WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); From 56727654fd2893fbe1e9b298240aa146ba29ffc5 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Wed, 5 Aug 2026 10:44:02 -0600 Subject: [PATCH 11/12] reverted caam 'fix' becuase I found out it was a false positive CAAM_ADDRESS is never going to be greater than 32 bit and usually much smaller --- IDE/QNX/example-server/server-tls.c | 6 +-- doc/dox_comments/header_files/wc_port.h | 15 ------- tests/api/test_aes.c | 2 + wolfcrypt/src/aes.c | 1 + wolfcrypt/src/ecc.c | 6 +-- .../src/port/Renesas/renesas_fspsm_sha.c | 11 ++--- wolfcrypt/src/port/caam/wolfcaam_ecdsa.c | 32 +++++--------- wolfcrypt/src/port/caam/wolfcaam_init.c | 5 +-- wolfcrypt/src/random.c | 14 +++--- wolfssl/wolfcrypt/ecc.h | 9 +--- wolfssl/wolfcrypt/include.am | 1 - wolfssl/wolfcrypt/port/caam/caam_qnx.h | 3 +- wolfssl/wolfcrypt/port/caam/caam_type.h | 43 ------------------- wolfssl/wolfcrypt/port/caam/wolfcaam.h | 1 - .../wolfcrypt/port/caam/wolfcaam_fsl_nxp.h | 2 +- wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h | 2 +- wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h | 3 +- wolfssl/wolfcrypt/settings.h | 2 - wolfssl/wolfcrypt/wc_port.h | 20 +-------- 19 files changed, 41 insertions(+), 137 deletions(-) delete mode 100644 wolfssl/wolfcrypt/port/caam/caam_type.h diff --git a/IDE/QNX/example-server/server-tls.c b/IDE/QNX/example-server/server-tls.c index 50561c2b2fb..2f41b0d3891 100644 --- a/IDE/QNX/example-server/server-tls.c +++ b/IDE/QNX/example-server/server-tls.c @@ -169,10 +169,8 @@ int cover(ecc_key* keyOut, const byte* der, word32 derSz) wc_ecc_free(keyOut); goto done; } - /* blackKey is CAAM_ADDRESS (uintptr_t), so cast up to a width that holds it - * on both armv7le and aarch64le rather than relying on int-sized varargs */ - printf("blackKeySz = %u, virtual secure address ecc_key.blackKey " - "= 0x%08lX\n", blackKeySz, (unsigned long)keyOut->blackKey); + printf("blackKeySz = %d, virtual secure address ecc_key.blackKey = 0x%08X\n", + blackKeySz, keyOut->blackKey); ret = 0; done: diff --git a/doc/dox_comments/header_files/wc_port.h b/doc/dox_comments/header_files/wc_port.h index b90f6a76689..74db950f9a3 100644 --- a/doc/dox_comments/header_files/wc_port.h +++ b/doc/dox_comments/header_files/wc_port.h @@ -3,16 +3,6 @@ \brief Used to initialize resources used by wolfCrypt. - \note Concurrent calls are serialized by an internal atomic init-state - machine, so only the first caller runs the initialization body. That - protection depends on working atomics: in builds with WOLFSSL_NO_ATOMICS - (or any non-SINGLE_THREADED build where WOLFSSL_ATOMIC_OPS ends up - undefined), the atomic primitives fall back to thread-unsafe non-atomic - operations and two threads racing the first wolfCrypt_Init() can both run - the init body, double-creating internal resources. The recommended calling - convention in every build is to call wolfCrypt_Init() once during startup, - before starting any thread that uses wolfSSL or wolfCrypt. - \return 0 upon success. \return <0 upon failure of init resources. @@ -35,11 +25,6 @@ int wolfCrypt_Init(void); \brief Used to clean up resources used by wolfCrypt. - \note Concurrent calls are serialized by the same atomic init-state machine - used by wolfCrypt_Init(), with the same dependence on working atomics. Call - wolfCrypt_Cleanup() once during shutdown, after every thread that uses - wolfSSL or wolfCrypt has been joined. See the note on wolfCrypt_Init(). - \return 0 upon success. \return <0 upon failure of cleaning up resources. diff --git a/tests/api/test_aes.c b/tests/api/test_aes.c index 874f6585172..6a830639746 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -93,6 +93,8 @@ static int test_wc_AesSetKey_BadArgs(Aes* aes, byte* key, word32 keyLen, WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_AesSetKey(aes , key , 48 , iv, AES_ENCRYPTION), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_AesSetKey(aes , NULL , 48 , iv, AES_ENCRYPTION), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); return EXPECT_RESULT(); } diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 4c010fbf28b..0ef7264bd76 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -15793,6 +15793,7 @@ int wc_AesInit(Aes* aes, void* heap, int devId) #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/ecc.c b/wolfcrypt/src/ecc.c index ca2e9bca158..ec0b5d5c460 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -10513,7 +10513,7 @@ static int _ecc_export_x963(ecc_key* key, byte* out, word32* outLen) /* store byte point type */ out[0] = ECC_POINT_UNCOMP; - if (caamReadPartition(key->securePubKey, out+1, keySz*2) != 0) + if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0) return WC_HW_E; *outLen = 1 + 2*keySz; @@ -12136,7 +12136,7 @@ static int _ecc_import_private_key_ex(const byte* priv, word32 privSz, } key->partNum = part; - key->blackKey = vaddr; + key->blackKey = (word32)vaddr; if (caamWriteToPartition(vaddr, priv, privSz) != 0) return WC_HW_E; @@ -12144,7 +12144,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 = vaddr + privSz; + key->securePubKey = (word32)vaddr + privSz; } } else { diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c index e61b149bb50..29a63c070b0 100644 --- a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c +++ b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c @@ -228,7 +228,7 @@ static int FSPSM_HashCopy(wolfssl_FSPSM_Hash* src, wolfssl_FSPSM_Hash* dst) * hash The FSPSM Hash object. * heap Buffer to hold heap if available * devId device Id - * return 0 on success, BAD_FUNC_ARG when has is NULL + * return 0 on success, BAD_FUNC_ARG when has is NULL or WC_HW_E on hw failure */ static int FSPSM_HashInit(wolfssl_FSPSM_Hash* hash, void* heap, int devId, word32 sha_type) @@ -298,7 +298,7 @@ static int FSPSM_HashInit(wolfssl_FSPSM_Hash* hash, void* heap, int devId, * hash The FSPSM Hash object. * data Buffer to hold plain text for hash * sz Length of data - * return 0 on success, otherwise MEMORY_E or BAD_FUNC_ARG on failure + * return 0 on success, otherwise MEMORY_E, BAD_FUNC_ARG or WC_HW_E on failure */ static int FSPSM_HashUpdate(wolfssl_FSPSM_Hash* hash, const byte* data, word32 sz) @@ -392,7 +392,7 @@ static int FSPSM_HashUpdate(wolfssl_FSPSM_Hash* hash, * out Buffer to hold hashed text * outSz Length of out * return FSP_SUCCESS(0) on success, - * otherwise BAD_FUNC_ARG or FSP Error code on failure + * otherwise BAD_FUNC_ARG or WC_HW_E on failure */ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) { @@ -494,11 +494,12 @@ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) heap = hash->heap; FSPSM_HashFree(hash); - FSPSM_HashInit(hash, heap, 0, hash->sha_type); + ret = FSPSM_HashInit(hash, heap, 0, hash->sha_type); return ret; } -/* Hash operation to message and return a result */ +/* Hash operation to message and return a result or BAD_FUNC_ARG/WC_HW_E + * on error */ static int FSPSM_HashGet(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) { int ret = FSP_SUCCESS; diff --git a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c index 5034e6b7159..57b3da424b6 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c +++ b/wolfcrypt/src/port/caam/wolfcaam_ecdsa.c @@ -64,7 +64,7 @@ static int wc_CAAM_DevEccSign(const byte* in, int inlen, byte* out, word32* outlen, WC_RNG *rng, ecc_key *key) { const ecc_set_type* dp; - int ret, keySz, isBlack; + int ret, keySz; byte r[MAX_ECC_BYTES] = {0}; byte s[MAX_ECC_BYTES] = {0}; @@ -91,13 +91,8 @@ static int wc_CAAM_DevEccSign(const byte* in, int inlen, byte* out, return MP_TO_E; } - /* blackKey holds a sentinel describing the black key encoding, anything - * outside of that range is an address or not a black key */ - isBlack = (key->blackKey >= CAAM_BLACK_KEY_SM && - key->blackKey <= CAAM_BLACK_KEY_ECB); - - ret = wc_DevCryptoEccSign(dp->id, isBlack, pk, keySz, in, - inlen, r, keySz, s, keySz); + ret = wc_DevCryptoEccSign(dp->id, key->blackKey, pk, keySz, in, inlen, + r, keySz, s, keySz); /* convert signature from raw bytes to signature format */ if (ret == 0) { @@ -178,7 +173,7 @@ static int wc_CAAM_DevEcdh(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outlen) { const ecc_set_type* dp; - int ret, keySz, isBlack; + int ret, keySz; byte pk[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0}; byte qx[MAX_ECC_BYTES] = {0}; @@ -213,13 +208,8 @@ static int wc_CAAM_DevEcdh(ecc_key* private_key, ecc_key* public_key, byte* out, return MP_TO_E; } - /* blackKey holds a sentinel describing the black key encoding, anything - * outside of that range is an address or not a black key */ - isBlack = (private_key->blackKey >= CAAM_BLACK_KEY_SM && - private_key->blackKey <= CAAM_BLACK_KEY_ECB); - - ret = wc_DevCryptoEccEcdh(dp->id, isBlack, pk, keySz, qxy, qxSz + qySz, - out, *outlen); + ret = wc_DevCryptoEccEcdh(dp->id, private_key->blackKey, pk, keySz, + qxy, qxSz + qySz, out, *outlen); if (ret == 0) { *outlen = keySz; } @@ -349,7 +339,7 @@ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, /* private key */ if (key->blackKey == CAAM_BLACK_KEY_SM) { - buf[idx].TheAddress = key->blackKey; + buf[idx].TheAddress = (CAAM_ADDRESS)key->blackKey; args[0] = CAAM_BLACK_KEY_SM; /* is a black key in sm */ buf[idx].Length = keySz; } @@ -371,8 +361,7 @@ int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen, buf[idx].Length = keySz; } buf[idx].TheAddress = (CAAM_ADDRESS)pk; - /* this value will always be word32 or less no risk in cast */ - args[0] = (word32)key->blackKey; /* potential black key, not in sm */ + args[0] = key->blackKey; /* potential black key, not in sm */ } idx++; @@ -649,8 +638,7 @@ int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out, } buf[idx].TheAddress = (CAAM_ADDRESS)pk; - args[0] = (word32)private_key->blackKey; /* potential black key, - but not sm */ + args[0] = private_key->blackKey; /* potential black key, but not sm */ } #if 0 @@ -737,7 +725,7 @@ int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId, } else { /* type of black key was already set in the ecc key struct */ - args[0] = (word32)key->blackKey; + args[0] = key->blackKey; } args[1] = ecdsel; diff --git a/wolfcrypt/src/port/caam/wolfcaam_init.c b/wolfcrypt/src/port/caam/wolfcaam_init.c index 068ddd8efea..16f05bc2b25 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_init.c +++ b/wolfcrypt/src/port/caam/wolfcaam_init.c @@ -806,8 +806,7 @@ int caamWriteToPartition(CAAM_ADDRESS addr, const unsigned char* in, int inSz) buf[0].TheAddress = (CAAM_ADDRESS)in; buf[0].Length = inSz; - /* this value will always be word32 or less no risk in cast */ - arg[0] = (word32)addr; + arg[0] = addr; arg[1] = inSz; if ((wc_caamAddAndWait(buf, 1, arg, CAAM_WRITE_PART)) != 0) { @@ -830,7 +829,7 @@ int caamReadPartition(CAAM_ADDRESS addr, unsigned char* out, int outSz) buf[0].TheAddress = (CAAM_ADDRESS)out; buf[0].Length = outSz; - arg[0] = (word32)addr; + arg[0] = addr; arg[1] = outSz; if ((wc_caamAddAndWait(buf, 1, arg, CAAM_READ_PART)) != 0) { diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 1ae63014882..34da1120bfa 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -400,9 +400,9 @@ enum { * wc_DrbgState_MutexInit and wc_DrbgState_MutexFree are called only from * wolfCrypt_Init() and wolfCrypt_Cleanup(), inside the span serialized by the * init-state machine, so this flag is not otherwise synchronized. */ -static volatile int drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; -#endif -#endif +static int drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; +#endif /* !defined(WOLFSSL_MUTEX_INITIALIZER) */ +#endif /* !defined(SINGLE_THREADED) */ int wc_DrbgState_MutexInit(void) @@ -418,8 +418,8 @@ int wc_DrbgState_MutexInit(void) drbgStateMutex_inited = WC_DRBG_MUTEX_INITED; } -#endif -#endif +#endif /* !defined(WOLFSSL_MUTEX_INITIALIZER) */ +#endif /* !defined(SINGLE_THREADED) */ return 0; } @@ -436,8 +436,8 @@ int wc_DrbgState_MutexFree(void) drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; } -#endif -#endif +#endif /* !defined(WOLFSSL_MUTEX_INITIALIZER) */ +#endif /* !defined(SINGLE_THREADED) */ return 0; } diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 97c0e0859f6..d020523c09f 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -67,11 +67,6 @@ #include #endif -#ifdef WOLFSSL_CAAM - /* for CAAM_ADDRESS, used by struct ecc_key below */ - #include -#endif - #if defined(WOLFSSL_XILINX_CRYPT_VERSAL) #include #endif @@ -533,8 +528,8 @@ struct ecc_key { #endif #ifdef WOLFSSL_CAAM - CAAM_ADDRESS blackKey; /* address of key encrypted and in secure memory */ - CAAM_ADDRESS securePubKey; /* address of public key in secure memory */ + word32 blackKey; /* address of key encrypted and in secure memory */ + word32 securePubKey; /* address of public key in secure memory */ int partNum; /* partition number*/ #endif #ifdef WOLFSSL_SE050 diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 00f727a644f..d10b3cb3dd4 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -210,7 +210,6 @@ endif if BUILD_CAAM nobase_include_HEADERS+= wolfssl/wolfcrypt/port/caam/wolfcaam.h \ - wolfssl/wolfcrypt/port/caam/caam_type.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_hash.h \ wolfssl/wolfcrypt/port/caam/wolfcaam_rsa.h \ diff --git a/wolfssl/wolfcrypt/port/caam/caam_qnx.h b/wolfssl/wolfcrypt/port/caam/caam_qnx.h index 74117569f2c..7e4f5676a1e 100644 --- a/wolfssl/wolfcrypt/port/caam/caam_qnx.h +++ b/wolfssl/wolfcrypt/port/caam/caam_qnx.h @@ -41,11 +41,10 @@ #define CAAM_LOCK_MUTEX(x) pthread_mutex_lock((x)) #define CAAM_UNLOCK_MUTEX(x) pthread_mutex_unlock((x)) -#include - #define Error int #define Value int #define Boolean int +#define CAAM_ADDRESS uintptr_t #define Success 1 #define Failure 0 #define INTERRUPT_Panic() do {} while (0) diff --git a/wolfssl/wolfcrypt/port/caam/caam_type.h b/wolfssl/wolfcrypt/port/caam/caam_type.h deleted file mode 100644 index a75dbf36e35..00000000000 --- a/wolfssl/wolfcrypt/port/caam/caam_type.h +++ /dev/null @@ -1,43 +0,0 @@ -/* caam_type.h - * - * Copyright (C) 2006-2026 wolfSSL Inc. - * - * This file is part of wolfSSL. - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA - */ - -/* Single definition of CAAM_ADDRESS, the type used to hold an address handed to - * or returned from the CAAM. - * - * struct ecc_key stores CAAM addresses, so its layout depends on this type. - * Keep the definition here, selected only from build configuration macros, so - * that every translation unit in a build agrees on it no matter which of the - * CAAM headers it happens to include, and in which order. - * - * This header intentionally has no wolfSSL dependencies; the standalone QNX - * driver build includes it without settings.h. Whatever includes it is expected - * to have already pulled in settings.h if it needs the configuration macros. - */ - -#ifndef WOLF_CRYPT_CAAM_TYPE_H -#define WOLF_CRYPT_CAAM_TYPE_H - -/* unguarded intentionaly as targets should have libc */ -#include - -#define CAAM_ADDRESS uintptr_t - -#endif /* WOLF_CRYPT_CAAM_TYPE_H */ diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam.h b/wolfssl/wolfcrypt/port/caam/wolfcaam.h index 4d7aa270aaf..d033054249b 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam.h @@ -24,7 +24,6 @@ #include #include -#include /* include for porting layer */ #ifdef WOLFSSL_QNX_CAAM diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h index 39a90e46a8f..032c0f22f29 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h @@ -50,7 +50,7 @@ #define NoActivityReady -1 #define MemoryOperationNotPerformed -1 -#include +#define CAAM_ADDRESS uintptr_t #ifndef WOLFSSL_CAAM_BUFFER #define WOLFSSL_CAAM_BUFFER typedef struct CAAM_BUFFER { diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h index b1f7b552097..910d17db12d 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_qnx.h @@ -41,7 +41,7 @@ #define NoActivityReady -1 #define MemoryOperationNotPerformed -1 -#include +#define CAAM_ADDRESS uintptr_t #ifndef WOLFSSL_CAAM_BUFFER #define WOLFSSL_CAAM_BUFFER typedef struct CAAM_BUFFER { diff --git a/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h b/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h index 19be34e8478..6d9004e9232 100644 --- a/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h +++ b/wolfssl/wolfcrypt/port/caam/wolfcaam_seco.h @@ -44,7 +44,8 @@ #define NoActivityReady -1 #define MemoryOperationNotPerformed -1 -#include +#include +#define CAAM_ADDRESS intptr_t #ifndef WOLFSSL_CAAM_BUFFER #define WOLFSSL_CAAM_BUFFER typedef struct CAAM_BUFFER { diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index c3eded1b936..696ece03230 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -3153,7 +3153,6 @@ #endif #ifdef WOLFSSL_SECO_CAAM - #undef WOLFSSL_CAAM #define WOLFSSL_CAAM #define WOLFSSL_HASH_KEEP @@ -3161,7 +3160,6 @@ #endif #ifdef WOLFSSL_IMXRT1170_CAAM - #undef WOLFSSL_CAAM #define WOLFSSL_CAAM #endif diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index ccbc146bfb6..3d3faf24ac6 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1087,25 +1087,7 @@ WOLFSSL_LOCAL int wc_local_InitDown(wc_init_state_t *s); /* wc_local_InitDownDone() closes the critical span of a cleanup sequence. */ WOLFSSL_LOCAL int wc_local_InitDownDone(wc_init_state_t *s); -/* main crypto initialization function - * - * THREADING: wolfCrypt_Init() and wolfCrypt_Cleanup() serialize against each - * other through the atomic init-state machine above (wc_local_InitUp() et al), - * so a thread arriving while another is still running the init or cleanup body - * spins until that body completes. This holds only in builds with working - * atomics. With WOLFSSL_NO_ATOMICS (or any non-SINGLE_THREADED build where - * WOLFSSL_ATOMIC_OPS ends up undefined), the atomic primitives degrade to - * plain non-atomic fallbacks with thread-unsafe semantics, and the state - * machine can no longer serialize anything: two threads racing the first - * wolfCrypt_Init() can then both run the init body and double-create internal - * resources, such as mutexes on ports where WOLFSSL_MUTEX_INITIALIZER is not - * defined and mutexes must be created at run time. - * - * Regardless of build, the recommended calling convention is to call - * wolfCrypt_Init() once during startup before starting the threads that use - * the library, and wolfCrypt_Cleanup() once during shutdown after those - * threads have been joined. - */ +/* main crypto initialization function */ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Init(void); WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); From 42bd8e29b4125a3a22386c5e627cb06e88355011 Mon Sep 17 00:00:00 2001 From: Aidan Keefe Date: Thu, 6 Aug 2026 11:24:21 -0600 Subject: [PATCH 12/12] review changes --- wolfcrypt/src/port/devcrypto/devcrypto_hash.c | 6 ++- wolfcrypt/src/port/devcrypto/wc_devcrypto.c | 16 ++++--- wolfcrypt/src/random.c | 47 +++++++++---------- wolfcrypt/src/wc_mlkem_poly.c | 5 +- .../wolfcrypt/port/devcrypto/wc_devcrypto.h | 5 +- 5 files changed, 40 insertions(+), 39 deletions(-) diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index ba8513eecfc..19e84b73504 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -235,8 +235,7 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) if ((ret = wc_InitSha256_ex(dst, src->heap, 0)) != 0) { return ret; } - dst->len = src->len; - dst->used = src->used; + if (src->len > 0) { dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); if (dst->msg == NULL) { @@ -246,6 +245,9 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) XMEMCPY(dst->msg, src->msg, src->len); } + dst->len = src->len; + dst->used = src->used; + return ret; #else /* dst is left untouched: nothing is copied or re-initialized here, so diff --git a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c index e13f8af1521..db047b9b957 100644 --- a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c +++ b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -89,13 +89,13 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) /* clone the master fd */ if (ioctl(fd, CRIOGET, &ctx->cfd) != 0) { WOLFSSL_MSG("Error cloning fd"); + ctx->cfd = -1; return WC_DEVCRYPTO_E; } if (fcntl(ctx->cfd, F_SETFD, 1) == -1) { WOLFSSL_MSG("Error setting F_SETFD with fcntl"); - (void)close(ctx->cfd); - return WC_DEVCRYPTO_E; + goto err_close; } /* set up session */ @@ -156,6 +156,7 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) default: WOLFSSL_MSG("Unknown / Unimplemented algorithm type"); (void)close(ctx->cfd); + ctx->cfd = -1; return BAD_FUNC_ARG; } @@ -164,17 +165,15 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) #if defined(DEBUG_DEVCRYPTO) perror("CIOGSESSION error "); #endif - (void)close(ctx->cfd); WOLFSSL_MSG("Error starting cryptodev session"); - return WC_DEVCRYPTO_E; + goto err_close; } #if defined(CIOCGSESSINFO) && defined(DEBUG_DEVCRYPTO) sesInfo.ses = ctx->sess.ses; if (ioctl(ctx->cfd, CIOCGSESSINFO, &sesInfo)) { - (void)close(ctx->cfd); WOLFSSL_MSG("Error getting session info"); - return WC_DEVCRYPTO_E; + goto err_close; } if (ctx->sess.cipher == 0) { printf("Using %s with driver %s\n", sesInfo.hash_info.cra_name, @@ -190,6 +189,11 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) (void)keySz; return 0; + +err_close: + (void)close(ctx->cfd); + ctx->cfd = -1; + return WC_DEVCRYPTO_E; } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 34da1120bfa..f1b86e5ba44 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -3810,6 +3810,7 @@ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) int ret = 0; word64 rndTmp; static int rdseed_sanity_status = 0; + word64 rndTmpLocal = 0; (void)os; @@ -3851,21 +3852,19 @@ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) else if (rdseed_sanity_status < 0) { return -1; } - { - word64 rndTmpLocal = 0; - for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), - output += sizeof(word64)) { - ret = IntelRDseed64_r(&rndTmpLocal); - if (ret != 0) { - break; - } - writeUnalignedWord64(output, rndTmpLocal); - } - ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); + for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), + output += sizeof(word64)) { + ret = IntelRDseed64_r(&rndTmpLocal); if (ret != 0) { - return ret; + break; } + writeUnalignedWord64(output, rndTmpLocal); + } + + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); + if (ret != 0) { + return ret; } if (sz == 0) @@ -3939,27 +3938,27 @@ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) { word64 rndTmp; int ret = 0; + word64 rndTmpLocal = 0; (void)os; if (!IS_INTEL_RDRAND(intel_flags)) return -1; - { - word64 rndTmpLocal = 0; - for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), - output += sizeof(word64)) { - ret = IntelRDrand64_r(&rndTmpLocal); - if (ret != 0) { - break; - } - writeUnalignedWord64(output, rndTmpLocal); - } - ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); + for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), + output += sizeof(word64)) { + ret = IntelRDrand64_r(&rndTmpLocal); if (ret != 0) { - return ret; + break; } + writeUnalignedWord64(output, rndTmpLocal); } + + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); + if (ret != 0) { + return ret; + } + if (sz == 0) return 0; diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c index 4e238cc3a97..e8d0e57b521 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -5109,8 +5109,7 @@ static int mlkem_get_noise_k4_avx512(MLKEM_PRF_T* prf, sword16* vec1, * @param [in] seed Seed to generate random from. * @param [in] o Offset of seed count. */ -static void mlkem_get_noise_x3_eta2_aarch64(word64 rand[3 * 25], byte* seed, - byte o) +static void mlkem_get_noise_x3_eta2_aarch64(word64* rand, byte* seed, byte o) { /* Only rand[i*25 + 4] is set here - the rest of the state is zeroed in * registers by the assembly. */ @@ -5264,7 +5263,7 @@ static int mlkem_get_noise_k2_aarch64(sword16* vec1, sword16* vec2, * @param [in] seed Seed to generate random from. * @param [in] o Offset of seed count. */ -static void mlkem_get_noise_eta2_aarch64(word64 rand[25], byte* seed, byte o) +static void mlkem_get_noise_eta2_aarch64(word64* rand, byte* seed, byte o) { readUnalignedWords64(rand, seed, 4); /* Transposed value same as not. */ diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h index 1b15fc230b2..0a36b837dc6 100644 --- a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -38,10 +38,7 @@ typedef struct WC_CRYPTODEV { int cfd; - /* Placed here rather than appended so the bit-field lands in the padding - * after cfd - on LP64 this keeps sizeof and the offset of sess - * unchanged on LP32 the size of the struct grows. */ - unsigned int inited : 1; /* is this object initialized (1) or not (0) */ + WC_BITFIELD inited : 1; /* is this object initialized (1) or not (0) */ struct session_op sess; } WC_CRYPTODEV;