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)
{
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)
{
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");
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;
}
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");