CVE-2018-0739 CVE-2019-1563 CVE-2020-1971 CVE-2021-23840 CVE-2021-23841 CVE-2022-0778 CVE-2021-3712 (cherry picked from commit a582068887203f626772052e466343c6ef2d0719)
71 lines
3.0 KiB
Diff
71 lines
3.0 KiB
Diff
From e21f8cf78a125cd3c8c0d1a1a6c8bb0b901f893f Mon Sep 17 00:00:00 2001
|
|
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
|
|
Date: Sun, 1 Sep 2019 00:16:28 +0200
|
|
Subject: [PATCH] Fix a padding oracle in PKCS7_dataDecode and
|
|
CMS_decrypt_set1_pkey
|
|
|
|
An attack is simple, if the first CMS_recipientInfo is valid but the
|
|
second CMS_recipientInfo is chosen ciphertext. If the second
|
|
recipientInfo decodes to PKCS #1 v1.5 form plaintext, the correct
|
|
encryption key will be replaced by garbage, and the message cannot be
|
|
decoded, but if the RSA decryption fails, the correct encryption key is
|
|
used and the recipient will not notice the attack.
|
|
|
|
As a work around for this potential attack the length of the decrypted
|
|
key must be equal to the cipher default key length, in case the
|
|
certifiate is not given and all recipientInfo are tried out.
|
|
|
|
The old behaviour can be re-enabled in the CMS code by setting the
|
|
CMS_DEBUG_DECRYPT flag.
|
|
|
|
Reviewed-by: Matt Caswell <matt@openssl.org>
|
|
(Merged from https://github.com/openssl/openssl/pull/9777)
|
|
|
|
(cherry picked from commit 5840ed0cd1e6487d247efbc1a04136a41d7b3a37)
|
|
---
|
|
crypto/pkcs7/pk7_doit.c | 12 ++++++++----
|
|
1 files changed, 8 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c
|
|
index 6a463680d7e..63bc88269ff 100644
|
|
--- a/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c
|
|
+++ b/Cryptlib/OpenSSL/crypto/pkcs7/pk7_doit.c
|
|
@@ -191,7 +191,8 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
|
|
}
|
|
|
|
static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
|
|
- PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
|
|
+ PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey,
|
|
+ size_t fixlen)
|
|
{
|
|
EVP_PKEY_CTX *pctx = NULL;
|
|
unsigned char *ek = NULL;
|
|
@@ -224,7 +225,9 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
|
|
}
|
|
|
|
if (EVP_PKEY_decrypt(pctx, ek, &eklen,
|
|
- ri->enc_key->data, ri->enc_key->length) <= 0) {
|
|
+ ri->enc_key->data, ri->enc_key->length) <= 0
|
|
+ || eklen == 0
|
|
+ || (fixlen != 0 && eklen != fixlen)) {
|
|
ret = 0;
|
|
PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
|
|
goto err;
|
|
@@ -571,13 +574,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
|
|
for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
|
|
ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
|
|
|
|
- if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
|
|
+ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
|
|
+ EVP_CIPHER_key_length(evp_cipher)) < 0)
|
|
goto err;
|
|
ERR_clear_error();
|
|
}
|
|
} else {
|
|
/* Only exit on fatal errors, not decrypt failure */
|
|
- if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
|
|
+ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
|
|
goto err;
|
|
ERR_clear_error();
|
|
}
|