Coverage Report

Created: 2022-08-24 06:30

/src/libressl/crypto/ec/ec_key.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: ec_key.c,v 1.26 2021/04/20 17:23:37 tb Exp $ */
2
/*
3
 * Written by Nils Larsch for the OpenSSL project.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 1998-2005 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
 * Portions originally developed by SUN MICROSYSTEMS, INC., and
61
 * contributed to the OpenSSL project.
62
 */
63
64
#include <string.h>
65
66
#include <openssl/opensslconf.h>
67
68
#ifndef OPENSSL_NO_ENGINE
69
#include <openssl/engine.h>
70
#endif
71
#include <openssl/err.h>
72
73
#include "bn_lcl.h"
74
#include "ec_lcl.h"
75
76
EC_KEY *
77
EC_KEY_new(void)
78
5.60k
{
79
5.60k
  return EC_KEY_new_method(NULL);
80
5.60k
}
81
82
EC_KEY *
83
EC_KEY_new_by_curve_name(int nid)
84
809
{
85
809
  EC_KEY *ret = EC_KEY_new();
86
809
  if (ret == NULL)
87
0
    return NULL;
88
809
  ret->group = EC_GROUP_new_by_curve_name(nid);
89
809
  if (ret->group == NULL) {
90
0
    EC_KEY_free(ret);
91
0
    return NULL;
92
0
  }
93
809
  if (ret->meth->set_group != NULL &&
94
809
      ret->meth->set_group(ret, ret->group) == 0) {
95
0
    EC_KEY_free(ret);
96
0
    return NULL;
97
0
  }
98
809
  return ret;
99
809
}
100
101
void 
102
EC_KEY_free(EC_KEY * r)
103
5.64k
{
104
5.64k
  int i;
105
106
5.64k
  if (r == NULL)
107
34
    return;
108
109
5.60k
  i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC);
110
5.60k
  if (i > 0)
111
0
    return;
112
113
5.60k
  if (r->meth != NULL && r->meth->finish != NULL)
114
0
    r->meth->finish(r);
115
116
5.60k
#ifndef OPENSSL_NO_ENGINE
117
5.60k
  ENGINE_finish(r->engine);
118
5.60k
#endif
119
5.60k
  CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
120
121
5.60k
  EC_GROUP_free(r->group);
122
5.60k
  EC_POINT_free(r->pub_key);
123
5.60k
  BN_clear_free(r->priv_key);
124
125
5.60k
  EC_EX_DATA_free_all_data(&r->method_data);
126
127
5.60k
  freezero(r, sizeof(EC_KEY));
128
5.60k
}
129
130
EC_KEY *
131
EC_KEY_copy(EC_KEY * dest, const EC_KEY * src)
132
3.23k
{
133
3.23k
  EC_EXTRA_DATA *d;
134
135
3.23k
  if (dest == NULL || src == NULL) {
136
0
    ECerror(ERR_R_PASSED_NULL_PARAMETER);
137
0
    return NULL;
138
0
  }
139
3.23k
  if (src->meth != dest->meth) {
140
0
    if (dest->meth != NULL && dest->meth->finish != NULL)
141
0
      dest->meth->finish(dest);
142
0
#ifndef OPENSSL_NO_ENGINE
143
0
    if (ENGINE_finish(dest->engine) == 0)
144
0
      return 0;
145
0
    dest->engine = NULL;
146
0
#endif
147
0
  }
148
  /* copy the parameters */
149
3.23k
  if (src->group) {
150
1.91k
    const EC_METHOD *meth = EC_GROUP_method_of(src->group);
151
    /* clear the old group */
152
1.91k
    EC_GROUP_free(dest->group);
153
1.91k
    dest->group = EC_GROUP_new(meth);
154
1.91k
    if (dest->group == NULL)
155
0
      return NULL;
156
1.91k
    if (!EC_GROUP_copy(dest->group, src->group))
157
0
      return NULL;
158
1.91k
  }
159
  /* copy the public key */
160
3.23k
  if (src->pub_key && src->group) {
161
448
    EC_POINT_free(dest->pub_key);
162
448
    dest->pub_key = EC_POINT_new(src->group);
163
448
    if (dest->pub_key == NULL)
164
0
      return NULL;
165
448
    if (!EC_POINT_copy(dest->pub_key, src->pub_key))
166
0
      return NULL;
167
448
  }
168
  /* copy the private key */
169
3.23k
  if (src->priv_key) {
170
387
    if (dest->priv_key == NULL) {
171
387
      dest->priv_key = BN_new();
172
387
      if (dest->priv_key == NULL)
173
0
        return NULL;
174
387
    }
175
387
    if (!BN_copy(dest->priv_key, src->priv_key))
176
0
      return NULL;
177
387
  }
178
  /* copy method/extra data */
179
3.23k
  EC_EX_DATA_free_all_data(&dest->method_data);
180
181
3.23k
  for (d = src->method_data; d != NULL; d = d->next) {
182
0
    void *t = d->dup_func(d->data);
183
184
0
    if (t == NULL)
185
0
      return 0;
186
0
    if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func,
187
0
        d->free_func, d->clear_free_func))
