From b9f0806ce1eae635503e2df1008d851c2d96edec Mon Sep 17 00:00:00 2001
From: CentOS Sources <bugs@centos.org>
Date: Fri, 11 Dec 2020 08:11:45 +0000
Subject: [PATCH] import openssl-1.1.1g-12.el8_3

---
 SOURCES/openssl-1.1.1-CVE-2020-1971.patch   | 713 ++++++++++++++++++++
 SOURCES/openssl-1.1.1-explicit-params.patch | 618 +++++++++++++++++
 SOURCES/openssl-1.1.1-fips-dh.patch         | 242 +++++++
 SOURCES/openssl-1.1.1-kdf-selftest.patch    | 316 ++++++++-
 SPECS/openssl.spec                          |  13 +-
 5 files changed, 1886 insertions(+), 16 deletions(-)
 create mode 100644 SOURCES/openssl-1.1.1-CVE-2020-1971.patch
 create mode 100644 SOURCES/openssl-1.1.1-explicit-params.patch

diff --git a/SOURCES/openssl-1.1.1-CVE-2020-1971.patch b/SOURCES/openssl-1.1.1-CVE-2020-1971.patch
new file mode 100644
index 0000000..b96f9b6
--- /dev/null
+++ b/SOURCES/openssl-1.1.1-CVE-2020-1971.patch
@@ -0,0 +1,713 @@
+diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
+index 613f9ae713..cc0a59ca4c 100644
+--- a/crypto/asn1/asn1_err.c
++++ b/crypto/asn1/asn1_err.c
+@@ -1,6 +1,6 @@
+ /*
+  * Generated by util/mkerr.pl DO NOT EDIT
+- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
++ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+  *
+  * Licensed under the OpenSSL license (the "License").  You may not use
+  * this file except in compliance with the License.  You can obtain a copy
+@@ -49,6 +49,7 @@ static const ERR_STRING_DATA ASN1_str_functs[] = {
+      "asn1_item_embed_d2i"},
+     {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EMBED_NEW, 0),
+      "asn1_item_embed_new"},
++    {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_EX_I2D, 0), "ASN1_item_ex_i2d"},
+     {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_FLAGS_I2D, 0),
+      "asn1_item_flags_i2d"},
+     {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_I2D_BIO, 0), "ASN1_item_i2d_bio"},
+@@ -160,6 +161,7 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = {
+     "asn1 sig parse error"},
+     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_AUX_ERROR), "aux error"},
+     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_OBJECT_HEADER), "bad object header"},
++    {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_TEMPLATE), "bad template"},
+     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BMPSTRING_IS_WRONG_LENGTH),
+     "bmpstring is wrong length"},
+     {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BN_LIB), "bn lib"},
+diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
+index 2332b204ed..1021705f43 100644
+--- a/crypto/asn1/tasn_dec.c
++++ b/crypto/asn1/tasn_dec.c
+@@ -182,6 +182,15 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
+                                      tag, aclass, opt, ctx);
+ 
+     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_EMBED_D2I, ASN1_R_BAD_TEMPLATE);
++            goto err;
++        }
++
+         p = *in;
+         /* Just read in tag and class */
+         ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
+@@ -199,6 +208,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
+             ASN1err(ASN1_F_ASN1_ITEM_EMBED_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 */
+@@ -215,6 +225,15 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
+         return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
+ 
+     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_EMBED_D2I, ASN1_R_BAD_TEMPLATE);
++            goto err;
++        }
++
+         if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+             goto auxerr;
+         if (*pval) {
+diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
+index d600c7a538..52a051d5b1 100644
+--- a/crypto/asn1/tasn_enc.c
++++ b/crypto/asn1/tasn_enc.c
+@@ -103,9 +103,25 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+         return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
+ 
+     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);
+diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
+index 0b5873ebbc..815460b24f 100644
+--- a/crypto/err/openssl.txt
++++ b/crypto/err/openssl.txt
+@@ -36,6 +36,7 @@ ASN1_F_ASN1_ITEM_D2I_FP:206:ASN1_item_d2i_fp
+ ASN1_F_ASN1_ITEM_DUP:191:ASN1_item_dup
+ ASN1_F_ASN1_ITEM_EMBED_D2I:120:asn1_item_embed_d2i
+ ASN1_F_ASN1_ITEM_EMBED_NEW:121:asn1_item_embed_new
++ASN1_F_ASN1_ITEM_EX_I2D:144:ASN1_item_ex_i2d
+ ASN1_F_ASN1_ITEM_FLAGS_I2D:118:asn1_item_flags_i2d
+ ASN1_F_ASN1_ITEM_I2D_BIO:192:ASN1_item_i2d_bio
+ ASN1_F_ASN1_ITEM_I2D_FP:193:ASN1_item_i2d_fp
+@@ -1771,6 +1772,7 @@ ASN1_R_ASN1_PARSE_ERROR:203:asn1 parse error
+ ASN1_R_ASN1_SIG_PARSE_ERROR:204:asn1 sig parse error
+ ASN1_R_AUX_ERROR:100:aux error
+ ASN1_R_BAD_OBJECT_HEADER:102:bad object header
++ASN1_R_BAD_TEMPLATE:230:bad template
+ ASN1_R_BMPSTRING_IS_WRONG_LENGTH:214:bmpstring is wrong length
+ ASN1_R_BN_LIB:105:bn lib
+ ASN1_R_BOOLEAN_IS_WRONG_LENGTH:106:boolean is wrong length
+diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509v3/v3_genn.c
+index 23e3bc4565..6f0a347cce 100644
+--- a/crypto/x509v3/v3_genn.c
++++ b/crypto/x509v3/v3_genn.c
+@@ -22,8 +22,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)
+@@ -57,6 +58,37 @@ GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
+                                     (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)
+ {
+@@ -66,8 +98,11 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
+         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:
+@@ -114,8 +149,11 @@ void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
+ {
+     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:
+@@ -149,8 +187,10 @@ void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype)
+         *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/include/openssl/asn1err.h b/include/openssl/asn1err.h
+index faed5a5518..e1ad1fefec 100644
+--- a/include/openssl/asn1err.h
++++ b/include/openssl/asn1err.h
+@@ -1,6 +1,6 @@
+ /*
+  * Generated by util/mkerr.pl DO NOT EDIT
+- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
++ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+  *
+  * Licensed under the OpenSSL license (the "License").  You may not use
+  * this file except in compliance with the License.  You can obtain a copy
+@@ -11,9 +11,7 @@
+ #ifndef HEADER_ASN1ERR_H
+ # define HEADER_ASN1ERR_H
+ 
+-# ifndef HEADER_SYMHACKS_H
+-#  include <openssl/symhacks.h>
+-# endif
++# include <openssl/symhacks.h>
+ 
+ # ifdef  __cplusplus
+ extern "C"
+@@ -53,6 +51,7 @@ int ERR_load_ASN1_strings(void);
+ # define ASN1_F_ASN1_ITEM_DUP                             191
+ # define ASN1_F_ASN1_ITEM_EMBED_D2I                       120
+ # define ASN1_F_ASN1_ITEM_EMBED_NEW                       121
++# define ASN1_F_ASN1_ITEM_EX_I2D                          144
+ # define ASN1_F_ASN1_ITEM_FLAGS_I2D                       118
+ # define ASN1_F_ASN1_ITEM_I2D_BIO                         192
+ # define ASN1_F_ASN1_ITEM_I2D_FP                          193
+@@ -145,6 +144,7 @@ int ERR_load_ASN1_strings(void);
+ # define ASN1_R_ASN1_SIG_PARSE_ERROR                      204
+ # define ASN1_R_AUX_ERROR                                 100
+ # define ASN1_R_BAD_OBJECT_HEADER                         102
++# define ASN1_R_BAD_TEMPLATE                              230
+ # define ASN1_R_BMPSTRING_IS_WRONG_LENGTH                 214
+ # define ASN1_R_BN_LIB                                    105
+ # define ASN1_R_BOOLEAN_IS_WRONG_LENGTH                   106
+diff --git a/test/asn1_decode_test.c b/test/asn1_decode_test.c
+index 369023d5f1..94a22c6682 100644
+--- a/test/asn1_decode_test.c
++++ b/test/asn1_decode_test.c
+@@ -160,6 +160,41 @@ static int test_uint64(void)
+     return 1;
+ }
+ 
++typedef struct {
++    ASN1_STRING *invalidDirString;
++} INVALIDTEMPLATE;
++
++ASN1_SEQUENCE(INVALIDTEMPLATE) = {
++    /*
++     * DirectoryString is a CHOICE type so it must use explicit tagging -
++     * but we deliberately use implicit here, which makes this template invalid.
++     */
++    ASN1_IMP(INVALIDTEMPLATE, invalidDirString, DIRECTORYSTRING, 12)
++} static_ASN1_SEQUENCE_END(INVALIDTEMPLATE)
++
++IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE)
++IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(INVALIDTEMPLATE)
++
++/* Empty sequence for invalid template test */
++static unsigned char t_invalid_template[] = {
++    0x30, 0x03,                  /* SEQUENCE tag + length */
++    0x0c, 0x01, 0x41             /* UTF8String, length 1, "A" */
++};
++
++static int test_invalid_template(void)
++{
++    const unsigned char *p = t_invalid_template;
++    INVALIDTEMPLATE *tmp = d2i_INVALIDTEMPLATE(NULL, &p,
++                                               sizeof(t_invalid_template));
++
++    /* We expect a NULL pointer return */
++    if (TEST_ptr_null(tmp))
++        return 1;
++
++    INVALIDTEMPLATE_free(tmp);
++    return 0;
++}
++
+ int setup_tests(void)
+ {
+ #if OPENSSL_API_COMPAT < 0x10200000L
+@@ -169,5 +204,6 @@ int setup_tests(void)
+     ADD_TEST(test_uint32);
+     ADD_TEST(test_int64);
+     ADD_TEST(test_uint64);
++    ADD_TEST(test_invalid_template);
+     return 1;
+ }
+diff --git a/test/asn1_encode_test.c b/test/asn1_encode_test.c
+index ed920a4d66..afbd18be6f 100644
+--- a/test/asn1_encode_test.c
++++ b/test/asn1_encode_test.c
+@@ -856,6 +856,38 @@ static int test_uint64(void)
+     return test_intern(&uint64_test_package);
+ }
+ 
++typedef struct {
++    ASN1_STRING *invalidDirString;
++} INVALIDTEMPLATE;
++
++ASN1_SEQUENCE(INVALIDTEMPLATE) = {
++    /*
++     * DirectoryString is a CHOICE type so it must use explicit tagging -
++     * but we deliberately use implicit here, which makes this template invalid.
++     */
++    ASN1_IMP(INVALIDTEMPLATE, invalidDirString, DIRECTORYSTRING, 12)
++} static_ASN1_SEQUENCE_END(INVALIDTEMPLATE)
++
++IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE)
++IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(INVALIDTEMPLATE)
++
++static int test_invalid_template(void)
++{
++    INVALIDTEMPLATE *temp = INVALIDTEMPLATE_new();
++    int ret;
++
++    if (!TEST_ptr(temp))
++        return 0;
++
++    ret = i2d_INVALIDTEMPLATE(temp, NULL);
++
++    INVALIDTEMPLATE_free(temp);
++
++    /* We expect the i2d operation to fail */
++    return ret < 0;
++}
++
++
+ int setup_tests(void)
+ {
+ #if OPENSSL_API_COMPAT < 0x10200000L
+@@ -866,5 +898,6 @@ int setup_tests(void)
+     ADD_TEST(test_uint32);
+     ADD_TEST(test_int64);
+     ADD_TEST(test_uint64);
++    ADD_TEST(test_invalid_template);
+     return 1;
+ }
+diff --git a/test/v3nametest.c b/test/v3nametest.c
+index 86f3829aed..4c8af92ce9 100644
+--- a/test/v3nametest.c
++++ b/test/v3nametest.c
+@@ -359,8 +359,352 @@ static int call_run_cert(int i)
+     return failed == 0;
+ }
+ 
++struct gennamedata {
++    const unsigned char der[22];
++    size_t derlen;
++} gennames[] = {
++    {
++        /*
++        * [0] {
++        *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
++        *   [0] {
++        *     SEQUENCE {}
++        *   }
++        * }
++        */
++        {
++            0xa0, 0x13, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
++            0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x02, 0x30, 0x00
++        },
++        21
++    }, {
++        /*
++        * [0] {
++        *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
++        *   [0] {
++        *     [APPLICATION 0] {}
++        *   }
++        * }
++        */
++        {
++            0xa0, 0x13, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
++            0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x02, 0x60, 0x00
++        },
++        21
++    }, {
++        /*
++        * [0] {
++        *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
++        *   [0] {
++        *     UTF8String { "a" }
++        *   }
++        * }
++        */
++        {
++            0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
++            0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x0c, 0x01, 0x61
++        },
++        22
++    }, {
++        /*
++        * [0] {
++        *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.2 }
++        *   [0] {
++        *     UTF8String { "a" }
++        *   }
++        * }
++        */
++        {
++            0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
++            0x01, 0x84, 0xb7, 0x09, 0x02, 0x02, 0xa0, 0x03, 0x0c, 0x01, 0x61
++        },
++        22
++    }, {
++        /*
++        * [0] {
++        *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
++        *   [0] {
++        *     UTF8String { "b" }
++        *   }
++        * }
++        */
++        {
++            0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
++            0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x0c, 0x01, 0x62
++        },
++        22
++    }, {
++        /*
++        * [0] {
++        *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
++        *   [0] {
++        *     BOOLEAN { TRUE }
++        *   }
++        * }
++        */
++        {
++            0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
++            0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x01, 0x01, 0xff
++        },
++        22
++    }, {
++        /*
++        * [0] {
++        *   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.2.1 }
++        *   [0] {
++        *     BOOLEAN { FALSE }
++        *   }
++        * }
++        */
++        {
++            0xa0, 0x14, 0x06, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04,
++            0x01, 0x84, 0xb7, 0x09, 0x02, 0x01, 0xa0, 0x03, 0x01, 0x01, 0x00
++        },
++        22
++    }, {
++        /* [1 PRIMITIVE] { "a" } */
++        {
++            0x81, 0x01, 0x61
++        },
++        3
++    }, {
++        /* [1 PRIMITIVE] { "b" } */
++        {
++            0x81, 0x01, 0x62
++        },
++        3
++    }, {
++        /* [2 PRIMITIVE] { "a" } */
++        {
++            0x82, 0x01, 0x61
++        },
++        3
++    }, {
++        /* [2 PRIMITIVE] { "b" } */
++        {
++            0x82, 0x01, 0x62
++        },
++        3
++    }, {
++        /*
++        * [4] {
++        *   SEQUENCE {
++        *     SET {
++        *       SEQUENCE {
++        *         # commonName
++        *         OBJECT_IDENTIFIER { 2.5.4.3 }
++        *         UTF8String { "a" }
++        *       }
++        *     }
++        *   }
++        * }
++        */
++        {
++            0xa4, 0x0e, 0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55,
++            0x04, 0x03, 0x0c, 0x01, 0x61
++        },
++        16
++    }, {
++        /*
++        * [4] {
++        *   SEQUENCE {
++        *     SET {
++        *       SEQUENCE {
++        *         # commonName
++        *         OBJECT_IDENTIFIER { 2.5.4.3 }
++        *         UTF8String { "b" }
++        *       }
++        *     }
++        *   }
++        * }
++        */
++        {
++            0xa4, 0x0e, 0x30, 0x0c, 0x31, 0x0a, 0x30, 0x08, 0x06, 0x03, 0x55,
++            0x04, 0x03, 0x0c, 0x01, 0x62
++        },
++        16
++    }, {
++        /*
++        * [5] {
++        *   [1] {
++        *     UTF8String { "a" }
++        *   }
++        * }
++        */
++        {
++            0xa5, 0x05, 0xa1, 0x03, 0x0c, 0x01, 0x61
++        },
++        7
++    }, {
++        /*
++        * [5] {
++        *   [1] {
++        *     UTF8String { "b" }
++        *   }
++        * }
++        */
++        {
++            0xa5, 0x05, 0xa1, 0x03, 0x0c, 0x01, 0x62
++        },
++        7
++    }, {
++        /*
++        * [5] {
++        *   [0] {
++        *     UTF8String {}
++        *   }
++        *   [1] {
++        *     UTF8String { "a" }
++        *   }
++        * }
++        */
++        {
++            0xa5, 0x09, 0xa0, 0x02, 0x0c, 0x00, 0xa1, 0x03, 0x0c, 0x01, 0x61
++        },
++        11
++    }, {
++        /*
++        * [5] {
++        *   [0] {
++        *     UTF8String { "a" }
++        *   }
++        *   [1] {
++        *     UTF8String { "a" }
++        *   }
++        * }
++        */
++        {
++            0xa5, 0x0a, 0xa0, 0x03, 0x0c, 0x01, 0x61, 0xa1, 0x03, 0x0c, 0x01,
++            0x61
++        },
++        12
++    }, {
++        /*
++        * [5] {
++        *   [0] {
++        *     UTF8String { "b" }
++        *   }
++        *   [1] {
++        *     UTF8String { "a" }
++        *   }
++        * }
++        */
++        {
++            0xa5, 0x0a, 0xa0, 0x03, 0x0c, 0x01, 0x62, 0xa1, 0x03, 0x0c, 0x01,
++            0x61
++        },
++        12
++    }, {
++        /* [6 PRIMITIVE] { "a" } */
++        {
++            0x86, 0x01, 0x61
++        },
++        3
++    }, {
++        /* [6 PRIMITIVE] { "b" } */
++        {
++            0x86, 0x01, 0x62
++        },
++        3
++    }, {
++        /* [7 PRIMITIVE] { `11111111` } */
++        {
++            0x87, 0x04, 0x11, 0x11, 0x11, 0x11
++        },
++        6
++    }, {
++        /* [7 PRIMITIVE] { `22222222`} */
++        {
++            0x87, 0x04, 0x22, 0x22, 0x22, 0x22
++        },
++        6
++    }, {
++        /* [7 PRIMITIVE] { `11111111111111111111111111111111` } */
++        {
++            0x87, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
++            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
++        },
++        18
++    }, {
++        /* [7 PRIMITIVE] { `22222222222222222222222222222222` } */
++        {
++            0x87, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
++            0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22
++        },
++        18
++    }, {
++        /* [8 PRIMITIVE] { 1.2.840.113554.4.1.72585.2.1 } */
++        {
++            0x88, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84,
++            0xb7, 0x09, 0x02, 0x01
++        },
++        15
++    }, {
++        /* [8 PRIMITIVE] { 1.2.840.113554.4.1.72585.2.2 } */
++        {
++            0x88, 0x0d, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84,
++            0xb7, 0x09, 0x02, 0x02
++        },
++        15
++    }
++};
++
++static int test_GENERAL_NAME_cmp(void)
++{
++    size_t i, j;
++    GENERAL_NAME **namesa = OPENSSL_malloc(sizeof(*namesa)
++                                           * OSSL_NELEM(gennames));
++    GENERAL_NAME **namesb = OPENSSL_malloc(sizeof(*namesb)
++                                           * OSSL_NELEM(gennames));
++    int testresult = 0;
++
++    if (!TEST_ptr(namesa) || !TEST_ptr(namesb))
++        goto end;
++
++    for (i = 0; i < OSSL_NELEM(gennames); i++) {
++        const unsigned char *derp = gennames[i].der;
++
++        /*
++         * We create two versions of each GENERAL_NAME so that we ensure when
++         * we compare them they are always different pointers.
++         */
++        namesa[i] = d2i_GENERAL_NAME(NULL, &derp, gennames[i].derlen);
++        derp = gennames[i].der;
++        namesb[i] = d2i_GENERAL_NAME(NULL, &derp, gennames[i].derlen);
++        if (!TEST_ptr(namesa[i]) || !TEST_ptr(namesb[i]))
++            goto end;
++    }
++
++    /* Every name should be equal to itself and not equal to any others. */
++    for (i = 0; i < OSSL_NELEM(gennames); i++) {
++        for (j = 0; j < OSSL_NELEM(gennames); j++) {
++            if (i == j) {
++                if (!TEST_int_eq(GENERAL_NAME_cmp(namesa[i], namesb[j]), 0))
++                    goto end;
++            } else {
++                if (!TEST_int_ne(GENERAL_NAME_cmp(namesa[i], namesb[j]), 0))
++                    goto end;
++            }
++        }
++    }
++    testresult = 1;
++
++ end:
++    for (i = 0; i < OSSL_NELEM(gennames); i++) {
++        if (namesa != NULL)
++            GENERAL_NAME_free(namesa[i]);
++        if (namesb != NULL)
++            GENERAL_NAME_free(namesb[i]);
++    }
++    OPENSSL_free(namesa);
++    OPENSSL_free(namesb);
++
++    return testresult;
++}
++
+ int setup_tests(void)
+ {
+     ADD_ALL_TESTS(call_run_cert, OSSL_NELEM(name_fns));
++    ADD_TEST(test_GENERAL_NAME_cmp);
+     return 1;
+ }
diff --git a/SOURCES/openssl-1.1.1-explicit-params.patch b/SOURCES/openssl-1.1.1-explicit-params.patch
new file mode 100644
index 0000000..82fb429
--- /dev/null
+++ b/SOURCES/openssl-1.1.1-explicit-params.patch
@@ -0,0 +1,618 @@
+diff -up openssl-1.1.1g/crypto/ec/ec_asn1.c.explicit-params openssl-1.1.1g/crypto/ec/ec_asn1.c
+--- openssl-1.1.1g/crypto/ec/ec_asn1.c.explicit-params	2020-04-21 14:22:39.000000000 +0200
++++ openssl-1.1.1g/crypto/ec/ec_asn1.c	2020-10-23 15:27:31.304312344 +0200
+@@ -137,6 +137,12 @@ struct ec_parameters_st {
+     ASN1_INTEGER *cofactor;
+ } /* ECPARAMETERS */ ;
+ 
++typedef enum {
++    ECPKPARAMETERS_TYPE_NAMED = 0,
++    ECPKPARAMETERS_TYPE_EXPLICIT,
++    ECPKPARAMETERS_TYPE_IMPLICIT
++} ecpk_parameters_type_t;
++
+ struct ecpk_parameters_st {
+     int type;
+     union {
+@@ -535,9 +541,10 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparamet
+             return NULL;
+         }
+     } else {
+-        if (ret->type == 0)
++        if (ret->type == ECPKPARAMETERS_TYPE_NAMED)
+             ASN1_OBJECT_free(ret->value.named_curve);
+-        else if (ret->type == 1 && ret->value.parameters)
++        else if (ret->type == ECPKPARAMETERS_TYPE_EXPLICIT
++                 && ret->value.parameters != NULL)
+             ECPARAMETERS_free(ret->value.parameters);
+     }
+ 
+@@ -547,7 +554,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparamet
+          */
+         tmp = EC_GROUP_get_curve_name(group);
+         if (tmp) {
+-            ret->type = 0;
++            ret->type = ECPKPARAMETERS_TYPE_NAMED;
+             if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
+                 ok = 0;
+         } else
+@@ -555,7 +562,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparamet
+             ok = 0;
+     } else {
+         /* use the ECPARAMETERS structure */
+-        ret->type = 1;
++        ret->type = ECPKPARAMETERS_TYPE_EXPLICIT;
+         if ((ret->value.parameters =
+              EC_GROUP_get_ecparameters(group, NULL)) == NULL)
+             ok = 0;
+@@ -894,7 +901,8 @@ EC_GROUP *EC_GROUP_new_from_ecpkparamete
+         return NULL;
+     }
+ 
+-    if (params->type == 0) {    /* the curve is given by an OID */
++    if (params->type == ECPKPARAMETERS_TYPE_NAMED) {
++        /* the curve is given by an OID */
+         tmp = OBJ_obj2nid(params->value.named_curve);
+         if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
+             ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS,
+@@ -902,15 +910,16 @@ EC_GROUP *EC_GROUP_new_from_ecpkparamete
+             return NULL;
+         }
+         EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
+-    } else if (params->type == 1) { /* the parameters are given by a
+-                                     * ECPARAMETERS structure */
++    } else if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT) {
++        /* the parameters are given by an ECPARAMETERS structure */
+         ret = EC_GROUP_new_from_ecparameters(params->value.parameters);
+         if (!ret) {
+             ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, ERR_R_EC_LIB);
+             return NULL;
+         }
+         EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE);
+-    } else if (params->type == 2) { /* implicitlyCA */
++    } else if (params->type == ECPKPARAMETERS_TYPE_IMPLICIT) {
++        /* implicit parameters inherited from CA - unsupported */
+         return NULL;
+     } else {
+         ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_ASN1_ERROR);
+@@ -940,6 +949,9 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **
+         return NULL;
+     }
+ 
++    if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT)
++        group->decoded_from_explicit_params = 1;
++
+     if (a) {
+         EC_GROUP_free(*a);
+         *a = group;
+@@ -991,6 +1003,9 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, con
+     if (priv_key->parameters) {
+         EC_GROUP_free(ret->group);
+         ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters);
++        if (ret->group != NULL
++            && priv_key->parameters->type == ECPKPARAMETERS_TYPE_EXPLICIT)
++            ret->group->decoded_from_explicit_params = 1;
+     }
+ 
+     if (ret->group == NULL) {
+diff -up openssl-1.1.1g/crypto/ec/ec_key.c.explicit-params openssl-1.1.1g/crypto/ec/ec_key.c
+--- openssl-1.1.1g/crypto/ec/ec_key.c.explicit-params	2020-10-23 15:27:31.296312275 +0200
++++ openssl-1.1.1g/crypto/ec/ec_key.c	2020-10-23 15:27:31.304312344 +0200
+@@ -566,6 +566,13 @@ void EC_KEY_clear_flags(EC_KEY *key, int
+     key->flags &= ~flags;
+ }
+ 
++int EC_KEY_decoded_from_explicit_params(const EC_KEY *key)
++{
++    if (key == NULL || key->group == NULL)
++        return -1;
++    return key->group->decoded_from_explicit_params;
++}
++
+ size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
+                         unsigned char **pbuf, BN_CTX *ctx)
+ {
+diff -up openssl-1.1.1g/crypto/ec/ec_lib.c.explicit-params openssl-1.1.1g/crypto/ec/ec_lib.c
+--- openssl-1.1.1g/crypto/ec/ec_lib.c.explicit-params	2020-04-21 14:22:39.000000000 +0200
++++ openssl-1.1.1g/crypto/ec/ec_lib.c	2020-10-23 15:27:31.304312344 +0200
+@@ -211,6 +211,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const
+ 
+     dest->asn1_flag = src->asn1_flag;
+     dest->asn1_form = src->asn1_form;
++    dest->decoded_from_explicit_params = src->decoded_from_explicit_params;
+ 
+     if (src->seed) {
+         OPENSSL_free(dest->seed);
+diff -up openssl-1.1.1g/crypto/ec/ec_local.h.explicit-params openssl-1.1.1g/crypto/ec/ec_local.h
+--- openssl-1.1.1g/crypto/ec/ec_local.h.explicit-params	2020-10-23 15:27:31.281312147 +0200
++++ openssl-1.1.1g/crypto/ec/ec_local.h	2020-10-23 15:27:31.304312344 +0200
+@@ -217,6 +217,8 @@ struct ec_group_st {
+     BIGNUM *order, *cofactor;
+     int curve_name;             /* optional NID for named curve */
+     int asn1_flag;              /* flag to control the asn1 encoding */
++    int decoded_from_explicit_params; /* set if decoded from explicit
++                                       * curve parameters encoding */
+     point_conversion_form_t asn1_form;
+     unsigned char *seed;        /* optional seed for parameters (appears in
+                                  * ASN1) */
+diff -up openssl-1.1.1g/crypto/x509/x509_txt.c.explicit-params openssl-1.1.1g/crypto/x509/x509_txt.c
+--- openssl-1.1.1g/crypto/x509/x509_txt.c.explicit-params	2020-04-21 14:22:39.000000000 +0200
++++ openssl-1.1.1g/crypto/x509/x509_txt.c	2020-10-23 15:27:31.305312352 +0200
+@@ -174,6 +174,8 @@ const char *X509_verify_cert_error_strin
+         return "OCSP verification failed";
+     case X509_V_ERR_OCSP_CERT_UNKNOWN:
+         return "OCSP unknown cert";
++    case X509_V_ERR_EC_KEY_EXPLICIT_PARAMS:
++        return "Certificate public key has explicit ECC parameters";
+ 
+     default:
+         /* Printing an error number into a static buffer is not thread-safe */
+diff -up openssl-1.1.1g/crypto/x509/x509_vfy.c.explicit-params openssl-1.1.1g/crypto/x509/x509_vfy.c
+--- openssl-1.1.1g/crypto/x509/x509_vfy.c.explicit-params	2020-10-23 15:27:31.252311900 +0200
++++ openssl-1.1.1g/crypto/x509/x509_vfy.c	2020-10-23 15:27:31.305312352 +0200
+@@ -80,6 +80,7 @@ static int get_issuer_sk(X509 **issuer,
+ static int check_dane_issuer(X509_STORE_CTX *ctx, int depth);
+ static int check_key_level(X509_STORE_CTX *ctx, X509 *cert);
+ static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert);
++static int check_curve(X509 *cert);
+ 
+ static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
+                          unsigned int *preasons, X509_CRL *crl, X509 *x);
+@@ -508,6 +509,14 @@ static int check_chain_extensions(X509_S
+                 ret = 1;
+             break;
+         }
++        if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && num > 1) {
++            /* Check for presence of explicit elliptic curve parameters */
++            ret = check_curve(x);
++            if (ret < 0)
++                ctx->error = X509_V_ERR_UNSPECIFIED;
++            else if (ret == 0)
++                ctx->error = X509_V_ERR_EC_KEY_EXPLICIT_PARAMS;
++        }
+         if ((x->ex_flags & EXFLAG_CA) == 0
+             && x->ex_pathlen != -1
+             && (ctx->param->flags & X509_V_FLAG_X509_STRICT)) {
+@@ -3259,6 +3268,32 @@ static int check_key_level(X509_STORE_CT
+ }
+ 
+ /*
++ * Check whether the public key of ``cert`` does not use explicit params
++ * for an elliptic curve.
++ *
++ * Returns 1 on success, 0 if check fails, -1 for other errors.
++ */
++static int check_curve(X509 *cert)
++{
++#ifndef OPENSSL_NO_EC
++    EVP_PKEY *pkey = X509_get0_pubkey(cert);
++
++    /* Unsupported or malformed key */
++    if (pkey == NULL)
++        return -1;
++
++    if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
++        int ret;
++
++        ret = EC_KEY_decoded_from_explicit_params(EVP_PKEY_get0_EC_KEY(pkey));
++        return ret < 0 ? ret : !ret;
++    }
++#endif
++
++    return 1;
++}
++
++/*
+  * Check whether the signature digest algorithm of ``cert`` meets the security
+  * level of ``ctx``.  Should not be checked for trust anchors (whether
+  * self-signed or otherwise).
+diff -up openssl-1.1.1g/doc/man3/EC_KEY_new.pod.explicit-params openssl-1.1.1g/doc/man3/EC_KEY_new.pod
+--- openssl-1.1.1g/doc/man3/EC_KEY_new.pod.explicit-params	2020-04-21 14:22:39.000000000 +0200
++++ openssl-1.1.1g/doc/man3/EC_KEY_new.pod	2020-10-23 15:27:31.305312352 +0200
+@@ -9,7 +9,8 @@ EC_KEY_get0_engine,
+ EC_KEY_get0_group, EC_KEY_set_group, EC_KEY_get0_private_key,
+ EC_KEY_set_private_key, EC_KEY_get0_public_key, EC_KEY_set_public_key,
+ EC_KEY_get_conv_form,
+-EC_KEY_set_conv_form, EC_KEY_set_asn1_flag, EC_KEY_precompute_mult,
++EC_KEY_set_conv_form, EC_KEY_set_asn1_flag,
++EC_KEY_decoded_from_explicit_params, EC_KEY_precompute_mult,
+ EC_KEY_generate_key, EC_KEY_check_key, EC_KEY_set_public_key_affine_coordinates,
+ EC_KEY_oct2key, EC_KEY_key2buf, EC_KEY_oct2priv, EC_KEY_priv2oct,
+ EC_KEY_priv2buf - Functions for creating, destroying and manipulating
+@@ -38,6 +39,7 @@ EC_KEY objects
+  point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
+  void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
+  void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
++ int EC_KEY_decoded_from_explicit_params(const EC_KEY *key);
+  int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
+  int EC_KEY_generate_key(EC_KEY *key);
+  int EC_KEY_check_key(const EC_KEY *key);
+@@ -118,6 +120,10 @@ EC_KEY_set_asn1_flag() sets the asn1_fla
+ (if set). Refer to L<EC_GROUP_copy(3)> for further information on the
+ asn1_flag.
+ 
++EC_KEY_decoded_from_explicit_params() returns 1 if the group of the I<key> was
++decoded from data with explicitly encoded group parameters, -1 if the I<key>
++is NULL or the group parameters are missing, and 0 otherwise.
++
+ EC_KEY_precompute_mult() stores multiples of the underlying EC_GROUP generator
+ for faster point multiplication. See also L<EC_POINT_add(3)>.
+ 
+diff -up openssl-1.1.1g/include/openssl/ec.h.explicit-params openssl-1.1.1g/include/openssl/ec.h
+--- openssl-1.1.1g/include/openssl/ec.h.explicit-params	2020-04-21 14:22:39.000000000 +0200
++++ openssl-1.1.1g/include/openssl/ec.h	2020-10-23 15:27:31.305312352 +0200
+@@ -829,6 +829,8 @@ void EC_KEY_set_flags(EC_KEY *key, int f
+ 
+ void EC_KEY_clear_flags(EC_KEY *key, int flags);
+ 
++int EC_KEY_decoded_from_explicit_params(const EC_KEY *key);
++
+ /** Creates a new EC_KEY object using a named curve as underlying
+  *  EC_GROUP object.
+  *  \param  nid  NID of the named curve.
+diff -up openssl-1.1.1g/include/openssl/x509_vfy.h.explicit-params openssl-1.1.1g/include/openssl/x509_vfy.h
+--- openssl-1.1.1g/include/openssl/x509_vfy.h.explicit-params	2020-04-21 14:22:39.000000000 +0200
++++ openssl-1.1.1g/include/openssl/x509_vfy.h	2020-10-23 15:27:31.305312352 +0200
+@@ -184,6 +184,7 @@ void X509_STORE_CTX_set_depth(X509_STORE
+ # define         X509_V_ERR_OCSP_VERIFY_NEEDED                   73  /* Need OCSP verification */
+ # define         X509_V_ERR_OCSP_VERIFY_FAILED                   74  /* Couldn't verify cert through OCSP */
+ # define         X509_V_ERR_OCSP_CERT_UNKNOWN                    75  /* Certificate wasn't recognized by the OCSP responder */
++# define         X509_V_ERR_EC_KEY_EXPLICIT_PARAMS               79
+ 
+ /* Certificate verify flags */
+ 
+diff -up openssl-1.1.1g/ssl/statem/statem_lib.c.explicit-params openssl-1.1.1g/ssl/statem/statem_lib.c
+--- openssl-1.1.1g/ssl/statem/statem_lib.c.explicit-params	2020-10-23 15:27:31.249311874 +0200
++++ openssl-1.1.1g/ssl/statem/statem_lib.c	2020-10-23 15:27:31.305312352 +0200
+@@ -1341,6 +1341,7 @@ int tls_get_message_body(SSL *s, size_t
+ static const X509ERR2ALERT x509table[] = {
+     {X509_V_ERR_APPLICATION_VERIFICATION, SSL_AD_HANDSHAKE_FAILURE},
+     {X509_V_ERR_CA_KEY_TOO_SMALL, SSL_AD_BAD_CERTIFICATE},
++    {X509_V_ERR_EC_KEY_EXPLICIT_PARAMS, SSL_AD_BAD_CERTIFICATE},
+     {X509_V_ERR_CA_MD_TOO_WEAK, SSL_AD_BAD_CERTIFICATE},
+     {X509_V_ERR_CERT_CHAIN_TOO_LONG, SSL_AD_UNKNOWN_CA},
+     {X509_V_ERR_CERT_HAS_EXPIRED, SSL_AD_CERTIFICATE_EXPIRED},
+diff -up openssl-1.1.1g/test/certs/ca-cert-ec-explicit.pem.explicit-params openssl-1.1.1g/test/certs/ca-cert-ec-explicit.pem
+--- openssl-1.1.1g/test/certs/ca-cert-ec-explicit.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ca-cert-ec-explicit.pem	2020-10-23 15:27:31.305312352 +0200
+@@ -0,0 +1,19 @@
++-----BEGIN CERTIFICATE-----
++MIIDGDCCAgCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
++IENBMCAXDTIwMDkxNTEzMDY0MVoYDzIxMjAwOTE2MTMwNjQxWjANMQswCQYDVQQD
++DAJDQTCCAUswggEDBgcqhkjOPQIBMIH3AgEBMCwGByqGSM49AQECIQD/////AAAA
++AQAAAAAAAAAAAAAAAP///////////////zBbBCD/////AAAAAQAAAAAAAAAAAAAA
++AP///////////////AQgWsY12Ko6k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsD
++FQDEnTYIhucEk2pmeOETnSa3gZ9+kARBBGsX0fLhLEJH+Lzm5WOkQPJ3A32BLesz
++oPShOUXYmMKWT+NC4v4af5uO5+tKfA+eFivOM1drMV7Oy7ZAaDe/UfUCIQD/////
++AAAAAP//////////vOb6racXnoTzucrC/GMlUQIBAQNCAASlXna3kSD/Yol3RA5I
++icjIxYb9UJoCTzb/LsxjlOvIS5OqCTzpqP0p3JrnvLPsbzq7Cf/g0bNlxAGs1iVM
++5NDco1MwUTAdBgNVHQ4EFgQUFk6ucH6gMXeadmuV7a1iWEnU/CIwHwYDVR0jBBgw
++FoAUjvUlrx6ba4Q9fICayVOcTXL3o1IwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
++9w0BAQsFAAOCAQEAdyUgfT0eAsZzoHFXoWN5uqi0MHuhLI37TEzkH5h7iTpDQJTQ
++F0SjbawfM/nxxUekRW3mjFu3lft+VA7yC0OTNBLffan/vTh+HGOvvYZSMJYgKrMG
++PRWgDId+n9RTcQCf+91cISvOazHixRiJG7JfRLdNZsAE+miw4HgPLFboTwpxtTDJ
++zJ4ssBC6P+5IHwBCtNMiilJMMMzuSaZa5iSo6M9AdXWfcQN3uhW1lgQOLOlKLcbo
++3UhW1GMMhTTeytM5aylbKhRsnL7ozmS44zsKZ25YaQxgjdKitFjVN6j7eyQ7C9J2
++bLXgl3APweLQbGGs0zv08Ad0SCCKYLHK6mMJqg==
++-----END CERTIFICATE-----
+diff -up openssl-1.1.1g/test/certs/ca-cert-ec-named.pem.explicit-params openssl-1.1.1g/test/certs/ca-cert-ec-named.pem
+--- openssl-1.1.1g/test/certs/ca-cert-ec-named.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ca-cert-ec-named.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,14 @@
++-----BEGIN CERTIFICATE-----
++MIICJDCCAQygAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
++IENBMCAXDTIwMDkxNTEzMDY1MFoYDzIxMjAwOTE2MTMwNjUwWjANMQswCQYDVQQD
++DAJDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPt+MXCi9+wztEvmdG2EVSk7
++bAiJMXJXW/u0NbcGCrrbhO1NJSHHV3Lks888sqeSPh/bif/ASJ0HX+VarMUoFIKj
++UzBRMB0GA1UdDgQWBBRjigU5REz8Lwf1iD6mALVhsHIanjAfBgNVHSMEGDAWgBSO
++9SWvHptrhD18gJrJU5xNcvejUjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
++CwUAA4IBAQCQs9wpblefb2C9a7usGL1DJjWJQIFHtUf+6p/KPgEV7LF138ECjL5s
++0AWRd8Q8SbsBH49j2r3LLLMkvFglyRaN+FF+TCC/UQtclTb4+HgLsUT2xSU8U2cY
++SOnzNB5AX/qAAsdOGqOjivPtGXcXFexDKPsw3n+3rJgymBP6hbLagb47IabNhot5
++bMM6S+bmfpMwfsm885zr5vG2Gg9FjjH94Vx4I7eRLkjCS88gkIR1J35ecHFteOdo
++idOaCHQddYiKukBzgdjtTxSDXKffkaybylrwOZ8VBlQd3zC7s02d+riHCnroLnnE
++cwYLlJ5z6jN7zoPZ55yX/EmA0RVny2le
++-----END CERTIFICATE-----
+diff -up openssl-1.1.1g/test/certs/ca-key-ec-explicit.pem.explicit-params openssl-1.1.1g/test/certs/ca-key-ec-explicit.pem
+--- openssl-1.1.1g/test/certs/ca-key-ec-explicit.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ca-key-ec-explicit.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,10 @@
++-----BEGIN PRIVATE KEY-----
++MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAAB
++AAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA
++///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMV
++AMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg
++9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8A
++AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBG0wawIBAQQgdEf20fpuqEZU
++tZ4ORoq4vb5ETV4a6QOl/iGnDQt++/ihRANCAASlXna3kSD/Yol3RA5IicjIxYb9
++UJoCTzb/LsxjlOvIS5OqCTzpqP0p3JrnvLPsbzq7Cf/g0bNlxAGs1iVM5NDc
++-----END PRIVATE KEY-----
+diff -up openssl-1.1.1g/test/certs/ca-key-ec-named.pem.explicit-params openssl-1.1.1g/test/certs/ca-key-ec-named.pem
+--- openssl-1.1.1g/test/certs/ca-key-ec-named.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ca-key-ec-named.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,5 @@
++-----BEGIN PRIVATE KEY-----
++MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgCTrYrMKcyV49+w4B
++TWr2WTZsMM4aFpaYulKAuhiuQ7mhRANCAAT7fjFwovfsM7RL5nRthFUpO2wIiTFy
++V1v7tDW3Bgq624TtTSUhx1dy5LPPPLKnkj4f24n/wEidB1/lWqzFKBSC
++-----END PRIVATE KEY-----
+diff -up openssl-1.1.1g/test/certs/ee-cert-ec-explicit.pem.explicit-params openssl-1.1.1g/test/certs/ee-cert-ec-explicit.pem
+--- openssl-1.1.1g/test/certs/ee-cert-ec-explicit.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ee-cert-ec-explicit.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,16 @@
++-----BEGIN CERTIFICATE-----
++MIIChzCCAi6gAwIBAgIBAjAKBggqhkjOPQQDAjANMQswCQYDVQQDDAJDQTAgFw0y
++MDA5MTUxMzE0MzlaGA8yMTIwMDkxNjEzMTQzOVowGTEXMBUGA1UEAwwOc2VydmVy
++LmV4YW1wbGUwggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA////
++/wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAA
++AAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n
++0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9
++gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA
++/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAE+7TDP7C9VqQP
++TnqoJc/Fvf/N45BX+lBfmfiGBeRKtSsvrERUlymzQ4/nxVtymozAgFxQ0my998HH
++TSVCj7Sq56N9MHswHQYDVR0OBBYEFKKwEfKYhNv6fbQf0Xd0te7J3GZdMB8GA1Ud
++IwQYMBaAFGOKBTlETPwvB/WIPqYAtWGwchqeMAkGA1UdEwQCMAAwEwYDVR0lBAww
++CgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4YW1wbGUwCgYIKoZIzj0E
++AwIDRwAwRAIgb4UITAOFlATeaayWQX9r5gf61qcnzT7TjXCekf7ww9oCIBDltg/u
++ZvS9gqviMFuPjTuk/FhsCTAUzTT7WmgcWeH7
++-----END CERTIFICATE-----
+diff -up openssl-1.1.1g/test/certs/ee-cert-ec-named-explicit.pem.explicit-params openssl-1.1.1g/test/certs/ee-cert-ec-named-explicit.pem
+--- openssl-1.1.1g/test/certs/ee-cert-ec-named-explicit.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ee-cert-ec-named-explicit.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,11 @@
++-----BEGIN CERTIFICATE-----
++MIIBlDCCATqgAwIBAgIBAjAKBggqhkjOPQQDAjANMQswCQYDVQQDDAJDQTAgFw0y
++MDA5MTUxMzE0NDVaGA8yMTIwMDkxNjEzMTQ0NVowGTEXMBUGA1UEAwwOc2VydmVy
++LmV4YW1wbGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQv5PnMStW/Wx9lpvjl
++JTsFIjc2wBv14sNuMh1hfNX8ZJcoCfAAKYu6ujxXt328GWBMaubRbBjOd/eqpEst
++tYKzo30wezAdBgNVHQ4EFgQUmb/qcE413hkpmtjEMyRZZFcN1TYwHwYDVR0jBBgw
++FoAUFk6ucH6gMXeadmuV7a1iWEnU/CIwCQYDVR0TBAIwADATBgNVHSUEDDAKBggr
++BgEFBQcDATAZBgNVHREEEjAQgg5zZXJ2ZXIuZXhhbXBsZTAKBggqhkjOPQQDAgNI
++ADBFAiEA9y6J8rdAbO0mDZscIb8rIn6HgxBW4WAqTlFeZeHjjOYCIAmt2ldyObOL
++tXaiaxYX3WAOR1vmfzsdrkCAOCfAkpbo
++-----END CERTIFICATE-----
+diff -up openssl-1.1.1g/test/certs/ee-cert-ec-named-named.pem.explicit-params openssl-1.1.1g/test/certs/ee-cert-ec-named-named.pem
+--- openssl-1.1.1g/test/certs/ee-cert-ec-named-named.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ee-cert-ec-named-named.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,11 @@
++-----BEGIN CERTIFICATE-----
++MIIBkzCCATqgAwIBAgIBAjAKBggqhkjOPQQDAjANMQswCQYDVQQDDAJDQTAgFw0y
++MDA5MTUxNDEwNDhaGA8yMTIwMDkxNjE0MTA0OFowGTEXMBUGA1UEAwwOc2VydmVy
++LmV4YW1wbGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS0YU57+RFRWxr/frnL
+++vOYkY3h9roKnvxCG07wK5tevEYtSdKz0KsHvDBDatw1r3JNv+m2p54/3AqFPAZ3
++5b0Po30wezAdBgNVHQ4EFgQUypypuZrUl0BEmbuhfJpo3QFNIvUwHwYDVR0jBBgw
++FoAUY4oFOURM/C8H9Yg+pgC1YbByGp4wCQYDVR0TBAIwADATBgNVHSUEDDAKBggr
++BgEFBQcDATAZBgNVHREEEjAQgg5zZXJ2ZXIuZXhhbXBsZTAKBggqhkjOPQQDAgNH
++ADBEAiAEkKD7H5uxQ4YbQOiN4evbu5RCV5W7TVE80iBfcY5u4wIgGcwr++lVNX0Q
++CTT+M3ukDjOA8OEvKUz1TiDuRAQ29qU=
++-----END CERTIFICATE-----
+diff -up openssl-1.1.1g/test/certs/ee-key-ec-explicit.pem.explicit-params openssl-1.1.1g/test/certs/ee-key-ec-explicit.pem
+--- openssl-1.1.1g/test/certs/ee-key-ec-explicit.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ee-key-ec-explicit.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,10 @@
++-----BEGIN PRIVATE KEY-----
++MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAAB
++AAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA
++///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMV
++AMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg
++9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8A
++AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBG0wawIBAQQg0cmpcTcEYG5G
++ZaVkGjtsBc3sLZn1EuV9qNK2qx6iNzmhRANCAAT7tMM/sL1WpA9Oeqglz8W9/83j
++kFf6UF+Z+IYF5Eq1Ky+sRFSXKbNDj+fFW3KajMCAXFDSbL33wcdNJUKPtKrn
++-----END PRIVATE KEY-----
+diff -up openssl-1.1.1g/test/certs/ee-key-ec-named-explicit.pem.explicit-params openssl-1.1.1g/test/certs/ee-key-ec-named-explicit.pem
+--- openssl-1.1.1g/test/certs/ee-key-ec-named-explicit.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ee-key-ec-named-explicit.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,5 @@
++-----BEGIN PRIVATE KEY-----
++MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg2ue+X5ZFJPJPQG2E
++WQY4ALv2PkPp2Gy6KrMiokgmjkehRANCAAQv5PnMStW/Wx9lpvjlJTsFIjc2wBv1
++4sNuMh1hfNX8ZJcoCfAAKYu6ujxXt328GWBMaubRbBjOd/eqpEsttYKz
++-----END PRIVATE KEY-----
+diff -up openssl-1.1.1g/test/certs/ee-key-ec-named-named.pem.explicit-params openssl-1.1.1g/test/certs/ee-key-ec-named-named.pem
+--- openssl-1.1.1g/test/certs/ee-key-ec-named-named.pem.explicit-params	2020-10-23 15:27:31.306312361 +0200
++++ openssl-1.1.1g/test/certs/ee-key-ec-named-named.pem	2020-10-23 15:27:31.306312361 +0200
+@@ -0,0 +1,5 @@
++-----BEGIN PRIVATE KEY-----
++MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGSoneIKG3//ujXGu
++/EoJdNhpKZj026EF/YQ5FblUBWahRANCAAS0YU57+RFRWxr/frnL+vOYkY3h9roK
++nvxCG07wK5tevEYtSdKz0KsHvDBDatw1r3JNv+m2p54/3AqFPAZ35b0P
++-----END PRIVATE KEY-----
+diff -up openssl-1.1.1g/test/certs/setup.sh.explicit-params openssl-1.1.1g/test/certs/setup.sh
+--- openssl-1.1.1g/test/certs/setup.sh.explicit-params	2020-04-21 14:22:39.000000000 +0200
++++ openssl-1.1.1g/test/certs/setup.sh	2020-10-23 15:27:31.306312361 +0200
+@@ -116,6 +116,10 @@ openssl x509 -in ca-cert-md5.pem -trusto
+ # CA has 768-bit key
+ OPENSSL_KEYBITS=768 \
+ ./mkcert.sh genca "CA" ca-key-768 ca-cert-768 root-key root-cert
++# EC cert with explicit curve
++./mkcert.sh genca "CA" ca-key-ec-explicit ca-cert-ec-explicit root-key root-cert
++# EC cert with named curve
++./mkcert.sh genca "CA" ca-key-ec-named ca-cert-ec-named root-key root-cert
+ 
+ # client intermediate ca: cca-cert
+ # trust variants: +serverAuth, -serverAuth, +clientAuth, -clientAuth
+@@ -184,6 +188,14 @@ OPENSSL_SIGALG=md5 \
+ # 768-bit leaf key
+ OPENSSL_KEYBITS=768 \
+ ./mkcert.sh genee server.example ee-key-768 ee-cert-768 ca-key ca-cert
++# EC cert with explicit curve signed by named curve ca
++./mkcert.sh genee server.example ee-key-ec-explicit ee-cert-ec-explicit ca-key-ec-named ca-cert-ec-named
++# EC cert with named curve signed by explicit curve ca
++./mkcert.sh genee server.example ee-key-ec-named-explicit \
++    ee-cert-ec-named-explicit ca-key-ec-explicit ca-cert-ec-explicit
++# EC cert with named curve signed by named curve ca
++./mkcert.sh genee server.example ee-key-ec-named-named \
++    ee-cert-ec-named-named ca-key-ec-named ca-cert-ec-named
+ 
+ # Proxy certificates, off of ee-client
+ # Start with some good ones
+diff -up openssl-1.1.1g/test/ec_internal_test.c.explicit-params openssl-1.1.1g/test/ec_internal_test.c
+--- openssl-1.1.1g/test/ec_internal_test.c.explicit-params	2020-04-21 14:22:39.000000000 +0200
++++ openssl-1.1.1g/test/ec_internal_test.c	2020-10-23 15:27:31.306312361 +0200
+@@ -183,6 +183,106 @@ static int field_tests_default(int n)
+     return ret;
+ }
+ 
++/*
++ * Tests behavior of the decoded_from_explicit_params flag and API
++ */
++static int decoded_flag_test(void)
++{
++    EC_GROUP *grp;
++    EC_GROUP *grp_copy = NULL;
++    ECPARAMETERS *ecparams = NULL;
++    ECPKPARAMETERS *ecpkparams = NULL;
++    EC_KEY *key = NULL;
++    unsigned char *encodedparams = NULL;
++    const unsigned char *encp;
++    int encodedlen;
++    int testresult = 0;
++
++    /* Test EC_GROUP_new not setting the flag */
++    grp = EC_GROUP_new(EC_GFp_simple_method());
++    if (!TEST_ptr(grp)
++        || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
++        goto err;
++    EC_GROUP_free(grp);
++
++    /* Test EC_GROUP_new_by_curve_name not setting the flag */
++    grp = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
++    if (!TEST_ptr(grp)
++        || !TEST_int_eq(grp->decoded_from_explicit_params, 0))
++        goto err;
++
++    /* Test EC_GROUP_new_from_ecparameters not setting the flag */
++    if (!TEST_ptr(ecparams = EC_GROUP_get_ecparameters(grp, NULL))
++        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecparameters(ecparams))
++        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
++        goto err;
++    EC_GROUP_free(grp_copy);
++    grp_copy = NULL;
++    ECPARAMETERS_free(ecparams);
++    ecparams = NULL;
++
++    /* Test EC_GROUP_new_from_ecpkparameters not setting the flag */
++    if (!TEST_int_eq(EC_GROUP_get_asn1_flag(grp), OPENSSL_EC_NAMED_CURVE)
++        || !TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
++        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
++        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0)
++        || !TEST_ptr(key = EC_KEY_new())
++    /* Test EC_KEY_decoded_from_explicit_params on key without a group */
++        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), -1)
++        || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
++    /* Test EC_KEY_decoded_from_explicit_params negative case */
++        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 0))
++        goto err;
++    EC_GROUP_free(grp_copy);
++    grp_copy = NULL;
++    ECPKPARAMETERS_free(ecpkparams);
++    ecpkparams = NULL;
++
++    /* Test d2i_ECPKParameters with named params not setting the flag */
++    if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
++        || !TEST_ptr(encp = encodedparams)
++        || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
++        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
++        goto err;
++    EC_GROUP_free(grp_copy);
++    grp_copy = NULL;
++    OPENSSL_free(encodedparams);
++    encodedparams = NULL;
++
++    /* Asn1 flag stays set to explicit with EC_GROUP_new_from_ecpkparameters */
++    EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_EXPLICIT_CURVE);
++    if (!TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL))
++        || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams))
++        || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
++        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0))
++        goto err;
++    EC_GROUP_free(grp_copy);
++    grp_copy = NULL;
++
++    /* Test d2i_ECPKParameters with explicit params setting the flag */
++    if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0)
++        || !TEST_ptr(encp = encodedparams)
++        || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen))
++        || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE)
++        || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 1)
++        || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1)
++    /* Test EC_KEY_decoded_from_explicit_params positive case */
++        || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 1))
++        goto err;
++
++    testresult = 1;
++
++ err:
++    EC_KEY_free(key);
++    EC_GROUP_free(grp);
++    EC_GROUP_free(grp_copy);
++    ECPARAMETERS_free(ecparams);
++    ECPKPARAMETERS_free(ecpkparams);
++    OPENSSL_free(encodedparams);
++
++    return testresult;
++}
++
+ int setup_tests(void)
+ {
+     crv_len = EC_get_builtin_curves(NULL, 0);
+@@ -196,6 +296,7 @@ int setup_tests(void)
+     ADD_TEST(field_tests_ec2_simple);
+ #endif
+     ADD_ALL_TESTS(field_tests_default, crv_len);
++    ADD_TEST(decoded_flag_test);
+     return 1;
+ }
+ 
+diff -up openssl-1.1.1g/test/recipes/25-test_verify.t.explicit-params openssl-1.1.1g/test/recipes/25-test_verify.t
+--- openssl-1.1.1g/test/recipes/25-test_verify.t.explicit-params	2020-10-23 15:27:31.253311908 +0200
++++ openssl-1.1.1g/test/recipes/25-test_verify.t	2020-10-23 15:27:31.306312361 +0200
+@@ -27,7 +27,7 @@ sub verify {
+     run(app([@args]));
+ }
+ 
+-plan tests => 137;
++plan tests => 142;
+ 
+ # Canonical success
+ ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
+@@ -280,6 +280,27 @@ ok(verify("ee-cert-md5", "sslserver", ["
+ ok(!verify("ee-cert-md5", "sslserver", ["root-cert"], ["ca-cert"]),
+    "reject md5 leaf at auth level 1");
+ 
++# Explicit vs named curve tests
++SKIP: {
++    skip "EC is not supported by this OpenSSL build", 5
++        if disabled("ec");
++    ok(verify("ee-cert-ec-explicit", "sslserver", ["root-cert"],
++               ["ca-cert-ec-named"]),
++        "accept explicit curve leaf with named curve intermediate without strict");
++    ok(verify("ee-cert-ec-named-explicit", "sslserver", ["root-cert"],
++               ["ca-cert-ec-explicit"]),
++        "accept named curve leaf with explicit curve intermediate without strict");
++    ok(!verify("ee-cert-ec-explicit", "sslserver", ["root-cert"],
++               ["ca-cert-ec-named"], "-x509_strict"),
++        "reject explicit curve leaf with named curve intermediate with strict");
++    ok(!verify("ee-cert-ec-named-explicit", "sslserver", ["root-cert"],
++               ["ca-cert-ec-explicit"], "-x509_strict"),
++        "reject named curve leaf with explicit curve intermediate with strict");
++    ok(verify("ee-cert-ec-named-named", "sslserver", ["root-cert"],
++              ["ca-cert-ec-named"], "-x509_strict"),
++        "accept named curve leaf with named curve intermediate with strict");
++}
++
+ # Depth tests, note the depth limit bounds the number of CA certificates
+ # between the trust-anchor and the leaf, so, for example, with a root->ca->leaf
+ # chain, depth = 1 is sufficient, but depth == 0 is not.
+diff -up openssl-1.1.1g/util/libcrypto.num.explicit-params openssl-1.1.1g/util/libcrypto.num
+--- openssl-1.1.1g/util/libcrypto.num.explicit-params	2020-10-23 15:27:31.265312011 +0200
++++ openssl-1.1.1g/util/libcrypto.num	2020-10-23 15:31:37.424413877 +0200
+@@ -4587,6 +4587,7 @@ EVP_PKEY_meth_set_digestverify
+ EVP_PKEY_meth_get_digestverify          4541	1_1_1e	EXIST::FUNCTION:
+ EVP_PKEY_meth_get_digestsign            4542	1_1_1e	EXIST::FUNCTION:
+ RSA_get0_pss_params                     4543	1_1_1e	EXIST::FUNCTION:RSA
++EC_KEY_decoded_from_explicit_params     4547	1_1_1h	EXIST::FUNCTION:EC
+ FIPS_drbg_reseed                        6348	1_1_0g	EXIST::FUNCTION:
+ FIPS_selftest_check                     6349	1_1_0g	EXIST::FUNCTION:
+ FIPS_rand_set_method                    6350	1_1_0g	EXIST::FUNCTION:
diff --git a/SOURCES/openssl-1.1.1-fips-dh.patch b/SOURCES/openssl-1.1.1-fips-dh.patch
index d98372e..6a1c4a6 100644
--- a/SOURCES/openssl-1.1.1-fips-dh.patch
+++ b/SOURCES/openssl-1.1.1-fips-dh.patch
@@ -2448,6 +2448,248 @@ diff -up openssl-1.1.1g/crypto/evp/p_lib.c.fips-dh openssl-1.1.1g/crypto/evp/p_l
      int ret = EVP_PKEY_assign(pkey, type, key);
  
      if (ret)
+diff -up openssl-1.1.1g/crypto/fips/fips_dh_selftest.c.fips-dh openssl-1.1.1g/crypto/fips/fips_dh_selftest.c
+--- openssl-1.1.1g/crypto/fips/fips_dh_selftest.c.fips-dh	2020-09-17 14:38:55.074927727 +0200
++++ openssl-1.1.1g/crypto/fips/fips_dh_selftest.c	2020-10-22 16:06:54.406229842 +0200
+@@ -59,107 +59,141 @@
+ 
+ #ifdef OPENSSL_FIPS
+ 
+-static const unsigned char dh_test_2048_p[] = {
+-    0xAE, 0xEC, 0xEE, 0x22, 0xFA, 0x3A, 0xA5, 0x22, 0xC0, 0xDE, 0x0F, 0x09,
+-    0x7E, 0x17, 0xC0, 0x05, 0xF9, 0xF1, 0xE7, 0xC6, 0x87, 0x14, 0x6D, 0x11,
+-    0xE7, 0xAE, 0xED, 0x2F, 0x72, 0x59, 0xC5, 0xA9, 0x9B, 0xB8, 0x02, 0xA5,
+-    0xF3, 0x69, 0x70, 0xD6, 0xDD, 0x90, 0xF9, 0x19, 0x79, 0xBE, 0x60, 0x8F,
+-    0x25, 0x92, 0x30, 0x1C, 0x51, 0x51, 0x38, 0x26, 0x82, 0x25, 0xE6, 0xFC,
+-    0xED, 0x65, 0x96, 0x8F, 0x57, 0xE5, 0x53, 0x8B, 0x38, 0x63, 0xC7, 0xCE,
+-    0xBC, 0x1B, 0x4D, 0x18, 0x2A, 0x5B, 0x04, 0x3F, 0x6A, 0x3C, 0x94, 0x39,
+-    0xAE, 0x36, 0xD6, 0x5E, 0x0F, 0xA2, 0xCC, 0xD0, 0xD4, 0xD5, 0xC6, 0x1E,
+-    0xF6, 0xA0, 0xF5, 0x89, 0x4E, 0xB4, 0x0B, 0xA4, 0xB3, 0x2B, 0x3D, 0xE2,
+-    0x4E, 0xE1, 0x49, 0x25, 0x99, 0x5F, 0x32, 0x16, 0x33, 0x32, 0x1B, 0x7A,
+-    0xA5, 0x5C, 0x6B, 0x34, 0x0D, 0x39, 0x99, 0xDC, 0xF0, 0x76, 0xE5, 0x5A,
+-    0xD4, 0x71, 0x00, 0xED, 0x5A, 0x73, 0xFB, 0xC8, 0x01, 0xAD, 0x99, 0xCF,
+-    0x99, 0x52, 0x7C, 0x9C, 0x64, 0xC6, 0x76, 0x40, 0x57, 0xAF, 0x59, 0xD7,
+-    0x38, 0x0B, 0x40, 0xDE, 0x33, 0x0D, 0xB8, 0x76, 0xEC, 0xA9, 0xD8, 0x73,
+-    0xF8, 0xEF, 0x26, 0x66, 0x06, 0x27, 0xDD, 0x7C, 0xA4, 0x10, 0x9C, 0xA6,
+-    0xAA, 0xF9, 0x53, 0x62, 0x73, 0x1D, 0xBA, 0x1C, 0xF1, 0x67, 0xF4, 0x35,
+-    0xED, 0x6F, 0x37, 0x92, 0xE8, 0x4F, 0x6C, 0xBA, 0x52, 0x6E, 0xA1, 0xED,
+-    0xDA, 0x9F, 0x85, 0x11, 0x82, 0x52, 0x62, 0x08, 0x44, 0xF1, 0x30, 0x03,
+-    0xC3, 0x38, 0x2C, 0x79, 0xBD, 0xD4, 0x43, 0x45, 0xEE, 0x8E, 0x50, 0xFC,
+-    0x29, 0x46, 0x9A, 0xFE, 0x54, 0x1A, 0x19, 0x8F, 0x4B, 0x84, 0x08, 0xDE,
+-    0x20, 0x62, 0x73, 0xCC, 0xDD, 0x7E, 0xF0, 0xEF, 0xA2, 0xFD, 0x86, 0x58,
+-    0x4B, 0xD8, 0x37, 0xEB
++static const unsigned char dh_test_2048_priv_key[] = {
++    0x0C, 0x4B, 0x30, 0x89, 0xD1, 0xB8, 0x62, 0xCB,
++    0x3C, 0x43, 0x64, 0x91, 0xF0, 0x91, 0x54, 0x70,
++    0xC5, 0x27, 0x96, 0xE3, 0xAC, 0xBE, 0xE8, 0x00,
++    0xEC, 0x55, 0xF6, 0xCC
+ };
+ 
+-static const unsigned char dh_test_2048_g[] = {
+-    0x02
++static const unsigned char dh_test_2048_pub_key[] = {
++    0xE8, 0x8B, 0xEC, 0x36, 0x93, 0xB4, 0x94, 0x44,
++    0xA3, 0x7D, 0x09, 0x5C, 0x0B, 0x60, 0x79, 0x4B,
++    0x2B, 0xCA, 0xCF, 0xB7, 0x16, 0x30, 0x4A, 0xD0,
++    0xEA, 0x23, 0x04, 0x24, 0x8C, 0x50, 0x82, 0x11,
++    0x79, 0x4C, 0x57, 0x6F, 0x96, 0xAC, 0xF9, 0x78,
++    0x38, 0x83, 0x03, 0x0B, 0x77, 0x47, 0xB7, 0x84,
++    0xB9, 0x6F, 0xE6, 0xB9, 0xCC, 0xA7, 0x2B, 0x94,
++    0xAE, 0x8A, 0xCA, 0x58, 0x15, 0x7B, 0xA0, 0x73,
++    0x5D, 0xD4, 0xD7, 0xC6, 0xBA, 0xA6, 0x03, 0x30,
++    0x6B, 0x52, 0x85, 0x94, 0x57, 0x11, 0xFB, 0xAA,
++    0x83, 0x71, 0x5E, 0x0E, 0xC4, 0x86, 0x89, 0xF8,
++    0x38, 0x5A, 0xAE, 0x66, 0xF2, 0xA1, 0x67, 0xE0,
++    0xF5, 0x7A, 0x38, 0xE6, 0x21, 0x98, 0xF0, 0x33,
++    0xD6, 0xD7, 0x27, 0x82, 0xED, 0xDE, 0x73, 0x52,
++    0xD4, 0x2C, 0xCF, 0x0A, 0xB1, 0xA1, 0xA0, 0x5A,
++    0xCE, 0x05, 0x40, 0xE7, 0xF7, 0x0C, 0xE2, 0x63,
++    0x21, 0xA0, 0xF3, 0x26, 0x9B, 0xEC, 0x6B, 0x33,
++    0x4D, 0x34, 0x9B, 0x8D, 0x86, 0x10, 0xB8, 0xE8,
++    0x96, 0x84, 0x66, 0x49, 0x27, 0xED, 0x2B, 0x76,
++    0x19, 0xF6, 0x9C, 0xCB, 0x71, 0x4F, 0xF9, 0x16,
++    0xB4, 0xD0, 0xC6, 0x49, 0x7A, 0x53, 0xDD, 0x53,
++    0xA1, 0x0E, 0x0B, 0xB6, 0x33, 0xC4, 0xE9, 0xCF,
++    0x5A, 0x1E, 0x4D, 0xC8, 0xE3, 0x1F, 0x14, 0x9D,
++    0xF0, 0x14, 0x70, 0x39, 0x50, 0x21, 0x8A, 0xEA,
++    0x7C, 0x72, 0xA3, 0x3F, 0x67, 0x5C, 0x1E, 0x32,
++    0xA7, 0x5D, 0x78, 0xCC, 0xE3, 0xA9, 0x03, 0x76,
++    0x4A, 0xD4, 0x65, 0x0E, 0x11, 0xEF, 0x56, 0x25,
++    0xE5, 0x78, 0x1A, 0xA8, 0x49, 0x8C, 0x14, 0x2E,
++    0xF7, 0xFA, 0x70, 0x27, 0xB1, 0x89, 0x66, 0x8F,
++    0xFA, 0xFC, 0xED, 0x15, 0x98, 0xE8, 0x0D, 0x72,
++    0x17, 0x02, 0x67, 0x14, 0x55, 0x6C, 0x32, 0x98,
++    0x59, 0xF3, 0x17, 0xBC, 0x55, 0xA1, 0x39, 0x69
+ };
+ 
+-static const unsigned char dh_test_2048_pub_key[] = {
+-    0xA0, 0x39, 0x11, 0x77, 0x9A, 0xC1, 0x30, 0x1F, 0xBE, 0x48, 0xA7, 0xAA,
+-    0xA0, 0x84, 0x54, 0x64, 0xAD, 0x1B, 0x70, 0xFA, 0x13, 0x55, 0x63, 0xD2,
+-    0x1F, 0x62, 0x32, 0x93, 0x8E, 0xC9, 0x3E, 0x09, 0xA7, 0x64, 0xE4, 0x12,
+-    0x6E, 0x1B, 0xF2, 0x92, 0x3B, 0xB9, 0xCB, 0x56, 0xEA, 0x07, 0x88, 0xB5,
+-    0xA6, 0xBC, 0x16, 0x1F, 0x27, 0xFE, 0xD8, 0xAA, 0x40, 0xB2, 0xB0, 0x2D,
+-    0x37, 0x76, 0xA6, 0xA4, 0x82, 0x2C, 0x0E, 0x22, 0x64, 0x9D, 0xCB, 0xD1,
+-    0x00, 0xB7, 0x89, 0x14, 0x72, 0x4E, 0xBE, 0x48, 0x41, 0xF8, 0xB2, 0x51,
+-    0x11, 0x09, 0x4B, 0x22, 0x01, 0x23, 0x39, 0x96, 0xE0, 0x15, 0xD7, 0x9F,
+-    0x60, 0xD1, 0xB7, 0xAE, 0xFE, 0x5F, 0xDB, 0xE7, 0x03, 0x17, 0x97, 0xA6,
+-    0x16, 0x74, 0xBD, 0x53, 0x81, 0x19, 0xC5, 0x47, 0x5E, 0xCE, 0x8D, 0xED,
+-    0x45, 0x5D, 0x3C, 0x00, 0xA0, 0x0A, 0x68, 0x6A, 0xE0, 0x8E, 0x06, 0x46,
+-    0x6F, 0xD7, 0xF9, 0xDF, 0x31, 0x7E, 0x77, 0x44, 0x0D, 0x98, 0xE0, 0xCA,
+-    0x98, 0x09, 0x52, 0x04, 0x90, 0xEA, 0x6D, 0xF4, 0x30, 0x69, 0x8F, 0xB1,
+-    0x9B, 0xC1, 0x43, 0xDB, 0xD5, 0x8D, 0xC8, 0x8E, 0xB6, 0x0B, 0x05, 0xBE,
+-    0x0E, 0xC5, 0x99, 0xC8, 0x6E, 0x4E, 0xF3, 0xCB, 0xC3, 0x5E, 0x9B, 0x53,
+-    0xF7, 0x06, 0x1C, 0x4F, 0xC7, 0xB8, 0x6E, 0x30, 0x18, 0xCA, 0x9B, 0xB9,
+-    0xBC, 0x5F, 0x17, 0x72, 0x29, 0x5A, 0xE5, 0xD9, 0x96, 0xB7, 0x0B, 0xF3,
+-    0x2D, 0x8C, 0xF1, 0xE1, 0x0E, 0x0D, 0x74, 0xD5, 0x9D, 0xF0, 0x06, 0xA9,
+-    0xB4, 0x95, 0x63, 0x76, 0x46, 0x55, 0x48, 0x82, 0x39, 0x90, 0xEF, 0x56,
+-    0x75, 0x34, 0xB8, 0x34, 0xC3, 0x18, 0x6E, 0x1E, 0xAD, 0xE3, 0x48, 0x7E,
+-    0x93, 0x2C, 0x23, 0xE7, 0xF8, 0x90, 0x73, 0xB1, 0x77, 0x80, 0x67, 0xA9,
+-    0x36, 0x9E, 0xDA, 0xD2
++static const unsigned char dh_test_2048_peer_key[] = {
++    0xD3, 0xAA, 0x26, 0x20, 0x2C, 0x02, 0x38, 0x0A,
++    0x2E, 0x4D, 0xC0, 0x62, 0xCB, 0xD8, 0x7F, 0xF2,
++    0x54, 0x23, 0xC3, 0x90, 0x33, 0xD8, 0xF7, 0x93,
++    0xAD, 0x5F, 0xDA, 0xE6, 0xA4, 0xAB, 0x29, 0xE1,
++    0x4B, 0x75, 0xE8, 0x3B, 0x4E, 0xC7, 0xB5, 0x43,
++    0xCD, 0xF7, 0xB9, 0x0F, 0x43, 0x68, 0xED, 0xF7,
++    0xD1, 0xFD, 0x13, 0x39, 0xCA, 0x39, 0x35, 0x39,
++    0xB4, 0x5A, 0x12, 0x96, 0xC6, 0x85, 0xEC, 0x80,
++    0xC0, 0x0D, 0xBC, 0xC6, 0x59, 0xC0, 0xAD, 0xB6,
++    0xD8, 0x68, 0xD4, 0xE0, 0x2A, 0x8B, 0x21, 0x09,
++    0xC0, 0xDB, 0xD9, 0xBA, 0x63, 0xC0, 0x11, 0x22,
++    0xBB, 0xF2, 0x81, 0x35, 0x5C, 0xE0, 0xCE, 0xBE,
++    0xAB, 0x2E, 0x83, 0x44, 0xCA, 0x05, 0x07, 0xDF,
++    0xAD, 0x1D, 0xAD, 0x12, 0x15, 0xD3, 0x9C, 0x8C,
++    0x92, 0xD3, 0xDE, 0x02, 0x00, 0x7B, 0x30, 0x97,
++    0x07, 0xC0, 0x7C, 0x58, 0xF8, 0x98, 0xAE, 0xB9,
++    0xE8, 0x82, 0x56, 0x0A, 0xEC, 0x4B, 0xF7, 0xEC,
++    0x85, 0xBA, 0xDF, 0xD7, 0xEA, 0x9D, 0x68, 0xAE,
++    0x1A, 0x2C, 0xEC, 0x25, 0x6A, 0x07, 0x2B, 0xFE,
++    0x6D, 0x49, 0xD7, 0x8A, 0x1C, 0x5E, 0xC9, 0xA5,
++    0x2C, 0xF2, 0xB5, 0x8A, 0x14, 0x91, 0x15, 0x6B,
++    0x71, 0x2E, 0x6D, 0x31, 0x1F, 0xC8, 0x61, 0x46,
++    0xF2, 0x0D, 0xCC, 0x10, 0xF7, 0x08, 0x9E, 0xBB,
++    0x66, 0x0D, 0x0D, 0x6D, 0xE7, 0x82, 0x0E, 0x71,
++    0xA4, 0x51, 0xC2, 0x63, 0xA5, 0xDC, 0xFA, 0xF1,
++    0x04, 0xD8, 0xCF, 0x16, 0x9F, 0x7F, 0x73, 0xA2,
++    0x3B, 0xF9, 0x0D, 0xC7, 0xDD, 0x9A, 0x3A, 0x2B,
++    0x0F, 0xB0, 0xB3, 0x97, 0x9D, 0xF1, 0xF0, 0x73,
++    0x7C, 0xFD, 0x76, 0x3A, 0xEB, 0x34, 0xDD, 0x87,
++    0xE6, 0x52, 0x79, 0xDD, 0x53, 0x9A, 0xCB, 0x62,
++    0xE4, 0xF1, 0xB2, 0xCA, 0x6B, 0xD8, 0xC2, 0x69,
++    0xBD, 0xA9, 0xB8, 0xE8, 0x76, 0x88, 0x91, 0x6D
+ };
+ 
+-static const unsigned char dh_test_2048_priv_key[] = {
+-    0x0C, 0x4B, 0x30, 0x89, 0xD1, 0xB8, 0x62, 0xCB, 0x3C, 0x43, 0x64, 0x91,
+-    0xF0, 0x91, 0x54, 0x70, 0xC5, 0x27, 0x96, 0xE3, 0xAC, 0xBE, 0xE8, 0x00,
+-    0xEC, 0x55, 0xF6, 0xCC
++static const unsigned char dh_test_2048_expected_key[] = {
++    0xB1, 0x26, 0x63, 0xAD, 0xB9, 0x4D, 0x9A, 0x38,
++    0x14, 0x25, 0x16, 0x4D, 0x3A, 0x18, 0x36, 0x10,
++    0xF8, 0xB1, 0x2C, 0x22, 0x4F, 0xD6, 0xA6, 0x2B,
++    0xEB, 0xDF, 0x39, 0xAA, 0x31, 0x8E, 0x44, 0x40,
++    0x09, 0xB6, 0x55, 0x7C, 0x95, 0x6E, 0x1F, 0x00,
++    0x5B, 0xF8, 0x94, 0x1E, 0x5B, 0x69, 0x7A, 0x63,
++    0x38, 0x12, 0x7B, 0xE6, 0xDD, 0x58, 0x08, 0x8E,
++    0x88, 0xF7, 0x82, 0xA5, 0x5D, 0xED, 0x24, 0x10,
++    0x0E, 0x87, 0x2E, 0x9A, 0x3A, 0xF0, 0xDB, 0xA5,
++    0x0E, 0x85, 0xAE, 0xFC, 0xD0, 0x35, 0x30, 0x79,
++    0xFE, 0x84, 0x84, 0xF1, 0x15, 0x14, 0x9C, 0x84,
++    0x72, 0xA6, 0xB3, 0x7C, 0xB7, 0xEF, 0x38, 0xF5,
++    0x2C, 0x90, 0x1B, 0xFC, 0x41, 0x85, 0x0A, 0xDE,
++    0x1B, 0xD3, 0x7E, 0x93, 0xCB, 0x59, 0xE8, 0x7C,
++    0xAB, 0x47, 0x3A, 0x02, 0x22, 0x4F, 0xAC, 0xAD,
++    0xE9, 0x56, 0x32, 0xEB, 0x3D, 0x02, 0x9B, 0x1F,
++    0x7C, 0x70, 0x0F, 0x83, 0xEF, 0x4D, 0x88, 0xE8,
++    0x70, 0x91, 0x34, 0xDD, 0x1C, 0xEF, 0x56, 0x97,
++    0xA3, 0x6E, 0xF6, 0x88, 0xAC, 0xF3, 0xA2, 0xBE,
++    0x30, 0xBD, 0xE0, 0xC0, 0xCD, 0x01, 0x46, 0x5E,
++    0x96, 0xC6, 0x14, 0x44, 0x60, 0xC0, 0x99, 0xFD,
++    0xF0, 0x0A, 0xF6, 0x7D, 0x29, 0xD6, 0x0D, 0xEE,
++    0x10, 0x91, 0x0F, 0x55, 0x71, 0x29, 0xA7, 0x6A,
++    0xEB, 0x18, 0x9B, 0x40, 0xF7, 0x37, 0x50, 0x91,
++    0xBC, 0x16, 0x5D, 0x29, 0x24, 0x63, 0xA2, 0x73,
++    0x0F, 0xA7, 0xA4, 0x0D, 0x00, 0xD4, 0x5F, 0x61,
++    0x74, 0x73, 0x99, 0x14, 0x73, 0xC7, 0x35, 0x2A,
++    0xC0, 0xBA, 0x38, 0x9E, 0x05, 0x09, 0x81, 0xA5,
++    0xDE, 0x8E, 0xB5, 0xE0, 0x77, 0xA7, 0x2F, 0x1A,
++    0x47, 0xD2, 0x68, 0xD4, 0x3E, 0x9A, 0x02, 0xA0,
++    0x5C, 0xC7, 0xFB, 0xE4, 0x2C, 0x7B, 0xC6, 0x26,
++    0x35, 0x92, 0x12, 0x88, 0x62, 0x36, 0x98, 0xFE
+ };
+ 
+ int FIPS_selftest_dh()
+ {
+     DH *dh = NULL;
+     int ret = 0;
+-    void *pub_key_bin = NULL;
++    unsigned char shared_key[sizeof(dh_test_2048_expected_key)];
+     int len;
+-    BIGNUM *p = NULL, *g = NULL, *priv_key = NULL, *tmp_pub_key = NULL;
+-    const BIGNUM *pub_key;
++    BIGNUM *priv_key = NULL;
++    BIGNUM *pub_key = NULL;
++    BIGNUM *peer_key = NULL;
+ 
+-    fips_load_key_component(p, dh_test_2048);
+-    fips_load_key_component(g, dh_test_2048);
+-    /* note that the private key is much shorter than normally used
+-     * but still g ** priv_key > p
+-     */
+     fips_load_key_component(priv_key, dh_test_2048);
+-    if ((tmp_pub_key = BN_new()) == NULL)
+-        goto err;
+-
+-    dh = DH_new();
++    fips_load_key_component(pub_key, dh_test_2048);
++    fips_load_key_component(peer_key, dh_test_2048);
+ 
+-    if (dh == NULL)
++    if ((dh = DH_new_by_nid(NID_ffdhe2048)) == NULL)
+         goto err;
+ 
+-    DH_set0_pqg(dh, p, NULL, g);
+-    DH_set0_key(dh, tmp_pub_key, priv_key);
++    DH_set0_key(dh, pub_key, priv_key);
+ 
+-    if (DH_generate_key(dh) <= 0)
+-        goto err;
+-
+-    DH_get0_key(dh, &pub_key, NULL);
+-
+-    if (pub_key == NULL)
+-        goto err;
++    len = DH_compute_key(shared_key, peer_key, dh);
+ 
+-    len = BN_num_bytes(pub_key);
+-    if ((pub_key_bin = OPENSSL_malloc(len)) == NULL)
+-        goto err;
+-    BN_bn2bin(pub_key, pub_key_bin);
+-
+-    if (len != sizeof(dh_test_2048_pub_key) ||
+-        memcmp(pub_key_bin, dh_test_2048_pub_key, len) != 0)
++    if (len != sizeof(dh_test_2048_expected_key) ||
++        memcmp(shared_key, dh_test_2048_expected_key, len) != 0)
+         goto err;
+ 
+     ret = 1;
+@@ -168,13 +202,10 @@ int FIPS_selftest_dh()
+     if (dh)
+         DH_free(dh);
+     else {
+-        BN_free(p);
+-        BN_free(g);
+         BN_free(priv_key);
+-        BN_free(tmp_pub_key);
++        BN_free(pub_key);
+     }
+-
+-    OPENSSL_free(pub_key_bin);
++    BN_free(peer_key);
+     return ret;
+ }
+ #endif
 diff -up openssl-1.1.1g/crypto/objects/obj_dat.h.fips-dh openssl-1.1.1g/crypto/objects/obj_dat.h
 --- openssl-1.1.1g/crypto/objects/obj_dat.h.fips-dh	2020-07-17 10:36:29.239788392 +0200
 +++ openssl-1.1.1g/crypto/objects/obj_dat.h	2020-07-17 10:36:29.247788458 +0200
diff --git a/SOURCES/openssl-1.1.1-kdf-selftest.patch b/SOURCES/openssl-1.1.1-kdf-selftest.patch
index 3cb3718..e54684e 100644
--- a/SOURCES/openssl-1.1.1-kdf-selftest.patch
+++ b/SOURCES/openssl-1.1.1-kdf-selftest.patch
@@ -10,10 +10,30 @@ diff -up openssl-1.1.1g/crypto/fips/build.info.kdf-selftest openssl-1.1.1g/crypt
  
  PROGRAMS_NO_INST=\
            fips_standalone_hmac
+diff -up openssl-1.1.1g/crypto/fips/fips_err.h.kdf-selftest openssl-1.1.1g/crypto/fips/fips_err.h
+--- openssl-1.1.1g/crypto/fips/fips_err.h.kdf-selftest	2020-07-14 15:27:51.681785958 +0200
++++ openssl-1.1.1g/crypto/fips/fips_err.h	2020-10-22 14:07:13.645614388 +0200
+@@ -108,9 +108,16 @@ static ERR_STRING_DATA FIPS_str_functs[]
+     {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"},
+     {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"},
+     {ERR_FUNC(FIPS_F_FIPS_SELFTEST_ECDSA), "FIPS_selftest_ecdsa"},
++    {ERR_FUNC(FIPS_F_FIPS_SELFTEST_HKDF), "FIPS_selftest_hkdf"},
+     {ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC), "FIPS_selftest_hmac"},
++    {ERR_FUNC(FIPS_F_FIPS_SELFTEST_KBKDF), "FIPS_selftest_kbkdf"},
++    {ERR_FUNC(FIPS_F_FIPS_SELFTEST_KRB5KDF), "FIPS_selftest_krb5kdf"},
++    {ERR_FUNC(FIPS_F_FIPS_SELFTEST_PBKDF2), "FIPS_selftest_pbkdf2"},
+     {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"},
+     {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA2), "FIPS_selftest_sha2"},
++    {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SSHKDF), "FIPS_selftest_sshkdf"},
++    {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SSKDF), "FIPS_selftest_sskdf"},
++    {ERR_FUNC(FIPS_F_FIPS_SELFTEST_TLS1_PRF), "FIPS_selftest_tls1_prf"},
+     {ERR_FUNC(FIPS_F_OSSL_ECDSA_SIGN_SIG), "ossl_ecdsa_sign_sig"},
+     {ERR_FUNC(FIPS_F_OSSL_ECDSA_VERIFY_SIG), "ossl_ecdsa_verify_sig"},
+     {ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN), "rsa_builtin_keygen"},
 diff -up openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c.kdf-selftest openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c
---- openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c.kdf-selftest	2020-06-03 16:08:36.337849577 +0200
-+++ openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c	2020-06-03 16:08:36.337849577 +0200
-@@ -0,0 +1,117 @@
+--- openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c.kdf-selftest	2020-10-22 16:25:33.211248158 +0200
++++ openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c	2020-10-22 16:56:54.652267521 +0200
+@@ -0,0 +1,377 @@
 +/*
 + * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved.
 + * Copyright (c) 2018-2019, Oracle and/or its affiliates.  All rights reserved.
@@ -33,7 +53,173 @@ diff -up openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c.kdf-selftest openssl-1.1
 +#include <openssl/kdf.h>
 +
 +#ifdef OPENSSL_FIPS
-+int FIPS_selftest_pbkdf2(void)
++static int FIPS_selftest_tls1_prf(void)
++{
++    int ret = 0;
++    EVP_KDF_CTX *kctx;
++    unsigned char out[16];
++
++    if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_TLS1_PRF)) == NULL) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_TLS_SECRET,
++                     "secret", (size_t)6) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_TLS_SEED, "seed", (size_t)4) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
++        goto err;
++    }
++
++    {
++        const unsigned char expected[sizeof(out)] = {
++            0x8e, 0x4d, 0x93, 0x25, 0x30, 0xd7, 0x65, 0xa0,
++            0xaa, 0xe9, 0x74, 0xc3, 0x04, 0x73, 0x5e, 0xcc
++        };
++        if (memcmp(out, expected, sizeof(expected))) {
++            goto err;
++        }
++    }
++    ret = 1;
++
++err:
++    if (!ret)
++        FIPSerr(FIPS_F_FIPS_SELFTEST_TLS1_PRF, FIPS_R_SELFTEST_FAILED);
++    EVP_KDF_CTX_free(kctx);
++    return ret;
++}
++
++static int FIPS_selftest_hkdf(void)
++{
++    int ret = 0;
++    EVP_KDF_CTX *kctx;
++    unsigned char out[10];
++
++    if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_HKDF)) == NULL) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, "salt", (size_t)4) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_HKDF_INFO,
++                     "label", (size_t)5) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
++        goto err;
++    }
++
++    {
++        const unsigned char expected[sizeof(out)] = {
++            0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8, 0xde, 0x13
++        };
++        if (memcmp(out, expected, sizeof(expected))) {
++            goto err;
++        }
++    }
++    ret = 1;
++err:
++    if (!ret)
++        FIPSerr(FIPS_F_FIPS_SELFTEST_HKDF, FIPS_R_SELFTEST_FAILED);
++    EVP_KDF_CTX_free(kctx);
++    return ret;
++}
++
++static int FIPS_selftest_sshkdf(void)
++{
++    int ret = 0;
++    EVP_KDF_CTX *kctx;
++    unsigned char out[32];
++    const unsigned char input_key[] = {
++        0x00, 0x00, 0x00, 0x80, 0x0f, 0xaa, 0x17, 0x2b,
++        0x8c, 0x28, 0x7e, 0x37, 0x2b, 0xb2, 0x36, 0xad,
++        0x34, 0xc7, 0x33, 0x69, 0x5c, 0x13, 0xd7, 0x7f,
++        0x88, 0x2a, 0xdc, 0x0f, 0x47, 0xe5, 0xa7, 0xf6,
++        0xa3, 0xde, 0x07, 0xef, 0xb1, 0x01, 0x20, 0x7a,
++        0xa5, 0xd6, 0x65, 0xb6, 0x19, 0x82, 0x6f, 0x75,
++        0x65, 0x91, 0xf6, 0x53, 0x10, 0xbb, 0xd2, 0xc9,
++        0x2c, 0x93, 0x84, 0xe6, 0xc6, 0xa6, 0x7b, 0x42,
++        0xde, 0xc3, 0x82, 0xfd, 0xb2, 0x4c, 0x59, 0x1d,
++        0x79, 0xff, 0x5e, 0x47, 0x73, 0x7b, 0x0f, 0x5b,
++        0x84, 0x79, 0x69, 0x4c, 0x3a, 0xdc, 0x19, 0x40,
++        0x17, 0x04, 0x91, 0x2b, 0xbf, 0xec, 0x27, 0x04,
++        0xd4, 0xd5, 0xbe, 0xbb, 0xfc, 0x1a, 0x7f, 0xc7,
++        0x96, 0xe2, 0x77, 0x63, 0x4e, 0x40, 0x85, 0x18,
++        0x51, 0xa1, 0x87, 0xec, 0x2d, 0x37, 0xed, 0x3f,
++        0x35, 0x1c, 0x45, 0x96, 0xa5, 0xa0, 0x89, 0x29,
++        0x16, 0xb4, 0xc5, 0x5f
++    };
++    const unsigned char xcghash[] = {
++        0xa3, 0x47, 0xf5, 0xf1, 0xe1, 0x91, 0xc3, 0x5f,
++        0x21, 0x2c, 0x93, 0x24, 0xd5, 0x86, 0x7e, 0xfd,
++        0xf8, 0x30, 0x26, 0xbe, 0x62, 0xc2, 0xb1, 0x6a,
++        0xe0, 0x06, 0xed, 0xb3, 0x37, 0x8d, 0x40, 0x06
++    };
++    const unsigned char session_id[] = {
++        0x90, 0xbe, 0xfc, 0xef, 0x3f, 0xf8, 0xf9, 0x20,
++        0x67, 0x4a, 0x9f, 0xab, 0x94, 0x19, 0x8c, 0xf3,
++        0xfd, 0x9d, 0xca, 0x24, 0xa2, 0x1d, 0x3c, 0x9d,
++        0xba, 0x39, 0x4d, 0xaa, 0xfb, 0xc6, 0x21, 0xed
++    };
++
++
++    if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF)) == NULL) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha256()) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, input_key,
++                     sizeof(input_key)) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSHKDF_XCGHASH, xcghash,
++                     sizeof(xcghash)) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID, session_id,
++                     sizeof(session_id)) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, (int)'F') <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
++        goto err;
++    }
++
++    {
++        const unsigned char expected[sizeof(out)] = {
++            0x14, 0x7a, 0x77, 0x14, 0x45, 0x12, 0x3f, 0x84,
++            0x6d, 0x8a, 0xe5, 0x14, 0xd7, 0xff, 0x9b, 0x3c,
++            0x93, 0xb2, 0xbc, 0xeb, 0x7c, 0x7c, 0x95, 0x00,
++            0x94, 0x21, 0x61, 0xb8, 0xe2, 0xd0, 0x11, 0x0f
++        };
++        if (memcmp(out, expected, sizeof(expected))) {
++            goto err;
++        }
++    }
++    ret = 1;
++
++err:
++    if (!ret)
++        FIPSerr(FIPS_F_FIPS_SELFTEST_SSHKDF, FIPS_R_SELFTEST_FAILED);
++    EVP_KDF_CTX_free(kctx);
++    return ret;
++}
++
++static int FIPS_selftest_pbkdf2(void)
 +{
 +    int ret = 0;
 +    EVP_KDF_CTX *kctx;
@@ -80,16 +266,16 @@ diff -up openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c.kdf-selftest openssl-1.1
 +
 +/* Test vector from RFC 8009 (AES Encryption with HMAC-SHA2 for Kerberos
 + * 5) appendix A. */
-+int FIPS_selftest_kbkdf(void)
++static int FIPS_selftest_kbkdf(void)
 +{
 +    int ret = 0;
 +    EVP_KDF_CTX *kctx;
 +    char *label = "prf", *prf_input = "test";
-+    static unsigned char input_key[] = {
++    const unsigned char input_key[] = {
 +        0x37, 0x05, 0xD9, 0x60, 0x80, 0xC1, 0x77, 0x28,
 +        0xA0, 0xE8, 0x00, 0xEA, 0xB6, 0xE0, 0xD2, 0x3C,
 +    };
-+    static unsigned char output[] = {
++    const unsigned char output[] = {
 +        0x9D, 0x18, 0x86, 0x16, 0xF6, 0x38, 0x52, 0xFE,
 +        0x86, 0x91, 0x5B, 0xB8, 0x40, 0xB4, 0xA8, 0x86,
 +        0xFF, 0x3E, 0x6B, 0xB0, 0xF8, 0x19, 0xB4, 0x9B,
@@ -118,16 +304,110 @@ diff -up openssl-1.1.1g/crypto/fips/fips_kdf_selftest.c.kdf-selftest openssl-1.1
 +    ret = EVP_KDF_derive(kctx, result, sizeof(result)) > 0
 +        && memcmp(result, output, sizeof(output)) == 0;
 +err:
-+
 +    if (!ret)
 +        FIPSerr(FIPS_F_FIPS_SELFTEST_KBKDF, FIPS_R_SELFTEST_FAILED);
 +    EVP_KDF_CTX_free(kctx);
 +    return ret;
 +}
 +
++static int FIPS_selftest_krb5kdf(void)
++{
++    int ret = 0;
++    EVP_KDF_CTX *kctx;
++    unsigned char out[16];
++    const unsigned char key[] = {
++        0x42, 0x26, 0x3C, 0x6E, 0x89, 0xF4, 0xFC, 0x28,
++        0xB8, 0xDF, 0x68, 0xEE, 0x09, 0x79, 0x9F, 0x15
++    };
++    const unsigned char constant[] = {
++        0x00, 0x00, 0x00, 0x02, 0x99
++    };
++    const unsigned char expected[sizeof(out)] = {
++        0x34, 0x28, 0x0A, 0x38, 0x2B, 0xC9, 0x27, 0x69,
++        0xB2, 0xDA, 0x2F, 0x9E, 0xF0, 0x66, 0x85, 0x4B
++    };
++
++    if ((kctx = EVP_KDF_CTX_new_id(EVP_KDF_KRB5KDF)) == NULL) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_CIPHER, EVP_aes_128_cbc()) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, key, sizeof(key)) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KRB5KDF_CONSTANT, constant, sizeof(constant)) <= 0) {
++        goto err;
++    }
++
++    ret =
++        EVP_KDF_derive(kctx, out, sizeof(out)) > 0
++        && memcmp(out, expected, sizeof(expected)) == 0;
++
++err:
++    if (!ret)
++        FIPSerr(FIPS_F_FIPS_SELFTEST_KRB5KDF, FIPS_R_SELFTEST_FAILED);
++    EVP_KDF_CTX_free(kctx);
++    return ret;
++}
++
++static int FIPS_selftest_sskdf(void)
++{
++    int ret = 0;
++    EVP_KDF_CTX *kctx;
++    const unsigned char z[] = {
++        0x6d,0xbd,0xc2,0x3f,0x04,0x54,0x88,0xe4,0x06,0x27,0x57,0xb0,0x6b,0x9e,
++        0xba,0xe1,0x83,0xfc,0x5a,0x59,0x46,0xd8,0x0d,0xb9,0x3f,0xec,0x6f,0x62,
++        0xec,0x07,0xe3,0x72,0x7f,0x01,0x26,0xae,0xd1,0x2c,0xe4,0xb2,0x62,0xf4,
++        0x7d,0x48,0xd5,0x42,0x87,0xf8,0x1d,0x47,0x4c,0x7c,0x3b,0x18,0x50,0xe9
++    };
++    const unsigned char other[] = {
++        0xa1,0xb2,0xc3,0xd4,0xe5,0x43,0x41,0x56,0x53,0x69,0x64,0x3c,0x83,0x2e,
++        0x98,0x49,0xdc,0xdb,0xa7,0x1e,0x9a,0x31,0x39,0xe6,0x06,0xe0,0x95,0xde,
++        0x3c,0x26,0x4a,0x66,0xe9,0x8a,0x16,0x58,0x54,0xcd,0x07,0x98,0x9b,0x1e,
++        0xe0,0xec,0x3f,0x8d,0xbe
++    };
++    const unsigned char expected[] = {
++        0xa4,0x62,0xde,0x16,0xa8,0x9d,0xe8,0x46,0x6e,0xf5,0x46,0x0b,0x47,0xb8
++    };
++    unsigned char out[14];
++
++    kctx = EVP_KDF_CTX_new_id(EVP_KDF_SS);
++
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, EVP_sha224()) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, z, sizeof(z)) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SSKDF_INFO, other,
++                     sizeof(other)) <= 0) {
++        goto err;
++    }
++    if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) {
++        goto err;
++    }
++
++    if (memcmp(out, expected, sizeof(expected)))
++        goto err;
++    ret = 1;
++
++err:
++    if (!ret)
++        FIPSerr(FIPS_F_FIPS_SELFTEST_SSKDF, FIPS_R_SELFTEST_FAILED);
++    EVP_KDF_CTX_free(kctx);
++    return ret;
++}
++
 +int FIPS_selftest_kdf(void)
 +{
-+    return FIPS_selftest_pbkdf2() && FIPS_selftest_kbkdf();
++    return FIPS_selftest_tls1_prf()
++        && FIPS_selftest_hkdf()
++        && FIPS_selftest_sshkdf()
++        && FIPS_selftest_pbkdf2()
++        && FIPS_selftest_kbkdf()
++        && FIPS_selftest_krb5kdf()
++        && FIPS_selftest_sskdf();
 +}
 +
 +#endif
