xref: /openbsd/lib/libcrypto/ec/ec_ameth.c (revision 5a38ef86)
1 /* $OpenBSD: ec_ameth.c,v 1.29 2021/12/12 21:30:13 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_locl.h"
70 #include "evp_locl.h"
71 
72 #ifndef OPENSSL_NO_CMS
73 static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
74 static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
75 #endif
76 
77 static int
78 eckey_param2type(int *pptype, void **ppval, EC_KEY * ec_key)
79 {
80 	const EC_GROUP *group;
81 	int nid;
82 	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
83 		ECerror(EC_R_MISSING_PARAMETERS);
84 		return 0;
85 	}
86 	if (EC_GROUP_get_asn1_flag(group) &&
87 	    (nid = EC_GROUP_get_curve_name(group))) {
88 		/* we have a 'named curve' => just set the OID */
89 		*ppval = OBJ_nid2obj(nid);
90 		*pptype = V_ASN1_OBJECT;
91 	} else {
92 		/* explicit parameters */
93 		ASN1_STRING *pstr = NULL;
94 		pstr = ASN1_STRING_new();
95 		if (!pstr)
96 			return 0;
97 		pstr->length = i2d_ECParameters(ec_key, &pstr->data);
98 		if (pstr->length <= 0) {
99 			ASN1_STRING_free(pstr);
100 			ECerror(ERR_R_EC_LIB);
101 			return 0;
102 		}
103 		*ppval = pstr;
104 		*pptype = V_ASN1_SEQUENCE;
105 	}
106 	return 1;
107 }
108 
109 static int
110 eckey_pub_encode(X509_PUBKEY * pk, const EVP_PKEY * pkey)
111 {
112 	EC_KEY *ec_key = pkey->pkey.ec;
113 	void *pval = NULL;
114 	int ptype;
115 	unsigned char *penc = NULL, *p;
116 	int penclen;
117 
118 	if (!eckey_param2type(&ptype, &pval, ec_key)) {
119 		ECerror(ERR_R_EC_LIB);
120 		return 0;
121 	}
122 	penclen = i2o_ECPublicKey(ec_key, NULL);
123 	if (penclen <= 0)
124 		goto err;
125 	penc = malloc(penclen);
126 	if (!penc)
127 		goto err;
128 	p = penc;
129 	penclen = i2o_ECPublicKey(ec_key, &p);
130 	if (penclen <= 0)
131 		goto err;
132 	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
133 		ptype, pval, penc, penclen))
134 		return 1;
135  err:
136 	if (ptype == V_ASN1_OBJECT)
137 		ASN1_OBJECT_free(pval);
138 	else
139 		ASN1_STRING_free(pval);
140 	free(penc);
141 	return 0;
142 }
143 
144 static EC_KEY *
145 eckey_type2param(int ptype, const void *pval)
146 {
147 	EC_GROUP *group = NULL;
148 	EC_KEY *eckey = NULL;
149 
150 	if (ptype == V_ASN1_SEQUENCE) {
151 		const ASN1_STRING *pstr = pval;
152 		const unsigned char *pm = NULL;
153 		int pmlen;
154 
155 		pm = pstr->data;
156 		pmlen = pstr->length;
157 		if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
158 			ECerror(EC_R_DECODE_ERROR);
159 			goto ecerr;
160 		}
161 	} else if (ptype == V_ASN1_OBJECT) {
162 		const ASN1_OBJECT *poid = pval;
163 
164 		/*
165 		 * type == V_ASN1_OBJECT => the parameters are given by an
166 		 * asn1 OID
167 		 */
168 		if ((eckey = EC_KEY_new()) == NULL) {
169 			ECerror(ERR_R_MALLOC_FAILURE);
170 			goto ecerr;
171 		}
172 		group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
173 		if (group == NULL)
174 			goto ecerr;
175 		EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
176 		if (EC_KEY_set_group(eckey, group) == 0)
177 			goto ecerr;
178 	} else {
179 		ECerror(EC_R_DECODE_ERROR);
180 		goto ecerr;
181 	}
182 
183 	EC_GROUP_free(group);
184 	return eckey;
185 
186  ecerr:
187 	EC_KEY_free(eckey);
188 	EC_GROUP_free(group);
189 	return NULL;
190 }
191 
192 static int
193 eckey_pub_decode(EVP_PKEY * pkey, X509_PUBKEY * pubkey)
194 {
195 	const unsigned char *p = NULL;
196 	const void *pval;
197 	int ptype, pklen;
198 	EC_KEY *eckey = NULL;
199 	X509_ALGOR *palg;
200 
201 	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
202 		return 0;
203 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
204 
205 	eckey = eckey_type2param(ptype, pval);
206 
207 	if (!eckey) {
208 		ECerror(ERR_R_EC_LIB);
209 		return 0;
210 	}
211 	/* We have parameters now set public key */
212 	if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
213 		ECerror(EC_R_DECODE_ERROR);
214 		goto ecerr;
215 	}
216 	EVP_PKEY_assign_EC_KEY(pkey, eckey);
217 	return 1;
218 
219  ecerr:
220 	if (eckey)
221 		EC_KEY_free(eckey);
222 	return 0;
223 }
224 
225 static int
226 eckey_pub_cmp(const EVP_PKEY * a, const EVP_PKEY * b)
227 {
228 	int r;
229 	const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
230 	const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec);
231 
232 	r = EC_POINT_cmp(group, pa, pb, NULL);
233 	if (r == 0)
234 		return 1;
235 	if (r == 1)
236 		return 0;
237 	return -2;
238 }
239 
240 static int
241 eckey_priv_decode(EVP_PKEY * pkey, const PKCS8_PRIV_KEY_INFO * p8)
242 {
243 	const unsigned char *p = NULL;
244 	const void *pval;
245 	int ptype, pklen;
246 	EC_KEY *eckey = NULL;
247 	const X509_ALGOR *palg;
248 
249 	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
250 		return 0;
251 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
252 
253 	eckey = eckey_type2param(ptype, pval);
254 
255 	if (!eckey)
256 		goto ecliberr;
257 
258 	/* We have parameters now set private key */
259 	if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
260 		ECerror(EC_R_DECODE_ERROR);
261 		goto ecerr;
262 	}
263 	/* calculate public key (if necessary) */
264 	if (EC_KEY_get0_public_key(eckey) == NULL) {
265 		const BIGNUM *priv_key;
266 		const EC_GROUP *group;
267 		EC_POINT *pub_key;
268 		/*
269 		 * the public key was not included in the SEC1 private key =>
270 		 * calculate the public key
271 		 */
272 		group = EC_KEY_get0_group(eckey);
273 		pub_key = EC_POINT_new(group);
274 		if (pub_key == NULL) {
275 			ECerror(ERR_R_EC_LIB);
276 			goto ecliberr;
277 		}
278 		if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
279 			EC_POINT_free(pub_key);
280 			ECerror(ERR_R_EC_LIB);
281 			goto ecliberr;
282 		}
283 		priv_key = EC_KEY_get0_private_key(eckey);
284 		if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
285 			EC_POINT_free(pub_key);
286 			ECerror(ERR_R_EC_LIB);
287 			goto ecliberr;
288 		}
289 		if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
290 			EC_POINT_free(pub_key);
291 			ECerror(ERR_R_EC_LIB);
292 			goto ecliberr;
293 		}
294 		EC_POINT_free(pub_key);
295 	}
296 	EVP_PKEY_assign_EC_KEY(pkey, eckey);
297 	return 1;
298 
299  ecliberr:
300 	ECerror(ERR_R_EC_LIB);
301  ecerr:
302 	if (eckey)
303 		EC_KEY_free(eckey);
304 	return 0;
305 }
306 
307 static int
308 eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey)
309 {
310 	EC_KEY *ec_key;
311 	unsigned char *ep, *p;
312 	int eplen, ptype;
313 	void *pval;
314 	unsigned int tmp_flags, old_flags;
315 
316 	ec_key = pkey->pkey.ec;
317 
318 	if (!eckey_param2type(&ptype, &pval, ec_key)) {
319 		ECerror(EC_R_DECODE_ERROR);
320 		return 0;
321 	}
322 	/* set the private key */
323 
324 	/*
325 	 * do not include the parameters in the SEC1 private key see PKCS#11
326 	 * 12.11
327 	 */
328 	old_flags = EC_KEY_get_enc_flags(ec_key);
329 	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
330 	EC_KEY_set_enc_flags(ec_key, tmp_flags);
331 	eplen = i2d_ECPrivateKey(ec_key, NULL);
332 	if (!eplen) {
333 		EC_KEY_set_enc_flags(ec_key, old_flags);
334 		ECerror(ERR_R_EC_LIB);
335 		return 0;
336 	}
337 	ep = malloc(eplen);
338 	if (!ep) {
339 		EC_KEY_set_enc_flags(ec_key, old_flags);
340 		ECerror(ERR_R_MALLOC_FAILURE);
341 		return 0;
342 	}
343 	p = ep;
344 	if (!i2d_ECPrivateKey(ec_key, &p)) {
345 		EC_KEY_set_enc_flags(ec_key, old_flags);
346 		free(ep);
347 		ECerror(ERR_R_EC_LIB);
348 		return 0;
349 	}
350 	/* restore old encoding flags */
351 	EC_KEY_set_enc_flags(ec_key, old_flags);
352 
353 	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
354 		ptype, pval, ep, eplen))
355 		return 0;
356 
357 	return 1;
358 }
359 
360 static int
361 int_ec_size(const EVP_PKEY * pkey)
362 {
363 	return ECDSA_size(pkey->pkey.ec);
364 }
365 
366 static int
367 ec_bits(const EVP_PKEY * pkey)
368 {
369 	BIGNUM *order = BN_new();
370 	const EC_GROUP *group;
371 	int ret;
372 
373 	if (!order) {
374 		ERR_clear_error();
375 		return 0;
376 	}
377 	group = EC_KEY_get0_group(pkey->pkey.ec);
378 	if (!EC_GROUP_get_order(group, order, NULL)) {
379 		BN_free(order);
380 		ERR_clear_error();
381 		return 0;
382 	}
383 	ret = BN_num_bits(order);
384 	BN_free(order);
385 	return ret;
386 }
387 
388 static int
389 ec_missing_parameters(const EVP_PKEY * pkey)
390 {
391 	if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
392 		return 1;
393 	return 0;
394 }
395 
396 static int
397 ec_copy_parameters(EVP_PKEY * to, const EVP_PKEY * from)
398 {
399 	return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec));
400 }
401 
402 static int
403 ec_cmp_parameters(const EVP_PKEY * a, const EVP_PKEY * b)
404 {
405 	const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec);
406 	if (EC_GROUP_cmp(group_a, group_b, NULL))
407 		return 0;
408 	else
409 		return 1;
410 }
411 
412 static void
413 int_ec_free(EVP_PKEY * pkey)
414 {
415 	EC_KEY_free(pkey->pkey.ec);
416 }
417 
418 static int
419 do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype)
420 {
421 	unsigned char *buffer = NULL;
422 	const char *ecstr;
423 	size_t buf_len = 0, i;
424 	int ret = 0, reason = ERR_R_BIO_LIB;
425 	BIGNUM *pub_key = NULL, *order = NULL;
426 	BN_CTX *ctx = NULL;
427 	const EC_GROUP *group;
428 	const EC_POINT *public_key;
429 	const BIGNUM *priv_key;
430 
431 	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
432 		reason = ERR_R_PASSED_NULL_PARAMETER;
433 		goto err;
434 	}
435 	ctx = BN_CTX_new();
436 	if (ctx == NULL) {
437 		reason = ERR_R_MALLOC_FAILURE;
438 		goto err;
439 	}
440 	if (ktype > 0) {
441 		public_key = EC_KEY_get0_public_key(x);
442 		if (public_key != NULL) {
443 			if ((pub_key = EC_POINT_point2bn(group, public_key,
444 			    EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) {
445 				reason = ERR_R_EC_LIB;
446 				goto err;
447 			}
448 			if (pub_key)
449 				buf_len = (size_t) BN_num_bytes(pub_key);
450 		}
451 	}
452 	if (ktype == 2) {
453 		priv_key = EC_KEY_get0_private_key(x);
454 		if (priv_key && (i = (size_t) BN_num_bytes(priv_key)) > buf_len)
455 			buf_len = i;
456 	} else
457 		priv_key = NULL;
458 
459 	if (ktype > 0) {
460 		buf_len += 10;
461 		if ((buffer = malloc(buf_len)) == NULL) {
462 			reason = ERR_R_MALLOC_FAILURE;
463 			goto err;
464 		}
465 	}
466 	if (ktype == 2)
467 		ecstr = "Private-Key";
468 	else if (ktype == 1)
469 		ecstr = "Public-Key";
470 	else
471 		ecstr = "ECDSA-Parameters";
472 
473 	if (!BIO_indent(bp, off, 128))
474 		goto err;
475 	if ((order = BN_new()) == NULL)
476 		goto err;
477 	if (!EC_GROUP_get_order(group, order, NULL))
478 		goto err;
479 	if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
480 		BN_num_bits(order)) <= 0)
481 		goto err;
482 
483 	if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
484 		buffer, off))
485 		goto err;
486 	if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
487 		buffer, off))
488 		goto err;
489 	if (!ECPKParameters_print(bp, group, off))
490 		goto err;
491 	ret = 1;
492  err:
493 	if (!ret)
494 		ECerror(reason);
495 	BN_free(pub_key);
496 	BN_free(order);
497 	BN_CTX_free(ctx);
498 	free(buffer);
499 	return (ret);
500 }
501 
502 static int
503 eckey_param_decode(EVP_PKEY * pkey,
504     const unsigned char **pder, int derlen)
505 {
506 	EC_KEY *eckey;
507 	if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
508 		ECerror(ERR_R_EC_LIB);
509 		return 0;
510 	}
511 	EVP_PKEY_assign_EC_KEY(pkey, eckey);
512 	return 1;
513 }
514 
515 static int
516 eckey_param_encode(const EVP_PKEY * pkey, unsigned char **pder)
517 {
518 	return i2d_ECParameters(pkey->pkey.ec, pder);
519 }
520 
521 static int
522 eckey_param_print(BIO * bp, const EVP_PKEY * pkey, int indent,
523     ASN1_PCTX * ctx)
524 {
525 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
526 }
527 
528 static int
529 eckey_pub_print(BIO * bp, const EVP_PKEY * pkey, int indent,
530     ASN1_PCTX * ctx)
531 {
532 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
533 }
534 
535 
536 static int
537 eckey_priv_print(BIO * bp, const EVP_PKEY * pkey, int indent,
538     ASN1_PCTX * ctx)
539 {
540 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
541 }
542 
543 static int
544 old_ec_priv_decode(EVP_PKEY * pkey,
545     const unsigned char **pder, int derlen)
546 {
547 	EC_KEY *ec;
548 	if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
549 		ECerror(EC_R_DECODE_ERROR);
550 		return 0;
551 	}
552 	EVP_PKEY_assign_EC_KEY(pkey, ec);
553 	return 1;
554 }
555 
556 static int
557 old_ec_priv_encode(const EVP_PKEY * pkey, unsigned char **pder)
558 {
559 	return i2d_ECPrivateKey(pkey->pkey.ec, pder);
560 }
561 
562 static int
563 ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2)
564 {
565 	switch (op) {
566 	case ASN1_PKEY_CTRL_PKCS7_SIGN:
567 		if (arg1 == 0) {
568 			int snid, hnid;
569 			X509_ALGOR *alg1, *alg2;
570 			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
571 			if (alg1 == NULL || alg1->algorithm == NULL)
572 				return -1;
573 			hnid = OBJ_obj2nid(alg1->algorithm);
574 			if (hnid == NID_undef)
575 				return -1;
576 			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
577 				return -1;
578 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
579 		}
580 		return 1;
581 
582 #ifndef OPENSSL_NO_CMS
583 	case ASN1_PKEY_CTRL_CMS_SIGN:
584 		if (arg1 == 0) {
585 			X509_ALGOR *alg1, *alg2;
586 			int snid, hnid;
587 
588 			CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
589 			if (alg1 == NULL || alg1->algorithm == NULL)
590 				return -1;
591 			hnid = OBJ_obj2nid(alg1->algorithm);
592 			if (hnid == NID_undef)
593 				return -1;
594 			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
595 				return -1;
596 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
597 		}
598 		return 1;
599 
600 	case ASN1_PKEY_CTRL_CMS_ENVELOPE:
601 		if (arg1 == 0)
602 			return ecdh_cms_encrypt(arg2);
603 		else if (arg1 == 1)
604 			return ecdh_cms_decrypt(arg2);
605 		return -2;
606 
607 	case ASN1_PKEY_CTRL_CMS_RI_TYPE:
608 		*(int *)arg2 = CMS_RECIPINFO_AGREE;
609 		return 1;
610 #endif
611 
612 	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
613 		*(int *) arg2 = NID_sha1;
614 		return 2;
615 
616 	default:
617 		return -2;
618 
619 	}
620 
621 }
622 
623 #ifndef OPENSSL_NO_CMS
624 
625 static int
626 ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg,
627     ASN1_BIT_STRING *pubkey)
628 {
629 	const ASN1_OBJECT *aoid;
630 	int atype;
631 	const void *aval;
632 	int rv = 0;
633 	EVP_PKEY *pkpeer = NULL;
634 	EC_KEY *ecpeer = NULL;
635 	const unsigned char *p;
636 	int plen;
637 
638 	X509_ALGOR_get0(&aoid, &atype, &aval, alg);
639 	if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
640 		goto err;
641 
642 	/* If absent parameters get group from main key */
643 	if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
644 		const EC_GROUP *grp;
645 		EVP_PKEY *pk;
646 
647 		pk = EVP_PKEY_CTX_get0_pkey(pctx);
648 		if (!pk)
649 			goto err;
650 		grp = EC_KEY_get0_group(pk->pkey.ec);
651 		ecpeer = EC_KEY_new();
652 		if (ecpeer == NULL)
653 			goto err;
654 		if (!EC_KEY_set_group(ecpeer, grp))
655 			goto err;
656 	} else {
657 		ecpeer = eckey_type2param(atype, aval);
658 		if (!ecpeer)
659 			goto err;
660 	}
661 
662 	/* We have parameters now set public key */
663 	plen = ASN1_STRING_length(pubkey);
664 	p = ASN1_STRING_get0_data(pubkey);
665 	if (!p || !plen)
666 		goto err;
667 	if (!o2i_ECPublicKey(&ecpeer, &p, plen))
668 		goto err;
669 	pkpeer = EVP_PKEY_new();
670 	if (pkpeer == NULL)
671 		goto err;
672 	EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
673 	if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
674 		rv = 1;
675  err:
676 	EC_KEY_free(ecpeer);
677 	EVP_PKEY_free(pkpeer);
678 	return rv;
679 }
680 
681 /* Set KDF parameters based on KDF NID */
682 static int
683 ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
684 {
685 	int kdf_nid, kdfmd_nid, cofactor;
686 	const EVP_MD *kdf_md;
687 
688 	if (eckdf_nid == NID_undef)
689 		return 0;
690 
691 	/* Lookup KDF type, cofactor mode and digest */
692 	if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
693 		return 0;
694 
695 	if (kdf_nid == NID_dh_std_kdf)
696 		cofactor = 0;
697 	else if (kdf_nid == NID_dh_cofactor_kdf)
698 		cofactor = 1;
699 	else
700 		return 0;
701 
702 	if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
703 		return 0;
704 
705 	if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
706 		return 0;
707 
708 	kdf_md = EVP_get_digestbynid(kdfmd_nid);
709 	if (!kdf_md)
710 		return 0;
711 
712 	if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
713 		return 0;
714 
715 	return 1;
716 }
717 
718 static int
719 ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
720 {
721 	X509_ALGOR *alg, *kekalg = NULL;
722 	ASN1_OCTET_STRING *ukm;
723 	const unsigned char *p;
724 	unsigned char *der = NULL;
725 	int plen, keylen;
726 	const EVP_CIPHER *kekcipher;
727 	EVP_CIPHER_CTX *kekctx;
728 	int rv = 0;
729 
730 	if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
731 		return 0;
732 
733 	if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
734 		ECerror(EC_R_KDF_PARAMETER_ERROR);
735 		return 0;
736 	}
737 
738 	if (alg->parameter->type != V_ASN1_SEQUENCE)
739 		return 0;
740 
741 	p = alg->parameter->value.sequence->data;
742 	plen = alg->parameter->value.sequence->length;
743 	kekalg = d2i_X509_ALGOR(NULL, &p, plen);
744 	if (!kekalg)
745 		goto err;
746 	kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
747 	if (!kekctx)
748 		goto err;
749 	kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
750 	if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
751 		goto err;
752 	if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
753 		goto err;
754 	if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
755 		goto err;
756 
757 	keylen = EVP_CIPHER_CTX_key_length(kekctx);
758 	if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
759 		goto err;
760 
761 	plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
762 	if (!plen)
763 		goto err;
764 
765 	if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
766 		goto err;
767 	der = NULL;
768 
769 	rv = 1;
770  err:
771 	X509_ALGOR_free(kekalg);
772 	free(der);
773 	return rv;
774 }
775 
776 static int
777 ecdh_cms_decrypt(CMS_RecipientInfo *ri)
778 {
779 	EVP_PKEY_CTX *pctx;
780 
781 	pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
782 	if (!pctx)
783 		return 0;
784 
785 	/* See if we need to set peer key */
786 	if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
787 		X509_ALGOR *alg;
788 		ASN1_BIT_STRING *pubkey;
789 
790 		if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
791 		    NULL, NULL, NULL))
792 			return 0;
793 		if (!alg || !pubkey)
794 			return 0;
795 		if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
796 			ECerror(EC_R_PEER_KEY_ERROR);
797 			return 0;
798 		}
799 	}
800 
801 	/* Set ECDH derivation parameters and initialise unwrap context */
802 	if (!ecdh_cms_set_shared_info(pctx, ri)) {
803 		ECerror(EC_R_SHARED_INFO_ERROR);
804 		return 0;
805 	}
806 
807 	return 1;
808 }
809 
810 static int
811 ecdh_cms_encrypt(CMS_RecipientInfo *ri)
812 {
813 	EVP_PKEY_CTX *pctx;
814 	EVP_PKEY *pkey;
815 	EVP_CIPHER_CTX *ctx;
816 	int keylen;
817 	X509_ALGOR *talg, *wrap_alg = NULL;
818 	const ASN1_OBJECT *aoid;
819 	ASN1_BIT_STRING *pubkey;
820 	ASN1_STRING *wrap_str;
821 	ASN1_OCTET_STRING *ukm;
822 	unsigned char *penc = NULL;
823 	int penclen;
824 	int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
825 	const EVP_MD *kdf_md;
826 	int rv = 0;
827 
828 	pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
829 	if (!pctx)
830 		return 0;
831 	/* Get ephemeral key */
832 	pkey = EVP_PKEY_CTX_get0_pkey(pctx);
833 	if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
834 	    NULL, NULL, NULL))
835 		goto err;
836 	X509_ALGOR_get0(&aoid, NULL, NULL, talg);
837 
838 	/* Is everything uninitialised? */
839 	if (aoid == OBJ_nid2obj(NID_undef)) {
840 		EC_KEY *eckey = pkey->pkey.ec;
841 		unsigned char *p;
842 
843 		/* Set the key */
844 		penclen = i2o_ECPublicKey(eckey, NULL);
845 		if (penclen <= 0)
846 			goto err;
847 		penc = malloc(penclen);
848 		if (penc == NULL)
849 			goto err;
850 		p = penc;
851 		penclen = i2o_ECPublicKey(eckey, &p);
852 		if (penclen <= 0)
853 			goto err;
854 		ASN1_STRING_set0(pubkey, penc, penclen);
855 		pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
856 		pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
857 		penc = NULL;
858 
859 		X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
860 		    V_ASN1_UNDEF, NULL);
861 	}
862 
863 	/* See if custom parameters set */
864 	kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
865 	if (kdf_type <= 0)
866 		goto err;
867 	if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
868 		goto err;
869 	ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
870 	if (ecdh_nid < 0)
871 		goto err;
872 	else if (ecdh_nid == 0)
873 		ecdh_nid = NID_dh_std_kdf;
874 	else if (ecdh_nid == 1)
875 		ecdh_nid = NID_dh_cofactor_kdf;
876 
877 	if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
878 		kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
879 		if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
880 			goto err;
881 	} else {
882 		/* Unknown KDF */
883 		goto err;
884 	}
885 	if (kdf_md == NULL) {
886 		/* Fixme later for better MD */
887 		kdf_md = EVP_sha1();
888 		if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
889 			goto err;
890 	}
891 
892 	if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
893 		goto err;
894 
895 	/* Lookup NID for KDF+cofactor+digest */
896 	if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
897 		goto err;
898 
899 	/* Get wrap NID */
900 	ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
901 	wrap_nid = EVP_CIPHER_CTX_type(ctx);
902 	keylen = EVP_CIPHER_CTX_key_length(ctx);
903 
904 	/* Package wrap algorithm in an AlgorithmIdentifier */
905 
906 	wrap_alg = X509_ALGOR_new();
907 	if (wrap_alg == NULL)
908 		goto err;
909 	wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
910 	wrap_alg->parameter = ASN1_TYPE_new();
911 	if (wrap_alg->parameter == NULL)
912 		goto err;
913 	if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
914 		goto err;
915 	if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
916 		ASN1_TYPE_free(wrap_alg->parameter);
917 		wrap_alg->parameter = NULL;
918 	}
919 
920 	if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
921 		goto err;
922 
923 	penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
924 	if (!penclen)
925 		goto err;
926 
927 	if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
928 		goto err;
929 	penc = NULL;
930 
931 	/*
932 	 * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
933 	 * of another AlgorithmIdentifier.
934 	 */
935 	penclen = i2d_X509_ALGOR(wrap_alg, &penc);
936 	if (!penc || !penclen)
937 		goto err;
938 	wrap_str = ASN1_STRING_new();
939 	if (wrap_str == NULL)
940 		goto err;
941 	ASN1_STRING_set0(wrap_str, penc, penclen);
942 	penc = NULL;
943 	X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
944 
945 	rv = 1;
946 
947  err:
948 	free(penc);
949 	X509_ALGOR_free(wrap_alg);
950 	return rv;
951 }
952 
953 #endif
954 
955 const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
956 	.pkey_id = EVP_PKEY_EC,
957 	.pkey_base_id = EVP_PKEY_EC,
958 
959 	.pem_str = "EC",
960 	.info = "OpenSSL EC algorithm",
961 
962 	.pub_decode = eckey_pub_decode,
963 	.pub_encode = eckey_pub_encode,
964 	.pub_cmp = eckey_pub_cmp,
965 	.pub_print = eckey_pub_print,
966 
967 	.priv_decode = eckey_priv_decode,
968 	.priv_encode = eckey_priv_encode,
969 	.priv_print = eckey_priv_print,
970 
971 	.pkey_size = int_ec_size,
972 	.pkey_bits = ec_bits,
973 
974 	.param_decode = eckey_param_decode,
975 	.param_encode = eckey_param_encode,
976 	.param_missing = ec_missing_parameters,
977 	.param_copy = ec_copy_parameters,
978 	.param_cmp = ec_cmp_parameters,
979 	.param_print = eckey_param_print,
980 
981 	.pkey_free = int_ec_free,
982 	.pkey_ctrl = ec_pkey_ctrl,
983 	.old_priv_decode = old_ec_priv_decode,
984 	.old_priv_encode = old_ec_priv_encode
985 };
986