[openssl] master update

Matt Caswell matt at openssl.org
Fri Jun 19 09:44:38 UTC 2020


The branch master has been updated
       via  989a85774b63a91ca8d3be558ec7560fdf91fa42 (commit)
       via  9ee77767b2186a4f0933ebfe2ba5caa83d814f4c (commit)
       via  febe6bb727082b07a6ffbf64b3b1b0dd871ec000 (commit)
       via  2da8d4eb2812e18cec5c8324a54a4c56b52563ed (commit)
      from  48e971dd9f88933a7f77f5051a8b79b9e17892a9 (commit)


- Log -----------------------------------------------------------------
commit 989a85774b63a91ca8d3be558ec7560fdf91fa42
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Jun 16 16:15:52 2020 +0100

    Add evp_extra_test2 to .gitignore
    
    This is a test executable which should not be added to the repository
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12159)

commit 9ee77767b2186a4f0933ebfe2ba5caa83d814f4c
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Jun 15 17:48:39 2020 +0100

    Add a test for d2i_AutoPrivateKey_ex with a non-default libctx
    
    Really this test should go in evp_extra_test. However that doesn't
    currently support a non-default libctx (with the "null" provider in the
    default libctx). So (for now) we create evp_extra_test2.c
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12159)

commit febe6bb727082b07a6ffbf64b3b1b0dd871ec000
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Jun 15 14:29:37 2020 +0100

    Ensure creating an EC public key uses the libctx
    
    Creating an EC public key from the private key uses random numbers
    internally, which require use of the proper libtx. Therefore we make
    sure the libctx is used during this operation.
    
    Fixes #12150
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12159)

commit 2da8d4eb2812e18cec5c8324a54a4c56b52563ed
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Jun 15 14:21:00 2020 +0100

    Add more complete support for libctx/propq in the EC code
    
    Renames some "new_ex" functions to "new_with_libctx" and ensures that we
    pass around the libctx AND the propq everywhere.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/12159)

-----------------------------------------------------------------------

Summary of changes:
 .gitignore                                   |   1 +
 crypto/ec/ec_ameth.c                         |  41 +++--
 crypto/ec/ec_backend.c                       |   5 +-
 crypto/ec/ec_curve.c                         |  16 +-
 crypto/ec/ec_cvt.c                           |   4 +-
 crypto/ec/ec_key.c                           |  34 ++--
 crypto/ec/ec_kmeth.c                         |  15 +-
 crypto/ec/ec_lib.c                           |  22 ++-
 crypto/ec/ec_local.h                         |   9 +-
 crypto/err/openssl.txt                       |   1 -
 doc/man3/EC_GROUP_new.pod                    |  53 +++---
 doc/man3/EC_KEY_new.pod                      |  70 ++++----
 include/crypto/ec.h                          |   1 +
 include/openssl/ec.h                         |  25 +--
 include/openssl/ecerr.h                      |   1 -
 providers/fips/fipsprov.c                    |   2 +-
 providers/implementations/keymgmt/ec_kmgmt.c |   6 +-
 test/build.info                              |  10 +-
 test/evp_extra_test2.c                       | 237 +++++++++++++++++++++++++++
 test/recipes/30-test_evp_extra.t             |   3 +-
 util/libcrypto.num                           |   9 +-
 21 files changed, 436 insertions(+), 129 deletions(-)
 create mode 100644 test/evp_extra_test2.c

diff --git a/.gitignore b/.gitignore
index 1ea4cb71af..49002162f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,6 +69,7 @@ providers/common/include/prov/der_digests.h
 /test/rsa_complex
 /test/confdump
 /test/bio_prefix_text
+/test/evp_extra_test2
 
 # Certain files that get created by tests on the fly
 /test-runs
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index bde8458274..761f697850 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -97,17 +97,24 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
     return 0;
 }
 
-static EC_KEY *eckey_type2param(int ptype, const void *pval)
+static EC_KEY *eckey_type2param(int ptype, const void *pval,
+                                OPENSSL_CTX *libctx, const char *propq)
 {
     EC_KEY *eckey = NULL;
     EC_GROUP *group = NULL;
 
+    if ((eckey = EC_KEY_new_with_libctx(libctx, propq)) == NULL) {
+        ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
+        goto ecerr;
+    }
+
     if (ptype == V_ASN1_SEQUENCE) {
         const ASN1_STRING *pstr = pval;
         const unsigned char *pm = pstr->data;
         int pmlen = pstr->length;
 
-        if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) {
+
+        if (d2i_ECParameters(&eckey, &pm, pmlen) == NULL) {
             ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
             goto ecerr;
         }
@@ -117,11 +124,9 @@ static EC_KEY *eckey_type2param(int ptype, const void *pval)
         /*
          * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
          */
-        if ((eckey = EC_KEY_new()) == NULL) {
-            ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
-            goto ecerr;
-        }
-        group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
+
+        group = EC_GROUP_new_by_curve_name_with_libctx(libctx, propq,
+                                                       OBJ_obj2nid(poid));
         if (group == NULL)
             goto ecerr;
         EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
@@ -153,7 +158,7 @@ static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
         return 0;
     X509_ALGOR_get0(NULL, &ptype, &pval, palg);
 
-    eckey = eckey_type2param(ptype, pval);
+    eckey = eckey_type2param(ptype, pval, NULL, NULL);
 
     if (!eckey) {
         ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
@@ -190,7 +195,10 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
     return -2;
 }
 
-static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+static int eckey_priv_decode_with_libctx(EVP_PKEY *pkey,
+                                         const PKCS8_PRIV_KEY_INFO *p8,
+                                         OPENSSL_CTX *libctx,
+                                         const char *propq)
 {
     const unsigned char *p = NULL;
     const void *pval;
@@ -202,14 +210,14 @@ static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
         return 0;
     X509_ALGOR_get0(NULL, &ptype, &pval, palg);
 
-    eckey = eckey_type2param(ptype, pval);
+    eckey = eckey_type2param(ptype, pval, libctx, propq);
 
     if (eckey == NULL)
         goto ecliberr;
 
     /* We have parameters now set private key */
     if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
-        ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
+        ECerr(0, EC_R_DECODE_ERROR);
         goto ecerr;
     }
 
@@ -217,7 +225,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
     return 1;
 
  ecliberr:
-    ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+    ECerr(0, ERR_R_EC_LIB);
  ecerr:
     EC_KEY_free(eckey);
     return 0;
@@ -762,7 +770,7 @@ static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
 {
     EVP_PKEY_CTX *pctx = vpctx;
     EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
-    EC_KEY *ec = EC_KEY_new_ex(pctx->libctx);
+    EC_KEY *ec = EC_KEY_new_with_libctx(pctx->libctx, pctx->propquery);
 
     if (ec == NULL) {
         ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
@@ -791,7 +799,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
     eckey_pub_cmp,
     eckey_pub_print,
 
-    eckey_priv_decode,
+    NULL,
     eckey_priv_encode,
     eckey_priv_print,
 
@@ -825,7 +833,8 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
 
     ec_pkey_dirty_cnt,
     ec_pkey_export_to,
-    ec_pkey_import_from
+    ec_pkey_import_from,
+    eckey_priv_decode_with_libctx
 };
 
 #if !defined(OPENSSL_NO_SM2)
@@ -879,7 +888,7 @@ static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
         if (!EC_KEY_set_group(ecpeer, grp))
             goto err;
     } else {
-        ecpeer = eckey_type2param(atype, aval);
+        ecpeer = eckey_type2param(atype, aval, pctx->libctx, pctx->propquery);
         if (!ecpeer)
             goto err;
     }
diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c
index b12a9411d2..2277c2c724 100644
--- a/crypto/ec/ec_backend.c
+++ b/crypto/ec/ec_backend.c
@@ -190,8 +190,9 @@ int ec_key_domparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
                 || (curve_nid = ec_curve_name2nid(curve_name)) == NID_undef)
             goto err;
 
-        if ((ecg = EC_GROUP_new_by_curve_name_ex(ec_key_get_libctx(ec),
-                                                 curve_nid)) == NULL)
+        if ((ecg = EC_GROUP_new_by_curve_name_with_libctx(ec_key_get_libctx(ec),
+                                                          ec_key_get0_propq(ec),
+                                                          curve_nid)) == NULL)
             goto err;
     }
 
diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c
index 3be62b3655..bf02c261f7 100644
--- a/crypto/ec/ec_curve.c
+++ b/crypto/ec/ec_curve.c
@@ -3180,6 +3180,7 @@ int ec_curve_name2nid(const char *name)
 }
 
 static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
