Coverage Report

Created: 2022-08-24 06:30

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