188
0
      return 0;
189
0
  }
190
191
  /* copy the rest */
192
3.23k
  dest->enc_flag = src->enc_flag;
193
3.23k
  dest->conv_form = src->conv_form;
194
3.23k
  dest->version = src->version;
195
3.23k
  dest->flags = src->flags;
196
197
3.23k
  if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, &dest->ex_data,
198
3.23k
      &((EC_KEY *)src)->ex_data))  /* XXX const */
199
0
    return NULL;
200
201
3.23k
  if (src->meth != dest->meth) {
202
0
#ifndef OPENSSL_NO_ENGINE
203
0
    if (src->engine != NULL && ENGINE_init(src->engine) == 0)
204
0
      return 0;
205
0
    dest->engine = src->engine;
206
0
#endif
207
0
    dest->meth = src->meth;
208
0
  }
209
210
3.23k
  if (src->meth != NULL && src->meth->copy != NULL &&
211
3.23k
      src->meth->copy(dest, src) == 0)
212
0
    return 0;
213
214
3.23k
  return dest;
215
3.23k
}
216
217
EC_KEY *
218
EC_KEY_dup(const EC_KEY * ec_key)
219
0
{
220
0
  EC_KEY *ret;
221
222
0
  if ((ret = EC_KEY_new_method(ec_key->engine)) == NULL)
223
0
    return NULL;
224
0
  if (EC_KEY_copy(ret, ec_key) == NULL) {
225
0
    EC_KEY_free(ret);
226
0
    return NULL;
227
0
  }
228
0
  return ret;
229
0
}
230
231
int 
232
EC_KEY_up_ref(EC_KEY * r)
233
0
{
234
0
  int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
235
0
  return ((i > 1) ? 1 : 0);
236
0
}
237
238
int
239
EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg)
240
0
{
241
0
  return CRYPTO_set_ex_data(&r->ex_data, idx, arg);
242
0
}
243
244
void *
245
EC_KEY_get_ex_data(const EC_KEY *r, int idx)
246
0
{
247
0
  return CRYPTO_get_ex_data(&r->ex_data, idx);
248
0
}
249
250
int
251
EC_KEY_generate_key(EC_KEY *eckey)
252
809
{
253
809
  if (eckey->meth->keygen != NULL)
254
809
    return eckey->meth->keygen(eckey);
255
0
  ECerror(EC_R_NOT_IMPLEMENTED);
256
0
  return 0;
257
809
}
258
259
int
260
ossl_ec_key_gen(EC_KEY *eckey)
261
809
{
262
809
  int ok = 0;
263
809
  BN_CTX *ctx = NULL;
264
809
  BIGNUM *priv_key = NULL, *order = NULL;
265
809
  EC_POINT *pub_key = NULL;
266
267
809
  if (!eckey || !eckey->group) {
268
0
    ECerror(ERR_R_PASSED_NULL_PARAMETER);
269
0
    return 0;
270
0
  }
271
272
809
  if ((order = BN_new()) == NULL)
273
0
    goto err;
274
809
  if ((ctx = BN_CTX_new()) == NULL)
275
0
    goto err;
276
277
809
  if ((priv_key = eckey->priv_key) == NULL) {
278
809
    if ((priv_key = BN_new()) == NULL)
279
0
      goto err;
280
809
  }
281
282
809
  if (!EC_GROUP_get_order(eckey->group, order, ctx))
283
0
    goto err;
284
285
809
  if (!bn_rand_interval(priv_key, BN_value_one(), order))
286
0
    goto err;
287
288
809
  if ((pub_key = eckey->pub_key) == NULL) {
289
809
    if ((pub_key = EC_POINT_new(eckey->group)) == NULL)
290
0
      goto err;
291
809
  }
292
293
809
  if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
294
0
    goto err;
295
296
809
  eckey->priv_key = priv_key;
297
809
  eckey->pub_key = pub_key;
298
299
809
  ok = 1;
300
301
809
 err:
302
809
  BN_free(order);
303
809
  if (eckey->pub_key == NULL)
304
0
    EC_POINT_free(pub_key);
305
809
  if (eckey->priv_key == NULL)
306
0
    BN_free(priv_key);
307
809
  BN_CTX_free(ctx);
308
809
  return (ok);
309
809
}
310
311
int 
312
EC_KEY_check_key(const EC_KEY * eckey)
313
0
{
314
0
  int ok = 0;
315
0
  BN_CTX *ctx = NULL;
316
0
  const BIGNUM *order = NULL;
317
0
  EC_POINT *point = NULL;
318
319
0
  if (!eckey || !eckey->group || !eckey->pub_key) {
320
0
    ECerror(ERR_R_PASSED_NULL_PARAMETER);
321
0
    return 0;
322
0
  }
323
0
  if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key) > 0) {
324
0
    ECerror(EC_R_POINT_AT_INFINITY);
325
0
    goto err;
326
0
  }
