GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/ec/ec_lib.c Lines: 269 482 55.8 %
Date: 2017-11-13 Branches: 127 314 40.4 %

Line Branch Exec Source
1
/* $OpenBSD: ec_lib.c,v 1.24 2017/05/02 03:59:44 deraadt 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 "ec_lcl.h"
72
73
/* functions for EC_GROUP objects */
74
75
EC_GROUP *
76
EC_GROUP_new(const EC_METHOD * meth)
77
{
78
	EC_GROUP *ret;
79
80
12154
	if (meth == NULL) {
81
		ECerror(EC_R_SLOT_FULL);
82
		return NULL;
83
	}
84
6077
	if (meth->group_init == 0) {
85
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
86
		return NULL;
87
	}
88
6077
	ret = malloc(sizeof *ret);
89
6077
	if (ret == NULL) {
90
		ECerror(ERR_R_MALLOC_FAILURE);
91
		return NULL;
92
	}
93
6077
	ret->meth = meth;
94
95
6077
	ret->extra_data = NULL;
96
97
6077
	ret->generator = NULL;
98
6077
	BN_init(&ret->order);
99
6077
	BN_init(&ret->cofactor);
100
101
6077
	ret->curve_name = 0;
102
6077
	ret->asn1_flag = 0;
103
6077
	ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
104
105
6077
	ret->seed = NULL;
106
6077
	ret->seed_len = 0;
107
108
6077
	if (!meth->group_init(ret)) {
109
		free(ret);
110
		return NULL;
111
	}
112
6077
	return ret;
113
6077
}
114
115
116
void
117
EC_GROUP_free(EC_GROUP * group)
118
{
119
18562
	if (!group)
120
		return;
121
122
6077
	if (group->meth->group_finish != 0)
123
6077
		group->meth->group_finish(group);
124
125
6077
	EC_EX_DATA_free_all_data(&group->extra_data);
126
127
6077
	EC_POINT_free(group->generator);
128
6077
	BN_free(&group->order);
129
6077
	BN_free(&group->cofactor);
130
131
6077
	free(group->seed);
132
133
6077
	free(group);
134
15358
}
135
136
137
void
138
EC_GROUP_clear_free(EC_GROUP * group)
139
{
140
372
	if (!group)
141
		return;
142
143
	if (group->meth->group_clear_finish != 0)
144
		group->meth->group_clear_finish(group);
145
	else if (group->meth->group_finish != 0)
146
		group->meth->group_finish(group);
147
148
	EC_EX_DATA_clear_free_all_data(&group->extra_data);
149
150
	EC_POINT_clear_free(group->generator);
151
	BN_clear_free(&group->order);
152
	BN_clear_free(&group->cofactor);
153
154
	freezero(group->seed, group->seed_len);
155
	freezero(group, sizeof *group);
156
186
}
157
158
159
int
160
EC_GROUP_copy(EC_GROUP * dest, const EC_GROUP * src)
161
{
162
	EC_EXTRA_DATA *d;
163
164
6488
	if (dest->meth->group_copy == 0) {
165
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
166
		return 0;
167
	}
168
3244
	if (dest->meth != src->meth) {
169
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
170
		return 0;
171
	}
172
3244
	if (dest == src)
173
		return 1;
174
175
3244
	EC_EX_DATA_free_all_data(&dest->extra_data);
176
177
6584
	for (d = src->extra_data; d != NULL; d = d->next) {
178
48
		void *t = d->dup_func(d->data);
179
180
48
		if (t == NULL)
181
			return 0;
182
96
		if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func,
183
48
		    d->free_func, d->clear_free_func))
184
			return 0;
185
48
	}
186
187
3244
	if (src->generator != NULL) {
188
3238
		if (dest->generator == NULL) {
189
3238
			dest->generator = EC_POINT_new(dest);
190
3238
			if (dest->generator == NULL)
191
				return 0;
192
		}
193
3238
		if (!EC_POINT_copy(dest->generator, src->generator))
194
			return 0;
195
	} else {
196
		/* src->generator == NULL */
197
6
		EC_POINT_clear_free(dest->generator);
198
6
		dest->generator = NULL;
199
	}
200
201
3244
	if (!BN_copy(&dest->order, &src->order))
