[openssl] master update

Richard Levitte levitte at openssl.org
Wed Apr 15 09:06:13 UTC 2020


The branch master has been updated
       via  49276c3569656a17c24517ff0781967ced2c9658 (commit)
       via  813d31717853252e777b810cb74fa5793fcbb154 (commit)
       via  10d756a70e2aeaff0c08e86014075a8623f3e0ab (commit)
       via  1f185f51a7899e1eddc9161d7781e3d5ae86ab78 (commit)
       via  2b9add696573131fc463d098ed8bcbff1b5829d9 (commit)
      from  a5c864ce901483d6f1067c22cb7c0a6322d351f5 (commit)


- Log -----------------------------------------------------------------
commit 49276c3569656a17c24517ff0781967ced2c9658
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat Apr 11 13:16:22 2020 +0200

    EVP: fix memleak in evp_pkey_downgrade()
    
    The EVP_KEYMGMT pointer in the pkey is removed when downgrading, but
    wasn't necessarily freed when need, thus leaving an incorrect
    reference count.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Nicola Tuveri <nic.tuv at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/11328)

commit 813d31717853252e777b810cb74fa5793fcbb154
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Mar 19 14:02:51 2020 +0100

    EVP: Add a temporary SM2 hack to key generation
    
    The reason to do this is many-fold.  We need EC key generation for
    other work.  However, SM2 are currently closely related to EC keys
    with legacy methods, but not with provider methods.
    
    To avoid having to wait on provider support for SM2, we temporarly
    do an extra check for what the legacy methods identify as SM2 keys
    (either the EVP_PKEY_SM2 pkey id was used, or the SM2 curve), and
    redirect to legacy code in one case, and in the other case, we
    forcedly downgrade provider side EC keys with SM2 curves to legacy
    SM2 keys, using available tools.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Nicola Tuveri <nic.tuv at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/11328)

commit 10d756a70e2aeaff0c08e86014075a8623f3e0ab
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Mar 19 14:02:42 2020 +0100

    EC: Refactor EVP_PKEY_CTX curve setting macros for param generation
    
    The macros are converted to functions, and are modified to support
    provider implementations.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Nicola Tuveri <nic.tuv at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/11328)

commit 1f185f51a7899e1eddc9161d7781e3d5ae86ab78
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Mar 19 14:02:28 2020 +0100

    PROV: Implement EC param / key generation
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Nicola Tuveri <nic.tuv at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/11328)

commit 2b9add696573131fc463d098ed8bcbff1b5829d9
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Mar 19 11:16:45 2020 +0100

    KEYMGMT: Add functions to get param/key generation parameters
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Nicola Tuveri <nic.tuv at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/11328)

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

Summary of changes:
 crypto/ec/build.info                              |   2 +-
 crypto/ec/{ec_evp_lib.c => ec_ctrl.c}             |  66 +++++++
 crypto/err/openssl.txt                            |   2 +
 crypto/evp/evp_local.h                            |   2 +
 crypto/evp/keymgmt_meth.c                         |  35 +++-
 crypto/evp/p_lib.c                                |  10 +-
 crypto/evp/pmeth_gn.c                             |  44 ++++-
 crypto/evp/pmeth_lib.c                            |  29 +++-
 doc/man3/EVP_PKEY_CTX_ctrl.pod                    |  26 ++-
 doc/man7/provider-keymgmt.pod                     |  12 ++
 include/crypto/evp.h                              |   4 +
 include/openssl/core_numbers.h                    |  28 +--
 include/openssl/ec.h                              |   9 +-
 providers/common/include/prov/providercommonerr.h |   2 +
 providers/common/provider_err.c                   |   2 +
 providers/implementations/keymgmt/ec_kmgmt.c      | 199 +++++++++++++++++++++-
 util/libcrypto.num                                |   3 +
 17 files changed, 450 insertions(+), 25 deletions(-)
 rename crypto/ec/{ec_evp_lib.c => ec_ctrl.c} (85%)

diff --git a/crypto/ec/build.info b/crypto/ec/build.info
index 8f12e2e39e..590bbbde53 100644
--- a/crypto/ec/build.info
+++ b/crypto/ec/build.info
@@ -53,7 +53,7 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
         curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
         $ECASM ec_backend.c ecx_backend.c
 SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \
-                        ec_err.c ecdh_kdf.c eck_prn.c ec_evp_lib.c
+                        ec_err.c ecdh_kdf.c eck_prn.c ec_ctrl.c
 SOURCE[../../providers/libfips.a]=$COMMON
 
 # Implementations are now spread across several libraries, so the defines
