From 19a9670aaa790afea6b2ad4ff8df63e159b779ff Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 8 Jun 2026 17:37:13 -0500 Subject: [PATCH 01/13] fix F-1234: IS_ERR Used on NULL-Returning Kernel Crypto Request Allocation Functions. --- linuxkm/lkcapi_aes_glue.c | 22 ++++++++++------------ linuxkm/lkcapi_dh_glue.c | 8 ++------ linuxkm/lkcapi_ecdh_glue.c | 8 ++------ linuxkm/lkcapi_ecdsa_glue.c | 8 ++------ linuxkm/lkcapi_rsa_glue.c | 12 ++++-------- 5 files changed, 20 insertions(+), 38 deletions(-) diff --git a/linuxkm/lkcapi_aes_glue.c b/linuxkm/lkcapi_aes_glue.c index 574c7d20de..6bd68978e0 100644 --- a/linuxkm/lkcapi_aes_glue.c +++ b/linuxkm/lkcapi_aes_glue.c @@ -3118,10 +3118,10 @@ static int linuxkm_test_aescbc(void) } req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES skcipher request %s failed\n", WOLFKM_AESCBC_DRIVER); - req = NULL; goto test_cbc_end; } @@ -3320,10 +3320,10 @@ static int linuxkm_test_aescfb(void) } req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES skcipher request %s failed\n", WOLFKM_AESCFB_DRIVER); - req = NULL; goto test_cfb_end; } @@ -3586,10 +3586,10 @@ static int linuxkm_test_aesgcm(void) } req = aead_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES aead request %s failed: %ld\n", WOLFKM_AESCBC_DRIVER, PTR_ERR(req)); - req = NULL; goto test_gcm_end; } @@ -4209,11 +4209,10 @@ static int aes_xts_128_test(void) } req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { - ret = PTR_ERR(req); + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES skcipher request %s failed: %d\n", WOLFKM_AESXTS_DRIVER, ret); - req = NULL; goto test_xts_end; } @@ -4690,11 +4689,10 @@ static int aes_xts_256_test(void) } req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { - ret = PTR_ERR(req); + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES skcipher request %s failed: %d\n", WOLFKM_AESXTS_DRIVER, ret); - req = NULL; goto test_xts_end; } diff --git a/linuxkm/lkcapi_dh_glue.c b/linuxkm/lkcapi_dh_glue.c index 581776b230..5fb3dd2ffd 100644 --- a/linuxkm/lkcapi_dh_glue.c +++ b/linuxkm/lkcapi_dh_glue.c @@ -2878,14 +2878,10 @@ static int linuxkm_test_kpp_driver(const char * driver, } req = kpp_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + test_rc = -ENOMEM; pr_err("error: allocating kpp request %s failed\n", driver); - if (PTR_ERR(req) == -ENOMEM) - test_rc = MEMORY_E; - else - test_rc = BAD_FUNC_ARG; - req = NULL; goto test_kpp_end; } diff --git a/linuxkm/lkcapi_ecdh_glue.c b/linuxkm/lkcapi_ecdh_glue.c index 24755917a5..f562285306 100644 --- a/linuxkm/lkcapi_ecdh_glue.c +++ b/linuxkm/lkcapi_ecdh_glue.c @@ -905,14 +905,10 @@ static int linuxkm_test_ecdh_nist_driver(const char * driver, } req = kpp_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + test_rc = -ENOMEM; pr_err("error: allocating kpp request %s failed\n", driver); - if (PTR_ERR(req) == -ENOMEM) - test_rc = MEMORY_E; - else - test_rc = BAD_FUNC_ARG; - req = NULL; goto test_ecdh_nist_end; } diff --git a/linuxkm/lkcapi_ecdsa_glue.c b/linuxkm/lkcapi_ecdsa_glue.c index 13a0e90be5..62e2eca120 100644 --- a/linuxkm/lkcapi_ecdsa_glue.c +++ b/linuxkm/lkcapi_ecdsa_glue.c @@ -763,14 +763,10 @@ static int linuxkm_test_ecdsa_nist_driver(const char * driver, } req = akcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + test_rc = -ENOMEM; pr_err("error: allocating akcipher request %s failed\n", driver); - if (PTR_ERR(req) == -ENOMEM) - test_rc = MEMORY_E; - else - test_rc = BAD_FUNC_ARG; - req = NULL; goto test_ecdsa_nist_end; } diff --git a/linuxkm/lkcapi_rsa_glue.c b/linuxkm/lkcapi_rsa_glue.c index ac7f8ff5c7..f76a8cbee9 100644 --- a/linuxkm/lkcapi_rsa_glue.c +++ b/linuxkm/lkcapi_rsa_glue.c @@ -2267,10 +2267,10 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) } req = akcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + ret = -ENOMEM; pr_err("error: allocating akcipher request %s failed\n", driver); - req = NULL; goto test_rsa_end; } @@ -2694,14 +2694,10 @@ static int linuxkm_test_pkcs1pad_driver(const char * driver, int nbits, } req = akcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + test_rc = -ENOMEM; pr_err("error: allocating akcipher request %s failed\n", driver); - if (PTR_ERR(req) == -ENOMEM) - test_rc = MEMORY_E; - else - test_rc = BAD_FUNC_ARG; - req = NULL; goto test_pkcs1_end; } From 05fc258ca2ea1a8fc8355dae2dd6fc32f36bd12a Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 8 Jun 2026 18:01:51 -0500 Subject: [PATCH 02/13] fix F-1423: AES-XTS Encrypt/Decrypt Missing skcipher_walk Cleanup on 6 Early-Return Error Paths --- linuxkm/lkcapi_aes_glue.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/linuxkm/lkcapi_aes_glue.c b/linuxkm/lkcapi_aes_glue.c index 6bd68978e0..7166d19a79 100644 --- a/linuxkm/lkcapi_aes_glue.c +++ b/linuxkm/lkcapi_aes_glue.c @@ -2079,9 +2079,6 @@ static int ccmAesAead_rfc4309_loaded = 0; #endif /* LINUXKM_LKCAPI_REGISTER_AESCCM || LINUXKM_LKCAPI_REGISTER_AESCCM_RFC4309 */ - - - #ifdef LINUXKM_LKCAPI_REGISTER_AESXTS #ifndef WOLFSSL_AESXTS_STREAM @@ -2193,7 +2190,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsEncrypt failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, 0); @@ -2228,7 +2226,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsEncryptInit failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } while ((nbytes = walk.nbytes) != 0) { @@ -2250,7 +2249,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsEncryptUpdate failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); @@ -2284,7 +2284,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsEncryptFinal failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, 0); @@ -2298,6 +2299,11 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) req->cryptlen); #endif /* WOLFKM_DEBUG_AES */ +out: + + if (err && walk.nbytes) + (void)skcipher_walk_done(&walk, err); + return err; } @@ -2331,7 +2337,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsDecrypt failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, 0); @@ -2365,7 +2372,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsDecryptInit failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } while ((nbytes = walk.nbytes) != 0) { @@ -2387,7 +2395,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsDecryptUpdate failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); @@ -2421,7 +2430,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsDecryptFinal failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, 0); @@ -2435,6 +2445,11 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) req->cryptlen); #endif /* WOLFKM_DEBUG_AES */ +out: + + if (err && walk.nbytes) + (void)skcipher_walk_done(&walk, err); + return err; } From 67c1d65ef77d8e82d358ab384e7acd670dd32379 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 8 Jun 2026 18:07:38 -0500 Subject: [PATCH 03/13] fixes for F-2554 Missing wc_ecc_free Before free in km_ecdh_init When wc_ecc_set_rng Fails F-2555 Missing wc_FreeDhKey Before free in km_ffdhe_init When wc_DhSetNamedKey Fails --- linuxkm/lkcapi_dh_glue.c | 1 + linuxkm/lkcapi_ecdh_glue.c | 1 + 2 files changed, 2 insertions(+) diff --git a/linuxkm/lkcapi_dh_glue.c b/linuxkm/lkcapi_dh_glue.c index 5fb3dd2ffd..02dcf5d780 100644 --- a/linuxkm/lkcapi_dh_glue.c +++ b/linuxkm/lkcapi_dh_glue.c @@ -779,6 +779,7 @@ static int km_ffdhe_init(struct crypto_kpp *tfm, int name, word32 nbits) pr_err("%s: wc_DhSetNamedKey returned: %d\n", WOLFKM_DH_DRIVER, err); #endif /* WOLFKM_DEBUG_DH */ + wc_FreeDhKey(ctx->key); free(ctx->key); ctx->key = NULL; return -ENOMEM; diff --git a/linuxkm/lkcapi_ecdh_glue.c b/linuxkm/lkcapi_ecdh_glue.c index f562285306..57a0831547 100644 --- a/linuxkm/lkcapi_ecdh_glue.c +++ b/linuxkm/lkcapi_ecdh_glue.c @@ -415,6 +415,7 @@ static int km_ecdh_init(struct crypto_kpp *tfm, int curve_id) #ifdef ECC_TIMING_RESISTANT ret = wc_ecc_set_rng(ctx->key, &ctx->rng); if (ret < 0) { + wc_ecc_free(ctx->key); free(ctx->key); ctx->key = NULL; return -ENOMEM; From ad98438baaae5dc0e58e19e2a7bd62f7b5452c49 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Mon, 8 Jun 2026 18:15:51 -0500 Subject: [PATCH 04/13] fixes for F-5335: ECDH overflow paths do not report the required output length F-5336: RSA PKCS#1 overflow paths do not report the required output length --- linuxkm/lkcapi_ecdh_glue.c | 2 ++ linuxkm/lkcapi_rsa_glue.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/linuxkm/lkcapi_ecdh_glue.c b/linuxkm/lkcapi_ecdh_glue.c index 57a0831547..a9325c23e0 100644 --- a/linuxkm/lkcapi_ecdh_glue.c +++ b/linuxkm/lkcapi_ecdh_glue.c @@ -493,6 +493,7 @@ static int km_ecdh_gen_pub(struct kpp_request *req) pr_err("error: dst_len too small: %d\n", req->dst_len); #endif /* WOLFKM_DEBUG_ECDH */ err = -EOVERFLOW; + req->dst_len = raw_pub_len; goto ecdh_gen_pub_end; } @@ -650,6 +651,7 @@ static int km_ecdh_compute_shared_secret(struct kpp_request *req) if (req->dst_len < shared_secret_len) { err = -EOVERFLOW; + req->dst_len = shared_secret_len; goto ecdh_shared_secret_end; } diff --git a/linuxkm/lkcapi_rsa_glue.c b/linuxkm/lkcapi_rsa_glue.c index f76a8cbee9..2a0dba6cfe 100644 --- a/linuxkm/lkcapi_rsa_glue.c +++ b/linuxkm/lkcapi_rsa_glue.c @@ -832,6 +832,7 @@ static int km_direct_rsa_dec(struct akcipher_request *req) if (out_len > req->dst_len) { err = -EOVERFLOW; + req->dst_len = out_len; goto rsa_dec_out; } @@ -1121,6 +1122,7 @@ static int km_pkcs1pad_sign(struct akcipher_request *req) if (req->dst_len < ctx->key_len) { err = -EOVERFLOW; + req->dst_len = ctx->key_len; goto pkcs1pad_sign_out; } @@ -1688,6 +1690,7 @@ static int km_pkcs1pad_enc(struct akcipher_request *req) if (req->dst_len < ctx->key_len) { err = -EOVERFLOW; + req->dst_len = ctx->key_len; goto pkcs1_enc_out; } @@ -1806,6 +1809,7 @@ static int km_pkcs1pad_dec(struct akcipher_request *req) if (dec_len > req->dst_len) { err = -EOVERFLOW; + req->dst_len = dec_len; goto pkcs1_dec_out; } From da1b7fe2366513313029003b0522d34b0e1f125e Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 9 Jun 2026 09:59:36 -0500 Subject: [PATCH 05/13] fixes for F-674: Non-Constant-Time memcmp in RSA PKCS#1 v1.5 Signature Verification --- linuxkm/lkcapi_rsa_glue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linuxkm/lkcapi_rsa_glue.c b/linuxkm/lkcapi_rsa_glue.c index 2a0dba6cfe..c0cac0df5d 100644 --- a/linuxkm/lkcapi_rsa_glue.c +++ b/linuxkm/lkcapi_rsa_glue.c @@ -1278,7 +1278,7 @@ static int km_pkcs1pad_verify(struct akcipher_request *req) goto pkcs1pad_verify_out; } - n_diff = memcmp(sig, msg, dec_len); + n_diff = ConstantCompare(sig, msg, dec_len); if (unlikely(n_diff != 0)) { err = -EKEYREJECTED; goto pkcs1pad_verify_out; @@ -1525,7 +1525,7 @@ static int km_pkcs1_verify(struct crypto_sig *tfm, goto pkcs1_verify_out; } - n_diff = memcmp(enc_digest, msg, enc_msg_len); + n_diff = ConstantCompare(enc_digest, msg, enc_msg_len); if (unlikely(n_diff != 0)) { #ifdef WOLFKM_DEBUG_RSA pr_err("error: %s: recovered msg did not match digest: %d\n", From c9cc79f9aee7e71c6a1fb7409440490a00a2491d Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 9 Jun 2026 15:07:53 -0500 Subject: [PATCH 06/13] cleanup inspired by false positive F-675: AES-CTR and AES-OFB Modes Bypass WC_C_DYNAMIC_FALLBACK Selection Logic --- linuxkm/lkcapi_aes_glue.c | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/linuxkm/lkcapi_aes_glue.c b/linuxkm/lkcapi_aes_glue.c index 7166d19a79..591dcccf1c 100644 --- a/linuxkm/lkcapi_aes_glue.c +++ b/linuxkm/lkcapi_aes_glue.c @@ -2509,13 +2509,10 @@ static int km_AesCtrEncrypt(struct skcipher_request *req) return err; } - /* Copy the cipher state to mitigate races on Aes.reg and Aes.tmp. */ - aes_copy = (struct Aes *)malloc(sizeof(Aes)); - if (aes_copy == NULL) { - err = -ENOMEM; + err = km_AesGet(ctx, 0 /* decrypt_p */, 1 /* copy_p */, &aes_copy); + if (unlikely(err)) { goto out; } - XMEMCPY(aes_copy, ctx->aes_encrypt, sizeof(Aes)); err = wc_AesSetIV(aes_copy, walk.iv); @@ -2583,16 +2580,11 @@ static int km_AesCtrDecrypt(struct skcipher_request *req) return err; } - /* Copy the cipher state to mitigate races on Aes.reg and Aes.tmp. */ - aes_copy = (struct Aes *)malloc(sizeof(Aes)); - if (aes_copy == NULL) { - err = -ENOMEM; + /* CTR uses the same schedule for encrypt and decrypt. */ + err = km_AesGet(ctx, 0 /* decrypt_p */, 1 /* copy_p */, &aes_copy); + if (unlikely(err)) { goto out; } - XMEMCPY(aes_copy, ctx->aes_encrypt, sizeof(Aes)); /* CTR uses the same - * schedule for encrypt - * and decrypt. - */ err = wc_AesSetIV(aes_copy, walk.iv); @@ -2697,13 +2689,10 @@ static int km_AesOfbEncrypt(struct skcipher_request *req) return err; } - /* Copy the cipher state to mitigate races on Aes.reg and Aes.tmp. */ - aes_copy = (struct Aes *)malloc(sizeof(Aes)); - if (aes_copy == NULL) { - err = -ENOMEM; + err = km_AesGet(ctx, 0 /* decrypt_p */, 1 /* copy_p */, &aes_copy); + if (unlikely(err)) { goto out; } - XMEMCPY(aes_copy, ctx->aes_encrypt, sizeof(Aes)); err = wc_AesSetIV(aes_copy, walk.iv); @@ -2771,16 +2760,11 @@ static int km_AesOfbDecrypt(struct skcipher_request *req) return err; } - /* Copy the cipher state to mitigate races on Aes.reg and Aes.tmp. */ - aes_copy = (struct Aes *)malloc(sizeof(Aes)); - if (aes_copy == NULL) { - err = -ENOMEM; + /* OFB uses the same schedule for encrypt and decrypt. */ + err = km_AesGet(ctx, 0 /* decrypt_p */, 1 /* copy_p */, &aes_copy); + if (unlikely(err)) { goto out; } - XMEMCPY(aes_copy, ctx->aes_encrypt, sizeof(Aes)); /* OFB uses the same - * schedule for encrypt - * and decrypt. - */ err = wc_AesSetIV(aes_copy, walk.iv); From afc2137351c249b4b6e6e956796397d7f82b2065 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 9 Jun 2026 16:57:17 -0500 Subject: [PATCH 07/13] fix F-682: Incorrect tolower/toupper Macros Produce Wrong Results for Non-Alpha Characters --- linuxkm/linuxkm_wc_port.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 83e35dc692..a9c7689189 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -1449,8 +1449,8 @@ */ #undef tolower #undef toupper - #define tolower(c) (islower(c) ? (c) : ((c) + ('a'-'A'))) - #define toupper(c) (isupper(c) ? (c) : ((c) - ('a'-'A'))) + #define tolower(c) (isupper(c) ? ((c) + ('a'-'A')) : (c)) + #define toupper(c) (islower(c) ? ((c) - ('a'-'A')) : (c)) #if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) #define GetCA WC_PIE_INDIRECT_SYM(GetCA) From b4139b1a904cbbdb8dc284e1c5581de4f763a5ee Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 9 Jun 2026 17:31:21 -0500 Subject: [PATCH 08/13] fix F-706: AES-CTR and AES-OFB Encrypt Leak Aes Context Containing Key Schedule on skcipher_walk_done Error --- linuxkm/lkcapi_aes_glue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linuxkm/lkcapi_aes_glue.c b/linuxkm/lkcapi_aes_glue.c index 591dcccf1c..134c695706 100644 --- a/linuxkm/lkcapi_aes_glue.c +++ b/linuxkm/lkcapi_aes_glue.c @@ -2539,7 +2539,7 @@ static int km_AesCtrEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: skcipher_walk_done failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return err; + goto out; } } @@ -2719,7 +2719,7 @@ static int km_AesOfbEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: skcipher_walk_done failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return err; + goto out; } } From 9b723b9e11d11d74290d5c4486eef71d167bc28c Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 10 Jun 2026 13:02:15 -0500 Subject: [PATCH 09/13] fix F-3024: Missing buffer-length validation in km_dh_decode_secret enables out-of-bounds read --- linuxkm/lkcapi_dh_glue.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/linuxkm/lkcapi_dh_glue.c b/linuxkm/lkcapi_dh_glue.c index 02dcf5d780..cc4dc8781e 100644 --- a/linuxkm/lkcapi_dh_glue.c +++ b/linuxkm/lkcapi_dh_glue.c @@ -356,6 +356,14 @@ static int km_dh_decode_secret(const u8 * buf, unsigned int len, return -EINVAL; } + if (len != expected_len) { + #ifdef WOLFKM_DEBUG_DH + pr_err("%s: km_dh_decode_secret: caller passed %u, expected %zu\n", + WOLFKM_DH_DRIVER, len, expected_len); + #endif /* WOLFKM_DEBUG_DH */ + return -EINVAL; + } + /* The rest of the fields are optional depending on how much data * was passed, and whether it's ffdhe or dh. */ if (params->key_size) { From 1e888383bb5fdad1046fc8839925f5cfeb8c0efe Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 10 Jun 2026 13:02:35 -0500 Subject: [PATCH 10/13] fix F-3025: Missing buffer-length validation in km_ecdh_decode_secret enables out-of-bounds read --- linuxkm/lkcapi_ecdh_glue.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/linuxkm/lkcapi_ecdh_glue.c b/linuxkm/lkcapi_ecdh_glue.c index a9325c23e0..be1186b060 100644 --- a/linuxkm/lkcapi_ecdh_glue.c +++ b/linuxkm/lkcapi_ecdh_glue.c @@ -210,6 +210,14 @@ static int km_ecdh_decode_secret(const u8 * buf, unsigned int len, return -EINVAL; } + if (len != expected_len) { + #ifdef WOLFKM_DEBUG_ECDH + pr_err("%s: km_ecdh_decode_secret: caller passed %u, expected %zu\n", + WOLFKM_ECDH_DRIVER, len, expected_len); + #endif /* WOLFKM_DEBUG_ECDH */ + return -EINVAL; + } + /* Only set the key if it was provided. */ if (params->key_size) { params->key = (void *)ptr; From e98a03b80e8db81337f12ada5a30170acd38d0eb Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 10 Jun 2026 14:11:50 -0500 Subject: [PATCH 11/13] fix F=3524: Heap Buffer Overflow in km_direct_rsa_dec When req->dst_len < ctx->key_len --- linuxkm/lkcapi_rsa_glue.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/linuxkm/lkcapi_rsa_glue.c b/linuxkm/lkcapi_rsa_glue.c index c0cac0df5d..4fb126605d 100644 --- a/linuxkm/lkcapi_rsa_glue.c +++ b/linuxkm/lkcapi_rsa_glue.c @@ -792,8 +792,12 @@ static int km_direct_rsa_dec(struct akcipher_request *req) goto rsa_dec_out; } - if (req->dst_len <= 0 || req->dst_len > (unsigned int) ctx->key_len) { - err = -EINVAL; + if (req->dst_len != (unsigned int)ctx->key_len) { + if ((req->dst_len > 0) && (req->dst_len < (unsigned int)ctx->key_len)) + err = -EOVERFLOW; + else + err = -EINVAL; + req->dst_len = ctx->key_len; goto rsa_dec_out; } From 0f3d3bedb0d8e906f6b2d8ea16ff3a54ac10d66a Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 10 Jun 2026 14:37:53 -0500 Subject: [PATCH 12/13] fix F-5334: AEAD decrypt accepts ciphertext shorter than authentication tag before unsigned length subtraction --- linuxkm/lkcapi_aes_glue.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/linuxkm/lkcapi_aes_glue.c b/linuxkm/lkcapi_aes_glue.c index 134c695706..24d9025de2 100644 --- a/linuxkm/lkcapi_aes_glue.c +++ b/linuxkm/lkcapi_aes_glue.c @@ -1131,6 +1131,13 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) if (decrypt_p) { /* Copy out original auth tag from req->src. */ + if (req->cryptlen < tfm->authsize) + return -EINVAL; + if (((word32)req->assoclen + (word32)req->cryptlen) != + ((word64)req->assoclen + (word64)req->cryptlen)) + { + return -EOVERFLOW; + } scatterwalk_map_and_copy(authTag, req->src, req->assoclen + req->cryptlen - tfm->authsize, tfm->authsize, 0); @@ -1350,6 +1357,13 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) if (decrypt_p) { /* Copy out original auth tag from req->src. */ + if (req->cryptlen < tfm->authsize) + return -EINVAL; + if (((word32)req->assoclen + (word32)req->cryptlen) != + ((word64)req->assoclen + (word64)req->cryptlen)) + { + return -EOVERFLOW; + } scatterwalk_map_and_copy(authTag, req->src, req->assoclen + req->cryptlen - tfm->authsize, tfm->authsize, 0); @@ -1823,6 +1837,13 @@ static int AesCcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4309_p) if (decrypt_p) { /* Copy out the original auth tag from req->src. */ + if (req->cryptlen < tfm->authsize) + return -EINVAL; + if (((word32)req->assoclen + (word32)req->cryptlen) != + ((word64)req->assoclen + (word64)req->cryptlen)) + { + return -EOVERFLOW; + } scatterwalk_map_and_copy(authTag, req->src, req->assoclen + req->cryptlen - tfm->authsize, tfm->authsize, 0); From 486e8eefc072ac627ffe3a34108817b35c5ea106 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 10 Jun 2026 17:32:20 -0500 Subject: [PATCH 13/13] .wolfssl_known_macro_extras: fix lexical order. --- .wolfssl_known_macro_extras | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index c23fd8949e..42d31cf0dd 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -661,8 +661,8 @@ WC_FORCE_LINUXKM_FORTIFY_SOURCE WC_HASH_CUSTOM_MAX_BLOCK_SIZE WC_HASH_CUSTOM_MAX_DIGEST_SIZE WC_HASH_CUSTOM_MIN_DIGEST_SIZE -WC_LINUXKM_NO_USE_HEAP_WRAPPERS WC_INIT_ERROR_WHEN_CONTENDED +WC_LINUXKM_NO_USE_HEAP_WRAPPERS WC_MLKEM_KERNEL_ASM WC_NO_ASYNC_SLEEP WC_NO_RNG_SIMPLE