diff --git a/backport-0001-CVE-2020-1971.patch b/backport-0001-CVE-2020-1971.patch new file mode 100644 index 0000000000000000000000000000000000000000..0dc6a22e78bcadf2f1124f0e548f81f8820d052d --- /dev/null +++ b/backport-0001-CVE-2020-1971.patch @@ -0,0 +1,34 @@ +From ae1e7c236db52fea0c84cb84ddbfe3d03c55ba4a Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 11 Nov 2020 15:19:34 +0000 +Subject: [PATCH] DirectoryString is a CHOICE type and therefore uses explicit + tagging + +EDIPartyName has 2 fields that use a DirectoryString. However they were +marked as implicit tagging - which is not correct for a CHOICE type. + +Additionally the partyName field was marked as Optional when, according to +RFC5280 it is not. + +Many thanks to github user @filipnavara for reporting this issue. Also to +David Benjamin from Google who independently identified and reported it. + +Fixes #6859 +--- + crypto/x509v3/v3_genn.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c ++++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c +@@ -72,8 +72,9 @@ ASN1_SEQUENCE(OTHERNAME) = { + IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME) + + ASN1_SEQUENCE(EDIPARTYNAME) = { +- ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), +- ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) ++ /* DirectoryString is a CHOICE type so use explicit tagging */ ++ ASN1_EXP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), ++ ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) + } ASN1_SEQUENCE_END(EDIPARTYNAME) + + IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME) diff --git a/backport-0002-CVE-2020-1971.patch b/backport-0002-CVE-2020-1971.patch new file mode 100644 index 0000000000000000000000000000000000000000..9a38e2c838a7a92e8fc9950c51335398dfdd2139 --- /dev/null +++ b/backport-0002-CVE-2020-1971.patch @@ -0,0 +1,94 @@ +From 84743d3e7fae623c0a20bd727ec6e8c4031bf42f Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 11 Nov 2020 16:12:58 +0000 +Subject: [PATCH] Correctly compare EdiPartyName in GENERAL_NAME_cmp() + +If a GENERAL_NAME field contained EdiPartyName data then it was +incorrectly being handled as type "other". This could lead to a +segmentation fault. + +Many thanks to David Benjamin from Google for reporting this issue. + +CVE-2020-1971 +--- + crypto/x509v3/v3_genn.c | 45 ++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 42 insertions(+), 3 deletions(-) + +--- a/Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c ++++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_genn.c +@@ -108,6 +108,37 @@ GENERAL_NAME *GENERAL_NAME_dup(GENERAL_N + (char *)a); + } + ++static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) ++{ ++ int res; ++ ++ if (a == NULL || b == NULL) { ++ /* ++ * Shouldn't be possible in a valid GENERAL_NAME, but we handle it ++ * anyway. OTHERNAME_cmp treats NULL != NULL so we do the same here ++ */ ++ return -1; ++ } ++ if (a->nameAssigner == NULL && b->nameAssigner != NULL) ++ return -1; ++ if (a->nameAssigner != NULL && b->nameAssigner == NULL) ++ return 1; ++ /* If we get here then both have nameAssigner set, or both unset */ ++ if (a->nameAssigner != NULL) { ++ res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner); ++ if (res != 0) ++ return res; ++ } ++ /* ++ * partyName is required, so these should never be NULL. We treat it in ++ * the same way as the a == NULL || b == NULL case above ++ */ ++ if (a->partyName == NULL || b->partyName == NULL) ++ return -1; ++ ++ return ASN1_STRING_cmp(a->partyName, b->partyName); ++} ++ + /* Returns 0 if they are equal, != 0 otherwise. */ + int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) + { +@@ -117,8 +148,11 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GE + return -1; + switch (a->type) { + case GEN_X400: ++ result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address); ++ break; ++ + case GEN_EDIPARTY: +- result = ASN1_TYPE_cmp(a->d.other, b->d.other); ++ result = edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName); + break; + + case GEN_OTHERNAME: +@@ -165,8 +199,11 @@ void GENERAL_NAME_set0_value(GENERAL_NAM + { + switch (type) { + case GEN_X400: ++ a->d.x400Address = value; ++ break; ++ + case GEN_EDIPARTY: +- a->d.other = value; ++ a->d.ediPartyName = value; + break; + + case GEN_OTHERNAME: +@@ -200,8 +237,10 @@ void *GENERAL_NAME_get0_value(GENERAL_NA + *ptype = a->type; + switch (a->type) { + case GEN_X400: ++ return a->d.x400Address; ++ + case GEN_EDIPARTY: +- return a->d.other; ++ return a->d.ediPartyName; + + case GEN_OTHERNAME: + return a->d.otherName; diff --git a/backport-0003-CVE-2020-1971.patch b/backport-0003-CVE-2020-1971.patch new file mode 100644 index 0000000000000000000000000000000000000000..2dce8108d3ba4f3ed1282ce2d12471e6e6e9763d --- /dev/null +++ b/backport-0003-CVE-2020-1971.patch @@ -0,0 +1,82 @@ +Backport of: + +From c521851116486d0cb351c46506d309dce0ae4c56 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 12 Nov 2020 11:58:12 +0000 +Subject: [PATCH] Check that multi-strings/CHOICE types don't use implicit + tagging + +It never makes sense for multi-string or CHOICE types to use implicit +tagging since the content would be ambiguous. It is an error in the +template if this ever happens. If we detect it we should stop parsing. + +Thanks to David Benjamin from Google for reporting this issue. +--- + crypto/asn1/asn1_err.c | 1 + + crypto/asn1/tasn_dec.c | 19 +++++++++++++++++++ + crypto/err/openssl.txt | 1 + + include/openssl/asn1err.h | 1 + + 4 files changed, 22 insertions(+) + +--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c ++++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c +@@ -202,6 +202,7 @@ static ERR_STRING_DATA ASN1_str_reasons[ + {ERR_REASON(ASN1_R_AUX_ERROR), "aux error"}, + {ERR_REASON(ASN1_R_BAD_CLASS), "bad class"}, + {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"}, ++ {ERR_REASON(ASN1_R_BAD_TEMPLATE), "bad template"}, + {ERR_REASON(ASN1_R_BAD_PASSWORD_READ), "bad password read"}, + {ERR_REASON(ASN1_R_BAD_TAG), "bad tag"}, + {ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), +--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c ++++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c +@@ -223,6 +223,15 @@ static int asn1_item_ex_d2i(ASN1_VALUE * + break; + + case ASN1_ITYPE_MSTRING: ++ /* ++ * It never makes sense for multi-strings to have implicit tagging, so ++ * if tag != -1, then this looks like an error in the template. ++ */ ++ if (tag != -1) { ++ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_BAD_TEMPLATE); ++ goto err; ++ } ++ + p = *in; + /* Just read in tag and class */ + ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, +@@ -240,6 +249,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE * + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); + goto err; + } ++ + /* Check tag matches bit map */ + if (!(ASN1_tag2bit(otag) & it->utype)) { + /* If OPTIONAL, assume this is OK */ +@@ -316,6 +326,15 @@ static int asn1_item_ex_d2i(ASN1_VALUE * + goto err; + + case ASN1_ITYPE_CHOICE: ++ /* ++ * It never makes sense for CHOICE types to have implicit tagging, so ++ * if tag != -1, then this looks like an error in the template. ++ */ ++ if (tag != -1) { ++ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_BAD_TEMPLATE); ++ goto err; ++ } ++ + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; + if (*pval) { +--- a/Cryptlib/Include/openssl/asn1.h ++++ b/Cryptlib/Include/openssl/asn1.h +@@ -1306,6 +1306,7 @@ void ERR_load_ASN1_strings(void); + # define ASN1_R_AUX_ERROR 100 + # define ASN1_R_BAD_CLASS 101 + # define ASN1_R_BAD_OBJECT_HEADER 102 ++# define ASN1_R_BAD_TEMPLATE 230 + # define ASN1_R_BAD_PASSWORD_READ 103 + # define ASN1_R_BAD_TAG 104 + # define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 diff --git a/backport-0004-CVE-2020-1971.patch b/backport-0004-CVE-2020-1971.patch new file mode 100644 index 0000000000000000000000000000000000000000..2914588137389e91900c3ff3469b509542a89a15 --- /dev/null +++ b/backport-0004-CVE-2020-1971.patch @@ -0,0 +1,67 @@ +Backport of: + +From 69f3d3c405991b0d6eea78d554b6aab4daeb4514 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 12 Nov 2020 14:55:31 +0000 +Subject: [PATCH] Complain if we are attempting to encode with an invalid ASN.1 + template + +It never makes sense for multi-string or CHOICE types to have implicit +tagging. If we have a template that uses the in this way then we +should immediately fail. + +Thanks to David Benjamin from Google for reporting this issue. +--- + crypto/asn1/asn1_err.c | 3 ++- + crypto/asn1/tasn_enc.c | 16 ++++++++++++++++ + include/openssl/asn1err.h | 7 +++---- + 3 files changed, 21 insertions(+), 5 deletions(-) + +--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c ++++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c +@@ -103,6 +103,7 @@ static ERR_STRING_DATA ASN1_str_functs[] + {ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"}, ++ {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_I2D), "ASN1_item_ex_i2d"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"}, +--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c ++++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_enc.c +@@ -150,9 +150,25 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, + break; + + case ASN1_ITYPE_MSTRING: ++ /* ++ * It never makes sense for multi-strings to have implicit tagging, so ++ * if tag != -1, then this looks like an error in the template. ++ */ ++ if (tag != -1) { ++ ASN1err(ASN1_F_ASN1_ITEM_EX_I2D, ASN1_R_BAD_TEMPLATE); ++ return -1; ++ } + return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); + + case ASN1_ITYPE_CHOICE: ++ /* ++ * It never makes sense for CHOICE types to have implicit tagging, so ++ * if tag != -1, then this looks like an error in the template. ++ */ ++ if (tag != -1) { ++ ASN1err(ASN1_F_ASN1_ITEM_EX_I2D, ASN1_R_BAD_TEMPLATE); ++ return -1; ++ } + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) + return 0; + i = asn1_get_choice_selector(pval, it); +--- a/Cryptlib/Include/openssl/asn1.h ++++ b/Cryptlib/Include/openssl/asn1.h +@@ -1210,6 +1210,7 @@ void ERR_load_ASN1_strings(void); + # define ASN1_F_ASN1_ITEM_DUP 191 + # define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 + # define ASN1_F_ASN1_ITEM_EX_D2I 120 ++# define ASN1_F_ASN1_ITEM_EX_I2D 144 + # define ASN1_F_ASN1_ITEM_I2D_BIO 192 + # define ASN1_F_ASN1_ITEM_I2D_FP 193 + # define ASN1_F_ASN1_ITEM_PACK 198 diff --git a/backport-CVE-2017-3735.patch b/backport-CVE-2017-3735.patch new file mode 100644 index 0000000000000000000000000000000000000000..002a8db20ea09470a27f79c139ad97cc1115b9a9 --- /dev/null +++ b/backport-CVE-2017-3735.patch @@ -0,0 +1,36 @@ +From 31c8b265591a0aaa462a1f3eb5770661aaac67db Mon Sep 17 00:00:00 2001 +From: Rich Salz +Date: Tue, 22 Aug 2017 11:44:41 -0400 +Subject: [PATCH] Avoid out-of-bounds read + +Fixes CVE 2017-3735 + +Reviewed-by: Kurt Roeckx +(Merged from https://github.com/openssl/openssl/pull/4276) + +(cherry picked from commit b23171744b01e473ebbfd6edad70c1c3825ffbcd) +--- + crypto/x509v3/v3_addr.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c b/Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c +index 1290dec9bb8..af080a04f2b 100644 +--- a/Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c ++++ b/Cryptlib/OpenSSL/crypto/x509v3/v3_addr.c +@@ -130,10 +130,12 @@ static int length_from_afi(const unsigned afi) + */ + unsigned int v3_addr_get_afi(const IPAddressFamily *f) + { +- return ((f != NULL && +- f->addressFamily != NULL && f->addressFamily->data != NULL) +- ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) +- : 0); ++ if (f == NULL ++ || f->addressFamily == NULL ++ || f->addressFamily->data == NULL ++ || f->addressFamily->length < 2) ++ return 0; ++ return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1]; + } + + /* diff --git a/backport-CVE-2017-3737.patch b/backport-CVE-2017-3737.patch new file mode 100644 index 0000000000000000000000000000000000000000..ce895ccbb0c9e34f89541bf8e00964ac2573b474 --- /dev/null +++ b/backport-CVE-2017-3737.patch @@ -0,0 +1,44 @@ +From 898fb884b706aaeb283de4812340bb0bde8476dc Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 29 Nov 2017 14:04:01 +0000 +Subject: [PATCH] Don't allow read/write after fatal error + +OpenSSL 1.0.2 (starting from version 1.0.2b) introduced an "error state" +mechanism. The intent was that if a fatal error occurred during a handshake +then OpenSSL would move into the error state and would immediately fail if +you attempted to continue the handshake. This works as designed for the +explicit handshake functions (SSL_do_handshake(), SSL_accept() and +SSL_connect()), however due to a bug it does not work correctly if +SSL_read() or SSL_write() is called directly. In that scenario, if the +handshake fails then a fatal error will be returned in the initial function +call. If SSL_read()/SSL_write() is subsequently called by the application +for the same SSL object then it will succeed and the data is passed without +being decrypted/encrypted directly from the SSL/TLS record layer. + +In order to exploit this issue an attacker would have to trick an +application into behaving incorrectly by issuing an SSL_read()/SSL_write() +after having already received a fatal error. + +Thanks to David Benjamin (Google) for reporting this issue and suggesting +this fix. + +CVE-2017-3737 + +Reviewed-by: Rich Salz +--- + ssl/ssl.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Cryptlib/Include/openssl/ssl.h b/Cryptlib/Include/openssl/ssl.h +index 90aeb0ce4e1..3cf96a239ba 100644 +--- a/Cryptlib/Include/openssl/ssl.h ++++ b/Cryptlib/Include/openssl/ssl.h +@@ -1727,7 +1727,7 @@ extern "C" { + # define SSL_ST_BEFORE 0x4000 + # define SSL_ST_OK 0x03 + # define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) +-# define SSL_ST_ERR 0x05 ++# define SSL_ST_ERR (0x05|SSL_ST_INIT) + + # define SSL_CB_LOOP 0x01 + # define SSL_CB_EXIT 0x02 diff --git a/backport-CVE-2018-0732.patch b/backport-CVE-2018-0732.patch new file mode 100644 index 0000000000000000000000000000000000000000..570beac3e5fefffbaf76348bd82c75138587a15c --- /dev/null +++ b/backport-CVE-2018-0732.patch @@ -0,0 +1,39 @@ +From 3984ef0b72831da8b3ece4745cac4f8575b19098 Mon Sep 17 00:00:00 2001 +From: Guido Vranken +Date: Mon, 11 Jun 2018 19:38:54 +0200 +Subject: [PATCH] Reject excessively large primes in DH key generation. + +CVE-2018-0732 + +Signed-off-by: Guido Vranken + +(cherry picked from commit 91f7361f47b082ae61ffe1a7b17bb2adf213c7fe) + +Reviewed-by: Tim Hudson +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/6457) +--- + crypto/dh/dh_key.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_key.c b/Cryptlib/OpenSSL/crypto/dh/dh_key.c +index 387558f1467..f235e0d682b 100644 +--- a/Cryptlib/OpenSSL/crypto/dh/dh_key.c ++++ b/Cryptlib/OpenSSL/crypto/dh/dh_key.c +@@ -130,10 +130,15 @@ static int generate_key(DH *dh) + int ok = 0; + int generate_new_key = 0; + unsigned l; +- BN_CTX *ctx; ++ BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + ++ if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { ++ DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); ++ return 0; ++ } ++ + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; diff --git a/backport-CVE-2018-0737.patch b/backport-CVE-2018-0737.patch new file mode 100644 index 0000000000000000000000000000000000000000..e929ec0e8b77f58955039ddd0e870529fa04e0a4 --- /dev/null +++ b/backport-CVE-2018-0737.patch @@ -0,0 +1,28 @@ +From 349a41da1ad88ad87825414752a8ff5fdd6a6c3f Mon Sep 17 00:00:00 2001 +From: Billy Brumley +Date: Wed, 11 Apr 2018 10:10:58 +0300 +Subject: [PATCH] RSA key generation: ensure BN_mod_inverse and BN_mod_exp_mont + both get called with BN_FLG_CONSTTIME flag set. + +CVE-2018-0737 + +Reviewed-by: Rich Salz +Reviewed-by: Matt Caswell +(cherry picked from commit 6939eab03a6e23d2bd2c3f5e34fe1d48e542e787) +--- + crypto/rsa/rsa_gen.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c +index 9ca5dfefb70..42b89a8dfaa 100644 +--- a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c ++++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c +@@ -156,6 +156,8 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + if (BN_copy(rsa->e, e_value) == NULL) + goto err; + ++ BN_set_flags(rsa->p, BN_FLG_CONSTTIME); ++ BN_set_flags(rsa->q, BN_FLG_CONSTTIME); + BN_set_flags(r2, BN_FLG_CONSTTIME); + /* generate p and q */ + for (;;) { diff --git a/backport-CVE-2018-0739.patch b/backport-CVE-2018-0739.patch new file mode 100644 index 0000000000000000000000000000000000000000..2e5d29cb1d55a8aab39205378646818f17fcc489 --- /dev/null +++ b/backport-CVE-2018-0739.patch @@ -0,0 +1,232 @@ +From 9310d45087ae546e27e61ddf8f6367f29848220d Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Thu, 22 Mar 2018 10:05:40 +0000 +Subject: [PATCH] Limit ASN.1 constructed types recursive definition depth + +Constructed types with a recursive definition (such as can be found in +PKCS7) could eventually exceed the stack given malicious input with +excessive recursion. Therefore we limit the stack depth. + +CVE-2018-0739 + +Credit to OSSFuzz for finding this issue. + +Reviewed-by: Rich Salz +--- + crypto/asn1/asn1.h | 1 + + crypto/asn1/asn1_err.c | 3 +- + crypto/asn1/tasn_dec.c | 62 ++++++++++++++++++++++++++++-------------- + 3 files changed, 44 insertions(+), 22 deletions(-) + +diff --git a/Cryptlib/Include/openssl/asn1.h b/Cryptlib/Include/openssl/asn1.h +index 68e791fcdbe..35a2b2aa023 100644 +--- a/Cryptlib/Include/openssl/asn1.h ++++ b/Cryptlib/Include/openssl/asn1.h +@@ -1365,6 +1365,7 @@ void ERR_load_ASN1_strings(void); + # define ASN1_R_MSTRING_NOT_UNIVERSAL 139 + # define ASN1_R_MSTRING_WRONG_TAG 140 + # define ASN1_R_NESTED_ASN1_STRING 197 ++# define ASN1_R_NESTED_TOO_DEEP 219 + # define ASN1_R_NON_HEX_CHARACTERS 141 + # define ASN1_R_NOT_ASCII_FORMAT 190 + # define ASN1_R_NOT_ENOUGH_DATA 142 +diff --git a/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c b/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c +index fd4ac8d9db8..cfc1512f9d0 100644 +--- a/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c ++++ b/Cryptlib/OpenSSL/crypto/asn1/asn1_err.c +@@ -1,6 +1,6 @@ + /* crypto/asn1/asn1_err.c */ + /* ==================================================================== +- * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -279,6 +279,7 @@ static ERR_STRING_DATA ASN1_str_reasons[] = { + {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"}, + {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"}, + {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"}, ++ {ERR_REASON(ASN1_R_NESTED_TOO_DEEP), "nested too deep"}, + {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"}, + {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"}, + {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"}, +diff --git a/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c +index d49a5d5792a..78126e94c37 100644 +--- a/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c ++++ b/Cryptlib/OpenSSL/crypto/asn1/tasn_dec.c +@@ -65,6 +65,14 @@ + #include + #include + ++/* ++ * Constructed types with a recursive definition (such as can be found in PKCS7) ++ * could eventually exceed the stack given malicious input with excessive ++ * recursion. Therefore we limit the stack depth. This is the maximum number of ++ * recursive invocations of asn1_item_embed_d2i(). ++ */ ++#define ASN1_MAX_CONSTRUCTED_NEST 30 ++ + static int asn1_check_eoc(const unsigned char **in, long len); + static int asn1_find_end(const unsigned char **in, long len, char inf); + +@@ -81,11 +89,11 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + static int asn1_template_ex_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, +- ASN1_TLC *ctx); ++ ASN1_TLC *ctx, int depth); + static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, +- ASN1_TLC *ctx); ++ ASN1_TLC *ctx, int depth); + static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, +@@ -154,17 +162,16 @@ int ASN1_template_d2i(ASN1_VALUE **pval, + { + ASN1_TLC c; + asn1_tlc_clear_nc(&c); +- return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); ++ return asn1_template_ex_d2i(pval, in, len, tt, 0, &c, 0); + } + + /* + * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and + * tag mismatch return -1 to handle OPTIONAL + */ +- +-int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, +- const ASN1_ITEM *it, +- int tag, int aclass, char opt, ASN1_TLC *ctx) ++static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, ++ long len, const ASN1_ITEM *it, int tag, int aclass, ++ char opt, ASN1_TLC *ctx, int depth) + { + const ASN1_TEMPLATE *tt, *errtt = NULL; + const ASN1_COMPAT_FUNCS *cf; +@@ -189,6 +196,11 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + else + asn1_cb = 0; + ++ if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { ++ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NESTED_TOO_DEEP); ++ goto err; ++ } ++ + switch (it->itype) { + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { +@@ -204,7 +216,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + goto err; + } + return asn1_template_ex_d2i(pval, in, len, +- it->templates, opt, ctx); ++ it->templates, opt, ctx, depth); + } + return asn1_d2i_ex_primitive(pval, in, len, it, + tag, aclass, opt, ctx); +@@ -326,7 +338,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + /* + * We mark field as OPTIONAL so its absence can be recognised. + */ +- ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); ++ ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); + /* If field not present, try the next one */ + if (ret == -1) + continue; +@@ -444,7 +456,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + * attempt to read in field, allowing each to be OPTIONAL + */ + +- ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); ++ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, ++ depth); + if (!ret) { + errtt = seqtt; + goto err; +@@ -514,6 +527,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + return 0; + } + ++int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, ++ const ASN1_ITEM *it, ++ int tag, int aclass, char opt, ASN1_TLC *ctx) ++{ ++ return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); ++} ++ + /* + * Templates are handled with two separate functions. One handles any + * EXPLICIT tag and the other handles the rest. +@@ -522,7 +542,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + static int asn1_template_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long inlen, + const ASN1_TEMPLATE *tt, char opt, +- ASN1_TLC *ctx) ++ ASN1_TLC *ctx, int depth) + { + int flags, aclass; + int ret; +@@ -557,7 +577,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, + return 0; + } + /* We've found the field so it can't be OPTIONAL now */ +- ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); ++ ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; +@@ -581,7 +601,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, + } + } + } else +- return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx); ++ return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); + + *in = p; + return 1; +@@ -594,7 +614,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, + static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, +- ASN1_TLC *ctx) ++ ASN1_TLC *ctx, int depth) + { + int flags, aclass; + int ret; +@@ -665,8 +685,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, + break; + } + skfield = NULL; +- if (!ASN1_item_ex_d2i(&skfield, &p, len, +- ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { ++ if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), ++ -1, 0, 0, ctx, depth)) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_NESTED_ASN1_ERROR); + goto err; +@@ -684,9 +704,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, + } + } else if (flags & ASN1_TFLG_IMPTAG) { + /* IMPLICIT tagging */ +- ret = ASN1_item_ex_d2i(val, &p, len, +- ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, +- ctx); ++ ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, ++ aclass, opt, ctx, depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; +@@ -694,8 +713,9 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, + return -1; + } else { + /* Nothing special */ +- ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), +- -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); ++ ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), ++ -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, ++ depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; diff --git a/backport-CVE-2019-1563.patch b/backport-CVE-2019-1563.patch new file mode 100644 index 0000000000000000000000000000000000000000..a7e706b708179746ca4d5c7def42bc3423efec43 --- /dev/null +++ b/backport-CVE-2019-1563.patch @@ -0,0 +1,70 @@ +From e21f8cf78a125cd3c8c0d1a1a6c8bb0b901f893f Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +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 +(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(); + } diff --git a/backport-CVE-2021-23840.patch b/backport-CVE-2021-23840.patch new file mode 100644 index 0000000000000000000000000000000000000000..bbcadc4dae0185b465ed597e07dc782044fd1b09 --- /dev/null +++ b/backport-CVE-2021-23840.patch @@ -0,0 +1,79 @@ +Backport of: + +From 6a51b9e1d0cf0bf8515f7201b68fb0a3482b3dc1 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Tue, 2 Feb 2021 17:17:23 +0000 +Subject: [PATCH] Don't overflow the output length in EVP_CipherUpdate calls + +CVE-2021-23840 + +Reviewed-by: Paul Dale +--- + crypto/err/openssl.txt | 3 ++- + crypto/evp/evp_enc.c | 27 +++++++++++++++++++++++++++ + crypto/evp/evp_err.c | 4 +++- + include/openssl/evperr.h | 7 +++---- + 4 files changed, 35 insertions(+), 6 deletions(-) + +--- a/Cryptlib/OpenSSL/crypto/evp/evp_enc.c ++++ b/Cryptlib/OpenSSL/crypto/evp/evp_enc.c +@@ -354,6 +354,19 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ct + return 1; + } else { + j = bl - i; ++ ++ /* ++ * Once we've processed the first j bytes from in, the amount of ++ * data left that is a multiple of the block length is: ++ * (inl - j) & ~(bl - 1) ++ * We must ensure that this amount of data, plus the one block that ++ * we process from ctx->buf does not exceed INT_MAX ++ */ ++ if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) { ++ EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE, ++ EVP_R_OUTPUT_WOULD_OVERFLOW); ++ return 0; ++ } + memcpy(&(ctx->buf[i]), in, j); + if (!M_do_cipher(ctx, out, ctx->buf, bl)) + return 0; +@@ -455,6 +468,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ct + OPENSSL_assert(b <= sizeof ctx->final); + + if (ctx->final_used) { ++ /* ++ * final_used is only ever set if buf_len is 0. Therefore the maximum ++ * length output we will ever see from evp_EncryptDecryptUpdate is ++ * the maximum multiple of the block length that is <= inl, or just: ++ * inl & ~(b - 1) ++ * Since final_used has been set then the final output length is: ++ * (inl & ~(b - 1)) + b ++ * This must never exceed INT_MAX ++ */ ++ if ((inl & ~(b - 1)) > INT_MAX - b) { ++ EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_OUTPUT_WOULD_OVERFLOW); ++ return 0; ++ } + memcpy(out, ctx->final, b); + out += b; + fix_len = 1; +--- a/Cryptlib/OpenSSL/crypto/evp/evp_err.c ++++ b/Cryptlib/OpenSSL/crypto/evp/evp_err.c +@@ -215,6 +215,7 @@ static ERR_STRING_DATA EVP_str_reasons[] + {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), + "operation not supported for this keytype"}, + {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, ++ {ERR_REASON(EVP_R_OUTPUT_WOULD_OVERFLOW), "output would overflow"}, + {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), + "pkcs8 unknown broken type"}, + {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"}, +--- a/Cryptlib/Include/openssl/evp.h ++++ b/Cryptlib/Include/openssl/evp.h +@@ -1509,6 +1509,7 @@ void ERR_load_EVP_strings(void); + # define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 + # define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 + # define EVP_R_OPERATON_NOT_INITIALIZED 151 ++# define EVP_R_OUTPUT_WOULD_OVERFLOW 184 + # define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 + # define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 + # define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 diff --git a/backport-CVE-2021-23841.patch b/backport-CVE-2021-23841.patch new file mode 100644 index 0000000000000000000000000000000000000000..773ea493bf24ca3733c5170b829b53dd35853c55 --- /dev/null +++ b/backport-CVE-2021-23841.patch @@ -0,0 +1,40 @@ +Backport of: + +From 122a19ab48091c657f7cb1fb3af9fc07bd557bbf Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 10 Feb 2021 16:10:36 +0000 +Subject: [PATCH] Fix Null pointer deref in X509_issuer_and_serial_hash() + +The OpenSSL public API function X509_issuer_and_serial_hash() attempts +to create a unique hash value based on the issuer and serial number data +contained within an X509 certificate. However it fails to correctly +handle any errors that may occur while parsing the issuer field (which +might occur if the issuer field is maliciously constructed). This may +subsequently result in a NULL pointer deref and a crash leading to a +potential denial of service attack. + +The function X509_issuer_and_serial_hash() is never directly called by +OpenSSL itself so applications are only vulnerable if they use this +function directly and they use it on certificates that may have been +obtained from untrusted sources. + +CVE-2021-23841 + +Reviewed-by: Richard Levitte +Reviewed-by: Paul Dale +(cherry picked from commit 8130d654d1de922ea224fa18ee3bc7262edc39c0) +--- + crypto/x509/x509_cmp.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/Cryptlib/OpenSSL/crypto/x509/x509_cmp.c ++++ b/Cryptlib/OpenSSL/crypto/x509/x509_cmp.c +@@ -87,6 +87,8 @@ unsigned long X509_issuer_and_serial_has + + EVP_MD_CTX_init(&ctx); + f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0); ++ if (f == NULL) ++ goto err; + if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f))) diff --git a/backport-CVE-2021-3712.patch b/backport-CVE-2021-3712.patch new file mode 100644 index 0000000000000000000000000000000000000000..37680848121dbab1082076d16b1da996c9366467 --- /dev/null +++ b/backport-CVE-2021-3712.patch @@ -0,0 +1,13 @@ +Index: openssl-1.0.2p/crypto/asn1/t_x509a.c +=================================================================== +--- a/Cryptlib/OpenSSL/crypto/asn1/t_x509a.c ++++ b/Cryptlib/OpenSSL/crypto/asn1/t_x509a.c +@@ -104,7 +104,7 @@ int X509_CERT_AUX_print(BIO *out, X509_C + } else + BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); + if (aux->alias) +- BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data); ++ BIO_printf(out, "%*sAlias: %.*s\n", indent, "", aux->alias->length, aux->alias->data); + if (aux->keyid) { + BIO_printf(out, "%*sKey Id: ", indent, ""); + for (i = 0; i < aux->keyid->length; i++) diff --git a/backport-CVE-2022-0778.patch b/backport-CVE-2022-0778.patch new file mode 100644 index 0000000000000000000000000000000000000000..db3376ec4e8f6e56fe1a8cabfcd2e689c3769c57 --- /dev/null +++ b/backport-CVE-2022-0778.patch @@ -0,0 +1,66 @@ +From 3118eb64934499d93db3230748a452351d1d9a65 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Mon, 28 Feb 2022 18:26:21 +0100 +Subject: [PATCH] Fix possible infinite loop in BN_mod_sqrt() + +The calculation in some cases does not finish for non-prime p. + +This fixes CVE-2022-0778. + +Based on patch by David Benjamin . + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +--- + crypto/bn/bn_sqrt.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c b/Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c +index 1723d5ded5a..53b0f559855 100644 +--- a/Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c ++++ b/Cryptlib/OpenSSL/crypto/bn/bn_sqrt.c +@@ -14,7 +14,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + /* + * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks + * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number +- * Theory", algorithm 1.5.1). 'p' must be prime! ++ * Theory", algorithm 1.5.1). 'p' must be prime, otherwise an error or ++ * an incorrect "result" will be returned. + */ + { + BIGNUM *ret = in; +@@ -301,18 +302,23 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + goto vrfy; + } + +- /* find smallest i such that b^(2^i) = 1 */ +- i = 1; +- if (!BN_mod_sqr(t, b, p, ctx)) +- goto end; +- while (!BN_is_one(t)) { +- i++; +- if (i == e) { +- BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); +- goto end; ++ /* Find the smallest i, 0 < i < e, such that b^(2^i) = 1. */ ++ for (i = 1; i < e; i++) { ++ if (i == 1) { ++ if (!BN_mod_sqr(t, b, p, ctx)) ++ goto end; ++ ++ } else { ++ if (!BN_mod_mul(t, t, t, p, ctx)) ++ goto end; + } +- if (!BN_mod_mul(t, t, t, p, ctx)) +- goto end; ++ if (BN_is_one(t)) ++ break; ++ } ++ /* If not found, a is not a square or p is not prime. */ ++ if (i >= e) { ++ BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); ++ goto end; + } + + /* t := y^2^(e - i - 1) */ diff --git a/backport-Fix-an-endless-loop-in-rsa_builtin_keygen.patch b/backport-Fix-an-endless-loop-in-rsa_builtin_keygen.patch new file mode 100644 index 0000000000000000000000000000000000000000..af76bc10b6504a8d391bf27e85669a6e9fd7745d --- /dev/null +++ b/backport-Fix-an-endless-loop-in-rsa_builtin_keygen.patch @@ -0,0 +1,58 @@ +From 32492093722636596018a799c438bfc04c343b40 Mon Sep 17 00:00:00 2001 +From: Rich Salz +Date: Mon, 6 Mar 2017 09:54:17 -0500 +Subject: [PATCH] Fix an endless loop in rsa_builtin_keygen. + +Cherry-picked by Matt Caswell from 69795831. + +Reviewed-by: Richard Levitte +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/4670) +--- + crypto/rsa/rsa_gen.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c +index 082c8da2efc..a85493d6097 100644 +--- a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c ++++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c +@@ -110,6 +110,16 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + int bitsp, bitsq, ok = -1, n = 0; + BN_CTX *ctx = NULL; + ++ /* ++ * When generating ridiculously small keys, we can get stuck ++ * continually regenerating the same prime values. ++ */ ++ if (bits < 16) { ++ ok = 0; /* we set our own err */ ++ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); ++ goto err; ++ } ++ + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; +@@ -161,21 +171,10 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + for (;;) { +- /* +- * When generating ridiculously small keys, we can get stuck +- * continually regenerating the same prime values. Check for this and +- * bail if it happens 3 times. +- */ +- unsigned int degenerate = 0; + do { + if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) + goto err; +- } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); +- if (degenerate == 3) { +- ok = 0; /* we set our own err */ +- RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); +- goto err; +- } ++ } while (BN_cmp(rsa->p, rsa->q) == 0); + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; + if (!BN_gcd(r1, r2, rsa->e, ctx)) diff --git a/backport-Replaced-variable-time-GCD-with-consttime-inversion.patch b/backport-Replaced-variable-time-GCD-with-consttime-inversion.patch new file mode 100644 index 0000000000000000000000000000000000000000..c5b3984d7d8cb211f075d936166f4b8e5b76b016 --- /dev/null +++ b/backport-Replaced-variable-time-GCD-with-consttime-inversion.patch @@ -0,0 +1,79 @@ +From 0b199a883e9170cdfe8e61c150bbaf8d8951f3e7 Mon Sep 17 00:00:00 2001 +From: Samuel Weiser +Date: Tue, 5 Dec 2017 15:55:17 +0100 +Subject: [PATCH] Replaced variable-time GCD with consttime inversion to avoid + side-channel attacks on RSA key generation + +Reviewed-by: Rich Salz +Reviewed-by: Kurt Roeckx +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/5170) + +(cherry picked from commit 9db724cfede4ba7a3668bff533973ee70145ec07) +--- + crypto/rsa/rsa_gen.c | 30 ++++++++++++++++++++++++------ + 1 file changed, 24 insertions(+), 6 deletions(-) + +diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c +index a85493d6097..8553772f062 100644 +--- a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c ++++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c +@@ -109,6 +109,7 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + BIGNUM *pr0, *d, *p; + int bitsp, bitsq, ok = -1, n = 0; + BN_CTX *ctx = NULL; ++ unsigned long error = 0; + + /* + * When generating ridiculously small keys, we can get stuck +@@ -155,16 +156,25 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + if (BN_copy(rsa->e, e_value) == NULL) + goto err; + ++ BN_set_flags(rsa->e, BN_FLG_CONSTTIME); + /* generate p and q */ + for (;;) { + if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) + goto err; + if (!BN_sub(r2, rsa->p, BN_value_one())) + goto err; +- if (!BN_gcd(r1, r2, rsa->e, ctx)) +- goto err; +- if (BN_is_one(r1)) ++ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { ++ /* GCD == 1 since inverse exists */ + break; ++ } ++ error = ERR_peek_last_error(); ++ if (ERR_GET_LIB(error) == ERR_LIB_BN ++ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { ++ /* GCD != 1 */ ++ ERR_clear_error(); ++ } else { ++ goto err; ++ } + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } +@@ -177,10 +187,18 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + } while (BN_cmp(rsa->p, rsa->q) == 0); + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; +- if (!BN_gcd(r1, r2, rsa->e, ctx)) +- goto err; +- if (BN_is_one(r1)) ++ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { ++ /* GCD == 1 since inverse exists */ + break; ++ } ++ error = ERR_peek_last_error(); ++ if (ERR_GET_LIB(error) == ERR_LIB_BN ++ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { ++ /* GCD != 1 */ ++ ERR_clear_error(); ++ } else { ++ goto err; ++ } + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } diff --git a/backport-consttime-flag-changed.patch b/backport-consttime-flag-changed.patch new file mode 100644 index 0000000000000000000000000000000000000000..9b74c567dcd70617fdef00e89e1c01e2665e3e23 --- /dev/null +++ b/backport-consttime-flag-changed.patch @@ -0,0 +1,28 @@ +From 0d6710289307d277ebc3354105c965b6e8ba8eb0 Mon Sep 17 00:00:00 2001 +From: Samuel Weiser +Date: Fri, 9 Feb 2018 14:11:47 +0100 +Subject: [PATCH] consttime flag changed + +Reviewed-by: Rich Salz +Reviewed-by: Kurt Roeckx +Reviewed-by: Matt Caswell +(Merged from https://github.com/openssl/openssl/pull/5170) + +(cherry picked from commit 7150a4720af7913cae16f2e4eaf768b578c0b298) +--- + crypto/rsa/rsa_gen.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c +index 610d82db665..9ca5dfefb70 100644 +--- a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c ++++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c +@@ -156,7 +156,7 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + if (BN_copy(rsa->e, e_value) == NULL) + goto err; + +- BN_set_flags(rsa->e, BN_FLG_CONSTTIME); ++ BN_set_flags(r2, BN_FLG_CONSTTIME); + /* generate p and q */ + for (;;) { + if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) diff --git a/backport-make-update-EVP_F_EVP_DECRYPTDECRYPTUPDATE.patch b/backport-make-update-EVP_F_EVP_DECRYPTDECRYPTUPDATE.patch new file mode 100644 index 0000000000000000000000000000000000000000..65c941d90e4f0a7d6e414977eae71ac0286705ff --- /dev/null +++ b/backport-make-update-EVP_F_EVP_DECRYPTDECRYPTUPDATE.patch @@ -0,0 +1,38 @@ +Backport of: + +From 4bd0db1feaaf97fbc2bd31f54f1fbdeab80b2b1a Mon Sep 17 00:00:00 2001 +From: Richard Levitte +Date: Sun, 9 Dec 2018 14:20:30 +0100 +Subject: [PATCH] make update + +Reviewed-by: Kurt Roeckx +Reviewed-by: Paul Dale +(Merged from https://github.com/openssl/openssl/pull/7852) + +(cherry picked from commit f2f734d4f9e34643a1d3e5b79d2447cd643519f8) +--- + crypto/err/openssl.txt | 1 + + crypto/evp/evp_err.c | 2 ++ + include/openssl/evperr.h | 1 + + 3 files changed, 4 insertions(+) + +--- a/Cryptlib/OpenSSL/crypto/evp/evp_err.c ++++ b/Cryptlib/OpenSSL/crypto/evp/evp_err.c +@@ -94,6 +94,7 @@ static ERR_STRING_DATA EVP_str_functs[] + {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, + {ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"}, + {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, ++ {ERR_FUNC(EVP_F_EVP_ENCRYPTDECRYPTUPDATE), "evp_EncryptDecryptUpdate"}, + {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, + {ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"}, + {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, +--- a/Cryptlib/Include/openssl/evp.h ++++ b/Cryptlib/Include/openssl/evp.h +@@ -1398,6 +1398,7 @@ void ERR_load_EVP_strings(void); + # define EVP_F_EVP_DECRYPTFINAL_EX 101 + # define EVP_F_EVP_DECRYPTUPDATE 166 + # define EVP_F_EVP_DIGESTINIT_EX 128 ++# define EVP_F_EVP_ENCRYPTDECRYPTUPDATE 219 + # define EVP_F_EVP_ENCRYPTFINAL_EX 127 + # define EVP_F_EVP_ENCRYPTUPDATE 167 + # define EVP_F_EVP_MD_CTX_COPY_EX 110 diff --git a/backport-make-update-EVP_F_EVP_DECRYPTUPDATE.patch b/backport-make-update-EVP_F_EVP_DECRYPTUPDATE.patch new file mode 100644 index 0000000000000000000000000000000000000000..85ea54085572d8591ad3ec1e9e36ac82ddfc4cdc --- /dev/null +++ b/backport-make-update-EVP_F_EVP_DECRYPTUPDATE.patch @@ -0,0 +1,41 @@ +Partial backport of: + +From 83151b73a4736bca1797f8edc2b0ad4cf7ac9146 Mon Sep 17 00:00:00 2001 +From: Andy Polyakov +Date: Mon, 25 Jul 2016 15:02:26 +0200 +Subject: [PATCH] evp/evp_enc.c: make assert error message more readable and + add EVPerr(PARTIALLY_OVERLAPPED) + +Reviewed-by: Stephen Henson +--- + crypto/evp/evp_enc.c | 28 +++++++++++++++++++--------- + crypto/evp/evp_err.c | 3 +++ + include/openssl/evp.h | 3 +++ + 3 files changed, 25 insertions(+), 9 deletions(-) + +--- a/Cryptlib/OpenSSL/crypto/evp/evp_err.c ++++ b/Cryptlib/OpenSSL/crypto/evp/evp_err.c +@@ -92,8 +92,10 @@ static ERR_STRING_DATA EVP_str_functs[] + {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), + "EVP_CIPHER_CTX_set_key_length"}, + {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, ++ {ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"}, + {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, + {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, ++ {ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"}, + {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, + {ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"}, + {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"}, +--- a/Cryptlib/Include/openssl/evp.h ++++ b/Cryptlib/Include/openssl/evp.h +@@ -1396,8 +1396,10 @@ void ERR_load_EVP_strings(void); + # define EVP_F_EVP_CIPHER_CTX_CTRL 124 + # define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 + # define EVP_F_EVP_DECRYPTFINAL_EX 101 ++# define EVP_F_EVP_DECRYPTUPDATE 166 + # define EVP_F_EVP_DIGESTINIT_EX 128 + # define EVP_F_EVP_ENCRYPTFINAL_EX 127 ++# define EVP_F_EVP_ENCRYPTUPDATE 167 + # define EVP_F_EVP_MD_CTX_COPY_EX 110 + # define EVP_F_EVP_MD_SIZE 162 + # define EVP_F_EVP_OPENINIT 102 diff --git a/shim.spec b/shim.spec index 46e0cdf24309b7a649c33df6a0eee6edf5f3e024..7d1e9134172e322f9e374d9a08d381275c4d727d 100644 --- a/shim.spec +++ b/shim.spec @@ -22,7 +22,7 @@ Name: shim Version: 15.4 -Release: 4 +Release: 5 Summary: First-stage UEFI bootloader ExclusiveArch: x86_64 aarch64 License: BSD @@ -38,6 +38,24 @@ Patch3: backport-mok-delete-the-existing-RT-variables-only-when-only_.patch Patch4: backport-shim-implement-SBAT-verification-for-the-shim_lock-p.patch Patch5: backport-0001-CVE-2022-28737.patch Patch6: backport-0002-CVE-2022-28737.patch +Patch7: backport-CVE-2017-3735.patch +Patch8: backport-CVE-2017-3737.patch +Patch9: backport-CVE-2018-0732.patch +Patch10: backport-Fix-an-endless-loop-in-rsa_builtin_keygen.patch +Patch11: backport-Replaced-variable-time-GCD-with-consttime-inversion.patch +Patch12: backport-consttime-flag-changed.patch +Patch13: backport-CVE-2018-0737.patch +Patch14: backport-CVE-2018-0739.patch +Patch15: backport-CVE-2019-1563.patch +Patch16: backport-0001-CVE-2020-1971.patch +Patch17: backport-0002-CVE-2020-1971.patch +Patch18: backport-0003-CVE-2020-1971.patch +Patch19: backport-0004-CVE-2020-1971.patch +Patch20: backport-make-update-EVP_F_EVP_DECRYPTUPDATE.patch +Patch21: backport-make-update-EVP_F_EVP_DECRYPTDECRYPTUPDATE.patch +Patch22: backport-CVE-2021-23840.patch +Patch23: backport-CVE-2021-23841.patch +Patch24: backport-CVE-2022-0778.patch BuildRequires: elfutils-libelf-devel openssl-devel openssl git pesign gnu-efi gnu-efi-devel gcc Requires: dbxtool efi-filesystem mokutil @@ -144,6 +162,11 @@ cd .. /usr/src/debug/%{name}-%{version}-%{release}/* %changelog +* Tue Sep 20 2022 jinlun - 15.4-5 +- fix CVE-2017-3735 CVE-2017-3737 CVE-2018-0732 CVE-2018-0737 + CVE-2018-0739 CVE-2019-1563 CVE-2020-1971 CVE-2021-23840 + CVE-2021-23841 CVE-2022-0778 CVE-2021-3712 + * Wed Jul 27 2022 jinlun - 15.4-4 - fix CVE-2022-28737