From 28679844c3629f9ac6a1ca8935096a1591fae615 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 22 May 2025 18:40:30 +0200 Subject: [PATCH 1/2] 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 | 6 +++--- crypto/cms/cms_err.c | 4 +++- crypto/cms/cms_local.h | 2 +- crypto/err/openssl.txt | 3 ++- include/crypto/cmserr.h | 2 +- include/openssl/cmserr.h | 4 ++-- test/cms-msg/enveloped-content-type-for-aes-gcm.pem | 7 +++++++ test/cmsapitest.c | 7 ++++--- test/recipes/80-test_cms.t | 12 +++++++++++- 10 files changed, 40 insertions(+), 15 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 69266b5073..08afb5ab11 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, @@ -259,5 +263,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 5bc31957d7..2acfea6a1b 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -1131,7 +1131,7 @@ 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) @@ -1169,7 +1169,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) @@ -1221,7 +1221,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 222aed561c..54d1ddf824 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -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 9037451551..9cd8c30910 100644 --- a/crypto/cms/cms_local.h +++ b/crypto/cms/cms_local.h @@ -432,7 +432,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 36388ca9f5..2ed2876883 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1,4 +1,4 @@ -# Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -302,6 +302,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:182: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/crypto/cmserr.h b/include/crypto/cmserr.h index f9fd933682..8b896822d0 100644 --- a/include/crypto/cmserr.h +++ b/include/crypto/cmserr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h index 9c4e9efe93..48f7723e16 100644 --- a/include/openssl/cmserr.h +++ b/include/openssl/cmserr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,7 +17,6 @@ #include #ifndef OPENSSL_NO_CMS - /* * CMS reason codes. */ @@ -26,6 +25,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 182 #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 0000000000..b0610a7ec8 --- /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 261a1bb759..bfe40a94e4 100644 --- a/test/cmsapitest.c +++ b/test/cmsapitest.c @@ -47,9 +47,10 @@ 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 03c715fb56..1e56a31e63 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -51,7 +51,7 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib) $no_rc2 = 1 if disabled("legacy"); -plan tests => 27; +plan tests => 28; ok(run(test(["pkcs7_test"])), "test pkcs7"); @@ -1200,6 +1200,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.55.0 From 9f1656d62aab6cbac575586fa40d61ea21e71640 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 17 Apr 2026 13:21:50 -0400 Subject: [PATCH 2/2] Reject potentially forged encrypted CMS AuthEnvelopedData messages 1. Adjust ossl_cms_EncryptedContent_init_bio to not accept non-AEAD ciphers. If a forged CMS message with AuthEnvelopedData is received with a non-AEAD cipher specified, we silently accept that and decrypt the message, skipping any authentication, which violates RFC 5083. We also add checks to ensure we fail if we try to encrypt AuthEnvelopedData without using an AEAD cipher. 2. Ensure that tag lengths on cms AEAD data is the recommended size. RFC 5084 recommends that mac tags be at least 12 bytes for AES-GCM and 4 bytes for AES-CCM on AuthEnvelopedData. As this code is not algorith-specific we add a check for a minimal size and just use the lower limit which is sufficient to prevent this attack. Without this check, its possible to set the tag length to 1 and within 256 guesses, forge a CMS message. Fixes CVE-2026-34182 Reviewed-by: Nikola Pajkovsky Reviewed-by: Tomas Mraz MergeDate: Mon Jun 8 14:33:15 2026 --- crypto/cms/cms_enc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index 08afb5ab11..ba7082cebd 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -109,13 +109,15 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, goto err; } piv = aparams.iv; - if (ec->taglen > 0 - && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, - ec->taglen, ec->tag) - <= 0) { + + if (ec->taglen < 4 || ec->taglen > 16 + || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (int)ec->taglen, ec->tag) <= 0) { ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_AEAD_SET_TAG_ERROR); goto err; } + } else if (auth) { + ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM); + goto err; } } len = EVP_CIPHER_CTX_get_key_length(ctx); -- 2.55.0