+                                        const char *propq,
                                         const ec_list_element curve)
 {
     EC_GROUP *group = NULL;
@@ -3195,8 +3196,8 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
 
     /* If no curve data curve method must handle everything */
     if (curve.data == NULL)
-        return ec_group_new_ex(libctx,
-                               curve.meth != NULL ? curve.meth() : NULL);
+        return ec_group_new_with_libctx(libctx, propq,
+                                        curve.meth != NULL ? curve.meth() : NULL);
 
     if ((ctx = BN_CTX_new_ex(libctx)) == NULL) {
         ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
@@ -3218,7 +3219,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
 
     if (curve.meth != 0) {
         meth = curve.meth();
-        if (((group = ec_group_new_ex(libctx, meth)) == NULL) ||
+        if (((group = ec_group_new_with_libctx(libctx, propq, meth)) == NULL) ||
             (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
             ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
             goto err;
@@ -3288,14 +3289,15 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
     return group;
 }
 
-EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid)
+EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx,
+                                                 const char *propq, int nid)
 {
     EC_GROUP *ret = NULL;
     const ec_list_element *curve;
 
     if ((curve = ec_curve_nid2curve(nid)) == NULL
-        || (ret = ec_group_new_from_data(libctx, *curve)) == NULL) {
-        ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX, EC_R_UNKNOWN_GROUP);
+        || (ret = ec_group_new_from_data(libctx, propq, *curve)) == NULL) {
+        ECerr(0, EC_R_UNKNOWN_GROUP);
         return NULL;
     }
 
@@ -3305,7 +3307,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid)
 #ifndef FIPS_MODULE
 EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
 {
-    return EC_GROUP_new_by_curve_name_ex(NULL, nid);
+    return EC_GROUP_new_by_curve_name_with_libctx(NULL, NULL, nid);
 }
 #endif
 
diff --git a/crypto/ec/ec_cvt.c b/crypto/ec/ec_cvt.c
index a8ea6fe7fd..e5e6f10ce4 100644
--- a/crypto/ec/ec_cvt.c
+++ b/crypto/ec/ec_cvt.c
@@ -54,7 +54,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
         meth = EC_GFp_mont_method();
 #endif
 
-    ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth);
+    ret = ec_group_new_with_libctx(bn_get_lib_ctx(ctx), NULL, meth);
     if (ret == NULL)
         return NULL;
 
@@ -75,7 +75,7 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
 
     meth = EC_GF2m_simple_method();
 
-    ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth);
+    ret = ec_group_new_with_libctx(bn_get_lib_ctx(ctx), NULL, meth);
     if (ret == NULL)
         return NULL;
 
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 47feede54b..84ce095693 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -29,21 +29,22 @@ static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
 #ifndef FIPS_MODULE
 EC_KEY *EC_KEY_new(void)
 {
-    return ec_key_new_method_int(NULL, NULL);
+    return ec_key_new_method_int(NULL, NULL, NULL);
 }
 #endif
 
-EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx)
+EC_KEY *EC_KEY_new_with_libctx(OPENSSL_CTX *ctx, const char *propq)
 {
-    return ec_key_new_method_int(ctx, NULL);
+    return ec_key_new_method_int(ctx, propq, NULL);
 }
 
-EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid)
+EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx,
+                                             const char *propq, int nid)
 {
-    EC_KEY *ret = EC_KEY_new_ex(ctx);
+    EC_KEY *ret = EC_KEY_new_with_libctx(ctx, propq);
     if (ret == NULL)
         return NULL;
-    ret->group = EC_GROUP_new_by_curve_name_ex(ctx, nid);
+    ret->group = EC_GROUP_new_by_curve_name_with_libctx(ctx, propq, nid);
     if (ret->group == NULL) {
         EC_KEY_free(ret);
         return NULL;
@@ -59,7 +60,7 @@ EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid)
 #ifndef FIPS_MODULE
 EC_KEY *EC_KEY_new_by_curve_name(int nid)
 {
-    return EC_KEY_new_by_curve_name_ex(NULL, nid);
+    return EC_KEY_new_by_curve_name_with_libctx(NULL, NULL, nid);
 }
 #endif
 
@@ -93,6 +94,7 @@ void EC_KEY_free(EC_KEY *r)
     EC_GROUP_free(r->group);
     EC_POINT_free(r->pub_key);
     BN_clear_free(r->priv_key);
+    OPENSSL_free(r->propq);
 
     OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
 }
@@ -119,7 +121,8 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
     if (src->group != NULL) {
         /* clear the old group */
         EC_GROUP_free(dest->group);
-        dest->group = ec_group_new_ex(src->libctx, src->group->meth);
+        dest->group = ec_group_new_with_libctx(src->libctx, src->propq,
+                                               src->group->meth);
         if (dest->group == NULL)
             return NULL;
         if (!EC_GROUP_copy(dest->group, src->group))
@@ -180,7 +183,8 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
 
 EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
 {
-    EC_KEY *ret = ec_key_new_method_int(ec_key->libctx, ec_key->engine);
+    EC_KEY *ret = ec_key_new_method_int(ec_key->libctx, ec_key->propq,
+                                        ec_key->engine);
 
     if (ret == NULL)
         return NULL;
@@ -345,14 +349,19 @@ int ec_key_simple_generate_key(EC_KEY *eckey)
 int ec_key_simple_generate_public_key(EC_KEY *eckey)
 {
     int ret;
+    BN_CTX *ctx = BN_CTX_new_ex(eckey->libctx);
+
+    if (ctx == NULL)
+        return 0;
 
     /*
      * See SP800-56AR3 5.6.1.2.2: Step (8)
      * pub_key = priv_key * G (where G is a point on the curve)
      */
     ret = EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
-                       NULL, NULL);
+                       NULL, ctx);
 
+    BN_CTX_free(ctx);
     if (ret == 1)
         eckey->dirty_cnt++;
 
@@ -631,6 +640,11 @@ OPENSSL_CTX *ec_key_get_libctx(const EC_KEY *key)
     return key->libctx;
 }
 
+const char *ec_key_get0_propq(const EC_KEY *key)
+{
+    return key->propq;
+}
+
 const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
 {
     return key->group;
diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c
index 1f30571089..3fec8a4d81 100644
--- a/crypto/ec/ec_kmeth.c
+++ b/crypto/ec/ec_kmeth.c
@@ -76,7 +76,8 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
     return 1;
 }
 
-EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine)
+EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, const char *propq,
+                              ENGINE *engine)
 {
     EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
 
@@ -86,13 +87,19 @@ EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine)
     }
 
     ret->libctx = libctx;