327
0
  if ((ctx = BN_CTX_new()) == NULL)
328
0
    goto err;
329
0
  if ((point = EC_POINT_new(eckey->group)) == NULL)
330
0
    goto err;
331
332
  /* testing whether the pub_key is on the elliptic curve */
333
0
  if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
334
0
    ECerror(EC_R_POINT_IS_NOT_ON_CURVE);
335
0
    goto err;
336
0
  }
337
  /* testing whether pub_key * order is the point at infinity */
338
0
  order = &eckey->group->order;
339
0
  if (BN_is_zero(order)) {
340
0
    ECerror(EC_R_INVALID_GROUP_ORDER);
341
0
    goto err;
342
0
  }
343
0
  if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
344
0
    ECerror(ERR_R_EC_LIB);
345
0
    goto err;
346
0
  }
347
0
  if (EC_POINT_is_at_infinity(eckey->group, point) <= 0) {
348
0
    ECerror(EC_R_WRONG_ORDER);
349
0
    goto err;
350
0
  }
351
  /*
352
   * in case the priv_key is present : check if generator * priv_key ==
353
   * pub_key
354
   */
355
0
  if (eckey->priv_key) {
356
0
    if (BN_cmp(eckey->priv_key, order) >= 0) {
357
0
      ECerror(EC_R_WRONG_ORDER);
358
0
      goto err;
359
0
    }
360
0
    if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
361
0
      NULL, NULL, ctx)) {
362
0
      ECerror(ERR_R_EC_LIB);
363
0
      goto err;
364
0
    }
365
0
    if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
366
0
      ctx) != 0) {
367
0
      ECerror(EC_R_INVALID_PRIVATE_KEY);
368
0
      goto err;
369
0
    }
370
0
  }
371
0
  ok = 1;
372
0
 err:
373
0
  BN_CTX_free(ctx);
374
0
  EC_POINT_free(point);
375
0
  return (ok);
376
0
}
377
378
int 
379
EC_KEY_set_public_key_affine_coordinates(EC_KEY * key, BIGNUM * x, BIGNUM * y)
380
0
{
381
0
  BN_CTX *ctx = NULL;
382
0
  BIGNUM *tx, *ty;
383
0
  EC_POINT *point = NULL;
384
0
  int ok = 0;
385
386
0
  if (!key || !key->group || !x || !y) {
387
0
    ECerror(ERR_R_PASSED_NULL_PARAMETER);
388
0
    return 0;
389
0
  }
390
0
  ctx = BN_CTX_new();
391
0
  if (!ctx)
392
0
    goto err;
393
394
0
  point = EC_POINT_new(key->group);
395
396
0
  if (!point)
397
0
    goto err;
398
399
0
  if ((tx = BN_CTX_get(ctx)) == NULL)
400
0
    goto err;
401
0
  if ((ty = BN_CTX_get(ctx)) == NULL)
402
0
    goto err;
403
404
0
  if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx))
405
0
    goto err;
406
0
  if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx))
407
0
    goto err;
408
  /*
409
   * Check if retrieved coordinates match originals: if not values are
410
   * out of range.
411
   */
412
0
  if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
413
0
    ECerror(EC_R_COORDINATES_OUT_OF_RANGE);
414
0
    goto err;
415
0
  }
416
0
  if (!EC_KEY_set_public_key(key, point))
417
0
    goto err;
418
419
0
  if (EC_KEY_check_key(key) == 0)
420
0
    goto err;
421
422
0
  ok = 1;
423
424
0
 err:
425
0
  BN_CTX_free(ctx);
426
0
  EC_POINT_free(point);
427
0
  return ok;