202
		return 0;
203
3244
	if (!BN_copy(&dest->cofactor, &src->cofactor))
204
		return 0;
205
206
3244
	dest->curve_name = src->curve_name;
207
3244
	dest->asn1_flag = src->asn1_flag;
208
3244
	dest->asn1_form = src->asn1_form;
209
210
6488
	if (src->seed) {
211
3244
		free(dest->seed);
212
2765
		dest->seed = malloc(src->seed_len);
213
2765
		if (dest->seed == NULL)
214
			return 0;
215
2765
		memcpy(dest->seed, src->seed, src->seed_len);
216
2765
		dest->seed_len = src->seed_len;
217
2765
	} else {
218
		free(dest->seed);
219
479
		dest->seed = NULL;
220
		dest->seed_len = 0;
221
	}
222
223
224
3244
	return dest->meth->group_copy(dest, src);
225
3244
}
226
227
228
EC_GROUP *
229
EC_GROUP_dup(const EC_GROUP * a)
230
{
231
	EC_GROUP *t = NULL;
232
233

12760
	if ((a != NULL) && ((t = EC_GROUP_new(a->meth)) != NULL) &&
234
3190
	    (!EC_GROUP_copy(t, a))) {
235
		EC_GROUP_free(t);
236
		t = NULL;
237
	}
238
3190
	return t;
239
}
240
241
242
const EC_METHOD *
243
EC_GROUP_method_of(const EC_GROUP *group)
244
{
245
13532
	return group->meth;
246
}
247
248
249
int
250
EC_METHOD_get_field_type(const EC_METHOD *meth)
251
{
252
13424
	return meth->field_type;
253
}
254
255
256
int
257
EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
258
    const BIGNUM *order, const BIGNUM *cofactor)
259
{
260
5750
	if (generator == NULL) {
261
		ECerror(ERR_R_PASSED_NULL_PARAMETER);
262
		return 0;
263
	}
264
2875
	if (group->generator == NULL) {
265
2833
		group->generator = EC_POINT_new(group);
266
2833
		if (group->generator == NULL)
267
			return 0;
268
	}
269
2875
	if (!EC_POINT_copy(group->generator, generator))
270
		return 0;
271
272
2875
	if (order != NULL) {
273
2875
		if (!BN_copy(&group->order, order))
274
			return 0;
275
	} else
276
		BN_zero(&group->order);
277
278
2875
	if (cofactor != NULL) {
279
2875
		if (!BN_copy(&group->cofactor, cofactor))
280
			return 0;
281
	} else
282
		BN_zero(&group->cofactor);
283
284
2875
	return 1;
285
2875
}
286
287
288
const EC_POINT *
289
EC_GROUP_get0_generator(const EC_GROUP *group)
290
{
291
8834
	return group->generator;
292
}
293
294
295
int
296
EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
297
{
298
11798
	if (!BN_copy(order, &group->order))
299
		return 0;
300
301
5899
	return !BN_is_zero(order);
302
5899
}
303
304
305
int
306
EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
307
{
308
2912
	if (!BN_copy(cofactor, &group->cofactor))
309
		return 0;
310
311
1456
	return !BN_is_zero(&group->cofactor);
312
1456
}
313
314
315
void
316
EC_GROUP_set_curve_name(EC_GROUP * group, int nid)
317
{
318
5282
	group->curve_name = nid;
319
2641
}
320
321
322
int
323
EC_GROUP_get_curve_name(const EC_GROUP * group)
324
{
325
512
	return group->curve_name;
326
}
327
328
329
void
330
EC_GROUP_set_asn1_flag(EC_GROUP * group, int flag)
331
{
332
1092
	group->asn1_flag = flag;
333
546
}
334
335
336
int
337
EC_GROUP_get_asn1_flag(const EC_GROUP * group)
338
{
339
2560
	return group->asn1_flag;
340
}
341
342
343
void
344
EC_GROUP_set_point_conversion_form(EC_GROUP * group,
345
    point_conversion_form_t form)
