xref: /openbsd/lib/libcrypto/ec/ec_ameth.c (revision 3bef86f7)
1 /* $OpenBSD: ec_ameth.c,v 1.51 2024/01/04 17:01:26 tb Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2006.
4  */
5 /* ====================================================================
6  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 
59 #include <stdio.h>
60 
61 #include <openssl/opensslconf.h>
62 
63 #include <openssl/bn.h>
64 #include <openssl/cms.h>
65 #include <openssl/ec.h>
66 #include <openssl/err.h>
67 #include <openssl/x509.h>
68 
69 #include "asn1_local.h"
70 #include "ec_local.h"
71 #include "evp_local.h"
72 
73 #ifndef OPENSSL_NO_CMS
74 static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
75 static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
76 #endif
77 
78 static void
79 eckey_param_free(int ptype, void *pval)
80 {
81 	if (pval == NULL)
82 		return;
83 	if (ptype == V_ASN1_OBJECT)
84 		ASN1_OBJECT_free(pval);		/* XXX - really necessary? */
85 	else
86 		ASN1_STRING_free(pval);
87 }
88 
89 static int
90 eckey_get_curve_name(const EC_KEY *eckey, int *nid)
91 {
92 	const EC_GROUP *group;
93 
94 	*nid = NID_undef;
95 
96 	if ((group = EC_KEY_get0_group(eckey)) == NULL) {
97 		ECerror(EC_R_MISSING_PARAMETERS);
98 		return 0;
99 	}
100 	if (EC_GROUP_get_asn1_flag(group) != 0)
101 		*nid = EC_GROUP_get_curve_name(group);
102 
103 	return 1;
104 }
105 
106 static int
107 eckey_to_explicit_params(EC_KEY *eckey, void **out_val)
108 {
109 	ASN1_STRING *astr = NULL;
110 	unsigned char *params = NULL;
111 	int params_len = 0;
112 	int ret = 0;
113 
114 	*out_val = NULL;
115 
116 	if ((params_len = i2d_ECParameters(eckey, &params)) <= 0) {
117 		ECerror(ERR_R_EC_LIB);
118 		params_len = 0;
119 		goto err;
120 	}
121 
122 	if ((astr = ASN1_STRING_new()) == NULL)
123 		goto err;
124 	ASN1_STRING_set0(astr, params, params_len);
125 	params = NULL;
126 	params_len = 0;
127 
128 	*out_val = astr;
129 	astr = NULL;
130 
131 	ret = 1;
132 
133  err:
134 	freezero(params, params_len);
135 	ASN1_STRING_free(astr);
136 
137 	return ret;
138 }
139 
140 static int
141 eckey_from_explicit_params(const ASN1_STRING *astr, EC_KEY **out_eckey)
142 {
143 	const unsigned char *params = astr->data;
144 	int params_len = astr->length;
145 
146 	EC_KEY_free(*out_eckey);
147 	if ((*out_eckey = d2i_ECParameters(NULL, &params, params_len)) == NULL) {
148 		ECerror(EC_R_DECODE_ERROR);
149 		return 0;
150 	}
151 
152 	return 1;
153 }
154 
155 static int
156 eckey_to_object(const EC_KEY *eckey, void **out_val)
157 {
158 	int nid = NID_undef;
159 
160 	*out_val = NULL;
161 
162 	if (!eckey_get_curve_name(eckey, &nid))
163 		return 0;
164 	if ((*out_val = OBJ_nid2obj(nid)) == NULL)
165 		return 0;
166 
167 	return 1;
168 }
169 
170 static int
171 eckey_from_object(const ASN1_OBJECT *aobj, EC_KEY **out_eckey)
172 {
173 	int nid;
174 
175 	*out_eckey = NULL;
176 
177 	if ((nid = OBJ_obj2nid(aobj)) == NID_undef)
178 		return 0;
179 	if ((*out_eckey = EC_KEY_new_by_curve_name(nid)) == NULL)
180 		return 0;
181 
182 	return 1;
183 }
184 
185 static int
186 eckey_to_params(EC_KEY *eckey, int *out_type, void **out_val)
187 {
188 	int nid;
189 
190 	*out_type = NID_undef;
191 	*out_val = NULL;
192 
193 	if (!eckey_get_curve_name(eckey, &nid))
194 		return 0;
195 
196 	if (nid == NID_undef) {
197 		*out_type = V_ASN1_SEQUENCE;
198 		return eckey_to_explicit_params(eckey, out_val);
199 	} else {
200 		*out_type = V_ASN1_OBJECT;
201 		return eckey_to_object(eckey, out_val);
202 	}
203 }
204 
205 static int
206 eckey_from_params(int ptype, const void *pval, EC_KEY **out_eckey)
207 {
208 	*out_eckey = NULL;
209 
210 	if (ptype == V_ASN1_SEQUENCE)
211 		return eckey_from_explicit_params(pval, out_eckey);
212 	if (ptype == V_ASN1_OBJECT)
213 		return eckey_from_object(pval, out_eckey);
214 
215 	ECerror(EC_R_DECODE_ERROR);
216 	return 0;
217 }
218 
219 static int
220 eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
221 {
222 	EC_KEY *eckey = pkey->pkey.ec;
223 	int ptype = V_ASN1_UNDEF;
224 	void *pval = NULL;
225 	ASN1_OBJECT *aobj;
226 	unsigned char *key = NULL;
227 	int key_len = 0;
228 	int ret = 0;
229 
230 	if (!eckey_to_params(eckey, &ptype, &pval)) {
231 		ECerror(ERR_R_EC_LIB);
232 		goto err;
233 	}
234 	if ((key_len = i2o_ECPublicKey(eckey, &key)) <= 0) {
235 		key_len = 0;
236 		goto err;
237 	}
238 	if ((aobj = OBJ_nid2obj(EVP_PKEY_EC)) == NULL)
239 		goto err;
240 	if (!X509_PUBKEY_set0_param(pk, aobj, ptype, pval, key, key_len))
241 		goto err;
242 	pval = NULL;
243 	key = NULL;
244 	key_len = 0;
245 
246 	ret = 1;
247 
248  err:
249 	eckey_param_free(ptype, pval);
250 	freezero(key, key_len);
251 
252 	return ret;
253 }
254 
255 static int
256 eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
257 {
258 	const unsigned char *p = NULL;
259 	const void *pval;
260 	int ptype, pklen;
261 	EC_KEY *eckey = NULL;
262 	X509_ALGOR *palg;
263 	int ret = 0;
264 
265 	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
266 		goto err;
267 
268 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
269 	if (!eckey_from_params(ptype, pval, &eckey))
270 		goto err;
271 
272 	if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
273 		ECerror(EC_R_DECODE_ERROR);
274 		goto err;
275 	}
276 	if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
277 		goto err;
278 	eckey = NULL;
279 
280 	ret = 1;
281 
282  err:
283 	EC_KEY_free(eckey);
284 
285 	return ret;
286 }
287 
288 static int
289 eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
290 {
291 	const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
292 	const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec);
293 	const EC_POINT *pb = EC_KEY_get0_public_key(b->pkey.ec);
294 	int r;
295 
296 	r = EC_POINT_cmp(group, pa, pb, NULL);
297 	if (r == 0)
298 		return 1;
299 	if (r == 1)
300 		return 0;
301 	return -2;
302 }
303 
304 static int
305 eckey_compute_pubkey(EC_KEY *eckey)
306 {
307 	const BIGNUM *priv_key;
308 	const EC_GROUP *group;
309 	EC_POINT *pub_key = NULL;
310 	int ret = 0;
311 
312 	if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL)
313 		goto err;
314 	if ((group = EC_KEY_get0_group(eckey)) == NULL)
315 		goto err;
316 	if ((pub_key = EC_POINT_new(group)) == NULL)
317 		goto err;
318 	if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
319 		goto err;
320 	if (!EC_KEY_set_public_key(eckey, pub_key))
321 		goto err;
322 	pub_key = NULL;
323 
324 	ret = 1;
325 
326  err:
327 	EC_POINT_free(pub_key);
328 
329 	return ret;
330 }
331 
332 static int
333 eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
334 {
335 	const unsigned char *priv = NULL;
336 	int priv_len;
337 	const void *pval;
338 	int ptype;
339 	EC_KEY *eckey = NULL;
340 	const X509_ALGOR *palg;
341 	int ret = 0;
342 
343 	if (!PKCS8_pkey_get0(NULL, &priv, &priv_len, &palg, p8))
344 		goto err;
345 
346 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
347 	if (!eckey_from_params(ptype, pval, &eckey))
348 		goto err;
349 
350 	/* Decode private key into eckey. */
351 	if (d2i_ECPrivateKey(&eckey, &priv, priv_len) == NULL) {
352 		ECerror(EC_R_DECODE_ERROR);
353 		goto err;
354 	}
355 	/* If public key was missing from SEC1 key, compute it. */
356 	if (EC_KEY_get0_public_key(eckey) == NULL) {
357 		if (!eckey_compute_pubkey(eckey))
358 			goto err;
359 	}
360 
361 	if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
362 		goto err;
363 	eckey = NULL;
364 
365 	ret = 1;
366 
367  err:
368 	EC_KEY_free(eckey);
369 
370 	return ret;
371 }
372 
373 static int
374 eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
375 {
376 	EC_KEY *eckey = pkey->pkey.ec;
377 	void *pval = NULL;
378 	int ptype = V_ASN1_UNDEF;
379 	ASN1_OBJECT *aobj;
380 	unsigned char *key = NULL;
381 	int key_len = 0;
382 	unsigned int flags;
383 	int ret = 0;
384 
385 	flags = EC_KEY_get_enc_flags(eckey);
386 
387 	if (!eckey_to_params(eckey, &ptype, &pval)) {
388 		ECerror(EC_R_DECODE_ERROR);
389 		goto err;
390 	}
391 
392 	/* PKCS#11 12.11: don't include parameters in the SEC1 private key. */
393 	EC_KEY_set_enc_flags(eckey, flags | EC_PKEY_NO_PARAMETERS);
394 
395 	if ((key_len = i2d_ECPrivateKey(eckey, &key)) <= 0) {
396 		ECerror(ERR_R_EC_LIB);
397 		key_len = 0;
398 		goto err;
399 	}
400 	if ((aobj = OBJ_nid2obj(NID_X9_62_id_ecPublicKey)) == NULL)
401 		goto err;
402 	if (!PKCS8_pkey_set0(p8, aobj, 0, ptype, pval, key, key_len))
403 		goto err;
404 	pval = NULL;
405 	key = NULL;
406 	key_len = 0;
407 
408 	ret = 1;
409 
410  err:
411 	eckey_param_free(ptype, pval);
412 	freezero(key, key_len);
413 
414 	EC_KEY_set_enc_flags(eckey, flags);
415 
416 	return ret;
417 }
418 
419 static int
420 ec_size(const EVP_PKEY *pkey)
421 {
422 	return ECDSA_size(pkey->pkey.ec);
423 }
424 
425 static int
426 ec_bits(const EVP_PKEY *pkey)
427 {
428 	const EC_GROUP *group;
429 
430 	if ((group = EC_KEY_get0_group(pkey->pkey.ec)) == NULL)
431 		return 0;
432 
433 	return EC_GROUP_order_bits(group);
434 }
435 
436 static int
437 ec_security_bits(const EVP_PKEY *pkey)
438 {
439 	int ecbits = ec_bits(pkey);
440 
441 	if (ecbits >= 512)
442 		return 256;
443 	if (ecbits >= 384)
444 		return 192;
445 	if (ecbits >= 256)
446 		return 128;
447 	if (ecbits >= 224)
448 		return 112;
449 	if (ecbits >= 160)
450 		return 80;
451 
452 	return ecbits / 2;
453 }
454 
455 static int
456 ec_missing_parameters(const EVP_PKEY *pkey)
457 {
458 	if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
459 		return 1;
460 	return 0;
461 }
462 
463 static int
464 ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
465 {
466 	return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec));
467 }
468 
469 static int
470 ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
471 {
472 	const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec);
473 	const EC_GROUP *group_b = EC_KEY_get0_group(b->pkey.ec);
474 
475 	if (EC_GROUP_cmp(group_a, group_b, NULL))
476 		return 0;
477 	else
478 		return 1;
479 }
480 
481 static void
482 ec_free(EVP_PKEY *pkey)
483 {
484 	EC_KEY_free(pkey->pkey.ec);
485 }
486 
487 static int
488 do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
489 {
490 	const char *ecstr;
491 	int ret = 0, reason = ERR_R_BIO_LIB;
492 	BIGNUM *pub_key = NULL;
493 	BN_CTX *ctx = NULL;
494 	const EC_GROUP *group;
495 	const EC_POINT *public_key;
496 	const BIGNUM *priv_key;
497 
498 	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
499 		reason = ERR_R_PASSED_NULL_PARAMETER;
500 		goto err;
501 	}
502 	ctx = BN_CTX_new();
503 	if (ctx == NULL) {
504 		reason = ERR_R_MALLOC_FAILURE;
505 		goto err;
506 	}
507 	if (ktype > 0) {
508 		public_key = EC_KEY_get0_public_key(x);
509 		if (public_key != NULL) {
510 			if ((pub_key = EC_POINT_point2bn(group, public_key,
511 			    EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) {
512 				reason = ERR_R_EC_LIB;
513 				goto err;
514 			}
515 		}
516 	}
517 	if (ktype == 2) {
518 		priv_key = EC_KEY_get0_private_key(x);
519 	} else
520 		priv_key = NULL;
521 
522 	if (ktype == 2)
523 		ecstr = "Private-Key";
524 	else if (ktype == 1)
525 		ecstr = "Public-Key";
526 	else
527 		ecstr = "ECDSA-Parameters";
528 
529 	if (!BIO_indent(bp, off, 128))
530 		goto err;
531 	if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
532 	    EC_GROUP_order_bits(group)) <= 0)
533 		goto err;
534 
535 	if (!bn_printf(bp, priv_key, off, "priv:"))
536 		goto err;
537 	if (!bn_printf(bp, pub_key, off, "pub: "))
538 		goto err;
539 	if (!ECPKParameters_print(bp, group, off))
540 		goto err;
541 
542 	ret = 1;
543 
544  err:
545 	if (!ret)
546 		ECerror(reason);
547 	BN_free(pub_key);
548 	BN_CTX_free(ctx);
549 
550 	return (ret);
551 }
552 
553 static int
554 eckey_param_decode(EVP_PKEY *pkey, const unsigned char **param, int param_len)
555 {
556 	EC_KEY *eckey;
557 	int ret = 0;
558 
559 	if ((eckey = d2i_ECParameters(NULL, param, param_len)) == NULL)
560 		goto err;
561 	if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
562 		goto err;
563 	eckey = NULL;
564 
565 	ret = 1;
566 
567  err:
568 	EC_KEY_free(eckey);
569 
570 	return ret;
571 }
572 
573 static int
574 eckey_param_encode(const EVP_PKEY *pkey, unsigned char **param)
575 {
576 	return i2d_ECParameters(pkey->pkey.ec, param);
577 }
578 
579 static int
580 eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
581 {
582 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
583 }
584 
585 static int
586 eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
587 {
588 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
589 }
590 
591 
592 static int
593 eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx)
594 {
595 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
596 }
597 
598 static int
599 old_ec_priv_decode(EVP_PKEY *pkey, const unsigned char **priv, int priv_len)
600 {
601 	EC_KEY *eckey;
602 	int ret = 0;
603 
604 	if ((eckey = d2i_ECPrivateKey(NULL, priv, priv_len)) == NULL)
605 		goto err;
606 	if (!EVP_PKEY_assign_EC_KEY(pkey, eckey))
607 		goto err;
608 	eckey = NULL;
609 
610 	ret = 1;
611 
612  err:
613 	EC_KEY_free(eckey);
614 
615 	return ret;
616 }
617 
618 static int
619 old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **priv)
620 {
621 	return i2d_ECPrivateKey(pkey->pkey.ec, priv);
622 }
623 
624 static int
625 ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
626 {
627 	switch (op) {
628 	case ASN1_PKEY_CTRL_PKCS7_SIGN:
629 		if (arg1 == 0) {
630 			int snid, hnid;
631 			X509_ALGOR *alg1, *alg2;
632 			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
633 			if (alg1 == NULL || alg1->algorithm == NULL)
634 				return -1;
635 			hnid = OBJ_obj2nid(alg1->algorithm);
636 			if (hnid == NID_undef)
637 				return -1;
638 			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
639 				return -1;
640 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
641 		}
642 		return 1;
643 
644 #ifndef OPENSSL_NO_CMS
645 	case ASN1_PKEY_CTRL_CMS_SIGN:
646 		if (arg1 == 0) {
647 			X509_ALGOR *alg1, *alg2;
648 			int snid, hnid;
649 
650 			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
651 			if (alg1 == NULL || alg1->algorithm == NULL)
652 				return -1;
653 			hnid = OBJ_obj2nid(alg1->algorithm);
654 			if (hnid == NID_undef)
655 				return -1;
656 			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
657 				return -1;
658 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
659 		}
660 		return 1;
661 
662 	case ASN1_PKEY_CTRL_CMS_ENVELOPE:
663 		if (arg1 == 0)
664 			return ecdh_cms_encrypt(arg2);
665 		else if (arg1 == 1)
666 			return ecdh_cms_decrypt(arg2);
667 		return -2;
668 
669 	case ASN1_PKEY_CTRL_CMS_RI_TYPE:
670 		*(int *)arg2 = CMS_RECIPINFO_AGREE;
671 		return 1;
672 #endif
673 
674 	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
675 		*(int *) arg2 = NID_sha1;
676 		return 2;
677 
678 	default:
679 		return -2;
680 
681 	}
682 
683 }
684 
685 static int
686 ec_pkey_check(const EVP_PKEY *pkey)
687 {
688 	EC_KEY *eckey = pkey->pkey.ec;
689 
690 	if (eckey->priv_key == NULL) {
691 		ECerror(EC_R_MISSING_PRIVATE_KEY);
692 		return 0;
693 	}
694 
695 	return EC_KEY_check_key(eckey);
696 }
697 
698 static int
699 ec_pkey_public_check(const EVP_PKEY *pkey)
700 {
701 	EC_KEY *eckey = pkey->pkey.ec;
702 
703 	/* This also checks the private key, but oh, well... */
704 	return EC_KEY_check_key(eckey);
705 }
706 
707 static int
708 ec_pkey_param_check(const EVP_PKEY *pkey)
709 {
710 	EC_KEY *eckey = pkey->pkey.ec;
711 
712 	if (eckey->group == NULL) {
713 		ECerror(EC_R_MISSING_PARAMETERS);
714 		return 0;
715 	}
716 
717 	return EC_GROUP_check(eckey->group, NULL);
718 }
719 
720 #ifndef OPENSSL_NO_CMS
721 
722 static int
723 ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg,
724     ASN1_BIT_STRING *pubkey)
725 {
726 	const ASN1_OBJECT *aoid;
727 	int atype;
728 	const void *aval;
729 	int rv = 0;
730 	EVP_PKEY *pkpeer = NULL;
731 	EC_KEY *ecpeer = NULL;
732 	const unsigned char *p;
733 	int plen;
734 
735 	X509_ALGOR_get0(&aoid, &atype, &aval, alg);
736 	if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
737 		goto err;
738 
739 	/* If absent parameters get group from main key */
740 	if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
741 		const EC_GROUP *grp;
742 		EVP_PKEY *pk;
743 
744 		pk = EVP_PKEY_CTX_get0_pkey(pctx);
745 		if (!pk)
746 			goto err;
747 		grp = EC_KEY_get0_group(pk->pkey.ec);
748 		ecpeer = EC_KEY_new();
749 		if (ecpeer == NULL)
750 			goto err;
751 		if (!EC_KEY_set_group(ecpeer, grp))
752 			goto err;
753 	} else {
754 		if (!eckey_from_params(atype, aval, &ecpeer))
755 			goto err;
756 	}
757 
758 	/* We have parameters now set public key */
759 	plen = ASN1_STRING_length(pubkey);
760 	p = ASN1_STRING_get0_data(pubkey);
761 	if (!p || !plen)
762 		goto err;
763 	if (!o2i_ECPublicKey(&ecpeer, &p, plen))
764 		goto err;
765 	pkpeer = EVP_PKEY_new();
766 	if (pkpeer == NULL)
767 		goto err;
768 	EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
769 	if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
770 		rv = 1;
771  err:
772 	EC_KEY_free(ecpeer);
773 	EVP_PKEY_free(pkpeer);
774 	return rv;
775 }
776 
777 /* Set KDF parameters based on KDF NID */
778 static int
779 ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
780 {
781 	int kdf_nid, kdfmd_nid, cofactor;
782 	const EVP_MD *kdf_md;
783 
784 	if (eckdf_nid == NID_undef)
785 		return 0;
786 
787 	/* Lookup KDF type, cofactor mode and digest */
788 	if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
789 		return 0;
790 
791 	if (kdf_nid == NID_dh_std_kdf)
792 		cofactor = 0;
793 	else if (kdf_nid == NID_dh_cofactor_kdf)
794 		cofactor = 1;
795 	else
796 		return 0;
797 
798 	if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
799 		return 0;
800 
801 	if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
802 		return 0;
803 
804 	kdf_md = EVP_get_digestbynid(kdfmd_nid);
805 	if (!kdf_md)
806 		return 0;
807 
808 	if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
809 		return 0;
810 
811 	return 1;
812 }
813 
814 static int
815 ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
816 {
817 	X509_ALGOR *alg, *kekalg = NULL;
818 	ASN1_OCTET_STRING *ukm;
819 	const unsigned char *p;
820 	unsigned char *der = NULL;
821 	int plen, keylen;
822 	const EVP_CIPHER *kekcipher;
823 	EVP_CIPHER_CTX *kekctx;
824 	int rv = 0;
825 
826 	if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
827 		return 0;
828 
829 	if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
830 		ECerror(EC_R_KDF_PARAMETER_ERROR);
831 		return 0;
832 	}
833 
834 	if (alg->parameter->type != V_ASN1_SEQUENCE)
835 		return 0;
836 
837 	p = alg->parameter->value.sequence->data;
838 	plen = alg->parameter->value.sequence->length;
839 	kekalg = d2i_X509_ALGOR(NULL, &p, plen);
840 	if (!kekalg)
841 		goto err;
842 	kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
843 	if (!kekctx)
844 		goto err;
845 	kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
846 	if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
847 		goto err;
848 	if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
849 		goto err;
850 	if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
851 		goto err;
852 
853 	keylen = EVP_CIPHER_CTX_key_length(kekctx);
854 	if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
855 		goto err;
856 
857 	plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
858 	if (plen <= 0)
859 		goto err;
860 
861 	if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
862 		goto err;
863 	der = NULL;
864 
865 	rv = 1;
866  err:
867 	X509_ALGOR_free(kekalg);
868 	free(der);
869 	return rv;
870 }
871 
872 static int
873 ecdh_cms_decrypt(CMS_RecipientInfo *ri)
874 {
875 	EVP_PKEY_CTX *pctx;
876 
877 	pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
878 	if (!pctx)
879 		return 0;
880 
881 	/* See if we need to set peer key */
882 	if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
883 		X509_ALGOR *alg;
884 		ASN1_BIT_STRING *pubkey;
885 
886 		if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
887 		    NULL, NULL, NULL))
888 			return 0;
889 		if (!alg || !pubkey)
890 			return 0;
891 		if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
892 			ECerror(EC_R_PEER_KEY_ERROR);
893 			return 0;
894 		}
895 	}
896 
897 	/* Set ECDH derivation parameters and initialise unwrap context */
898 	if (!ecdh_cms_set_shared_info(pctx, ri)) {
899 		ECerror(EC_R_SHARED_INFO_ERROR);
900 		return 0;
901 	}
902 
903 	return 1;
904 }
905 
906 static int
907 ecdh_cms_encrypt(CMS_RecipientInfo *ri)
908 {
909 	EVP_PKEY_CTX *pctx;
910 	EVP_PKEY *pkey;
911 	EVP_CIPHER_CTX *ctx;
912 	int keylen;
913 	X509_ALGOR *talg, *wrap_alg = NULL;
914 	const ASN1_OBJECT *aoid;
915 	ASN1_BIT_STRING *pubkey;
916 	ASN1_STRING *wrap_str;
917 	ASN1_OCTET_STRING *ukm;
918 	unsigned char *penc = NULL;
919 	int penclen;
920 	int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
921 	const EVP_MD *kdf_md;
922 	int rv = 0;
923 
924 	pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
925 	if (!pctx)
926 		return 0;
927 	/* Get ephemeral key */
928 	pkey = EVP_PKEY_CTX_get0_pkey(pctx);
929 	if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
930 	    NULL, NULL, NULL))
931 		goto err;
932 	X509_ALGOR_get0(&aoid, NULL, NULL, talg);
933 
934 	/* Is everything uninitialised? */
935 	if (aoid == OBJ_nid2obj(NID_undef)) {
936 		EC_KEY *eckey = pkey->pkey.ec;
937 		unsigned char *p;
938 
939 		/* Set the key */
940 		penclen = i2o_ECPublicKey(eckey, NULL);
941 		if (penclen <= 0)
942 			goto err;
943 		penc = malloc(penclen);
944 		if (penc == NULL)
945 			goto err;
946 		p = penc;
947 		penclen = i2o_ECPublicKey(eckey, &p);
948 		if (penclen <= 0)
949 			goto err;
950 		ASN1_STRING_set0(pubkey, penc, penclen);
951 		if (!asn1_abs_set_unused_bits(pubkey, 0))
952 			goto err;
953 		penc = NULL;
954 
955 		X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
956 		    V_ASN1_UNDEF, NULL);
957 	}
958 
959 	/* See if custom parameters set */
960 	kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
961 	if (kdf_type <= 0)
962 		goto err;
963 	if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
964 		goto err;
965 	ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
966 	if (ecdh_nid < 0)
967 		goto err;
968 	else if (ecdh_nid == 0)
969 		ecdh_nid = NID_dh_std_kdf;
970 	else if (ecdh_nid == 1)
971 		ecdh_nid = NID_dh_cofactor_kdf;
972 
973 	if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
974 		kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
975 		if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
976 			goto err;
977 	} else {
978 		/* Unknown KDF */
979 		goto err;
980 	}
981 	if (kdf_md == NULL) {
982 		/* Fixme later for better MD */
983 		kdf_md = EVP_sha1();
984 		if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
985 			goto err;
986 	}
987 
988 	if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
989 		goto err;
990 
991 	/* Lookup NID for KDF+cofactor+digest */
992 	if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
993 		goto err;
994 
995 	/* Get wrap NID */
996 	ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
997 	wrap_nid = EVP_CIPHER_CTX_type(ctx);
998 	keylen = EVP_CIPHER_CTX_key_length(ctx);
999 
1000 	/* Package wrap algorithm in an AlgorithmIdentifier */
1001 
1002 	wrap_alg = X509_ALGOR_new();
1003 	if (wrap_alg == NULL)
1004 		goto err;
1005 	wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
1006 	wrap_alg->parameter = ASN1_TYPE_new();
1007 	if (wrap_alg->parameter == NULL)
1008 		goto err;
1009 	if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
1010 		goto err;
1011 	if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
1012 		ASN1_TYPE_free(wrap_alg->parameter);
1013 		wrap_alg->parameter = NULL;
1014 	}
1015 
1016 	if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
1017 		goto err;
1018 
1019 	penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
1020 	if (penclen <= 0)
1021 		goto err;
1022 
1023 	if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
1024 		goto err;
1025 	penc = NULL;
1026 
1027 	/*
1028 	 * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
1029 	 * of another AlgorithmIdentifier.
1030 	 */
1031 	penclen = i2d_X509_ALGOR(wrap_alg, &penc);
1032 	if (penclen <= 0)
1033 		goto err;
1034 	wrap_str = ASN1_STRING_new();
1035 	if (wrap_str == NULL)
1036 		goto err;
1037 	ASN1_STRING_set0(wrap_str, penc, penclen);
1038 	penc = NULL;
1039 	X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
1040 
1041 	rv = 1;
1042 
1043  err:
1044 	free(penc);
1045 	X509_ALGOR_free(wrap_alg);
1046 	return rv;
1047 }
1048 
1049 #endif
1050 
1051 const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
1052 	.base_method = &eckey_asn1_meth,
1053 	.pkey_id = EVP_PKEY_EC,
1054 
1055 	.pem_str = "EC",
1056 	.info = "OpenSSL EC algorithm",
1057 
1058 	.pub_decode = eckey_pub_decode,
1059 	.pub_encode = eckey_pub_encode,
1060 	.pub_cmp = eckey_pub_cmp,
1061 	.pub_print = eckey_pub_print,
1062 
1063 	.priv_decode = eckey_priv_decode,
1064 	.priv_encode = eckey_priv_encode,
1065 	.priv_print = eckey_priv_print,
1066 
1067 	.pkey_size = ec_size,
1068 	.pkey_bits = ec_bits,
1069 	.pkey_security_bits = ec_security_bits,
1070 
1071 	.param_decode = eckey_param_decode,
1072 	.param_encode = eckey_param_encode,
1073 	.param_missing = ec_missing_parameters,
1074 	.param_copy = ec_copy_parameters,
1075 	.param_cmp = ec_cmp_parameters,
1076 	.param_print = eckey_param_print,
1077 
1078 	.pkey_free = ec_free,
1079 	.pkey_ctrl = ec_pkey_ctrl,
1080 	.old_priv_decode = old_ec_priv_decode,
1081 	.old_priv_encode = old_ec_priv_encode,
1082 
1083 	.pkey_check = ec_pkey_check,
1084 	.pkey_public_check = ec_pkey_public_check,
1085 	.pkey_param_check = ec_pkey_param_check,
1086 };
1087