diff --git a/crypto/ec/ec_evp_lib.c b/crypto/ec/ec_ctrl.c
similarity index 85%
rename from crypto/ec/ec_evp_lib.c
rename to crypto/ec/ec_ctrl.c
index e4d7815993..314ebe6181 100644
--- a/crypto/ec/ec_evp_lib.c
+++ b/crypto/ec/ec_ctrl.c
@@ -420,3 +420,69 @@ int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
 
     return (int)ukmlen;
 }
+
+int EVP_PKEY_CTX_set_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+                                            const char *name)
+{
+    OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+    OSSL_PARAM *p = params;
+
+    if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+        return -2;
+    }
+
+    if (name == NULL)
+        return -1;
+
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME,
+                                            (char *)name, 0);
+    return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+int EVP_PKEY_CTX_get_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+                                            char *name, size_t namelen)
+{
+    OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+    OSSL_PARAM *p = params;
+
+    if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+        return -2;
+    }
+
+    if (name == NULL)
+        return -1;
+
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME,
+                                            name, namelen);
+    if (!EVP_PKEY_CTX_get_params(ctx, params))
+        return -1;
+    return 1;
+}
+
+#ifndef FIPS_MODE
+int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid)
+{
+    if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
+        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+        return -2;
+    }
+
+    /* Legacy: if key type not EC return error */
+    if (ctx->pmeth != NULL
+        && EVP_PKEY_type(ctx->pmeth->pkey_id) != EVP_PKEY_EC)
+        return -1;
+
+    if (ctx->op.keymgmt.genctx == NULL)
+        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+                                 EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN,
+                                 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID,
+                                 nid, NULL);
+
+    return EVP_PKEY_CTX_set_ec_paramgen_curve_name(ctx, OBJ_nid2sn(nid));
+}
+#endif
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index cf6b9cd893..12826beb0b 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2819,6 +2819,7 @@ PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\
 PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length
 PROV_R_INVALID_AAD:108:invalid aad
 PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length
+PROV_R_INVALID_CURVE:176:invalid curve
 PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length
 PROV_R_INVALID_DATA:115:invalid data
 PROV_R_INVALID_DIGEST:122:invalid digest
@@ -2858,6 +2859,7 @@ PROV_R_MISSING_XCGHASH:135:missing xcghash
 PROV_R_NOT_SUPPORTED:136:not supported
 PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
 PROV_R_NO_KEY_SET:114:no key set
+PROV_R_NO_PARAMETERS_SET:177:no parameters set
 PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
 PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small
 PROV_R_READ_KEY:159:read key
diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h
index 836dc33e26..40f02b340a 100644
--- a/crypto/evp/evp_local.h
+++ b/crypto/evp/evp_local.h
@@ -86,6 +86,8 @@ struct evp_keymgmt_st {
     OSSL_OP_keymgmt_gen_set_template_fn *gen_set_template;
     OSSL_OP_keymgmt_gen_set_params_fn *gen_set_params;
     OSSL_OP_keymgmt_gen_settable_params_fn *gen_settable_params;
+    OSSL_OP_keymgmt_gen_get_params_fn *gen_get_params;
+    OSSL_OP_keymgmt_gen_gettable_params_fn *gen_gettable_params;
     OSSL_OP_keymgmt_gen_fn *gen;
     OSSL_OP_keymgmt_gen_cleanup_fn *gen_cleanup;
 
diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c
index 07d52ebf68..7ea414e8dd 100644
--- a/crypto/evp/keymgmt_meth.c
+++ b/crypto/evp/keymgmt_meth.c
@@ -38,7 +38,8 @@ static void *keymgmt_from_dispatch(int name_id,
                                    OSSL_PROVIDER *prov)
 {
     EVP_KEYMGMT *keymgmt = NULL;
-    int setparamfncnt = 0, getparamfncnt = 0, setgenparamfncnt = 0;
+    int setparamfncnt = 0, getparamfncnt = 0;
+    int setgenparamfncnt = 0, getgenparamfncnt = 0;
     int importfncnt = 0, exportfncnt = 0;
 
     if ((keymgmt = keymgmt_new()) == NULL) {
@@ -76,6 +77,20 @@ static void *keymgmt_from_dispatch(int name_id,
                     OSSL_get_OP_keymgmt_gen_settable_params(fns);
             }
             break;
+        case OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS:
+            if (keymgmt->gen_get_params == NULL) {
+                getgenparamfncnt++;
+                keymgmt->gen_get_params =
+                    OSSL_get_OP_keymgmt_gen_get_params(fns);
+            }
+            break;
+        case OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS:
+            if (keymgmt->gen_gettable_params == NULL) {
+                getgenparamfncnt++;
+                keymgmt->gen_gettable_params =
+                    OSSL_get_OP_keymgmt_gen_gettable_params(fns);
+            }
+            break;
         case OSSL_FUNC_KEYMGMT_GEN:
             if (keymgmt->gen == NULL)
                 keymgmt->gen = OSSL_get_OP_keymgmt_gen(fns);
@@ -171,6 +186,7 @@ static void *keymgmt_from_dispatch(int name_id,
         || (getparamfncnt != 0 && getparamfncnt != 2)
         || (setparamfncnt != 0 && setparamfncnt != 2)
         || (setgenparamfncnt != 0 && setgenparamfncnt != 2)
+        || (getgenparamfncnt != 0 && getgenparamfncnt != 2)
         || (importfncnt != 0 && importfncnt != 2)
         || (exportfncnt != 0 && exportfncnt != 2)
         || (keymgmt->gen != NULL
@@ -319,6 +335,23 @@ const OSSL_PARAM *evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt)
     return keymgmt->gen_settable_params(provctx);
 }
 
+int evp_keymgmt_gen_get_params(const EVP_KEYMGMT *keymgmt, void *genctx,
+                               OSSL_PARAM params[])
+{
+    if (keymgmt->gen_get_params == NULL)
+        return 0;
+    return keymgmt->gen_get_params(genctx, params);
+}
+
+const OSSL_PARAM *evp_keymgmt_gen_gettable_params(const EVP_KEYMGMT *keymgmt)
+{
+    void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
+
+    if (keymgmt->gen_gettable_params == NULL)
+        return NULL;
+    return keymgmt->gen_gettable_params(provctx);
+}
+
 void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
                       OSSL_CALLBACK *cb, void *cbarg)
 {
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index c1a8a8804d..9f04c72330 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -1559,8 +1559,11 @@ int evp_pkey_downgrade(EVP_PKEY *pk)
     evp_pkey_free_it(pk);
     if (EVP_PKEY_set_type(pk, type)) {
         /* If the key is typed but empty, we're done */
-        if (keydata == NULL)
+        if (keydata == NULL) {
+            /* We're dropping the EVP_KEYMGMT */
+            EVP_KEYMGMT_free(keymgmt);
             return 1;
+        }
 
         if (pk->ameth->import_from == NULL) {
             ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION,
@@ -1579,6 +1582,9 @@ int evp_pkey_downgrade(EVP_PKEY *pk)
 
             /* Synchronize the dirty count */
             pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
+
+            /* evp_keymgmt_export() increased the refcount... */
+            EVP_KEYMGMT_free(keymgmt);
             return 1;
         }
 
@@ -1597,6 +1603,8 @@ int evp_pkey_downgrade(EVP_PKEY *pk)
         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
         return 0;
     }
+    /* EVP_PKEY_set_type_by_keymgmt() increased the refcount... */
+    EVP_KEYMGMT_free(keymgmt);
     pk->keydata = keydata;
     evp_keymgmt_util_cache_keyinfo(pk);
     return 0;     /* No downgrade, but at least the key is restored */
diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c
index 67800282de..78ed9ec781 100644
--- a/crypto/evp/pmeth_gn.c
+++ b/crypto/evp/pmeth_gn.c
@@ -20,6 +20,17 @@
 #include "crypto/evp.h"
 #include "evp_local.h"
 
+#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_EC)
+# define TMP_SM2_HACK
+#endif
+
+/* TODO(3.0) remove when provider SM2 key generation is implemented */
+#ifdef TMP_SM2_HACK
+# include <openssl/ec.h>
+# include <openssl/serializer.h>
+# include "internal/sizes.h"
+#endif
+
 static int gen_init(EVP_PKEY_CTX *ctx, int operation)
 {
     int ret = 0;
@@ -33,6 +44,12 @@ static int gen_init(EVP_PKEY_CTX *ctx, int operation)
     if (ctx->keymgmt == NULL || ctx->keymgmt->gen_init == NULL)
         goto legacy;
 
+/* TODO remove when provider SM2 key generation is implemented */
+#ifdef TMP_SM2_HACK
+    if (ctx->pmeth != NULL && ctx->pmeth->pkey_id == EVP_PKEY_SM2)
+        goto legacy;
+#endif
+
     switch (operation) {
     case EVP_PKEY_OP_PARAMGEN:
         ctx->op.keymgmt.genctx =
@@ -143,7 +160,7 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
         return -1;
     }
 
-    if (ctx->keymgmt == NULL || ctx->op.keymgmt.genctx == NULL)
+    if (ctx->op.keymgmt.genctx == NULL)
         goto legacy;
 
     ret = 1;
@@ -174,6 +191,31 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
         evp_pkey_free_legacy(*ppkey);
 #endif
 
+/* TODO remove when SM2 key have been cleanly separated from EC keys */
+#ifdef TMP_SM2_HACK
+    /*
+     * Legacy SM2 keys are implemented as EC_KEY with a twist.  The legacy
+     * key generation detects the SM2 curve and "magically" changes the pkey
+     * id accordingly.
+     * Since we don't have SM2 in the provider implementation, we need to
+     * downgrade the generated provider side key to a legacy one under the
+     * same conditions.
+     *
+     * THIS IS AN UGLY BUT TEMPORARY HACK
+     */
+    {
+        char curve_name[OSSL_MAX_NAME_SIZE] = "";
+
+        if (EVP_PKEY_CTX_get_ec_paramgen_curve_name(ctx, curve_name,
+                                                    sizeof(curve_name)) < 1
+            || strcmp(curve_name, "SM2") != 0)
+            goto end;
+    }
+
+    if (!evp_pkey_downgrade(*ppkey)
+        || !EVP_PKEY_set_alias_type(*ppkey, EVP_PKEY_SM2))
+        ret = 0;
+#endif
     goto end;
 
  legacy:
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index f36a7363db..6a86b26ded 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
@@ -611,6 +610,12 @@ int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
             && ctx->op.ciph.cipher->get_ctx_params != NULL)
         return ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.ciphprovctx,
                                                    params);
+    if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
+        && ctx->op.keymgmt.genctx != NULL
+        && ctx->keymgmt != NULL
+        && ctx->keymgmt->gen_get_params != NULL)
+        return evp_keymgmt_gen_get_params(ctx->keymgmt, ctx->op.keymgmt.genctx,
+                                          params);
     return 0;
 }
 
@@ -814,6 +819,8 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
 # ifndef OPENSSL_NO_EC
     if (keytype == EVP_PKEY_EC) {
         switch (cmd) {
+        case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
+            return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, p1);
         case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
             if (p1 == -2) {
                 return EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx);
@@ -959,6 +966,24 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
 static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
                                     const char *value)
 {
+
+    /* Special cases that we intercept */
+# ifndef OPENSSL_NO_EC
+    /*
+     * We don't support encoding settings for providers, i.e. the only
+     * possible encoding is "named_curve", so we simply fail when something
+     * else is given, and otherwise just pretend all is fine.
+     */
+    if (strcmp(name, "ec_param_enc") == 0) {
+        if (strcmp(value, "named_curve") == 0) {
+            return 1;
+        } else {
+            ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+            return -2;
+        }
+    }
+# endif
+
     if (strcmp(name, "rsa_padding_mode") == 0)
         name = OSSL_ASYM_CIPHER_PARAM_PAD_MODE;
     else if (strcmp(name, "rsa_mgf1_md") == 0)
@@ -980,6 +1005,8 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
         name = OSSL_EXCHANGE_PARAM_PAD;
 # endif
 # ifndef OPENSSL_NO_EC
+    else if (strcmp(name, "ec_paramgen_curve") == 0)
+        name = OSSL_PKEY_PARAM_EC_NAME;
     else if (strcmp(name, "ecdh_cofactor_mode") == 0)
         name = OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE;
     else if (strcmp(name, "ecdh_kdf_md") == 0)
diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod
index ca1b1fa8b9..829bdb9e3d 100644
--- a/doc/man3/EVP_PKEY_CTX_ctrl.pod
+++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod
@@ -51,6 +51,8 @@ EVP_PKEY_CTX_set_dh_kdf_outlen,
 EVP_PKEY_CTX_get_dh_kdf_outlen,
 EVP_PKEY_CTX_set0_dh_kdf_ukm,
 EVP_PKEY_CTX_get0_dh_kdf_ukm,
+EVP_PKEY_CTX_set_ec_paramgen_curve_name,
+EVP_PKEY_CTX_get_ec_paramgen_curve_name,
 EVP_PKEY_CTX_set_ec_paramgen_curve_nid,
 EVP_PKEY_CTX_set_ec_param_enc,
 EVP_PKEY_CTX_set_ecdh_cofactor_mode,
@@ -143,6 +145,10 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
 
  #include <openssl/ec.h>
 
+ int EVP_PKEY_CTX_set_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+                                             const char *name);
+ int EVP_PKEY_CTX_get_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+                                             char *name, size_t namelen);
  int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
  int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc);
  int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode);