428
429
0
}
430
431
const EC_GROUP *
432
EC_KEY_get0_group(const EC_KEY * key)
433
1.24k
{
434
1.24k
  return key->group;
435
1.24k
}
436
437
int 
438
EC_KEY_set_group(EC_KEY * key, const EC_GROUP * group)
439
1.47k
{
440
1.47k
  if (key->meth->set_group != NULL &&
441
1.47k
      key->meth->set_group(key, group) == 0)
442
0
    return 0;
443
1.47k
  EC_GROUP_free(key->group);
444
1.47k
  key->group = EC_GROUP_dup(group);
445
1.47k
  return (key->group == NULL) ? 0 : 1;
446
1.47k
}
447
448
const BIGNUM *
449
EC_KEY_get0_private_key(const EC_KEY * key)
450
1.20k
{
451
1.20k
  return key->priv_key;
452
1.20k
}
453
454
int 
455
EC_KEY_set_private_key(EC_KEY * key, const BIGNUM * priv_key)
456
688
{
457
688
  if (key->meth->set_private != NULL &&
458
688
      key->meth->set_private(key, priv_key) == 0)
459
0
    return 0;
460
688
  BN_clear_free(key->priv_key);
461
688
  key->priv_key = BN_dup(priv_key);
462
688
  return (key->priv_key == NULL) ? 0 : 1;
463
688
}
464
465
const EC_POINT *
466
EC_KEY_get0_public_key(const EC_KEY * key)
467
463
{
468
463
  return key->pub_key;
469
463
}
470
471
int 
472
EC_KEY_set_public_key(EC_KEY * key, const EC_POINT * pub_key)
473
504
{
474
504
  if (key->meth->set_public != NULL &&
475
504
      key->meth->set_public(key, pub_key) == 0)
476
0
    return 0;
477
504
  EC_POINT_free(key->pub_key);
478
504
  key->pub_key = EC_POINT_dup(pub_key, key->group);
479
504
  return (key->pub_key == NULL) ? 0 : 1;
480
504
}
481
482
unsigned int 
483
EC_KEY_get_enc_flags(const EC_KEY * key)
484
0
{
485
0
  return key->enc_flag;
486
0
}
487
488
void 
489
EC_KEY_set_enc_flags(EC_KEY * key, unsigned int flags)
490
0
{
491
0
  key->enc_flag = flags;
492
0
}
493
494
point_conversion_form_t 
495
EC_KEY_get_conv_form(const EC_KEY * key)
496
0
{
497
0
  return key->conv_form;
498
0
}
499
500
void 
501
EC_KEY_set_conv_form(EC_KEY * key, point_conversion_form_t cform)
502
0
{
503
0
  key->conv_form = cform;
504
0
  if (key->group != NULL)
505
0
    EC_GROUP_set_point_conversion_form(key->group, cform);
506
0
}
507
508
void *
509
EC_KEY_get_key_method_data(EC_KEY *key,
510
    void *(*dup_func) (void *),
511
    void (*free_func) (void *),
512
    void (*clear_free_func) (void *))
513
1.63k
{
514
1.63k
  void *ret;
515
516
1.63k
  CRYPTO_r_lock(CRYPTO_LOCK_EC);
517
1.63k
  ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
518
1.63k
  CRYPTO_r_unlock(CRYPTO_LOCK_EC);
519
520
1.63k
  return ret;
521
1.63k
}
522
523
void *
524
EC_KEY_insert_key_method_data(EC_KEY * key, void *data,
525
    void *(*dup_func) (void *),
526
    void (*free_func) (void *),
527
    void (*clear_free_func) (void *))
528
855
{
529
855
  EC_EXTRA_DATA *ex_data;
530
531
855
  CRYPTO_w_lock(CRYPTO_LOCK_EC);
532
855
  ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
533
855
  if (ex_data == NULL)
534
855
    EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
535
855
  CRYPTO_w_unlock(CRYPTO_LOCK_EC);
536
537
855
  return ex_data;
538
855
}
539
540
void 
541
EC_KEY_set_asn1_flag(EC_KEY * key, int flag)
542
0
{
543
0
  if (key->group != NULL)
544
0
    EC_GROUP_set_asn1_flag(key->group, flag);
545
0
}
546
547
int 
548
EC_KEY_precompute_mult(EC_KEY * key, BN_CTX * ctx)
549
0
{
550
0
  if (key->group == NULL)
551
0
    return 0;
552
0
  return EC_GROUP_precompute_mult(key->group, ctx);
553
0
}
554
555
int 
556
EC_KEY_get_flags(const EC_KEY * key)
557
0
{
558
0
  return key->flags;
559
0
}
560
561
void 
562
EC_KEY_set_flags(EC_KEY * key, int flags)
563
0
{
564
0
  key->flags |= flags;
565
0
}
566
567
void 
568
EC_KEY_clear_flags(EC_KEY * key, int flags)
569
0
{
570
0
  key->flags &= ~flags;
571
0
}