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