@@ -513,12 +519,24 @@ by the library and should not be freed by the caller.
 
 =head2 EC parameters
 
-The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter
-generation to I<nid>. For EC parameter generation this macro must be called
-or an error occurs because there is no default curve.
-This function can also be called to set the curve explicitly when
+EVP_PKEY_CTX_set_ec_paramgen_curve_name() sets the EC curve to I<name> for EC
+parameter generation.
+
+EVP_PKEY_CTX_set_ec_paramgen_curve_nid() does the same as
+EVP_PKEY_CTX_set_ec_paramgen_curve_name(), but uses a I<nid> rather than a
+name string.
+
+For EC parameter generation, one of EVP_PKEY_CTX_set_ec_paramgen_curve_name()
+or EVP_PKEY_CTX_set_ec_paramgen_curve_nid() must be called or an error occurs
+because there is no default curve.
+These function can also be called to set the curve explicitly when
 generating an EC key.
 
+EVP_PKEY_CTX_get_ec_paramgen_curve_name() finds the curve name that's currently
+set with I<ctx>, and writes it to the location that I<name> points at, as long
+as its size I<namelen> is large enough to store that name, including a
+terminating NUL byte.
+
 The EVP_PKEY_CTX_set_ec_param_enc() macro sets the EC parameter encoding to
 I<param_enc> when generating EC parameters or an EC key. The encoding can be
 B<OPENSSL_EC_EXPLICIT_CURVE> for explicit parameters (the default in versions
diff --git a/doc/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod
index 00596a0a4b..52cb977cb4 100644
--- a/doc/man7/provider-keymgmt.pod
+++ b/doc/man7/provider-keymgmt.pod
@@ -22,6 +22,8 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions
  int OP_keymgmt_gen_set_template(void *genctx, void *template);
  int OP_keymgmt_gen_set_params(void *genctx, const OSSL_PARAM params[]);
  const OSSL_PARAM *OP_keymgmt_gen_settable_params(void *provctx);
+ int OP_keymgmt_gen_get_params(void *genctx, const OSSL_PARAM params[]);
+ const OSSL_PARAM *OP_keymgmt_gen_gettable_params(void *provctx);
  void *OP_keymgmt_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg);
  void OP_keymgmt_gen_cleanup(void *genctx);
 
@@ -91,6 +93,8 @@ macros in L<openssl-core_numbers.h(7)>, as follows:
  OP_keymgmt_gen_set_template     OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE
  OP_keymgmt_gen_set_params       OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS
  OP_keymgmt_gen_settable_params  OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS
+ OP_keymgmt_gen_get_params       OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS
+ OP_keymgmt_gen_gettable_params  OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS
  OP_keymgmt_gen                  OSSL_FUNC_KEYMGMT_GEN
  OP_keymgmt_gen_cleanup          OSSL_FUNC_KEYMGMT_GEN_CLEANUP
 
@@ -209,6 +213,7 @@ OP_keymgmt_free() should free the passed I<keydata>.
 
 OP_keymgmt_gen_init(), OP_keymgmt_gen_set_template(),
 OP_keymgmt_gen_set_params(), OP_keymgmt_gen_settable_params(),
+OP_keymgmt_gen_get_params(), OP_keymgmt_gen_gettable_params(),
 OP_keymgmt_gen() and OP_keymgmt_gen_cleanup() work together as a more
 elaborate context based key object constructor.
 
@@ -230,6 +235,13 @@ OP_keymgmt_gen_settable_params() should return a constant array of
 descriptor B<OSSL_PARAM>, for parameters that OP_keymgmt_gen_set_params() 
 can handle.
 
+OP_keymgmt_gen_get_params() should extract information data associated
+with the key object generation context I<genctx>.
+
+OP_keymgmt_gen_gettable_params() should return a constant array of
+descriptor B<OSSL_PARAM>, for parameters that OP_keymgmt_gen_get_params() 
+can handle.
+
 OP_keymgmt_gen() should perform the key object generation itself, and
 return the result.  The callback I<cb> should be called at regular
 intervals with indications on how the key object generation
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 8acbc6a73e..38adbd0c82 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -676,6 +676,10 @@ int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx,
                                const OSSL_PARAM params[]);
 const OSSL_PARAM *
 evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt);
