VirtualBox

source: vbox/trunk/src/libs/openssl-3.1.5/crypto/ec/ec_key.c@ 104285

Last change on this file since 104285 was 104078, checked in by vboxsync, 11 months ago

openssl-3.1.5: Applied and adjusted our OpenSSL changes to 3.1.4. bugref:10638

File size: 29.5 KB
Line 
1/*
2 * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4 *
5 * Licensed under the Apache License 2.0 (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/*
12 * EC_KEY low level APIs are deprecated for public use, but still ok for
13 * internal use.
14 */
15#include "internal/deprecated.h"
16
17#include "internal/cryptlib.h"
18#include <string.h>
19#include "ec_local.h"
20#include "internal/refcount.h"
21#include <openssl/err.h>
22#ifndef FIPS_MODULE
23# include <openssl/engine.h>
24#endif
25#include <openssl/self_test.h>
26#include "prov/providercommon.h"
27#include "crypto/bn.h"
28
29static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
30 void *cbarg);
31
32#ifndef FIPS_MODULE
33EC_KEY *EC_KEY_new(void)
34{
35 return ossl_ec_key_new_method_int(NULL, NULL, NULL);
36}
37#endif
38
39EC_KEY *EC_KEY_new_ex(OSSL_LIB_CTX *ctx, const char *propq)
40{
41 return ossl_ec_key_new_method_int(ctx, propq, NULL);
42}
43
44EC_KEY *EC_KEY_new_by_curve_name_ex(OSSL_LIB_CTX *ctx, const char *propq,
45 int nid)
46{
47 EC_KEY *ret = EC_KEY_new_ex(ctx, propq);
48 if (ret == NULL)
49 return NULL;
50 ret->group = EC_GROUP_new_by_curve_name_ex(ctx, propq, nid);
51 if (ret->group == NULL) {
52 EC_KEY_free(ret);
53 return NULL;
54 }
55 if (ret->meth->set_group != NULL
56 && ret->meth->set_group(ret, ret->group) == 0) {
57 EC_KEY_free(ret);
58 return NULL;
59 }
60 return ret;
61}
62
63#ifndef FIPS_MODULE
64EC_KEY *EC_KEY_new_by_curve_name(int nid)
65{
66 return EC_KEY_new_by_curve_name_ex(NULL, NULL, nid);
67}
68#endif
69
70void EC_KEY_free(EC_KEY *r)
71{
72 int i;
73
74 if (r == NULL)
75 return;
76
77 CRYPTO_DOWN_REF(&r->references, &i, r->lock);
78 REF_PRINT_COUNT("EC_KEY", r);
79 if (i > 0)
80 return;
81 REF_ASSERT_ISNT(i < 0);
82
83 if (r->meth != NULL && r->meth->finish != NULL)
84 r->meth->finish(r);
85
86#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
87 ENGINE_finish(r->engine);
88#endif
89
90 if (r->group && r->group->meth->keyfinish)
91 r->group->meth->keyfinish(r);
92
93#ifndef FIPS_MODULE
94 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
95#endif
96 CRYPTO_THREAD_lock_free(r->lock);
97 EC_GROUP_free(r->group);
98 EC_POINT_free(r->pub_key);
99 BN_clear_free(r->priv_key);
100 OPENSSL_free(r->propq);
101
102 OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
103}
104
105EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
106{
107 if (dest == NULL || src == NULL) {
108 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
109 return NULL;
110 }
111 if (src->meth != dest->meth) {
112 if (dest->meth->finish != NULL)
113 dest->meth->finish(dest);
114 if (dest->group && dest->group->meth->keyfinish)
115 dest->group->meth->keyfinish(dest);
116#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
117 if (ENGINE_finish(dest->engine) == 0)
118 return 0;
119 dest->engine = NULL;
120#endif
121 }
122 dest->libctx = src->libctx;
123 /* copy the parameters */
124 if (src->group != NULL) {
125 /* clear the old group */
126 EC_GROUP_free(dest->group);
127 dest->group = ossl_ec_group_new_ex(src->libctx, src->propq,
128 src->group->meth);
129 if (dest->group == NULL)
130 return NULL;
131 if (!EC_GROUP_copy(dest->group, src->group))
132 return NULL;
133
134 /* copy the public key */
135 if (src->pub_key != NULL) {
136 EC_POINT_free(dest->pub_key);
137 dest->pub_key = EC_POINT_new(src->group);
138 if (dest->pub_key == NULL)
139 return NULL;
140 if (!EC_POINT_copy(dest->pub_key, src->pub_key))
141 return NULL;
142 }
143 /* copy the private key */
144 if (src->priv_key != NULL) {
145 if (dest->priv_key == NULL) {
146 dest->priv_key = BN_new();
147 if (dest->priv_key == NULL)
148 return NULL;
149 }
150 if (!BN_copy(dest->priv_key, src->priv_key))
151 return NULL;
152 if (src->group->meth->keycopy
153 && src->group->meth->keycopy(dest, src) == 0)
154 return NULL;
155 }
156 }
157
158
159 /* copy the rest */
160 dest->enc_flag = src->enc_flag;
161 dest->conv_form = src->conv_form;
162 dest->version = src->version;
163 dest->flags = src->flags;
164#ifndef FIPS_MODULE
165 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
166 &dest->ex_data, &src->ex_data))
167 return NULL;
168#endif
169
170 if (src->meth != dest->meth) {
171#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
172 if (src->engine != NULL && ENGINE_init(src->engine) == 0)
173 return NULL;
174 dest->engine = src->engine;
175#endif
176 dest->meth = src->meth;
177 }
178
179 if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
180 return NULL;
181
182 dest->dirty_cnt++;
183
184 return dest;
185}
186
187EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
188{
189 return ossl_ec_key_dup(ec_key, OSSL_KEYMGMT_SELECT_ALL);
190}
191
192int EC_KEY_up_ref(EC_KEY *r)
193{
194 int i;
195
196 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
197 return 0;
198
199 REF_PRINT_COUNT("EC_KEY", r);
200 REF_ASSERT_ISNT(i < 2);
201 return ((i > 1) ? 1 : 0);
202}
203
204ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey)
205{
206 return eckey->engine;
207}
208
209int EC_KEY_generate_key(EC_KEY *eckey)
210{
211 if (eckey == NULL || eckey->group == NULL) {
212 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
213 return 0;
214 }
215 if (eckey->meth->keygen != NULL) {
216 int ret;
217
218 ret = eckey->meth->keygen(eckey);
219 if (ret == 1)
220 eckey->dirty_cnt++;
221
222 return ret;
223 }
224 ERR_raise(ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED);
225 return 0;
226}
227
228int ossl_ec_key_gen(EC_KEY *eckey)
229{
230 int ret;
231
232 ret = eckey->group->meth->keygen(eckey);
233
234 if (ret == 1)
235 eckey->dirty_cnt++;
236 return ret;
237}
238
239/*
240 * Refer: FIPS 140-3 IG 10.3.A Additional Comment 1
241 * Perform a KAT by duplicating the public key generation.
242 *
243 * NOTE: This issue requires a background understanding, provided in a separate
244 * document; the current IG 10.3.A AC1 is insufficient regarding the PCT for
245 * the key agreement scenario.
246 *
247 * Currently IG 10.3.A requires PCT in the mode of use prior to use of the
248 * key pair, citing the PCT defined in the associated standard. For key
249 * agreement, the only PCT defined in SP 800-56A is that of Section 5.6.2.4:
250 * the comparison of the original public key to a newly calculated public key.
251 */
252static int ecdsa_keygen_knownanswer_test(EC_KEY *eckey, BN_CTX *ctx,
253 OSSL_CALLBACK *cb, void *cbarg)
254{
255 int len, ret = 0;
256 OSSL_SELF_TEST *st = NULL;
257 unsigned char bytes[512] = {0};
258 EC_POINT *pub_key2 = EC_POINT_new(eckey->group);
259
260 if (pub_key2 == NULL)
261 return 0;
262
263 st = OSSL_SELF_TEST_new(cb, cbarg);
264 if (st == NULL)
265 return 0;
266
267 OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT_KAT,
268 OSSL_SELF_TEST_DESC_PCT_ECDSA);
269
270 /* pub_key = priv_key * G (where G is a point on the curve) */
271 if (!EC_POINT_mul(eckey->group, pub_key2, eckey->priv_key, NULL, NULL, ctx))
272 goto err;
273
274 if (BN_num_bytes(pub_key2->X) > (int)sizeof(bytes))
275 goto err;
276 len = BN_bn2bin(pub_key2->X, bytes);
277 if (OSSL_SELF_TEST_oncorrupt_byte(st, bytes)
278 && BN_bin2bn(bytes, len, pub_key2->X) == NULL)
279 goto err;
280 ret = !EC_POINT_cmp(eckey->group, eckey->pub_key, pub_key2, ctx);
281
282err:
283 OSSL_SELF_TEST_onend(st, ret);
284 OSSL_SELF_TEST_free(st);
285 EC_POINT_free(pub_key2);
286 return ret;
287}
288
289/*
290 * ECC Key generation.
291 * See SP800-56AR3 5.6.1.2.2 "Key Pair Generation by Testing Candidates"
292 *
293 * Params:
294 * libctx A context containing an optional self test callback.
295 * eckey An EC key object that contains domain params. The generated keypair
296 * is stored in this object.
297 * pairwise_test Set to non zero to perform a pairwise test. If the test
298 * fails then the keypair is not generated,
299 * Returns 1 if the keypair was generated or 0 otherwise.
300 */
301static int ec_generate_key(EC_KEY *eckey, int pairwise_test)
302{
303 int ok = 0;
304 BIGNUM *priv_key = NULL;
305 const BIGNUM *tmp = NULL;
306 BIGNUM *order = NULL;
307 EC_POINT *pub_key = NULL;
308 const EC_GROUP *group = eckey->group;
309 BN_CTX *ctx = BN_CTX_secure_new_ex(eckey->libctx);
310 int sm2 = EC_KEY_get_flags(eckey) & EC_FLAG_SM2_RANGE ? 1 : 0;
311
312 if (ctx == NULL)
313 goto err;
314
315 if (eckey->priv_key == NULL) {
316 priv_key = BN_secure_new();
317 if (priv_key == NULL)
318 goto err;
319 } else
320 priv_key = eckey->priv_key;
321
322 /*
323 * Steps (1-2): Check domain parameters and security strength.
324 * These steps must be done by the user. This would need to be
325 * stated in the security policy.
326 */
327
328 tmp = EC_GROUP_get0_order(group);
329 if (tmp == NULL)
330 goto err;
331
332 /*
333 * Steps (3-7): priv_key = DRBG_RAND(order_n_bits) (range [1, n-1]).
334 * Although this is slightly different from the standard, it is effectively
335 * equivalent as it gives an unbiased result ranging from 1..n-1. It is also
336 * faster as the standard needs to retry more often. Also doing
337 * 1 + rand[0..n-2] would effect the way that tests feed dummy entropy into
338 * rand so the simpler backward compatible method has been used here.
339 */
340
341 /* range of SM2 private key is [1, n-1) */
342 if (sm2) {
343 order = BN_new();
344 if (order == NULL || !BN_sub(order, tmp, BN_value_one()))
345 goto err;
346 } else {
347 order = BN_dup(tmp);
348 if (order == NULL)
349 goto err;
350 }
351
352 do
353 if (!BN_priv_rand_range_ex(priv_key, order, 0, ctx))
354 goto err;
355 while (BN_is_zero(priv_key)) ;
356
357 if (eckey->pub_key == NULL) {
358 pub_key = EC_POINT_new(group);
359 if (pub_key == NULL)
360 goto err;
361 } else
362 pub_key = eckey->pub_key;
363
364 /* Step (8) : pub_key = priv_key * G (where G is a point on the curve) */
365 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
366 goto err;
367
368 eckey->priv_key = priv_key;
369 eckey->pub_key = pub_key;
370 priv_key = NULL;
371 pub_key = NULL;
372
373 eckey->dirty_cnt++;
374
375#ifdef FIPS_MODULE
376 pairwise_test = 1;
377#endif /* FIPS_MODULE */
378
379 ok = 1;
380 if (pairwise_test) {
381 OSSL_CALLBACK *cb = NULL;
382 void *cbarg = NULL;
383
384 OSSL_SELF_TEST_get_callback(eckey->libctx, &cb, &cbarg);
385 ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg)
386 && ecdsa_keygen_knownanswer_test(eckey, ctx, cb, cbarg);
387 }
388err:
389 /* Step (9): If there is an error return an invalid keypair. */
390 if (!ok) {
391 ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
392 BN_clear(eckey->priv_key);
393 if (eckey->pub_key != NULL)
394 EC_POINT_set_to_infinity(group, eckey->pub_key);
395 }
396
397 EC_POINT_free(pub_key);
398 BN_clear_free(priv_key);
399 BN_CTX_free(ctx);
400 BN_free(order);
401 return ok;
402}
403
404int ossl_ec_key_simple_generate_key(EC_KEY *eckey)
405{
406 return ec_generate_key(eckey, 0);
407}
408
409int ossl_ec_key_simple_generate_public_key(EC_KEY *eckey)
410{
411 int ret;
412 BN_CTX *ctx = BN_CTX_new_ex(eckey->libctx);
413
414 if (ctx == NULL)
415 return 0;
416
417 /*
418 * See SP800-56AR3 5.6.1.2.2: Step (8)
419 * pub_key = priv_key * G (where G is a point on the curve)
420 */
421 ret = EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
422 NULL, ctx);
423
424 BN_CTX_free(ctx);
425 if (ret == 1)
426 eckey->dirty_cnt++;
427
428 return ret;
429}
430
431int EC_KEY_check_key(const EC_KEY *eckey)
432{
433 if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
434 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
435 return 0;
436 }
437
438 if (eckey->group->meth->keycheck == NULL) {
439 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
440 return 0;
441 }
442
443 return eckey->group->meth->keycheck(eckey);
444}
445
446/*
447 * Check the range of the EC public key.
448 * See SP800-56A R3 Section 5.6.2.3.3 (Part 2)
449 * i.e.
450 * - If q = odd prime p: Verify that xQ and yQ are integers in the
451 * interval[0, p - 1], OR
452 * - If q = 2m: Verify that xQ and yQ are bit strings of length m bits.
453 * Returns 1 if the public key has a valid range, otherwise it returns 0.
454 */
455static int ec_key_public_range_check(BN_CTX *ctx, const EC_KEY *key)
456{
457 int ret = 0;
458 BIGNUM *x, *y;
459
460 BN_CTX_start(ctx);
461 x = BN_CTX_get(ctx);
462 y = BN_CTX_get(ctx);
463 if (y == NULL)
464 goto err;
465
466 if (!EC_POINT_get_affine_coordinates(key->group, key->pub_key, x, y, ctx))
467 goto err;
468
469 if (EC_GROUP_get_field_type(key->group) == NID_X9_62_prime_field) {
470 if (BN_is_negative(x)
471 || BN_cmp(x, key->group->field) >= 0
472 || BN_is_negative(y)
473 || BN_cmp(y, key->group->field) >= 0) {
474 goto err;
475 }
476 } else {
477 int m = EC_GROUP_get_degree(key->group);
478 if (BN_num_bits(x) > m || BN_num_bits(y) > m) {
479 goto err;
480 }
481 }
482 ret = 1;
483err:
484 BN_CTX_end(ctx);
485 return ret;
486}
487
488/*
489 * ECC Partial Public-Key Validation as specified in SP800-56A R3
490 * Section 5.6.2.3.4 ECC Partial Public-Key Validation Routine.
491 */
492int ossl_ec_key_public_check_quick(const EC_KEY *eckey, BN_CTX *ctx)
493{
494 if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
495 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
496 return 0;
497 }
498
499 /* 5.6.2.3.3 (Step 1): Q != infinity */
500 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
501 ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
502 return 0;
503 }
504
505 /* 5.6.2.3.3 (Step 2) Test if the public key is in range */
506 if (!ec_key_public_range_check(ctx, eckey)) {
507 ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
508 return 0;
509 }
510
511 /* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */
512 if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
513 ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE);
514 return 0;
515 }
516 return 1;
517}
518
519/*
520 * ECC Key validation as specified in SP800-56A R3.
521 * Section 5.6.2.3.3 ECC Full Public-Key Validation Routine.
522 */
523int ossl_ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx)
524{
525 int ret = 0;
526 EC_POINT *point = NULL;
527 const BIGNUM *order = NULL;
528
529 if (!ossl_ec_key_public_check_quick(eckey, ctx))
530 return 0;
531
532 point = EC_POINT_new(eckey->group);
533 if (point == NULL)
534 return 0;
535
536 order = eckey->group->order;
537 if (BN_is_zero(order)) {
538 ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER);
539 goto err;
540 }
541 /* 5.6.2.3.3 (Step 4) : pub_key * order is the point at infinity. */
542 if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
543 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
544 goto err;
545 }
546 if (!EC_POINT_is_at_infinity(eckey->group, point)) {
547 ERR_raise(ERR_LIB_EC, EC_R_WRONG_ORDER);
548 goto err;
549 }
550 ret = 1;
551err:
552 EC_POINT_free(point);
553 return ret;
554}
555
556/*
557 * ECC Key validation as specified in SP800-56A R3.
558 * Section 5.6.2.1.2 Owner Assurance of Private-Key Validity
559 * The private key is in the range [1, order-1]
560 */
561int ossl_ec_key_private_check(const EC_KEY *eckey)
562{
563 if (eckey == NULL || eckey->group == NULL || eckey->priv_key == NULL) {
564 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
565 return 0;
566 }
567 if (BN_cmp(eckey->priv_key, BN_value_one()) < 0
568 || BN_cmp(eckey->priv_key, eckey->group->order) >= 0) {
569 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
570 return 0;
571 }
572 return 1;
573}
574
575/*
576 * ECC Key validation as specified in SP800-56A R3.
577 * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency (b)
578 * Check if generator * priv_key = pub_key
579 */
580int ossl_ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx)
581{
582 int ret = 0;
583 EC_POINT *point = NULL;
584
585 if (eckey == NULL
586 || eckey->group == NULL
587 || eckey->pub_key == NULL
588 || eckey->priv_key == NULL) {
589 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
590 return 0;
591 }
592
593 point = EC_POINT_new(eckey->group);
594 if (point == NULL)
595 goto err;
596
597
598 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
599 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
600 goto err;
601 }
602 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
603 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
604 goto err;
605 }
606 ret = 1;
607err:
608 EC_POINT_free(point);
609 return ret;
610}
611
612
613/*
614 * ECC Key validation as specified in SP800-56A R3.
615 * Section 5.6.2.3.3 ECC Full Public-Key Validation
616 * Section 5.6.2.1.2 Owner Assurance of Private-Key Validity
617 * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency
618 * NOTES:
619 * Before calling this method in fips mode, there should be an assurance that
620 * an approved elliptic-curve group is used.
621 * Returns 1 if the key is valid, otherwise it returns 0.
622 */
623int ossl_ec_key_simple_check_key(const EC_KEY *eckey)
624{
625 int ok = 0;
626 BN_CTX *ctx = NULL;
627
628 if (eckey == NULL) {
629 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
630 return 0;
631 }
632 if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL)
633 return 0;
634
635 if (!ossl_ec_key_public_check(eckey, ctx))
636 goto err;
637
638 if (eckey->priv_key != NULL) {
639 if (!ossl_ec_key_private_check(eckey)
640 || !ossl_ec_key_pairwise_check(eckey, ctx))
641 goto err;
642 }
643 ok = 1;
644err:
645 BN_CTX_free(ctx);
646 return ok;
647}
648
649int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
650 BIGNUM *y)
651{
652 BN_CTX *ctx = NULL;
653 BIGNUM *tx, *ty;
654 EC_POINT *point = NULL;
655 int ok = 0;
656
657 if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
658 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
659 return 0;
660 }
661 ctx = BN_CTX_new_ex(key->libctx);
662 if (ctx == NULL)
663 return 0;
664
665 BN_CTX_start(ctx);
666 point = EC_POINT_new(key->group);
667
668 if (point == NULL)
669 goto err;
670
671 tx = BN_CTX_get(ctx);
672 ty = BN_CTX_get(ctx);
673 if (ty == NULL)
674 goto err;
675
676 if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx))
677 goto err;
678 if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx))
679 goto err;
680
681 /*
682 * Check if retrieved coordinates match originals. The range check is done
683 * inside EC_KEY_check_key().
684 */
685 if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
686 ERR_raise(ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE);
687 goto err;
688 }
689
690 /* EC_KEY_set_public_key updates dirty_cnt */
691 if (!EC_KEY_set_public_key(key, point))
692 goto err;
693
694 if (EC_KEY_check_key(key) == 0)
695 goto err;
696
697 ok = 1;
698
699 err:
700 BN_CTX_end(ctx);
701 BN_CTX_free(ctx);
702 EC_POINT_free(point);
703 return ok;
704
705}
706
707OSSL_LIB_CTX *ossl_ec_key_get_libctx(const EC_KEY *key)
708{
709 return key->libctx;
710}
711
712const char *ossl_ec_key_get0_propq(const EC_KEY *key)
713{
714 return key->propq;
715}
716
717void ossl_ec_key_set0_libctx(EC_KEY *key, OSSL_LIB_CTX *libctx)
718{
719 key->libctx = libctx;
720 /* Do we need to propagate this to the group? */
721}
722
723const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
724{
725 return key->group;
726}
727
728int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
729{
730 if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0)
731 return 0;
732 EC_GROUP_free(key->group);
733 key->group = EC_GROUP_dup(group);
734 if (key->group != NULL && EC_GROUP_get_curve_name(key->group) == NID_sm2)
735 EC_KEY_set_flags(key, EC_FLAG_SM2_RANGE);
736
737 key->dirty_cnt++;
738 return (key->group == NULL) ? 0 : 1;
739}
740
741const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
742{
743 return key->priv_key;
744}
745
746int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
747{
748 int fixed_top;
749 const BIGNUM *order = NULL;
750 BIGNUM *tmp_key = NULL;
751
752 if (key->group == NULL || key->group->meth == NULL)
753 return 0;
754
755 /*
756 * Not only should key->group be set, but it should also be in a valid
757 * fully initialized state.
758 *
759 * Specifically, to operate in constant time, we need that the group order
760 * is set, as we use its length as the fixed public size of any scalar used
761 * as an EC private key.
762 */
763 order = EC_GROUP_get0_order(key->group);
764 if (order == NULL || BN_is_zero(order))
765 return 0; /* This should never happen */
766
767 if (key->group->meth->set_private != NULL
768 && key->group->meth->set_private(key, priv_key) == 0)
769 return 0;
770 if (key->meth->set_private != NULL
771 && key->meth->set_private(key, priv_key) == 0)
772 return 0;
773
774 /*
775 * Return `0` to comply with legacy behavior for this function, see
776 * https://github.com/openssl/openssl/issues/18744#issuecomment-1195175696
777 */
778 if (priv_key == NULL) {
779 BN_clear_free(key->priv_key);
780 key->priv_key = NULL;
781 return 0; /* intentional for legacy compatibility */
782 }
783
784 /*
785 * We should never leak the bit length of the secret scalar in the key,
786 * so we always set the `BN_FLG_CONSTTIME` flag on the internal `BIGNUM`
787 * holding the secret scalar.
788 *
789 * This is important also because `BN_dup()` (and `BN_copy()`) do not
790 * propagate the `BN_FLG_CONSTTIME` flag from the source `BIGNUM`, and
791 * this brings an extra risk of inadvertently losing the flag, even when
792 * the caller specifically set it.
793 *
794 * The propagation has been turned on and off a few times in the past
795 * years because in some conditions has shown unintended consequences in
796 * some code paths, so at the moment we can't fix this in the BN layer.
797 *
798 * In `EC_KEY_set_private_key()` we can work around the propagation by
799 * manually setting the flag after `BN_dup()` as we know for sure that
800 * inside the EC module the `BN_FLG_CONSTTIME` is always treated
801 * correctly and should not generate unintended consequences.
802 *
803 * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
804 * to preallocate the BIGNUM internal buffer to a fixed public size big
805 * enough that operations performed during the processing never trigger
806 * a realloc which would leak the size of the scalar through memory
807 * accesses.
808 *
809 * Fixed Length
810 * ------------
811 *
812 * The order of the large prime subgroup of the curve is our choice for
813 * a fixed public size, as that is generally the upper bound for
814 * generating a private key in EC cryptosystems and should fit all valid
815 * secret scalars.
816 *
817 * For preallocating the BIGNUM storage we look at the number of "words"
818 * required for the internal representation of the order, and we
819 * preallocate 2 extra "words" in case any of the subsequent processing
820 * might temporarily overflow the order length.
821 */
822 tmp_key = BN_dup(priv_key);
823 if (tmp_key == NULL)
824 return 0;
825
826 BN_set_flags(tmp_key, BN_FLG_CONSTTIME);
827
828 fixed_top = bn_get_top(order) + 2;
829 if (bn_wexpand(tmp_key, fixed_top) == NULL) {
830 BN_clear_free(tmp_key);
831 return 0;
832 }
833
834 BN_clear_free(key->priv_key);
835 key->priv_key = tmp_key;
836 key->dirty_cnt++;
837
838 return 1;
839}
840
841const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
842{
843 return key->pub_key;
844}
845
846int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
847{
848 if (key->meth->set_public != NULL
849 && key->meth->set_public(key, pub_key) == 0)
850 return 0;
851 EC_POINT_free(key->pub_key);
852 key->pub_key = EC_POINT_dup(pub_key, key->group);
853 key->dirty_cnt++;
854 return (key->pub_key == NULL) ? 0 : 1;
855}
856
857unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
858{
859 return key->enc_flag;
860}
861
862void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
863{
864 key->enc_flag = flags;
865}
866
867point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
868{
869 return key->conv_form;
870}
871
872void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
873{
874 key->conv_form = cform;
875 if (key->group != NULL)
876 EC_GROUP_set_point_conversion_form(key->group, cform);
877}
878
879void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
880{
881 if (key->group != NULL)
882 EC_GROUP_set_asn1_flag(key->group, flag);
883}
884
885#ifndef OPENSSL_NO_DEPRECATED_3_0
886int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
887{
888 if (key->group == NULL)
889 return 0;
890 return EC_GROUP_precompute_mult(key->group, ctx);
891}
892#endif
893
894int EC_KEY_get_flags(const EC_KEY *key)
895{
896 return key->flags;
897}
898
899void EC_KEY_set_flags(EC_KEY *key, int flags)
900{
901 key->flags |= flags;
902 key->dirty_cnt++;
903}
904
905void EC_KEY_clear_flags(EC_KEY *key, int flags)
906{
907 key->flags &= ~flags;
908 key->dirty_cnt++;
909}
910
911int EC_KEY_decoded_from_explicit_params(const EC_KEY *key)
912{
913 if (key == NULL || key->group == NULL)
914 return -1;
915 return key->group->decoded_from_explicit_params;
916}
917
918size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
919 unsigned char **pbuf, BN_CTX *ctx)
920{
921 if (key == NULL || key->pub_key == NULL || key->group == NULL)
922 return 0;
923 return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
924}
925
926int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
927 BN_CTX *ctx)
928{
929 if (key == NULL || key->group == NULL)
930 return 0;
931 if (key->pub_key == NULL)
932 key->pub_key = EC_POINT_new(key->group);
933 if (key->pub_key == NULL)
934 return 0;
935 if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
936 return 0;
937 key->dirty_cnt++;
938 /*
939 * Save the point conversion form.
940 * For non-custom curves the first octet of the buffer (excluding
941 * the last significant bit) contains the point conversion form.
942 * EC_POINT_oct2point() has already performed sanity checking of
943 * the buffer so we know it is valid.
944 */
945 if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0)
946 key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01);
947 return 1;
948}
949
950size_t EC_KEY_priv2oct(const EC_KEY *eckey,
951 unsigned char *buf, size_t len)
952{
953 if (eckey->group == NULL || eckey->group->meth == NULL)
954 return 0;
955 if (eckey->group->meth->priv2oct == NULL) {
956 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
957 return 0;
958 }
959
960 return eckey->group->meth->priv2oct(eckey, buf, len);
961}
962
963size_t ossl_ec_key_simple_priv2oct(const EC_KEY *eckey,
964 unsigned char *buf, size_t len)
965{
966 size_t buf_len;
967
968 buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8;
969 if (eckey->priv_key == NULL)
970 return 0;
971 if (buf == NULL)
972 return buf_len;
973 else if (len < buf_len)
974 return 0;
975
976 /* Octetstring may need leading zeros if BN is to short */
977
978 if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
979 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
980 return 0;
981 }
982
983 return buf_len;
984}
985
986int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
987{
988 int ret;
989
990 if (eckey->group == NULL || eckey->group->meth == NULL)
991 return 0;
992 if (eckey->group->meth->oct2priv == NULL) {
993 ERR_raise(ERR_LIB_EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
994 return 0;
995 }
996 ret = eckey->group->meth->oct2priv(eckey, buf, len);
997 if (ret == 1)
998 eckey->dirty_cnt++;
999 return ret;
1000}
1001
1002int ossl_ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf,
1003 size_t len)
1004{
1005 if (eckey->priv_key == NULL)
1006 eckey->priv_key = BN_secure_new();
1007 if (eckey->priv_key == NULL) {
1008 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1009 return 0;
1010 }
1011 if (BN_bin2bn(buf, len, eckey->priv_key) == NULL) {
1012 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
1013 return 0;
1014 }
1015 eckey->dirty_cnt++;
1016 return 1;
1017}
1018
1019size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
1020{
1021 size_t len;
1022 unsigned char *buf;
1023
1024 len = EC_KEY_priv2oct(eckey, NULL, 0);
1025 if (len == 0)
1026 return 0;
1027 if ((buf = OPENSSL_malloc(len)) == NULL) {
1028 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1029 return 0;
1030 }
1031 len = EC_KEY_priv2oct(eckey, buf, len);
1032 if (len == 0) {
1033 OPENSSL_free(buf);
1034 return 0;
1035 }
1036 *pbuf = buf;
1037 return len;
1038}
1039
1040int EC_KEY_can_sign(const EC_KEY *eckey)
1041{
1042 if (eckey->group == NULL || eckey->group->meth == NULL
1043 || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
1044 return 0;
1045 return 1;
1046}
1047
1048/*
1049 * FIPS 140-2 IG 9.9 AS09.33
1050 * Perform a sign/verify operation.
1051 *
1052 * NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
1053 * states that no additional pairwise tests are required (apart from the tests
1054 * specified in SP800-56A) when generating keys. Hence pairwise ECDH tests are
1055 * omitted here.
1056 */
1057static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
1058 void *cbarg)
1059{
1060 int ret = 0;
1061 unsigned char dgst[16] = {0};
1062 int dgst_len = (int)sizeof(dgst);
1063 ECDSA_SIG *sig = NULL;
1064 OSSL_SELF_TEST *st = NULL;
1065
1066 st = OSSL_SELF_TEST_new(cb, cbarg);
1067 if (st == NULL)
1068 return 0;
1069
1070 OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
1071 OSSL_SELF_TEST_DESC_PCT_ECDSA);
1072
1073 sig = ECDSA_do_sign(dgst, dgst_len, eckey);
1074 if (sig == NULL)
1075 goto err;
1076
1077 OSSL_SELF_TEST_oncorrupt_byte(st, dgst);
1078
1079 if (ECDSA_do_verify(dgst, dgst_len, sig, eckey) != 1)
1080 goto err;
1081
1082 ret = 1;
1083err:
1084 OSSL_SELF_TEST_onend(st, ret);
1085 OSSL_SELF_TEST_free(st);
1086 ECDSA_SIG_free(sig);
1087 return ret;
1088}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette