2 * Copyright 2020-2021 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 * Low level APIs related to EC_KEY are deprecated for public use,
12 * but still ok for internal use.
14 #include "internal/deprecated.h"
16 #include <openssl/core_names.h>
17 #include <openssl/objects.h>
18 #include <openssl/params.h>
19 #include <openssl/err.h>
21 # include <openssl/engine.h>
22 # include <openssl/x509.h>
24 #include "crypto/bn.h"
25 #include "crypto/ec.h"
28 #include "internal/param_build_set.h"
30 /* Mapping between a flag and a name */
31 static const OSSL_ITEM encoding_nameid_map
[] = {
32 { OPENSSL_EC_EXPLICIT_CURVE
, OSSL_PKEY_EC_ENCODING_EXPLICIT
},
33 { OPENSSL_EC_NAMED_CURVE
, OSSL_PKEY_EC_ENCODING_GROUP
},
36 static const OSSL_ITEM check_group_type_nameid_map
[] = {
37 { 0, OSSL_PKEY_EC_GROUP_CHECK_DEFAULT
},
38 { EC_FLAG_CHECK_NAMED_GROUP
, OSSL_PKEY_EC_GROUP_CHECK_NAMED
},
39 { EC_FLAG_CHECK_NAMED_GROUP_NIST
, OSSL_PKEY_EC_GROUP_CHECK_NAMED_NIST
},
42 static const OSSL_ITEM format_nameid_map
[] = {
43 { (int)POINT_CONVERSION_UNCOMPRESSED
, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_UNCOMPRESSED
},
44 { (int)POINT_CONVERSION_COMPRESSED
, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_COMPRESSED
},
45 { (int)POINT_CONVERSION_HYBRID
, OSSL_PKEY_EC_POINT_CONVERSION_FORMAT_HYBRID
},
48 int ossl_ec_encoding_name2id(const char *name
)
52 /* Return the default value if there is no name */
54 return OPENSSL_EC_NAMED_CURVE
;
56 for (i
= 0, sz
= OSSL_NELEM(encoding_nameid_map
); i
< sz
; i
++) {
57 if (strcasecmp(name
, encoding_nameid_map
[i
].ptr
) == 0)
58 return encoding_nameid_map
[i
].id
;
63 static char *ec_param_encoding_id2name(int id
)
67 for (i
= 0, sz
= OSSL_NELEM(encoding_nameid_map
); i
< sz
; i
++) {
68 if (id
== (int)encoding_nameid_map
[i
].id
)
69 return encoding_nameid_map
[i
].ptr
;
74 char *ossl_ec_check_group_type_id2name(int id
)
78 for (i
= 0, sz
= OSSL_NELEM(check_group_type_nameid_map
); i
< sz
; i
++) {
79 if (id
== (int)check_group_type_nameid_map
[i
].id
)
80 return check_group_type_nameid_map
[i
].ptr
;
85 static int ec_check_group_type_name2id(const char *name
)
89 /* Return the default value if there is no name */
93 for (i
= 0, sz
= OSSL_NELEM(check_group_type_nameid_map
); i
< sz
; i
++) {
94 if (strcasecmp(name
, check_group_type_nameid_map
[i
].ptr
) == 0)
95 return check_group_type_nameid_map
[i
].id
;
100 int ossl_ec_set_check_group_type_from_name(EC_KEY
*ec
, const char *name
)
102 int flags
= ec_check_group_type_name2id(name
);
106 EC_KEY_clear_flags(ec
, EC_FLAG_CHECK_NAMED_GROUP_MASK
);
107 EC_KEY_set_flags(ec
, flags
);
111 static int ec_set_check_group_type_from_param(EC_KEY
*ec
, const OSSL_PARAM
*p
)
113 const char *name
= NULL
;
116 switch (p
->data_type
) {
117 case OSSL_PARAM_UTF8_STRING
:
119 status
= (name
!= NULL
);
121 case OSSL_PARAM_UTF8_PTR
:
122 status
= OSSL_PARAM_get_utf8_ptr(p
, &name
);
126 return ossl_ec_set_check_group_type_from_name(ec
, name
);
130 int ossl_ec_pt_format_name2id(const char *name
)
134 /* Return the default value if there is no name */
136 return (int)POINT_CONVERSION_UNCOMPRESSED
;
138 for (i
= 0, sz
= OSSL_NELEM(format_nameid_map
); i
< sz
; i
++) {
139 if (strcasecmp(name
, format_nameid_map
[i
].ptr
) == 0)
140 return format_nameid_map
[i
].id
;
145 char *ossl_ec_pt_format_id2name(int id
)
149 for (i
= 0, sz
= OSSL_NELEM(format_nameid_map
); i
< sz
; i
++) {
150 if (id
== (int)format_nameid_map
[i
].id
)
151 return format_nameid_map
[i
].ptr
;
156 static int ec_group_explicit_todata(const EC_GROUP
*group
, OSSL_PARAM_BLD
*tmpl
,
157 OSSL_PARAM params
[], BN_CTX
*bnctx
,
158 unsigned char **genbuf
)
161 const char *field_type
;
162 const OSSL_PARAM
*param
= NULL
;
163 const OSSL_PARAM
*param_p
= NULL
;
164 const OSSL_PARAM
*param_a
= NULL
;
165 const OSSL_PARAM
*param_b
= NULL
;
167 fid
= EC_GROUP_get_field_type(group
);
169 if (fid
== NID_X9_62_prime_field
) {
170 field_type
= SN_X9_62_prime_field
;
171 } else if (fid
== NID_X9_62_characteristic_two_field
) {
172 #ifdef OPENSSL_NO_EC2M
173 ERR_raise(ERR_LIB_EC
, EC_R_GF2M_NOT_SUPPORTED
);
176 field_type
= SN_X9_62_characteristic_two_field
;
179 ERR_raise(ERR_LIB_EC
, EC_R_INVALID_FIELD
);
183 param_p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_P
);
184 param_a
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_A
);
185 param_b
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_B
);
186 if (tmpl
!= NULL
|| param_p
!= NULL
|| param_a
!= NULL
|| param_b
!= NULL
)
188 BIGNUM
*p
= BN_CTX_get(bnctx
);
189 BIGNUM
*a
= BN_CTX_get(bnctx
);
190 BIGNUM
*b
= BN_CTX_get(bnctx
);
193 ERR_raise(ERR_LIB_EC
, ERR_R_MALLOC_FAILURE
);
197 if (!EC_GROUP_get_curve(group
, p
, a
, b
, bnctx
)) {
198 ERR_raise(ERR_LIB_EC
, EC_R_INVALID_CURVE
);
201 if (!ossl_param_build_set_bn(tmpl
, params
, OSSL_PKEY_PARAM_EC_P
, p
)
202 || !ossl_param_build_set_bn(tmpl
, params
, OSSL_PKEY_PARAM_EC_A
, a
)
203 || !ossl_param_build_set_bn(tmpl
, params
, OSSL_PKEY_PARAM_EC_B
, b
)) {
204 ERR_raise(ERR_LIB_EC
, ERR_R_MALLOC_FAILURE
);
209 param
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_ORDER
);
210 if (tmpl
!= NULL
|| param
!= NULL
) {
211 const BIGNUM
*order
= EC_GROUP_get0_order(group
);
214 ERR_raise(ERR_LIB_EC
, EC_R_INVALID_GROUP_ORDER
);
217 if (!ossl_param_build_set_bn(tmpl
, params
, OSSL_PKEY_PARAM_EC_ORDER
,
219 ERR_raise(ERR_LIB_EC
, ERR_R_MALLOC_FAILURE
);
224 param
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_FIELD_TYPE
);
225 if (tmpl
!= NULL
|| param
!= NULL
) {
226 if (!ossl_param_build_set_utf8_string(tmpl
, params
,
227 OSSL_PKEY_PARAM_EC_FIELD_TYPE
,
229 ERR_raise(ERR_LIB_EC
, ERR_R_MALLOC_FAILURE
);
234 param
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_GENERATOR
);
235 if (tmpl
!= NULL
|| param
!= NULL
) {
237 const EC_POINT
*genpt
= EC_GROUP_get0_generator(group
);
238 point_conversion_form_t genform
= EC_GROUP_get_point_conversion_form(group
);
241 ERR_raise(ERR_LIB_EC
, EC_R_INVALID_GENERATOR
);
244 genbuf_len
= EC_POINT_point2buf(group
, genpt
, genform
, genbuf
, bnctx
);
245 if (genbuf_len
== 0) {
246 ERR_raise(ERR_LIB_EC
, EC_R_INVALID_GENERATOR
);
249 if (!ossl_param_build_set_octet_string(tmpl
, params
,
250 OSSL_PKEY_PARAM_EC_GENERATOR
,
251 *genbuf
, genbuf_len
)) {
252 ERR_raise(ERR_LIB_EC
, ERR_R_MALLOC_FAILURE
);
257 param
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_COFACTOR
);
258 if (tmpl
!= NULL
|| param
!= NULL
) {
259 const BIGNUM
*cofactor
= EC_GROUP_get0_cofactor(group
);
262 && !ossl_param_build_set_bn(tmpl
, params
,
263 OSSL_PKEY_PARAM_EC_COFACTOR
, cofactor
)) {
264 ERR_raise(ERR_LIB_EC
, ERR_R_MALLOC_FAILURE
);
269 param
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_SEED
);
270 if (tmpl
!= NULL
|| param
!= NULL
) {
271 unsigned char *seed
= EC_GROUP_get0_seed(group
);
272 size_t seed_len
= EC_GROUP_get_seed_len(group
);
276 && !ossl_param_build_set_octet_string(tmpl
, params
,
277 OSSL_PKEY_PARAM_EC_SEED
,
279 ERR_raise(ERR_LIB_EC
, ERR_R_MALLOC_FAILURE
);
288 int ossl_ec_group_todata(const EC_GROUP
*group
, OSSL_PARAM_BLD
*tmpl
,
289 OSSL_PARAM params
[], OSSL_LIB_CTX
*libctx
,
291 BN_CTX
*bnctx
, unsigned char **genbuf
)
293 int ret
= 0, curve_nid
, encoding_flag
;
294 const char *encoding_name
, *pt_form_name
;
295 point_conversion_form_t genform
;
298 ERR_raise(ERR_LIB_EC
,EC_R_PASSED_NULL_PARAMETER
);
302 genform
= EC_GROUP_get_point_conversion_form(group
);
303 pt_form_name
= ossl_ec_pt_format_id2name(genform
);
304 if (pt_form_name
== NULL
305 || !ossl_param_build_set_utf8_string(
307 OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT
, pt_form_name
)) {
308 ERR_raise(ERR_LIB_EC
, EC_R_INVALID_FORM
);
311 encoding_flag
= EC_GROUP_get_asn1_flag(group
) & OPENSSL_EC_NAMED_CURVE
;
312 encoding_name
= ec_param_encoding_id2name(encoding_flag
);
313 if (encoding_name
== NULL
314 || !ossl_param_build_set_utf8_string(tmpl
, params
,
315 OSSL_PKEY_PARAM_EC_ENCODING
,
317 ERR_raise(ERR_LIB_EC
, EC_R_INVALID_ENCODING
);
321 curve_nid
= EC_GROUP_get_curve_name(group
);
324 * Get the explicit parameters in these two cases:
325 * - We do not have a template, i.e. specific parameters are requested
326 * - The curve is not a named curve
328 if (tmpl
== NULL
|| curve_nid
== NID_undef
)
329 if (!ec_group_explicit_todata(group
, tmpl
, params
, bnctx
, genbuf
))
332 if (curve_nid
!= NID_undef
) {
334 const char *curve_name
= OSSL_EC_curve_nid2name(curve_nid
);
336 if (curve_name
== NULL
337 || !ossl_param_build_set_utf8_string(tmpl
, params
,
338 OSSL_PKEY_PARAM_GROUP_NAME
,
340 ERR_raise(ERR_LIB_EC
, EC_R_INVALID_CURVE
);
350 * The intention with the "backend" source file is to offer backend support
351 * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
352 * implementations alike.
354 int ossl_ec_set_ecdh_cofactor_mode(EC_KEY
*ec
, int mode
)
356 const EC_GROUP
*ecg
= EC_KEY_get0_group(ec
);
357 const BIGNUM
*cofactor
;
359 * mode can be only 0 for disable, or 1 for enable here.
361 * This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that
362 * also supports mode == -1 with the meaning of "reset to the default for
363 * the associated key".
365 if (mode
< 0 || mode
> 1)
368 if ((cofactor
= EC_GROUP_get0_cofactor(ecg
)) == NULL
)
371 /* ECDH cofactor mode has no effect if cofactor is 1 */
372 if (BN_is_one(cofactor
))
376 EC_KEY_set_flags(ec
, EC_FLAG_COFACTOR_ECDH
);
378 EC_KEY_clear_flags(ec
, EC_FLAG_COFACTOR_ECDH
);
384 * Callers of ossl_ec_key_fromdata MUST make sure that ec_key_params_fromdata has
385 * been called before!
387 * This function only gets the bare keypair, domain parameters and other
388 * parameters are treated separately, and domain parameters are required to
391 int ossl_ec_key_fromdata(EC_KEY
*ec
, const OSSL_PARAM params
[], int include_private
)
393 const OSSL_PARAM
*param_priv_key
= NULL
, *param_pub_key
= NULL
;
395 BIGNUM
*priv_key
= NULL
;
396 unsigned char *pub_key
= NULL
;
398 const EC_GROUP
*ecg
= NULL
;
399 EC_POINT
*pub_point
= NULL
;
402 ecg
= EC_KEY_get0_group(ec
);
407 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PUB_KEY
);
410 OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PRIV_KEY
);
412 ctx
= BN_CTX_new_ex(ossl_ec_key_get_libctx(ec
));
416 if (param_pub_key
!= NULL
)
417 if (!OSSL_PARAM_get_octet_string(param_pub_key
,
418 (void **)&pub_key
, 0, &pub_key_len
)
419 || (pub_point
= EC_POINT_new(ecg
)) == NULL
420 || !EC_POINT_oct2point(ecg
, pub_point
, pub_key
, pub_key_len
, ctx
))
423 if (param_priv_key
!= NULL
&& include_private
) {
428 * Key import/export should never leak the bit length of the secret
431 * For this reason, on export we use padded BIGNUMs with fixed length.
433 * When importing we also should make sure that, even if short lived,
434 * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
435 * soon as possible, so that any processing of this BIGNUM might opt for
436 * constant time implementations in the backend.
438 * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
439 * to preallocate the BIGNUM internal buffer to a fixed public size big
440 * enough that operations performed during the processing never trigger
441 * a realloc which would leak the size of the scalar through memory
447 * The order of the large prime subgroup of the curve is our choice for
448 * a fixed public size, as that is generally the upper bound for
449 * generating a private key in EC cryptosystems and should fit all valid
452 * For padding on export we just use the bit length of the order
453 * converted to bytes (rounding up).
455 * For preallocating the BIGNUM storage we look at the number of "words"
456 * required for the internal representation of the order, and we
457 * preallocate 2 extra "words" in case any of the subsequent processing
458 * might temporarily overflow the order length.
460 order
= EC_GROUP_get0_order(ecg
);
461 if (order
== NULL
|| BN_is_zero(order
))
464 fixed_words
= bn_get_top(order
) + 2;
466 if ((priv_key
= BN_secure_new()) == NULL
)
468 if (bn_wexpand(priv_key
, fixed_words
) == NULL
)
470 BN_set_flags(priv_key
, BN_FLG_CONSTTIME
);
472 if (!OSSL_PARAM_get_BN(param_priv_key
, &priv_key
))
477 && !EC_KEY_set_private_key(ec
, priv_key
))
480 if (pub_point
!= NULL
481 && !EC_KEY_set_public_key(ec
, pub_point
))
488 BN_clear_free(priv_key
);
489 OPENSSL_free(pub_key
);
490 EC_POINT_free(pub_point
);
494 int ossl_ec_group_fromdata(EC_KEY
*ec
, const OSSL_PARAM params
[])
497 EC_GROUP
*group
= NULL
;
502 group
= EC_GROUP_new_from_params(params
, ossl_ec_key_get_libctx(ec
),
503 ossl_ec_key_get0_propq(ec
));
505 if (!EC_KEY_set_group(ec
, group
))
509 EC_GROUP_free(group
);
513 static int ec_key_point_format_fromdata(EC_KEY
*ec
, const OSSL_PARAM params
[])
518 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT
);
520 if (!ossl_ec_pt_format_param2id(p
, &format
)) {
521 ECerr(0, EC_R_INVALID_FORM
);
524 EC_KEY_set_conv_form(ec
, format
);
529 static int ec_key_group_check_fromdata(EC_KEY
*ec
, const OSSL_PARAM params
[])
533 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE
);
535 return ec_set_check_group_type_from_param(ec
, p
);
539 static int ec_set_include_public(EC_KEY
*ec
, int include
)
541 int flags
= EC_KEY_get_enc_flags(ec
);
544 flags
|= EC_PKEY_NO_PUBKEY
;
546 flags
&= ~EC_PKEY_NO_PUBKEY
;
547 EC_KEY_set_enc_flags(ec
, flags
);
551 int ossl_ec_key_otherparams_fromdata(EC_KEY
*ec
, const OSSL_PARAM params
[])
558 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH
);
562 if (!OSSL_PARAM_get_int(p
, &mode
)
563 || !ossl_ec_set_ecdh_cofactor_mode(ec
, mode
))
567 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC
);
571 if (!OSSL_PARAM_get_int(p
, &include
)
572 || !ec_set_include_public(ec
, include
))
575 if (!ec_key_point_format_fromdata(ec
, params
))
577 if (!ec_key_group_check_fromdata(ec
, params
))
582 int ossl_ec_key_is_foreign(const EC_KEY
*ec
)
585 if (ec
->engine
!= NULL
|| EC_KEY_get_method(ec
) != EC_KEY_OpenSSL())
592 EC_KEY
*ossl_ec_key_dup(const EC_KEY
*src
, int selection
)
597 ERR_raise(ERR_LIB_EC
, ERR_R_PASSED_NULL_PARAMETER
);
601 if ((ret
= ossl_ec_key_new_method_int(src
->libctx
, src
->propq
,
602 src
->engine
)) == NULL
)
605 /* copy the parameters */
606 if (src
->group
!= NULL
607 && (selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0) {
608 ret
->group
= ossl_ec_group_new_ex(src
->libctx
, src
->propq
,
610 if (ret
->group
== NULL
611 || !EC_GROUP_copy(ret
->group
, src
->group
))
614 if (src
->meth
!= NULL
) {
615 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
616 if (src
->engine
!= NULL
&& ENGINE_init(src
->engine
) == 0)
618 ret
->engine
= src
->engine
;
620 ret
->meth
= src
->meth
;
624 /* copy the public key */
625 if (src
->pub_key
!= NULL
626 && (selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0) {
627 if (ret
->group
== NULL
)
628 /* no parameter-less keys allowed */
630 ret
->pub_key
= EC_POINT_new(ret
->group
);
631 if (ret
->pub_key
== NULL
632 || !EC_POINT_copy(ret
->pub_key
, src
->pub_key
))
636 /* copy the private key */
637 if (src
->priv_key
!= NULL
638 && (selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0) {
639 if (ret
->group
== NULL
)
640 /* no parameter-less keys allowed */
642 ret
->priv_key
= BN_new();
643 if (ret
->priv_key
== NULL
|| !BN_copy(ret
->priv_key
, src
->priv_key
))
645 if (ret
->group
->meth
->keycopy
646 && ret
->group
->meth
->keycopy(ret
, src
) == 0)
651 if ((selection
& OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
) != 0) {
652 ret
->enc_flag
= src
->enc_flag
;
653 ret
->conv_form
= src
->conv_form
;
656 ret
->version
= src
->version
;
657 ret
->flags
= src
->flags
;
660 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY
,
661 &ret
->ex_data
, &src
->ex_data
))
665 if (ret
->meth
!= NULL
&& ret
->meth
->copy
!= NULL
) {
667 & OSSL_KEYMGMT_SELECT_KEYPAIR
) != OSSL_KEYMGMT_SELECT_KEYPAIR
)
669 if (ret
->meth
->copy(ret
, src
) == 0)
679 int ossl_ec_encoding_param2id(const OSSL_PARAM
*p
, int *id
)
681 const char *name
= NULL
;
684 switch (p
->data_type
) {
685 case OSSL_PARAM_UTF8_STRING
:
686 /* The OSSL_PARAM functions have no support for this */
688 status
= (name
!= NULL
);
690 case OSSL_PARAM_UTF8_PTR
:
691 status
= OSSL_PARAM_get_utf8_ptr(p
, &name
);
695 int i
= ossl_ec_encoding_name2id(name
);
705 int ossl_ec_pt_format_param2id(const OSSL_PARAM
*p
, int *id
)
707 const char *name
= NULL
;
710 switch (p
->data_type
) {
711 case OSSL_PARAM_UTF8_STRING
:
712 /* The OSSL_PARAM functions have no support for this */
714 status
= (name
!= NULL
);
716 case OSSL_PARAM_UTF8_PTR
:
717 status
= OSSL_PARAM_get_utf8_ptr(p
, &name
);
721 int i
= ossl_ec_pt_format_name2id(name
);
732 int ossl_x509_algor_is_sm2(const X509_ALGOR
*palg
)
735 const void *pval
= NULL
;
737 X509_ALGOR_get0(NULL
, &ptype
, &pval
, palg
);
739 if (ptype
== V_ASN1_OBJECT
)
740 return OBJ_obj2nid((ASN1_OBJECT
*)pval
) == NID_sm2
;
742 if (ptype
== V_ASN1_SEQUENCE
) {
743 const ASN1_STRING
*str
= pval
;
744 const unsigned char *der
= str
->data
;
745 int derlen
= str
->length
;
749 if ((group
= d2i_ECPKParameters(NULL
, &der
, derlen
)) == NULL
)
752 ret
= (EC_GROUP_get_curve_name(group
) == NID_sm2
);
754 EC_GROUP_free(group
);
761 EC_KEY
*ossl_ec_key_param_from_x509_algor(const X509_ALGOR
*palg
,
762 OSSL_LIB_CTX
*libctx
, const char *propq
)
765 const void *pval
= NULL
;
766 EC_KEY
*eckey
= NULL
;
767 EC_GROUP
*group
= NULL
;
769 X509_ALGOR_get0(NULL
, &ptype
, &pval
, palg
);
770 if ((eckey
= EC_KEY_new_ex(libctx
, propq
)) == NULL
) {
771 ERR_raise(ERR_LIB_EC
, ERR_R_MALLOC_FAILURE
);
775 if (ptype
== V_ASN1_SEQUENCE
) {
776 const ASN1_STRING
*pstr
= pval
;
777 const unsigned char *pm
= pstr
->data
;
778 int pmlen
= pstr
->length
;
781 if (d2i_ECParameters(&eckey
, &pm
, pmlen
) == NULL
) {
782 ERR_raise(ERR_LIB_EC
, EC_R_DECODE_ERROR
);
785 } else if (ptype
== V_ASN1_OBJECT
) {
786 const ASN1_OBJECT
*poid
= pval
;
789 * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
792 group
= EC_GROUP_new_by_curve_name_ex(libctx
, propq
, OBJ_obj2nid(poid
));
795 EC_GROUP_set_asn1_flag(group
, OPENSSL_EC_NAMED_CURVE
);
796 if (EC_KEY_set_group(eckey
, group
) == 0)
798 EC_GROUP_free(group
);
800 ERR_raise(ERR_LIB_EC
, EC_R_DECODE_ERROR
);
808 EC_GROUP_free(group
);
812 EC_KEY
*ossl_ec_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO
*p8inf
,
813 OSSL_LIB_CTX
*libctx
, const char *propq
)
815 const unsigned char *p
= NULL
;
817 EC_KEY
*eckey
= NULL
;
818 const X509_ALGOR
*palg
;
820 if (!PKCS8_pkey_get0(NULL
, &p
, &pklen
, &palg
, p8inf
))
822 eckey
= ossl_ec_key_param_from_x509_algor(palg
, libctx
, propq
);
826 /* We have parameters now set private key */
827 if (!d2i_ECPrivateKey(&eckey
, &p
, pklen
)) {
828 ERR_raise(ERR_LIB_EC
, EC_R_DECODE_ERROR
);