+int evp_keymgmt_gen_get_params(const EVP_KEYMGMT *keymgmt, void *genctx,
+                               OSSL_PARAM params[]);
+const OSSL_PARAM *
+evp_keymgmt_gen_gettable_params(const EVP_KEYMGMT *keymgmt);
 void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
                       OSSL_CALLBACK *cb, void *cbarg);
 void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx);
diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h
index 925dfeaa3e..e3b89fd252 100644
--- a/include/openssl/core_numbers.h
+++ b/include/openssl/core_numbers.h
@@ -388,12 +388,14 @@ OSSL_CORE_MAKE_FUNC(int, OP_kdf_set_ctx_params,
 OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_new, (void *provctx))
 
 /* Generation, a more complex constructor */
-# define OSSL_FUNC_KEYMGMT_GEN_INIT                    3
-# define OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE            4
-# define OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS              5
-# define OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS         6
-# define OSSL_FUNC_KEYMGMT_GEN                         7
-# define OSSL_FUNC_KEYMGMT_GEN_CLEANUP                 8
+# define OSSL_FUNC_KEYMGMT_GEN_INIT                    2
+# define OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE            3
+# define OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS              4
+# define OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS         5
+# define OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS              6
+# define OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS         7
+# define OSSL_FUNC_KEYMGMT_GEN                         8
+# define OSSL_FUNC_KEYMGMT_GEN_CLEANUP                 9
 OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_gen_init,
                     (void *provctx, int selection))
 OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_gen_set_template,
@@ -402,23 +404,27 @@ OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_gen_set_params,
                     (void *genctx, const OSSL_PARAM params[]))
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,
                     OP_keymgmt_gen_settable_params, (void *provctx))
+OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_gen_get_params,
+                    (void *genctx, OSSL_PARAM params[]))
+OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,
+                    OP_keymgmt_gen_gettable_params, (void *provctx))
 OSSL_CORE_MAKE_FUNC(void *, OP_keymgmt_gen,
                     (void *genctx, OSSL_CALLBACK *cb, void *cbarg))
 OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_gen_cleanup, (void *genctx))
 
 /* Basic key object destruction */
-# define OSSL_FUNC_KEYMGMT_FREE                        9
+# define OSSL_FUNC_KEYMGMT_FREE                       10
 OSSL_CORE_MAKE_FUNC(void, OP_keymgmt_free, (void *keydata))
 
 /* Key object information, with discovery */
-#define OSSL_FUNC_KEYMGMT_GET_PARAMS                  10
-#define OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS             11
+#define OSSL_FUNC_KEYMGMT_GET_PARAMS                  11
+#define OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS             12
 OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_get_params,
                     (void *keydata, OSSL_PARAM params[]))
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_gettable_params, (void))
 
-#define OSSL_FUNC_KEYMGMT_SET_PARAMS                  12
-#define OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS             13
+#define OSSL_FUNC_KEYMGMT_SET_PARAMS                  13
+#define OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS             14
 OSSL_CORE_MAKE_FUNC(int, OP_keymgmt_set_params,
                     (void *keydata, const OSSL_PARAM params[]))
 OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, OP_keymgmt_settable_params, (void))
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index c5d5fc04fe..de3698a06f 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -1450,10 +1450,11 @@ DEPRECATEDIN_3_0(void EC_KEY_METHOD_get_verify
 #   endif
 #  endif
 
-#  define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
-        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
-                          EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
-                          EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
+int EVP_PKEY_CTX_set_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+                                            const char *name);
+int EVP_PKEY_CTX_get_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+                                            char *name, size_t namelen);
+int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
 
 #  define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \
         EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h
index f834a71347..5b3bcbb6a0 100644
--- a/providers/common/include/prov/providercommonerr.h
+++ b/providers/common/include/prov/providercommonerr.h
@@ -69,6 +69,7 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_INAVLID_UKM_LENGTH                        146
 # define PROV_R_INVALID_AAD                               108
 # define PROV_R_INVALID_CONSTANT_LENGTH                   157
+# define PROV_R_INVALID_CURVE                             176
 # define PROV_R_INVALID_CUSTOM_LENGTH                     111
 # define PROV_R_INVALID_DATA                              115
 # define PROV_R_INVALID_DIGEST                            122
@@ -108,6 +109,7 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_NOT_SUPPORTED                             136
 # define PROV_R_NOT_XOF_OR_INVALID_LENGTH                 113
 # define PROV_R_NO_KEY_SET                                114
