/src/libressl/crypto/ec/ec_key.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* $OpenBSD: ec_key.c,v 1.26 2021/04/20 17:23:37 tb Exp $ */ |
2 | | /* |
3 | | * Written by Nils Larsch for the OpenSSL project. |
4 | | */ |
5 | | /* ==================================================================== |
6 | | * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. |
7 | | * |
8 | | * Redistribution and use in source and binary forms, with or without |
9 | | * modification, are permitted provided that the following conditions |
10 | | * are met: |
11 | | * |
12 | | * 1. Redistributions of source code must retain the above copyright |
13 | | * notice, this list of conditions and the following disclaimer. |
14 | | * |
15 | | * 2. Redistributions in binary form must reproduce the above copyright |
16 | | * notice, this list of conditions and the following disclaimer in |
17 | | * the documentation and/or other materials provided with the |
18 | | * distribution. |
19 | | * |
20 | | * 3. All advertising materials mentioning features or use of this |
21 | | * software must display the following acknowledgment: |
22 | | * "This product includes software developed by the OpenSSL Project |
23 | | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
24 | | * |
25 | | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
26 | | * endorse or promote products derived from this software without |
27 | | * prior written permission. For written permission, please contact |
28 | | * openssl-core@openssl.org. |
29 | | * |
30 | | * 5. Products derived from this software may not be called "OpenSSL" |
31 | | * nor may "OpenSSL" appear in their names without prior written |
32 | | * permission of the OpenSSL Project. |
33 | | * |
34 | | * 6. Redistributions of any form whatsoever must retain the following |
35 | | * acknowledgment: |
36 | | * "This product includes software developed by the OpenSSL Project |
37 | | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
38 | | * |
39 | | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
40 | | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
41 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
42 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
43 | | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
44 | | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
45 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
46 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
47 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
48 | | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
49 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
50 | | * OF THE POSSIBILITY OF SUCH DAMAGE. |
51 | | * ==================================================================== |
52 | | * |
53 | | * This product includes cryptographic software written by Eric Young |
54 | | * (eay@cryptsoft.com). This product includes software written by Tim |
55 | | * Hudson (tjh@cryptsoft.com). |
56 | | * |
57 | | */ |
58 | | /* ==================================================================== |
59 | | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. |
60 | | * Portions originally developed by SUN MICROSYSTEMS, INC., and |
61 | | * contributed to the OpenSSL project. |
62 | | */ |
63 | | |
64 | | #include <string.h> |
65 | | |
66 | | #include <openssl/opensslconf.h> |
67 | | |
68 | | #ifndef OPENSSL_NO_ENGINE |
69 | | #include <openssl/engine.h> |
70 | | #endif |
71 | | #include <openssl/err.h> |
72 | | |
73 | | #include "bn_lcl.h" |
74 | | #include "ec_lcl.h" |
75 | | |
76 | | EC_KEY * |
77 | | EC_KEY_new(void) |
78 | 5.60k | { |
79 | 5.60k | return EC_KEY_new_method(NULL); |
80 | 5.60k | } |
81 | | |
82 | | EC_KEY * |
83 | | EC_KEY_new_by_curve_name(int nid) |
84 | 809 | { |
85 | 809 | EC_KEY *ret = EC_KEY_new(); |
86 | 809 | if (ret == NULL) |
87 | 0 | return NULL; |
88 | 809 | ret->group = EC_GROUP_new_by_curve_name(nid); |
89 | 809 | if (ret->group == NULL) { |
90 | 0 | EC_KEY_free(ret); |
91 | 0 | return NULL; |
92 | 0 | } |
93 | 809 | if (ret->meth->set_group != NULL && |
94 | 809 | ret->meth->set_group(ret, ret->group) == 0) { |
95 | 0 | EC_KEY_free(ret); |
96 | 0 | return NULL; |
97 | 0 | } |
98 | 809 | return ret; |
99 | 809 | } |
100 | | |
101 | | void |
102 | | EC_KEY_free(EC_KEY * r) |
103 | 5.64k | { |
104 | 5.64k | int i; |
105 | | |
106 | 5.64k | if (r == NULL) |
107 | 34 | return; |
108 | | |
109 | 5.60k | i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); |
110 | 5.60k | if (i > 0) |
111 | 0 | return; |
112 | | |
113 | 5.60k | if (r->meth != NULL && r->meth->finish != NULL) |
114 | 0 | r->meth->finish(r); |
115 | | |
116 | 5.60k | #ifndef OPENSSL_NO_ENGINE |
117 | 5.60k | ENGINE_finish(r->engine); |
118 | 5.60k | #endif |
119 | 5.60k | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); |
120 | | |
121 | 5.60k | EC_GROUP_free(r->group); |
122 | 5.60k | EC_POINT_free(r->pub_key); |
123 | 5.60k | BN_clear_free(r->priv_key); |
124 | | |
125 | 5.60k | EC_EX_DATA_free_all_data(&r->method_data); |
126 | | |
127 | 5.60k | freezero(r, sizeof(EC_KEY)); |
128 | 5.60k | } |
129 | | |
130 | | EC_KEY * |
131 | | EC_KEY_copy(EC_KEY * dest, const EC_KEY * src) |
132 | 3.23k | { |
133 | 3.23k | EC_EXTRA_DATA *d; |
134 | | |
135 | 3.23k | if (dest == NULL || src == NULL) { |
136 | 0 | ECerror(ERR_R_PASSED_NULL_PARAMETER); |
137 | 0 | return NULL; |
138 | 0 | } |
139 | 3.23k | if (src->meth != dest->meth) { |
140 | 0 | if (dest->meth != NULL && dest->meth->finish != NULL) |
141 | 0 | dest->meth->finish(dest); |
142 | 0 | #ifndef OPENSSL_NO_ENGINE |
143 | 0 | if (ENGINE_finish(dest->engine) == 0) |
144 | 0 | return 0; |
145 | 0 | dest->engine = NULL; |
146 | 0 | #endif |
147 | 0 | } |
148 | | /* copy the parameters */ |
149 | 3.23k | if (src->group) { |
150 | 1.91k | const EC_METHOD *meth = EC_GROUP_method_of(src->group); |
151 | | /* clear the old group */ |
152 | 1.91k | EC_GROUP_free(dest->group); |
153 | 1.91k | dest->group = EC_GROUP_new(meth); |
154 | 1.91k | if (dest->group == NULL) |
155 | 0 | return NULL; |
156 | 1.91k | if (!EC_GROUP_copy(dest->group, src->group)) |
157 | 0 | return NULL; |
158 | 1.91k | } |
159 | | /* copy the public key */ |
160 | 3.23k | if (src->pub_key && src->group) { |
161 | 448 | EC_POINT_free(dest->pub_key); |
162 | 448 | dest->pub_key = EC_POINT_new(src->group); |
163 | 448 | if (dest->pub_key == NULL) |
164 | 0 | return NULL; |
165 | 448 | if (!EC_POINT_copy(dest->pub_key, src->pub_key)) |
166 | 0 | return NULL; |
167 | 448 | } |
168 | | /* copy the private key */ |
169 | 3.23k | if (src->priv_key) { |
170 | 387 | if (dest->priv_key == NULL) { |
171 | 387 | dest->priv_key = BN_new(); |
172 | 387 | if (dest->priv_key == NULL) |
173 | 0 | return NULL; |
174 | 387 | } |
175 | 387 | if (!BN_copy(dest->priv_key, src->priv_key)) |
176 | 0 | return NULL; |
177 | 387 | } |
178 | | /* copy method/extra data */ |
179 | 3.23k | EC_EX_DATA_free_all_data(&dest->method_data); |
180 | | |
181 | 3.23k | for (d = src->method_data; d != NULL; d = d->next) { |
182 | 0 | void *t = d->dup_func(d->data); |
183 | |
|
184 | 0 | if (t == NULL) |
185 | 0 | return 0; |
186 | 0 | if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, |
187 | 0 | d->free_func, d->clear_free_func)) |
188 | 0 | return 0; |
189 | 0 | } |
190 | | |
191 | | /* copy the rest */ |
192 | 3.23k | dest->enc_flag = src->enc_flag; |
193 | 3.23k | dest->conv_form = src->conv_form; |
194 | 3.23k | dest->version = src->version; |
195 | 3.23k | dest->flags = src->flags; |
196 | | |
197 | 3.23k | if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, &dest->ex_data, |
198 | 3.23k | &((EC_KEY *)src)->ex_data)) /* XXX const */ |
199 | 0 | return NULL; |
200 | | |
201 | 3.23k | if (src->meth != dest->meth) { |
202 | 0 | #ifndef OPENSSL_NO_ENGINE |
203 | 0 | if (src->engine != NULL && ENGINE_init(src->engine) == 0) |
204 | 0 | return 0; |
205 | 0 | dest->engine = src->engine; |
206 | 0 | #endif |
207 | 0 | dest->meth = src->meth; |
208 | 0 | } |
209 | | |
210 | 3.23k | if (src->meth != NULL && src->meth->copy != NULL && |
211 | 3.23k | src->meth->copy(dest, src) == 0) |
212 | 0 | return 0; |
213 | | |
214 | 3.23k | return dest; |
215 | 3.23k | } |
216 | | |
217 | | EC_KEY * |
218 | | EC_KEY_dup(const EC_KEY * ec_key) |
219 | 0 | { |
220 | 0 | EC_KEY *ret; |
221 | |
|
222 | 0 | if ((ret = EC_KEY_new_method(ec_key->engine)) == NULL) |
223 | 0 | return NULL; |
224 | 0 | if (EC_KEY_copy(ret, ec_key) == NULL) { |
225 | 0 | EC_KEY_free(ret); |
226 | 0 | return NULL; |
227 | 0 | } |
228 | 0 | return ret; |
229 | 0 | } |
230 | | |
231 | | int |
232 | | EC_KEY_up_ref(EC_KEY * r) |
233 | 0 | { |
234 | 0 | int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); |
235 | 0 | return ((i > 1) ? 1 : 0); |
236 | 0 | } |
237 | | |
238 | | int |
239 | | EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg) |
240 | 0 | { |
241 | 0 | return CRYPTO_set_ex_data(&r->ex_data, idx, arg); |
242 | 0 | } |
243 | | |
244 | | void * |
245 | | EC_KEY_get_ex_data(const EC_KEY *r, int idx) |
246 | 0 | { |
247 | 0 | return CRYPTO_get_ex_data(&r->ex_data, idx); |
248 | 0 | } |
249 | | |
250 | | int |
251 | | EC_KEY_generate_key(EC_KEY *eckey) |
252 | 809 | { |
253 | 809 | if (eckey->meth->keygen != NULL) |
254 | 809 | return eckey->meth->keygen(eckey); |
255 | 0 | ECerror(EC_R_NOT_IMPLEMENTED); |
256 | 0 | return 0; |
257 | 809 | } |
258 | | |
259 | | int |
260 | | ossl_ec_key_gen(EC_KEY *eckey) |
261 | 809 | { |
262 | 809 | int ok = 0; |
263 | 809 | BN_CTX *ctx = NULL; |
264 | 809 | BIGNUM *priv_key = NULL, *order = NULL; |
265 | 809 | EC_POINT *pub_key = NULL; |
266 | | |
267 | 809 | if (!eckey || !eckey->group) { |
268 | 0 | ECerror(ERR_R_PASSED_NULL_PARAMETER); |
269 | 0 | return 0; |
270 | 0 | } |
271 | | |
272 | 809 | if ((order = BN_new()) == NULL) |
273 | 0 | goto err; |
274 | 809 | if ((ctx = BN_CTX_new()) == NULL) |
275 | 0 | goto err; |
276 | | |
277 | 809 | if ((priv_key = eckey->priv_key) == NULL) { |
278 | 809 | if ((priv_key = BN_new()) == NULL) |
279 | 0 | goto err; |
280 | 809 | } |
281 | | |
282 | 809 | if (!EC_GROUP_get_order(eckey->group, order, ctx)) |
283 | 0 | goto err; |
284 | | |
285 | 809 | if (!bn_rand_interval(priv_key, BN_value_one(), order)) |
286 | 0 | goto err; |
287 | | |
288 | 809 | if ((pub_key = eckey->pub_key) == NULL) { |
289 | 809 | if ((pub_key = EC_POINT_new(eckey->group)) == NULL) |
290 | 0 | goto err; |
291 | 809 | } |
292 | | |
293 | 809 | if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) |
294 | 0 | goto err; |
295 | | |
296 | 809 | eckey->priv_key = priv_key; |
297 | 809 | eckey->pub_key = pub_key; |
298 | | |
299 | 809 | ok = 1; |
300 | | |
301 | 809 | err: |
302 | 809 | BN_free(order); |
303 | 809 | if (eckey->pub_key == NULL) |
304 | 0 | EC_POINT_free(pub_key); |
305 | 809 | if (eckey->priv_key == NULL) |
306 | 0 | BN_free(priv_key); |
307 | 809 | BN_CTX_free(ctx); |
308 | 809 | return (ok); |
309 | 809 | } |
310 | | |
311 | | int |
312 | | EC_KEY_check_key(const EC_KEY * eckey) |
313 | 0 | { |
314 | 0 | int ok = 0; |
315 | 0 | BN_CTX *ctx = NULL; |
316 | 0 | const BIGNUM *order = NULL; |
317 | 0 | EC_POINT *point = NULL; |
318 | |
|
319 | 0 | if (!eckey || !eckey->group || !eckey->pub_key) { |
320 | 0 | ECerror(ERR_R_PASSED_NULL_PARAMETER); |
321 | 0 | return 0; |
322 | 0 | } |
323 | 0 | if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key) > 0) { |
324 | 0 | ECerror(EC_R_POINT_AT_INFINITY); |
325 | 0 | goto err; |
326 | 0 | } |
327 | 0 | if ((ctx = BN_CTX_new()) == NULL) |
328 | 0 | goto err; |
329 | 0 | if ((point = EC_POINT_new(eckey->group)) == NULL) |
330 | 0 | goto err; |
331 | | |
332 | | /* testing whether the pub_key is on the elliptic curve */ |
333 | 0 | if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { |
334 | 0 | ECerror(EC_R_POINT_IS_NOT_ON_CURVE); |
335 | 0 | goto err; |
336 | 0 | } |
337 | | /* testing whether pub_key * order is the point at infinity */ |
338 | 0 | order = &eckey->group->order; |
339 | 0 | if (BN_is_zero(order)) { |
340 | 0 | ECerror(EC_R_INVALID_GROUP_ORDER); |
341 | 0 | goto err; |
342 | 0 | } |
343 | 0 | if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { |
344 | 0 | ECerror(ERR_R_EC_LIB); |
345 | 0 | goto err; |
346 | 0 | } |
347 | 0 | if (EC_POINT_is_at_infinity(eckey->group, point) <= 0) { |
348 | 0 | ECerror(EC_R_WRONG_ORDER); |
349 | 0 | goto err; |
350 | 0 | } |
351 | | /* |
352 | | * in case the priv_key is present : check if generator * priv_key == |
353 | | * pub_key |
354 | | */ |
355 | 0 | if (eckey->priv_key) { |
356 | 0 | if (BN_cmp(eckey->priv_key, order) >= 0) { |
357 | 0 | ECerror(EC_R_WRONG_ORDER); |
358 | 0 | goto err; |
359 | 0 | } |
360 | 0 | if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, |
361 | 0 | NULL, NULL, ctx)) { |
362 | 0 | ECerror(ERR_R_EC_LIB); |
363 | 0 | goto err; |
364 | 0 | } |
365 | 0 | if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, |
366 | 0 | ctx) != 0) { |
367 | 0 | ECerror(EC_R_INVALID_PRIVATE_KEY); |
368 | 0 | goto err; |
369 | 0 | } |
370 | 0 | } |
371 | 0 | ok = 1; |
372 | 0 | err: |
373 | 0 | BN_CTX_free(ctx); |
374 | 0 | EC_POINT_free(point); |
375 | 0 | return (ok); |
376 | 0 | } |
377 | | |
378 | | int |
379 | | EC_KEY_set_public_key_affine_coordinates(EC_KEY * key, BIGNUM * x, BIGNUM * y) |
380 | 0 | { |
381 | 0 | BN_CTX *ctx = NULL; |
382 | 0 | BIGNUM *tx, *ty; |
383 | 0 | EC_POINT *point = NULL; |
384 | 0 | int ok = 0; |
385 | |
|
386 | 0 | if (!key || !key->group || !x || !y) { |
387 | 0 | ECerror(ERR_R_PASSED_NULL_PARAMETER); |
388 | 0 | return 0; |
389 | 0 | } |
390 | 0 | ctx = BN_CTX_new(); |
391 | 0 | if (!ctx) |
392 | 0 | goto err; |
393 | | |
394 | 0 | point = EC_POINT_new(key->group); |
395 | |
|
396 | 0 | if (!point) |
397 | 0 | goto err; |
398 | | |
399 | 0 | if ((tx = BN_CTX_get(ctx)) == NULL) |
400 | 0 | goto err; |
401 | 0 | if ((ty = BN_CTX_get(ctx)) == NULL) |
402 | 0 | goto err; |
403 | | |
404 | 0 | if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx)) |
405 | 0 | goto err; |
406 | 0 | if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx)) |
407 | 0 | goto err; |
408 | | /* |
409 | | * Check if retrieved coordinates match originals: if not values are |
410 | | * out of range. |
411 | | */ |
412 | 0 | if (BN_cmp(x, tx) || BN_cmp(y, ty)) { |
413 | 0 | ECerror(EC_R_COORDINATES_OUT_OF_RANGE); |
414 | 0 | goto err; |
415 | 0 | } |
416 | 0 | if (!EC_KEY_set_public_key(key, point)) |
417 | 0 | goto err; |
418 | | |
419 | 0 | if (EC_KEY_check_key(key) == 0) |
420 | 0 | goto err; |
421 | | |
422 | 0 | ok = 1; |
423 | |
|
424 | 0 | err: |
425 | 0 | BN_CTX_free(ctx); |
426 | 0 | EC_POINT_free(point); |
427 | 0 | return ok; |
428 | |
|
429 | 0 | } |
430 | | |
431 | | const EC_GROUP * |
432 | | EC_KEY_get0_group(const EC_KEY * key) |
433 | 1.24k | { |
434 | 1.24k | return key->group; |
435 | 1.24k | } |
436 | | |
437 | | int |
438 | | EC_KEY_set_group(EC_KEY * key, const EC_GROUP * group) |
439 | 1.47k | { |
440 | 1.47k | if (key->meth->set_group != NULL && |
441 | 1.47k | key->meth->set_group(key, group) == 0) |
442 | 0 | return 0; |
443 | 1.47k | EC_GROUP_free(key->group); |
444 | 1.47k | key->group = EC_GROUP_dup(group); |
445 | 1.47k | return (key->group == NULL) ? 0 : 1; |
446 | 1.47k | } |
447 | | |
448 | | const BIGNUM * |
449 | | EC_KEY_get0_private_key(const EC_KEY * key) |
450 | 1.20k | { |
451 | 1.20k | return key->priv_key; |
452 | 1.20k | } |
453 | | |
454 | | int |
455 | | EC_KEY_set_private_key(EC_KEY * key, const BIGNUM * priv_key) |
456 | 688 | { |
457 | 688 | if (key->meth->set_private != NULL && |
458 | 688 | key->meth->set_private(key, priv_key) == 0) |
459 | 0 | return 0; |
460 | 688 | BN_clear_free(key->priv_key); |
461 | 688 | key->priv_key = BN_dup(priv_key); |
462 | 688 | return (key->priv_key == NULL) ? 0 : 1; |
463 | 688 | } |
464 | | |
465 | | const EC_POINT * |
466 | | EC_KEY_get0_public_key(const EC_KEY * key) |
467 | 463 | { |
468 | 463 | return key->pub_key; |
469 | 463 | } |
470 | | |
471 | | int |
472 | | EC_KEY_set_public_key(EC_KEY * key, const EC_POINT * pub_key) |
473 | 504 | { |
474 | 504 | if (key->meth->set_public != NULL && |
475 | 504 | key->meth->set_public(key, pub_key) == 0) |
476 | 0 | return 0; |
477 | 504 | EC_POINT_free(key->pub_key); |
478 | 504 | key->pub_key = EC_POINT_dup(pub_key, key->group); |
479 | 504 | return (key->pub_key == NULL) ? 0 : 1; |
480 | 504 | } |
481 | | |
482 | | unsigned int |
483 | | EC_KEY_get_enc_flags(const EC_KEY * key) |
484 | 0 | { |
485 | 0 | return key->enc_flag; |
486 | 0 | } |
487 | | |
488 | | void |
489 | | EC_KEY_set_enc_flags(EC_KEY * key, unsigned int flags) |
490 | 0 | { |
491 | 0 | key->enc_flag = flags; |
492 | 0 | } |
493 | | |
494 | | point_conversion_form_t |
495 | | EC_KEY_get_conv_form(const EC_KEY * key) |
496 | 0 | { |
497 | 0 | return key->conv_form; |
498 | 0 | } |
499 | | |
500 | | void |
501 | | EC_KEY_set_conv_form(EC_KEY * key, point_conversion_form_t cform) |
502 | 0 | { |
503 | 0 | key->conv_form = cform; |
504 | 0 | if (key->group != NULL) |
505 | 0 | EC_GROUP_set_point_conversion_form(key->group, cform); |
506 | 0 | } |
507 | | |
508 | | void * |
509 | | EC_KEY_get_key_method_data(EC_KEY *key, |
510 | | void *(*dup_func) (void *), |
511 | | void (*free_func) (void *), |
512 | | void (*clear_free_func) (void *)) |
513 | 1.63k | { |
514 | 1.63k | void *ret; |
515 | | |
516 | 1.63k | CRYPTO_r_lock(CRYPTO_LOCK_EC); |
517 | 1.63k | ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); |
518 | 1.63k | CRYPTO_r_unlock(CRYPTO_LOCK_EC); |
519 | | |
520 | 1.63k | return ret; |
521 | 1.63k | } |
522 | | |
523 | | void * |
524 | | EC_KEY_insert_key_method_data(EC_KEY * key, void *data, |
525 | | void *(*dup_func) (void *), |
526 | | void (*free_func) (void *), |
527 | | void (*clear_free_func) (void *)) |
528 | 855 | { |
529 | 855 | EC_EXTRA_DATA *ex_data; |
530 | | |
531 | 855 | CRYPTO_w_lock(CRYPTO_LOCK_EC); |
532 | 855 | ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); |
533 | 855 | if (ex_data == NULL) |
534 | 855 | EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func); |
535 | 855 | CRYPTO_w_unlock(CRYPTO_LOCK_EC); |
536 | | |
537 | 855 | return ex_data; |
538 | 855 | } |
539 | | |
540 | | void |
541 | | EC_KEY_set_asn1_flag(EC_KEY * key, int flag) |
542 | 0 | { |
543 | 0 | if (key->group != NULL) |
544 | 0 | EC_GROUP_set_asn1_flag(key->group, flag); |
545 | 0 | } |
546 | | |
547 | | int |
548 | | EC_KEY_precompute_mult(EC_KEY * key, BN_CTX * ctx) |
549 | 0 | { |
550 | 0 | if (key->group == NULL) |
551 | 0 | return 0; |
552 | 0 | return EC_GROUP_precompute_mult(key->group, ctx); |
553 | 0 | } |
554 | | |
555 | | int |
556 | | EC_KEY_get_flags(const EC_KEY * key) |
557 | 0 | { |
558 | 0 | return key->flags; |
559 | 0 | } |
560 | | |
561 | | void |
562 | | EC_KEY_set_flags(EC_KEY * key, int flags) |
563 | 0 | { |
564 | 0 | key->flags |= flags; |
565 | 0 | } |
566 | | |
567 | | void |
568 | | EC_KEY_clear_flags(EC_KEY * key, int flags) |
569 | 0 | { |
570 | 0 | key->flags &= ~flags; |
571 | 0 | } |