From 88c2600e42745f853567fbd71e5a4f7a187d7c6b Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 12:48:51 -0700 Subject: [PATCH 01/82] F-4294 - Set DH bits after param generation to fix derive overflow --- src/wp_dh_kmgmt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_dh_kmgmt.c b/src/wp_dh_kmgmt.c index 1f1cdde2..ea90cb90 100644 --- a/src/wp_dh_kmgmt.c +++ b/src/wp_dh_kmgmt.c @@ -1628,6 +1628,9 @@ static int wp_dh_gen_parameters(wp_DhGenCtx *ctx, wp_Dh* dh) WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_DhGenerateParams", rc); ok = 0; } + if (ok) { + dh->bits = mp_count_bits(&dh->key.p); + } WOLFPROV_LEAVE(WP_LOG_COMP_DH, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; From 08669a621af7427ae5eb41136740811102b64f85 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 12:49:34 -0700 Subject: [PATCH 02/82] F-2811 - Reject oversized input in RSA X931 sign to prevent overflow --- src/wp_rsa_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index 962c50ac..cae8f2ce 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -880,6 +880,9 @@ static int wp_rsa_sign_x931(wp_RsaSigCtx* ctx, unsigned char* sig, if (paddedSz <= 0) { ok = 0; } + if (ok && (tbsLen >= (size_t)paddedSz)) { + ok = 0; + } if (ok) { tbuf = (unsigned char *)OPENSSL_malloc(paddedSz); if (tbuf == NULL) { From e83e6f915c5e7df31c36cc8ae739ddd2027a5222 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 12:53:26 -0700 Subject: [PATCH 03/82] F-3165 - Reject too-short PEM to prevent header compare over-read --- src/wp_dec_pem2der.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wp_dec_pem2der.c b/src/wp_dec_pem2der.c index 0635db05..898ce291 100644 --- a/src/wp_dec_pem2der.c +++ b/src/wp_dec_pem2der.c @@ -230,7 +230,11 @@ static int wp_pem2der_decode_data(const unsigned char* data, word32 len, /* Identify the type of object by looking at the header. */ /* TODO: support more PEM headers. */ - if (XMEMCMP(data, "-----BEGIN CERTIFICATE-----", 27) == 0) { + /* Reject input too short for the fixed-length header compares below. */ + if (len < 41) { + ok = 0; + } + else if (XMEMCMP(data, "-----BEGIN CERTIFICATE-----", 27) == 0) { type = CERT_TYPE; obj = OSSL_OBJECT_CERT; } From d79f03d3a8ce610a463f03d071e8b1570ca384f8 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 12:55:24 -0700 Subject: [PATCH 04/82] F-3172 - Zeroize TLS 1.3 HKDF salt secret on free --- src/wp_hkdf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp_hkdf.c b/src/wp_hkdf.c index 43a53d5e..b0fe3b52 100644 --- a/src/wp_hkdf.c +++ b/src/wp_hkdf.c @@ -158,7 +158,7 @@ static void wp_kdf_hkdf_clear(wp_HkdfCtx* ctx) } OPENSSL_free(ctx->label); OPENSSL_free(ctx->prefix); - OPENSSL_free(ctx->salt); + OPENSSL_clear_free(ctx->salt, ctx->saltSz); OPENSSL_cleanse(ctx->info, ctx->infoSz); } @@ -368,7 +368,7 @@ static int wp_hkdf_base_set_ctx_params(wp_HkdfCtx* ctx, #else if (p != NULL) { #endif - OPENSSL_free(ctx->salt); + OPENSSL_clear_free(ctx->salt, ctx->saltSz); ctx->salt = NULL; if (!OSSL_PARAM_get_octet_string( p, (void**)&ctx->salt, 0, &ctx->saltSz)) { From 5a607124ea9800d792282dd78dccca8a03b331db Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 12:56:18 -0700 Subject: [PATCH 05/82] F-4827 - Zeroize decrypted PKCS8 key by allocating as PRIVATEKEY_TYPE --- src/wp_dec_epki2pki.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wp_dec_epki2pki.c b/src/wp_dec_epki2pki.c index 7671cdc6..055163a1 100644 --- a/src/wp_dec_epki2pki.c +++ b/src/wp_dec_epki2pki.c @@ -145,7 +145,8 @@ static int wp_DecryptPKCS8Key(byte* input, word32 sz, const char* password, ret = 0; } if (ret == 0) { - ret = wc_AllocDer(&pkcs8Der, pkcs8Sz, DYNAMIC_TYPE_KEY, NULL); + /* PRIVATEKEY_TYPE so wc_FreeDer zeroizes the decrypted key. */ + ret = wc_AllocDer(&pkcs8Der, pkcs8Sz, PRIVATEKEY_TYPE, NULL); } if (ret == 0) { ret = wc_CreatePKCS8Key(pkcs8Der->buffer, &pkcs8Der->length, From 018375f67a145164b785ccfac7a66226fd5ba32e Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 12:57:04 -0700 Subject: [PATCH 06/82] F-2804 - Advance index over ECX private key so export buffer is zeroized --- src/wp_ecx_kmgmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index 5c84d570..b90bf0e8 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -1154,6 +1154,7 @@ static int wp_ecx_export_keypair(wp_Ecx* ecx, OSSL_PARAM* params, int* pIdx, } wp_param_set_octet_string_ptr(¶ms[i++], OSSL_PKEY_PARAM_PRIV_KEY, data + *idx, outLen); + *idx += outLen; } } From 72932a41fa9bc9d50965143e667e43643c10c60b Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 12:57:55 -0700 Subject: [PATCH 07/82] F-2044 - Zeroize PBKDF1-derived key before free in wp_BufferKeyEncrypt --- src/wp_internal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp_internal.c b/src/wp_internal.c index ceb2fce6..6eafb0e2 100644 --- a/src/wp_internal.c +++ b/src/wp_internal.c @@ -1003,6 +1003,7 @@ static int wp_BufferKeyEncrypt(wp_EncryptedInfo* info, byte* der, word32 derSz, #ifndef NO_PWDBASED if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1, info->keySz, hashType)) != 0) { + ForceZero(key, WC_MAX_SYM_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY); #endif @@ -1022,6 +1023,7 @@ static int wp_BufferKeyEncrypt(wp_EncryptedInfo* info, byte* der, word32 derSz, info->iv); #endif /* !NO_AES && HAVE_AES_CBC */ + ForceZero(key, WC_MAX_SYM_KEY_SIZE); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_SYMMETRIC_KEY); #endif From d34066fadf04c9ebe9c8a12eb2669666359d9d26 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 12:58:25 -0700 Subject: [PATCH 08/82] F-3856 - Zeroize copied AES round keys on dupctx error path --- src/wp_aes_block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_aes_block.c b/src/wp_aes_block.c index 5712ca56..cc2fcf24 100644 --- a/src/wp_aes_block.c +++ b/src/wp_aes_block.c @@ -117,7 +117,7 @@ static void *wp_aes_block_dupctx(wp_AesBlockCtx *src) if (src->tlsmacAlloced && src->tlsmac != NULL) { dst->tlsmac = OPENSSL_malloc(src->tlsmacsize); if (dst->tlsmac == NULL) { - OPENSSL_free(dst); + OPENSSL_clear_free(dst, sizeof(*dst)); return NULL; } XMEMCPY(dst->tlsmac, src->tlsmac, src->tlsmacsize); From 5b80bb334365ff934a17c697d9fff1a6b58e25fa Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:00:48 -0700 Subject: [PATCH 09/82] F-4550 - Push restored IV into DES3 state on CBC re-init --- src/wp_des.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_des.c b/src/wp_des.c index 2fde72a3..865e3794 100644 --- a/src/wp_des.c +++ b/src/wp_des.c @@ -296,6 +296,9 @@ static int wp_des3_block_init(wp_Des3BlockCtx *ctx, const unsigned char *key, } if (ok && (iv == NULL) && ctx->ivSet && (ctx->mode == EVP_CIPH_CBC_MODE)) { XMEMCPY(ctx->iv, ctx->oiv, ctx->ivLen); + if (wc_Des3_SetIV(&ctx->des3, ctx->iv) != 0) { + ok = 0; + } } if (ok && (key != NULL)) { From 0e06fd398d0c62539b806559677876a1f86ac48d Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:05:57 -0700 Subject: [PATCH 10/82] F-2239 - Fix DH private key byte order for unsigned-integer get_params --- src/wp_dh_kmgmt.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/wp_dh_kmgmt.c b/src/wp_dh_kmgmt.c index ea90cb90..61f9d3bd 100644 --- a/src/wp_dh_kmgmt.c +++ b/src/wp_dh_kmgmt.c @@ -861,13 +861,21 @@ static int wp_dh_get_params(wp_Dh* dh, OSSL_PARAM params[]) p->return_size = dh->privSz; } else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { - if (p->data_size < dh->privSz) { + mp_int priv; + + if (mp_init(&priv) != 0) { ok = 0; } else { - /* OSSL returns a BIGNUM, but we copy raw bytes*/ - XMEMCPY(p->data, dh->priv, dh->privSz); - p->return_size = dh->privSz; + if (mp_read_unsigned_bin(&priv, dh->priv, + (int)dh->privSz) != 0) { + ok = 0; + } + if (ok) { + ok = wp_params_set_mp(params, OSSL_PKEY_PARAM_PRIV_KEY, + &priv, 1); + } + mp_forcezero(&priv); } } else { From fd347e384e04444045d499d407ebe98b19733cc2 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:06:40 -0700 Subject: [PATCH 11/82] F-6241 - Initialize Ed25519/Ed448 verify result to fail closed on error --- src/wp_ecx_sig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp_ecx_sig.c b/src/wp_ecx_sig.c index e5b6a0a0..bf2306c1 100644 --- a/src/wp_ecx_sig.c +++ b/src/wp_ecx_sig.c @@ -463,7 +463,7 @@ static int wp_ed25519_digest_verify(wp_EcxSigCtx *ctx, unsigned char *sig, } } if (ok) { - int res; + int res = 0; int rc = wc_ed25519_verify_msg(sig, (word32)sigLen, tbs, (word32)tbsLen, &res, wp_ecx_get_key(ctx->ecx)); if (rc != 0) { @@ -676,7 +676,7 @@ static int wp_ed448_digest_verify(wp_EcxSigCtx *ctx, unsigned char *sig, } } if (ok) { - int res; + int res = 0; int rc = wc_ed448_verify_msg(sig, (word32)sigLen, tbs, (word32)tbsLen, &res, wp_ecx_get_key(ctx->ecx), NULL, 0); if (rc != 0) { From a9c7f4b4bfab1dc66769f948518d26423d3895b2 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:08:43 -0700 Subject: [PATCH 12/82] F-6679 - Fix ML-DSA match reflexivity for single-component keys --- src/wp_mldsa_kmgmt.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/wp_mldsa_kmgmt.c b/src/wp_mldsa_kmgmt.c index dea599a7..45eb4680 100644 --- a/src/wp_mldsa_kmgmt.c +++ b/src/wp_mldsa_kmgmt.c @@ -456,6 +456,7 @@ static int wp_mldsa_match(const wp_MlDsa* a, const wp_MlDsa* b, int selection) word32 lenB; word32 allocA = 0; word32 allocB = 0; + int checked = 0; WOLFPROV_ENTER(WP_LOG_COMP_PQC, "wp_mldsa_match"); @@ -467,7 +468,14 @@ static int wp_mldsa_match(const wp_MlDsa* a, const wp_MlDsa* b, int selection) WOLFPROV_LEAVE(WP_LOG_COMP_PQC, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), 0); return 0; } - if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + /* Presence mismatch fails; both-present compares; neither-present skips. */ + if (((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) && + (a->hasPub != b->hasPub)) { + ok = 0; + } + if (ok && ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) && + a->hasPub && b->hasPub) { + checked = 1; lenA = a->data->pubKeySize; lenB = b->data->pubKeySize; bufA = (unsigned char*)OPENSSL_malloc(lenA); @@ -495,7 +503,13 @@ static int wp_mldsa_match(const wp_MlDsa* a, const wp_MlDsa* b, int selection) bufA = NULL; bufB = NULL; } - if (ok && ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)) { + if (ok && ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) && + (a->hasPriv != b->hasPriv)) { + ok = 0; + } + if (ok && ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) && + a->hasPriv && b->hasPriv) { + checked = 1; allocA = a->data->privKeySize; allocB = b->data->privKeySize; lenA = allocA; @@ -524,6 +538,12 @@ static int wp_mldsa_match(const wp_MlDsa* a, const wp_MlDsa* b, int selection) OPENSSL_clear_free(bufA, allocA); OPENSSL_clear_free(bufB, allocB); } + /* A public/private selection with no component present in both is not a match. */ + if (ok && !checked && + ((selection & (OSSL_KEYMGMT_SELECT_PUBLIC_KEY | + OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) != 0)) { + ok = 0; + } WOLFPROV_LEAVE(WP_LOG_COMP_PQC, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; } From 51df566c52a307567477fbb01993c5004a70ca2c Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:10:45 -0700 Subject: [PATCH 13/82] F-6496 - Allow RSA key-data size-only query with NULL data buffer --- src/wp_rsa_kmgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index fd2c4858..2dbc001c 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -915,7 +915,7 @@ static int wp_rsa_get_params_key_data(wp_Rsa* rsa, OSSL_PARAM params[]) size_t oLen; mp_int* mp = (mp_int*)(((byte*)&rsa->key) + wp_rsa_offset[i]); oLen = mp_unsigned_bin_size(mp); - if (oLen > p->data_size) { + if ((p->data != NULL) && (oLen > p->data_size)) { ok = 0; } if (ok && (p->data != NULL) && From 7d779b789cab802291b658e8ff00455b46fe1b53 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:12:25 -0700 Subject: [PATCH 14/82] F-6499 - Advertise ECX private key as octet string to match import --- src/wp_ecx_kmgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index b90bf0e8..642044ef 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -1024,7 +1024,7 @@ static int wp_ecx_import(wp_Ecx* ecx, int selection, const OSSL_PARAM params[]) /** ECX private key parameters. */ #define WP_ECX_PRIVATE_KEY_PARAMS \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) /** ECX public key parameters. */ #define WP_ECX_PUBLIC_KEY_PARAMS \ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) From 5d7b936b61f536120d49047b19f0e2c3b331e268 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:14:52 -0700 Subject: [PATCH 15/82] F-6500 - Treat DH public key as integer to match import and OpenSSL --- src/wp_dh_kmgmt.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/wp_dh_kmgmt.c b/src/wp_dh_kmgmt.c index 61f9d3bd..de8cb430 100644 --- a/src/wp_dh_kmgmt.c +++ b/src/wp_dh_kmgmt.c @@ -847,7 +847,25 @@ static int wp_dh_get_params(wp_Dh* dh, OSSL_PARAM params[]) if (p->data == NULL) { p->return_size = dh->pubSz; } - else { + else if (p->data_type == OSSL_PARAM_UNSIGNED_INTEGER) { + mp_int pub; + + if (mp_init(&pub) != 0) { + ok = 0; + } + else { + if (mp_read_unsigned_bin(&pub, dh->pub, + (int)dh->pubSz) != 0) { + ok = 0; + } + if (ok) { + ok = wp_params_set_mp(params, OSSL_PKEY_PARAM_PUB_KEY, + &pub, 1); + } + mp_clear(&pub); + } + } + else { /* return_size is set within this function */ ok = wp_params_set_octet_string_be(params, OSSL_PKEY_PARAM_PUB_KEY, dh->pub, dh->pubSz); @@ -1196,7 +1214,7 @@ static int wp_dh_import(wp_Dh* dh, int selection, const OSSL_PARAM params[]) OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) /** DH public key parameters. */ #define WP_DH_PUBLIC_KEY_PARAMS \ - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) + OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) /** DH domain parameters - with FFC_Q. */ #define WP_DH_DOMAIN_PARAMS \ OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \ From 8d96889a4c62a57173417cc39c70787dfb8fbd94 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:15:27 -0700 Subject: [PATCH 16/82] F-4086 - Advertise ECC GROUP_NAME and USE_COFACTOR_ECDH in gettable params --- src/wp_ecc_kmgmt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp_ecc_kmgmt.c b/src/wp_ecc_kmgmt.c index 2d50e0d0..3d5bd74d 100644 --- a/src/wp_ecc_kmgmt.c +++ b/src/wp_ecc_kmgmt.c @@ -688,6 +688,8 @@ static const OSSL_PARAM *wp_ecc_gettable_params(WOLFPROV_CTX* provCtx) OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), + OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), OSSL_PARAM_END }; (void)provCtx; From 04ed7266ca6db4209efb2bae860ea272dc2789d3 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:18:30 -0700 Subject: [PATCH 17/82] F-3652 - Copy kdfMdName in DH and ECDH dupctx --- src/wp_dh_exch.c | 1 + src/wp_ecdh_exch.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/wp_dh_exch.c b/src/wp_dh_exch.c index 3154e297..7b9c4d44 100644 --- a/src/wp_dh_exch.c +++ b/src/wp_dh_exch.c @@ -152,6 +152,7 @@ static wp_DhCtx* wp_dh_dupctx(wp_DhCtx* src) dst->pad = src->pad; dst->kdfType = src->kdfType; dst->kdfMd = src->kdfMd; + XMEMCPY(dst->kdfMdName, src->kdfMdName, sizeof(dst->kdfMdName)); dst->ukmLen = src->ukmLen; dst->keyLen = src->keyLen; } diff --git a/src/wp_ecdh_exch.c b/src/wp_ecdh_exch.c index f9ba02d5..b00d0a0b 100644 --- a/src/wp_ecdh_exch.c +++ b/src/wp_ecdh_exch.c @@ -154,6 +154,7 @@ static wp_EcdhCtx* wp_ecdh_dup(wp_EcdhCtx* src) dst->cofactor = src->cofactor; dst->kdfType = src->kdfType; dst->kdfMd = src->kdfMd; + XMEMCPY(dst->kdfMdName, src->kdfMdName, sizeof(dst->kdfMdName)); dst->ukmLen = src->ukmLen; dst->keyLen = src->keyLen; } From d7714cb7ced0a07face4dfefa09db55b60a923bd Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:24:14 -0700 Subject: [PATCH 18/82] F-5916 - Guard KBKDF MAC update length against word32 truncation --- src/wp_kbkdf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_kbkdf.c b/src/wp_kbkdf.c index 7b595cb6..05cf3cf0 100644 --- a/src/wp_kbkdf.c +++ b/src/wp_kbkdf.c @@ -479,6 +479,10 @@ static int wp_kbkdf_mac_update(wp_KbkdfCtx* ctx, const unsigned char *data, WOLFPROV_ENTER(WP_LOG_COMP_KDF, "wp_kbkdf_mac_update"); + if (dataLen > 0xFFFFFFFFU) { + return 0; + } + switch(ctx->mac) { #ifdef WP_HAVE_HMAC case WP_MAC_TYPE_HMAC: From 251537551d33ee3bd5b948553347728d8e08e0c4 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:24:29 -0700 Subject: [PATCH 19/82] F-5202 - Guard KBKDF CMAC key length against word32 truncation --- src/wp_kbkdf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_kbkdf.c b/src/wp_kbkdf.c index 05cf3cf0..4f5aeb84 100644 --- a/src/wp_kbkdf.c +++ b/src/wp_kbkdf.c @@ -419,6 +419,10 @@ static int wp_kbkdf_init_mac(wp_KbkdfCtx* ctx, unsigned char* key, WOLFPROV_ENTER(WP_LOG_COMP_KDF, "wp_kbkdf_init_mac"); + if (keyLen > 0xFFFFFFFFU) { + return 0; + } + switch(ctx->mac) { #ifdef WP_HAVE_HMAC case WP_MAC_TYPE_HMAC: From dc3f2564f2bee1abe979016e1a2ca51775872f78 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:24:46 -0700 Subject: [PATCH 20/82] F-4297 - Cap KBKDF output to the 32-bit SP800-108 L field --- src/wp_kbkdf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp_kbkdf.c b/src/wp_kbkdf.c index 4f5aeb84..d1600cc3 100644 --- a/src/wp_kbkdf.c +++ b/src/wp_kbkdf.c @@ -603,6 +603,11 @@ static int wp_kdf_kbkdf_derive(wp_KbkdfCtx* ctx, unsigned char* key, WOLFPROV_ENTER(WP_LOG_COMP_KDF, "wp_kdf_kbkdf_derive"); + /* SP800-108 L is a 32-bit bit-length, so cap output at what it can hold. */ + if (keyLen > 0x1FFFFFFFU) { + return 0; + } + if (!wolfssl_prov_is_running()) { ok = 0; } From d231f84eb092f37cc8805794852f9f75b837a9fc Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:25:06 -0700 Subject: [PATCH 21/82] F-5201 - Guard HMAC key length against word32 truncation --- src/wp_hmac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_hmac.c b/src/wp_hmac.c index 4878c003..4e9739a5 100644 --- a/src/wp_hmac.c +++ b/src/wp_hmac.c @@ -128,6 +128,10 @@ static int wp_hmac_set_key(wp_HmacCtx* macCtx, const unsigned char* key, WP_CHECK_FIPS_ALGO(WP_CAST_ALGO_HMAC); + if (keyLen > 0xFFFFFFFFU) { + return 0; + } + if (macCtx->keyLen > 0) { OPENSSL_secure_clear_free(macCtx->key, macCtx->keyLen); } From cf9148019ec88564f5de1110a54a5ffa05ee7d7d Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:25:55 -0700 Subject: [PATCH 22/82] F-4295 - Guard HKDF derive lengths against word32 truncation --- src/wp_hkdf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp_hkdf.c b/src/wp_hkdf.c index b0fe3b52..786c0e02 100644 --- a/src/wp_hkdf.c +++ b/src/wp_hkdf.c @@ -209,6 +209,11 @@ static int wp_kdf_hkdf_derive(wp_HkdfCtx* ctx, unsigned char* key, int ok = 1; WOLFPROV_ENTER(WP_LOG_COMP_HKDF, "wp_kdf_hkdf_derive"); + + if ((keyLen > 0xFFFFFFFFU) || (ctx->keySz > 0xFFFFFFFFU) || + (ctx->saltSz > 0xFFFFFFFFU) || (ctx->infoSz > 0xFFFFFFFFU)) { + return 0; + } WOLFPROV_MSG_DEBUG(WP_LOG_COMP_HKDF, "HKDF derive: keyLen=%zu, mode=%d", keyLen, ctx->mode); WOLFPROV_MSG_DEBUG(WP_LOG_COMP_HKDF, "HKDF derive: keySz=%zu, saltSz=%zu, infoSz=%zu", ctx->keySz, ctx->saltSz, ctx->infoSz); From b251b28da89ead2b5d5197fe0a89e0dd7e017658 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:26:13 -0700 Subject: [PATCH 23/82] F-4296 - Guard TLS 1.3 HKDF expand lengths against word32 truncation --- src/wp_hkdf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wp_hkdf.c b/src/wp_hkdf.c index 786c0e02..c671ead5 100644 --- a/src/wp_hkdf.c +++ b/src/wp_hkdf.c @@ -580,6 +580,12 @@ static int wp_tls13_hkdf_expand(wp_HkdfCtx* ctx, unsigned char* inKey, int rc; WOLFPROV_ENTER(WP_LOG_COMP_HKDF, "wp_tls13_hkdf_expand"); + + if ((keyLen > 0xFFFFFFFFU) || (inKeyLen > 0xFFFFFFFFU) || + (dataLen > 0xFFFFFFFFU) || (ctx->prefixLen > 0xFFFFFFFFU) || + (ctx->labelLen > 0xFFFFFFFFU)) { + return 0; + } WOLFPROV_MSG_DEBUG(WP_LOG_COMP_HKDF, "TLS1.3 HKDF expand: inKeyLen=%zu, dataLen=%zu, keyLen=%zu", inKeyLen, dataLen, keyLen); From de63c52f60a3c72946c73728b13aaf26bf944ec4 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:30:14 -0700 Subject: [PATCH 24/82] F-5203 - Reject PBKDF2 iteration count above INT_MAX --- src/wp_pbkdf2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_pbkdf2.c b/src/wp_pbkdf2.c index f1a0a4f3..b5ebb1e5 100644 --- a/src/wp_pbkdf2.c +++ b/src/wp_pbkdf2.c @@ -297,6 +297,10 @@ static int wp_kdf_pbkdf2_derive(wp_Pbkdf2Ctx* ctx, unsigned char* key, } /* wc_PBKDF2_ex fails when ctx->iterations is 0. */ + if (ok && (ctx->iterations > 0x7FFFFFFFU)) { + ok = 0; + } + if (ok) { int rc; From 557e09bf05afc6811b057d881b1c03486229c41b Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:30:33 -0700 Subject: [PATCH 25/82] F-5180 - Guard PBKDF2 password, salt, and key lengths against int truncation --- src/wp_pbkdf2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_pbkdf2.c b/src/wp_pbkdf2.c index b5ebb1e5..31e13ca5 100644 --- a/src/wp_pbkdf2.c +++ b/src/wp_pbkdf2.c @@ -300,6 +300,10 @@ static int wp_kdf_pbkdf2_derive(wp_Pbkdf2Ctx* ctx, unsigned char* key, if (ok && (ctx->iterations > 0x7FFFFFFFU)) { ok = 0; } + if (ok && ((ctx->passwordSz > 0x7FFFFFFFU) || + (ctx->saltSz > 0x7FFFFFFFU) || (keyLen > 0x7FFFFFFFU))) { + ok = 0; + } if (ok) { int rc; From 5c625b2d33019c6f6cf49dd38d7ee0d90437dbcb Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:32:31 -0700 Subject: [PATCH 26/82] F-4383 - Guard AES-GCM input and AAD lengths against word32 truncation --- src/wp_aes_aead.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_aes_aead.c b/src/wp_aes_aead.c index c5e58bc5..432b779b 100644 --- a/src/wp_aes_aead.c +++ b/src/wp_aes_aead.c @@ -1460,6 +1460,10 @@ static int wp_aesgcm_encdec(wp_AeadCtx *ctx, unsigned char *out, size_t* outLen, WOLFPROV_ENTER(WP_LOG_COMP_AES, "wp_aesgcm_encdec"); + if ((ctx->inLen > 0xFFFFFFFFU) || (ctx->aadLen > 0xFFFFFFFFU)) { + return 0; + } + if (ctx->tagLen == UNINITIALISED_SIZET) { ctx->tagLen = EVP_GCM_TLS_TAG_LEN; } From dbaceb9f3a9123de433c817ad5ce6ce4e6b8c238 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:32:44 -0700 Subject: [PATCH 27/82] F-4939 - Guard AES-CCM input and AAD lengths against word32 truncation --- src/wp_aes_aead.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_aes_aead.c b/src/wp_aes_aead.c index 432b779b..9b13e102 100644 --- a/src/wp_aes_aead.c +++ b/src/wp_aes_aead.c @@ -1986,6 +1986,10 @@ static int wp_aesccm_encdec(wp_AeadCtx *ctx, unsigned char *out, WOLFPROV_ENTER(WP_LOG_COMP_AES, "wp_aesccm_encdec"); + if ((inLen > 0xFFFFFFFFU) || (ctx->aadLen > 0xFFFFFFFFU)) { + return 0; + } + if (ctx->tagLen == UNINITIALISED_SIZET) { ctx->tagLen = EVP_CCM_TLS_TAG_LEN; } From cf58e42a01ec2293b486a733ce58136e9b98db85 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:33:17 -0700 Subject: [PATCH 28/82] F-4696 - Cap accumulated GMAC data length to avoid overflow and truncation --- src/wp_gmac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_gmac.c b/src/wp_gmac.c index 50bff4d1..620920d0 100644 --- a/src/wp_gmac.c +++ b/src/wp_gmac.c @@ -244,6 +244,9 @@ static int wp_gmac_update(wp_GmacCtx* macCtx, const unsigned char* data, WOLFPROV_ENTER(WP_LOG_COMP_MAC, "wp_gmac_update"); /* Data cached as wolfSSL doesn't have a streaming API. */ + if (dataLen > 0xFFFFFFFFU - macCtx->dataLen) { + return 0; + } p = OPENSSL_realloc(macCtx->data, macCtx->dataLen + dataLen); if (p == NULL) { ok = 0; From 84d9a9de24b1f1b1952711b73c1a27bb71f473ff Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:33:33 -0700 Subject: [PATCH 29/82] F-5200 - Guard GMAC data and output lengths against word32 truncation --- src/wp_gmac.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp_gmac.c b/src/wp_gmac.c index 620920d0..0ab10cfd 100644 --- a/src/wp_gmac.c +++ b/src/wp_gmac.c @@ -279,7 +279,10 @@ static int wp_gmac_final(wp_GmacCtx* macCtx, unsigned char* out, size_t* outl, WOLFPROV_ENTER(WP_LOG_COMP_MAC, "wp_gmac_final"); - if (!wolfssl_prov_is_running()) { + if ((macCtx->dataLen > 0xFFFFFFFFU) || (outSize > 0xFFFFFFFFU)) { + ok = 0; + } + if (ok && !wolfssl_prov_is_running()) { ok = 0; } if (ok && (outSize < AES_BLOCK_SIZE)) { From b30b492af5836522e76c9a5e8ee31b4128e520cd Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:34:04 -0700 Subject: [PATCH 30/82] F-5915 - Guard AES key-wrap input and output lengths against truncation --- src/wp_aes_wrap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp_aes_wrap.c b/src/wp_aes_wrap.c index 6dc36129..3abc7dd5 100644 --- a/src/wp_aes_wrap.c +++ b/src/wp_aes_wrap.c @@ -345,7 +345,10 @@ static int wp_aes_wrap_update(wp_AesWrapCtx *ctx, unsigned char *out, WOLFPROV_ENTER(WP_LOG_COMP_AES, "wp_aes_wrap_update"); - if (!wolfssl_prov_is_running()) { + if ((inLen > 0xFFFFFFFFU) || (outSize > 0xFFFFFFFFU)) { + ok = 0; + } + if (ok && !wolfssl_prov_is_running()) { ok = 0; } From 23d6779c0f1563c047d89032029fb512c3d88b40 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:34:20 -0700 Subject: [PATCH 31/82] F-4700 - Guard RSA encrypt input and output lengths against truncation --- src/wp_rsa_asym.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp_rsa_asym.c b/src/wp_rsa_asym.c index 364c1494..117514de 100644 --- a/src/wp_rsa_asym.c +++ b/src/wp_rsa_asym.c @@ -293,7 +293,10 @@ static int wp_rsaa_encrypt(wp_RsaAsymCtx* ctx, unsigned char* out, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsaa_encrypt"); - if (!wolfssl_prov_is_running()) { + if ((inLen > 0xFFFFFFFFU) || (outSize > 0xFFFFFFFFU)) { + ok = 0; + } + if (ok && !wolfssl_prov_is_running()) { ok = 0; } else if (!wp_rsa_check_key_size(ctx->rsa, 1)) { From 1dcca764853660d0067cd2723cf42746074633b3 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:34:34 -0700 Subject: [PATCH 32/82] F-5178 - Guard RSA decrypt input and output lengths against truncation --- src/wp_rsa_asym.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/wp_rsa_asym.c b/src/wp_rsa_asym.c index 117514de..3b5973c7 100644 --- a/src/wp_rsa_asym.c +++ b/src/wp_rsa_asym.c @@ -293,10 +293,14 @@ static int wp_rsaa_encrypt(wp_RsaAsymCtx* ctx, unsigned char* out, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsaa_encrypt"); - if ((inLen > 0xFFFFFFFFU) || (outSize > 0xFFFFFFFFU)) { + if ((inLen > 0xFFFFFFFFU) || + ((outSize != (size_t)-1) && (outSize > 0xFFFFFFFFU))) { ok = 0; } - if (ok && !wolfssl_prov_is_running()) { + if (!ok) { + /* Length guard already failed; skip the operation. */ + } + else if (!wolfssl_prov_is_running()) { ok = 0; } else if (!wp_rsa_check_key_size(ctx->rsa, 1)) { @@ -406,7 +410,14 @@ static int wp_rsaa_decrypt(wp_RsaAsymCtx* ctx, unsigned char* out, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsaa_decrypt"); - if (!wolfssl_prov_is_running()) { + if ((inLen > 0xFFFFFFFFU) || + ((outSize != (size_t)-1) && (outSize > 0xFFFFFFFFU))) { + ok = 0; + } + if (!ok) { + /* Length guard already failed; skip the operation. */ + } + else if (!wolfssl_prov_is_running()) { ok = 0; } else if (!wp_rsa_check_key_size(ctx->rsa, 1)) { From fb7d6a6444ad4ccbf8e131e1997901ea15e29a4e Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:36:09 -0700 Subject: [PATCH 33/82] F-4299 - Guard ECDH X9.63 KDF lengths against word32 truncation --- src/wp_ecdh_exch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp_ecdh_exch.c b/src/wp_ecdh_exch.c index b00d0a0b..5012a1f3 100644 --- a/src/wp_ecdh_exch.c +++ b/src/wp_ecdh_exch.c @@ -229,6 +229,11 @@ static int wp_ecdh_kdf_derive(wp_EcdhCtx* ctx, unsigned char* key, WOLFPROV_ENTER(WP_LOG_COMP_ECDH, "wp_ecdh_kdf_derive"); + if ((secLen > 0xFFFFFFFFU) || (ctx->ukmLen > 0xFFFFFFFFU) || + (ctx->keyLen > 0xFFFFFFFFU)) { + return 0; + } + if (keySize < ctx->keyLen) { ok = 0; } From 96c8d943b4e8f2499b23728828060cf9463e2f12 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:36:22 -0700 Subject: [PATCH 34/82] F-4382 - Guard DH secret length against word32 truncation --- src/wp_dh_exch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp_dh_exch.c b/src/wp_dh_exch.c index 7b9c4d44..66a19e1e 100644 --- a/src/wp_dh_exch.c +++ b/src/wp_dh_exch.c @@ -277,8 +277,11 @@ static int wp_dh_derive_secret(wp_DhCtx* ctx, unsigned char* secret, WOLFPROV_ENTER(WP_LOG_COMP_DH, "wp_dh_derive_secret"); + if (*secLen > 0xFFFFFFFFU) { + ok = 0; + } /* Get our private key data. */ - if (!wp_dh_get_priv(ctx->key, &priv, &privSz)) { + if (ok && (!wp_dh_get_priv(ctx->key, &priv, &privSz))) { ok = 0; } /* Get peer's public key data. */ From 4abeeeb4099d4259012cbab071270e5535852e41 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:37:04 -0700 Subject: [PATCH 35/82] F-4385 - Guard X25519/X448 shared-secret size against word32 truncation --- src/wp_ecx_exch.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/wp_ecx_exch.c b/src/wp_ecx_exch.c index c900fe42..cc28333a 100644 --- a/src/wp_ecx_exch.c +++ b/src/wp_ecx_exch.c @@ -230,7 +230,10 @@ static int wp_x25519_derive(wp_EcxCtx* ctx, unsigned char* secret, WOLFPROV_ENTER(WP_LOG_COMP_X25519, "wp_x25519_derive"); - if (!wolfssl_prov_is_running()) { + if (secSize > 0xFFFFFFFFU) { + ok = 0; + } + if (ok && !wolfssl_prov_is_running()) { ok = 0; } @@ -330,7 +333,10 @@ static int wp_x448_derive(wp_EcxCtx* ctx, unsigned char* secret, WOLFPROV_ENTER(WP_LOG_COMP_X448, "wp_x448_derive"); - if (!wolfssl_prov_is_running()) { + if (secSize > 0xFFFFFFFFU) { + ok = 0; + } + if (ok && !wolfssl_prov_is_running()) { ok = 0; } From d1aac47cbb0effeb763d4ae7d3eec36c5fbe247c Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:38:14 -0700 Subject: [PATCH 36/82] F-5199 - Guard XOF output length against word32 truncation --- src/wp_digests.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_digests.c b/src/wp_digests.c index 0c777eeb..6d18d472 100644 --- a/src/wp_digests.c +++ b/src/wp_digests.c @@ -640,7 +640,7 @@ static int name##_final(CTX* ctx, unsigned char* out, size_t* outLen, \ if (!wolfssl_prov_is_running()) { \ ok = 0; \ } \ - if (ok && (outSize < ctx->outLen)) { \ + if (ok && ((outSize < ctx->outLen) || (ctx->outLen > 0xFFFFFFFFU))) { \ ok = 0; \ } \ if (ok) { \ From ff22d4729b49a18c56037ca5f60332d4eaecefea Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:38:37 -0700 Subject: [PATCH 37/82] F-4293 - Guard TLS1-PRF key length against word32 truncation --- src/wp_tls1_prf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_tls1_prf.c b/src/wp_tls1_prf.c index 6d99db77..85b72577 100644 --- a/src/wp_tls1_prf.c +++ b/src/wp_tls1_prf.c @@ -166,6 +166,9 @@ static int wp_kdf_tls1_prf_derive(wp_Tls1Prf_Ctx* ctx, unsigned char* key, if (ok && (keyLen == 0)) { ok = 0; } + if (ok && (keyLen > 0xFFFFFFFFU)) { + ok = 0; + } if (ok) { int rc; From f146161f4bc497cacdf268cbe1bcb5a8191b488d Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:41:12 -0700 Subject: [PATCH 38/82] F-5181 - Guard ECDSA sign lengths against word32 truncation --- src/wp_ecdsa_sig.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp_ecdsa_sig.c b/src/wp_ecdsa_sig.c index 09833818..17c444fc 100644 --- a/src/wp_ecdsa_sig.c +++ b/src/wp_ecdsa_sig.c @@ -301,8 +301,11 @@ static int wp_ecdsa_sign(wp_EcdsaSigCtx *ctx, unsigned char *sig, if (sigSize == (size_t)-1) { sigSize = *sigLen; } + if ((sigSize > 0xFFFFFFFFU) || (tbsLen > 0xFFFFFFFFU)) { + ok = 0; + } len = (word32)sigSize; - if (wp_lock(wp_ecc_get_mutex(ctx->ecc)) != 1) { + if (ok && (wp_lock(wp_ecc_get_mutex(ctx->ecc)) != 1)) { ok = 0; } if (ok) { From 4cfad8877eb4970cbc64cd58f6aee2828ce044fe Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:41:58 -0700 Subject: [PATCH 39/82] F-5182 - Guard ECDSA verify lengths against word32 truncation --- src/wp_ecdsa_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_ecdsa_sig.c b/src/wp_ecdsa_sig.c index 17c444fc..c31bdcff 100644 --- a/src/wp_ecdsa_sig.c +++ b/src/wp_ecdsa_sig.c @@ -394,6 +394,9 @@ static int wp_ecdsa_verify(wp_EcdsaSigCtx *ctx, const unsigned char *sig, (tbsLen < WC_MIN_DIGEST_SIZE)) { ok = 0; } + else if ((sigLen > 0xFFFFFFFFU) || (tbsLen > 0xFFFFFFFFU)) { + ok = 0; + } else { int res; int rc = wc_ecc_verify_hash(sig, (word32)sigLen, tbs, (word32)tbsLen, From 27531f12304a56c9e3fd65283891eb2e15087c97 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:42:32 -0700 Subject: [PATCH 40/82] F-5183 - Guard ECDSA digest update length against word32 truncation --- src/wp_ecdsa_sig.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_ecdsa_sig.c b/src/wp_ecdsa_sig.c index c31bdcff..ddd6120c 100644 --- a/src/wp_ecdsa_sig.c +++ b/src/wp_ecdsa_sig.c @@ -583,6 +583,10 @@ static int wp_ecdsa_digest_signverify_update(wp_EcdsaSigCtx *ctx, WOLFPROV_ENTER(WP_LOG_COMP_ECDSA, "wp_ecdsa_digest_signverify_update"); + if (dataLen > 0xFFFFFFFFU) { + return 0; + } + int rc = wc_HashUpdate(&ctx->hash, #if LIBWOLFSSL_VERSION_HEX >= 0x05007004 ctx->hash.type, From 89290de36c6dafd27f7e8765563f91a99407889c Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:43:29 -0700 Subject: [PATCH 41/82] F-5193 - Guard Ed25519 sign length against word32 truncation --- src/wp_ecx_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_ecx_sig.c b/src/wp_ecx_sig.c index bf2306c1..d0a66779 100644 --- a/src/wp_ecx_sig.c +++ b/src/wp_ecx_sig.c @@ -399,6 +399,9 @@ static int wp_ed25519_digest_sign(wp_EcxSigCtx *ctx, unsigned char *sig, } } } + if (ok && (tbsLen > 0xFFFFFFFFU)) { + ok = 0; + } if (ok) { if (wp_lock(wp_ecx_get_mutex(ctx->ecx)) != 1) { ok = 0; From c3e90b594edb82782293c5d4b2521ea6a75e1c10 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:43:42 -0700 Subject: [PATCH 42/82] F-5194 - Guard Ed25519 verify lengths against word32 truncation --- src/wp_ecx_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_ecx_sig.c b/src/wp_ecx_sig.c index d0a66779..3374a837 100644 --- a/src/wp_ecx_sig.c +++ b/src/wp_ecx_sig.c @@ -465,6 +465,9 @@ static int wp_ed25519_digest_verify(wp_EcxSigCtx *ctx, unsigned char *sig, } } } + if (ok && ((sigLen > 0xFFFFFFFFU) || (tbsLen > 0xFFFFFFFFU))) { + ok = 0; + } if (ok) { int res = 0; int rc = wc_ed25519_verify_msg(sig, (word32)sigLen, tbs, (word32)tbsLen, From 8fbc1bc532f56475291acdc2ddfea79b89173668 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:43:59 -0700 Subject: [PATCH 43/82] F-5195 - Guard Ed448 sign length against word32 truncation --- src/wp_ecx_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_ecx_sig.c b/src/wp_ecx_sig.c index 3374a837..a4045f38 100644 --- a/src/wp_ecx_sig.c +++ b/src/wp_ecx_sig.c @@ -612,6 +612,9 @@ static int wp_ed448_digest_sign(wp_EcxSigCtx *ctx, unsigned char *sig, } } } + if (ok && (tbsLen > 0xFFFFFFFFU)) { + ok = 0; + } if (ok) { if (wp_lock(wp_ecx_get_mutex(ctx->ecx)) != 1) { ok = 0; From b8bc2981bf06d71ff504eb99af2b0a172833be2d Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:44:13 -0700 Subject: [PATCH 44/82] F-5196 - Guard Ed448 verify lengths against word32 truncation --- src/wp_ecx_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_ecx_sig.c b/src/wp_ecx_sig.c index a4045f38..6cb0cfe5 100644 --- a/src/wp_ecx_sig.c +++ b/src/wp_ecx_sig.c @@ -684,6 +684,9 @@ static int wp_ed448_digest_verify(wp_EcxSigCtx *ctx, unsigned char *sig, } } } + if (ok && ((sigLen > 0xFFFFFFFFU) || (tbsLen > 0xFFFFFFFFU))) { + ok = 0; + } if (ok) { int res = 0; int rc = wc_ed448_verify_msg(sig, (word32)sigLen, tbs, (word32)tbsLen, From ec6fd93885ae38dc4b63edbeae820bb3c286ff29 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:46:27 -0700 Subject: [PATCH 45/82] F-5187 - Guard RSA PKCS1 sign lengths against word32 truncation --- src/wp_rsa_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index cae8f2ce..2f5f6e77 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -650,6 +650,9 @@ static int wp_rsa_sign_pkcs1(wp_RsaSigCtx* ctx, unsigned char* sig, if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { ok = 0; } + if (ok && ((tbsLen > 0xFFFFFFFFU) || (sigSize > 0xFFFFFFFFU))) { + ok = 0; + } if (ok) { PRIVATE_KEY_UNLOCK(); rc = wc_RsaSSL_Sign(tbs, (word32)tbsLen, sig, (word32)sigSize, From 890471051f453a7ecd3ff0f40925416a7a52934f Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:46:41 -0700 Subject: [PATCH 46/82] F-5188 - Guard RSA PSS sign lengths against word32 truncation --- src/wp_rsa_sig.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index 2f5f6e77..cd06c2ce 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -647,10 +647,10 @@ static int wp_rsa_sign_pkcs1(wp_RsaSigCtx* ctx, unsigned char* sig, } } if (ok) { - if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { + if ((tbsLen > 0xFFFFFFFFU) || (sigSize > 0xFFFFFFFFU)) { ok = 0; } - if (ok && ((tbsLen > 0xFFFFFFFFU) || (sigSize > 0xFFFFFFFFU))) { + if (ok && (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1)) { ok = 0; } if (ok) { @@ -706,7 +706,10 @@ static int wp_rsa_sign_pss(wp_RsaSigCtx* ctx, unsigned char* sig, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsa_sign_pss"); if (ok) { - if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { + if ((tbsLen > 0xFFFFFFFFU) || (sigSize > 0xFFFFFFFFU)) { + ok = 0; + } + if (ok && (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1)) { ok = 0; } if (ok) { From ccb36cb79b1071a96ca01c601fbd1fde91b4ce59 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:47:06 -0700 Subject: [PATCH 47/82] F-5204 - Guard RSA X931 sign output size against word32 truncation --- src/wp_rsa_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index cd06c2ce..6f8f81f6 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -916,6 +916,9 @@ static int wp_rsa_sign_x931(wp_RsaSigCtx* ctx, unsigned char* sig, ok = 0; } } + if (ok && (sigSize > 0xFFFFFFFFU)) { + ok = 0; + } if (ok) { word32 len = (word32)sigSize; if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { From 45884e948ba800cd04cd086666cc1d2737f9abb6 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:47:41 -0700 Subject: [PATCH 48/82] F-5192 - Guard RSA digest update length against word32 truncation --- src/wp_rsa_sig.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index 6f8f81f6..4990bdae 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -1583,6 +1583,10 @@ static int wp_rsa_digest_signverify_update(wp_RsaSigCtx* ctx, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsa_digest_signverify_update"); + if (dataLen > 0xFFFFFFFFU) { + return 0; + } + int rc = wc_HashUpdate(&ctx->hash, #if LIBWOLFSSL_VERSION_HEX >= 0x05007004 ctx->hash.type, From da9073e6d9d57dbb05750811471dc033396b3a6d Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:47:58 -0700 Subject: [PATCH 49/82] F-5191 - Guard RSA verify-recover lengths against word32 truncation --- src/wp_rsa_sig.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index 4990bdae..91b81d34 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -1524,6 +1524,9 @@ static int wp_rsa_verify_recover(wp_RsaSigCtx* ctx, unsigned char* rout, ok = 0; } + if (ok && ((sigLen > 0xFFFFFFFFU) || (routsize > 0xFFFFFFFFU))) { + ok = 0; + } if (ok) { rc = wc_RsaSSL_Verify(sig, (word32)sigLen, rout, (word32)routsize, wp_rsa_get_key(ctx->rsa)); From 9c03c36b6a429e76bac94542e399afd869d72993 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:48:37 -0700 Subject: [PATCH 50/82] F-5189 - Guard RSA PKCS1 verify length against word32 truncation --- src/wp_rsa_sig.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index 91b81d34..65ec1ee8 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -1090,6 +1090,10 @@ static int wp_rsa_verify_pkcs1(wp_RsaSigCtx* ctx, const unsigned char* sig, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsa_verify_pkcs1"); + if (sigLen > 0xFFFFFFFFU) { + return 0; + } + rc = wc_RsaSSL_Verify(sig, (word32)sigLen, decryptedSig, (word32)sigLen, wp_rsa_get_key(ctx->rsa)); if (rc < 0) { From 00a9e85b9ad6dffaf16ad8b4eedcf24e72d7aca3 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:49:14 -0700 Subject: [PATCH 51/82] F-5190 - Guard RSA PSS verify length against word32 truncation --- src/wp_rsa_sig.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index 65ec1ee8..f9197d6b 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -1157,10 +1157,14 @@ static int wp_rsa_verify_pss(wp_RsaSigCtx* ctx, const unsigned char* sig, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsa_verify_pss"); + if (sigLen > 0xFFFFFFFFU) { + ok = 0; + } + #if LIBWOLFSSL_VERSION_HEX >= 0x05007004 - if (ctx->hash.type == WC_HASH_TYPE_NONE) + if (ok && (ctx->hash.type == WC_HASH_TYPE_NONE)) #else - if (ctx->hashType == WC_HASH_TYPE_NONE) + if (ok && (ctx->hashType == WC_HASH_TYPE_NONE)) #endif { ok = wp_rsa_setup_md(ctx, WP_RSA_DEFAULT_MD, NULL, EVP_PKEY_OP_VERIFY); From 5c93ef476c2a9fb59593b0e64c170fcfaecf0d47 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:50:33 -0700 Subject: [PATCH 52/82] F-835 - Use else-if for mutually exclusive ECDSA digest alg-id lookup --- src/wp_ecdsa_sig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp_ecdsa_sig.c b/src/wp_ecdsa_sig.c index ddd6120c..85886b5d 100644 --- a/src/wp_ecdsa_sig.c +++ b/src/wp_ecdsa_sig.c @@ -780,14 +780,14 @@ static int wp_ecdsa_digest_verify_final(wp_EcdsaSigCtx *ctx, unsigned char *sig, }; ok = OSSL_PARAM_set_octet_string(p, ecdsa_sha256, sizeof(ecdsa_sha256)); } - if ((XMEMCMP(ctx->mdName, "SHA384", 7) == 0) || + else if ((XMEMCMP(ctx->mdName, "SHA384", 7) == 0) || (XMEMCMP(ctx->mdName, "sha384", 7) == 0)) { static const unsigned char ecdsa_sha384[] = { 0x30, 0x0a, 0x06, 0x08, 42, 134, 72, 206, 61, 4, 3, 3 }; ok = OSSL_PARAM_set_octet_string(p, ecdsa_sha384, sizeof(ecdsa_sha384)); } - if ((XMEMCMP(ctx->mdName, "SHA512", 7) == 0) || + else if ((XMEMCMP(ctx->mdName, "SHA512", 7) == 0) || (XMEMCMP(ctx->mdName, "sha512", 7) == 0)) { static const unsigned char ecdsa_sha512[] = { 0x30, 0x0a, 0x06, 0x08, 42, 134, 72, 206, 61, 4, 3, 4 From 6daeae36ce705f5db04694ad9b0bbe24a10e654d Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:51:35 -0700 Subject: [PATCH 53/82] F-275 - Bound digest name copy to prevent buffer overflow --- src/wp_params.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wp_params.c b/src/wp_params.c index b7b02308..b4d0900c 100644 --- a/src/wp_params.c +++ b/src/wp_params.c @@ -247,7 +247,13 @@ int wp_params_get_digest(const OSSL_PARAM* params, char* name, const char* mdProps = NULL; if (name != NULL) { - XMEMCPY(name, mdName, XSTRLEN(mdName) + 1); + size_t nameLen = XSTRLEN(mdName); + + if (nameLen >= WP_MAX_MD_NAME_SIZE) { + nameLen = WP_MAX_MD_NAME_SIZE - 1; + } + XMEMCPY(name, mdName, nameLen); + name[nameLen] = '\0'; } if (ok && (type != NULL) && (!wp_params_get_utf8_string_ptr(params, OSSL_ALG_PARAM_PROPERTIES, &mdProps))) { From 010f2d540845b95c05461d0971665d668bf45050 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:52:05 -0700 Subject: [PATCH 54/82] F-3149 - Fix copy-pasted Ed25519/Ed448 keymgmt description strings --- src/wp_wolfprov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp_wolfprov.c b/src/wp_wolfprov.c index d92618ef..354b9def 100644 --- a/src/wp_wolfprov.c +++ b/src/wp_wolfprov.c @@ -631,11 +631,11 @@ static const OSSL_ALGORITHM wolfprov_keymgmt[] = { #ifdef WP_HAVE_ED25519 { WP_NAMES_ED25519, WOLFPROV_PROPERTIES, wp_ed25519_keymgmt_functions, - "X25519" }, + "ED25519" }, #endif #ifdef WP_HAVE_ED448 { WP_NAMES_ED448, WOLFPROV_PROPERTIES, wp_ed448_keymgmt_functions, - "X448" }, + "ED448" }, #endif #ifdef WP_HAVE_DH From 7ab6180ceaf39d4d377ff49bd25df0c7fdb9cc6b Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:53:02 -0700 Subject: [PATCH 55/82] F-3151 - Require exact CMAC cipher-name match to prevent prefix match --- src/wp_cmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wp_cmac.c b/src/wp_cmac.c index 9971edba..c309c3fc 100644 --- a/src/wp_cmac.c +++ b/src/wp_cmac.c @@ -419,8 +419,9 @@ static int wp_cmac_setup_cipher(wp_CmacCtx* macCtx, const OSSL_PARAM params[]) macCtx->size = AES_BLOCK_SIZE; for (i = 0; i < WP_CMAC_CIPHER_NAMES_LEN; i++) { - if (XSTRNCMP(p->data, wp_cmac_cipher_names[i].name, - p->data_size) == 0) { + if ((XSTRLEN(wp_cmac_cipher_names[i].name) == p->data_size) && + (XSTRNCMP(p->data, wp_cmac_cipher_names[i].name, + p->data_size) == 0)) { macCtx->expKeySize = wp_cmac_cipher_names[i].keySize; break; } From 78b7487b443b69c9e468adbdf726a239e52ae0fe Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:53:16 -0700 Subject: [PATCH 56/82] F-3152 - Require exact GMAC cipher-name match to prevent prefix match --- src/wp_gmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wp_gmac.c b/src/wp_gmac.c index 0ab10cfd..d1820d2b 100644 --- a/src/wp_gmac.c +++ b/src/wp_gmac.c @@ -420,8 +420,9 @@ static int wp_gmac_setup_cipher(wp_GmacCtx* macCtx, const OSSL_PARAM params[]) size_t i; for (i = 0; i < WP_GMAC_CIPHER_NAMES_LEN; i++) { - if (XSTRNCMP(p->data, wp_gmac_cipher_names[i].name, - p->data_size) == 0) { + if ((XSTRLEN(wp_gmac_cipher_names[i].name) == p->data_size) && + (XSTRNCMP(p->data, wp_gmac_cipher_names[i].name, + p->data_size) == 0)) { macCtx->expKeySize = wp_gmac_cipher_names[i].keySize; break; } From 482d0d42ea5b79debeba5b2aae493df8d2615196 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:53:34 -0700 Subject: [PATCH 57/82] F-3153 - Require exact cipher-name match to prevent prefix match --- src/wp_internal.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wp_internal.c b/src/wp_internal.c index 6eafb0e2..8c6260cc 100644 --- a/src/wp_internal.c +++ b/src/wp_internal.c @@ -885,8 +885,9 @@ int wp_cipher_from_params(const OSSL_PARAM params[], int* cipher, size_t i; for (i = 0; i < WP_CIPHER_NAMES_LEN; i++) { - if (XSTRNCMP(p->data, wp_cipher_names[i].name, - p->data_size) == 0) { + if ((XSTRLEN(wp_cipher_names[i].name) == p->data_size) && + (XSTRNCMP(p->data, wp_cipher_names[i].name, + p->data_size) == 0)) { *cipher = wp_cipher_names[i].id; if (cipherName != NULL) { *cipherName = wp_cipher_names[i].canonName; From 21a71d681348bf9f073ed990b253c1fdb5a9c7f0 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:55:05 -0700 Subject: [PATCH 58/82] F-2047 - Zeroize GCM temporary plaintext buffer before free --- src/wp_aes_aead.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_aes_aead.c b/src/wp_aes_aead.c index 9b13e102..b234206f 100644 --- a/src/wp_aes_aead.c +++ b/src/wp_aes_aead.c @@ -1544,7 +1544,7 @@ static int wp_aesgcm_encdec(wp_AeadCtx *ctx, unsigned char *out, size_t* outLen, XMEMCPY(out, tmp + offset, (ctx->inLen - offset)); *outLen = (ctx->inLen - offset); } - OPENSSL_free(tmp); + OPENSSL_clear_free(tmp, ctx->inLen); } else { *outLen = 0; From 094a3cdaaaa7dc5960a975f9a9d5d91e4325d9d9 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:55:30 -0700 Subject: [PATCH 59/82] F-3173 - Zeroize accumulated GCM input buffer before free --- src/wp_aes_aead.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_aes_aead.c b/src/wp_aes_aead.c index b234206f..1b358c04 100644 --- a/src/wp_aes_aead.c +++ b/src/wp_aes_aead.c @@ -1554,7 +1554,7 @@ static int wp_aesgcm_encdec(wp_AeadCtx *ctx, unsigned char *out, size_t* outLen, ctx->aad = NULL; ctx->aadLen = 0; ctx->aadSet = 0; - OPENSSL_free(ctx->in); + OPENSSL_clear_free(ctx->in, ctx->inLen); ctx->bufSize = 0; ctx->in = NULL; ctx->inLen = 0; From 06b36320b4863d791602b77ee50c59be6e5ee1a4 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 13:56:36 -0700 Subject: [PATCH 60/82] F-3170 - Zeroize AES-CTS scratch buffers before return --- src/wp_aes_stream.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp_aes_stream.c b/src/wp_aes_stream.c index 38c9f29a..de0dcbfd 100644 --- a/src/wp_aes_stream.c +++ b/src/wp_aes_stream.c @@ -438,6 +438,8 @@ static int wp_aes_cts_encrypt(wp_AesStreamCtx *ctx, unsigned char *out, XMEMCPY(out + AES_BLOCK_SIZE, ctsBlock, inLen - AES_BLOCK_SIZE); } + OPENSSL_cleanse(ctsBlock, sizeof(ctsBlock)); + return ok; } @@ -505,6 +507,9 @@ static int wp_aes_cts_decrypt(wp_AesStreamCtx *ctx, unsigned char *out, } } + OPENSSL_cleanse(ctsBlock, sizeof(ctsBlock)); + OPENSSL_cleanse(tmp, sizeof(tmp)); + return ok; } From 293b9d4654faf18b0fda0ba76af6ac9ac1b180cf Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:01:37 -0700 Subject: [PATCH 61/82] F-6068 - Use consistent allocator for DRBG rng to fix free mismatch --- src/wp_drbg.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/wp_drbg.c b/src/wp_drbg.c index a92188f8..f3c6f71f 100644 --- a/src/wp_drbg.c +++ b/src/wp_drbg.c @@ -138,12 +138,8 @@ static void wp_drbg_free(wp_DrbgCtx* ctx) OPENSSL_free(ctx->mutex); } #endif - #if LIBWOLFSSL_VERSION_HEX >= 0x05000000 - (void)wc_rng_free(ctx->rng); - #else wc_FreeRng(ctx->rng); OPENSSL_clear_free(ctx->rng, sizeof(*ctx->rng)); - #endif OPENSSL_free(ctx); } } @@ -235,28 +231,20 @@ static int wp_drbg_instantiate(wp_DrbgCtx* ctx, unsigned int strength, WOLFPROV_MSG_DEBUG(WP_LOG_COMP_RNG, "No parent DRBG, using direct seeding"); - #if LIBWOLFSSL_VERSION_HEX >= 0x05000000 - ctx->rng = wc_rng_new((byte*)pStr, (word32)pStrLen, NULL); - if (ctx->rng == NULL) { - ok = 0; - } - #else - (void)pStr; - (void)pStrLen; - + /* wc_InitRngNonce (not wc_rng_new) keeps rng on the OPENSSL allocator to match the parent path's free. */ ctx->rng = OPENSSL_zalloc(sizeof(*ctx->rng)); if (ctx->rng == NULL) { ok = 0; } if (ok) { - int rc = wc_InitRng(ctx->rng); + int rc = wc_InitRngNonce(ctx->rng, (byte*)pStr, (word32)pStrLen); if (rc != 0) { - WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, "wc_InitRng", rc); + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_COMP_RNG, "wc_InitRngNonce", rc); OPENSSL_clear_free(ctx->rng, sizeof(*ctx->rng)); + ctx->rng = NULL; ok = 0; } } - #endif } #ifndef WP_HAVE_DRBG_RESEED @@ -279,12 +267,8 @@ static int wp_drbg_uninstantiate(wp_DrbgCtx* ctx) { WOLFPROV_ENTER(WP_LOG_COMP_RNG, "wp_drbg_uninstantiate"); -#if LIBWOLFSSL_VERSION_HEX >= 0x05000000 - (void)wc_rng_free(ctx->rng); -#else wc_FreeRng(ctx->rng); OPENSSL_clear_free(ctx->rng, sizeof(*ctx->rng)); -#endif ctx->rng = NULL; #ifndef WP_HAVE_DRBG_RESEED ctx->rngError = 0; From b7b85b71ab460207eb33a9d0826e351c07239910 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:04:30 -0700 Subject: [PATCH 62/82] F-6681 - Free up-referenced core BIO in ECX and ML-DSA encoders --- src/wp_ecx_kmgmt.c | 1 + src/wp_mldsa_kmgmt.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index 642044ef..812e3989 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -2240,6 +2240,7 @@ static int wp_ecx_encode(wp_EcxEncDecCtx* ctx, OSSL_CORE_BIO *cBio, OPENSSL_free(pemData); } OPENSSL_free(cipherInfo); + BIO_free(out); WOLFPROV_LEAVE(WP_LOG_COMP_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; } diff --git a/src/wp_mldsa_kmgmt.c b/src/wp_mldsa_kmgmt.c index 45eb4680..5faceac4 100644 --- a/src/wp_mldsa_kmgmt.c +++ b/src/wp_mldsa_kmgmt.c @@ -1574,6 +1574,7 @@ static int wp_mldsa_encode(wp_MlDsaEncDecCtx* ctx, OSSL_CORE_BIO* cBio, OPENSSL_free(pemData); } OPENSSL_free(cipherInfo); + BIO_free(out); WOLFPROV_LEAVE(WP_LOG_COMP_PQC, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; } From 6646ca10422ec1c583a1d450bfdca707edd243b5 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:06:10 -0700 Subject: [PATCH 63/82] F-3167 - Reject CMAC key that mismatches the configured cipher key size --- src/wp_cmac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_cmac.c b/src/wp_cmac.c index c309c3fc..241cba8b 100644 --- a/src/wp_cmac.c +++ b/src/wp_cmac.c @@ -120,6 +120,9 @@ static int wp_cmac_set_key(wp_CmacCtx* macCtx, const unsigned char* key, if (keyLen > AES_256_KEY_SIZE) { ok = 0; } + if (ok && (macCtx->expKeySize != 0) && (keyLen != macCtx->expKeySize)) { + ok = 0; + } if (ok) { if (macCtx->keyLen > 0) { OPENSSL_cleanse(macCtx->key, macCtx->keyLen); From c2b2fa15a0c692f5359ff0a893476cf56c6df264 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:06:10 -0700 Subject: [PATCH 64/82] F-3168 - Reject GMAC key that mismatches the configured cipher key size --- src/wp_gmac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp_gmac.c b/src/wp_gmac.c index d1820d2b..785f8c25 100644 --- a/src/wp_gmac.c +++ b/src/wp_gmac.c @@ -123,6 +123,9 @@ static int wp_gmac_set_key(wp_GmacCtx* macCtx, const unsigned char *key, if (keyLen > AES_256_KEY_SIZE) { ok = 0; } + if (ok && (macCtx->expKeySize != 0) && (keyLen != macCtx->expKeySize)) { + ok = 0; + } if (ok) { if (macCtx->keyLen > 0) { OPENSSL_cleanse(macCtx->key, macCtx->keyLen); From 4e2a54992f9889ca1cfaaa67c8a66ee4f18f3290 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:10:28 -0700 Subject: [PATCH 65/82] F-3159 - Track and enforce RSA KEM operation to prevent direction confusion --- src/wp_rsa_kem.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/wp_rsa_kem.c b/src/wp_rsa_kem.c index 10f81eef..31dbfc8b 100644 --- a/src/wp_rsa_kem.c +++ b/src/wp_rsa_kem.c @@ -51,6 +51,9 @@ typedef struct wp_RsaKemCtx { /** Type of pperation being performed. */ int op; + + /** EVP operation (encapsulate/decapsulate) this ctx was initialized for. */ + int operation; } wp_RsaKemCtx; @@ -127,6 +130,7 @@ static wp_RsaKemCtx* wp_rsakem_ctx_dup(wp_RsaKemCtx* srcCtx) if (ok) { dstCtx->rsa = srcCtx->rsa; dstCtx->op = srcCtx->op; + dstCtx->operation = srcCtx->operation; } if (!ok) { @@ -153,8 +157,7 @@ static int wp_rsakem_init(wp_RsaKemCtx* ctx, wp_Rsa* rsa, { int ok = 1; - /* TODO: check key type and size with operation. */ - (void)operation; + ctx->operation = operation; WP_CHECK_FIPS_ALGO(WP_CAST_ALGO_RSA); @@ -391,6 +394,10 @@ static int wp_rsakem_encapsulate(wp_RsaKemCtx* ctx, unsigned char* out, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsakem_encapsulate"); + if (ctx->operation != EVP_PKEY_OP_ENCAPSULATE) { + return 0; + } + switch (ctx->op) { case WP_RSA_KEM_OP_RSASVE: ok = wp_rsasve_generate(ctx, out, outlen, secret, secretlen); @@ -486,6 +493,10 @@ static int wp_rsakem_decapsulate(wp_RsaKemCtx* ctx, unsigned char* out, WOLFPROV_ENTER(WP_LOG_COMP_RSA, "wp_rsakem_decapsulate"); + if (ctx->operation != EVP_PKEY_OP_DECAPSULATE) { + return 0; + } + switch (ctx->op) { case WP_RSA_KEM_OP_RSASVE: ok = wp_rsasve_recover(ctx, out, outlen, in, inlen); From c9384699f1894a83f3aaad5eb925bb10961b0709 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:12:10 -0700 Subject: [PATCH 66/82] F-2795 - Use constant-time compare for ECX private key match --- src/wp_ecx_kmgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index 812e3989..003ca6d6 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -739,7 +739,7 @@ static int wp_ecx_match_priv_key(const wp_Ecx* ecx1, const wp_Ecx* ecx2) if (ok && (len1 != len2)) { ok = 0; } - if (ok && (XMEMCMP(key1, key2, len1) != 0)) { + if (ok && (CRYPTO_memcmp(key1, key2, len1) != 0)) { ok = 0; } From b7139d6488a25eeafabcfd84e98f23e2f2ca1638 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:12:43 -0700 Subject: [PATCH 67/82] F-6673 - Use constant-time compare for ML-DSA private key match --- src/wp_mldsa_kmgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_mldsa_kmgmt.c b/src/wp_mldsa_kmgmt.c index 5faceac4..3535db97 100644 --- a/src/wp_mldsa_kmgmt.c +++ b/src/wp_mldsa_kmgmt.c @@ -531,7 +531,7 @@ static int wp_mldsa_match(const wp_MlDsa* a, const wp_MlDsa* b, int selection) ok = 0; } } - if (ok && ((lenA != lenB) || (XMEMCMP(bufA, bufB, lenA) != 0))) { + if (ok && ((lenA != lenB) || (CRYPTO_memcmp(bufA, bufB, lenA) != 0))) { ok = 0; } /* Zero full allocations even if export truncated the out lengths. */ From 39c431ace3d2dbeed8e3f63e25c0034654a91580 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:14:16 -0700 Subject: [PATCH 68/82] F-515 - Decrement RSA refcount only under held mutex --- src/wp_rsa_kmgmt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index 2dbc001c..d8287030 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -530,10 +530,14 @@ void wp_rsa_free(wp_Rsa* rsa) int rc; rc = wc_LockMutex(&rsa->mutex); - cnt = --rsa->refCnt; if (rc == 0) { + cnt = --rsa->refCnt; wc_UnLockMutex(&rsa->mutex); } + else { + /* Cannot safely decrement without the lock; keep the object. */ + cnt = rsa->refCnt; + } #else cnt = --rsa->refCnt; #endif From 927b7f1dbfb0afdc14cd9691f02bd1fd5d9bd863 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:15:45 -0700 Subject: [PATCH 69/82] F-1283 - Decrement ECC refcount only under held mutex --- src/wp_ecc_kmgmt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/wp_ecc_kmgmt.c b/src/wp_ecc_kmgmt.c index 3d5bd74d..1ee73e16 100644 --- a/src/wp_ecc_kmgmt.c +++ b/src/wp_ecc_kmgmt.c @@ -406,13 +406,15 @@ void wp_ecc_free(wp_Ecc* ecc) int rc; rc = wc_LockMutex(&ecc->mutex); - if (rc < 0) { - WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_LockMutex", rc); - } - cnt = --ecc->refCnt; if (rc == 0) { + cnt = --ecc->refCnt; wc_UnLockMutex(&ecc->mutex); } + else { + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_LockMutex", rc); + /* Cannot safely decrement without the lock; keep the object. */ + cnt = ecc->refCnt; + } #else cnt = --ecc->refCnt; #endif From ca9322974591a8eca1e3aca8c274d59c3343ec15 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:15:45 -0700 Subject: [PATCH 70/82] F-1284 - Decrement ECX refcount only under held mutex --- src/wp_ecx_kmgmt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index 003ca6d6..d1e3af79 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -323,13 +323,15 @@ void wp_ecx_free(wp_Ecx* ecx) int rc; rc = wc_LockMutex(&ecx->mutex); - if (rc < 0) { - WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_LockMutex", rc); - } - cnt = --ecx->refCnt; if (rc == 0) { + cnt = --ecx->refCnt; wc_UnLockMutex(&ecx->mutex); } + else { + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_LockMutex", rc); + /* Cannot safely decrement without the lock; keep the object. */ + cnt = ecx->refCnt; + } #else cnt = --ecx->refCnt; #endif From 5e144b8fb5caec05faff5e3c9907e4f4075bea85 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:15:45 -0700 Subject: [PATCH 71/82] F-1285 - Decrement DH refcount only under held mutex --- src/wp_dh_kmgmt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/wp_dh_kmgmt.c b/src/wp_dh_kmgmt.c index de8cb430..c2fa8c6a 100644 --- a/src/wp_dh_kmgmt.c +++ b/src/wp_dh_kmgmt.c @@ -450,13 +450,15 @@ void wp_dh_free(wp_Dh* dh) int rc; rc = wc_LockMutex(&dh->mutex); - if (rc < 0) { - WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_LockMutex", rc); - } - cnt = --dh->refCnt; if (rc == 0) { + cnt = --dh->refCnt; wc_UnLockMutex(&dh->mutex); } + else { + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_LockMutex", rc); + /* Cannot safely decrement without the lock; keep the object. */ + cnt = dh->refCnt; + } #else cnt = --dh->refCnt; #endif From b7f256a132f8641b10a789e9f276b9de956cad4b Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:15:45 -0700 Subject: [PATCH 72/82] F-840 - Decrement KDF refcount only under held mutex --- src/wp_kdf_kmgmt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wp_kdf_kmgmt.c b/src/wp_kdf_kmgmt.c index 69a2420a..c208a6a1 100644 --- a/src/wp_kdf_kmgmt.c +++ b/src/wp_kdf_kmgmt.c @@ -126,10 +126,14 @@ void wp_kdf_free(wp_Kdf* kdf) int rc; rc = wc_LockMutex(&kdf->mutex); - cnt = --kdf->refCnt; if (rc == 0) { + cnt = --kdf->refCnt; wc_UnLockMutex(&kdf->mutex); } + else { + /* Cannot safely decrement without the lock; keep the object. */ + cnt = kdf->refCnt; + } #else cnt = --kdf->refCnt; #endif From 3974cd59a3b728d11970f85bf0421b902e44cf6b Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:15:45 -0700 Subject: [PATCH 73/82] F-6671 - Decrement ML-DSA refcount only under held mutex --- src/wp_mldsa_kmgmt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wp_mldsa_kmgmt.c b/src/wp_mldsa_kmgmt.c index 3535db97..14eba6c4 100644 --- a/src/wp_mldsa_kmgmt.c +++ b/src/wp_mldsa_kmgmt.c @@ -284,10 +284,14 @@ void wp_mldsa_free(wp_MlDsa* mldsa) int rc; rc = wc_LockMutex(&mldsa->mutex); - cnt = --mldsa->refCnt; if (rc == 0) { + cnt = --mldsa->refCnt; wc_UnLockMutex(&mldsa->mutex); } + else { + /* Cannot safely decrement without the lock; keep the object. */ + cnt = mldsa->refCnt; + } #else cnt = --mldsa->refCnt; #endif From ad9306cc305104644796b7ec163c6eca0918bdee Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:16:48 -0700 Subject: [PATCH 74/82] F-2805 - Set RSA hasPriv only when private exponent is imported --- src/wp_rsa_kmgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index d8287030..7dbf6ff1 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -1609,7 +1609,7 @@ static int wp_rsa_import(wp_Rsa* rsa, int selection, const OSSL_PARAM params[]) if (ok) { rsa->bits = mp_count_bits(&rsa->key.n); rsa->hasPub = importPub; - rsa->hasPriv = importPriv; + rsa->hasPriv = importPriv && !mp_iszero((mp_int*)&rsa->key.d); } WOLFPROV_LEAVE(WP_LOG_COMP_RSA, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); From fc736f6cb188d84491bd31451588804e8b8f27e2 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:18:22 -0700 Subject: [PATCH 75/82] F-1287 - Hold key mutex around ECC validate type override --- src/wp_ecc_kmgmt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp_ecc_kmgmt.c b/src/wp_ecc_kmgmt.c index 1ee73e16..a0658bd4 100644 --- a/src/wp_ecc_kmgmt.c +++ b/src/wp_ecc_kmgmt.c @@ -1058,6 +1058,8 @@ static int wp_ecc_validate(const wp_Ecc* ecc, int selection, int checkType) (void)checkType; #endif { + int locked = (wp_lock(wp_ecc_get_mutex((wp_Ecc*)ecc)) == 1); + /* We may have a private key inside that does not match the public * key that has been set, which is OK. Override the internal type * to force a public key only check */ @@ -1065,6 +1067,9 @@ static int wp_ecc_validate(const wp_Ecc* ecc, int selection, int checkType) ((wp_Ecc*)ecc)->key.type = ECC_PUBLICKEY; rc = wc_ecc_check_key((ecc_key*)&ecc->key); ((wp_Ecc*)ecc)->key.type = origType; + if (locked) { + wp_unlock(wp_ecc_get_mutex((wp_Ecc*)ecc)); + } if (rc != 0) { WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_ecc_check_key", rc); ok = 0; From 836402a68f30bc47588d0bd981fdd89f5535652b Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:21:39 -0700 Subject: [PATCH 76/82] F-177 - Serialize RSA blinding RNG on shared key with key mutex --- src/wp_rsa_asym.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/wp_rsa_asym.c b/src/wp_rsa_asym.c index 3b5973c7..24ce7730 100644 --- a/src/wp_rsa_asym.c +++ b/src/wp_rsa_asym.c @@ -433,17 +433,26 @@ static int wp_rsaa_decrypt(wp_RsaAsymCtx* ctx, unsigned char* out, } else { int rc = 0; +#ifdef WC_RSA_BLINDING + int locked = 0; +#endif if (outSize == (size_t)-1) { outSize = *outLen; } #ifdef WC_RSA_BLINDING - /* TODO: not thread safe */ - rc = wc_RsaSetRNG(wp_rsa_get_key(ctx->rsa), &ctx->rng); - if (rc != 0) { - WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_RsaSetRNG", rc); + /* Fail closed if the key mutex can't be held for the shared-key RNG. */ + if (wp_lock(wp_rsa_get_mutex(ctx->rsa)) != 1) { ok = 0; } + else { + locked = 1; + rc = wc_RsaSetRNG(wp_rsa_get_key(ctx->rsa), &ctx->rng); + if (rc != 0) { + WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_RsaSetRNG", rc); + ok = 0; + } + } if (!ok) { } else @@ -538,7 +547,10 @@ static int wp_rsaa_decrypt(wp_RsaAsymCtx* ctx, unsigned char* out, ok = 0; } #ifdef WC_RSA_BLINDING - wc_RsaSetRNG(wp_rsa_get_key(ctx->rsa), NULL); + if (locked) { + wc_RsaSetRNG(wp_rsa_get_key(ctx->rsa), NULL); + wp_unlock(wp_rsa_get_mutex(ctx->rsa)); + } #endif if (ok) { *outLen = rc; From 677f8d32fe4b57bf211da5ff4699aefd15e405e2 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:25:06 -0700 Subject: [PATCH 77/82] F-3150 - Use format specifier for hex-dump line to prevent format-string injection --- src/wp_logging.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_logging.c b/src/wp_logging.c index cad93e44..74fc0155 100644 --- a/src/wp_logging.c +++ b/src/wp_logging.c @@ -454,7 +454,7 @@ void WOLFPROV_BUFFER(int component, const unsigned char* buffer, } } - wolfprovider_msg(component, WP_LOG_LEVEL_VERBOSE, line); + wolfprovider_msg(component, WP_LOG_LEVEL_VERBOSE, "%s", line); buffer += WOLFPROV_LINE_LEN; buflen -= WOLFPROV_LINE_LEN; } From af2b700fcea6475d1d9951bb6217bb5e301b4e3a Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:25:44 -0700 Subject: [PATCH 78/82] F-5540 - Guard AEAD cached AAD length against overflow before realloc --- src/wp_aes_aead.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/wp_aes_aead.c b/src/wp_aes_aead.c index 1b358c04..ff2d9988 100644 --- a/src/wp_aes_aead.c +++ b/src/wp_aes_aead.c @@ -290,10 +290,15 @@ static int wp_aead_cache_aad(wp_AeadCtx *ctx, const unsigned char *in, WOLFPROV_ENTER(WP_LOG_COMP_AES, "wp_aead_cache_aad"); if (inLen > 0) { - p = (unsigned char*)OPENSSL_realloc(ctx->aad, ctx->aadLen + inLen); - if (p == NULL) { + if (inLen > 0xFFFFFFFFU - ctx->aadLen) { ok = 0; } + if (ok) { + p = (unsigned char*)OPENSSL_realloc(ctx->aad, ctx->aadLen + inLen); + if (p == NULL) { + ok = 0; + } + } if (ok) { ctx->aad = p; XMEMCPY(ctx->aad + ctx->aadLen, in, inLen); From 4860c146373a8c175aae37f0c1249a1f71caf143 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:26:36 -0700 Subject: [PATCH 79/82] F-4538 - Advertise DRBG STATE param as int to match how it is set --- src/wp_drbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp_drbg.c b/src/wp_drbg.c index f3c6f71f..4b53b16d 100644 --- a/src/wp_drbg.c +++ b/src/wp_drbg.c @@ -611,7 +611,7 @@ static const OSSL_PARAM* wp_drbg_gettable_ctx_params(wp_DrbgCtx* ctx, */ static const OSSL_PARAM wp_supported_gettable_drbg_ctx_params[] = { OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL), - OSSL_PARAM_size_t(OSSL_RAND_PARAM_STATE, NULL), + OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL), OSSL_PARAM_END }; (void)ctx; From adeaff2e7693300727b3df4e7585964796d76d90 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:27:33 -0700 Subject: [PATCH 80/82] F-3840 - Honor advertised KBKDF LABEL param in set_ctx_params --- src/wp_kbkdf.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/wp_kbkdf.c b/src/wp_kbkdf.c index d1600cc3..3b052a9d 100644 --- a/src/wp_kbkdf.c +++ b/src/wp_kbkdf.c @@ -254,6 +254,18 @@ static int wp_kdf_kbkdf_set_ctx_params(wp_KbkdfCtx* ctx, } } + if (ok) { + p = OSSL_PARAM_locate((OSSL_PARAM*)params, OSSL_KDF_PARAM_LABEL); + if ((p != NULL) && (p->data != NULL)) { + OPENSSL_free(ctx->label); + ctx->label = NULL; + if (!OSSL_PARAM_get_octet_string(p, (void**)&ctx->label, 0, + &ctx->labelLen)) { + ok = 0; + } + } + } + if (ok) { p = OSSL_PARAM_locate((OSSL_PARAM*)params, OSSL_KDF_PARAM_INFO); if ((p != NULL) && (p->data != NULL)) { From 804f1e1d76d0064edff2f33dcccf1c0c50ea1e65 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 14:30:23 -0700 Subject: [PATCH 81/82] F-4548 - Do not fail RSA get_ctx_params when alg-id digest is unencodable --- src/wp_rsa_sig.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp_rsa_sig.c b/src/wp_rsa_sig.c index f9197d6b..8b4e6fb8 100644 --- a/src/wp_rsa_sig.c +++ b/src/wp_rsa_sig.c @@ -1976,7 +1976,10 @@ static int wp_rsa_get_ctx_params(wp_RsaSigCtx* ctx, OSSL_PARAM* params) if (ok) { p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); if (p != NULL) { - ok = wp_rsa_get_alg_id(ctx, p); + /* An unencodable digest must not fail the whole get; mark it empty. */ + if (!wp_rsa_get_alg_id(ctx, p)) { + p->return_size = 0; + } } } From 6baabe70dd4241b53fd17a29f2a2ad44a36b0f37 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Fri, 10 Jul 2026 19:46:09 -0700 Subject: [PATCH 82/82] ci: resolve refs without jq for containers that lack it --- scripts/resolve-ref.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/resolve-ref.sh b/scripts/resolve-ref.sh index 7c2a86ac..05170f2b 100755 --- a/scripts/resolve-ref.sh +++ b/scripts/resolve-ref.sh @@ -38,7 +38,12 @@ else exit 1 fi - sha=$(echo "$body" | jq -r .sha) + # OSP container images (e.g. sssd) ship without jq; fall back to grep. + if command -v jq >/dev/null 2>&1; then + sha=$(printf '%s' "$body" | jq -r .sha) + else + sha=$(printf '%s' "$body" | grep -o '"sha"[[:space:]]*:[[:space:]]*"[0-9a-f]\{40\}"' | head -n1 | grep -o '[0-9a-f]\{40\}') + fi if [[ -z "$sha" || "$sha" == "null" ]]; then echo "resolve-ref: no sha for $REF in $REPO" >&2 exit 1