Set error code on alloc failures
[openssl.git] / crypto / ec / ec_lib.c
1 /*
2  * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4  *
5  * Licensed under the OpenSSL license (the "License").  You may not use
6  * this file except in compliance with the License.  You can obtain a copy
7  * in the file LICENSE in the source distribution or at
8  * https://www.openssl.org/source/license.html
9  */
10
11 #include <string.h>
12
13 #include <openssl/err.h>
14 #include <openssl/opensslv.h>
15
16 #include "ec_lcl.h"
17
18 /* functions for EC_GROUP objects */
19
20 EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
21 {
22     EC_GROUP *ret;
23
24     if (meth == NULL) {
25         ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
26         return NULL;
27     }
28     if (meth->group_init == 0) {
29         ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
30         return NULL;
31     }
32
33     ret = OPENSSL_zalloc(sizeof(*ret));
34     if (ret == NULL) {
35         ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
36         return NULL;
37     }
38
39     ret->meth = meth;
40     if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
41         ret->order = BN_new();
42         if (ret->order == NULL)
43             goto err;
44         ret->cofactor = BN_new();
45         if (ret->cofactor == NULL)
46             goto err;
47     }
48     ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
49     ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
50     if (!meth->group_init(ret))
51         goto err;
52     return ret;
53
54  err:
55     BN_free(ret->order);
56     BN_free(ret->cofactor);
57     OPENSSL_free(ret);
58     return NULL;
59 }
60
61 void EC_pre_comp_free(EC_GROUP *group)
62 {
63     switch (group->pre_comp_type) {
64     case PCT_none:
65         break;
66     case PCT_nistz256:
67 #ifdef ECP_NISTZ256_ASM
68         EC_nistz256_pre_comp_free(group->pre_comp.nistz256);
69 #endif
70         break;
71 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
72     case PCT_nistp224:
73         EC_nistp224_pre_comp_free(group->pre_comp.nistp224);
74         break;
75     case PCT_nistp256:
76         EC_nistp256_pre_comp_free(group->pre_comp.nistp256);
77         break;
78     case PCT_nistp521:
79         EC_nistp521_pre_comp_free(group->pre_comp.nistp521);
80         break;
81 #else
82     case PCT_nistp224:
83     case PCT_nistp256:
84     case PCT_nistp521:
85         break;
86 #endif
87     case PCT_ec:
88         EC_ec_pre_comp_free(group->pre_comp.ec);
89         break;
90     }
91     group->pre_comp.ec = NULL;
92 }
93
94 void EC_GROUP_free(EC_GROUP *group)
95 {
96     if (!group)
97         return;
98
99     if (group->meth->group_finish != 0)
100         group->meth->group_finish(group);
101
102     EC_pre_comp_free(group);
103     BN_MONT_CTX_free(group->mont_data);
104     EC_POINT_free(group->generator);
105     BN_free(group->order);
106     BN_free(group->cofactor);
107     OPENSSL_free(group->seed);
108     OPENSSL_free(group);
109 }
110
111 void EC_GROUP_clear_free(EC_GROUP *group)
112 {
113     if (!group)
114         return;
115
116     if (group->meth->group_clear_finish != 0)
117         group->meth->group_clear_finish(group);
118     else if (group->meth->group_finish != 0)
119         group->meth->group_finish(group);
120
121     EC_pre_comp_free(group);
122     BN_MONT_CTX_free(group->mont_data);
123     EC_POINT_clear_free(group->generator);
124     BN_clear_free(group->order);
125     BN_clear_free(group->cofactor);
126     OPENSSL_clear_free(group->seed, group->seed_len);
127     OPENSSL_clear_free(group, sizeof(*group));
128 }
129
130 int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
131 {
132     if (dest->meth->group_copy == 0) {
133         ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
134         return 0;
135     }
136     if (dest->meth != src->meth) {
137         ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
138         return 0;
139     }
140     if (dest == src)
141         return 1;
142
143     /* Copy precomputed */
144     dest->pre_comp_type = src->pre_comp_type;
145     switch (src->pre_comp_type) {
146     case PCT_none:
147         dest->pre_comp.ec = NULL;
148         break;
149     case PCT_nistz256:
150 #ifdef ECP_NISTZ256_ASM
151         dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256);
152 #endif
153         break;
154 #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
155     case PCT_nistp224:
156         dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224);
157         break;
158     case PCT_nistp256:
159         dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256);
160         break;
161     case PCT_nistp521:
162         dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
163         break;
164 #else
165     case PCT_nistp224:
166     case PCT_nistp256:
167     case PCT_nistp521:
168         break;
169 #endif
170     case PCT_ec:
171         dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec);
172         break;
173     }
174
175     if (src->mont_data != NULL) {
176         if (dest->mont_data == NULL) {
177             dest->mont_data = BN_MONT_CTX_new();
178             if (dest->mont_data == NULL)
179                 return 0;
180         }
181         if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
182             return 0;
183     } else {
184         /* src->generator == NULL */
185         BN_MONT_CTX_free(dest->mont_data);
186         dest->mont_data = NULL;
187     }
188
189     if (src->generator != NULL) {
190         if (dest->generator == NULL) {
191             dest->generator = EC_POINT_new(dest);
192             if (dest->generator == NULL)
193                 return 0;
194         }
195         if (!EC_POINT_copy(dest->generator, src->generator))
196             return 0;
197     } else {
198         /* src->generator == NULL */
199         EC_POINT_clear_free(dest->generator);
200         dest->generator = NULL;
201     }
202
203     if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
204         if (!BN_copy(dest->order, src->order))
205             return 0;
206         if (!BN_copy(dest->cofactor, src->cofactor))
207             return 0;
208     }
209
210     dest->curve_name = src->curve_name;
211     dest->asn1_flag = src->asn1_flag;
212     dest->asn1_form = src->asn1_form;
213
214     if (src->seed) {
215         OPENSSL_free(dest->seed);
216         if ((dest->seed = OPENSSL_malloc(src->seed_len)) == NULL) {
217             ECerr(EC_F_EC_GROUP_COPY, ERR_R_MALLOC_FAILURE);
218             return 0;
219         }
220         if (!memcpy(dest->seed, src->seed, src->seed_len))
221             return 0;
222         dest->seed_len = src->seed_len;
223     } else {
224         OPENSSL_free(dest->seed);
225         dest->seed = NULL;
226         dest->seed_len = 0;
227     }
228
229     return dest->meth->group_copy(dest, src);
230 }
231
232 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
233 {
234     EC_GROUP *t = NULL;
235     int ok = 0;
236
237     if (a == NULL)
238         return NULL;
239
240     if ((t = EC_GROUP_new(a->meth)) == NULL)
241         return NULL;
242     if (!EC_GROUP_copy(t, a))
243         goto err;
244
245     ok = 1;
246
247  err:
248     if (!ok) {
249         EC_GROUP_free(t);
250         return NULL;
251     }
252         return t;
253 }
254
255 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
256 {
257     return group->meth;
258 }
259
260 int EC_METHOD_get_field_type(const EC_METHOD *meth)
261 {
262     return meth->field_type;
263 }
264
265 static int ec_precompute_mont_data(EC_GROUP *);
266
267 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
268                            const BIGNUM *order, const BIGNUM *cofactor)
269 {
270     if (generator == NULL) {
271         ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
272         return 0;
273     }
274
275     if (group->generator == NULL) {
276         group->generator = EC_POINT_new(group);
277         if (group->generator == NULL)
278             return 0;
279     }
280     if (!EC_POINT_copy(group->generator, generator))
281         return 0;
282
283     if (order != NULL) {
284         if (!BN_copy(group->order, order))
285             return 0;
286     } else
287         BN_zero(group->order);
288
289     if (cofactor != NULL) {
290         if (!BN_copy(group->cofactor, cofactor))
291             return 0;
292     } else
293         BN_zero(group->cofactor);
294
295     /*
296      * Some groups have an order with
297      * factors of two, which makes the Montgomery setup fail.
298      * |group->mont_data| will be NULL in this case.
299      */
300     if (BN_is_odd(group->order)) {
301         return ec_precompute_mont_data(group);
302     }
303
304     BN_MONT_CTX_free(group->mont_data);
305     group->mont_data = NULL;
306     return 1;
307 }
308
309 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
310 {
311     return group->generator;
312 }
313
314 BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
315 {
316     return group->mont_data;
317 }
318
319 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
320 {
321     if (group->order == NULL)
322         return 0;
323     if (!BN_copy(order, group->order))
324         return 0;
325
326     return !BN_is_zero(order);
327 }
328
329 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group)
330 {
331     return group->order;
332 }
333
334 int EC_GROUP_order_bits(const EC_GROUP *group)
335 {
336     return group->meth->group_order_bits(group);
337 }
338
339 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
340                           BN_CTX *ctx)
341 {
342
343     if (group->cofactor == NULL)
344         return 0;
345     if (!BN_copy(cofactor, group->cofactor))
346         return 0;
347
348     return !BN_is_zero(group->cofactor);
349 }
350
351 const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group)
352 {
353     return group->cofactor;
354 }
355
356 void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
357 {
358     group->curve_name = nid;
359 }
360
361 int EC_GROUP_get_curve_name(const EC_GROUP *group)
362 {
363     return group->curve_name;
364 }
365
366 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
367 {
368     group->asn1_flag = flag;
369 }
370
371 int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
372 {
373     return group->asn1_flag;
374 }
375
376 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
377                                         point_conversion_form_t form)
378 {
379     group->asn1_form = form;
380 }
381
382 point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
383                                                            *group)
384 {
385     return group->asn1_form;
386 }
387
388 size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
389 {
390     OPENSSL_free(group->seed);
391     group->seed = NULL;
392     group->seed_len = 0;
393
394     if (!len || !p)
395         return 1;
396
397     if ((group->seed = OPENSSL_malloc(len)) == NULL)
398         return 0;
399     memcpy(group->seed, p, len);
400     group->seed_len = len;
401
402     return len;
403 }
404
405 unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
406 {
407     return group->seed;
408 }
409
410 size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
411 {
412     return group->seed_len;
413 }
414
415 int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
416                            const BIGNUM *b, BN_CTX *ctx)
417 {
418     if (group->meth->group_set_curve == 0) {
419         ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
420         return 0;
421     }
422     return group->meth->group_set_curve(group, p, a, b, ctx);
423 }
424
425 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
426                            BIGNUM *b, BN_CTX *ctx)
427 {
428     if (group->meth->group_get_curve == 0) {
429         ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
430         return 0;
431     }
432     return group->meth->group_get_curve(group, p, a, b, ctx);
433 }
434
435 #ifndef OPENSSL_NO_EC2M
436 int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
437                             const BIGNUM *b, BN_CTX *ctx)
438 {
439     if (group->meth->group_set_curve == 0) {
440         ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
441               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
442         return 0;
443     }
444     return group->meth->group_set_curve(group, p, a, b, ctx);
445 }
446
447 int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
448                             BIGNUM *b, BN_CTX *ctx)
449 {
450     if (group->meth->group_get_curve == 0) {
451         ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M,
452               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
453         return 0;
454     }
455     return group->meth->group_get_curve(group, p, a, b, ctx);
456 }
457 #endif
458
459 int EC_GROUP_get_degree(const EC_GROUP *group)
460 {
461     if (group->meth->group_get_degree == 0) {
462         ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
463         return 0;
464     }
465     return group->meth->group_get_degree(group);
466 }
467
468 int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
469 {
470     if (group->meth->group_check_discriminant == 0) {
471         ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
472               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
473         return 0;
474     }
475     return group->meth->group_check_discriminant(group, ctx);
476 }
477
478 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
479 {
480     int r = 0;
481     BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
482     BN_CTX *ctx_new = NULL;
483
484     /* compare the field types */
485     if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
486         EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
487         return 1;
488     /* compare the curve name (if present in both) */
489     if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
490         EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
491         return 1;
492     if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
493         return 0;
494
495     if (ctx == NULL)
496         ctx_new = ctx = BN_CTX_new();
497     if (ctx == NULL)
498         return -1;
499
500     BN_CTX_start(ctx);
501     a1 = BN_CTX_get(ctx);
502     a2 = BN_CTX_get(ctx);
503     a3 = BN_CTX_get(ctx);
504     b1 = BN_CTX_get(ctx);
505     b2 = BN_CTX_get(ctx);
506     b3 = BN_CTX_get(ctx);
507     if (b3 == NULL) {
508         BN_CTX_end(ctx);
509         BN_CTX_free(ctx_new);
510         return -1;
511     }
512
513     /*
514      * XXX This approach assumes that the external representation of curves
515      * over the same field type is the same.
516      */
517     if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
518         !b->meth->group_get_curve(b, b1, b2, b3, ctx))
519         r = 1;
520
521     if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
522         r = 1;
523
524     /* XXX EC_POINT_cmp() assumes that the methods are equal */
525     if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
526                           EC_GROUP_get0_generator(b), ctx))
527         r = 1;
528
529     if (!r) {
530         const BIGNUM *ao, *bo, *ac, *bc;
531         /* compare the order and cofactor */
532         ao = EC_GROUP_get0_order(a);
533         bo = EC_GROUP_get0_order(b);
534         ac = EC_GROUP_get0_cofactor(a);
535         bc = EC_GROUP_get0_cofactor(b);
536         if (ao == NULL || bo == NULL) {
537             BN_CTX_end(ctx);
538             BN_CTX_free(ctx_new);
539             return -1;
540         }
541         if (BN_cmp(ao, bo) || BN_cmp(ac, bc))
542             r = 1;
543     }
544
545     BN_CTX_end(ctx);
546     BN_CTX_free(ctx_new);
547
548     return r;
549 }
550
551 /* functions for EC_POINT objects */
552
553 EC_POINT *EC_POINT_new(const EC_GROUP *group)
554 {
555     EC_POINT *ret;
556
557     if (group == NULL) {
558         ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
559         return NULL;
560     }
561     if (group->meth->point_init == 0) {
562         ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
563         return NULL;
564     }
565
566     ret = OPENSSL_zalloc(sizeof(*ret));
567     if (ret == NULL) {
568         ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
569         return NULL;
570     }
571
572     ret->meth = group->meth;
573
574     if (!ret->meth->point_init(ret)) {
575         OPENSSL_free(ret);
576         return NULL;
577     }
578
579     return ret;
580 }
581
582 void EC_POINT_free(EC_POINT *point)
583 {
584     if (!point)
585         return;
586
587     if (point->meth->point_finish != 0)
588         point->meth->point_finish(point);
589     OPENSSL_free(point);
590 }
591
592 void EC_POINT_clear_free(EC_POINT *point)
593 {
594     if (!point)
595         return;
596
597     if (point->meth->point_clear_finish != 0)
598         point->meth->point_clear_finish(point);
599     else if (point->meth->point_finish != 0)
600         point->meth->point_finish(point);
601     OPENSSL_clear_free(point, sizeof(*point));
602 }
603
604 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
605 {
606     if (dest->meth->point_copy == 0) {
607         ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
608         return 0;
609     }
610     if (dest->meth != src->meth) {
611         ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
612         return 0;
613     }
614     if (dest == src)
615         return 1;
616     return dest->meth->point_copy(dest, src);
617 }
618
619 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
620 {
621     EC_POINT *t;
622     int r;
623
624     if (a == NULL)
625         return NULL;
626
627     t = EC_POINT_new(group);
628     if (t == NULL)
629         return NULL;
630     r = EC_POINT_copy(t, a);
631     if (!r) {
632         EC_POINT_free(t);
633         return NULL;
634     }
635     return t;
636 }
637
638 const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
639 {
640     return point->meth;
641 }
642
643 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
644 {
645     if (group->meth->point_set_to_infinity == 0) {
646         ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
647               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
648         return 0;
649     }
650     if (group->meth != point->meth) {
651         ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
652         return 0;
653     }
654     return group->meth->point_set_to_infinity(group, point);
655 }
656
657 int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
658                                              EC_POINT *point, const BIGNUM *x,
659                                              const BIGNUM *y, const BIGNUM *z,
660                                              BN_CTX *ctx)
661 {
662     if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
663         ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
664               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
665         return 0;
666     }
667     if (group->meth != point->meth) {
668         ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
669               EC_R_INCOMPATIBLE_OBJECTS);
670         return 0;
671     }
672     return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
673                                                               y, z, ctx);
674 }
675
676 int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
677                                              const EC_POINT *point, BIGNUM *x,
678                                              BIGNUM *y, BIGNUM *z,
679                                              BN_CTX *ctx)
680 {
681     if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
682         ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
683               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
684         return 0;
685     }
686     if (group->meth != point->meth) {
687         ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
688               EC_R_INCOMPATIBLE_OBJECTS);
689         return 0;
690     }
691     return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
692                                                               y, z, ctx);
693 }
694
695 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
696                                         EC_POINT *point, const BIGNUM *x,
697                                         const BIGNUM *y, BN_CTX *ctx)
698 {
699     if (group->meth->point_set_affine_coordinates == 0) {
700         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
701               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
702         return 0;
703     }
704     if (group->meth != point->meth) {
705         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
706               EC_R_INCOMPATIBLE_OBJECTS);
707         return 0;
708     }
709     if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
710         return 0;
711
712     if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
713         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
714               EC_R_POINT_IS_NOT_ON_CURVE);
715         return 0;
716     }
717     return 1;
718 }
719
720 #ifndef OPENSSL_NO_EC2M
721 int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
722                                          EC_POINT *point, const BIGNUM *x,
723                                          const BIGNUM *y, BN_CTX *ctx)
724 {
725     if (group->meth->point_set_affine_coordinates == 0) {
726         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
727               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
728         return 0;
729     }
730     if (group->meth != point->meth) {
731         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
732               EC_R_INCOMPATIBLE_OBJECTS);
733         return 0;
734     }
735     if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
736         return 0;
737
738     if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
739         ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
740               EC_R_POINT_IS_NOT_ON_CURVE);
741         return 0;
742     }
743     return 1;
744 }
745 #endif
746
747 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
748                                         const EC_POINT *point, BIGNUM *x,
749                                         BIGNUM *y, BN_CTX *ctx)
750 {
751     if (group->meth->point_get_affine_coordinates == 0) {
752         ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
753               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
754         return 0;
755     }
756     if (group->meth != point->meth) {
757         ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
758               EC_R_INCOMPATIBLE_OBJECTS);
759         return 0;
760     }
761     return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
762 }
763
764 #ifndef OPENSSL_NO_EC2M
765 int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
766                                          const EC_POINT *point, BIGNUM *x,
767                                          BIGNUM *y, BN_CTX *ctx)
768 {
769     if (group->meth->point_get_affine_coordinates == 0) {
770         ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
771               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
772         return 0;
773     }
774     if (group->meth != point->meth) {
775         ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
776               EC_R_INCOMPATIBLE_OBJECTS);
777         return 0;
778     }
779     return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
780 }
781 #endif
782
783 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
784                  const EC_POINT *b, BN_CTX *ctx)
785 {
786     if (group->meth->add == 0) {
787         ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
788         return 0;
789     }
790     if ((group->meth != r->meth) || (r->meth != a->meth)
791         || (a->meth != b->meth)) {
792         ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
793         return 0;
794     }
795     return group->meth->add(group, r, a, b, ctx);
796 }
797
798 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
799                  BN_CTX *ctx)
800 {
801     if (group->meth->dbl == 0) {
802         ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
803         return 0;
804     }
805     if ((group->meth != r->meth) || (r->meth != a->meth)) {
806         ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
807         return 0;
808     }
809     return group->meth->dbl(group, r, a, ctx);
810 }
811
812 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
813 {
814     if (group->meth->invert == 0) {
815         ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
816         return 0;
817     }
818     if (group->meth != a->meth) {
819         ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
820         return 0;
821     }
822     return group->meth->invert(group, a, ctx);
823 }
824
825 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
826 {
827     if (group->meth->is_at_infinity == 0) {
828         ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
829               ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
830         return 0;
831     }
832     if (group->meth != point->meth) {
833         ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
834         return 0;
835     }
836     return group->meth->is_at_infinity(group, point);
837 }
838
839 /*
840  * Check whether an EC_POINT is on the curve or not. Note that the return
841  * value for this function should NOT be treated as a boolean. Return values:
842  *  1: The point is on the curve
843  *  0: The point is not on the curve
844  * -1: An error occurred
845  */
846 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
847                          BN_CTX *ctx)
848 {
849     if (group->meth->is_on_curve == 0) {
850         ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
851         return 0;
852     }
853     if (group->meth != point->meth) {
854         ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
855         return 0;
856     }
857     return group->meth->is_on_curve(group, point, ctx);
858 }
859
860 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
861                  BN_CTX *ctx)
862 {
863     if (group->meth->point_cmp == 0) {
864         ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
865         return -1;
866     }
867     if ((group->meth != a->meth) || (a->meth != b->meth)) {
868         ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
869         return -1;
870     }
871     return group->meth->point_cmp(group, a, b, ctx);
872 }
873
874 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
875 {
876     if (group->meth->make_affine == 0) {
877         ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
878         return 0;
879     }
880     if (group->meth != point->meth) {
881         ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
882         return 0;
883     }
884     return group->meth->make_affine(group, point, ctx);
885 }
886
887 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
888                           EC_POINT *points[], BN_CTX *ctx)
889 {
890     size_t i;
891
892     if (group->meth->points_make_affine == 0) {
893         ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
894         return 0;
895     }
896     for (i = 0; i < num; i++) {
897         if (group->meth != points[i]->meth) {
898             ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
899             return 0;
900         }
901     }
902     return group->meth->points_make_affine(group, num, points, ctx);
903 }
904
905 /*
906  * Functions for point multiplication. If group->meth->mul is 0, we use the
907  * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
908  * methods.
909  */
910
911 int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
912                   size_t num, const EC_POINT *points[],
913                   const BIGNUM *scalars[], BN_CTX *ctx)
914 {
915     if (group->meth->mul == 0)
916         /* use default */
917         return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
918
919     return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
920 }
921
922 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
923                  const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
924 {
925     /* just a convenient interface to EC_POINTs_mul() */
926
927     const EC_POINT *points[1];
928     const BIGNUM *scalars[1];
929
930     points[0] = point;
931     scalars[0] = p_scalar;
932
933     return EC_POINTs_mul(group, r, g_scalar,
934                          (point != NULL
935                           && p_scalar != NULL), points, scalars, ctx);
936 }
937
938 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
939 {
940     if (group->meth->mul == 0)
941         /* use default */
942         return ec_wNAF_precompute_mult(group, ctx);
943
944     if (group->meth->precompute_mult != 0)
945         return group->meth->precompute_mult(group, ctx);
946     else
947         return 1;               /* nothing to do, so report success */
948 }
949
950 int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
951 {
952     if (group->meth->mul == 0)
953         /* use default */
954         return ec_wNAF_have_precompute_mult(group);
955
956     if (group->meth->have_precompute_mult != 0)
957         return group->meth->have_precompute_mult(group);
958     else
959         return 0;               /* cannot tell whether precomputation has
960                                  * been performed */
961 }
962
963 /*
964  * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
965  * returns one on success. On error it returns zero.
966  */
967 static int ec_precompute_mont_data(EC_GROUP *group)
968 {
969     BN_CTX *ctx = BN_CTX_new();
970     int ret = 0;
971
972     BN_MONT_CTX_free(group->mont_data);
973     group->mont_data = NULL;
974
975     if (ctx == NULL)
976         goto err;
977
978     group->mont_data = BN_MONT_CTX_new();
979     if (group->mont_data == NULL)
980         goto err;
981
982     if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) {
983         BN_MONT_CTX_free(group->mont_data);
984         group->mont_data = NULL;
985         goto err;
986     }
987
988     ret = 1;
989
990  err:
991
992     BN_CTX_free(ctx);
993     return ret;
994 }
995
996 int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg)
997 {
998     return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
999 }
1000
1001 void *EC_KEY_get_ex_data(const EC_KEY *key, int idx)
1002 {
1003     return CRYPTO_get_ex_data(&key->ex_data, idx);
1004 }
1005
1006 int ec_group_simple_order_bits(const EC_GROUP *group)
1007 {
1008     if (group->order == NULL)
1009         return 0;
1010     return BN_num_bits(group->order);
1011 }
1012
1013 int EC_GROUP_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
1014                             BIGNUM *x, BN_CTX *ctx)
1015 {
1016     if (group->meth->field_inverse_mod_ord != NULL)
1017         return group->meth->field_inverse_mod_ord(group, res, x, ctx);
1018     else
1019         return 0;
1020 }