+# define PROV_R_NO_PARAMETERS_SET                         177
 # define PROV_R_OUTPUT_BUFFER_TOO_SMALL                   106
 # define PROV_R_PSS_SALTLEN_TOO_SMALL                     172
 # define PROV_R_READ_KEY                                  159
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 1a65e2cc87..1018fa31ea 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -47,6 +47,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AAD), "invalid aad"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONSTANT_LENGTH),
     "invalid constant length"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CURVE), "invalid curve"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CUSTOM_LENGTH),
     "invalid custom length"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DATA), "invalid data"},
@@ -99,6 +100,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH),
     "not xof or invalid length"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_KEY_SET), "no key set"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_PARAMETERS_SET), "no parameters set"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL),
     "output buffer too small"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PSS_SALTLEN_TOO_SMALL),
diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
index 661aa2de9f..0e310ecbae 100644
--- a/providers/implementations/keymgmt/ec_kmgmt.c
+++ b/providers/implementations/keymgmt/ec_kmgmt.c
@@ -16,15 +16,25 @@
 #include <openssl/core_numbers.h>
 #include <openssl/core_names.h>
 #include <openssl/bn.h>
+#include <openssl/err.h>
 #include <openssl/objects.h>
 #include "crypto/bn.h"
 #include "crypto/ec.h"
 #include "prov/implementations.h"
 #include "prov/providercommon.h"
+#include "prov/providercommonerr.h"
 #include "prov/provider_ctx.h"
 #include "internal/param_build_set.h"
 
 static OSSL_OP_keymgmt_new_fn ec_newdata;
+static OSSL_OP_keymgmt_gen_init_fn ec_gen_init;
+static OSSL_OP_keymgmt_gen_set_template_fn ec_gen_set_template;
+static OSSL_OP_keymgmt_gen_set_params_fn ec_gen_set_params;
+static OSSL_OP_keymgmt_gen_settable_params_fn ec_gen_settable_params;
+static OSSL_OP_keymgmt_gen_get_params_fn ec_gen_get_params;
+static OSSL_OP_keymgmt_gen_gettable_params_fn ec_gen_gettable_params;
+static OSSL_OP_keymgmt_gen_fn ec_gen;
+static OSSL_OP_keymgmt_gen_cleanup_fn ec_gen_cleanup;
 static OSSL_OP_keymgmt_free_fn ec_freedata;
 static OSSL_OP_keymgmt_get_params_fn ec_get_params;
 static OSSL_OP_keymgmt_gettable_params_fn ec_gettable_params;
@@ -558,8 +568,195 @@ int ec_validate(void *keydata, int selection)
     return ok;
 }
 