+    if (propq != NULL) {
+        ret->propq = OPENSSL_strdup(propq);
+        if (ret->propq == NULL) {
+            ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
 
     ret->references = 1;
     ret->lock = CRYPTO_THREAD_lock_new();
     if (ret->lock == NULL) {
         ECerr(EC_F_EC_KEY_NEW_METHOD_INT, ERR_R_MALLOC_FAILURE);
-        OPENSSL_free(ret);
-        return NULL;
+        goto err;
     }
 
     ret->meth = EC_KEY_get_default_method();
@@ -138,7 +145,7 @@ EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine)
 #ifndef FIPS_MODULE
 EC_KEY *EC_KEY_new_method(ENGINE *engine)
 {
-    return ec_key_new_method_int(NULL, engine);
+    return ec_key_new_method_int(NULL, NULL, engine);
 }
 #endif
 
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index f62eff5034..a0c007a13e 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -23,26 +23,34 @@
 
 /* functions for EC_GROUP objects */
 
-EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
+EC_GROUP *ec_group_new_with_libctx(OPENSSL_CTX *libctx, const char *propq,
+                                   const EC_METHOD *meth)
 {
     EC_GROUP *ret;
 
     if (meth == NULL) {
-        ECerr(EC_F_EC_GROUP_NEW_EX, EC_R_SLOT_FULL);
+        ECerr(0, EC_R_SLOT_FULL);
         return NULL;
     }
     if (meth->group_init == 0) {
-        ECerr(EC_F_EC_GROUP_NEW_EX, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        ECerr(0, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
         return NULL;
     }
 
     ret = OPENSSL_zalloc(sizeof(*ret));
     if (ret == NULL) {
-        ECerr(EC_F_EC_GROUP_NEW_EX, ERR_R_MALLOC_FAILURE);
+        ECerr(0, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
 
     ret->libctx = libctx;
+    if (propq != NULL) {
+        ret->propq = OPENSSL_strdup(propq);
+        if (ret->propq == NULL) {
+            ECerr(0, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
     ret->meth = meth;
     if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
         ret->order = BN_new();
@@ -61,6 +69,7 @@ EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
  err:
     BN_free(ret->order);
     BN_free(ret->cofactor);
+    OPENSSL_free(ret->propq);
     OPENSSL_free(ret);
     return NULL;
 }
@@ -69,7 +78,7 @@ EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth)
 # ifndef FIPS_MODULE
 EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
 {
-    return ec_group_new_ex(NULL, meth);
+    return ec_group_new_with_libctx(NULL, NULL, meth);
 }
 # endif
 #endif
@@ -121,6 +130,7 @@ void EC_GROUP_free(EC_GROUP *group)
     BN_free(group->order);
     BN_free(group->cofactor);
     OPENSSL_free(group->seed);
+    OPENSSL_free(group->propq);
     OPENSSL_free(group);
 }
 
@@ -257,7 +267,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
     if (a == NULL)
         return NULL;
 
-    if ((t = ec_group_new_ex(a->libctx, a->meth)) == NULL)
+    if ((t = ec_group_new_with_libctx(a->libctx, a->propq, a->meth)) == NULL)
         return NULL;
     if (!EC_GROUP_copy(t, a))
         goto err;
diff --git a/crypto/ec/ec_local.h b/crypto/ec/ec_local.h
index 7f9b61bc49..aa040b54d1 100644
--- a/crypto/ec/ec_local.h
+++ b/crypto/ec/ec_local.h
@@ -274,6 +274,7 @@ struct ec_group_st {
     } pre_comp;
 
     OPENSSL_CTX *libctx;
+    char *propq;
 };
 
 #define SETPRECOMP(g, type, pre) \
@@ -297,6 +298,7 @@ struct ec_key_st {
 #endif
     CRYPTO_RWLOCK *lock;
     OPENSSL_CTX *libctx;
+    char *propq;
 
     /* Provider data */
     size_t dirty_cnt; /* If any key material changes, increment this */
@@ -593,10 +595,12 @@ int ec_group_simple_order_bits(const EC_GROUP *group);
  *  Creates a new EC_GROUP object
  *  \param   libctx The associated library context or NULL for the default
  *                  library context
+ *  \param   propq  Any property query string
  *  \param   meth   EC_METHOD to use
  *  \return  newly created EC_GROUP object or NULL in case of an error.
  */
-EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth);
+EC_GROUP *ec_group_new_with_libctx(OPENSSL_CTX *libctx, const char *propq,
+                                   const EC_METHOD *meth);
 
 #ifdef ECP_NISTZ256_ASM
 /** Returns GFp methods using montgomery multiplication, with x86-64 optimized
@@ -651,7 +655,8 @@ struct ec_key_method_st {
 
 #define EC_KEY_METHOD_DYNAMIC   1
 
-EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, ENGINE *engine);
+EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, const char *propq,
+                              ENGINE *engine);
 
 int ossl_ec_key_gen(EC_KEY *eckey);
 int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen,
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 515dfc3f11..a30b808a25 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -652,7 +652,6 @@ EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS:193:EC_GROUP_get_pentanomial_basis
 EC_F_EC_GROUP_GET_TRINOMIAL_BASIS:194:EC_GROUP_get_trinomial_basis
 EC_F_EC_GROUP_NEW:108:EC_GROUP_new
 EC_F_EC_GROUP_NEW_BY_CURVE_NAME:174:EC_GROUP_new_by_curve_name
-EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX:301:EC_GROUP_new_by_curve_name_ex
 EC_F_EC_GROUP_NEW_EX:302:EC_GROUP_new_ex
 EC_F_EC_GROUP_NEW_FROM_DATA:175:ec_group_new_from_data
 EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS:263:EC_GROUP_new_from_ecparameters
diff --git a/doc/man3/EC_GROUP_new.pod b/doc/man3/EC_GROUP_new.pod
index fa61275806..76fed3b246 100644
--- a/doc/man3/EC_GROUP_new.pod
+++ b/doc/man3/EC_GROUP_new.pod
@@ -11,7 +11,7 @@ EC_GROUP_free,
 EC_GROUP_clear_free,
 EC_GROUP_new_curve_GFp,
 EC_GROUP_new_curve_GF2m,
-EC_GROUP_new_by_curve_name_ex,
+EC_GROUP_new_by_curve_name_with_libctx,
 EC_GROUP_new_by_curve_name,
 EC_GROUP_set_curve,
 EC_GROUP_get_curve,
@@ -34,7 +34,8 @@ objects
                                   const BIGNUM *b, BN_CTX *ctx);
  EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
                                    const BIGNUM *b, BN_CTX *ctx);
- EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid);
+ EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx,
+                                                  const char *propq, int nid);
  EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
 
  int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
@@ -83,24 +84,24 @@ pentanomial for this parameter.
 
 Although deprecated since OpenSSL 3.0 and should no longer be used,
 a new curve can be constructed by calling EC_GROUP_new(), using the
-implementation provided by B<meth> (see L<EC_GFp_simple_method(3)>) and
-associated with the library context B<ctx> (see L<OPENSSL_CTX(3)>).
-The B<ctx> parameter may be NULL in which case the default library context is
+implementation provided by I<meth> (see L<EC_GFp_simple_method(3)>) and
+associated with the library context I<ctx> (see L<OPENSSL_CTX(3)>).
+The I<ctx> parameter may be NULL in which case the default library context is
 used.
 It is then necessary to call EC_GROUP_set_curve() to set the curve parameters.
 Applications should instead use one of the other EC_GROUP_new_* constructors.
 
 EC_GROUP_new_from_ecparameters() will create a group from the
-specified B<params> and
+specified I<params> and
 EC_GROUP_new_from_ecpkparameters() will create a group from the specific PK
-B<params>.
+I<params>.
 
-EC_GROUP_set_curve() sets the curve parameters B<p>, B<a> and B<b>. For a curve
-over Fp B<p> is the prime for the field. For a curve over F2^m B<p> represents
+EC_GROUP_set_curve() sets the curve parameters I<p>, I<a> and I<b>. For a curve
+over Fp I<p> is the prime for the field. For a curve over F2^m I<p> represents
 the irreducible polynomial - each bit represents a term in the polynomial.
 Therefore there will either be three or five bits set dependent on whether the
 polynomial is a trinomial or a pentanomial.
-In either case, B<a> and B<b> represents the coefficients a and b from the
+In either case, I<a> and I<b> represents the coefficients a and b from the
 relevant equation introduced above.
 
 EC_group_get_curve() obtains the previously set curve parameters.
@@ -120,13 +121,13 @@ An appropriate default implementation method will be used.
 Whilst the library can be used to create any curve using the functions described
 above, there are also a number of predefined curves that are available. In order
 to obtain a list of all of the predefined curves, call the function
-EC_get_builtin_curves(). The parameter B<r> should be an array of
-EC_builtin_curve structures of size B<nitems>. The function will populate the
-B<r> array with information about the built-in curves. If B<nitems> is less than
-the total number of curves available, then the first B<nitems> curves will be
+EC_get_builtin_curves(). The parameter I<r> should be an array of
+EC_builtin_curve structures of size I<nitems>. The function will populate the
+I<r> array with information about the built-in curves. If I<nitems> is less than
+the total number of curves available, then the first I<nitems> curves will be
 returned. Otherwise the total number of curves will be provided. The return
 value is the total number of curves available (whether that number has been
-populated in B<r> or not). Passing a NULL B<r>, or setting B<nitems> to 0 will
+populated in I<r> or not). Passing a NULL I<r>, or setting I<nitems> to 0 will
 do nothing other than return the total number of curves available.
 The EC_builtin_curve structure is defined as follows:
 
@@ -135,26 +136,28 @@ The EC_builtin_curve structure is defined as follows:
         const char *comment;
         } EC_builtin_curve;
 
-Each EC_builtin_curve item has a unique integer id (B<nid>), and a human
+Each EC_builtin_curve item has a unique integer id (I<nid>), and a human
 readable comment string describing the curve.
 
 In order to construct a built-in curve use the function
-EC_GROUP_new_by_curve_name_ex() and provide the B<nid> of the curve to be
-constructed and the associated library context to be used in B<ctx> (see
-L<OPENSSL_CTX(3)>).  The B<ctx> value may be NULL in which case the default
-library context is used.
+EC_GROUP_new_by_curve_name_with_libctx() and provide the I<nid> of the curve to
+be constructed, the associated library context to be used in I<ctx> (see
+L<OPENSSL_CTX(3)>) and any property query string in I<propq>. The I<ctx> value
+may be NULL in which case the default library context is used. The I<propq>
+value may also be NULL.
 
-EC_GROUP_new_by_curve_name() is the same as EC_GROUP_new_by_curve_name_ex()
-except that the default library context is always used.
+EC_GROUP_new_by_curve_name() is the same as
+EC_GROUP_new_by_curve_name_with_libctx() except that the default library context
+is always used along with a NULL property query string.
 
 EC_GROUP_free() frees the memory associated with the EC_GROUP.
-If B<group> is NULL nothing is done.
+If I<group> is NULL nothing is done.
 
 EC_GROUP_clear_free() is deprecated: it was meant to destroy any sensitive data
 held within the EC_GROUP and then free its memory, but since all the data stored
 in the EC_GROUP is public anyway, this function is unnecessary.
 Its use can be safely replaced with EC_GROUP_free().
-If B<group> is NULL nothing is done.
+If I<group> is NULL nothing is done.
 
 =head1 RETURN VALUES
 
@@ -182,7 +185,7 @@ L<OPENSSL_CTX(3)>
 
 EC_GROUP_new() was deprecated in OpenSSL 3.0.
 
-EC_GROUP_new_by_curve_name_ex() was added in OpenSSL 3.0.
+EC_GROUP_new_by_curve_name_with_libctx() was added in OpenSSL 3.0.
 
 =item *
 
diff --git a/doc/man3/EC_KEY_new.pod b/doc/man3/EC_KEY_new.pod
index 04ad740bc6..a907435153 100644
--- a/doc/man3/EC_KEY_new.pod
+++ b/doc/man3/EC_KEY_new.pod
@@ -2,10 +2,10 @@
 
 =head1 NAME
 
-EC_KEY_get_method, EC_KEY_set_method, EC_KEY_new_ex,
+EC_KEY_get_method, EC_KEY_set_method, EC_KEY_new_with_libctx,
 EC_KEY_new, EC_KEY_get_flags, EC_KEY_set_flags, EC_KEY_clear_flags,
-EC_KEY_new_by_curve_name_ex, EC_KEY_new_by_curve_name, EC_KEY_free, EC_KEY_copy,
-EC_KEY_dup, EC_KEY_up_ref, EC_KEY_get0_engine,
+EC_KEY_new_by_curve_name_with_libctx, EC_KEY_new_by_curve_name, EC_KEY_free,
+EC_KEY_copy, EC_KEY_dup, EC_KEY_up_ref, 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,
@@ -19,12 +19,13 @@ EC_KEY objects
 
  #include <openssl/ec.h>
 
- EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx);
+ EC_KEY *EC_KEY_new_with_libctx(OPENSSL_CTX *ctx, const char *propq);
  EC_KEY *EC_KEY_new(void);
  int EC_KEY_get_flags(const EC_KEY *key);
  void EC_KEY_set_flags(EC_KEY *key, int flags);
  void EC_KEY_clear_flags(EC_KEY *key, int flags);
- EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid);
+ EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx,
+                                              const char *propq, int nid);
  EC_KEY *EC_KEY_new_by_curve_name(int nid);
  void EC_KEY_free(EC_KEY *key);
  EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
@@ -64,9 +65,9 @@ Deprecated since OpenSSL 3.0:
 An EC_KEY represents a public key and, optionally, the associated private
 key.
 A new EC_KEY with no associated curve can be constructed by calling
-EC_KEY_new_ex() and specifying the associated library context in B<ctx>
-(see L<OPENSSL_CTX(3)>).
-The B<ctx> parameter may be NULL in which case the default library context is
+EC_KEY_new_ex() and specifying the associated library context in I<ctx>
+(see L<OPENSSL_CTX(3)>) and property query string I<propq>.
+The I<ctx> parameter may be NULL in which case the default library context is
 used.
 The reference count for the newly created EC_KEY is initially
 set to 1.
@@ -77,24 +78,26 @@ EC_KEY_new() is the same as EC_KEY_new_ex() except that the default library
 context is always used.
 
 Alternatively a new EC_KEY can be constructed by calling
-EC_KEY_new_by_curve_name_ex() and supplying the nid of the associated curve and
-the library context to be used B<ctx> (see L<OPENSSL_CTX(3)>).
-The B<ctx> parameter may be NULL in which case the default library context is
-used.
+EC_KEY_new_by_curve_name_with_libctx() and supplying the nid of the associated
+curve, the library context to be used I<ctx> (see L<OPENSSL_CTX(3)>) and any
+property query string I<propq>.
+The I<ctx> parameter may be NULL in which case the default library context is
+used. The I<propq> value may also be NULL.
 See L<EC_GROUP_new(3)> for a description of curve names.
 This function simply wraps calls to EC_KEY_new_ex() and
-EC_GROUP_new_by_curve_name_ex().
+EC_GROUP_new_by_curve_name_with_libctx().
 
-EC_KEY_new_by_curve_name() is the same as EC_KEY_new_by_curve_name_ex() except
-that the default library context is always used.
+EC_KEY_new_by_curve_name() is the same as EC_KEY_new_by_curve_name_with_libctx()
+except that the default library context is always used and a NULL property query
+string.
 
 Calling EC_KEY_free() decrements the reference count for the EC_KEY object,
 and if it has dropped to zero then frees the memory associated with it.  If
-B<key> is NULL nothing is done.
+I<key> is NULL nothing is done.
 
-EC_KEY_copy() copies the contents of the EC_KEY in B<src> into B<dest>.
+EC_KEY_copy() copies the contents of the EC_KEY in I<src> into I<dest>.
 
-EC_KEY_dup() creates a new EC_KEY object and copies B<ec_key> into it.
+EC_KEY_dup() creates a new EC_KEY object and copies I<ec_key> into it.
 
 EC_KEY_up_ref() increments the reference count associated with the EC_KEY
 object.
@@ -103,7 +106,7 @@ EC_KEY_get0_engine() returns a handle to the ENGINE that has been set for
 this EC_KEY object.
 
 EC_KEY_generate_key() generates a new public and private key for the supplied
-B<eckey> object. B<eckey> must have an EC_GROUP object associated with it
+I<eckey> object. I<eckey> must have an EC_GROUP object associated with it
 before calling this function. The private key is a random integer (0 < priv_key
 < order, where I<order> is the order of the EC_GROUP object). The public key is
 an EC_POINT on the curve calculated by multiplying the generator for the
@@ -112,27 +115,27 @@ curve by the private key.
 EC_KEY_check_key() performs various sanity checks on the EC_KEY object to
 confirm that it is valid.
 
-EC_KEY_set_public_key_affine_coordinates() sets the public key for B<key> based
+EC_KEY_set_public_key_affine_coordinates() sets the public key for I<key> based
 on its affine co-ordinates; i.e., it constructs an EC_POINT object based on
-the supplied B<x> and B<y> values and sets the public key to be this
+the supplied I<x> and I<y> values and sets the public key to be this
 EC_POINT. It also performs certain sanity checks on the key to confirm
 that it is valid.
 
 The functions EC_KEY_get0_group(), EC_KEY_set_group(),
 EC_KEY_get0_private_key(), EC_KEY_set_private_key(), EC_KEY_get0_public_key(),
 and EC_KEY_set_public_key() get and set the EC_GROUP object, the private key,
-and the EC_POINT public key for the B<key> respectively.
+and the EC_POINT public key for the I<key> respectively.
 
 The functions EC_KEY_get_conv_form() and EC_KEY_set_conv_form() get and set the
-point_conversion_form for the B<key>. For a description of
+point_conversion_form for the I<key>. For a description of
 point_conversion_forms please see L<EC_POINT_new(3)>.
 
-EC_KEY_set_flags() sets the flags in the B<flags> parameter on the EC_KEY
+EC_KEY_set_flags() sets the flags in the I<flags> parameter on the EC_KEY
 object. Any flags that are already set are left set. The flags currently
 defined are EC_FLAG_NON_FIPS_ALLOW and EC_FLAG_FIPS_CHECKED. In
 addition there is the flag EC_FLAG_COFACTOR_ECDH which is specific to ECDH.
 EC_KEY_get_flags() returns the current flags that are set for this EC_KEY.
-EC_KEY_clear_flags() clears the flags indicated by the B<flags> parameter; all
+EC_KEY_clear_flags() clears the flags indicated by the I<flags> parameter; all
 other flags are left in their existing state.
 
 EC_KEY_set_asn1_flag() sets the asn1_flag on the underlying EC_GROUP object
@@ -147,11 +150,11 @@ hardcoded lookup tables for.
 
 EC_KEY_oct2key() and EC_KEY_key2buf() are identical to the functions
 EC_POINT_oct2point() and EC_POINT_point2buf() except they use the public key
-EC_POINT in B<eckey>.
+EC_POINT in I<eckey>.
 
 EC_KEY_oct2priv() and EC_KEY_priv2oct() convert between the private key
-component of B<eckey> and octet form. The octet form consists of the content
-octets of the B<privateKey> OCTET STRING in an B<ECPrivateKey> ASN.1 structure.
+component of I<eckey> and octet form. The octet form consists of the content
+octets of the I<privateKey> OCTET STRING in an I<ECPrivateKey> ASN.1 structure.
 
 The function EC_KEY_priv2oct() must be supplied with a buffer long enough to
 store the octet form. The return value provides the number of octets stored.
@@ -159,17 +162,18 @@ Calling the function with a NULL buffer will not perform the conversion but
 will just return the required buffer length.
 
 The function EC_KEY_priv2buf() allocates a buffer of suitable length and writes
-an EC_KEY to it in octet format. The allocated buffer is written to B<*pbuf>
+an EC_KEY to it in octet format. The allocated buffer is written to I<*pbuf>
 and its length is returned. The caller must free up the allocated buffer with a
-call to OPENSSL_free(). Since the allocated buffer value is written to B<*pbuf>
-the B<pbuf> parameter B<MUST NOT> be B<NULL>.
+call to OPENSSL_free(). Since the allocated buffer value is written to I<*pbuf>
+the I<pbuf> parameter B<MUST NOT> be B<NULL>.
 
 EC_KEY_priv2buf() converts an EC_KEY private key into an allocated buffer.
 
 =head1 RETURN VALUES
 
-EC_KEY_new_ex(), EC_KEY_new(), EC_KEY_new_by_curve_name() and EC_KEY_dup()
-return a pointer to the newly created EC_KEY object, or NULL on error.
+EC_KEY_new_with_libctx(), EC_KEY_new(), EC_KEY_new_by_curve_name_with_libctx(),
+EC_KEY_new_by_curve_name() and EC_KEY_dup() return a pointer to the newly
+created EC_KEY object, or NULL on error.
 
 EC_KEY_get_flags() returns the flags associated with the EC_KEY object as an
 integer.
diff --git a/include/crypto/ec.h b/include/crypto/ec.h
index bccebb06db..a771cfd706 100644
--- a/include/crypto/ec.h
+++ b/include/crypto/ec.h
@@ -54,6 +54,7 @@ int ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx);
 int ec_key_private_check(const EC_KEY *eckey);
 int ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx);
 OPENSSL_CTX *ec_key_get_libctx(const EC_KEY *eckey);
+const char *ec_key_get0_propq(const EC_KEY *eckey);
 const char *ec_curve_nid2name(int nid);
 int ec_curve_name2nid(const char *name);
 const unsigned char *ecdsa_algorithmidentifier_encoding(int md_nid, size_t *len);
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 1302e27bb0..35dbeb9301 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -383,15 +383,18 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
  * Creates a EC_GROUP object with a curve specified by a NID
  *  \param  libctx The associated library context or NULL for the default
  *                 context
+ *  \param  propq  A property query string
  *  \param  nid    NID of the OID of the curve name
  *  \return newly created EC_GROUP object with specified curve or NULL
  *          if an error occurred
  */
-EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid);
+EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx,
+                                                 const char *propq, int nid);
 
 /**
  * Creates a EC_GROUP object with a curve specified by a NID. Same as
- * EC_GROUP_new_by_curve_name_ex but the libctx is always NULL.
+ * EC_GROUP_new_by_curve_name_with_libctx but the libctx and propq are always
+ * NULL.
  *  \param  nid    NID of the OID of the curve name
  *  \return newly created EC_GROUP object with specified curve or NULL
  *          if an error occurred
@@ -864,11 +867,11 @@ int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
  *               which case the default library context is used.
  *  \return EC_KEY object or NULL if an error occurred.
  */
-EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx);
+EC_KEY *EC_KEY_new_with_libctx(OPENSSL_CTX *ctx, const char *propq);
 
 /**
- *  Creates a new EC_KEY object. Same as calling EC_KEY_new_ex with a NULL
- *  library context
+ *  Creates a new EC_KEY object. Same as calling EC_KEY_new_with_libctx with a
+ *  NULL library context
  *  \return EC_KEY object or NULL if an error occurred.
  */
 EC_KEY *EC_KEY_new(void);
@@ -882,17 +885,19 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags);
 /**
  *  Creates a new EC_KEY object using a named curve as underlying
  *  EC_GROUP object.
- *  \param  ctx  The library context for to use for this EC_KEY. May be NULL in
- *               which case the default library context is used.
- *  \param  nid  NID of the named curve.
+ *  \param  ctx   The library context for to use for this EC_KEY. May be NULL in
+ *                which case the default library context is used.
+ *  \param  propq Any property query string
+ *  \param  nid   NID of the named curve.
  *  \return EC_KEY object or NULL if an error occurred.
  */
-EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid);
+EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx, const char *propq,
+                                             int nid);
 
 /**
  *  Creates a new EC_KEY object using a named curve as underlying
  *  EC_GROUP object. Same as calling EC_KEY_new_by_curve_name_ex with a NULL
- *  library context.
+ *  library context and property query string.
  *  \param  nid  NID of the named curve.
  *  \return EC_KEY object or NULL if an error occurred.
  */
diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h
index 49adc7c681..033c94d9a9 100644
--- a/include/openssl/ecerr.h
+++ b/include/openssl/ecerr.h
@@ -128,7 +128,6 @@ int ERR_load_EC_strings(void);
 #   define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS                0
 #   define EC_F_EC_GROUP_NEW                                0
 #   define EC_F_EC_GROUP_NEW_BY_CURVE_NAME                  0
-#   define EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX               0
 #   define EC_F_EC_GROUP_NEW_EX                             0
 #   define EC_F_EC_GROUP_NEW_FROM_DATA                      0
 #   define EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS              0
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 9efb6af1c9..4d39570464 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -194,7 +194,7 @@ static int dummy_evp_call(OPENSSL_CTX *libctx)
 
 #ifndef OPENSSL_NO_EC
     /* Do some dummy EC calls */
-    key = EC_KEY_new_by_curve_name_ex(libctx, NID_X9_62_prime256v1);
+    key = EC_KEY_new_by_curve_name_with_libctx(libctx, NULL, NID_X9_62_prime256v1);
     if (key == NULL)
         goto err;
 
diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
index 0b006047d5..cd8e7f5ece 100644
--- a/providers/implementations/keymgmt/ec_kmgmt.c
+++ b/providers/implementations/keymgmt/ec_kmgmt.c
@@ -244,7 +244,7 @@ int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
 static
 void *ec_newdata(void *provctx)
 {
-    return EC_KEY_new_ex(PROV_LIBRARY_CONTEXT_OF(provctx));
+    return EC_KEY_new_with_libctx(PROV_LIBRARY_CONTEXT_OF(provctx), NULL);
 }
 
 static
