From 2dda0c50eafc1de8a2c008fbf60340ba5e60bfb3 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 22 May 2025 18:40:30 +0200 Subject: [PATCH] CMS: Produce error when AEAD algorithms are used in enveloped data Fixes GH-21414 Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/27772) --- crypto/cms/cms_enc.c | 8 ++++++-- crypto/cms/cms_env.c | 7 ++++--- crypto/cms/cms_err.c | 2 ++ crypto/cms/cms_local.h | 2 +- crypto/err/openssl.txt | 1 + include/openssl/cmserr.h | 1 + test/cms-msg/enveloped-content-type-for-aes-gcm.pem | 7 +++++++ test/cmsapitest.c | 9 +++++---- test/recipes/80-test_cms.t | 12 +++++++++++- 9 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 test/cms-msg/enveloped-content-type-for-aes-gcm.pem diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index 4f514360572..d64d9a3e341 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -23,7 +23,7 @@ /* Return BIO based on EncryptedContentInfo and key */ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, - const CMS_CTX *cms_ctx) + const CMS_CTX *cms_ctx, int auth) { BIO *b; EVP_CIPHER_CTX *ctx; @@ -104,6 +104,10 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, goto err; } if ((EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + if (!auth) { + ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_AEAD_IN_ENVELOPED_DATA); + goto err; + } piv = aparams.iv; if (ec->taglen > 0 && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, @@ -255,5 +259,5 @@ BIO *ossl_cms_EncryptedData_init_bio(const CMS_ContentInfo *cms) if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) enc->version = 2; return ossl_cms_EncryptedContent_init_bio(enc->encryptedContentInfo, - ossl_cms_get0_cmsctx(cms)); + ossl_cms_get0_cmsctx(cms), 0); } diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index 47432cee144..c7448769db6 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -1173,7 +1173,8 @@ static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms) { CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo; BIO *contentBio = ossl_cms_EncryptedContent_init_bio(ec, - ossl_cms_get0_cmsctx(cms)); + ossl_cms_get0_cmsctx(cms), + 0); EVP_CIPHER_CTX *ctx = NULL; if (contentBio == NULL) @@ -1209,7 +1210,7 @@ static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms) /* Get BIO first to set up key */ ec = env->encryptedContentInfo; - ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms)); + ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms), 0); /* If error end of processing */ if (!ret) @@ -1261,7 +1262,7 @@ BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms) ec->tag = aenv->mac->data; ec->taglen = aenv->mac->length; } - ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms)); + ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms), 1); /* If error or no cipher end of processing */ if (ret == NULL || ec->cipher == NULL) diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c index 1815c51db1c..d883ace9a12 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -25,6 +25,8 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { "certificate has no keyid"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_AEAD_IN_ENVELOPED_DATA), + "cipher aead in enveloped data"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_AEAD_SET_TAG_ERROR), "cipher aead set tag error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_GET_TAG), "cipher get tag"}, diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h index 990f86d221b..7cbc3fd0687 100644 --- a/crypto/cms/cms_local.h +++ b/crypto/cms/cms_local.h @@ -464,7 +464,7 @@ int ossl_cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert); int ossl_cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert); BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, - const CMS_CTX *ctx); + const CMS_CTX *ctx, int auth); BIO *ossl_cms_EncryptedData_init_bio(const CMS_ContentInfo *cms); int ossl_cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, const EVP_CIPHER *cipher, diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index f47bc5ae756..82b80ecbf6d 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -311,6 +311,7 @@ CMS_R_ATTRIBUTE_ERROR:161:attribute error CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present CMS_R_CERTIFICATE_HAS_NO_KEYID:160:certificate has no keyid CMS_R_CERTIFICATE_VERIFY_ERROR:100:certificate verify error +CMS_R_CIPHER_AEAD_IN_ENVELOPED_DATA:200:cipher aead in enveloped data CMS_R_CIPHER_AEAD_SET_TAG_ERROR:184:cipher aead set tag error CMS_R_CIPHER_GET_TAG:185:cipher get tag CMS_R_CIPHER_INITIALISATION_ERROR:101:cipher initialisation error diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h index 606cc114b86..92733c18cce 100644 --- a/include/openssl/cmserr.h +++ b/include/openssl/cmserr.h @@ -28,6 +28,7 @@ # define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 # define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 # define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +# define CMS_R_CIPHER_AEAD_IN_ENVELOPED_DATA 200 # define CMS_R_CIPHER_AEAD_SET_TAG_ERROR 184 # define CMS_R_CIPHER_GET_TAG 185 # define CMS_R_CIPHER_INITIALISATION_ERROR 101 diff --git a/test/cms-msg/enveloped-content-type-for-aes-gcm.pem b/test/cms-msg/enveloped-content-type-for-aes-gcm.pem new file mode 100644 index 00000000000..b0610a7ec8a --- /dev/null +++ b/test/cms-msg/enveloped-content-type-for-aes-gcm.pem @@ -0,0 +1,7 @@ +-----BEGIN PKCS7----- +MIAGCSqGSIb3DQEHA6CAMIACAQIxNqI0AgEEMAgEBkMwRkVFMDALBglghkgBZQME +AQUEGPN0q9rM3neSiY7HIADpnqWym33mRZC4JDCABgkqhkiG9w0BBwEwHgYJYIZI +AWUDBAEGMBEEDIExQGiHZFSYa0ZBqQIBEKCABGNap+JL1B21Mq7ojKPzVuxtRkg3 +LWt8khnK1EzfmV7e64l5KnTdjq9+gfbwOfbuhTavfBI7VK/ZtpH3HII4fCOe37kV +mju8/YnYeRq2KcxESmJBySV/veMwxqmHGAw71JyHpg4AAAAAAAAAAAAA +-----END PKCS7----- diff --git a/test/cmsapitest.c b/test/cmsapitest.c index a7820f7bab1..344b80a467c 100644 --- a/test/cmsapitest.c +++ b/test/cmsapitest.c @@ -46,10 +46,11 @@ static int test_encrypt_decrypt(const EVP_CIPHER *cipher) CMS_TEXT))) goto end; - if (!TEST_ptr(contentbio = - CMS_EnvelopedData_decrypt(content->d.envelopedData, - NULL, privkey, cert, NULL, - CMS_TEXT, NULL, NULL))) + if (!(EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) + && !TEST_ptr(contentbio = + CMS_EnvelopedData_decrypt(content->d.envelopedData, + NULL, privkey, cert, NULL, + CMS_TEXT, NULL, NULL))) goto end; /* Check we got the message we first started with */ diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t index e2095b09a3a..84b594fb00c 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -54,7 +54,7 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib) $no_rc2 = 1 if disabled("legacy"); -plan tests => 32; +plan tests => 33; ok(run(test(["pkcs7_test"])), "test pkcs7"); @@ -1312,6 +1312,16 @@ ok(!run(app(['openssl', 'cms', '-verify', ])), "issue#19643"); +# Check that users get error when using incorrect envelope type for AEAD algorithms +ok(!run(app(['openssl', 'cms', '-decrypt', + '-inform', 'PEM', '-stream', + '-secretkey', '000102030405060708090A0B0C0D0E0F', + '-secretkeyid', 'C0FEE0', + '-in', srctop_file("test/cms-msg", + "enveloped-content-type-for-aes-gcm.pem") + ])), + "Error AES-GCM in enveloped content type"); + # Check that kari encryption with originator does not segfault with({ exit_checker => sub { return shift == 3; } }, sub { -- 2.47.3