+struct ec_gen_ctx {
+    OPENSSL_CTX *libctx;
+
+    EC_GROUP *gen_group;
+    int selection;
+};
+
+static void *ec_gen_init(void *provctx, int selection)
+{
+    OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
+    struct ec_gen_ctx *gctx = NULL;
+
+    if ((selection & (EC_POSSIBLE_SELECTIONS)) == 0)
+        return NULL;
+
+    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
+        gctx->libctx = libctx;
+        gctx->gen_group = NULL;
+        gctx->selection = selection;
+    }
+    return gctx;
+}
+
+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);
+    if (group == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
+        return 0;
+    }
+    EC_GROUP_free(gctx->gen_group);
+    gctx->gen_group = group;
+    return 1;
+}
+static int ec_gen_set_template(void *genctx, void *templ)
+{
+    struct ec_gen_ctx *gctx = genctx;
+    EC_KEY *ec = templ;
+    const EC_GROUP *ec_group;
+
+    if (gctx == NULL || ec == NULL)
+        return 0;
+    if ((ec_group = EC_KEY_get0_group(ec)) == NULL)
+        return 0;
+    return ec_gen_set_group(gctx, EC_GROUP_get_curve_name(ec_group));
+}
+
+static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[])
+{
+    struct ec_gen_ctx *gctx = genctx;
+    const OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_NAME))
+        != NULL) {
+        const char *curve_name = NULL;
+        int ret = 0;
+
+        switch (p->data_type) {
+        case OSSL_PARAM_UTF8_STRING:
+            /* The OSSL_PARAM functions have no support for this */
+            curve_name = p->data;
+            ret = (curve_name != NULL);
+            break;
+        case OSSL_PARAM_UTF8_PTR:
+            ret = OSSL_PARAM_get_utf8_ptr(p, &curve_name);
+            break;
+        }
+
+        if (ret) {
+            int nid = ec_curve_name2nid(curve_name);
+
+            if (nid == NID_undef) {
+                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
+                ret = 0;
+            } else {
+                ret = ec_gen_set_group(gctx, nid);
+            }
+        }
+        return ret;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *ec_gen_settable_params(void *provctx)
+{
+    static OSSL_PARAM settable[] = {
+        { OSSL_PKEY_PARAM_EC_NAME, OSSL_PARAM_UTF8_STRING, NULL, 0, 0 },
+        OSSL_PARAM_END
+    };
+
+    return settable;
+}
+
+static int ec_gen_get_params(void *genctx, OSSL_PARAM params[])
+{
+    struct ec_gen_ctx *gctx = genctx;
+    OSSL_PARAM *p;
+
+    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_NAME)) != NULL) {
+        int nid = EC_GROUP_get_curve_name(gctx->gen_group);
+        int ret = 0;
+        const char *curve_name = ec_curve_nid2name(nid);
+
+        switch (p->data_type) {
+        case OSSL_PARAM_UTF8_STRING:
+            ret = OSSL_PARAM_set_utf8_string(p, curve_name);
+            break;
+        case OSSL_PARAM_UTF8_PTR:
+            ret = OSSL_PARAM_set_utf8_ptr(p, curve_name);
+            break;
+        }
+        return ret;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM *ec_gen_gettable_params(void *provctx)
+{
+    static OSSL_PARAM gettable[] = {
+        { OSSL_PKEY_PARAM_EC_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
+        OSSL_PARAM_END
+    };
+
+    return gettable;
+}
+
+static int ec_gen_assign_group(EC_KEY *ec, EC_GROUP *group)
+{
+    if (group == NULL) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
+        return 0;
+    }
+    return EC_KEY_set_group(ec, group) > 0;
+}
+
+/*
+ * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation
+ */
+static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
+{
+    struct ec_gen_ctx *gctx = genctx;
+    EC_KEY *ec = NULL;
+    int ret = 1;                 /* Start optimistically */
+
+    if (gctx == NULL
+        || (ec = EC_KEY_new_ex(gctx->libctx)) == NULL)
+        return NULL;
+
+    /* We must always assign a group, no matter what */
+    ret = ec_gen_assign_group(ec, gctx->gen_group);
+    /* Whether you want it or not, you get a keypair, not just one half */
+    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
+        ret = ret && EC_KEY_generate_key(ec);
+
+    if (ret)
+        return ec;
+
+    /* Something went wrong, throw the key away */
+    EC_KEY_free(ec);
+    return NULL;
+}
+
+static void ec_gen_cleanup(void *genctx)
+{
+    struct ec_gen_ctx *gctx = genctx;
+
+    if (gctx == NULL)
+        return;
+
+    EC_GROUP_free(gctx->gen_group);
+    OPENSSL_free(gctx);
+}
+
 const OSSL_DISPATCH ec_keymgmt_functions[] = {
     { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata },
+    { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init },
+    { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE,
+      (void (*)(void))ec_gen_set_template },
+    { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params },
+    { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
+      (void (*)(void))ec_gen_settable_params },
+    { OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, (void (*)(void))ec_gen_get_params },
+    { OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS,
+      (void (*)(void))ec_gen_gettable_params },
+    { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))ec_gen },
+    { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup },
     { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata },
     { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))ec_get_params },
     { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))ec_gettable_params },
@@ -573,6 +770,6 @@ const OSSL_DISPATCH ec_keymgmt_functions[] = {
     { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export },
     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
     { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
-        (void (*)(void))ec_query_operation_name },
+      (void (*)(void))ec_query_operation_name },
     { 0, NULL }
 };
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 983c74a6bf..60202b9008 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5047,3 +5047,6 @@ CTLOG_new_from_base64_with_libctx       ?	3_0_0	EXIST::FUNCTION:CT
 CTLOG_STORE_new_with_libctx             ?	3_0_0	EXIST::FUNCTION:CT
 EVP_PKEY_set_ex_data                    ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_get_ex_data                    ?	3_0_0	EXIST::FUNCTION:
+EVP_PKEY_CTX_set_ec_paramgen_curve_name ?	3_0_0	EXIST::FUNCTION:EC
+EVP_PKEY_CTX_get_ec_paramgen_curve_name ?	3_0_0	EXIST::FUNCTION:EC
+EVP_PKEY_CTX_set_ec_paramgen_curve_nid  ?	3_0_0	EXIST::FUNCTION:EC


More information about the openssl-commits mailing list