346
{
347
1092
	group->asn1_form = form;
348
546
}
349
350
351
point_conversion_form_t
352
EC_GROUP_get_point_conversion_form(const EC_GROUP * group)
353
{
354
2912
	return group->asn1_form;
355
}
356
357
358
size_t
359
EC_GROUP_set_seed(EC_GROUP * group, const unsigned char *p, size_t len)
360
{
361
4030
	if (group->seed) {
362
		free(group->seed);
363
		group->seed = NULL;
364
		group->seed_len = 0;
365
	}
366
2015
	if (!len || !p)
367
		return 1;
368
369
2015
	if ((group->seed = malloc(len)) == NULL)
370
		return 0;
371
2015
	memcpy(group->seed, p, len);
372
2015
	group->seed_len = len;
373
374
2015
	return len;
375
2015
}
376
377
378
unsigned char *
379
EC_GROUP_get0_seed(const EC_GROUP * group)
380
{
381
368
	return group->seed;
382
}
383
384
385
size_t
386
EC_GROUP_get_seed_len(const EC_GROUP * group)
387
{
388
172
	return group->seed_len;
389
}
390
391
392
int
393
EC_GROUP_set_curve_GFp(EC_GROUP * group, const BIGNUM * p, const BIGNUM * a,
394
    const BIGNUM * b, BN_CTX * ctx)
395
{
396
4506
	if (group->meth->group_set_curve == 0) {
397
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
398
		return 0;
399
	}
400
2253
	return group->meth->group_set_curve(group, p, a, b, ctx);
401
2253
}
402
403
404
int
405
EC_GROUP_get_curve_GFp(const EC_GROUP * group, BIGNUM * p, BIGNUM * a,
406
    BIGNUM * b, BN_CTX * ctx)
407
{
408
2750
	if (group->meth->group_get_curve == 0) {
409
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
410
		return 0;
411
	}
412
1375
	return group->meth->group_get_curve(group, p, a, b, ctx);
413
1375
}
414
415
#ifndef OPENSSL_NO_EC2M
416
int
417
EC_GROUP_set_curve_GF2m(EC_GROUP * group, const BIGNUM * p, const BIGNUM * a,
418
    const BIGNUM * b, BN_CTX * ctx)
419
{
420
1256
	if (group->meth->group_set_curve == 0) {
421
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
422
		return 0;
423
	}
424
628
	return group->meth->group_set_curve(group, p, a, b, ctx);
425
628
}
426
427
428
int
429
EC_GROUP_get_curve_GF2m(const EC_GROUP * group, BIGNUM * p, BIGNUM * a,
430
    BIGNUM * b, BN_CTX * ctx)
431
{
432
1350
	if (group->meth->group_get_curve == 0) {
433
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
434
		return 0;
435
	}
436
675
	return group->meth->group_get_curve(group, p, a, b, ctx);
437
675
}
438
#endif
439
440
int
441
EC_GROUP_get_degree(const EC_GROUP * group)
442
{
443
11572
	if (group->meth->group_get_degree == 0) {
444
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
445
		return 0;
446
	}
447
5786
	return group->meth->group_get_degree(group);
448
5786
}
449
450
451
int
452
EC_GROUP_check_discriminant(const EC_GROUP * group, BN_CTX * ctx)
453
{
454
540
	if (group->meth->group_check_discriminant == 0) {
455
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
456
		return 0;
457
	}
458
270
	return group->meth->group_check_discriminant(group, ctx);
459
270
}
460
461
462
int
463
EC_GROUP_cmp(const EC_GROUP * a, const EC_GROUP * b, BN_CTX * ctx)
464
{
465
	int r = 0;
466
	BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
467
	BN_CTX *ctx_new = NULL;
468
469
	/* compare the field types */
470
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
471
	    EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
472
		return 1;
473
	/* compare the curve name (if present in both) */
474
	if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
475
	    EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
476
		return 1;
477
478
	if (!ctx)
479
		ctx_new = ctx = BN_CTX_new();
480
	if (!ctx)
481
		return -1;
482
483
	BN_CTX_start(ctx);
484
	if ((a1 = BN_CTX_get(ctx)) == NULL)
485
		goto err;
486
	if ((a2 = BN_CTX_get(ctx)) == NULL)
487
		goto err;
488
	if ((a3 = BN_CTX_get(ctx)) == NULL)
489
		goto err;
490
	if ((b1 = BN_CTX_get(ctx)) == NULL)
491
		goto err;
492
	if ((b2 = BN_CTX_get(ctx)) == NULL)
493
		goto err;
494
	if ((b3 = BN_CTX_get(ctx)) == NULL)
495
		goto err;
496
497
	/*
498
	 * XXX This approach assumes that the external representation of
499
	 * curves over the same field type is the same.
500
	 */
501
	if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
502
	    !b->meth->group_get_curve(b, b1, b2, b3, ctx))
