isaacpittman-hitachi / rpms / openssl

Forked from rpms/openssl 2 years ago
Clone

Blame SOURCES/openssl-1.1.1-cve-2019-1563.patch

3a273b
From 08229ad838c50f644d7e928e2eef147b4308ad64 Mon Sep 17 00:00:00 2001
3a273b
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
3a273b
Date: Sun, 1 Sep 2019 00:16:28 +0200
3a273b
Subject: [PATCH] Fix a padding oracle in PKCS7_dataDecode and
3a273b
 CMS_decrypt_set1_pkey
3a273b
3a273b
An attack is simple, if the first CMS_recipientInfo is valid but the
3a273b
second CMS_recipientInfo is chosen ciphertext. If the second
3a273b
recipientInfo decodes to PKCS #1 v1.5 form plaintext, the correct
3a273b
encryption key will be replaced by garbage, and the message cannot be
3a273b
decoded, but if the RSA decryption fails, the correct encryption key is
3a273b
used and the recipient will not notice the attack.
3a273b
3a273b
As a work around for this potential attack the length of the decrypted
3a273b
key must be equal to the cipher default key length, in case the
3a273b
certifiate is not given and all recipientInfo are tried out.
3a273b
3a273b
The old behaviour can be re-enabled in the CMS code by setting the
3a273b
CMS_DEBUG_DECRYPT flag.
3a273b
3a273b
Reviewed-by: Matt Caswell <matt@openssl.org>
3a273b
(Merged from https://github.com/openssl/openssl/pull/9777)
3a273b
3a273b
(cherry picked from commit 5840ed0cd1e6487d247efbc1a04136a41d7b3a37)
3a273b
---
3a273b
 crypto/cms/cms_env.c    | 18 +++++++++++++++++-
3a273b
 crypto/cms/cms_lcl.h    |  2 ++
3a273b
 crypto/cms/cms_smime.c  |  4 ++++
3a273b
 crypto/pkcs7/pk7_doit.c | 12 ++++++++----
3a273b
 5 files changed, 45 insertions(+), 5 deletions(-)
3a273b
3a273b
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
3a273b
index bb95af75e3..25df1c40b1 100644
3a273b
--- a/crypto/cms/cms_env.c
3a273b
+++ b/crypto/cms/cms_env.c
3a273b
@@ -363,6 +363,7 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
3a273b
     unsigned char *ek = NULL;
3a273b
     size_t eklen;
3a273b
     int ret = 0;
3a273b
+    size_t fixlen = 0;
3a273b
     CMS_EncryptedContentInfo *ec;
3a273b
     ec = cms->d.envelopedData->encryptedContentInfo;
3a273b
 
3a273b
@@ -371,6 +372,19 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
3a273b
         return 0;
3a273b
     }
3a273b
 
3a273b
+    if (cms->d.envelopedData->encryptedContentInfo->havenocert
3a273b
+            && !cms->d.envelopedData->encryptedContentInfo->debug) {
3a273b
+        X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
3a273b
+        const EVP_CIPHER *ciph = EVP_get_cipherbyobj(calg->algorithm);
3a273b
+
3a273b
+        if (ciph == NULL) {
3a273b
+            CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER);
3a273b
+            return 0;
3a273b
+        }
3a273b
+
3a273b
+        fixlen = EVP_CIPHER_key_length(ciph);
3a273b
+    }
3a273b
+
3a273b
     ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
3a273b
     if (ktri->pctx == NULL)
3a273b
         return 0;
3a273b
@@ -401,7 +415,9 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
3a273b
 
3a273b
     if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
3a273b
                          ktri->encryptedKey->data,
3a273b
-                         ktri->encryptedKey->length) <= 0) {
3a273b
+                         ktri->encryptedKey->length) <= 0
3a273b
+            || eklen == 0
3a273b
+            || (fixlen != 0 && eklen != fixlen)) {
3a273b
         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
3a273b
         goto err;
3a273b
     }
3a273b
diff --git a/crypto/cms/cms_lcl.h b/crypto/cms/cms_lcl.h
3a273b
index b5c06b7f6c..8eddb02493 100644
3a273b
--- a/crypto/cms/cms_lcl.h
3a273b
+++ b/crypto/cms/cms_lcl.h
3a273b
@@ -125,6 +125,8 @@ struct CMS_EncryptedContentInfo_st {
3a273b
     size_t keylen;
3a273b
     /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
3a273b
     int debug;
3a273b
+    /* Set to 1 if we have no cert and need extra safety measures for MMA */
3a273b
+    int havenocert;
3a273b
 };
3a273b
 
3a273b
 struct CMS_RecipientInfo_st {
3a273b
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
3a273b
index 5dcf803f4b..3a26108b8c 100644
3a273b
--- a/crypto/cms/cms_smime.c
3a273b
+++ b/crypto/cms/cms_smime.c
3a273b
@@ -743,6 +743,10 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
3a273b
         cms->d.envelopedData->encryptedContentInfo->debug = 1;
3a273b
     else
3a273b
         cms->d.envelopedData->encryptedContentInfo->debug = 0;
3a273b
+    if (!cert)
3a273b
+        cms->d.envelopedData->encryptedContentInfo->havenocert = 1;
3a273b
+    else
3a273b
+        cms->d.envelopedData->encryptedContentInfo->havenocert = 0;
3a273b
     if (!pk && !cert && !dcont && !out)
3a273b
         return 1;
3a273b
     if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
3a273b
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
3a273b
index ee08e602a1..15a6160cfe 100644
3a273b
--- a/crypto/pkcs7/pk7_doit.c
3a273b
+++ b/crypto/pkcs7/pk7_doit.c
3a273b
@@ -137,7 +137,8 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
3a273b
 }
3a273b
 
3a273b
 static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
3a273b
-                               PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
3a273b
+                               PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey,
3a273b
+                               size_t fixlen)
3a273b
 {
3a273b
     EVP_PKEY_CTX *pctx = NULL;
3a273b
     unsigned char *ek = NULL;
3a273b
@@ -170,7 +171,9 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
3a273b
     }
3a273b
 
3a273b
     if (EVP_PKEY_decrypt(pctx, ek, &eklen,
3a273b
-                         ri->enc_key->data, ri->enc_key->length) <= 0) {
3a273b
+                         ri->enc_key->data, ri->enc_key->length) <= 0
3a273b
+            || eklen == 0
3a273b
+            || (fixlen != 0 && eklen != fixlen)) {
3a273b
         ret = 0;
3a273b
         PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
3a273b
         goto err;
3a273b
@@ -499,13 +502,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
3a273b
             for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
3a273b
                 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
3a273b
 
3a273b
-                if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
3a273b
+                if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
3a273b
+                        EVP_CIPHER_key_length(evp_cipher)) < 0)
3a273b
                     goto err;
3a273b
                 ERR_clear_error();
3a273b
             }
3a273b
         } else {
3a273b
             /* Only exit on fatal errors, not decrypt failure */
3a273b
-            if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
3a273b
+            if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
3a273b
                 goto err;
3a273b
             ERR_clear_error();
3a273b
         }
3a273b
-- 
3a273b
2.20.1
3a273b