@@ -667,7 +667,7 @@ static int ec_gen_set_group(void *genctx, int nid)
     struct ec_gen_ctx *gctx = genctx;
     EC_GROUP *group;
 
-    group = EC_GROUP_new_by_curve_name_ex(gctx->libctx, nid);
+    group = EC_GROUP_new_by_curve_name_with_libctx(gctx->libctx, NULL, nid);
     if (group == NULL) {
         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
         return 0;
@@ -760,7 +760,7 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
     int ret = 1;                 /* Start optimistically */
 
     if (gctx == NULL
-        || (ec = EC_KEY_new_ex(gctx->libctx)) == NULL)
+        || (ec = EC_KEY_new_with_libctx(gctx->libctx, NULL)) == NULL)
         return NULL;
 
     /* We must always assign a group, no matter what */
diff --git a/test/build.info b/test/build.info
index 430931b8e1..88b35d4d3c 100644
--- a/test/build.info
+++ b/test/build.info
@@ -35,9 +35,11 @@ IF[{- !$disabled{tests} -}]
           ectest ecstresstest gmdifftest pbelutest \
           destest mdc2test \
           enginetest exptest \
-          evp_pkey_provided_test evp_test evp_extra_test evp_fetch_prov_test \
-          acvp_test \
+          evp_pkey_provided_test evp_test evp_extra_test evp_extra_test2 \
+          evp_fetch_prov_test acvp_test \
           v3nametest v3ext \
