diff --git a/0058-CVE-2026-31790.patch b/0058-CVE-2026-31790.patch new file mode 100644 index 0000000..1b556a7 --- /dev/null +++ b/0058-CVE-2026-31790.patch @@ -0,0 +1,185 @@ +From 001e01db3e996e13ffc72386fe79d03a6683b5ac Mon Sep 17 00:00:00 2001 +From: Nikola Pajkovsky +Date: Thu, 19 Mar 2026 12:16:08 +0100 +Subject: [PATCH 1/2] rsa_kem: validate RSA_public_encrypt() result in RSASVE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RSA_public_encrypt() returns the number of bytes written on success and +-1 on failure. With the existing `if (ret)` check, a provider-side RSA KEM +encapsulation can incorrectly succeed when the underlying RSA public +encrypt operation fails. In that case the code reports success, returns +lengths as if encapsulation completed normally, and leaves the freshly +generated secret available instead of discarding it. + +Tighten the success condition so RSASVE only succeeds when +RSA_public_encrypt() returns a positive value equal to the modulus-sized +output expected for RSA_NO_PADDING. Any other return value is treated as +failure, and the generated secret is cleansed before returning. + +Fixes CVE-2026-31790 +Signed-off-by: Nikola Pajkovsky + +Reviewed-by: Saša Nedvědický +Reviewed-by: Tomas Mraz +MergeDate: Mon Apr 6 19:51:30 2026 +--- + providers/implementations/kem/rsa_kem.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/providers/implementations/kem/rsa_kem.c b/providers/implementations/kem/rsa_kem.c +index f7bf368a0d..74dfafddd9 100644 +--- a/providers/implementations/kem/rsa_kem.c ++++ b/providers/implementations/kem/rsa_kem.c +@@ -316,17 +316,19 @@ static int rsasve_generate(PROV_RSA_CTX *prsactx, + return 0; + + /* Step(3): out = RSAEP((n,e), z) */ +- ret = RSA_public_encrypt(nlen, secret, out, prsactx->rsa, RSA_NO_PADDING); +- if (ret) { +- ret = 1; +- if (outlen != NULL) +- *outlen = nlen; +- if (secretlen != NULL) +- *secretlen = nlen; +- } else { ++ ret = RSA_public_encrypt((int)nlen, secret, out, prsactx->rsa, ++ RSA_NO_PADDING); ++ if (ret <= 0 || ret != (int)nlen) { + OPENSSL_cleanse(secret, nlen); ++ return 0; + } +- return ret; ++ ++ if (outlen != NULL) ++ *outlen = nlen; ++ if (secretlen != NULL) ++ *secretlen = nlen; ++ ++ return 1; + } + + /** +-- +2.53.0 + + +From c61bbd3f873d28e098f503f0187459ed488977c9 Mon Sep 17 00:00:00 2001 +From: Nikola Pajkovsky +Date: Mon, 23 Mar 2026 08:41:20 +0100 +Subject: [PATCH 2/2] rsa_kem: test RSA_public_encrypt() result in RSASVE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RSA_public_encrypt() returns the number of bytes written on success and +-1 on failure. + +Add regression coverage in evp_extra_test using invalid RSA pubkey +which triggers -1 in RSA_public_encrypt() using encapsulation. + +Signed-off-by: Nikola Pajkovsky + +Reviewed-by: Saša Nedvědický +Reviewed-by: Tomas Mraz +MergeDate: Mon Apr 6 19:51:31 2026 +--- + test/evp_extra_test.c | 67 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 67 insertions(+) + +diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c +index 5ea95c0dfa..573732bfec 100644 +--- a/test/evp_extra_test.c ++++ b/test/evp_extra_test.c +@@ -929,6 +929,32 @@ static EVP_PKEY *load_example_ec_key(void) + #endif + + #ifndef OPENSSL_NO_DEPRECATED_3_0 ++ ++static EVP_PKEY *make_bad_rsa_pubkey(void) ++{ ++ RSA *rsa = NULL; ++ BIGNUM *n = NULL, *e = NULL; ++ EVP_PKEY *pkey = NULL; ++ ++ /* Deliberately invalid public key: n = 17, e = 17 */ ++ if (!TEST_ptr(pkey = EVP_PKEY_new()) ++ || !TEST_ptr(rsa = RSA_new()) ++ || !TEST_ptr(n = BN_new()) ++ || !TEST_ptr(e = BN_new()) ++ || !TEST_true(BN_set_word(n, 17)) ++ || !TEST_true(BN_set_word(e, 17)) ++ || !TEST_true(RSA_set0_key(rsa, n, e, NULL)) ++ || !EVP_PKEY_assign_RSA(pkey, rsa)) ++ goto err; ++ ++ return pkey; ++err: ++ BN_free(n); ++ BN_free(e); ++ RSA_free(rsa); ++ return NULL; ++} ++ + #ifndef OPENSSL_NO_DH + static EVP_PKEY *load_example_dh_key(void) + { +@@ -5898,6 +5924,46 @@ err: + return testresult; + } + ++static int test_rsasve_kem_with_invalid_pub_key(void) ++{ ++ RSA *rsa = NULL; ++ EVP_PKEY *pkey = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ unsigned char *ct = NULL; ++ unsigned char *secret = NULL; ++ size_t ctlen = 0, secretlen = 0; ++ int testresult = 0; ++ ++ if (nullprov != NULL) { ++ testresult = TEST_skip("Test does not support a non-default library context"); ++ goto err; ++ } ++ ++ if (!TEST_ptr(pkey = make_bad_rsa_pubkey())) ++ goto err; ++ ++ if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(testctx, pkey, NULL)) ++ || !TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1) ++ || !TEST_int_eq(EVP_PKEY_CTX_set_kem_op(ctx, "RSASVE"), 1) ++ || !TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, &ctlen, NULL, &secretlen), 1) ++ || !TEST_ptr(ct = OPENSSL_malloc(ctlen)) ++ || !TEST_ptr(secret = OPENSSL_malloc(secretlen))) ++ goto err; ++ ++ if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, ct, &ctlen, secret, &secretlen), 0)) ++ goto err; ++ ++ testresult = 1; ++ ++err: ++ OPENSSL_free(secret); ++ OPENSSL_free(ct); ++ EVP_PKEY_CTX_free(ctx); ++ RSA_free(rsa); ++ EVP_PKEY_free(pkey); ++ return testresult; ++} ++ + #ifndef OPENSSL_NO_DYNAMIC_ENGINE + /* Test we can create a signature keys with an associated ENGINE */ + static int test_signatures_with_engine(int tst) +@@ -6893,6 +6959,7 @@ int setup_tests(void) + ADD_TEST(test_evp_md_cipher_meth); + ADD_TEST(test_custom_md_meth); + ADD_TEST(test_custom_ciph_meth); ++ ADD_TEST(test_rsasve_kem_with_invalid_pub_key); + + #ifndef OPENSSL_NO_DYNAMIC_ENGINE + /* Tests only support the default libctx */ +-- +2.53.0 + diff --git a/openssl.spec b/openssl.spec index 53bc2c0..072846c 100644 --- a/openssl.spec +++ b/openssl.spec @@ -29,7 +29,7 @@ print(string.sub(hash, 0, 16)) Summary: Utilities from the general purpose cryptography library with TLS implementation Name: openssl Version: 3.5.5 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 1 Source0: openssl-%{version}.tar.gz Source1: fips-hmacify.sh @@ -98,6 +98,7 @@ Patch0054: 0054-Temporarily-disable-SLH-DSA-FIPS-self-tests.patch Patch0055: 0055-Add-a-define-to-disable-symver-attributes.patch Patch0056: 0056-Add-targets-to-skip-build-of-non-installable-program.patch Patch0057: 0057-Disable-RSA-PKCS1.5-FIPS-POST-not-relevant-for-RHEL.patch +Patch0058: 0058-CVE-2026-31790.patch #The patches that are different for RHEL9 and 10 start here Patch0100: 0100-RHEL9-Allow-SHA1-in-seclevel-2-if-rh-allow-sha1-signatures.patch @@ -456,6 +457,10 @@ ln -s /etc/crypto-policies/back-ends/openssl_fips.config $RPM_BUILD_ROOT%{_sysco %ldconfig_scriptlets libs %changelog +* Thu Apr 09 2026 Pavol Žáčik - 1:3.5.5-2 +- Fix CVE-2026-31790 + Resolves: RHEL-161586 + * Tue Jan 27 2026 Dmitry Belyavskiy - 1:3.5.5-1 - Rebase to OpenSSL 3.5.5 Resolves: RHEL-136895