xref: /dragonfly/crypto/libressl/crypto/ec/ec_ameth.c (revision 72c33676)
1 /* $OpenBSD: ec_ameth.c,v 1.25 2018/08/24 20:22:15 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/ec.h>
65 #include <openssl/err.h>
66 #include <openssl/x509.h>
67 
68 
69 #include "asn1_locl.h"
70 
71 static int
72 eckey_param2type(int *pptype, void **ppval, EC_KEY * ec_key)
73 {
74 	const EC_GROUP *group;
75 	int nid;
76 	if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
77 		ECerror(EC_R_MISSING_PARAMETERS);
78 		return 0;
79 	}
80 	if (EC_GROUP_get_asn1_flag(group) &&
81 	    (nid = EC_GROUP_get_curve_name(group))) {
82 		/* we have a 'named curve' => just set the OID */
83 		*ppval = OBJ_nid2obj(nid);
84 		*pptype = V_ASN1_OBJECT;
85 	} else {
86 		/* explicit parameters */
87 		ASN1_STRING *pstr = NULL;
88 		pstr = ASN1_STRING_new();
89 		if (!pstr)
90 			return 0;
91 		pstr->length = i2d_ECParameters(ec_key, &pstr->data);
92 		if (pstr->length <= 0) {
93 			ASN1_STRING_free(pstr);
94 			ECerror(ERR_R_EC_LIB);
95 			return 0;
96 		}
97 		*ppval = pstr;
98 		*pptype = V_ASN1_SEQUENCE;
99 	}
100 	return 1;
101 }
102 
103 static int
104 eckey_pub_encode(X509_PUBKEY * pk, const EVP_PKEY * pkey)
105 {
106 	EC_KEY *ec_key = pkey->pkey.ec;
107 	void *pval = NULL;
108 	int ptype;
109 	unsigned char *penc = NULL, *p;
110 	int penclen;
111 
112 	if (!eckey_param2type(&ptype, &pval, ec_key)) {
113 		ECerror(ERR_R_EC_LIB);
114 		return 0;
115 	}
116 	penclen = i2o_ECPublicKey(ec_key, NULL);
117 	if (penclen <= 0)
118 		goto err;
119 	penc = malloc(penclen);
120 	if (!penc)
121 		goto err;
122 	p = penc;
123 	penclen = i2o_ECPublicKey(ec_key, &p);
124 	if (penclen <= 0)
125 		goto err;
126 	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
127 		ptype, pval, penc, penclen))
128 		return 1;
129  err:
130 	if (ptype == V_ASN1_OBJECT)
131 		ASN1_OBJECT_free(pval);
132 	else
133 		ASN1_STRING_free(pval);
134 	free(penc);
135 	return 0;
136 }
137 
138 static EC_KEY *
139 eckey_type2param(int ptype, const void *pval)
140 {
141 	EC_KEY *eckey = NULL;
142 
143 	if (ptype == V_ASN1_SEQUENCE) {
144 		const ASN1_STRING *pstr = pval;
145 		const unsigned char *pm = NULL;
146 		int pmlen;
147 
148 		pm = pstr->data;
149 		pmlen = pstr->length;
150 		if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
151 			ECerror(EC_R_DECODE_ERROR);
152 			goto ecerr;
153 		}
154 	} else if (ptype == V_ASN1_OBJECT) {
155 		const ASN1_OBJECT *poid = pval;
156 		EC_GROUP *group;
157 
158 		/*
159 		 * type == V_ASN1_OBJECT => the parameters are given by an
160 		 * asn1 OID
161 		 */
162 		if ((eckey = EC_KEY_new()) == NULL) {
163 			ECerror(ERR_R_MALLOC_FAILURE);
164 			goto ecerr;
165 		}
166 		group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
167 		if (group == NULL)
168 			goto ecerr;
169 		EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
170 		if (EC_KEY_set_group(eckey, group) == 0)
171 			goto ecerr;
172 		EC_GROUP_free(group);
173 	} else {
174 		ECerror(EC_R_DECODE_ERROR);
175 		goto ecerr;
176 	}
177 
178 	return eckey;
179 
180  ecerr:
181 	if (eckey)
182 		EC_KEY_free(eckey);
183 	return NULL;
184 }
185 
186 static int
187 eckey_pub_decode(EVP_PKEY * pkey, X509_PUBKEY * pubkey)
188 {
189 	const unsigned char *p = NULL;
190 	const void *pval;
191 	int ptype, pklen;
192 	EC_KEY *eckey = NULL;
193 	X509_ALGOR *palg;
194 
195 	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
196 		return 0;
197 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
198 
199 	eckey = eckey_type2param(ptype, pval);
200 
201 	if (!eckey) {
202 		ECerror(ERR_R_EC_LIB);
203 		return 0;
204 	}
205 	/* We have parameters now set public key */
206 	if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
207 		ECerror(EC_R_DECODE_ERROR);
208 		goto ecerr;
209 	}
210 	EVP_PKEY_assign_EC_KEY(pkey, eckey);
211 	return 1;
212 
213  ecerr:
214 	if (eckey)
215 		EC_KEY_free(eckey);
216 	return 0;
217 }
218 
219 static int
220 eckey_pub_cmp(const EVP_PKEY * a, const EVP_PKEY * b)
221 {
222 	int r;
223 	const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
224 	const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec);
225 
226 	r = EC_POINT_cmp(group, pa, pb, NULL);
227 	if (r == 0)
228 		return 1;
229 	if (r == 1)
230 		return 0;
231 	return -2;
232 }
233 
234 static int
235 eckey_priv_decode(EVP_PKEY * pkey, const PKCS8_PRIV_KEY_INFO * p8)
236 {
237 	const unsigned char *p = NULL;
238 	const void *pval;
239 	int ptype, pklen;
240 	EC_KEY *eckey = NULL;
241 	const X509_ALGOR *palg;
242 
243 	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
244 		return 0;
245 	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
246 
247 	eckey = eckey_type2param(ptype, pval);
248 
249 	if (!eckey)
250 		goto ecliberr;
251 
252 	/* We have parameters now set private key */
253 	if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
254 		ECerror(EC_R_DECODE_ERROR);
255 		goto ecerr;
256 	}
257 	/* calculate public key (if necessary) */
258 	if (EC_KEY_get0_public_key(eckey) == NULL) {
259 		const BIGNUM *priv_key;
260 		const EC_GROUP *group;
261 		EC_POINT *pub_key;
262 		/*
263 		 * the public key was not included in the SEC1 private key =>
264 		 * calculate the public key
265 		 */
266 		group = EC_KEY_get0_group(eckey);
267 		pub_key = EC_POINT_new(group);
268 		if (pub_key == NULL) {
269 			ECerror(ERR_R_EC_LIB);
270 			goto ecliberr;
271 		}
272 		if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
273 			EC_POINT_free(pub_key);
274 			ECerror(ERR_R_EC_LIB);
275 			goto ecliberr;
276 		}
277 		priv_key = EC_KEY_get0_private_key(eckey);
278 		if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
279 			EC_POINT_free(pub_key);
280 			ECerror(ERR_R_EC_LIB);
281 			goto ecliberr;
282 		}
283 		if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
284 			EC_POINT_free(pub_key);
285 			ECerror(ERR_R_EC_LIB);
286 			goto ecliberr;
287 		}
288 		EC_POINT_free(pub_key);
289 	}
290 	EVP_PKEY_assign_EC_KEY(pkey, eckey);
291 	return 1;
292 
293  ecliberr:
294 	ECerror(ERR_R_EC_LIB);
295  ecerr:
296 	if (eckey)
297 		EC_KEY_free(eckey);
298 	return 0;
299 }
300 
301 static int
302 eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey)
303 {
304 	EC_KEY *ec_key;
305 	unsigned char *ep, *p;
306 	int eplen, ptype;
307 	void *pval;
308 	unsigned int tmp_flags, old_flags;
309 
310 	ec_key = pkey->pkey.ec;
311 
312 	if (!eckey_param2type(&ptype, &pval, ec_key)) {
313 		ECerror(EC_R_DECODE_ERROR);
314 		return 0;
315 	}
316 	/* set the private key */
317 
318 	/*
319 	 * do not include the parameters in the SEC1 private key see PKCS#11
320 	 * 12.11
321 	 */
322 	old_flags = EC_KEY_get_enc_flags(ec_key);
323 	tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
324 	EC_KEY_set_enc_flags(ec_key, tmp_flags);
325 	eplen = i2d_ECPrivateKey(ec_key, NULL);
326 	if (!eplen) {
327 		EC_KEY_set_enc_flags(ec_key, old_flags);
328 		ECerror(ERR_R_EC_LIB);
329 		return 0;
330 	}
331 	ep = malloc(eplen);
332 	if (!ep) {
333 		EC_KEY_set_enc_flags(ec_key, old_flags);
334 		ECerror(ERR_R_MALLOC_FAILURE);
335 		return 0;
336 	}
337 	p = ep;
338 	if (!i2d_ECPrivateKey(ec_key, &p)) {
339 		EC_KEY_set_enc_flags(ec_key, old_flags);
340 		free(ep);
341 		ECerror(ERR_R_EC_LIB);
342 		return 0;
343 	}
344 	/* restore old encoding flags */
345 	EC_KEY_set_enc_flags(ec_key, old_flags);
346 
347 	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
348 		ptype, pval, ep, eplen))
349 		return 0;
350 
351 	return 1;
352 }
353 
354 static int
355 int_ec_size(const EVP_PKEY * pkey)
356 {
357 	return ECDSA_size(pkey->pkey.ec);
358 }
359 
360 static int
361 ec_bits(const EVP_PKEY * pkey)
362 {
363 	BIGNUM *order = BN_new();
364 	const EC_GROUP *group;
365 	int ret;
366 
367 	if (!order) {
368 		ERR_clear_error();
369 		return 0;
370 	}
371 	group = EC_KEY_get0_group(pkey->pkey.ec);
372 	if (!EC_GROUP_get_order(group, order, NULL)) {
373 		BN_free(order);
374 		ERR_clear_error();
375 		return 0;
376 	}
377 	ret = BN_num_bits(order);
378 	BN_free(order);
379 	return ret;
380 }
381 
382 static int
383 ec_missing_parameters(const EVP_PKEY * pkey)
384 {
385 	if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
386 		return 1;
387 	return 0;
388 }
389 
390 static int
391 ec_copy_parameters(EVP_PKEY * to, const EVP_PKEY * from)
392 {
393 	return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec));
394 }
395 
396 static int
397 ec_cmp_parameters(const EVP_PKEY * a, const EVP_PKEY * b)
398 {
399 	const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec);
400 	if (EC_GROUP_cmp(group_a, group_b, NULL))
401 		return 0;
402 	else
403 		return 1;
404 }
405 
406 static void
407 int_ec_free(EVP_PKEY * pkey)
408 {
409 	EC_KEY_free(pkey->pkey.ec);
410 }
411 
412 static int
413 do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype)
414 {
415 	unsigned char *buffer = NULL;
416 	const char *ecstr;
417 	size_t buf_len = 0, i;
418 	int ret = 0, reason = ERR_R_BIO_LIB;
419 	BIGNUM *pub_key = NULL, *order = NULL;
420 	BN_CTX *ctx = NULL;
421 	const EC_GROUP *group;
422 	const EC_POINT *public_key;
423 	const BIGNUM *priv_key;
424 
425 	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
426 		reason = ERR_R_PASSED_NULL_PARAMETER;
427 		goto err;
428 	}
429 	ctx = BN_CTX_new();
430 	if (ctx == NULL) {
431 		reason = ERR_R_MALLOC_FAILURE;
432 		goto err;
433 	}
434 	if (ktype > 0) {
435 		public_key = EC_KEY_get0_public_key(x);
436 		if (public_key != NULL) {
437 			if ((pub_key = EC_POINT_point2bn(group, public_key,
438 			    EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) {
439 				reason = ERR_R_EC_LIB;
440 				goto err;
441 			}
442 			if (pub_key)
443 				buf_len = (size_t) BN_num_bytes(pub_key);
444 		}
445 	}
446 	if (ktype == 2) {
447 		priv_key = EC_KEY_get0_private_key(x);
448 		if (priv_key && (i = (size_t) BN_num_bytes(priv_key)) > buf_len)
449 			buf_len = i;
450 	} else
451 		priv_key = NULL;
452 
453 	if (ktype > 0) {
454 		buf_len += 10;
455 		if ((buffer = malloc(buf_len)) == NULL) {
456 			reason = ERR_R_MALLOC_FAILURE;
457 			goto err;
458 		}
459 	}
460 	if (ktype == 2)
461 		ecstr = "Private-Key";
462 	else if (ktype == 1)
463 		ecstr = "Public-Key";
464 	else
465 		ecstr = "ECDSA-Parameters";
466 
467 	if (!BIO_indent(bp, off, 128))
468 		goto err;
469 	if ((order = BN_new()) == NULL)
470 		goto err;
471 	if (!EC_GROUP_get_order(group, order, NULL))
472 		goto err;
473 	if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
474 		BN_num_bits(order)) <= 0)
475 		goto err;
476 
477 	if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
478 		buffer, off))
479 		goto err;
480 	if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
481 		buffer, off))
482 		goto err;
483 	if (!ECPKParameters_print(bp, group, off))
484 		goto err;
485 	ret = 1;
486  err:
487 	if (!ret)
488 		ECerror(reason);
489 	BN_free(pub_key);
490 	BN_free(order);
491 	BN_CTX_free(ctx);
492 	free(buffer);
493 	return (ret);
494 }
495 
496 static int
497 eckey_param_decode(EVP_PKEY * pkey,
498     const unsigned char **pder, int derlen)
499 {
500 	EC_KEY *eckey;
501 	if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
502 		ECerror(ERR_R_EC_LIB);
503 		return 0;
504 	}
505 	EVP_PKEY_assign_EC_KEY(pkey, eckey);
506 	return 1;
507 }
508 
509 static int
510 eckey_param_encode(const EVP_PKEY * pkey, unsigned char **pder)
511 {
512 	return i2d_ECParameters(pkey->pkey.ec, pder);
513 }
514 
515 static int
516 eckey_param_print(BIO * bp, const EVP_PKEY * pkey, int indent,
517     ASN1_PCTX * ctx)
518 {
519 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
520 }
521 
522 static int
523 eckey_pub_print(BIO * bp, const EVP_PKEY * pkey, int indent,
524     ASN1_PCTX * ctx)
525 {
526 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
527 }
528 
529 
530 static int
531 eckey_priv_print(BIO * bp, const EVP_PKEY * pkey, int indent,
532     ASN1_PCTX * ctx)
533 {
534 	return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
535 }
536 
537 static int
538 old_ec_priv_decode(EVP_PKEY * pkey,
539     const unsigned char **pder, int derlen)
540 {
541 	EC_KEY *ec;
542 	if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
543 		ECerror(EC_R_DECODE_ERROR);
544 		return 0;
545 	}
546 	EVP_PKEY_assign_EC_KEY(pkey, ec);
547 	return 1;
548 }
549 
550 static int
551 old_ec_priv_encode(const EVP_PKEY * pkey, unsigned char **pder)
552 {
553 	return i2d_ECPrivateKey(pkey->pkey.ec, pder);
554 }
555 
556 static int
557 ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2)
558 {
559 	switch (op) {
560 	case ASN1_PKEY_CTRL_PKCS7_SIGN:
561 		if (arg1 == 0) {
562 			int snid, hnid;
563 			X509_ALGOR *alg1, *alg2;
564 			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
565 			if (alg1 == NULL || alg1->algorithm == NULL)
566 				return -1;
567 			hnid = OBJ_obj2nid(alg1->algorithm);
568 			if (hnid == NID_undef)
569 				return -1;
570 			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
571 				return -1;
572 			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
573 		}
574 		return 1;
575 
576 	case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
577 		*(int *) arg2 = NID_sha1;
578 		return 2;
579 
580 	default:
581 		return -2;
582 
583 	}
584 
585 }
586 
587 const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
588 	.pkey_id = EVP_PKEY_EC,
589 	.pkey_base_id = EVP_PKEY_EC,
590 
591 	.pem_str = "EC",
592 	.info = "OpenSSL EC algorithm",
593 
594 	.pub_decode = eckey_pub_decode,
595 	.pub_encode = eckey_pub_encode,
596 	.pub_cmp = eckey_pub_cmp,
597 	.pub_print = eckey_pub_print,
598 
599 	.priv_decode = eckey_priv_decode,
600 	.priv_encode = eckey_priv_encode,
601 	.priv_print = eckey_priv_print,
602 
603 	.pkey_size = int_ec_size,
604 	.pkey_bits = ec_bits,
605 
606 	.param_decode = eckey_param_decode,
607 	.param_encode = eckey_param_encode,
608 	.param_missing = ec_missing_parameters,
609 	.param_copy = ec_copy_parameters,
610 	.param_cmp = ec_cmp_parameters,
611 	.param_print = eckey_param_print,
612 
613 	.pkey_free = int_ec_free,
614 	.pkey_ctrl = ec_pkey_ctrl,
615 	.old_priv_decode = old_ec_priv_decode,
616 	.old_priv_encode = old_ec_priv_encode
617 };
618