+          evp_pkey_provided_test evp_test evp_extra_test evp_extra_test2 \
+          evp_fetch_prov_test v3nametest v3ext \
           crltest danetest bad_dtls_test lhash_test sparse_array_test \
           conf_include_test params_api_test params_conversion_test \
           constant_time_test verify_extra_test clienthellotest \
@@ -135,6 +137,10 @@ IF[{- !$disabled{tests} -}]
   INCLUDE[evp_extra_test]=../include ../apps/include
   DEPEND[evp_extra_test]=../libcrypto libtestutil.a
 
+  SOURCE[evp_extra_test2]=evp_extra_test2.c
+  INCLUDE[evp_extra_test2]=../include ../apps/include
+  DEPEND[evp_extra_test2]=../libcrypto libtestutil.a
+
   SOURCE[evp_fetch_prov_test]=evp_fetch_prov_test.c
   INCLUDE[evp_fetch_prov_test]=../include ../apps/include
   DEPEND[evp_fetch_prov_test]=../libcrypto libtestutil.a
diff --git a/test/evp_extra_test2.c b/test/evp_extra_test2.c
new file mode 100644
index 0000000000..f4d8b98256
--- /dev/null
+++ b/test/evp_extra_test2.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * TODO(3.0): Really these tests should be in evp_extra_test - but that doesn't
+ * yet support testing with a non-default libctx. Once it does we should move
+ * everything into one file. Consequently some things are duplicated between
+ * the two files.
+ */
+
+#include <openssl/evp.h>
+#include <openssl/provider.h>
+#include "testutil.h"
+#include "internal/nelem.h"
+
+static OPENSSL_CTX *libctx = NULL;
+static OSSL_PROVIDER *nullprov = NULL;
+
+/*
+ * kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you
+ * should never use this key anywhere but in an example.
+ */
+static const unsigned char kExampleRSAKeyDER[] = {
+    0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xf8,
+    0xb8, 0x6c, 0x83, 0xb4, 0xbc, 0xd9, 0xa8, 0x57, 0xc0, 0xa5, 0xb4, 0x59,
+    0x76, 0x8c, 0x54, 0x1d, 0x79, 0xeb, 0x22, 0x52, 0x04, 0x7e, 0xd3, 0x37,
+    0xeb, 0x41, 0xfd, 0x83, 0xf9, 0xf0, 0xa6, 0x85, 0x15, 0x34, 0x75, 0x71,
+    0x5a, 0x84, 0xa8, 0x3c, 0xd2, 0xef, 0x5a, 0x4e, 0xd3, 0xde, 0x97, 0x8a,
+    0xdd, 0xff, 0xbb, 0xcf, 0x0a, 0xaa, 0x86, 0x92, 0xbe, 0xb8, 0x50, 0xe4,
+    0xcd, 0x6f, 0x80, 0x33, 0x30, 0x76, 0x13, 0x8f, 0xca, 0x7b, 0xdc, 0xec,
+    0x5a, 0xca, 0x63, 0xc7, 0x03, 0x25, 0xef, 0xa8, 0x8a, 0x83, 0x58, 0x76,
+    0x20, 0xfa, 0x16, 0x77, 0xd7, 0x79, 0x92, 0x63, 0x01, 0x48, 0x1a, 0xd8,
+    0x7b, 0x67, 0xf1, 0x52, 0x55, 0x49, 0x4e, 0xd6, 0x6e, 0x4a, 0x5c, 0xd7,
+    0x7a, 0x37, 0x36, 0x0c, 0xde, 0xdd, 0x8f, 0x44, 0xe8, 0xc2, 0xa7, 0x2c,
+    0x2b, 0xb5, 0xaf, 0x64, 0x4b, 0x61, 0x07, 0x02, 0x03, 0x01, 0x00, 0x01,
+    0x02, 0x81, 0x80, 0x74, 0x88, 0x64, 0x3f, 0x69, 0x45, 0x3a, 0x6d, 0xc7,
+    0x7f, 0xb9, 0xa3, 0xc0, 0x6e, 0xec, 0xdc, 0xd4, 0x5a, 0xb5, 0x32, 0x85,
+    0x5f, 0x19, 0xd4, 0xf8, 0xd4, 0x3f, 0x3c, 0xfa, 0xc2, 0xf6, 0x5f, 0xee,
+    0xe6, 0xba, 0x87, 0x74, 0x2e, 0xc7, 0x0c, 0xd4, 0x42, 0xb8, 0x66, 0x85,
+    0x9c, 0x7b, 0x24, 0x61, 0xaa, 0x16, 0x11, 0xf6, 0xb5, 0xb6, 0xa4, 0x0a,
+    0xc9, 0x55, 0x2e, 0x81, 0xa5, 0x47, 0x61, 0xcb, 0x25, 0x8f, 0xc2, 0x15,
+    0x7b, 0x0e, 0x7c, 0x36, 0x9f, 0x3a, 0xda, 0x58, 0x86, 0x1c, 0x5b, 0x83,
+    0x79, 0xe6, 0x2b, 0xcc, 0xe6, 0xfa, 0x2c, 0x61, 0xf2, 0x78, 0x80, 0x1b,
+    0xe2, 0xf3, 0x9d, 0x39, 0x2b, 0x65, 0x57, 0x91, 0x3d, 0x71, 0x99, 0x73,
+    0xa5, 0xc2, 0x79, 0x20, 0x8c, 0x07, 0x4f, 0xe5, 0xb4, 0x60, 0x1f, 0x99,
+    0xa2, 0xb1, 0x4f, 0x0c, 0xef, 0xbc, 0x59, 0x53, 0x00, 0x7d, 0xb1, 0x02,
+    0x41, 0x00, 0xfc, 0x7e, 0x23, 0x65, 0x70, 0xf8, 0xce, 0xd3, 0x40, 0x41,
+    0x80, 0x6a, 0x1d, 0x01, 0xd6, 0x01, 0xff, 0xb6, 0x1b, 0x3d, 0x3d, 0x59,
+    0x09, 0x33, 0x79, 0xc0, 0x4f, 0xde, 0x96, 0x27, 0x4b, 0x18, 0xc6, 0xd9,
+    0x78, 0xf1, 0xf4, 0x35, 0x46, 0xe9, 0x7c, 0x42, 0x7a, 0x5d, 0x9f, 0xef,
+    0x54, 0xb8, 0xf7, 0x9f, 0xc4, 0x33, 0x6c, 0xf3, 0x8c, 0x32, 0x46, 0x87,
+    0x67, 0x30, 0x7b, 0xa7, 0xac, 0xe3, 0x02, 0x41, 0x00, 0xfc, 0x2c, 0xdf,
+    0x0c, 0x0d, 0x88, 0xf5, 0xb1, 0x92, 0xa8, 0x93, 0x47, 0x63, 0x55, 0xf5,
+    0xca, 0x58, 0x43, 0xba, 0x1c, 0xe5, 0x9e, 0xb6, 0x95, 0x05, 0xcd, 0xb5,
+    0x82, 0xdf, 0xeb, 0x04, 0x53, 0x9d, 0xbd, 0xc2, 0x38, 0x16, 0xb3, 0x62,
+    0xdd, 0xa1, 0x46, 0xdb, 0x6d, 0x97, 0x93, 0x9f, 0x8a, 0xc3, 0x9b, 0x64,
+    0x7e, 0x42, 0xe3, 0x32, 0x57, 0x19, 0x1b, 0xd5, 0x6e, 0x85, 0xfa, 0xb8,
+    0x8d, 0x02, 0x41, 0x00, 0xbc, 0x3d, 0xde, 0x6d, 0xd6, 0x97, 0xe8, 0xba,
+    0x9e, 0x81, 0x37, 0x17, 0xe5, 0xa0, 0x64, 0xc9, 0x00, 0xb7, 0xe7, 0xfe,
+    0xf4, 0x29, 0xd9, 0x2e, 0x43, 0x6b, 0x19, 0x20, 0xbd, 0x99, 0x75, 0xe7,
+    0x76, 0xf8, 0xd3, 0xae, 0xaf, 0x7e, 0xb8, 0xeb, 0x81, 0xf4, 0x9d, 0xfe,
+    0x07, 0x2b, 0x0b, 0x63, 0x0b, 0x5a, 0x55, 0x90, 0x71, 0x7d, 0xf1, 0xdb,
+    0xd9, 0xb1, 0x41, 0x41, 0x68, 0x2f, 0x4e, 0x39, 0x02, 0x40, 0x5a, 0x34,
+    0x66, 0xd8, 0xf5, 0xe2, 0x7f, 0x18, 0xb5, 0x00, 0x6e, 0x26, 0x84, 0x27,
+    0x14, 0x93, 0xfb, 0xfc, 0xc6, 0x0f, 0x5e, 0x27, 0xe6, 0xe1, 0xe9, 0xc0,
+    0x8a, 0xe4, 0x34, 0xda, 0xe9, 0xa2, 0x4b, 0x73, 0xbc, 0x8c, 0xb9, 0xba,
+    0x13, 0x6c, 0x7a, 0x2b, 0x51, 0x84, 0xa3, 0x4a, 0xe0, 0x30, 0x10, 0x06,
+    0x7e, 0xed, 0x17, 0x5a, 0x14, 0x00, 0xc9, 0xef, 0x85, 0xea, 0x52, 0x2c,
+    0xbc, 0x65, 0x02, 0x40, 0x51, 0xe3, 0xf2, 0x83, 0x19, 0x9b, 0xc4, 0x1e,
+    0x2f, 0x50, 0x3d, 0xdf, 0x5a, 0xa2, 0x18, 0xca, 0x5f, 0x2e, 0x49, 0xaf,
+    0x6f, 0xcc, 0xfa, 0x65, 0x77, 0x94, 0xb5, 0xa1, 0x0a, 0xa9, 0xd1, 0x8a,
+    0x39, 0x37, 0xf4, 0x0b, 0xa0, 0xd7, 0x82, 0x27, 0x5e, 0xae, 0x17, 0x17,
+    0xa1, 0x1e, 0x54, 0x34, 0xbf, 0x6e, 0xc4, 0x8e, 0x99, 0x5d, 0x08, 0xf1,
+    0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf,
+};
+
+/*
+ * kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8
+ * PrivateKeyInfo.
+ */
+static const unsigned char kExampleRSAKeyPKCS8[] = {
+    0x30, 0x82, 0x02, 0x76, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+    0x02, 0x60, 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81,
+    0x00, 0xf8, 0xb8, 0x6c, 0x83, 0xb4, 0xbc, 0xd9, 0xa8, 0x57, 0xc0, 0xa5,
+    0xb4, 0x59, 0x76, 0x8c, 0x54, 0x1d, 0x79, 0xeb, 0x22, 0x52, 0x04, 0x7e,
+    0xd3, 0x37, 0xeb, 0x41, 0xfd, 0x83, 0xf9, 0xf0, 0xa6, 0x85, 0x15, 0x34,
+    0x75, 0x71, 0x5a, 0x84, 0xa8, 0x3c, 0xd2, 0xef, 0x5a, 0x4e, 0xd3, 0xde,
+    0x97, 0x8a, 0xdd, 0xff, 0xbb, 0xcf, 0x0a, 0xaa, 0x86, 0x92, 0xbe, 0xb8,
+    0x50, 0xe4, 0xcd, 0x6f, 0x80, 0x33, 0x30, 0x76, 0x13, 0x8f, 0xca, 0x7b,
+    0xdc, 0xec, 0x5a, 0xca, 0x63, 0xc7, 0x03, 0x25, 0xef, 0xa8, 0x8a, 0x83,
+    0x58, 0x76, 0x20, 0xfa, 0x16, 0x77, 0xd7, 0x79, 0x92, 0x63, 0x01, 0x48,
+    0x1a, 0xd8, 0x7b, 0x67, 0xf1, 0x52, 0x55, 0x49, 0x4e, 0xd6, 0x6e, 0x4a,
+    0x5c, 0xd7, 0x7a, 0x37, 0x36, 0x0c, 0xde, 0xdd, 0x8f, 0x44, 0xe8, 0xc2,
+    0xa7, 0x2c, 0x2b, 0xb5, 0xaf, 0x64, 0x4b, 0x61, 0x07, 0x02, 0x03, 0x01,
+    0x00, 0x01, 0x02, 0x81, 0x80, 0x74, 0x88, 0x64, 0x3f, 0x69, 0x45, 0x3a,
+    0x6d, 0xc7, 0x7f, 0xb9, 0xa3, 0xc0, 0x6e, 0xec, 0xdc, 0xd4, 0x5a, 0xb5,
+    0x32, 0x85, 0x5f, 0x19, 0xd4, 0xf8, 0xd4, 0x3f, 0x3c, 0xfa, 0xc2, 0xf6,
+    0x5f, 0xee, 0xe6, 0xba, 0x87, 0x74, 0x2e, 0xc7, 0x0c, 0xd4, 0x42, 0xb8,
+    0x66, 0x85, 0x9c, 0x7b, 0x24, 0x61, 0xaa, 0x16, 0x11, 0xf6, 0xb5, 0xb6,
+    0xa4, 0x0a, 0xc9, 0x55, 0x2e, 0x81, 0xa5, 0x47, 0x61, 0xcb, 0x25, 0x8f,
+    0xc2, 0x15, 0x7b, 0x0e, 0x7c, 0x36, 0x9f, 0x3a, 0xda, 0x58, 0x86, 0x1c,
+    0x5b, 0x83, 0x79, 0xe6, 0x2b, 0xcc, 0xe6, 0xfa, 0x2c, 0x61, 0xf2, 0x78,
+    0x80, 0x1b, 0xe2, 0xf3, 0x9d, 0x39, 0x2b, 0x65, 0x57, 0x91, 0x3d, 0x71,
+    0x99, 0x73, 0xa5, 0xc2, 0x79, 0x20, 0x8c, 0x07, 0x4f, 0xe5, 0xb4, 0x60,
+    0x1f, 0x99, 0xa2, 0xb1, 0x4f, 0x0c, 0xef, 0xbc, 0x59, 0x53, 0x00, 0x7d,
+    0xb1, 0x02, 0x41, 0x00, 0xfc, 0x7e, 0x23, 0x65, 0x70, 0xf8, 0xce, 0xd3,
+    0x40, 0x41, 0x80, 0x6a, 0x1d, 0x01, 0xd6, 0x01, 0xff, 0xb6, 0x1b, 0x3d,
+    0x3d, 0x59, 0x09, 0x33, 0x79, 0xc0, 0x4f, 0xde, 0x96, 0x27, 0x4b, 0x18,
+    0xc6, 0xd9, 0x78, 0xf1, 0xf4, 0x35, 0x46, 0xe9, 0x7c, 0x42, 0x7a, 0x5d,
+    0x9f, 0xef, 0x54, 0xb8, 0xf7, 0x9f, 0xc4, 0x33, 0x6c, 0xf3, 0x8c, 0x32,
+    0x46, 0x87, 0x67, 0x30, 0x7b, 0xa7, 0xac, 0xe3, 0x02, 0x41, 0x00, 0xfc,
+    0x2c, 0xdf, 0x0c, 0x0d, 0x88, 0xf5, 0xb1, 0x92, 0xa8, 0x93, 0x47, 0x63,
+    0x55, 0xf5, 0xca, 0x58, 0x43, 0xba, 0x1c, 0xe5, 0x9e, 0xb6, 0x95, 0x05,
+    0xcd, 0xb5, 0x82, 0xdf, 0xeb, 0x04, 0x53, 0x9d, 0xbd, 0xc2, 0x38, 0x16,
+    0xb3, 0x62, 0xdd, 0xa1, 0x46, 0xdb, 0x6d, 0x97, 0x93, 0x9f, 0x8a, 0xc3,
+    0x9b, 0x64, 0x7e, 0x42, 0xe3, 0x32, 0x57, 0x19, 0x1b, 0xd5, 0x6e, 0x85,
+    0xfa, 0xb8, 0x8d, 0x02, 0x41, 0x00, 0xbc, 0x3d, 0xde, 0x6d, 0xd6, 0x97,
+    0xe8, 0xba, 0x9e, 0x81, 0x37, 0x17, 0xe5, 0xa0, 0x64, 0xc9, 0x00, 0xb7,
+    0xe7, 0xfe, 0xf4, 0x29, 0xd9, 0x2e, 0x43, 0x6b, 0x19, 0x20, 0xbd, 0x99,
+    0x75, 0xe7, 0x76, 0xf8, 0xd3, 0xae, 0xaf, 0x7e, 0xb8, 0xeb, 0x81, 0xf4,
+    0x9d, 0xfe, 0x07, 0x2b, 0x0b, 0x63, 0x0b, 0x5a, 0x55, 0x90, 0x71, 0x7d,
+    0xf1, 0xdb, 0xd9, 0xb1, 0x41, 0x41, 0x68, 0x2f, 0x4e, 0x39, 0x02, 0x40,
+    0x5a, 0x34, 0x66, 0xd8, 0xf5, 0xe2, 0x7f, 0x18, 0xb5, 0x00, 0x6e, 0x26,
+    0x84, 0x27, 0x14, 0x93, 0xfb, 0xfc, 0xc6, 0x0f, 0x5e, 0x27, 0xe6, 0xe1,
+    0xe9, 0xc0, 0x8a, 0xe4, 0x34, 0xda, 0xe9, 0xa2, 0x4b, 0x73, 0xbc, 0x8c,
+    0xb9, 0xba, 0x13, 0x6c, 0x7a, 0x2b, 0x51, 0x84, 0xa3, 0x4a, 0xe0, 0x30,
+    0x10, 0x06, 0x7e, 0xed, 0x17, 0x5a, 0x14, 0x00, 0xc9, 0xef, 0x85, 0xea,
+    0x52, 0x2c, 0xbc, 0x65, 0x02, 0x40, 0x51, 0xe3, 0xf2, 0x83, 0x19, 0x9b,
+    0xc4, 0x1e, 0x2f, 0x50, 0x3d, 0xdf, 0x5a, 0xa2, 0x18, 0xca, 0x5f, 0x2e,
+    0x49, 0xaf, 0x6f, 0xcc, 0xfa, 0x65, 0x77, 0x94, 0xb5, 0xa1, 0x0a, 0xa9,
+    0xd1, 0x8a, 0x39, 0x37, 0xf4, 0x0b, 0xa0, 0xd7, 0x82, 0x27, 0x5e, 0xae,
+    0x17, 0x17, 0xa1, 0x1e, 0x54, 0x34, 0xbf, 0x6e, 0xc4, 0x8e, 0x99, 0x5d,
+    0x08, 0xf1, 0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf,
+};
+
+#ifndef OPENSSL_NO_EC
+/*
+ * kExampleECKeyDER is a sample EC private key encoded as an ECPrivateKey
+ * structure.
+ */
+static const unsigned char kExampleECKeyDER[] = {
+    0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x07, 0x0f, 0x08, 0x72, 0x7a,
+    0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9, 0x4d, 0x89, 0x68, 0x77, 0x08,
+    0xb5, 0x6f, 0xc9, 0x5d, 0x30, 0x77, 0x0e, 0xe8, 0xd1, 0xc9, 0xce, 0x0a,
+    0x8b, 0xb4, 0x6a, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69,
+    0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c,
+    0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9,
+    0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18,
+    0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16,
+    0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22,
+    0xc1,
+};
+
+/* P-384 sample EC private key in PKCS8 format (no public key) */
+static const unsigned char kExampleECKey2DER[] = {
+    0x30, 0x4E, 0x02, 0x01, 0x00, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48,
+    0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x04,
+    0x37, 0x30, 0x35, 0x02, 0x01, 0x01, 0x04, 0x30, 0x73, 0xE3, 0x3A, 0x05,
+    0xF2, 0xB6, 0x99, 0x6D, 0x0C, 0x33, 0x7F, 0x15, 0x9E, 0x10, 0xA9, 0x17,
+    0x4C, 0x0A, 0x82, 0x57, 0x71, 0x13, 0x7A, 0xAC, 0x46, 0xA2, 0x5E, 0x1C,
+    0xE0, 0xC7, 0xB2, 0xF8, 0x20, 0x40, 0xC2, 0x27, 0xC8, 0xBE, 0x02, 0x7E,
+    0x96, 0x69, 0xE0, 0x04, 0xCB, 0x89, 0x0B, 0x42
+};
+#endif
+
+typedef struct APK_DATA_st {
+    const unsigned char *kder;
+    size_t size;
+    int evptype;
+} APK_DATA;
+
+static APK_DATA keydata[] = {
+    {kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), EVP_PKEY_RSA},
+    {kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8), EVP_PKEY_RSA},
+#ifndef OPENSSL_NO_EC
+    {kExampleECKeyDER, sizeof(kExampleECKeyDER), EVP_PKEY_EC},
+    {kExampleECKey2DER, sizeof(kExampleECKey2DER), EVP_PKEY_EC}
+#endif
+};
+
+/* This is the equivalent of test_d2i_AutoPrivateKey in evp_extra_test */
+static int test_d2i_AutoPrivateKey_ex(int i)
+{
+    int ret = 0;
+    const unsigned char *p;
+    EVP_PKEY *pkey = NULL;
+    const APK_DATA *ak = &keydata[i];
+    const unsigned char *input = ak->kder;
+    size_t input_len = ak->size;
+    int expected_id = ak->evptype;
+
+    p = input;
+    if (!TEST_ptr(pkey = d2i_AutoPrivateKey_ex(NULL, &p, input_len, libctx,
+                                               NULL))
+            || !TEST_ptr_eq(p, input + input_len)
+            || !TEST_int_eq(EVP_PKEY_id(pkey), expected_id))
+        goto done;
+
+    ret = 1;
+
+ done:
+    EVP_PKEY_free(pkey);
+    return ret;
+}
+
+int setup_tests(void)
+{
+    libctx = OPENSSL_CTX_new();
+
+    if (!TEST_ptr(libctx))
+        return 0;
+
+    nullprov = OSSL_PROVIDER_load(NULL, "null");
+    if (!TEST_ptr(nullprov)) {
+        OPENSSL_CTX_free(libctx);
+        libctx = NULL;
+        return 0;
+    }
+
+    ADD_ALL_TESTS(test_d2i_AutoPrivateKey_ex, OSSL_NELEM(keydata));
+
+    return 1;
+}
+
+void cleanup_tests(void)
+{
+    OPENSSL_CTX_free(libctx);
+    OSSL_PROVIDER_unload(nullprov);
+}
diff --git a/test/recipes/30-test_evp_extra.t b/test/recipes/30-test_evp_extra.t
index 3f4b963fdb..87dc328bcb 100644
--- a/test/recipes/30-test_evp_extra.t
+++ b/test/recipes/30-test_evp_extra.t
@@ -14,6 +14,7 @@ use OpenSSL::Test qw/:DEFAULT bldtop_dir/;
 
 setup("test_evp_extra");
 