503
		r = 1;
504
505
	if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
506
		r = 1;
507
508
	/* XXX EC_POINT_cmp() assumes that the methods are equal */
509
	if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
510
		EC_GROUP_get0_generator(b), ctx))
511
		r = 1;
512
513
	if (!r) {
514
		/* compare the order and cofactor */
515
		if (!EC_GROUP_get_order(a, a1, ctx) ||
516
		    !EC_GROUP_get_order(b, b1, ctx) ||
517
		    !EC_GROUP_get_cofactor(a, a2, ctx) ||
518
		    !EC_GROUP_get_cofactor(b, b2, ctx))
519
			goto err;
520
		if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
521
			r = 1;
522
	}
523
	BN_CTX_end(ctx);
524
	if (ctx_new)
525
		BN_CTX_free(ctx);
526
527
	return r;
528
529
err:
530
	BN_CTX_end(ctx);
531
	if (ctx_new)
532
		BN_CTX_free(ctx);
533
	return -1;
534
}
535
536
537
/* this has 'package' visibility */
538
int
539
EC_EX_DATA_set_data(EC_EXTRA_DATA ** ex_data, void *data,
540
    void *(*dup_func) (void *),
541
    void (*free_func) (void *),
542
    void (*clear_free_func) (void *))
543
{
544
	EC_EXTRA_DATA *d;
545
546
3812
	if (ex_data == NULL)
547
		return 0;
548
549
3812
	for (d = *ex_data; d != NULL; d = d->next) {
550
		if (d->dup_func == dup_func && d->free_func == free_func &&
551
		    d->clear_free_func == clear_free_func) {
552
			ECerror(EC_R_SLOT_FULL);
553
			return 0;
554
		}
555
	}
556
557
1906
	if (data == NULL)
558
		/* no explicit entry needed */
559
		return 1;
560
561
1906
	d = malloc(sizeof *d);
562
1906
	if (d == NULL)
563
		return 0;
564
565
1906
	d->data = data;
566
1906
	d->dup_func = dup_func;
567
1906
	d->free_func = free_func;
568
1906
	d->clear_free_func = clear_free_func;
569
570
1906
	d->next = *ex_data;
571
1906
	*ex_data = d;
572
573
1906
	return 1;
574
1906
}
575
576
/* this has 'package' visibility */
577
void *
578
EC_EX_DATA_get_data(const EC_EXTRA_DATA * ex_data,
579
    void *(*dup_func) (void *),
580
    void (*free_func) (void *),
581
    void (*clear_free_func) (void *))
582
{
583
	const EC_EXTRA_DATA *d;
584
585
26013
	for (d = ex_data; d != NULL; d = d->next) {
586

4563
		if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
587
1521
			return d->data;
588
	}
589
590
7150
	return NULL;
591
8671
}
592
593
/* this has 'package' visibility */
594
void
595
EC_EX_DATA_free_data(EC_EXTRA_DATA ** ex_data,
596
    void *(*dup_func) (void *),
597
    void (*free_func) (void *),
598
    void (*clear_free_func) (void *))
599
{
600
	EC_EXTRA_DATA **p;
601
602
96
	if (ex_data == NULL)
603
		return;
604
605
96
	for (p = ex_data; *p != NULL; p = &((*p)->next)) {
606

84
		if ((*p)->dup_func == dup_func &&
607
42
		    (*p)->free_func == free_func &&
608
42
		    (*p)->clear_free_func == clear_free_func) {
609
42
			EC_EXTRA_DATA *next = (*p)->next;
610
611
42
			(*p)->free_func((*p)->data);
612
42
			free(*p);
613
614
42
			*p = next;
615
			return;
616
		}
617
	}
618
54
}
619
620
/* this has 'package' visibility */
621
void
622
EC_EX_DATA_clear_free_data(EC_EXTRA_DATA ** ex_data,
623
    void *(*dup_func) (void *),
624
    void (*free_func) (void *),
625
    void (*clear_free_func) (void *))
