1 | /* |
2 | * Copyright 2002-2019 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 | #include "internal/cryptlib.h" |
12 | #include <string.h> |
13 | #include "ec_local.h" |
14 | #include "internal/refcount.h" |
15 | #include <openssl/err.h> |
16 | #include <openssl/engine.h> |
17 | |
18 | #ifndef FIPS_MODE |
19 | EC_KEY *EC_KEY_new(void) |
20 | { |
21 | return ec_key_new_method_int(NULL, NULL); |
22 | } |
23 | #endif |
24 | |
25 | EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx) |
26 | { |
27 | return ec_key_new_method_int(ctx, NULL); |
28 | } |
29 | |
30 | EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid) |
31 | { |
32 | EC_KEY *ret = EC_KEY_new_ex(ctx); |
33 | if (ret == NULL) |
34 | return NULL; |
35 | ret->group = EC_GROUP_new_by_curve_name_ex(ctx, nid); |
36 | if (ret->group == NULL) { |
37 | EC_KEY_free(ret); |
38 | return NULL; |
39 | } |
40 | if (ret->meth->set_group != NULL |
41 | && ret->meth->set_group(ret, ret->group) == 0) { |
42 | EC_KEY_free(ret); |
43 | return NULL; |
44 | } |
45 | return ret; |
46 | } |
47 | |
48 | #ifndef FIPS_MODE |
49 | EC_KEY *EC_KEY_new_by_curve_name(int nid) |
50 | { |
51 | return EC_KEY_new_by_curve_name_ex(NULL, nid); |
52 | } |
53 | #endif |
54 | |
55 | void EC_KEY_free(EC_KEY *r) |
56 | { |
57 | int i; |
58 | |
59 | if (r == NULL) |
60 | return; |
61 | |
62 | CRYPTO_DOWN_REF(&r->references, &i, r->lock); |
63 | REF_PRINT_COUNT("EC_KEY" , r); |
64 | if (i > 0) |
65 | return; |
66 | REF_ASSERT_ISNT(i < 0); |
67 | |
68 | if (r->meth != NULL && r->meth->finish != NULL) |
69 | r->meth->finish(r); |
70 | |
71 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) |
72 | ENGINE_finish(r->engine); |
73 | #endif |
74 | |
75 | if (r->group && r->group->meth->keyfinish) |
76 | r->group->meth->keyfinish(r); |
77 | |
78 | #ifndef FIPS_MODE |
79 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); |
80 | #endif |
81 | CRYPTO_THREAD_lock_free(r->lock); |
82 | EC_GROUP_free(r->group); |
83 | EC_POINT_free(r->pub_key); |
84 | BN_clear_free(r->priv_key); |
85 | |
86 | OPENSSL_clear_free((void *)r, sizeof(EC_KEY)); |
87 | } |
88 | |
89 | EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) |
90 | { |
91 | if (dest == NULL || src == NULL) { |
92 | ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); |
93 | return NULL; |
94 | } |
95 | if (src->meth != dest->meth) { |
96 | if (dest->meth->finish != NULL) |
97 | dest->meth->finish(dest); |
98 | if (dest->group && dest->group->meth->keyfinish) |
99 | dest->group->meth->keyfinish(dest); |
100 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) |
101 | if (ENGINE_finish(dest->engine) == 0) |
102 | return 0; |
103 | dest->engine = NULL; |
104 | #endif |
105 | } |
106 | dest->libctx = src->libctx; |
107 | /* copy the parameters */ |
108 | if (src->group != NULL) { |
109 | const EC_METHOD *meth = EC_GROUP_method_of(src->group); |
110 | /* clear the old group */ |
111 | EC_GROUP_free(dest->group); |
112 | dest->group = EC_GROUP_new_ex(src->libctx, meth); |
113 | if (dest->group == NULL) |
114 | return NULL; |
115 | if (!EC_GROUP_copy(dest->group, src->group)) |
116 | return NULL; |
117 | |
118 | /* copy the public key */ |
119 | if (src->pub_key != NULL) { |
120 | EC_POINT_free(dest->pub_key); |
121 | dest->pub_key = EC_POINT_new(src->group); |
122 | if (dest->pub_key == NULL) |
123 | return NULL; |
124 | if (!EC_POINT_copy(dest->pub_key, src->pub_key)) |
125 | return NULL; |
126 | } |
127 | /* copy the private key */ |
128 | if (src->priv_key != NULL) { |
129 | if (dest->priv_key == NULL) { |
130 | dest->priv_key = BN_new(); |
131 | if (dest->priv_key == NULL) |
132 | return NULL; |
133 | } |
134 | if (!BN_copy(dest->priv_key, src->priv_key)) |
135 | return NULL; |
136 | if (src->group->meth->keycopy |
137 | && src->group->meth->keycopy(dest, src) == 0) |
138 | return NULL; |
139 | } |
140 | } |
141 | |
142 | |
143 | /* copy the rest */ |
144 | dest->enc_flag = src->enc_flag; |
145 | dest->conv_form = src->conv_form; |
146 | dest->version = src->version; |
147 | dest->flags = src->flags; |
148 | #ifndef FIPS_MODE |
149 | if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, |
150 | &dest->ex_data, &src->ex_data)) |
151 | return NULL; |
152 | #endif |
153 | |
154 | if (src->meth != dest->meth) { |
155 | #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) |
156 | if (src->engine != NULL && ENGINE_init(src->engine) == 0) |
157 | return NULL; |
158 | dest->engine = src->engine; |
159 | #endif |
160 | dest->meth = src->meth; |
161 | } |
162 | |
163 | if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0) |
164 | return NULL; |
165 | |
166 | return dest; |
167 | } |
168 | |
169 | EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) |
170 | { |
171 | EC_KEY *ret = ec_key_new_method_int(ec_key->libctx, ec_key->engine); |
172 | |
173 | if (ret == NULL) |
174 | return NULL; |
175 | |
176 | if (EC_KEY_copy(ret, ec_key) == NULL) { |
177 | EC_KEY_free(ret); |
178 | return NULL; |
179 | } |
180 | return ret; |
181 | } |
182 | |
183 | int EC_KEY_up_ref(EC_KEY *r) |
184 | { |
185 | int i; |
186 | |
187 | if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) |
188 | return 0; |
189 | |
190 | REF_PRINT_COUNT("EC_KEY" , r); |
191 | REF_ASSERT_ISNT(i < 2); |
192 | return ((i > 1) ? 1 : 0); |
193 | } |
194 | |
195 | ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey) |
196 | { |
197 | return eckey->engine; |
198 | } |
199 | |
200 | int EC_KEY_generate_key(EC_KEY *eckey) |
201 | { |
202 | if (eckey == NULL || eckey->group == NULL) { |
203 | ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); |
204 | return 0; |
205 | } |
206 | if (eckey->meth->keygen != NULL) |
207 | return eckey->meth->keygen(eckey); |
208 | ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED); |
209 | return 0; |
210 | } |
211 | |
212 | int ossl_ec_key_gen(EC_KEY *eckey) |
213 | { |
214 | return eckey->group->meth->keygen(eckey); |
215 | } |
216 | |
217 | /* |
218 | * ECC Key generation. |
219 | * See SP800-56AR3 5.6.1.2.2 "Key Pair Generation by Testing Candidates" |
220 | * |
221 | * Params: |
222 | * eckey An EC key object that contains domain params. The generated keypair |
223 | * is stored in this object. |
224 | * Returns 1 if the keypair was generated or 0 otherwise. |
225 | */ |
226 | int ec_key_simple_generate_key(EC_KEY *eckey) |
227 | { |
228 | int ok = 0; |
229 | BIGNUM *priv_key = NULL; |
230 | const BIGNUM *order = NULL; |
231 | EC_POINT *pub_key = NULL; |
232 | const EC_GROUP *group = eckey->group; |
233 | BN_CTX *ctx = BN_CTX_secure_new_ex(eckey->libctx); |
234 | |
235 | if (ctx == NULL) |
236 | goto err; |
237 | |
238 | if (eckey->priv_key == NULL) { |
239 | priv_key = BN_secure_new(); |
240 | if (priv_key == NULL) |
241 | goto err; |
242 | } else |
243 | priv_key = eckey->priv_key; |
244 | |
245 | /* |
246 | * Steps (1-2): Check domain parameters and security strength. |
247 | * These steps must be done by the user. This would need to be |
248 | * stated in the security policy. |
249 | */ |
250 | |
251 | order = EC_GROUP_get0_order(group); |
252 | if (order == NULL) |
253 | goto err; |
254 | |
255 | /* |
256 | * Steps (3-7): priv_key = DRBG_RAND(order_n_bits) (range [1, n-1]). |
257 | * Although this is slightly different from the standard, it is effectively |
258 | * equivalent as it gives an unbiased result ranging from 1..n-1. It is also |
259 | * faster as the standard needs to retry more often. Also doing |
260 | * 1 + rand[0..n-2] would effect the way that tests feed dummy entropy into |
261 | * rand so the simpler backward compatible method has been used here. |
262 | */ |
263 | do |
264 | if (!BN_priv_rand_range_ex(priv_key, order, ctx)) |
265 | goto err; |
266 | while (BN_is_zero(priv_key)) ; |
267 | |
268 | if (eckey->pub_key == NULL) { |
269 | pub_key = EC_POINT_new(group); |
270 | if (pub_key == NULL) |
271 | goto err; |
272 | } else |
273 | pub_key = eckey->pub_key; |
274 | |
275 | /* Step (8) : pub_key = priv_key * G (where G is a point on the curve) */ |
276 | if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) |
277 | goto err; |
278 | |
279 | eckey->priv_key = priv_key; |
280 | eckey->pub_key = pub_key; |
281 | priv_key = NULL; |
282 | pub_key = NULL; |
283 | |
284 | ok = 1; |
285 | |
286 | err: |
287 | /* Step (9): If there is an error return an invalid keypair. */ |
288 | if (!ok) { |
289 | BN_clear(eckey->priv_key); |
290 | if (eckey->pub_key != NULL) |
291 | EC_POINT_set_to_infinity(group, eckey->pub_key); |
292 | } |
293 | |
294 | EC_POINT_free(pub_key); |
295 | BN_clear_free(priv_key); |
296 | BN_CTX_free(ctx); |
297 | return ok; |
298 | } |
299 | |
300 | int ec_key_simple_generate_public_key(EC_KEY *eckey) |
301 | { |
302 | /* |
303 | * See SP800-56AR3 5.6.1.2.2: Step (8) |
304 | * pub_key = priv_key * G (where G is a point on the curve) |
305 | */ |
306 | return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL, |
307 | NULL, NULL); |
308 | } |
309 | |
310 | int EC_KEY_check_key(const EC_KEY *eckey) |
311 | { |
312 | if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { |
313 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); |
314 | return 0; |
315 | } |
316 | |
317 | if (eckey->group->meth->keycheck == NULL) { |
318 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
319 | return 0; |
320 | } |
321 | |
322 | return eckey->group->meth->keycheck(eckey); |
323 | } |
324 | |
325 | /* |
326 | * Check the range of the EC public key. |
327 | * See SP800-56A R3 Section 5.6.2.3.3 (Part 2) |
328 | * i.e. |
329 | * - If q = odd prime p: Verify that xQ and yQ are integers in the |
330 | * interval[0, p - 1], OR |
331 | * - If q = 2m: Verify that xQ and yQ are bit strings of length m bits. |
332 | * Returns 1 if the public key has a valid range, otherwise it returns 0. |
333 | */ |
334 | static int ec_key_public_range_check(BN_CTX *ctx, const EC_KEY *key) |
335 | { |
336 | int ret = 0; |
337 | BIGNUM *x, *y; |
338 | |
339 | BN_CTX_start(ctx); |
340 | x = BN_CTX_get(ctx); |
341 | y = BN_CTX_get(ctx); |
342 | if (y == NULL) |
343 | goto err; |
344 | |
345 | if (!EC_POINT_get_affine_coordinates(key->group, key->pub_key, x, y, ctx)) |
346 | goto err; |
347 | |
348 | if (EC_METHOD_get_field_type(key->group->meth) == NID_X9_62_prime_field) { |
349 | if (BN_is_negative(x) |
350 | || BN_cmp(x, key->group->field) >= 0 |
351 | || BN_is_negative(y) |
352 | || BN_cmp(y, key->group->field) >= 0) { |
353 | goto err; |
354 | } |
355 | } else { |
356 | int m = EC_GROUP_get_degree(key->group); |
357 | if (BN_num_bits(x) > m || BN_num_bits(y) > m) { |
358 | goto err; |
359 | } |
360 | } |
361 | ret = 1; |
362 | err: |
363 | BN_CTX_end(ctx); |
364 | return ret; |
365 | } |
366 | |
367 | /* |
368 | * ECC Key validation as specified in SP800-56A R3. |
369 | * Section 5.6.2.3.3 ECC Full Public-Key Validation |
370 | * Section 5.6.2.1.2 Owner Assurance of Private-Key Validity |
371 | * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency |
372 | * NOTES: |
373 | * Before calling this method in fips mode, there should be an assurance that |
374 | * an approved elliptic-curve group is used. |
375 | * Returns 1 if the key is valid, otherwise it returns 0. |
376 | */ |
377 | int ec_key_simple_check_key(const EC_KEY *eckey) |
378 | { |
379 | int ok = 0; |
380 | BN_CTX *ctx = NULL; |
381 | const BIGNUM *order = NULL; |
382 | EC_POINT *point = NULL; |
383 | |
384 | if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) { |
385 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); |
386 | return 0; |
387 | } |
388 | |
389 | /* 5.6.2.3.3 (Step 1): Q != infinity */ |
390 | if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { |
391 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY); |
392 | goto err; |
393 | } |
394 | |
395 | if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) |
396 | goto err; |
397 | |
398 | if ((point = EC_POINT_new(eckey->group)) == NULL) |
399 | goto err; |
400 | |
401 | /* 5.6.2.3.3 (Step 2) Test if the public key is in range */ |
402 | if (!ec_key_public_range_check(ctx, eckey)) { |
403 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_COORDINATES_OUT_OF_RANGE); |
404 | goto err; |
405 | } |
406 | |
407 | /* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */ |
408 | if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { |
409 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); |
410 | goto err; |
411 | } |
412 | |
413 | order = eckey->group->order; |
414 | if (BN_is_zero(order)) { |
415 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); |
416 | goto err; |
417 | } |
418 | /* 5.6.2.3.3 (Step 4) : pub_key * order is the point at infinity. */ |
419 | if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { |
420 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB); |
421 | goto err; |
422 | } |
423 | if (!EC_POINT_is_at_infinity(eckey->group, point)) { |
424 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER); |
425 | goto err; |
426 | } |
427 | |
428 | if (eckey->priv_key != NULL) { |
429 | /* |
430 | * 5.6.2.1.2 Owner Assurance of Private-Key Validity |
431 | * The private key is in the range [1, order-1] |
432 | */ |
433 | if (BN_cmp(eckey->priv_key, BN_value_one()) < 0 |
434 | || BN_cmp(eckey->priv_key, order) >= 0) { |
435 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER); |
436 | goto err; |
437 | } |
438 | /* |
439 | * Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency (b) |
440 | * Check if generator * priv_key = pub_key |
441 | */ |
442 | if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, |
443 | NULL, NULL, ctx)) { |
444 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB); |
445 | goto err; |
446 | } |
447 | if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { |
448 | ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); |
449 | goto err; |
450 | } |
451 | } |
452 | ok = 1; |
453 | err: |
454 | BN_CTX_free(ctx); |
455 | EC_POINT_free(point); |
456 | return ok; |
457 | } |
458 | |
459 | int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, |
460 | BIGNUM *y) |
461 | { |
462 | BN_CTX *ctx = NULL; |
463 | BIGNUM *tx, *ty; |
464 | EC_POINT *point = NULL; |
465 | int ok = 0; |
466 | |
467 | if (key == NULL || key->group == NULL || x == NULL || y == NULL) { |
468 | ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, |
469 | ERR_R_PASSED_NULL_PARAMETER); |
470 | return 0; |
471 | } |
472 | ctx = BN_CTX_new_ex(key->libctx); |
473 | if (ctx == NULL) |
474 | return 0; |
475 | |
476 | BN_CTX_start(ctx); |
477 | point = EC_POINT_new(key->group); |
478 | |
479 | if (point == NULL) |
480 | goto err; |
481 | |
482 | tx = BN_CTX_get(ctx); |
483 | ty = BN_CTX_get(ctx); |
484 | if (ty == NULL) |
485 | goto err; |
486 | |
487 | if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx)) |
488 | goto err; |
489 | if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx)) |
490 | goto err; |
491 | |
492 | /* |
493 | * Check if retrieved coordinates match originals. The range check is done |
494 | * inside EC_KEY_check_key(). |
495 | */ |
496 | if (BN_cmp(x, tx) || BN_cmp(y, ty)) { |
497 | ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, |
498 | EC_R_COORDINATES_OUT_OF_RANGE); |
499 | goto err; |
500 | } |
501 | |
502 | if (!EC_KEY_set_public_key(key, point)) |
503 | goto err; |
504 | |
505 | if (EC_KEY_check_key(key) == 0) |
506 | goto err; |
507 | |
508 | ok = 1; |
509 | |
510 | err: |
511 | BN_CTX_end(ctx); |
512 | BN_CTX_free(ctx); |
513 | EC_POINT_free(point); |
514 | return ok; |
515 | |
516 | } |
517 | |
518 | const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) |
519 | { |
520 | return key->group; |
521 | } |
522 | |
523 | int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) |
524 | { |
525 | if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0) |
526 | return 0; |
527 | EC_GROUP_free(key->group); |
528 | key->group = EC_GROUP_dup(group); |
529 | return (key->group == NULL) ? 0 : 1; |
530 | } |
531 | |
532 | const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) |
533 | { |
534 | return key->priv_key; |
535 | } |
536 | |
537 | int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) |
538 | { |
539 | if (key->group == NULL || key->group->meth == NULL) |
540 | return 0; |
541 | if (key->group->meth->set_private != NULL |
542 | && key->group->meth->set_private(key, priv_key) == 0) |
543 | return 0; |
544 | if (key->meth->set_private != NULL |
545 | && key->meth->set_private(key, priv_key) == 0) |
546 | return 0; |
547 | BN_clear_free(key->priv_key); |
548 | key->priv_key = BN_dup(priv_key); |
549 | return (key->priv_key == NULL) ? 0 : 1; |
550 | } |
551 | |
552 | const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) |
553 | { |
554 | return key->pub_key; |
555 | } |
556 | |
557 | int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) |
558 | { |
559 | if (key->meth->set_public != NULL |
560 | && key->meth->set_public(key, pub_key) == 0) |
561 | return 0; |
562 | EC_POINT_free(key->pub_key); |
563 | key->pub_key = EC_POINT_dup(pub_key, key->group); |
564 | return (key->pub_key == NULL) ? 0 : 1; |
565 | } |
566 | |
567 | unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) |
568 | { |
569 | return key->enc_flag; |
570 | } |
571 | |
572 | void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) |
573 | { |
574 | key->enc_flag = flags; |
575 | } |
576 | |
577 | point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) |
578 | { |
579 | return key->conv_form; |
580 | } |
581 | |
582 | void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) |
583 | { |
584 | key->conv_form = cform; |
585 | if (key->group != NULL) |
586 | EC_GROUP_set_point_conversion_form(key->group, cform); |
587 | } |
588 | |
589 | void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) |
590 | { |
591 | if (key->group != NULL) |
592 | EC_GROUP_set_asn1_flag(key->group, flag); |
593 | } |
594 | |
595 | int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) |
596 | { |
597 | if (key->group == NULL) |
598 | return 0; |
599 | return EC_GROUP_precompute_mult(key->group, ctx); |
600 | } |
601 | |
602 | int EC_KEY_get_flags(const EC_KEY *key) |
603 | { |
604 | return key->flags; |
605 | } |
606 | |
607 | void EC_KEY_set_flags(EC_KEY *key, int flags) |
608 | { |
609 | key->flags |= flags; |
610 | } |
611 | |
612 | void EC_KEY_clear_flags(EC_KEY *key, int flags) |
613 | { |
614 | key->flags &= ~flags; |
615 | } |
616 | |
617 | size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, |
618 | unsigned char **pbuf, BN_CTX *ctx) |
619 | { |
620 | if (key == NULL || key->pub_key == NULL || key->group == NULL) |
621 | return 0; |
622 | return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx); |
623 | } |
624 | |
625 | int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, |
626 | BN_CTX *ctx) |
627 | { |
628 | if (key == NULL || key->group == NULL) |
629 | return 0; |
630 | if (key->pub_key == NULL) |
631 | key->pub_key = EC_POINT_new(key->group); |
632 | if (key->pub_key == NULL) |
633 | return 0; |
634 | if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0) |
635 | return 0; |
636 | /* |
637 | * Save the point conversion form. |
638 | * For non-custom curves the first octet of the buffer (excluding |
639 | * the last significant bit) contains the point conversion form. |
640 | * EC_POINT_oct2point() has already performed sanity checking of |
641 | * the buffer so we know it is valid. |
642 | */ |
643 | if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) |
644 | key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01); |
645 | return 1; |
646 | } |
647 | |
648 | size_t EC_KEY_priv2oct(const EC_KEY *eckey, |
649 | unsigned char *buf, size_t len) |
650 | { |
651 | if (eckey->group == NULL || eckey->group->meth == NULL) |
652 | return 0; |
653 | if (eckey->group->meth->priv2oct == NULL) { |
654 | ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
655 | return 0; |
656 | } |
657 | |
658 | return eckey->group->meth->priv2oct(eckey, buf, len); |
659 | } |
660 | |
661 | size_t ec_key_simple_priv2oct(const EC_KEY *eckey, |
662 | unsigned char *buf, size_t len) |
663 | { |
664 | size_t buf_len; |
665 | |
666 | buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8; |
667 | if (eckey->priv_key == NULL) |
668 | return 0; |
669 | if (buf == NULL) |
670 | return buf_len; |
671 | else if (len < buf_len) |
672 | return 0; |
673 | |
674 | /* Octetstring may need leading zeros if BN is to short */ |
675 | |
676 | if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) { |
677 | ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL); |
678 | return 0; |
679 | } |
680 | |
681 | return buf_len; |
682 | } |
683 | |
684 | int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len) |
685 | { |
686 | if (eckey->group == NULL || eckey->group->meth == NULL) |
687 | return 0; |
688 | if (eckey->group->meth->oct2priv == NULL) { |
689 | ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
690 | return 0; |
691 | } |
692 | return eckey->group->meth->oct2priv(eckey, buf, len); |
693 | } |
694 | |
695 | int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len) |
696 | { |
697 | if (eckey->priv_key == NULL) |
698 | eckey->priv_key = BN_secure_new(); |
699 | if (eckey->priv_key == NULL) { |
700 | ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE); |
701 | return 0; |
702 | } |
703 | eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key); |
704 | if (eckey->priv_key == NULL) { |
705 | ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB); |
706 | return 0; |
707 | } |
708 | return 1; |
709 | } |
710 | |
711 | size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf) |
712 | { |
713 | size_t len; |
714 | unsigned char *buf; |
715 | |
716 | len = EC_KEY_priv2oct(eckey, NULL, 0); |
717 | if (len == 0) |
718 | return 0; |
719 | if ((buf = OPENSSL_malloc(len)) == NULL) { |
720 | ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE); |
721 | return 0; |
722 | } |
723 | len = EC_KEY_priv2oct(eckey, buf, len); |
724 | if (len == 0) { |
725 | OPENSSL_free(buf); |
726 | return 0; |
727 | } |
728 | *pbuf = buf; |
729 | return len; |
730 | } |
731 | |
732 | int EC_KEY_can_sign(const EC_KEY *eckey) |
733 | { |
734 | if (eckey->group == NULL || eckey->group->meth == NULL |
735 | || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN)) |
736 | return 0; |
737 | return 1; |
738 | } |
739 | |