From: Nikola Pajkovsky Date: Thu, 21 May 2026 12:18:11 +0000 (+0200) Subject: cms: kek_unwrap_key: test for fix out-of-bounds read in check-byte validation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f789ca4f2bbbd57a821c08eabee6d193a03bf24;p=thirdparty%2Fopenssl.git cms: kek_unwrap_key: test for fix out-of-bounds read in check-byte validation added EnvelopedData blob with a PasswordRecipientInfo using id-alg-PWRI-KEK and an AES-128-CFB key encryption cipher. CFB's 1-byte effective block size let the inlen >= 2 * blocklen guard in kek_unwrap_key() accept a wrapped key shorter than the seven octets the check-byte test reads from tmp[1..6]; the encryptedKey OCTET STRING here is only two bytes. Signed-off-by: Nikola Pajkovsky Reviewed-by: Daniel Kubec Reviewed-by: Milan Broz Reviewed-by: Tomas Mraz MergeDate: Mon Jun 8 14:06:38 2026 --- diff --git a/test/cmsapitest.c b/test/cmsapitest.c index 4b250624a87..eaad075b0d8 100644 --- a/test/cmsapitest.c +++ b/test/cmsapitest.c @@ -21,6 +21,7 @@ static X509 *cert = NULL; 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 int test_encrypt_decrypt(const EVP_CIPHER *cipher) { @@ -512,7 +513,48 @@ end: return ret; } -OPT_TEST_DECLARE_USAGE("certfile privkeyfile derfile\n") +/* + * CMS EnvelopedData with a single PasswordRecipientInfo using + * id-alg-PWRI-KEK and an AES-128-CFB key encryption cipher + * (1-byte effective block size). The encryptedKey OCTET STRING is + * only two bytes long, so the wrapped key buffer is shorter than + * the seven octets read by the check-byte test in kek_unwrap_key(). + * Prior to CVE-2026-9076 this triggered an out-of-bounds heap read; + * CMS_decrypt() must now fail cleanly. + */ +static int test_pwri_kek_unwrap_short_encrypted_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_oob_der_in, "rb")) + || !TEST_ptr(cms = d2i_CMS_bio(in, NULL))) + goto end; + + /* + * The unwrap is attempted eagerly inside CMS_decrypt_set1_password(). + * It must fail cleanly (no OOB read) and report CMS_R_UNWRAP_FAILURE. + */ + 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_UNWRAP_FAILURE)) + goto end; + + ERR_clear_error(); + ret = 1; +end: + CMS_ContentInfo_free(cms); + BIO_free(in); + return ret; +} + +OPT_TEST_DECLARE_USAGE("certfile privkeyfile derfile tooLongIVpem pwriKekOobDer\n") int setup_tests(void) { @@ -527,7 +569,8 @@ int setup_tests(void) if (!TEST_ptr(certin = test_get_argument(0)) || !TEST_ptr(privkeyin = test_get_argument(1)) || !TEST_ptr(derin = test_get_argument(2)) - || !TEST_ptr(too_long_iv_cms_in = test_get_argument(3))) + || !TEST_ptr(too_long_iv_cms_in = test_get_argument(3)) + || !TEST_ptr(pwri_kek_oob_der_in = test_get_argument(4))) return 0; certbio = BIO_new_file(certin, "r"); @@ -564,6 +607,7 @@ int setup_tests(void) ADD_TEST(test_encrypted_data_aead); 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); return 1; } diff --git a/test/recipes/80-test_cmsapi.t b/test/recipes/80-test_cmsapi.t index 8d9371e005c..3d1dae84646 100644 --- a/test/recipes/80-test_cmsapi.t +++ b/test/recipes/80-test_cmsapi.t @@ -19,5 +19,6 @@ plan tests => 1; ok(run(test(["cmsapitest", srctop_file("test", "certs", "servercert.pem"), srctop_file("test", "certs", "serverkey.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", "encDataWithTooLongIV.pem"), + srctop_file("test", "recipes", "80-test_cmsapi_data", "cms_pwri_kek_oob.der")])), "running cmsapitest"); diff --git a/test/recipes/80-test_cmsapi_data/cms_pwri_kek_oob.der b/test/recipes/80-test_cmsapi_data/cms_pwri_kek_oob.der new file mode 100644 index 00000000000..c3ef3abd10e Binary files /dev/null and b/test/recipes/80-test_cmsapi_data/cms_pwri_kek_oob.der differ