626
{
627
	EC_EXTRA_DATA **p;
628
629
	if (ex_data == NULL)
630
		return;
631
632
	for (p = ex_data; *p != NULL; p = &((*p)->next)) {
633
		if ((*p)->dup_func == dup_func &&
634
		    (*p)->free_func == free_func &&
635
		    (*p)->clear_free_func == clear_free_func) {
636
			EC_EXTRA_DATA *next = (*p)->next;
637
638
			(*p)->clear_free_func((*p)->data);
639
			free(*p);
640
641
			*p = next;
642
			return;
643
		}
644
	}
645
}
646
647
/* this has 'package' visibility */
648
void
649
EC_EX_DATA_free_all_data(EC_EXTRA_DATA ** ex_data)
650
{
651
	EC_EXTRA_DATA *d;
652
653
26428
	if (ex_data == NULL)
654
		return;
655
656
13214
	d = *ex_data;
657
30156
	while (d) {
658
1864
		EC_EXTRA_DATA *next = d->next;
659
660
1864
		d->free_func(d->data);
661
1864
		free(d);
662
663
		d = next;
664
	}
665
13214
	*ex_data = NULL;
666
26428
}
667
668
/* this has 'package' visibility */
669
void
670
EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data)
671
{
672
	EC_EXTRA_DATA *d;
673
674
	if (ex_data == NULL)
675
		return;
676
677
	d = *ex_data;
678
	while (d) {
679
		EC_EXTRA_DATA *next = d->next;
680
681
		d->clear_free_func(d->data);
682
		free(d);
683
684
		d = next;
685
	}
686
	*ex_data = NULL;
687
}
688
689
690
/* functions for EC_POINT objects */
691
692
EC_POINT *
693
EC_POINT_new(const EC_GROUP * group)
694
{
695
	EC_POINT *ret;
696
697
129158
	if (group == NULL) {
698
		ECerror(ERR_R_PASSED_NULL_PARAMETER);
699
		return NULL;
700
	}
701
64579
	if (group->meth->point_init == 0) {
702
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
703
		return NULL;
704
	}
705
64579
	ret = malloc(sizeof *ret);
706
64579
	if (ret == NULL) {
707
		ECerror(ERR_R_MALLOC_FAILURE);
708
		return NULL;
709
	}
710
64579
	ret->meth = group->meth;
711
712
64579
	if (!ret->meth->point_init(ret)) {
713
		free(ret);
714
		return NULL;
715
	}
716
64579
	return ret;
717
64579
}
718
719
720
void
721
EC_POINT_free(EC_POINT * point)
722
{
723
84162
	if (!point)
724
		return;
725
726
40292
	if (point->meth->point_finish != 0)
727
40292
		point->meth->point_finish(point);
728
40292
	free(point);
729
82373
}
730
731
732
void
733
EC_POINT_clear_free(EC_POINT * point)
734
{
735
48950
	if (!point)
736
		return;
737
738
24287
	if (point->meth->point_clear_finish != 0)
739
24287
		point->meth->point_clear_finish(point);
740
	else if (point->meth->point_finish != 0)
741
		point->meth->point_finish(point);
742
24287
	freezero(point, sizeof *point);
743
48762
}
744
745
746
int
747
EC_POINT_copy(EC_POINT * dest, const EC_POINT * src)
748
{
749
50978
	if (dest->meth->point_copy == 0) {
750
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
751
		return 0;
752
	}
753
25489
	if (dest->meth != src->meth) {
754
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
755
		return 0;
756
	}
757
25489
	if (dest == src)
758
436
		return 1;
759
25053
	return dest->meth->point_copy(dest, src);
760
25489
}
761
762
763
EC_POINT *
764
EC_POINT_dup(const EC_POINT * a, const EC_GROUP * group)
765
{
766
	EC_POINT *t;
767
	int r;
768
769
2566
	if (a == NULL)
770
		return NULL;
771
772
1283
	t = EC_POINT_new(group);
773
1283
	if (t == NULL)
774
		return (NULL);
775
1283
	r = EC_POINT_copy(t, a);
776
1283
	if (!r) {
777
		EC_POINT_free(t);
778
		return NULL;
779
	} else
780
1283
		return t;
781
1283
}
782
783
784
const EC_METHOD *
785
EC_POINT_method_of(const EC_POINT * point)
786
{
787
	return point->meth;
788
}
789
790
791
int
792
EC_POINT_set_to_infinity(const EC_GROUP * group, EC_POINT * point)
793
{
794
4128
	if (group->meth->point_set_to_infinity == 0) {
795
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
796
		return 0;
797
	}
798
2064
	if (group->meth != point->meth) {
799
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
800
		return 0;
801
	}
802
2064
	return group->meth->point_set_to_infinity(group, point);
803
2064
}
804
805
806
int
807
EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
808
    const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx)
