2 * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * ECDH/ECDSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
16 #include <openssl/core_numbers.h>
17 #include <openssl/core_names.h>
18 #include <openssl/bn.h>
19 #include <openssl/err.h>
20 #include <openssl/objects.h>
21 #include "crypto/bn.h"
22 #include "crypto/ec.h"
23 #include "prov/implementations.h"
24 #include "prov/providercommon.h"
25 #include "prov/providercommonerr.h"
26 #include "prov/provider_ctx.h"
27 #include "internal/param_build_set.h"
29 static OSSL_OP_keymgmt_new_fn ec_newdata;
30 static OSSL_OP_keymgmt_gen_init_fn ec_gen_init;
31 static OSSL_OP_keymgmt_gen_set_template_fn ec_gen_set_template;
32 static OSSL_OP_keymgmt_gen_set_params_fn ec_gen_set_params;
33 static OSSL_OP_keymgmt_gen_settable_params_fn ec_gen_settable_params;
34 static OSSL_OP_keymgmt_gen_get_params_fn ec_gen_get_params;
35 static OSSL_OP_keymgmt_gen_gettable_params_fn ec_gen_gettable_params;
36 static OSSL_OP_keymgmt_gen_fn ec_gen;
37 static OSSL_OP_keymgmt_gen_cleanup_fn ec_gen_cleanup;
38 static OSSL_OP_keymgmt_free_fn ec_freedata;
39 static OSSL_OP_keymgmt_get_params_fn ec_get_params;
40 static OSSL_OP_keymgmt_gettable_params_fn ec_gettable_params;
41 static OSSL_OP_keymgmt_set_params_fn ec_set_params;
42 static OSSL_OP_keymgmt_settable_params_fn ec_settable_params;
43 static OSSL_OP_keymgmt_has_fn ec_has;
44 static OSSL_OP_keymgmt_match_fn ec_match;
45 static OSSL_OP_keymgmt_validate_fn ec_validate;
46 static OSSL_OP_keymgmt_import_fn ec_import;
47 static OSSL_OP_keymgmt_import_types_fn ec_import_types;
48 static OSSL_OP_keymgmt_export_fn ec_export;
49 static OSSL_OP_keymgmt_export_types_fn ec_export_types;
50 static OSSL_OP_keymgmt_query_operation_name_fn ec_query_operation_name;
52 #define EC_POSSIBLE_SELECTIONS \
53 (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS)
56 const char *ec_query_operation_name(int operation_id)
58 switch (operation_id) {
61 case OSSL_OP_SIGNATURE:
68 int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
77 ecg = EC_KEY_get0_group(ec);
81 curve_nid = EC_GROUP_get_curve_name(ecg);
83 if (curve_nid == NID_undef) {
84 /* TODO(3.0): should we support explicit parameters curves? */
88 const char *curve_name = NULL;
90 if ((curve_name = ec_curve_nid2name(curve_nid)) == NULL)
92 if (!ossl_param_build_set_utf8_string(tmpl, params,
93 OSSL_PKEY_PARAM_EC_NAME,
103 * Callers of key_to_params MUST make sure that domparams_to_params is also
106 * This function only exports the bare keypair, domain parameters and other
107 * parameters are exported separately.
110 int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
111 OSSL_PARAM params[], int include_private,
112 unsigned char **pub_key)
114 const BIGNUM *priv_key = NULL;
115 const EC_POINT *pub_point = NULL;
116 const EC_GROUP *ecg = NULL;
117 size_t pub_key_len = 0;
119 BN_CTX *bnctx = NULL;
122 || (ecg = EC_KEY_get0_group(eckey)) == NULL)
125 priv_key = EC_KEY_get0_private_key(eckey);
126 pub_point = EC_KEY_get0_public_key(eckey);
128 if (pub_point != NULL) {
130 * EC_POINT_point2buf() can generate random numbers in some
131 * implementations so we need to ensure we use the correct libctx.
133 bnctx = BN_CTX_new_ex(ec_key_get_libctx(eckey));
137 /* convert pub_point to a octet string according to the SECG standard */
138 if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
139 POINT_CONVERSION_COMPRESSED,
140 pub_key, bnctx)) == 0
141 || !ossl_param_build_set_octet_string(tmpl, params,
142 OSSL_PKEY_PARAM_PUB_KEY,
143 *pub_key, pub_key_len))
147 if (priv_key != NULL && include_private) {
152 * Key import/export should never leak the bit length of the secret
155 * For this reason, on export we use padded BIGNUMs with fixed length.
157 * When importing we also should make sure that, even if short lived,
158 * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
159 * soon as possible, so that any processing of this BIGNUM might opt for
160 * constant time implementations in the backend.
162 * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
163 * to preallocate the BIGNUM internal buffer to a fixed public size big
164 * enough that operations performed during the processing never trigger
165 * a realloc which would leak the size of the scalar through memory
171 * The order of the large prime subgroup of the curve is our choice for
172 * a fixed public size, as that is generally the upper bound for
173 * generating a private key in EC cryptosystems and should fit all valid
176 * For padding on export we just use the bit length of the order
177 * converted to bytes (rounding up).
179 * For preallocating the BIGNUM storage we look at the number of "words"
180 * required for the internal representation of the order, and we
181 * preallocate 2 extra "words" in case any of the subsequent processing
182 * might temporarily overflow the order length.
184 ecbits = EC_GROUP_order_bits(ecg);
187 sz = (ecbits + 7 ) / 8;
189 if (!ossl_param_build_set_bn_pad(tmpl, params,
190 OSSL_PKEY_PARAM_PRIV_KEY,
201 int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
204 int ecdh_cofactor_mode = 0;
210 (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
211 return ossl_param_build_set_int(tmpl, params,
212 OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
217 void *ec_newdata(void *provctx)
219 return EC_KEY_new_ex(PROV_LIBRARY_CONTEXT_OF(provctx));
223 void ec_freedata(void *keydata)
225 EC_KEY_free(keydata);
229 int ec_has(void *keydata, int selection)
231 EC_KEY *ec = keydata;
235 if ((selection & EC_POSSIBLE_SELECTIONS) != 0)
238 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
239 ok = ok && (EC_KEY_get0_public_key(ec) != NULL);
240 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
241 ok = ok && (EC_KEY_get0_private_key(ec) != NULL);
242 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
243 ok = ok && (EC_KEY_get0_group(ec) != NULL);
245 * We consider OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS to always be
246 * available, so no extra check is needed other than the previous one
247 * against EC_POSSIBLE_SELECTIONS.
253 static int ec_match(const void *keydata1, const void *keydata2, int selection)
255 const EC_KEY *ec1 = keydata1;
256 const EC_KEY *ec2 = keydata2;
257 const EC_GROUP *group_a = EC_KEY_get0_group(ec1);
258 const EC_GROUP *group_b = EC_KEY_get0_group(ec2);
261 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
262 ok = ok && group_a != NULL && group_b != NULL
263 && EC_GROUP_cmp(group_a, group_b, NULL) == 0;
264 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
265 const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
266 const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
268 ok = ok && BN_cmp(pa, pb) == 0;
270 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
271 const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
272 const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
274 ok = ok && EC_POINT_cmp(group_b, pa, pb, NULL);
280 int ec_import(void *keydata, int selection, const OSSL_PARAM params[])
282 EC_KEY *ec = keydata;
289 * In this implementation, we can export/import only keydata in the
290 * following combinations:
291 * - domain parameters only
292 * - public key with associated domain parameters (+optional other params)
293 * - private key with associated public key and domain parameters
294 * (+optional other params)
297 * - domain parameters must always be requested
298 * - private key must be requested alongside public key
299 * - other parameters must be requested only alongside a key
301 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
303 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
304 && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
306 if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0
307 && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
310 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
311 ok = ok && ec_key_domparams_fromdata(ec, params);
312 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
313 int include_private =
314 selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
316 ok = ok && ec_key_fromdata(ec, params, include_private);
318 if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
319 ok = ok && ec_key_otherparams_fromdata(ec, params);
325 int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
328 EC_KEY *ec = keydata;
329 OSSL_PARAM_BLD *tmpl;
330 OSSL_PARAM *params = NULL;
331 unsigned char *pub_key = NULL;
338 * In this implementation, we can export/import only keydata in the
339 * following combinations:
340 * - domain parameters only
341 * - public key with associated domain parameters (+optional other params)
342 * - private key with associated public key and domain parameters
343 * (+optional other params)
346 * - domain parameters must always be requested
347 * - private key must be requested alongside public key
348 * - other parameters must be requested only alongside a key
350 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
352 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
353 && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
355 if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0
356 && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
359 tmpl = OSSL_PARAM_BLD_new();
363 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
364 ok = ok && domparams_to_params(ec, tmpl, NULL);
366 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
367 int include_private =
368 selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
370 ok = ok && key_to_params(ec, tmpl, NULL, include_private, &pub_key);
372 if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
373 ok = ok && otherparams_to_params(ec, tmpl, NULL);
375 if (ok && (params = OSSL_PARAM_BLD_to_param(tmpl)) != NULL)
376 ok = param_cb(params, cbarg);
378 OSSL_PARAM_BLD_free_params(params);
379 OSSL_PARAM_BLD_free(tmpl);
380 OPENSSL_free(pub_key);
384 /* IMEXPORT = IMPORT + EXPORT */
386 # define EC_IMEXPORTABLE_DOM_PARAMETERS \
387 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_NAME, NULL, 0)
388 # define EC_IMEXPORTABLE_PUBLIC_KEY \
389 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
390 # define EC_IMEXPORTABLE_PRIVATE_KEY \
391 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
392 # define EC_IMEXPORTABLE_OTHER_PARAMETERS \
393 OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL)
396 * Include all the possible combinations of OSSL_PARAM arrays for
397 * ec_imexport_types().
399 * They are in a separate file as it is ~100 lines of unreadable and
400 * uninteresting machine generated stuff.
402 * TODO(3.0): the generated list looks quite ugly, as to cover all possible
403 * combinations of the bits in `selection`, it also includes combinations that
404 * are not really useful: we might want to consider alternatives to this
407 #include "ec_kmgmt_imexport.inc"
410 const OSSL_PARAM *ec_imexport_types(int selection)
414 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
416 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
418 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
420 if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
422 return ec_types[type_select];
426 const OSSL_PARAM *ec_import_types(int selection)
428 return ec_imexport_types(selection);
432 const OSSL_PARAM *ec_export_types(int selection)
434 return ec_imexport_types(selection);
438 int ec_get_params(void *key, OSSL_PARAM params[])
442 const EC_GROUP *ecg = NULL;
444 unsigned char *pub_key = NULL;
446 ecg = EC_KEY_get0_group(eck);
450 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
451 && !OSSL_PARAM_set_int(p, ECDSA_size(eck)))
453 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
454 && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg)))
456 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) {
457 int ecbits, sec_bits;
459 ecbits = EC_GROUP_order_bits(ecg);
462 * The following estimates are based on the values published
463 * in Table 2 of "NIST Special Publication 800-57 Part 1 Revision 4"
464 * at http://dx.doi.org/10.6028/NIST.SP.800-57pt1r4 .
466 * Note that the above reference explicitly categorizes algorithms in a
467 * discrete set of values {80, 112, 128, 192, 256}, and that it is
468 * relevant only for NIST approved Elliptic Curves, while OpenSSL
469 * applies the same logic also to other curves.
471 * Classifications produced by other standardazing bodies might differ,
472 * so the results provided for "bits of security" by this provider are
473 * to be considered merely indicative, and it is the users'
474 * responsibility to compare these values against the normative
475 * references that may be relevant for their intent and purposes.
479 else if (ecbits >= 384)
481 else if (ecbits >= 256)
483 else if (ecbits >= 224)
485 else if (ecbits >= 160)
488 sec_bits = ecbits / 2;
490 if (!OSSL_PARAM_set_int(p, sec_bits))
494 p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
496 int ecdh_cofactor_mode = 0;
499 (EC_KEY_get_flags(eck) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
501 if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode))
504 ret = domparams_to_params(eck, NULL, params)
505 && key_to_params(eck, NULL, params, 1, &pub_key)
506 && otherparams_to_params(eck, NULL, params);
507 OPENSSL_free(pub_key);
511 static const OSSL_PARAM ec_known_gettable_params[] = {
512 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
513 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
514 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
515 EC_IMEXPORTABLE_DOM_PARAMETERS,
516 EC_IMEXPORTABLE_PUBLIC_KEY,
517 EC_IMEXPORTABLE_PRIVATE_KEY,
518 EC_IMEXPORTABLE_OTHER_PARAMETERS,
523 const OSSL_PARAM *ec_gettable_params(void)
525 return ec_known_gettable_params;
528 static const OSSL_PARAM ec_known_settable_params[] = {
529 OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
534 const OSSL_PARAM *ec_settable_params(void)
536 return ec_known_settable_params;
540 int ec_set_params(void *key, const OSSL_PARAM params[])
545 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
546 if (p != NULL && !ec_set_param_ecdh_cofactor_mode(eck, p))
553 int ec_validate(void *keydata, int selection)
555 EC_KEY *eck = keydata;
557 BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(eck));
562 if ((selection & EC_POSSIBLE_SELECTIONS) != 0)
565 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
566 ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
568 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
569 ok = ok && ec_key_public_check(eck, ctx);
571 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
572 ok = ok && ec_key_private_check(eck);
574 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
575 ok = ok && ec_key_pairwise_check(eck, ctx);
588 static void *ec_gen_init(void *provctx, int selection)
590 OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
591 struct ec_gen_ctx *gctx = NULL;
593 if ((selection & (EC_POSSIBLE_SELECTIONS)) == 0)
596 if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
597 gctx->libctx = libctx;
598 gctx->gen_group = NULL;
599 gctx->selection = selection;
604 static int ec_gen_set_group(void *genctx, int nid)
606 struct ec_gen_ctx *gctx = genctx;
609 group = EC_GROUP_new_by_curve_name_ex(gctx->libctx, nid);
611 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
614 EC_GROUP_free(gctx->gen_group);
615 gctx->gen_group = group;
618 static int ec_gen_set_template(void *genctx, void *templ)
620 struct ec_gen_ctx *gctx = genctx;
622 const EC_GROUP *ec_group;
624 if (gctx == NULL || ec == NULL)
626 if ((ec_group = EC_KEY_get0_group(ec)) == NULL)
628 return ec_gen_set_group(gctx, EC_GROUP_get_curve_name(ec_group));
631 static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[])
633 struct ec_gen_ctx *gctx = genctx;
636 if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_NAME))
638 const char *curve_name = NULL;
641 switch (p->data_type) {
642 case OSSL_PARAM_UTF8_STRING:
643 /* The OSSL_PARAM functions have no support for this */
644 curve_name = p->data;
645 ret = (curve_name != NULL);
647 case OSSL_PARAM_UTF8_PTR:
648 ret = OSSL_PARAM_get_utf8_ptr(p, &curve_name);
653 int nid = ec_curve_name2nid(curve_name);
655 if (nid == NID_undef) {
656 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
659 ret = ec_gen_set_group(gctx, nid);
667 static const OSSL_PARAM *ec_gen_settable_params(void *provctx)
669 static OSSL_PARAM settable[] = {
670 { OSSL_PKEY_PARAM_EC_NAME, OSSL_PARAM_UTF8_STRING, NULL, 0, 0 },
677 static int ec_gen_get_params(void *genctx, OSSL_PARAM params[])
679 struct ec_gen_ctx *gctx = genctx;
682 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_NAME)) != NULL) {
683 int nid = EC_GROUP_get_curve_name(gctx->gen_group);
685 const char *curve_name = ec_curve_nid2name(nid);
687 switch (p->data_type) {
688 case OSSL_PARAM_UTF8_STRING:
689 ret = OSSL_PARAM_set_utf8_string(p, curve_name);
691 case OSSL_PARAM_UTF8_PTR:
692 ret = OSSL_PARAM_set_utf8_ptr(p, curve_name);
700 static const OSSL_PARAM *ec_gen_gettable_params(void *provctx)
702 static OSSL_PARAM gettable[] = {
703 { OSSL_PKEY_PARAM_EC_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
710 static int ec_gen_assign_group(EC_KEY *ec, EC_GROUP *group)
713 ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
716 return EC_KEY_set_group(ec, group) > 0;
720 * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation
722 static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
724 struct ec_gen_ctx *gctx = genctx;
726 int ret = 1; /* Start optimistically */
729 || (ec = EC_KEY_new_ex(gctx->libctx)) == NULL)
732 /* We must always assign a group, no matter what */
733 ret = ec_gen_assign_group(ec, gctx->gen_group);
734 /* Whether you want it or not, you get a keypair, not just one half */
735 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
736 ret = ret && EC_KEY_generate_key(ec);
741 /* Something went wrong, throw the key away */
746 static void ec_gen_cleanup(void *genctx)
748 struct ec_gen_ctx *gctx = genctx;
753 EC_GROUP_free(gctx->gen_group);
757 const OSSL_DISPATCH ec_keymgmt_functions[] = {
758 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata },
759 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init },
760 { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE,
761 (void (*)(void))ec_gen_set_template },
762 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params },
763 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
764 (void (*)(void))ec_gen_settable_params },
765 { OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS, (void (*)(void))ec_gen_get_params },
766 { OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS,
767 (void (*)(void))ec_gen_gettable_params },
768 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))ec_gen },
769 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup },
770 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata },
771 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))ec_get_params },
772 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))ec_gettable_params },
773 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))ec_set_params },
774 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))ec_settable_params },
775 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has },
776 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match },
777 { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))ec_validate },
778 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ec_import },
779 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types },
780 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export },
781 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
782 { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
783 (void (*)(void))ec_query_operation_name },