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/objects.h>
20 #include <openssl/params.h>
21 #include "crypto/bn.h"
22 #include "crypto/ec.h"
23 #include "internal/param_build.h"
24 #include "prov/implementations.h"
25 #include "prov/providercommon.h"
27 static OSSL_OP_keymgmt_new_fn ec_newdata
;
28 static OSSL_OP_keymgmt_free_fn ec_freedata
;
29 static OSSL_OP_keymgmt_get_params_fn ec_get_params
;
30 static OSSL_OP_keymgmt_gettable_params_fn ec_gettable_params
;
31 static OSSL_OP_keymgmt_set_params_fn ec_set_params
;
32 static OSSL_OP_keymgmt_settable_params_fn ec_settable_params
;
33 static OSSL_OP_keymgmt_has_fn ec_has
;
34 static OSSL_OP_keymgmt_match_fn ec_match
;
35 static OSSL_OP_keymgmt_validate_fn ec_validate
;
36 static OSSL_OP_keymgmt_import_fn ec_import
;
37 static OSSL_OP_keymgmt_import_types_fn ec_import_types
;
38 static OSSL_OP_keymgmt_export_fn ec_export
;
39 static OSSL_OP_keymgmt_export_types_fn ec_export_types
;
40 static OSSL_OP_keymgmt_query_operation_name_fn ec_query_operation_name
;
42 #define EC_POSSIBLE_SELECTIONS \
43 (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS )
46 const char *ec_query_operation_name(int operation_id
)
48 switch (operation_id
) {
52 case OSSL_OP_SIGNATURE
:
53 return deflt_signature
;
60 int params_to_domparams(EC_KEY
*ec
, const OSSL_PARAM params
[])
62 const OSSL_PARAM
*param_ec_name
;
64 char *curve_name
= NULL
;
70 param_ec_name
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_NAME
);
71 if (param_ec_name
== NULL
) {
72 /* explicit parameters */
75 * TODO(3.0): should we support explicit parameters curves?
82 if (!OSSL_PARAM_get_utf8_string(param_ec_name
, &curve_name
, 0)
84 || (curve_nid
= OBJ_sn2nid(curve_name
)) == NID_undef
)
87 if ((ecg
= EC_GROUP_new_by_curve_name(curve_nid
)) == NULL
)
91 if (!EC_KEY_set_group(ec
, ecg
))
95 * TODO(3.0): if the group has changed, should we invalidate the private and
102 OPENSSL_free(curve_name
);
108 int domparams_to_params(const EC_KEY
*ec
, OSSL_PARAM_BLD
*tmpl
)
116 ecg
= EC_KEY_get0_group(ec
);
120 curve_nid
= EC_GROUP_get_curve_name(ecg
);
122 if (curve_nid
== NID_undef
) {
123 /* explicit parameters */
126 * TODO(3.0): should we support explicit parameters curves?
131 const char *curve_name
= NULL
;
133 if ((curve_name
= OBJ_nid2sn(curve_nid
)) == NULL
)
136 if (!ossl_param_bld_push_utf8_string(tmpl
, OSSL_PKEY_PARAM_EC_NAME
, curve_name
, 0))
144 * Callers of params_to_key MUST make sure that params_to_domparams has been
147 * This function only imports the bare keypair, domain parameters and other
148 * parameters are imported separately, and domain parameters are required to
152 int params_to_key(EC_KEY
*ec
, const OSSL_PARAM params
[], int include_private
)
154 const OSSL_PARAM
*param_priv_key
, *param_pub_key
;
155 BIGNUM
*priv_key
= NULL
;
156 unsigned char *pub_key
= NULL
;
158 const EC_GROUP
*ecg
= NULL
;
159 EC_POINT
*pub_point
= NULL
;
162 ecg
= EC_KEY_get0_group(ec
);
167 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PRIV_KEY
);
169 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PUB_KEY
);
172 * We want to have at least a public key either way, so we end up
173 * requiring it unconditionally.
175 if (param_pub_key
== NULL
176 || !OSSL_PARAM_get_octet_string(param_pub_key
,
177 (void **)&pub_key
, 0, &pub_key_len
)
178 || (pub_point
= EC_POINT_new(ecg
)) == NULL
179 || !EC_POINT_oct2point(ecg
, pub_point
,
180 pub_key
, pub_key_len
, NULL
))
183 if (param_priv_key
!= NULL
&& include_private
) {
188 * Key import/export should never leak the bit length of the secret
191 * For this reason, on export we use padded BIGNUMs with fixed length.
193 * When importing we also should make sure that, even if short lived,
194 * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
195 * soon as possible, so that any processing of this BIGNUM might opt for
196 * constant time implementations in the backend.
198 * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
199 * to preallocate the BIGNUM internal buffer to a fixed public size big
200 * enough that operations performed during the processing never trigger
201 * a realloc which would leak the size of the scalar through memory
207 * The order of the large prime subgroup of the curve is our choice for
208 * a fixed public size, as that is generally the upper bound for
209 * generating a private key in EC cryptosystems and should fit all valid
212 * For padding on export we just use the bit length of the order
213 * converted to bytes (rounding up).
215 * For preallocating the BIGNUM storage we look at the number of "words"
216 * required for the internal representation of the order, and we
217 * preallocate 2 extra "words" in case any of the subsequent processing
218 * might temporarily overflow the order length.
220 order
= EC_GROUP_get0_order(ecg
);
221 if (order
== NULL
|| BN_is_zero(order
))
224 fixed_top
= bn_get_top(order
) + 2;
226 if ((priv_key
= BN_new()) == NULL
)
228 if (bn_wexpand(priv_key
, fixed_top
) == NULL
)
230 BN_set_flags(priv_key
, BN_FLG_CONSTTIME
);
232 if (!OSSL_PARAM_get_BN(param_priv_key
, &priv_key
))
237 && !EC_KEY_set_private_key(ec
, priv_key
))
240 if (!EC_KEY_set_public_key(ec
, pub_point
))
246 BN_clear_free(priv_key
);
247 OPENSSL_free(pub_key
);
248 EC_POINT_free(pub_point
);
253 * Callers of key_to_params MUST make sure that domparams_to_params is also
256 * This function only exports the bare keypair, domain parameters and other
257 * parameters are exported separately.
260 int key_to_params(const EC_KEY
*eckey
, OSSL_PARAM_BLD
*tmpl
, int include_private
)
262 const BIGNUM
*priv_key
= NULL
;
263 const EC_POINT
*pub_point
= NULL
;
264 const EC_GROUP
*ecg
= NULL
;
265 unsigned char *pub_key
= NULL
;
266 size_t pub_key_len
= 0;
272 ecg
= EC_KEY_get0_group(eckey
);
273 priv_key
= EC_KEY_get0_private_key(eckey
);
274 pub_point
= EC_KEY_get0_public_key(eckey
);
276 /* group and public_key must be present, priv_key is optional */
277 if (ecg
== NULL
|| pub_point
== NULL
)
279 if ((pub_key_len
= EC_POINT_point2buf(ecg
, pub_point
,
280 POINT_CONVERSION_COMPRESSED
,
281 &pub_key
, NULL
)) == 0)
284 if (!ossl_param_bld_push_octet_string(tmpl
,
285 OSSL_PKEY_PARAM_PUB_KEY
,
286 pub_key
, pub_key_len
))
289 if (priv_key
!= NULL
&& include_private
) {
294 * Key import/export should never leak the bit length of the secret
297 * For this reason, on export we use padded BIGNUMs with fixed length.
299 * When importing we also should make sure that, even if short lived,
300 * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
301 * soon as possible, so that any processing of this BIGNUM might opt for
302 * constant time implementations in the backend.
304 * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
305 * to preallocate the BIGNUM internal buffer to a fixed public size big
306 * enough that operations performed during the processing never trigger
307 * a realloc which would leak the size of the scalar through memory
313 * The order of the large prime subgroup of the curve is our choice for
314 * a fixed public size, as that is generally the upper bound for
315 * generating a private key in EC cryptosystems and should fit all valid
318 * For padding on export we just use the bit length of the order
319 * converted to bytes (rounding up).
321 * For preallocating the BIGNUM storage we look at the number of "words"
322 * required for the internal representation of the order, and we
323 * preallocate 2 extra "words" in case any of the subsequent processing
324 * might temporarily overflow the order length.
326 ecbits
= EC_GROUP_order_bits(ecg
);
329 sz
= (ecbits
+ 7 ) / 8;
330 if (!ossl_param_bld_push_BN_pad(tmpl
,
331 OSSL_PKEY_PARAM_PRIV_KEY
,
339 OPENSSL_free(pub_key
);
344 int ec_set_param_ecdh_cofactor_mode(EC_KEY
*ec
, const OSSL_PARAM
*p
)
346 const EC_GROUP
*ecg
= EC_KEY_get0_group(ec
);
347 const BIGNUM
*cofactor
;
350 if (!OSSL_PARAM_get_int(p
, &mode
))
354 * mode can be only 0 for disable, or 1 for enable here.
356 * This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that
357 * also supports mode == -1 with the meaning of "reset to the default for
358 * the associated key".
360 if (mode
< 0 || mode
> 1)
363 if ((cofactor
= EC_GROUP_get0_cofactor(ecg
)) == NULL
)
366 /* ECDH cofactor mode has no effect if cofactor is 1 */
367 if (BN_is_one(cofactor
))
371 EC_KEY_set_flags(ec
, EC_FLAG_COFACTOR_ECDH
);
373 EC_KEY_clear_flags(ec
, EC_FLAG_COFACTOR_ECDH
);
379 int params_to_otherparams(EC_KEY
*ec
, const OSSL_PARAM params
[])
386 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH
);
387 if (p
!= NULL
&& !ec_set_param_ecdh_cofactor_mode(ec
, p
))
394 int otherparams_to_params(const EC_KEY
*ec
, OSSL_PARAM_BLD
*tmpl
)
396 int ecdh_cofactor_mode
= 0;
402 (EC_KEY_get_flags(ec
) & EC_FLAG_COFACTOR_ECDH
) ? 1 : 0;
403 if (!ossl_param_bld_push_int(tmpl
,
404 OSSL_PKEY_PARAM_USE_COFACTOR_ECDH
,
412 void *ec_newdata(void *provctx
)
418 void ec_freedata(void *keydata
)
420 EC_KEY_free(keydata
);
424 int ec_has(void *keydata
, int selection
)
426 EC_KEY
*ec
= keydata
;
429 if ((selection
& EC_POSSIBLE_SELECTIONS
) != 0)
432 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
433 ok
= ok
&& (EC_KEY_get0_public_key(ec
) != NULL
);
434 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
435 ok
= ok
&& (EC_KEY_get0_private_key(ec
) != NULL
);
436 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
437 ok
= ok
&& (EC_KEY_get0_group(ec
) != NULL
);
439 * We consider OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS to always be available,
440 * so no extra check is needed other than the previous one against
441 * EC_POSSIBLE_SELECTIONS.
447 static int ec_match(const void *keydata1
, const void *keydata2
, int selection
)
449 const EC_KEY
*ec1
= keydata1
;
450 const EC_KEY
*ec2
= keydata2
;
451 const EC_GROUP
*group_a
= EC_KEY_get0_group(ec1
);
452 const EC_GROUP
*group_b
= EC_KEY_get0_group(ec2
);
455 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
456 ok
= ok
&& group_a
!= NULL
&& group_b
!= NULL
457 && EC_GROUP_cmp(group_a
, group_b
, NULL
) == 0;
458 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0) {
459 const BIGNUM
*pa
= EC_KEY_get0_private_key(ec1
);
460 const BIGNUM
*pb
= EC_KEY_get0_private_key(ec2
);
462 ok
= ok
&& BN_cmp(pa
, pb
) == 0;
464 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0) {
465 const EC_POINT
*pa
= EC_KEY_get0_public_key(ec1
);
466 const EC_POINT
*pb
= EC_KEY_get0_public_key(ec2
);
468 ok
= ok
&& EC_POINT_cmp(group_b
, pa
, pb
, NULL
);
474 int ec_import(void *keydata
, int selection
, const OSSL_PARAM params
[])
476 EC_KEY
*ec
= keydata
;
483 * In this implementation, we can export/import only keydata in the
484 * following combinations:
485 * - domain parameters only
486 * - public key with associated domain parameters (+optional other params)
487 * - private key with associated public key and domain parameters
488 * (+optional other params)
491 * - domain parameters must always be requested
492 * - private key must be requested alongside public key
493 * - other parameters must be requested only alongside a key
495 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) == 0)
497 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0
498 && (selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) == 0)
500 if ((selection
& OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
) != 0
501 && (selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
504 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
505 ok
= ok
&& params_to_domparams(ec
, params
);
506 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0) {
507 int include_private
=
508 selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
? 1 : 0;
510 ok
= ok
&& params_to_key(ec
, params
, include_private
);
512 if ((selection
& OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
) != 0)
513 ok
= ok
&& params_to_otherparams(ec
, params
);
519 int ec_export(void *keydata
, int selection
, OSSL_CALLBACK
*param_cb
,
522 EC_KEY
*ec
= keydata
;
524 OSSL_PARAM
*params
= NULL
;
531 * In this implementation, we can export/import only keydata in the
532 * following combinations:
533 * - domain parameters only
534 * - public key with associated domain parameters (+optional other params)
535 * - private key with associated public key and domain parameters
536 * (+optional other params)
539 * - domain parameters must always be requested
540 * - private key must be requested alongside public key
541 * - other parameters must be requested only alongside a key
543 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) == 0)
545 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0
546 && (selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) == 0)
548 if ((selection
& OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
) != 0
549 && (selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
552 ossl_param_bld_init(&tmpl
);
554 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
555 ok
= ok
&& domparams_to_params(ec
, &tmpl
);
556 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0) {
557 int include_private
=
558 selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
? 1 : 0;
560 ok
= ok
&& key_to_params(ec
, &tmpl
, include_private
);
562 if ((selection
& OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
) != 0)
563 ok
= ok
&& otherparams_to_params(ec
, &tmpl
);
566 || (params
= ossl_param_bld_to_param(&tmpl
)) == NULL
)
569 ok
= param_cb(params
, cbarg
);
570 ossl_param_bld_free(params
);
574 /* IMEXPORT = IMPORT + EXPORT */
576 # define EC_IMEXPORTABLE_DOM_PARAMETERS \
577 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_NAME, NULL, 0)
578 # define EC_IMEXPORTABLE_PUBLIC_KEY \
579 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
580 # define EC_IMEXPORTABLE_PRIVATE_KEY \
581 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
582 # define EC_IMEXPORTABLE_OTHER_PARAMETERS \
583 OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL)
586 * Include all the possible combinations of OSSL_PARAM arrays for
587 * ec_imexport_types().
589 * They are in a separate file as it is ~100 lines of unreadable and
590 * uninteresting machine generated stuff.
592 * TODO(3.0): the generated list looks quite ugly, as to cover all possible
593 * combinations of the bits in `selection`, it also includes combinations that
594 * are not really useful: we might want to consider alternatives to this
597 #include "ec_kmgmt_imexport.inc"
600 const OSSL_PARAM
*ec_imexport_types(int selection
)
604 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
606 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
608 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
610 if ((selection
& OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
) != 0)
612 return ec_types
[type_select
];
616 const OSSL_PARAM
*ec_import_types(int selection
)
618 return ec_imexport_types(selection
);
622 const OSSL_PARAM
*ec_export_types(int selection
)
624 return ec_imexport_types(selection
);
628 int ec_get_params(void *key
, OSSL_PARAM params
[])
631 const EC_GROUP
*ecg
= NULL
;
634 ecg
= EC_KEY_get0_group(eck
);
638 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_MAX_SIZE
)) != NULL
639 && !OSSL_PARAM_set_int(p
, ECDSA_size(eck
)))
641 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_BITS
)) != NULL
642 && !OSSL_PARAM_set_int(p
, EC_GROUP_order_bits(ecg
)))
644 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_SECURITY_BITS
)) != NULL
) {
645 int ecbits
, sec_bits
;
647 ecbits
= EC_GROUP_order_bits(ecg
);
650 * The following estimates are based on the values published
651 * in Table 2 of "NIST Special Publication 800-57 Part 1 Revision 4"
652 * at http://dx.doi.org/10.6028/NIST.SP.800-57pt1r4 .
654 * Note that the above reference explicitly categorizes algorithms in a
655 * discrete set of values {80, 112, 128, 192, 256}, and that it is
656 * relevant only for NIST approved Elliptic Curves, while OpenSSL
657 * applies the same logic also to other curves.
659 * Classifications produced by other standardazing bodies might differ,
660 * so the results provided for "bits of security" by this provider are
661 * to be considered merely indicative, and it is the users'
662 * responsibility to compare these values against the normative
663 * references that may be relevant for their intent and purposes.
667 else if (ecbits
>= 384)
669 else if (ecbits
>= 256)
671 else if (ecbits
>= 224)
673 else if (ecbits
>= 160)
676 sec_bits
= ecbits
/ 2;
678 if (!OSSL_PARAM_set_int(p
, sec_bits
))
682 p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH
);
684 int ecdh_cofactor_mode
= 0;
687 (EC_KEY_get_flags(eck
) & EC_FLAG_COFACTOR_ECDH
) ? 1 : 0;
689 if (!OSSL_PARAM_set_int(p
, ecdh_cofactor_mode
))
696 static const OSSL_PARAM ec_known_gettable_params
[] = {
697 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS
, NULL
),
698 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS
, NULL
),
699 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE
, NULL
),
700 OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH
, NULL
),
705 const OSSL_PARAM
*ec_gettable_params(void)
707 return ec_known_gettable_params
;
710 static const OSSL_PARAM ec_known_settable_params
[] = {
711 OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH
, NULL
),
716 const OSSL_PARAM
*ec_settable_params(void)
718 return ec_known_settable_params
;
722 int ec_set_params(void *key
, const OSSL_PARAM params
[])
727 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH
);
728 if (p
!= NULL
&& !ec_set_param_ecdh_cofactor_mode(eck
, p
))
735 int ec_validate(void *keydata
, int selection
)
737 EC_KEY
*eck
= keydata
;
739 BN_CTX
*ctx
= BN_CTX_new_ex(ec_key_get_libctx(eck
));
744 if ((selection
& EC_POSSIBLE_SELECTIONS
) != 0)
747 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
748 ok
= ok
&& EC_GROUP_check(EC_KEY_get0_group(eck
), ctx
);
750 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
751 ok
= ok
&& ec_key_public_check(eck
, ctx
);
753 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
754 ok
= ok
&& ec_key_private_check(eck
);
756 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == OSSL_KEYMGMT_SELECT_KEYPAIR
)
757 ok
= ok
&& ec_key_pairwise_check(eck
, ctx
);
763 const OSSL_DISPATCH ec_keymgmt_functions
[] = {
764 { OSSL_FUNC_KEYMGMT_NEW
, (void (*)(void))ec_newdata
},
765 { OSSL_FUNC_KEYMGMT_FREE
, (void (*)(void))ec_freedata
},
766 { OSSL_FUNC_KEYMGMT_GET_PARAMS
, (void (*) (void))ec_get_params
},
767 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS
, (void (*) (void))ec_gettable_params
},
768 { OSSL_FUNC_KEYMGMT_SET_PARAMS
, (void (*) (void))ec_set_params
},
769 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS
, (void (*) (void))ec_settable_params
},
770 { OSSL_FUNC_KEYMGMT_HAS
, (void (*)(void))ec_has
},
771 { OSSL_FUNC_KEYMGMT_MATCH
, (void (*)(void))ec_match
},
772 { OSSL_FUNC_KEYMGMT_VALIDATE
, (void (*)(void))ec_validate
},
773 { OSSL_FUNC_KEYMGMT_IMPORT
, (void (*)(void))ec_import
},
774 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES
, (void (*)(void))ec_import_types
},
775 { OSSL_FUNC_KEYMGMT_EXPORT
, (void (*)(void))ec_export
},
776 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES
, (void (*)(void))ec_export_types
},
777 { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME
,
778 (void (*)(void))ec_query_operation_name
},