xref: /openbsd/lib/libcrypto/ec/ec_lib.c (revision d415bd75)
1 /* $OpenBSD: ec_lib.c,v 1.65 2023/07/25 06:57:26 tb Exp $ */
2 /*
3  * Originally written by Bodo Moeller for the OpenSSL project.
4  */
5 /* ====================================================================
6  * Copyright (c) 1998-2003 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  *    openssl-core@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  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60  * Binary polynomial ECC support in OpenSSL originally developed by
61  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62  */
63 
64 #include <string.h>
65 
66 #include <openssl/opensslconf.h>
67 
68 #include <openssl/err.h>
69 #include <openssl/opensslv.h>
70 
71 #include "bn_local.h"
72 #include "ec_local.h"
73 
74 /* functions for EC_GROUP objects */
75 
76 EC_GROUP *
77 EC_GROUP_new(const EC_METHOD *meth)
78 {
79 	EC_GROUP *ret;
80 
81 	if (meth == NULL) {
82 		ECerror(EC_R_SLOT_FULL);
83 		return NULL;
84 	}
85 	if (meth->group_init == NULL) {
86 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
87 		return NULL;
88 	}
89 	ret = malloc(sizeof *ret);
90 	if (ret == NULL) {
91 		ECerror(ERR_R_MALLOC_FAILURE);
92 		return NULL;
93 	}
94 	ret->meth = meth;
95 
96 	ret->generator = NULL;
97 	BN_init(&ret->order);
98 	BN_init(&ret->cofactor);
99 
100 	ret->curve_name = 0;
101 	ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
102 	ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
103 
104 	ret->seed = NULL;
105 	ret->seed_len = 0;
106 
107 	if (!meth->group_init(ret)) {
108 		free(ret);
109 		return NULL;
110 	}
111 	return ret;
112 }
113 LCRYPTO_ALIAS(EC_GROUP_new);
114 
115 
116 void
117 EC_GROUP_free(EC_GROUP *group)
118 {
119 	if (group == NULL)
120 		return;
121 
122 	if (group->meth->group_finish != NULL)
123 		group->meth->group_finish(group);
124 
125 	EC_POINT_free(group->generator);
126 	BN_free(&group->order);
127 	BN_free(&group->cofactor);
128 
129 	freezero(group->seed, group->seed_len);
130 	freezero(group, sizeof *group);
131 }
132 LCRYPTO_ALIAS(EC_GROUP_free);
133 
134 void
135 EC_GROUP_clear_free(EC_GROUP *group)
136 {
137 	EC_GROUP_free(group);
138 }
139 
140 int
141 EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
142 {
143 	if (dest->meth->group_copy == NULL) {
144 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
145 		return 0;
146 	}
147 	if (dest->meth != src->meth) {
148 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
149 		return 0;
150 	}
151 	if (dest == src)
152 		return 1;
153 
154 	if (src->generator != NULL) {
155 		if (dest->generator == NULL) {
156 			dest->generator = EC_POINT_new(dest);
157 			if (dest->generator == NULL)
158 				return 0;
159 		}
160 		if (!EC_POINT_copy(dest->generator, src->generator))
161 			return 0;
162 	} else {
163 		/* src->generator == NULL */
164 		EC_POINT_free(dest->generator);
165 		dest->generator = NULL;
166 	}
167 
168 	if (!bn_copy(&dest->order, &src->order))
169 		return 0;
170 	if (!bn_copy(&dest->cofactor, &src->cofactor))
171 		return 0;
172 
173 	dest->curve_name = src->curve_name;
174 	dest->asn1_flag = src->asn1_flag;
175 	dest->asn1_form = src->asn1_form;
176 
177 	if (src->seed) {
178 		free(dest->seed);
179 		dest->seed = malloc(src->seed_len);
180 		if (dest->seed == NULL)
181 			return 0;
182 		memcpy(dest->seed, src->seed, src->seed_len);
183 		dest->seed_len = src->seed_len;
184 	} else {
185 		free(dest->seed);
186 		dest->seed = NULL;
187 		dest->seed_len = 0;
188 	}
189 
190 
191 	return dest->meth->group_copy(dest, src);
192 }
193 LCRYPTO_ALIAS(EC_GROUP_copy);
194 
195 
196 EC_GROUP *
197 EC_GROUP_dup(const EC_GROUP *a)
198 {
199 	EC_GROUP *t = NULL;
200 
201 	if ((a != NULL) && ((t = EC_GROUP_new(a->meth)) != NULL) &&
202 	    (!EC_GROUP_copy(t, a))) {
203 		EC_GROUP_free(t);
204 		t = NULL;
205 	}
206 	return t;
207 }
208 LCRYPTO_ALIAS(EC_GROUP_dup);
209 
210 
211 const EC_METHOD *
212 EC_GROUP_method_of(const EC_GROUP *group)
213 {
214 	return group->meth;
215 }
216 LCRYPTO_ALIAS(EC_GROUP_method_of);
217 
218 
219 int
220 EC_METHOD_get_field_type(const EC_METHOD *meth)
221 {
222 	return meth->field_type;
223 }
224 LCRYPTO_ALIAS(EC_METHOD_get_field_type);
225 
226 /*
227  * If there is a user-provided cofactor, sanity check and use it. Otherwise
228  * try computing the cofactor from generator order n and field cardinality q.
229  * This works for all curves of cryptographic interest.
230  *
231  * Hasse's theorem: | h * n - (q + 1) | <= 2 * sqrt(q)
232  *
233  * So: h_min = (q + 1 - 2*sqrt(q)) / n and h_max = (q + 1 + 2*sqrt(q)) / n and
234  * therefore h_max - h_min = 4*sqrt(q) / n. So if n > 4*sqrt(q) holds, there is
235  * only one possible value for h:
236  *
237  *	h = \lfloor (h_min + h_max)/2 \rceil = \lfloor (q + 1)/n \rceil
238  *
239  * Otherwise, zero cofactor and return success.
240  */
241 static int
242 ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor)
243 {
244 	BN_CTX *ctx = NULL;
245 	BIGNUM *cofactor;
246 	int ret = 0;
247 
248 	BN_zero(&group->cofactor);
249 
250 	if ((ctx = BN_CTX_new()) == NULL)
251 		goto err;
252 
253 	BN_CTX_start(ctx);
254 	if ((cofactor = BN_CTX_get(ctx)) == NULL)
255 		goto err;
256 
257 	/*
258 	 * Unfortunately, the cofactor is an optional field in many standards.
259 	 * Internally, the library uses a 0 cofactor as a marker for "unknown
260 	 * cofactor".  So accept in_cofactor == NULL or in_cofactor >= 0.
261 	 */
262 	if (in_cofactor != NULL && !BN_is_zero(in_cofactor)) {
263 		if (BN_is_negative(in_cofactor)) {
264 			ECerror(EC_R_UNKNOWN_COFACTOR);
265 			goto err;
266 		}
267 		if (!bn_copy(cofactor, in_cofactor))
268 			goto err;
269 		goto done;
270 	}
271 
272 	/*
273 	 * If the cofactor is too large, we cannot guess it and default to zero.
274 	 * The RHS of below is a strict overestimate of log(4 * sqrt(q)).
275 	 */
276 	if (BN_num_bits(&group->order) <=
277 	    (BN_num_bits(&group->field) + 1) / 2 + 3)
278 		goto done;
279 
280 	/*
281 	 * Compute
282 	 *     h = \lfloor (q + 1)/n \rceil = \lfloor (q + 1 + n/2) / n \rfloor.
283 	 */
284 
285 	/* h = n/2 */
286 	if (!BN_rshift1(cofactor, &group->order))
287 		goto err;
288 	/* h = 1 + n/2 */
289 	if (!BN_add_word(cofactor, 1))
290 		goto err;
291 	/* h = q + 1 + n/2 */
292 	if (!BN_add(cofactor, cofactor, &group->field))
293 		goto err;
294 	/* h = (q + 1 + n/2) / n */
295 	if (!BN_div_ct(cofactor, NULL, cofactor, &group->order, ctx))
296 		goto err;
297 
298  done:
299 	/* Use Hasse's theorem to bound the cofactor. */
300 	if (BN_num_bits(cofactor) > BN_num_bits(&group->field) + 1) {
301 		ECerror(EC_R_INVALID_GROUP_ORDER);
302 		goto err;
303 	}
304 
305 	if (!bn_copy(&group->cofactor, cofactor))
306 		goto err;
307 
308 	ret = 1;
309 
310  err:
311 	BN_CTX_end(ctx);
312 	BN_CTX_free(ctx);
313 
314 	return ret;
315 }
316 
317 int
318 EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
319     const BIGNUM *order, const BIGNUM *cofactor)
320 {
321 	if (generator == NULL) {
322 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
323 		return 0;
324 	}
325 
326 	/* Require group->field >= 1. */
327 	if (BN_is_zero(&group->field) || BN_is_negative(&group->field)) {
328 		ECerror(EC_R_INVALID_FIELD);
329 		return 0;
330 	}
331 
332 	/*
333 	 * Require order > 1 and enforce an upper bound of at most one bit more
334 	 * than the field cardinality due to Hasse's theorem.
335 	 */
336 	if (order == NULL || BN_cmp(order, BN_value_one()) <= 0 ||
337 	    BN_num_bits(order) > BN_num_bits(&group->field) + 1) {
338 		ECerror(EC_R_INVALID_GROUP_ORDER);
339 		return 0;
340 	}
341 
342 	if (group->generator == NULL) {
343 		group->generator = EC_POINT_new(group);
344 		if (group->generator == NULL)
345 			return 0;
346 	}
347 	if (!EC_POINT_copy(group->generator, generator))
348 		return 0;
349 
350 	if (!bn_copy(&group->order, order))
351 		return 0;
352 
353 	if (!ec_set_cofactor(group, cofactor))
354 		return 0;
355 
356 	return 1;
357 }
358 LCRYPTO_ALIAS(EC_GROUP_set_generator);
359 
360 
361 const EC_POINT *
362 EC_GROUP_get0_generator(const EC_GROUP *group)
363 {
364 	return group->generator;
365 }
366 LCRYPTO_ALIAS(EC_GROUP_get0_generator);
367 
368 int
369 EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
370 {
371 	if (!bn_copy(order, &group->order))
372 		return 0;
373 
374 	return !BN_is_zero(order);
375 }
376 LCRYPTO_ALIAS(EC_GROUP_get_order);
377 
378 const BIGNUM *
379 EC_GROUP_get0_order(const EC_GROUP *group)
380 {
381 	return &group->order;
382 }
383 
384 int
385 EC_GROUP_order_bits(const EC_GROUP *group)
386 {
387 	return group->meth->group_order_bits(group);
388 }
389 LCRYPTO_ALIAS(EC_GROUP_order_bits);
390 
391 int
392 EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
393 {
394 	if (!bn_copy(cofactor, &group->cofactor))
395 		return 0;
396 
397 	return !BN_is_zero(&group->cofactor);
398 }
399 LCRYPTO_ALIAS(EC_GROUP_get_cofactor);
400 
401 
402 void
403 EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
404 {
405 	group->curve_name = nid;
406 }
407 LCRYPTO_ALIAS(EC_GROUP_set_curve_name);
408 
409 
410 int
411 EC_GROUP_get_curve_name(const EC_GROUP *group)
412 {
413 	return group->curve_name;
414 }
415 LCRYPTO_ALIAS(EC_GROUP_get_curve_name);
416 
417 
418 void
419 EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
420 {
421 	group->asn1_flag = flag;
422 }
423 LCRYPTO_ALIAS(EC_GROUP_set_asn1_flag);
424 
425 
426 int
427 EC_GROUP_get_asn1_flag(const EC_GROUP *group)
428 {
429 	return group->asn1_flag;
430 }
431 LCRYPTO_ALIAS(EC_GROUP_get_asn1_flag);
432 
433 
434 void
435 EC_GROUP_set_point_conversion_form(EC_GROUP *group,
436     point_conversion_form_t form)
437 {
438 	group->asn1_form = form;
439 }
440 LCRYPTO_ALIAS(EC_GROUP_set_point_conversion_form);
441 
442 
443 point_conversion_form_t
444 EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
445 {
446 	return group->asn1_form;
447 }
448 LCRYPTO_ALIAS(EC_GROUP_get_point_conversion_form);
449 
450 
451 size_t
452 EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
453 {
454 	if (group->seed) {
455 		free(group->seed);
456 		group->seed = NULL;
457 		group->seed_len = 0;
458 	}
459 	if (!len || !p)
460 		return 1;
461 
462 	if ((group->seed = malloc(len)) == NULL)
463 		return 0;
464 	memcpy(group->seed, p, len);
465 	group->seed_len = len;
466 
467 	return len;
468 }
469 LCRYPTO_ALIAS(EC_GROUP_set_seed);
470 
471 
472 unsigned char *
473 EC_GROUP_get0_seed(const EC_GROUP *group)
474 {
475 	return group->seed;
476 }
477 LCRYPTO_ALIAS(EC_GROUP_get0_seed);
478 
479 
480 size_t
481 EC_GROUP_get_seed_len(const EC_GROUP *group)
482 {
483 	return group->seed_len;
484 }
485 LCRYPTO_ALIAS(EC_GROUP_get_seed_len);
486 
487 int
488 EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
489     const BIGNUM *b, BN_CTX *ctx_in)
490 {
491 	BN_CTX *ctx;
492 	int ret = 0;
493 
494 	if ((ctx = ctx_in) == NULL)
495 		ctx = BN_CTX_new();
496 	if (ctx == NULL)
497 		goto err;
498 
499 	if (group->meth->group_set_curve == NULL) {
500 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
501 		goto err;
502 	}
503 	ret = group->meth->group_set_curve(group, p, a, b, ctx);
504 
505  err:
506 	if (ctx != ctx_in)
507 		BN_CTX_free(ctx);
508 
509 	return ret;
510 }
511 LCRYPTO_ALIAS(EC_GROUP_set_curve);
512 
513 int
514 EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
515     BN_CTX *ctx_in)
516 {
517 	BN_CTX *ctx;
518 	int ret = 0;
519 
520 	if ((ctx = ctx_in) == NULL)
521 		ctx = BN_CTX_new();
522 	if (ctx == NULL)
523 		goto err;
524 
525 	if (group->meth->group_get_curve == NULL) {
526 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
527 		goto err;
528 	}
529 	ret = group->meth->group_get_curve(group, p, a, b, ctx);
530 
531  err:
532 	if (ctx != ctx_in)
533 		BN_CTX_free(ctx);
534 
535 	return ret;
536 }
537 LCRYPTO_ALIAS(EC_GROUP_get_curve);
538 
539 int
540 EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
541     const BIGNUM *b, BN_CTX *ctx)
542 {
543 	return EC_GROUP_set_curve(group, p, a, b, ctx);
544 }
545 
546 int
547 EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b,
548     BN_CTX *ctx)
549 {
550 	return EC_GROUP_get_curve(group, p, a, b, ctx);
551 }
552 
553 int
554 EC_GROUP_get_degree(const EC_GROUP *group)
555 {
556 	if (group->meth->group_get_degree == NULL) {
557 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
558 		return 0;
559 	}
560 	return group->meth->group_get_degree(group);
561 }
562 LCRYPTO_ALIAS(EC_GROUP_get_degree);
563 
564 
565 int
566 EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx_in)
567 {
568 	BN_CTX *ctx;
569 	int ret = 0;
570 
571 	if ((ctx = ctx_in) == NULL)
572 		ctx = BN_CTX_new();
573 	if (ctx == NULL)
574 		goto err;
575 
576 	if (group->meth->group_check_discriminant == NULL) {
577 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
578 		goto err;
579 	}
580 	ret = group->meth->group_check_discriminant(group, ctx);
581 
582  err:
583 	if (ctx != ctx_in)
584 		BN_CTX_free(ctx);
585 
586 	return ret;
587 }
588 LCRYPTO_ALIAS(EC_GROUP_check_discriminant);
589 
590 
591 int
592 EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
593 {
594 	int r = 0;
595 	BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
596 	BN_CTX *ctx_new = NULL;
597 
598 	/* compare the field types */
599 	if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
600 	    EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
601 		return 1;
602 	/* compare the curve name (if present in both) */
603 	if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
604 	    EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
605 		return 1;
606 
607 	if (!ctx)
608 		ctx_new = ctx = BN_CTX_new();
609 	if (!ctx)
610 		return -1;
611 
612 	BN_CTX_start(ctx);
613 	if ((a1 = BN_CTX_get(ctx)) == NULL)
614 		goto err;
615 	if ((a2 = BN_CTX_get(ctx)) == NULL)
616 		goto err;
617 	if ((a3 = BN_CTX_get(ctx)) == NULL)
618 		goto err;
619 	if ((b1 = BN_CTX_get(ctx)) == NULL)
620 		goto err;
621 	if ((b2 = BN_CTX_get(ctx)) == NULL)
622 		goto err;
623 	if ((b3 = BN_CTX_get(ctx)) == NULL)
624 		goto err;
625 
626 	/*
627 	 * XXX This approach assumes that the external representation of
628 	 * curves over the same field type is the same.
629 	 */
630 	if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
631 	    !b->meth->group_get_curve(b, b1, b2, b3, ctx))
632 		r = 1;
633 
634 	if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
635 		r = 1;
636 
637 	/* XXX EC_POINT_cmp() assumes that the methods are equal */
638 	if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
639 		EC_GROUP_get0_generator(b), ctx))
640 		r = 1;
641 
642 	if (!r) {
643 		/* compare the order and cofactor */
644 		if (!EC_GROUP_get_order(a, a1, ctx) ||
645 		    !EC_GROUP_get_order(b, b1, ctx) ||
646 		    !EC_GROUP_get_cofactor(a, a2, ctx) ||
647 		    !EC_GROUP_get_cofactor(b, b2, ctx))
648 			goto err;
649 		if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
650 			r = 1;
651 	}
652 	BN_CTX_end(ctx);
653 	if (ctx_new)
654 		BN_CTX_free(ctx);
655 
656 	return r;
657 
658  err:
659 	BN_CTX_end(ctx);
660 	if (ctx_new)
661 		BN_CTX_free(ctx);
662 	return -1;
663 }
664 LCRYPTO_ALIAS(EC_GROUP_cmp);
665 
666 /*
667  * Coordinate blinding for EC_POINT.
668  *
669  * The underlying EC_METHOD can optionally implement this function:
670  * underlying implementations should return 0 on errors, or 1 on success.
671  *
672  * This wrapper returns 1 in case the underlying EC_METHOD does not support
673  * coordinate blinding.
674  */
675 int
676 ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
677 {
678 	if (group->meth->blind_coordinates == NULL)
679 		return 1;
680 
681 	return group->meth->blind_coordinates(group, p, ctx);
682 }
683 
684 EC_POINT *
685 EC_POINT_new(const EC_GROUP *group)
686 {
687 	EC_POINT *ret;
688 
689 	if (group == NULL) {
690 		ECerror(ERR_R_PASSED_NULL_PARAMETER);
691 		return NULL;
692 	}
693 	if (group->meth->point_init == NULL) {
694 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
695 		return NULL;
696 	}
697 	ret = malloc(sizeof *ret);
698 	if (ret == NULL) {
699 		ECerror(ERR_R_MALLOC_FAILURE);
700 		return NULL;
701 	}
702 	ret->meth = group->meth;
703 
704 	if (!ret->meth->point_init(ret)) {
705 		free(ret);
706 		return NULL;
707 	}
708 	return ret;
709 }
710 LCRYPTO_ALIAS(EC_POINT_new);
711 
712 void
713 EC_POINT_free(EC_POINT *point)
714 {
715 	if (point == NULL)
716 		return;
717 
718 	if (point->meth->point_finish != NULL)
719 		point->meth->point_finish(point);
720 
721 	freezero(point, sizeof *point);
722 }
723 LCRYPTO_ALIAS(EC_POINT_free);
724 
725 void
726 EC_POINT_clear_free(EC_POINT *point)
727 {
728 	EC_POINT_free(point);
729 }
730 
731 int
732 EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
733 {
734 	if (dest->meth->point_copy == NULL) {
735 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
736 		return 0;
737 	}
738 	if (dest->meth != src->meth) {
739 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
740 		return 0;
741 	}
742 	if (dest == src)
743 		return 1;
744 	return dest->meth->point_copy(dest, src);
745 }
746 LCRYPTO_ALIAS(EC_POINT_copy);
747 
748 EC_POINT *
749 EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
750 {
751 	EC_POINT *t;
752 	int r;
753 
754 	if (a == NULL)
755 		return NULL;
756 
757 	t = EC_POINT_new(group);
758 	if (t == NULL)
759 		return (NULL);
760 	r = EC_POINT_copy(t, a);
761 	if (!r) {
762 		EC_POINT_free(t);
763 		return NULL;
764 	} else
765 		return t;
766 }
767 LCRYPTO_ALIAS(EC_POINT_dup);
768 
769 const EC_METHOD *
770 EC_POINT_method_of(const EC_POINT *point)
771 {
772 	return point->meth;
773 }
774 LCRYPTO_ALIAS(EC_POINT_method_of);
775 
776 int
777 EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
778 {
779 	if (group->meth->point_set_to_infinity == NULL) {
780 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
781 		return 0;
782 	}
783 	if (group->meth != point->meth) {
784 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
785 		return 0;
786 	}
787 	return group->meth->point_set_to_infinity(group, point);
788 }
789 LCRYPTO_ALIAS(EC_POINT_set_to_infinity);
790 
791 int
792 EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *point,
793     const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx_in)
794 {
795 	BN_CTX *ctx;
796 	int ret = 0;
797 
798 	if ((ctx = ctx_in) == NULL)
799 		ctx = BN_CTX_new();
800 	if (ctx == NULL)
801 		goto err;
802 
803 	if (group->meth->point_set_Jprojective_coordinates == NULL) {
804 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
805 		goto err;
806 	}
807 	if (group->meth != point->meth) {
808 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
809 		goto err;
810 	}
811 	if (!group->meth->point_set_Jprojective_coordinates(group, point,
812 	    x, y, z, ctx))
813 		goto err;
814 
815 	if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
816 		ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
817 		goto err;
818 	}
819 
820 	ret = 1;
821 
822  err:
823 	if (ctx != ctx_in)
824 		BN_CTX_free(ctx);
825 
826 	return ret;
827 }
828 
829 int
830 EC_POINT_get_Jprojective_coordinates(const EC_GROUP *group,
831     const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx_in)
832 {
833 	BN_CTX *ctx;
834 	int ret = 0;
835 
836 	if ((ctx = ctx_in) == NULL)
837 		ctx = BN_CTX_new();
838 	if (ctx == NULL)
839 		goto err;
840 
841 	if (group->meth->point_get_Jprojective_coordinates == NULL) {
842 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
843 		goto err;
844 	}
845 	if (group->meth != point->meth) {
846 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
847 		goto err;
848 	}
849 	ret = group->meth->point_get_Jprojective_coordinates(group, point,
850 	    x, y, z, ctx);
851 
852  err:
853 	if (ctx != ctx_in)
854 		BN_CTX_free(ctx);
855 
856 	return ret;
857 }
858 
859 int
860 EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
861     const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
862 {
863 	return EC_POINT_set_Jprojective_coordinates(group, point, x, y, z, ctx);
864 }
865 
866 int
867 EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
868     const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
869 {
870 	return EC_POINT_get_Jprojective_coordinates(group, point, x, y, z, ctx);
871 }
872 
873 int
874 EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
875     const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx_in)
876 {
877 	BN_CTX *ctx;
878 	int ret = 0;
879 
880 	if ((ctx = ctx_in) == NULL)
881 		ctx = BN_CTX_new();
882 	if (ctx == NULL)
883 		goto err;
884 
885 	if (group->meth->point_set_affine_coordinates == NULL) {
886 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
887 		goto err;
888 	}
889 	if (group->meth != point->meth) {
890 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
891 		goto err;
892 	}
893 	if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
894 		goto err;
895 
896 	if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
897 		ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
898 		goto err;
899 	}
900 
901 	ret = 1;
902 
903  err:
904 	if (ctx != ctx_in)
905 		BN_CTX_free(ctx);
906 
907 	return ret;
908 }
909 LCRYPTO_ALIAS(EC_POINT_set_affine_coordinates);
910 
911 int
912 EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
913     const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
914 {
915 	return EC_POINT_set_affine_coordinates(group, point, x, y, ctx);
916 }
917 
918 int
919 EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
920     BIGNUM *x, BIGNUM *y, BN_CTX *ctx_in)
921 {
922 	BN_CTX *ctx;
923 	int ret = 0;
924 
925 	if ((ctx = ctx_in) == NULL)
926 		ctx = BN_CTX_new();
927 	if (ctx == NULL)
928 		goto err;
929 
930 	if (group->meth->point_get_affine_coordinates == NULL) {
931 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
932 		goto err;
933 	}
934 	if (group->meth != point->meth) {
935 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
936 		goto err;
937 	}
938 	ret = group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
939 
940  err:
941 	if (ctx != ctx_in)
942 		BN_CTX_free(ctx);
943 
944 	return ret;
945 }
946 LCRYPTO_ALIAS(EC_POINT_get_affine_coordinates);
947 
948 int
949 EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
950     BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
951 {
952 	return EC_POINT_get_affine_coordinates(group, point, x, y, ctx);
953 }
954 
955 int
956 EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
957     const EC_POINT *b, BN_CTX *ctx_in)
958 {
959 	BN_CTX *ctx;
960 	int ret = 0;
961 
962 	if ((ctx = ctx_in) == NULL)
963 		ctx = BN_CTX_new();
964 	if (ctx == NULL)
965 		goto err;
966 
967 	if (group->meth->add == NULL) {
968 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
969 		goto err;
970 	}
971 	if (group->meth != r->meth || group->meth != a->meth ||
972 	    group->meth != b->meth) {
973 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
974 		goto err;
975 	}
976 	ret = group->meth->add(group, r, a, b, ctx);
977 
978  err:
979 	if (ctx != ctx_in)
980 		BN_CTX_free(ctx);
981 
982 	return ret;
983 }
984 LCRYPTO_ALIAS(EC_POINT_add);
985 
986 int
987 EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
988     BN_CTX *ctx_in)
989 {
990 	BN_CTX *ctx;
991 	int ret = 0;
992 
993 	if ((ctx = ctx_in) == NULL)
994 		ctx = BN_CTX_new();
995 	if (ctx == NULL)
996 		goto err;
997 
998 	if (group->meth->dbl == NULL) {
999 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1000 		goto err;
1001 	}
1002 	if (group->meth != r->meth || r->meth != a->meth) {
1003 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1004 		goto err;
1005 	}
1006 	ret = group->meth->dbl(group, r, a, ctx);
1007 
1008  err:
1009 	if (ctx != ctx_in)
1010 		BN_CTX_free(ctx);
1011 
1012 	return ret;
1013 }
1014 LCRYPTO_ALIAS(EC_POINT_dbl);
1015 
1016 int
1017 EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx_in)
1018 {
1019 	BN_CTX *ctx;
1020 	int ret = 0;
1021 
1022 	if ((ctx = ctx_in) == NULL)
1023 		ctx = BN_CTX_new();
1024 	if (ctx == NULL)
1025 		goto err;
1026 
1027 	if (group->meth->invert == NULL) {
1028 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1029 		goto err;
1030 	}
1031 	if (group->meth != a->meth) {
1032 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1033 		goto err;
1034 	}
1035 	ret = group->meth->invert(group, a, ctx);
1036 
1037  err:
1038 	if (ctx != ctx_in)
1039 		BN_CTX_free(ctx);
1040 
1041 	return ret;
1042 }
1043 LCRYPTO_ALIAS(EC_POINT_invert);
1044 
1045 int
1046 EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
1047 {
1048 	if (group->meth->is_at_infinity == NULL) {
1049 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1050 		return 0;
1051 	}
1052 	if (group->meth != point->meth) {
1053 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1054 		return 0;
1055 	}
1056 	return group->meth->is_at_infinity(group, point);
1057 }
1058 LCRYPTO_ALIAS(EC_POINT_is_at_infinity);
1059 
1060 int
1061 EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
1062     BN_CTX *ctx_in)
1063 {
1064 	BN_CTX *ctx;
1065 	int ret = -1;
1066 
1067 	if ((ctx = ctx_in) == NULL)
1068 		ctx = BN_CTX_new();
1069 	if (ctx == NULL)
1070 		goto err;
1071 
1072 	if (group->meth->is_on_curve == NULL) {
1073 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1074 		goto err;
1075 	}
1076 	if (group->meth != point->meth) {
1077 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1078 		goto err;
1079 	}
1080 	ret = group->meth->is_on_curve(group, point, ctx);
1081 
1082  err:
1083 	if (ctx != ctx_in)
1084 		BN_CTX_free(ctx);
1085 
1086 	return ret;
1087 }
1088 LCRYPTO_ALIAS(EC_POINT_is_on_curve);
1089 
1090 int
1091 EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
1092     BN_CTX *ctx_in)
1093 {
1094 	BN_CTX *ctx;
1095 	int ret = -1;
1096 
1097 	if ((ctx = ctx_in) == NULL)
1098 		ctx = BN_CTX_new();
1099 	if (ctx == NULL)
1100 		goto err;
1101 
1102 	if (group->meth->point_cmp == NULL) {
1103 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1104 		goto err;
1105 	}
1106 	if (group->meth != a->meth || a->meth != b->meth) {
1107 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1108 		goto err;
1109 	}
1110 	ret = group->meth->point_cmp(group, a, b, ctx);
1111 
1112  err:
1113 	if (ctx != ctx_in)
1114 		BN_CTX_free(ctx);
1115 
1116 	return ret;
1117 }
1118 LCRYPTO_ALIAS(EC_POINT_cmp);
1119 
1120 int
1121 EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx_in)
1122 {
1123 	BN_CTX *ctx;
1124 	int ret = 0;
1125 
1126 	if ((ctx = ctx_in) == NULL)
1127 		ctx = BN_CTX_new();
1128 	if (ctx == NULL)
1129 		goto err;
1130 
1131 	if (group->meth->make_affine == NULL) {
1132 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1133 		goto err;
1134 	}
1135 	if (group->meth != point->meth) {
1136 		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1137 		goto err;
1138 	}
1139 	ret = group->meth->make_affine(group, point, ctx);
1140 
1141  err:
1142 	if (ctx != ctx_in)
1143 		BN_CTX_free(ctx);
1144 
1145 	return ret;
1146 }
1147 LCRYPTO_ALIAS(EC_POINT_make_affine);
1148 
1149 int
1150 EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1151     BN_CTX *ctx_in)
1152 {
1153 	BN_CTX *ctx;
1154 	size_t i;
1155 	int ret = 0;
1156 
1157 	if ((ctx = ctx_in) == NULL)
1158 		ctx = BN_CTX_new();
1159 	if (ctx == NULL)
1160 		goto err;
1161 
1162 	if (group->meth->points_make_affine == NULL) {
1163 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1164 		goto err;
1165 	}
1166 	for (i = 0; i < num; i++) {
1167 		if (group->meth != points[i]->meth) {
1168 			ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1169 			goto err;
1170 		}
1171 	}
1172 	ret = group->meth->points_make_affine(group, num, points, ctx);
1173 
1174  err:
1175 	if (ctx != ctx_in)
1176 		BN_CTX_free(ctx);
1177 
1178 	return ret;
1179 }
1180 LCRYPTO_ALIAS(EC_POINTs_make_affine);
1181 
1182 int
1183 EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1184     size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
1185     BN_CTX *ctx_in)
1186 {
1187 	BN_CTX *ctx;
1188 	int ret = 0;
1189 
1190 	if ((ctx = ctx_in) == NULL)
1191 		ctx = BN_CTX_new();
1192 	if (ctx == NULL)
1193 		goto err;
1194 
1195 	/* Only num == 0 and num == 1 is supported. */
1196 	if (group->meth->mul_generator_ct == NULL ||
1197 	    group->meth->mul_single_ct == NULL ||
1198 	    group->meth->mul_double_nonct == NULL ||
1199 	    num > 1) {
1200 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1201 		goto err;
1202 	}
1203 
1204 	if (num == 1 && points != NULL && scalars != NULL) {
1205 		/* Either bP or aG + bP, this is sane. */
1206 		ret = EC_POINT_mul(group, r, scalar, points[0], scalars[0], ctx);
1207 	} else if (scalar != NULL && points == NULL && scalars == NULL) {
1208 		/* aG, this is sane */
1209 		ret = EC_POINT_mul(group, r, scalar, NULL, NULL, ctx);
1210 	} else {
1211 		/* anything else is an error */
1212 		ECerror(ERR_R_EC_LIB);
1213 		goto err;
1214 	}
1215 
1216  err:
1217 	if (ctx != ctx_in)
1218 		BN_CTX_free(ctx);
1219 
1220 	return ret;
1221 }
1222 LCRYPTO_ALIAS(EC_POINTs_mul);
1223 
1224 int
1225 EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1226     const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx_in)
1227 {
1228 	BN_CTX *ctx;
1229 	int ret = 0;
1230 
1231 	if ((ctx = ctx_in) == NULL)
1232 		ctx = BN_CTX_new();
1233 	if (ctx == NULL)
1234 		goto err;
1235 
1236 	if (group->meth->mul_generator_ct == NULL ||
1237 	    group->meth->mul_single_ct == NULL ||
1238 	    group->meth->mul_double_nonct == NULL) {
1239 		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1240 		goto err;
1241 	}
1242 
1243 	if (g_scalar != NULL && point == NULL && p_scalar == NULL) {
1244 		/*
1245 		 * In this case we want to compute g_scalar * GeneratorPoint:
1246 		 * this codepath is reached most prominently by (ephemeral) key
1247 		 * generation of EC cryptosystems (i.e. ECDSA keygen and sign
1248 		 * setup, ECDH keygen/first half), where the scalar is always
1249 		 * secret. This is why we ignore if BN_FLG_CONSTTIME is actually
1250 		 * set and we always call the constant time version.
1251 		 */
1252 		ret = group->meth->mul_generator_ct(group, r, g_scalar, ctx);
1253 	} else if (g_scalar == NULL && point != NULL && p_scalar != NULL) {
1254 		/*
1255 		 * In this case we want to compute p_scalar * GenericPoint:
1256 		 * this codepath is reached most prominently by the second half
1257 		 * of ECDH, where the secret scalar is multiplied by the peer's
1258 		 * public point. To protect the secret scalar, we ignore if
1259 		 * BN_FLG_CONSTTIME is actually set and we always call the
1260 		 * constant time version.
1261 		 */
1262 		ret = group->meth->mul_single_ct(group, r, p_scalar, point, ctx);
1263 	} else if (g_scalar != NULL && point != NULL && p_scalar != NULL) {
1264 		/*
1265 		 * In this case we want to compute
1266 		 *   g_scalar * GeneratorPoint + p_scalar * GenericPoint:
1267 		 * this codepath is reached most prominently by ECDSA signature
1268 		 * verification. So we call the non-ct version.
1269 		 */
1270 		ret = group->meth->mul_double_nonct(group, r, g_scalar,
1271 		    p_scalar, point, ctx);
1272 	} else {
1273 		/* Anything else is an error. */
1274 		ECerror(ERR_R_EC_LIB);
1275 		goto err;
1276 	}
1277 
1278  err:
1279 	if (ctx != ctx_in)
1280 		BN_CTX_free(ctx);
1281 
1282 	return ret;
1283 }
1284 LCRYPTO_ALIAS(EC_POINT_mul);
1285 
1286 int
1287 EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx_in)
1288 {
1289 	return 1;
1290 }
1291 LCRYPTO_ALIAS(EC_GROUP_precompute_mult);
1292 
1293 int
1294 EC_GROUP_have_precompute_mult(const EC_GROUP *group)
1295 {
1296 	return 0;
1297 }
1298 LCRYPTO_ALIAS(EC_GROUP_have_precompute_mult);
1299 
1300 int
1301 ec_group_simple_order_bits(const EC_GROUP *group)
1302 {
1303 	/* XXX change group->order to a pointer? */
1304 #if 0
1305 	if (group->order == NULL)
1306 		return 0;
1307 #endif
1308 	return BN_num_bits(&group->order);
1309 }
1310 
1311 EC_KEY *
1312 ECParameters_dup(EC_KEY *key)
1313 {
1314 	const unsigned char *p;
1315 	unsigned char *der = NULL;
1316 	EC_KEY *dup = NULL;
1317 	int len;
1318 
1319 	if (key == NULL)
1320 		return NULL;
1321 
1322 	if ((len = i2d_ECParameters(key, &der)) <= 0)
1323 		return NULL;
1324 
1325 	p = der;
1326 	dup = d2i_ECParameters(NULL, &p, len);
1327 	freezero(der, len);
1328 
1329 	return dup;
1330 }
1331 LCRYPTO_ALIAS(ECParameters_dup);
1332