Coverage Report

Created: 2026-07-23 06:28

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