From 9ebf997cb32fa0ce7eb7b912ed1498443f64e3cd Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 23 Jun 2026 16:35:05 +0200 Subject: Restore the check for missing IV param in evp_cipher_asn1_to_param_ex STREAM ciphers (RC4) and WRAP MODE ciphers (CMS3DESwrap) do not have an IV parameter value, all other ciphers need an IV value, previously the missing IV param value was handled as an error condition. The check that an IV value is there was accidentally removed for all ciphers. This restores the check for all ciphers except RC4. Fixes: 114d99b46bfb ("Fix incomplete checks for EVP_CIPHER_asn1_to_param") Reviewed-by: Dmitry Belyavskiy Reviewed-by: Mounir Idrassi Merge-date: Thu Aug 27 15:07:58 2026 Merged-from: https://github.com/openssl/openssl/pull/32394 (cherry picked from commit 1671f994548a1a33246859ab6cc43200b1c65d87) --- crypto/evp/evp_lib.c | 4 ++- test/cmsapitest.c | 40 +++++++++++++++++++-- test/recipes/80-test_cmsapi.t | 1 + .../80-test_cmsapi_data/cms_pwri_kek_NoIV.der | Bin 0 -> 193 bytes 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 test/recipes/80-test_cmsapi_data/cms_pwri_kek_NoIV.der diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 95b8bf32748..474886c0d2d 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -210,7 +210,9 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, break; default: - ret = EVP_CIPHER_get_asn1_iv(c, type) >= 0 ? 1 : -1; + ret = EVP_CIPHER_get_asn1_iv(c, type); + if (ret == 0 && EVP_CIPHER_CTX_get_iv_length(c) == 0) + ret = 1; } } else if (cipher->prov != NULL) { OSSL_PARAM params[3], *p = params; diff --git a/test/cmsapitest.c b/test/cmsapitest.c index df5f8d59dcd..0f67a9717f5 100644 --- a/test/cmsapitest.c +++ b/test/cmsapitest.c @@ -21,6 +21,7 @@ static EVP_PKEY *privkey = NULL; static char *derin = NULL; static char *too_long_iv_cms_in = NULL; static char *pwri_kek_oob_der_in = NULL; +static char *pwri_kek_no_iv_in = NULL; static char *ec_recip_in = NULL; /* @@ -712,6 +713,39 @@ end: return ret; } +static int test_pwri_kek_unwrap_no_iv_key(void) +{ + BIO *in = NULL; + CMS_ContentInfo *cms = NULL; + unsigned long err = 0; + int ret = 0; + + if (!TEST_ptr(in = BIO_new_file(pwri_kek_no_iv_in, "rb")) + || !TEST_ptr(cms = d2i_CMS_bio(in, NULL))) + goto end; + + /* + * Due to the missing IV, the unwrap must fail with + * CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR. + */ + if (!TEST_false(CMS_decrypt_set1_password(cms, + (unsigned char *)"password", -1))) + goto end; + + err = ERR_peek_last_error(); + if (!TEST_int_eq(ERR_GET_LIB(err), ERR_LIB_CMS) + || !TEST_int_eq(ERR_GET_REASON(err), + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR)) + goto end; + + ERR_clear_error(); + ret = 1; +end: + CMS_ContentInfo_free(cms); + BIO_free(in); + return ret; +} + #ifndef OPENSSL_NO_EC /* @@ -805,7 +839,7 @@ end: } #endif -OPT_TEST_DECLARE_USAGE("certfile privkeyfile derfile tooLongIVpem pwriKekOobDer ecrecip\n") +OPT_TEST_DECLARE_USAGE("certfile privkeyfile derfile tooLongIVpem pwriKekOobDer pwriKekNoIv ecrecip\n") int setup_tests(void) { @@ -822,7 +856,8 @@ int setup_tests(void) || !TEST_ptr(derin = test_get_argument(2)) || !TEST_ptr(too_long_iv_cms_in = test_get_argument(3)) || !TEST_ptr(pwri_kek_oob_der_in = test_get_argument(4)) - || !TEST_ptr(ec_recip_in = test_get_argument(5))) + || !TEST_ptr(pwri_kek_no_iv_in = test_get_argument(5)) + || !TEST_ptr(ec_recip_in = test_get_argument(6))) return 0; certbio = BIO_new_file(certin, "r"); @@ -862,6 +897,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_d2i_CMS_decode, 2); ADD_TEST(test_cms_aesgcm_iv_too_long); ADD_TEST(test_pwri_kek_unwrap_short_encrypted_key); + ADD_TEST(test_pwri_kek_unwrap_no_iv_key); #ifndef OPENSSL_NO_EC ADD_TEST(test_kari_wrap_pad_unwrap_overflow); diff --git a/test/recipes/80-test_cmsapi.t b/test/recipes/80-test_cmsapi.t index 1f5f7ae233e..840a00b33f7 100644 --- a/test/recipes/80-test_cmsapi.t +++ b/test/recipes/80-test_cmsapi.t @@ -21,5 +21,6 @@ ok(run(test(["cmsapitest", srctop_file("test", "certs", "servercert.pem"), srctop_file("test", "recipes", "80-test_cmsapi_data", "encryptedData.der"), srctop_file("test", "recipes", "80-test_cmsapi_data", "encDataWithTooLongIV.pem"), srctop_file("test", "recipes", "80-test_cmsapi_data", "cms_pwri_kek_oob.der"), + srctop_file("test", "recipes", "80-test_cmsapi_data", "cms_pwri_kek_NoIV.der"), srctop_file("test", "smime-certs", "smec1.pem")])), "running cmsapitest"); diff --git a/test/recipes/80-test_cmsapi_data/cms_pwri_kek_NoIV.der b/test/recipes/80-test_cmsapi_data/cms_pwri_kek_NoIV.der new file mode 100644 index 00000000000..c3ef3abd10e Binary files /dev/null and b/test/recipes/80-test_cmsapi_data/cms_pwri_kek_NoIV.der differ -- cgit