From 097cd576ffe4c532dcf347b4b7c205559e0d082e Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 28 Oct 2025 15:10:29 -0500 Subject: [PATCH 1/3] linuxkm/module_hooks.c: in wc_linuxkm_GenerateSeed_IntelRD(), log when RDSEED support is missing, and add verbose logging for generation failures. --- linuxkm/module_hooks.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index 7823e7815b..d2ebef6021 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -369,22 +369,38 @@ int wc_linuxkm_GenerateSeed_IntelRD(struct OS_Seed* os, byte* output, word32 sz) wc_InitRng_IntelRD(); - if (!IS_INTEL_RDSEED(intel_flags)) + if (!IS_INTEL_RDSEED(intel_flags)) { + static wolfSSL_Atomic_Int warned_on_missing_RDSEED = WOLFSSL_ATOMIC_INITIALIZER(0); + int expected_warned_on_missing_RDSEED = 0; + if (wolfSSL_Atomic_Int_CompareExchange( + &warned_on_missing_RDSEED, &expected_warned_on_missing_RDSEED, 1)) + { + pr_err("ERROR: wc_linuxkm_GenerateSeed_IntelRD() called on CPU without RDSEED support.\n"); + } return -1; + } for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), output += sizeof(word64)) { ret = IntelRDseed64_r((word64*)output); - if (ret != 0) + if (ret != 0) { +#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG + pr_err("ERROR: IntelRDseed64_r() returned code %d.\n", ret); +#endif return ret; + } } if (sz == 0) return 0; /* handle unaligned remainder */ ret = IntelRDseed64_r(&rndTmp); - if (ret != 0) + if (ret != 0) { +#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG + pr_err("ERROR: IntelRDseed64_r() returned code %d.\n", ret); +#endif return ret; + } XMEMCPY(output, &rndTmp, sz); wc_ForceZero(&rndTmp, sizeof(rndTmp)); From 9b90ea83eb031adadbb8c1a16b8cb4431bd24356 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 28 Oct 2025 15:10:46 -0500 Subject: [PATCH 2/3] src/x509.c: in wolfSSL_X509_get_ext_by_OBJ() and wolfSSL_X509_load_cert_crl_file(), add local protection from null derefs (fixes -Wnull-dereferences); wolfcrypt/src/chacha.c and wolfssl/wolfcrypt/chacha.h: implement USE_ARM_CHACHA_SPEEDUP gate; wolfcrypt/src/kdf.c: in wc_SSH_KDF(), add early return if _HashInit() fails (fixes _HashFree() of uninited _hash); wolfcrypt/src/sha256.c: initialize sha256->W in ARMASM variant of wc_InitSha256_ex(), and pass sha256->heap to XMALLOC/XFREE consistently. --- src/x509.c | 13 ++++++++++--- wolfcrypt/src/chacha.c | 16 ++++++++-------- wolfcrypt/src/kdf.c | 6 ++++-- wolfcrypt/src/sha256.c | 18 +++++++++++------- wolfssl/wolfcrypt/chacha.h | 8 ++++++-- 5 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/x509.c b/src/x509.c index 17a5ac2ddc..399515e898 100644 --- a/src/x509.c +++ b/src/x509.c @@ -463,10 +463,14 @@ int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x, lastpos++; if (lastpos < 0) lastpos = 0; - for (; lastpos < wolfSSL_sk_num(sk); lastpos++) - if (wolfSSL_OBJ_cmp(wolfSSL_sk_X509_EXTENSION_value(sk, - lastpos)->obj, obj) == 0) + for (; lastpos < wolfSSL_sk_num(sk); lastpos++) { + const WOLFSSL_X509_EXTENSION *ext = + wolfSSL_sk_X509_EXTENSION_value(sk, lastpos); + if (ext == NULL) + continue; + if (wolfSSL_OBJ_cmp(ext->obj, obj) == 0) return lastpos; + } return WOLFSSL_FATAL_ERROR; } @@ -8343,6 +8347,9 @@ int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx, for (i=0; i < num; i++) { info_tmp = wolfSSL_sk_X509_INFO_value(info, i); + if (info_tmp == NULL) + continue; + if (info_tmp->x509) { if (wolfSSL_X509_STORE_add_cert(ctx->store, info_tmp->x509) == WOLFSSL_SUCCESS) { diff --git a/wolfcrypt/src/chacha.c b/wolfcrypt/src/chacha.c index da47a4ad68..9e939650f5 100644 --- a/wolfcrypt/src/chacha.c +++ b/wolfcrypt/src/chacha.c @@ -115,7 +115,7 @@ Public domain. */ int wc_Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter) { -#if !defined(WOLFSSL_ARMASM) +#if !defined(USE_ARM_CHACHA_SPEEDUP) word32 temp[CHACHA_IV_WORDS];/* used for alignment of memory */ #endif @@ -124,7 +124,7 @@ int wc_Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter) ctx->left = 0; /* resets state */ -#if !defined(WOLFSSL_ARMASM) +#if !defined(USE_ARM_CHACHA_SPEEDUP) XMEMCPY(temp, inIv, CHACHA_IV_BYTES); /* block counter */ ctx->X[CHACHA_MATRIX_CNT_IV+0] = counter; @@ -141,7 +141,7 @@ int wc_Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter) return 0; } -#if !defined(WOLFSSL_ARMASM) +#if !defined(USE_ARM_CHACHA_SPEEDUP) /* "expand 32-byte k" as unsigned 32 byte */ static const word32 sigma[4] = {0x61707865, 0x3320646e, 0x79622d32, 0x6b206574}; /* "expand 16-byte k" as unsigned 16 byte */ @@ -153,7 +153,7 @@ static const word32 tau[4] = {0x61707865, 0x3120646e, 0x79622d36, 0x6b206574}; */ int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz) { -#if !defined(WOLFSSL_ARMASM) +#if !defined(USE_ARM_CHACHA_SPEEDUP) const word32* constants; const byte* k; #ifdef XSTREAM_ALIGN @@ -167,7 +167,7 @@ int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz) if (keySz != (CHACHA_MAX_KEY_SZ/2) && keySz != CHACHA_MAX_KEY_SZ) return BAD_FUNC_ARG; -#if !defined(WOLFSSL_ARMASM) +#if !defined(USE_ARM_CHACHA_SPEEDUP) #ifdef XSTREAM_ALIGN if ((wc_ptr_t)key % 4) { WOLFSSL_MSG("wc_ChachaSetKey unaligned key"); @@ -220,7 +220,7 @@ int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz) return 0; } -#if !defined(USE_INTEL_CHACHA_SPEEDUP) && !defined(WOLFSSL_ARMASM) +#if !defined(USE_INTEL_CHACHA_SPEEDUP) && !defined(USE_ARM_CHACHA_SPEEDUP) /** * Converts word into bytes with rotations having been done. */ @@ -267,7 +267,7 @@ extern void chacha_encrypt_avx2(ChaCha* ctx, const byte* m, byte* c, #endif -#if !defined(USE_INTEL_CHACHA_SPEEDUP) && !defined(WOLFSSL_ARMASM) +#if !defined(USE_INTEL_CHACHA_SPEEDUP) && !defined(USE_ARM_CHACHA_SPEEDUP) /** * Encrypt a stream of bytes */ @@ -365,7 +365,7 @@ int wc_Chacha_Process(ChaCha* ctx, byte* output, const byte* input, chacha_encrypt_x64(ctx, input, output, msglen); return 0; } -#elif defined(WOLFSSL_ARMASM) +#elif defined(USE_ARM_CHACHA_SPEEDUP) /* Handle left over bytes from last block. */ if ((msglen > 0) && (ctx->left > 0)) { byte* over = ((byte*)ctx->over) + CHACHA_CHUNK_BYTES - ctx->left; diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 5f57f64c70..beb9e79124 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -797,8 +797,10 @@ int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz, remainder = keySz % digestSz; ret = _HashInit(enmhashId, &hash); - if (ret == 0) - ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ); + if (ret != 0) + return ret; + + ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ); if (ret == 0 && kPad) ret = _HashUpdate(enmhashId, &hash, &pad, 1); if (ret == 0) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 823559c113..5400e74742 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -1105,6 +1105,10 @@ int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId) sha256->heap = heap; (void)devId; + #ifdef WOLFSSL_SMALL_STACK_CACHE + sha256->W = NULL; + #endif + return ret; } @@ -1241,16 +1245,16 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data, #if defined(WOLFSSL_SMALL_STACK_CACHE) && !defined(WOLFSSL_NO_MALLOC) word32* W = sha256->W; if (W == NULL) { - W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL, - DYNAMIC_TYPE_DIGEST); + W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, + sha256->heap, DYNAMIC_TYPE_DIGEST); if (W == NULL) return MEMORY_E; sha256->W = W; } #elif defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) word32* W; - W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL, - DYNAMIC_TYPE_TMP_BUFFER); + W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, + sha256->heap, DYNAMIC_TYPE_TMP_BUFFER); if (W == NULL) return MEMORY_E; #else @@ -1291,7 +1295,7 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data, #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE) &&\ !defined(WOLFSSL_NO_MALLOC) ForceZero(W, sizeof(word32) * WC_SHA256_BLOCK_SIZE); - XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(W, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return 0; } @@ -2308,7 +2312,7 @@ static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data, #ifdef WOLFSSL_SMALL_STACK_CACHE if (sha224->W != NULL) { ForceZero(sha224->W, sizeof(word32) * WC_SHA224_BLOCK_SIZE); - XFREE(sha224->W, NULL, DYNAMIC_TYPE_DIGEST); + XFREE(sha224->W, sha224->heap, DYNAMIC_TYPE_DIGEST); sha224->W = NULL; } #endif @@ -2391,7 +2395,7 @@ void wc_Sha256Free(wc_Sha256* sha256) #ifdef WOLFSSL_SMALL_STACK_CACHE if (sha256->W != NULL) { ForceZero(sha256->W, sizeof(word32) * WC_SHA256_BLOCK_SIZE); - XFREE(sha256->W, NULL, DYNAMIC_TYPE_DIGEST); + XFREE(sha256->W, sha256->heap, DYNAMIC_TYPE_DIGEST); sha256->W = NULL; } #endif diff --git a/wolfssl/wolfcrypt/chacha.h b/wolfssl/wolfcrypt/chacha.h index 4c7bc8b18f..9e2e094bd1 100644 --- a/wolfssl/wolfcrypt/chacha.h +++ b/wolfssl/wolfcrypt/chacha.h @@ -68,6 +68,10 @@ Block counter is located at index 12. #define USE_INTEL_CHACHA_SPEEDUP #define HAVE_INTEL_AVX1 #endif +#elif defined(WOLFSSL_ARMASM) + #ifndef NO_CHACHA_ASM + #define USE_ARM_CHACHA_SPEEDUP + #endif #endif enum { @@ -82,7 +86,7 @@ typedef struct ChaCha { byte extra[12]; #endif word32 left; /* number of bytes leftover */ -#if defined(USE_INTEL_CHACHA_SPEEDUP) || defined(WOLFSSL_ARMASM) || \ +#if defined(USE_INTEL_CHACHA_SPEEDUP) || defined(USE_ARM_CHACHA_SPEEDUP) || \ defined(WOLFSSL_RISCV_ASM) word32 over[CHACHA_CHUNK_WORDS]; #endif @@ -107,7 +111,7 @@ WOLFSSL_API int wc_XChacha_SetKey(ChaCha *ctx, const byte *key, word32 keySz, word32 counter); #endif -#if defined(WOLFSSL_ARMASM) +#if defined(USE_ARM_CHACHA_SPEEDUP) WOLFSSL_LOCAL void wc_chacha_setiv(word32* x, const byte* iv, word32 counter); WOLFSSL_LOCAL void wc_chacha_setkey(word32* x, const byte* key, word32 keySz); From 8c60b7b250f1881811dc85613670d4f321b2d8bc Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 28 Oct 2025 15:49:18 -0500 Subject: [PATCH 3/3] src/internal.c and tests/api.c: fix clang-analyzer-core.NullPointerArithms. --- src/internal.c | 44 ++++++++++++++++++++++++++++---------------- tests/api.c | 31 +++++++++++++++++-------------- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/internal.c b/src/internal.c index 72428d710c..e587982039 100644 --- a/src/internal.c +++ b/src/internal.c @@ -34022,9 +34022,11 @@ int SendClientKeyExchange(WOLFSSL* ssl) { #ifdef HAVE_CURVE25519 if (ssl->peerX25519KeyPresent) { - ret = X25519SharedSecret(ssl, + ret = X25519SharedSecret( + ssl, (curve25519_key*)ssl->hsKey, ssl->peerX25519Key, - args->output + OPAQUE8_LEN, &args->length, + args->output ? args->output + OPAQUE8_LEN : NULL, + &args->length, ssl->arrays->preMasterSecret + OPAQUE16_LEN, &ssl->arrays->preMasterSz, WOLFSSL_CLIENT_END @@ -34043,9 +34045,11 @@ int SendClientKeyExchange(WOLFSSL* ssl) #endif #ifdef HAVE_CURVE448 if (ssl->peerX448KeyPresent) { - ret = X448SharedSecret(ssl, + ret = X448SharedSecret( + ssl, (curve448_key*)ssl->hsKey, ssl->peerX448Key, - args->output + OPAQUE8_LEN, &args->length, + args->output ? args->output + OPAQUE8_LEN : NULL, + &args->length, ssl->arrays->preMasterSecret + OPAQUE16_LEN, &ssl->arrays->preMasterSz, WOLFSSL_CLIENT_END @@ -34062,9 +34066,11 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif - ret = EccSharedSecret(ssl, + ret = EccSharedSecret( + ssl, (ecc_key*)ssl->hsKey, ssl->peerEccKey, - args->output + OPAQUE8_LEN, &args->length, + args->output ? args->output + OPAQUE8_LEN : NULL, + &args->length, ssl->arrays->preMasterSecret + OPAQUE16_LEN, &ssl->arrays->preMasterSz, WOLFSSL_CLIENT_END @@ -34090,9 +34096,11 @@ int SendClientKeyExchange(WOLFSSL* ssl) #ifdef HAVE_CURVE25519 if (ssl->peerX25519KeyPresent) { - ret = X25519SharedSecret(ssl, + ret = X25519SharedSecret( + ssl, (curve25519_key*)ssl->hsKey, ssl->peerX25519Key, - args->encSecret + OPAQUE8_LEN, &args->encSz, + args->encSecret ? args->encSecret + OPAQUE8_LEN : NULL, + &args->encSz, ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, WOLFSSL_CLIENT_END @@ -34111,9 +34119,11 @@ int SendClientKeyExchange(WOLFSSL* ssl) #endif #ifdef HAVE_CURVE448 if (ssl->peerX448KeyPresent) { - ret = X448SharedSecret(ssl, + ret = X448SharedSecret( + ssl, (curve448_key*)ssl->hsKey, ssl->peerX448Key, - args->encSecret + OPAQUE8_LEN, &args->encSz, + args->encSecret ? args->encSecret + OPAQUE8_LEN : NULL, + &args->encSz, ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, WOLFSSL_CLIENT_END @@ -34134,12 +34144,14 @@ int SendClientKeyExchange(WOLFSSL* ssl) peerKey = (ssl->specs.static_ecdh) ? ssl->peerEccDsaKey : ssl->peerEccKey; - ret = EccSharedSecret(ssl, - (ecc_key*)ssl->hsKey, peerKey, - args->encSecret + OPAQUE8_LEN, &args->encSz, - ssl->arrays->preMasterSecret, - &ssl->arrays->preMasterSz, - WOLFSSL_CLIENT_END); + ret = EccSharedSecret( + ssl, + (ecc_key*)ssl->hsKey, peerKey, + args->encSecret ? args->encSecret + OPAQUE8_LEN : NULL, + &args->encSz, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, + WOLFSSL_CLIENT_END); if (!ssl->specs.static_ecdh #ifdef WOLFSSL_ASYNC_CRYPT diff --git a/tests/api.c b/tests/api.c index 1730db85e1..02a8a3d8d5 100644 --- a/tests/api.c +++ b/tests/api.c @@ -36905,6 +36905,7 @@ static int test_wolfSSL_PKCS7_sign(void) flags = PKCS7_BINARY | PKCS7_DETACHED; ExpectNotNull(p7 = PKCS7_sign(signCert, signKey, NULL, inBio, flags)); ExpectIntGT((outLen = i2d_PKCS7(p7, &out)), 0); + ExpectNotNull(out); /* verify with wolfCrypt, d2i_PKCS7 does not support detached content */ ExpectNotNull(p7Ver = wc_PKCS7_New(HEAP_HINT, testDevId)); @@ -36924,14 +36925,16 @@ static int test_wolfSSL_PKCS7_sign(void) p7Ver->contentSz = sizeof(data); } /* test for streaming */ - ret = -1; - for (z = 0; z < outLen && ret != 0; z++) { - ret = wc_PKCS7_VerifySignedData(p7Ver, out + z, 1); - if (ret < 0){ - ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)); + if (EXPECT_SUCCESS()) { + ret = -1; + for (z = 0; z < outLen && ret != 0; z++) { + ret = wc_PKCS7_VerifySignedData(p7Ver, out + z, 1); + if (ret < 0){ + ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)); + } } + ExpectIntEQ(ret, 0); } - ExpectIntEQ(ret, 0); wc_PKCS7_Free(p7Ver); p7Ver = NULL; #endif /* !NO_PKCS7_STREAM */ @@ -36943,7 +36946,6 @@ static int test_wolfSSL_PKCS7_sign(void) PKCS7_free(p7Ver); p7Ver = NULL; - ExpectNotNull(out); XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER); out = NULL; PKCS7_free(p7); @@ -36983,15 +36985,16 @@ static int test_wolfSSL_PKCS7_sign(void) p7Ver->contentSz = sizeof(data); } /* test for streaming */ - ret = -1; - for (z = 0; z < outLen && ret != 0; z++) { - ret = wc_PKCS7_VerifySignedData(p7Ver, out + z, 1); - if (ret < 0){ - ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)); + if (EXPECT_SUCCESS()) { + ret = -1; + for (z = 0; z < outLen && ret != 0; z++) { + ret = wc_PKCS7_VerifySignedData(p7Ver, out + z, 1); + if (ret < 0){ + ExpectIntEQ(ret, WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)); + } } + ExpectIntEQ(ret, 0); } - ExpectIntEQ(ret, 0); - ExpectNotNull(out); wc_PKCS7_Free(p7Ver); p7Ver = NULL; #endif /* !NO_PKCS7_STREAM */