-plan tests => 1;
+plan tests => 2;
 
 ok(run(test(["evp_extra_test"])), "running evp_extra_test");
+ok(run(test(["evp_extra_test2"])), "running evp_extra_test2");
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 38cc5700d7..acaa17394e 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4683,9 +4683,9 @@ ERR_set_error                           ?	3_0_0	EXIST::FUNCTION:
 ERR_vset_error                          ?	3_0_0	EXIST::FUNCTION:
 X509_get0_authority_issuer              ?	3_0_0	EXIST::FUNCTION:
 X509_get0_authority_serial              ?	3_0_0	EXIST::FUNCTION:
-EC_GROUP_new_by_curve_name_ex           ?	3_0_0	EXIST::FUNCTION:EC
-EC_KEY_new_ex                           ?	3_0_0	EXIST::FUNCTION:EC
-EC_KEY_new_by_curve_name_ex             ?	3_0_0	EXIST::FUNCTION:EC
+EC_GROUP_new_by_curve_name_ex           ?	3_0_0	NOEXIST::FUNCTION:EC
+EC_KEY_new_ex                           ?	3_0_0	NOEXIST::FUNCTION:EC
+EC_KEY_new_by_curve_name_ex             ?	3_0_0	NOEXIST::FUNCTION:EC
 OPENSSL_hexstr2buf_ex                   ?	3_0_0	EXIST::FUNCTION:
 OPENSSL_buf2hexstr_ex                   ?	3_0_0	EXIST::FUNCTION:
 OSSL_PARAM_allocate_from_text           ?	3_0_0	EXIST::FUNCTION:
@@ -5100,3 +5100,6 @@ EVP_PKEY_parameters_eq                  ?	3_0_0	EXIST::FUNCTION:
 OSSL_PROVIDER_query_operation           ?	3_0_0	EXIST::FUNCTION:
 OSSL_PROVIDER_get0_provider_ctx         ?	3_0_0	EXIST::FUNCTION:
 OSSL_PROVIDER_get_capabilities          ?	3_0_0	EXIST::FUNCTION:
+EC_GROUP_new_by_curve_name_with_libctx  ?	3_0_0	EXIST::FUNCTION:EC
+EC_KEY_new_with_libctx                  ?	3_0_0	EXIST::FUNCTION:EC
+EC_KEY_new_by_curve_name_with_libctx    ?	3_0_0	EXIST::FUNCTION:EC


More information about the openssl-commits mailing list