@@ -146,25 +426,31 @@ diff -up openssl-1.1.1g/crypto/fips/fips_post.c.kdf-selftest openssl-1.1.1g/cryp
 diff -up openssl-1.1.1g/include/crypto/fips.h.kdf-selftest openssl-1.1.1g/include/crypto/fips.h
 --- openssl-1.1.1g/include/crypto/fips.h.kdf-selftest	2020-06-03 16:08:36.330849519 +0200
 +++ openssl-1.1.1g/include/crypto/fips.h	2020-06-03 16:08:36.338849585 +0200
-@@ -72,6 +72,9 @@ void FIPS_drbg_stick(int onoff);
+@@ -72,6 +72,7 @@ void FIPS_drbg_stick(int onoff);
  int FIPS_selftest_hmac(void);
  int FIPS_selftest_drbg(void);
  int FIPS_selftest_cmac(void);
-+int FIPS_selftest_kbkdf(void);
-+int FIPS_selftest_pbkdf2(void);
 +int FIPS_selftest_kdf(void);
  
  int fips_in_post(void);
  
 diff -up openssl-1.1.1g/include/openssl/fips.h.kdf-selftest openssl-1.1.1g/include/openssl/fips.h
---- openssl-1.1.1g/include/openssl/fips.h.kdf-selftest	2020-06-03 16:08:36.282849124 +0200
-+++ openssl-1.1.1g/include/openssl/fips.h	2020-06-03 16:08:36.338849585 +0200
-@@ -123,6 +123,8 @@ extern "C" {
+--- openssl-1.1.1g/include/openssl/fips.h.kdf-selftest	2020-07-14 15:27:51.685785988 +0200
++++ openssl-1.1.1g/include/openssl/fips.h	2020-10-22 14:03:28.868575785 +0200
+@@ -122,9 +122,16 @@ extern "C" {
+ # define FIPS_F_FIPS_SELFTEST_DES                         111
  # define FIPS_F_FIPS_SELFTEST_DSA                         112
  # define FIPS_F_FIPS_SELFTEST_ECDSA                       133
++# define FIPS_F_FIPS_SELFTEST_HKDF                        153
  # define FIPS_F_FIPS_SELFTEST_HMAC                        113
 +# define FIPS_F_FIPS_SELFTEST_KBKDF                       151
++# define FIPS_F_FIPS_SELFTEST_KRB5KDF                     154
 +# define FIPS_F_FIPS_SELFTEST_PBKDF2                      152
  # define FIPS_F_FIPS_SELFTEST_SHA1                        115
  # define FIPS_F_FIPS_SELFTEST_SHA2                        105
++# define FIPS_F_FIPS_SELFTEST_SSHKDF                      155
++# define FIPS_F_FIPS_SELFTEST_SSKDF                       156
++# define FIPS_F_FIPS_SELFTEST_TLS1_PRF                    157
  # define FIPS_F_OSSL_ECDSA_SIGN_SIG                       143
+ # define FIPS_F_OSSL_ECDSA_VERIFY_SIG                     148
+ # define FIPS_F_RSA_BUILTIN_KEYGEN                        116
diff --git a/SPECS/openssl.spec b/SPECS/openssl.spec
index dbd4c4d..99c8a73 100644
--- a/SPECS/openssl.spec
+++ b/SPECS/openssl.spec
@@ -22,7 +22,7 @@
 Summary: Utilities from the general purpose cryptography library with TLS implementation
 Name: openssl
 Version: 1.1.1g
-Release: 11%{?dist}
+Release: 12%{?dist}
 Epoch: 1
 # We have to remove certain patented algorithms from the openssl source
 # tarball with the hobble-openssl script which is included below.
@@ -77,6 +77,8 @@ Patch52: openssl-1.1.1-s390x-update.patch
 Patch53: openssl-1.1.1-fips-crng-test.patch
 Patch55: openssl-1.1.1-arm-update.patch
 Patch56: openssl-1.1.1-s390x-ecc.patch
+Patch57: openssl-1.1.1-explicit-params.patch
+Patch71: openssl-1.1.1-CVE-2020-1971.patch
 
 License: OpenSSL and ASL 2.0
 URL: http://www.openssl.org/
@@ -193,6 +195,8 @@ cp %{SOURCE13} test/
 %patch68 -p1 -b .reneg-no-extms
 %patch69 -p1 -b .alpn-cb
 %patch70 -p1 -b .rewire-fips-drbg
+%patch57 -p1 -b .explicit-params
+%patch71 -p1 -b .null-dereference
 
 
 %build
@@ -477,6 +481,13 @@ export LD_LIBRARY_PATH
 %postun libs -p /sbin/ldconfig
 
 %changelog
+* Fri Dec  4 2020 Sahana Prasad <sahana@redhat.com> 1.1.1g-12
+- Fix CVE-2020-1971 ediparty null pointer dereference
+
+* Mon Nov  2 2020 Tomáš Mráz <tmraz@redhat.com> 1.1.1g-11.1
+- Implemented new FIPS requirements in regards to KDF and DH selftests
+- Disallow certificates with explicit EC parameters
+
 * Mon Jul 20 2020 Tomáš Mráz <tmraz@redhat.com> 1.1.1g-11
 - Further changes for SP 800-56A rev3 requirements