809
{
810
7356
	if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
811
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
812
		return 0;
813
	}
814
3678
	if (group->meth != point->meth) {
815
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
816
		return 0;
817
	}
818
3678
	return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
819
3678
}
820
821
822
int
823
EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
824
    const EC_POINT *point, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx)
825
{
826
6
	if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
827
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
828
		return 0;
829
	}
830
3
	if (group->meth != point->meth) {
831
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
832
		return 0;
833
	}
834
3
	return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx);
835
3
}
836
837
838
int
839
EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
840
    const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
841
{
842
8378
	if (group->meth->point_set_affine_coordinates == 0) {
843
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
844
		return 0;
845
	}
846
4189
	if (group->meth != point->meth) {
847
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
848
		return 0;
849
	}
850
4189
	return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
851
4189
}
852
853
#ifndef OPENSSL_NO_EC2M
854
int
855
EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
856
    const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
857
{
858
70148
	if (group->meth->point_set_affine_coordinates == 0) {
859
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
860
		return 0;
861
	}
862
35074
	if (group->meth != point->meth) {
863
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
864
		return 0;
865
	}
866
35074
	return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
867
35074
}
868
#endif
869
870
int
871
EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
872
    BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
873
{
874
9578
	if (group->meth->point_get_affine_coordinates == 0) {
875
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
876
		return 0;
877
	}
878
4789
	if (group->meth != point->meth) {
879
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
880
		return 0;
881
	}
882
4789
	return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
883
4789
}
884
885
#ifndef OPENSSL_NO_EC2M
886
int
887
EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
888
    BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
889
{
890
3752
	if (group->meth->point_get_affine_coordinates == 0) {
891
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
892
		return 0;
893
	}
894
1876
	if (group->meth != point->meth) {
895
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
896
		return 0;
897
	}
898
1876
	return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
899
1876
}
900
#endif
901
902
int
903
EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
904
    const EC_POINT *b, BN_CTX *ctx)
905
{
906
588358
	if (group->meth->add == 0) {
907
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
908
		return 0;
909
	}
910

882537
	if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) {
911
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
912
		return 0;
913
	}
914
294179
	return group->meth->add(group, r, a, b, ctx);
915
294179
}
916
917
918
int
919
EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
920
{
921
2487866
	if (group->meth->dbl == 0) {
922
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
923
		return 0;
924
	}
925

2487866
	if ((group->meth != r->meth) || (r->meth != a->meth)) {
926
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
927
		return 0;
928
	}
929
1243933
	return group->meth->dbl(group, r, a, ctx);
930
1243933
}
931
932
933
int
934
EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
935
{
936
265190
	if (group->meth->invert == 0) {
937
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
938
		return 0;
939
	}
940
132595
	if (group->meth != a->meth) {
941
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
942
		return 0;
943
	}
944
132595
	return group->meth->invert(group, a, ctx);
945
132595
}
946
947
948
int
949
EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
950
{
951
4016106
	if (group->meth->is_at_infinity == 0) {
952
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
953
		return 0;
954
	}
955
2008053
	if (group->meth != point->meth) {
956
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
957
		return 0;
958
	}
959
2008053
	return group->meth->is_at_infinity(group, point);
960
2008053
}
961
962
963
int
964
EC_POINT_is_on_curve(const EC_GROUP * group, const EC_POINT * point, BN_CTX * ctx)
965
{
966
4720
	if (group->meth->is_on_curve == 0) {
967
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
968
		return 0;
969
	}
970
2360
	if (group->meth != point->meth) {
971
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
972
		return 0;
973
	}
974
2360
	return group->meth->is_on_curve(group, point, ctx);
975
2360
}
976
977
978
int
979
EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
980
    BN_CTX * ctx)
981
{
982
1172
	if (group->meth->point_cmp == 0) {
983
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
984
		return -1;
985
	}
986

1172
	if ((group->meth != a->meth) || (a->meth != b->meth)) {
987
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
988
		return -1;
989
	}
990
586
	return group->meth->point_cmp(group, a, b, ctx);
991
586
}
992
993
994
int
995
EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
996
{
997
2750
	if (group->meth->make_affine == 0) {
998
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
999
		return 0;
1000
	}
1001
1375
	if (group->meth != point->meth) {
1002
		ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1003
		return 0;
1004
	}
1005
1375
	return group->meth->make_affine(group, point, ctx);
1006
1375
}
1007
1008
1009
int
1010
EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1011
    BN_CTX *ctx)
1012
{
1013
	size_t i;
1014
1015
9326
	if (group->meth->points_make_affine == 0) {
1016
		ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1017
		return 0;
1018
	}
1019
88220
	for (i = 0; i < num; i++) {
1020
39447
		if (group->meth != points[i]->meth) {
1021
			ECerror(EC_R_INCOMPATIBLE_OBJECTS);
1022
			return 0;
1023
		}
1024
	}
1025
4663
	return group->meth->points_make_affine(group, num, points, ctx);
1026
4663
}
1027
1028
1029
/* Functions for point multiplication.
1030
 *
1031
 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
1032
 * otherwise we dispatch through methods.
1033
 */
1034
1035
int
1036
EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1037
    size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
1038
{
1039
12280
	if (group->meth->mul == 0)
1040
		/* use default */
1041
4552
		return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
1042
1043
1588
	return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
1044
6140
}
1045
1046
int
1047
EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1048
    const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
1049
{
1050
	/* just a convenient interface to EC_POINTs_mul() */
1051
1052
12232
	const EC_POINT *points[1];
1053
6116
	const BIGNUM *scalars[1];
1054
1055
6116
	points[0] = point;
1056
6116
	scalars[0] = p_scalar;
1057
1058
12232
	return EC_POINTs_mul(group, r, g_scalar,
1059
6116
	    (point != NULL && p_scalar != NULL),
1060
6116
	    points, scalars, ctx);
1061
6116
}
1062
1063
int
1064
EC_GROUP_precompute_mult(EC_GROUP * group, BN_CTX * ctx)
1065
{
1066
96
	if (group->meth->mul == 0)
1067
		/* use default */
1068
18
		return ec_wNAF_precompute_mult(group, ctx);
1069
1070
30
	if (group->meth->precompute_mult != 0)
1071
30
		return group->meth->precompute_mult(group, ctx);
1072
	else
1073
		return 1;	/* nothing to do, so report success */
1074
48
}
1075
1076
int
1077
EC_GROUP_have_precompute_mult(const EC_GROUP * group)
1078
{
1079
1540
	if (group->meth->mul == 0)
1080
		/* use default */
1081
		return ec_wNAF_have_precompute_mult(group);
1082
1083
770
	if (group->meth->have_precompute_mult != 0)
1084
770
		return group->meth->have_precompute_mult(group);
1085
	else
1086
		return 0;	/* cannot tell whether precomputation has
1087
				 * been performed */
1088
770
}
1089
1090
EC_KEY *
1091
ECParameters_dup(EC_KEY *key)
1092
{
1093
	unsigned char *p = NULL;
1094
	EC_KEY *k = NULL;
1095
	int len;
1096
1097
	if (key == NULL)
1098
		return (NULL);
1099
1100
	if ((len = i2d_ECParameters(key, &p)) > 0)
1101
		k = d2i_ECParameters(NULL, (const unsigned char **)&p, len);
1102
1103
	return (k);
1104
}