/src/openssl/crypto/ec/ec_key.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* crypto/ec/ec_key.c */ |
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 | | #include "ec_lcl.h" |
66 | | #include <openssl/err.h> |
67 | | #ifdef OPENSSL_FIPS |
68 | | # include <openssl/fips.h> |
69 | | #endif |
70 | | |
71 | | EC_KEY *EC_KEY_new(void) |
72 | 0 | { |
73 | 0 | EC_KEY *ret; |
74 | |
|
75 | 0 | ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); |
76 | 0 | if (ret == NULL) { |
77 | 0 | ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); |
78 | 0 | return (NULL); |
79 | 0 | } |
80 | | |
81 | 0 | ret->version = 1; |
82 | 0 | ret->flags = 0; |
83 | 0 | ret->group = NULL; |
84 | 0 | ret->pub_key = NULL; |
85 | 0 | ret->priv_key = NULL; |
86 | 0 | ret->enc_flag = 0; |
87 | 0 | ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; |
88 | 0 | ret->references = 1; |
89 | 0 | ret->method_data = NULL; |
90 | 0 | return (ret); |
91 | 0 | } |
92 | | |
93 | | EC_KEY *EC_KEY_new_by_curve_name(int nid) |
94 | 0 | { |
95 | 0 | EC_KEY *ret = EC_KEY_new(); |
96 | 0 | if (ret == NULL) |
97 | 0 | return NULL; |
98 | 0 | ret->group = EC_GROUP_new_by_curve_name(nid); |
99 | 0 | if (ret->group == NULL) { |
100 | 0 | EC_KEY_free(ret); |
101 | 0 | return NULL; |
102 | 0 | } |
103 | 0 | return ret; |
104 | 0 | } |
105 | | |
106 | | void EC_KEY_free(EC_KEY *r) |
107 | 0 | { |
108 | 0 | int i; |
109 | |
|
110 | 0 | if (r == NULL) |
111 | 0 | return; |
112 | | |
113 | 0 | i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); |
114 | | #ifdef REF_PRINT |
115 | | REF_PRINT("EC_KEY", r); |
116 | | #endif |
117 | 0 | if (i > 0) |
118 | 0 | return; |
119 | | #ifdef REF_CHECK |
120 | | if (i < 0) { |
121 | | fprintf(stderr, "EC_KEY_free, bad reference count\n"); |
122 | | abort(); |
123 | | } |
124 | | #endif |
125 | | |
126 | 0 | if (r->group != NULL) |
127 | 0 | EC_GROUP_free(r->group); |
128 | 0 | if (r->pub_key != NULL) |
129 | 0 | EC_POINT_free(r->pub_key); |
130 | 0 | if (r->priv_key != NULL) |
131 | 0 | BN_clear_free(r->priv_key); |
132 | |
|
133 | 0 | EC_EX_DATA_free_all_data(&r->method_data); |
134 | |
|
135 | 0 | OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); |
136 | |
|
137 | 0 | OPENSSL_free(r); |
138 | 0 | } |
139 | | |
140 | | EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) |
141 | 0 | { |
142 | 0 | EC_EXTRA_DATA *d; |
143 | |
|
144 | 0 | if (dest == NULL || src == NULL) { |
145 | 0 | ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); |
146 | 0 | return NULL; |
147 | 0 | } |
148 | | /* copy the parameters */ |
149 | 0 | if (src->group) { |
150 | 0 | const EC_METHOD *meth = EC_GROUP_method_of(src->group); |
151 | | /* clear the old group */ |
152 | 0 | if (dest->group) |
153 | 0 | EC_GROUP_free(dest->group); |
154 | 0 | dest->group = EC_GROUP_new(meth); |
155 | 0 | if (dest->group == NULL) |
156 | 0 | return NULL; |
157 | 0 | if (!EC_GROUP_copy(dest->group, src->group)) |
158 | 0 | return NULL; |
159 | 0 | } |
160 | | /* copy the public key */ |
161 | 0 | if (src->pub_key && src->group) { |
162 | 0 | if (dest->pub_key) |
163 | 0 | EC_POINT_free(dest->pub_key); |
164 | 0 | dest->pub_key = EC_POINT_new(src->group); |
165 | 0 | if (dest->pub_key == NULL) |
166 | 0 | return NULL; |
167 | 0 | if (!EC_POINT_copy(dest->pub_key, src->pub_key)) |
168 | 0 | return NULL; |
169 | 0 | } |
170 | | /* copy the private key */ |
171 | 0 | if (src->priv_key) { |
172 | 0 | if (dest->priv_key == NULL) { |
173 | 0 | dest->priv_key = BN_new(); |
174 | 0 | if (dest->priv_key == NULL) |
175 | 0 | return NULL; |
176 | 0 | } |
177 | 0 | if (!BN_copy(dest->priv_key, src->priv_key)) |
178 | 0 | return NULL; |
179 | 0 | } |
180 | | /* copy method/extra data */ |
181 | 0 | EC_EX_DATA_free_all_data(&dest->method_data); |
182 | |
|
183 | 0 | for (d = src->method_data; d != NULL; d = d->next) { |
184 | 0 | void *t = d->dup_func(d->data); |
185 | |
|
186 | 0 | if (t == NULL) |
187 | 0 | return 0; |
188 | 0 | if (!EC_EX_DATA_set_data |
189 | 0 | (&dest->method_data, t, d->dup_func, d->free_func, |
190 | 0 | d->clear_free_func)) |
191 | 0 | return 0; |
192 | 0 | } |
193 | | |
194 | | /* copy the rest */ |
195 | 0 | dest->enc_flag = src->enc_flag; |
196 | 0 | dest->conv_form = src->conv_form; |
197 | 0 | dest->version = src->version; |
198 | 0 | dest->flags = src->flags; |
199 | |
|
200 | 0 | return dest; |
201 | 0 | } |
202 | | |
203 | | EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) |
204 | 0 | { |
205 | 0 | EC_KEY *ret = EC_KEY_new(); |
206 | 0 | if (ret == NULL) |
207 | 0 | return NULL; |
208 | 0 | if (EC_KEY_copy(ret, ec_key) == NULL) { |
209 | 0 | EC_KEY_free(ret); |
210 | 0 | return NULL; |
211 | 0 | } |
212 | 0 | return ret; |
213 | 0 | } |
214 | | |
215 | | int EC_KEY_up_ref(EC_KEY *r) |
216 | 0 | { |
217 | 0 | int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); |
218 | | #ifdef REF_PRINT |
219 | | REF_PRINT("EC_KEY", r); |
220 | | #endif |
221 | | #ifdef REF_CHECK |
222 | | if (i < 2) { |
223 | | fprintf(stderr, "EC_KEY_up, bad reference count\n"); |
224 | | abort(); |
225 | | } |
226 | | #endif |
227 | 0 | return ((i > 1) ? 1 : 0); |
228 | 0 | } |
229 | | |
230 | | int EC_KEY_generate_key(EC_KEY *eckey) |
231 | 0 | { |
232 | 0 | int ok = 0; |
233 | 0 | BN_CTX *ctx = NULL; |
234 | 0 | BIGNUM *priv_key = NULL, *order = NULL; |
235 | 0 | EC_POINT *pub_key = NULL; |
236 | |
|
237 | | #ifdef OPENSSL_FIPS |
238 | | if (FIPS_mode()) |
239 | | return FIPS_ec_key_generate_key(eckey); |
240 | | #endif |
241 | |
|
242 | 0 | if (!eckey || !eckey->group) { |
243 | 0 | ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); |
244 | 0 | return 0; |
245 | 0 | } |
246 | | |
247 | 0 | if ((order = BN_new()) == NULL) |
248 | 0 | goto err; |
249 | 0 | if ((ctx = BN_CTX_new()) == NULL) |
250 | 0 | goto err; |
251 | | |
252 | 0 | if (eckey->priv_key == NULL) { |
253 | 0 | priv_key = BN_new(); |
254 | 0 | if (priv_key == NULL) |
255 | 0 | goto err; |
256 | 0 | } else |
257 | 0 | priv_key = eckey->priv_key; |
258 | | |
259 | 0 | if (!EC_GROUP_get_order(eckey->group, order, ctx)) |
260 | 0 | goto err; |
261 | | |
262 | 0 | do |
263 | 0 | if (!BN_rand_range(priv_key, order)) |
264 | 0 | goto err; |
265 | 0 | while (BN_is_zero(priv_key)) ; |
266 | | |
267 | 0 | if (eckey->pub_key == NULL) { |
268 | 0 | pub_key = EC_POINT_new(eckey->group); |
269 | 0 | if (pub_key == NULL) |
270 | 0 | goto err; |
271 | 0 | } else |
272 | 0 | pub_key = eckey->pub_key; |
273 | | |
274 | 0 | if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) |
275 | 0 | goto err; |
276 | | |
277 | 0 | eckey->priv_key = priv_key; |
278 | 0 | eckey->pub_key = pub_key; |
279 | |
|
280 | 0 | ok = 1; |
281 | |
|
282 | 0 | err: |
283 | 0 | if (order) |
284 | 0 | BN_free(order); |
285 | 0 | if (pub_key != NULL && eckey->pub_key == NULL) |
286 | 0 | EC_POINT_free(pub_key); |
287 | 0 | if (priv_key != NULL && eckey->priv_key == NULL) |
288 | 0 | BN_free(priv_key); |
289 | 0 | if (ctx != NULL) |
290 | 0 | BN_CTX_free(ctx); |
291 | 0 | return (ok); |
292 | 0 | } |
293 | | |
294 | | int EC_KEY_check_key(const EC_KEY *eckey) |
295 | 0 | { |
296 | 0 | int ok = 0; |
297 | 0 | BN_CTX *ctx = NULL; |
298 | 0 | const BIGNUM *order = NULL; |
299 | 0 | EC_POINT *point = NULL; |
300 | |
|
301 | 0 | if (!eckey || !eckey->group || !eckey->pub_key) { |
302 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); |
303 | 0 | return 0; |
304 | 0 | } |
305 | | |
306 | 0 | if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { |
307 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); |
308 | 0 | goto err; |
309 | 0 | } |
310 | | |
311 | 0 | if ((ctx = BN_CTX_new()) == NULL) |
312 | 0 | goto err; |
313 | 0 | if ((point = EC_POINT_new(eckey->group)) == NULL) |
314 | 0 | goto err; |
315 | | |
316 | | /* testing whether the pub_key is on the elliptic curve */ |
317 | 0 | if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { |
318 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); |
319 | 0 | goto err; |
320 | 0 | } |
321 | | /* testing whether pub_key * order is the point at infinity */ |
322 | 0 | order = &eckey->group->order; |
323 | 0 | if (BN_is_zero(order)) { |
324 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); |
325 | 0 | goto err; |
326 | 0 | } |
327 | 0 | if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { |
328 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); |
329 | 0 | goto err; |
330 | 0 | } |
331 | 0 | if (!EC_POINT_is_at_infinity(eckey->group, point)) { |
332 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); |
333 | 0 | goto err; |
334 | 0 | } |
335 | | /* |
336 | | * in case the priv_key is present : check if generator * priv_key == |
337 | | * pub_key |
338 | | */ |
339 | 0 | if (eckey->priv_key) { |
340 | 0 | if (BN_cmp(eckey->priv_key, order) >= 0) { |
341 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); |
342 | 0 | goto err; |
343 | 0 | } |
344 | 0 | if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, |
345 | 0 | NULL, NULL, ctx)) { |
346 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); |
347 | 0 | goto err; |
348 | 0 | } |
349 | 0 | if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { |
350 | 0 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); |
351 | 0 | goto err; |
352 | 0 | } |
353 | 0 | } |
354 | 0 | ok = 1; |
355 | 0 | err: |
356 | 0 | if (ctx != NULL) |
357 | 0 | BN_CTX_free(ctx); |
358 | 0 | if (point != NULL) |
359 | 0 | EC_POINT_free(point); |
360 | 0 | return (ok); |
361 | 0 | } |
362 | | |
363 | | int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, |
364 | | BIGNUM *y) |
365 | 0 | { |
366 | 0 | BN_CTX *ctx = NULL; |
367 | 0 | BIGNUM *tx, *ty; |
368 | 0 | EC_POINT *point = NULL; |
369 | 0 | int ok = 0; |
370 | 0 | #ifndef OPENSSL_NO_EC2M |
371 | 0 | int tmp_nid, is_char_two = 0; |
372 | 0 | #endif |
373 | |
|
374 | 0 | if (!key || !key->group || !x || !y) { |
375 | 0 | ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, |
376 | 0 | ERR_R_PASSED_NULL_PARAMETER); |
377 | 0 | return 0; |
378 | 0 | } |
379 | 0 | ctx = BN_CTX_new(); |
380 | 0 | if (ctx == NULL) |
381 | 0 | return 0; |
382 | 0 | BN_CTX_start(ctx); |
383 | 0 | point = EC_POINT_new(key->group); |
384 | |
|
385 | 0 | if (!point) |
386 | 0 | goto err; |
387 | | |
388 | 0 | tx = BN_CTX_get(ctx); |
389 | 0 | ty = BN_CTX_get(ctx); |
390 | 0 | if (ty == NULL) |
391 | 0 | goto err; |
392 | | |
393 | 0 | #ifndef OPENSSL_NO_EC2M |
394 | 0 | tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group)); |
395 | |
|
396 | 0 | if (tmp_nid == NID_X9_62_characteristic_two_field) |
397 | 0 | is_char_two = 1; |
398 | |
|
399 | 0 | if (is_char_two) { |
400 | 0 | if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point, |
401 | 0 | x, y, ctx)) |
402 | 0 | goto err; |
403 | 0 | if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point, |
404 | 0 | tx, ty, ctx)) |
405 | 0 | goto err; |
406 | 0 | } else |
407 | 0 | #endif |
408 | 0 | { |
409 | 0 | if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, |
410 | 0 | x, y, ctx)) |
411 | 0 | goto err; |
412 | 0 | if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, |
413 | 0 | tx, ty, ctx)) |
414 | 0 | goto err; |
415 | 0 | } |
416 | | /* |
417 | | * Check if retrieved coordinates match originals: if not values are out |
418 | | * of range. |
419 | | */ |
420 | 0 | if (BN_cmp(x, tx) || BN_cmp(y, ty)) { |
421 | 0 | ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, |
422 | 0 | EC_R_COORDINATES_OUT_OF_RANGE); |
423 | 0 | goto err; |
424 | 0 | } |
425 | | |
426 | 0 | if (!EC_KEY_set_public_key(key, point)) |
427 | 0 | goto err; |
428 | | |
429 | 0 | if (EC_KEY_check_key(key) == 0) |
430 | 0 | goto err; |
431 | | |
432 | 0 | ok = 1; |
433 | |
|
434 | 0 | err: |
435 | 0 | BN_CTX_end(ctx); |
436 | 0 | BN_CTX_free(ctx); |
437 | 0 | EC_POINT_free(point); |
438 | 0 | return ok; |
439 | |
|
440 | 0 | } |
441 | | |
442 | | const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) |
443 | 0 | { |
444 | 0 | return key->group; |
445 | 0 | } |
446 | | |
447 | | int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) |
448 | 0 | { |
449 | 0 | if (key->group != NULL) |
450 | 0 | EC_GROUP_free(key->group); |
451 | 0 | key->group = EC_GROUP_dup(group); |
452 | 0 | return (key->group == NULL) ? 0 : 1; |
453 | 0 | } |
454 | | |
455 | | const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) |
456 | 0 | { |
457 | 0 | return key->priv_key; |
458 | 0 | } |
459 | | |
460 | | int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) |
461 | 0 | { |
462 | 0 | if (key->priv_key) |
463 | 0 | BN_clear_free(key->priv_key); |
464 | 0 | key->priv_key = BN_dup(priv_key); |
465 | 0 | return (key->priv_key == NULL) ? 0 : 1; |
466 | 0 | } |
467 | | |
468 | | const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) |
469 | 0 | { |
470 | 0 | return key->pub_key; |
471 | 0 | } |
472 | | |
473 | | int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) |
474 | 0 | { |
475 | 0 | if (key->pub_key != NULL) |
476 | 0 | EC_POINT_free(key->pub_key); |
477 | 0 | key->pub_key = EC_POINT_dup(pub_key, key->group); |
478 | 0 | return (key->pub_key == NULL) ? 0 : 1; |
479 | 0 | } |
480 | | |
481 | | unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) |
482 | 0 | { |
483 | 0 | return key->enc_flag; |
484 | 0 | } |
485 | | |
486 | | void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) |
487 | 0 | { |
488 | 0 | key->enc_flag = flags; |
489 | 0 | } |
490 | | |
491 | | point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) |
492 | 0 | { |
493 | 0 | return key->conv_form; |
494 | 0 | } |
495 | | |
496 | | void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) |
497 | 0 | { |
498 | 0 | key->conv_form = cform; |
499 | 0 | if (key->group != NULL) |
500 | 0 | EC_GROUP_set_point_conversion_form(key->group, cform); |
501 | 0 | } |
502 | | |
503 | | void *EC_KEY_get_key_method_data(EC_KEY *key, |
504 | | void *(*dup_func) (void *), |
505 | | void (*free_func) (void *), |
506 | | void (*clear_free_func) (void *)) |
507 | 0 | { |
508 | 0 | void *ret; |
509 | |
|
510 | 0 | CRYPTO_r_lock(CRYPTO_LOCK_EC); |
511 | 0 | ret = |
512 | 0 | EC_EX_DATA_get_data(key->method_data, dup_func, free_func, |
513 | 0 | clear_free_func); |
514 | 0 | CRYPTO_r_unlock(CRYPTO_LOCK_EC); |
515 | |
|
516 | 0 | return ret; |
517 | 0 | } |
518 | | |
519 | | void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, |
520 | | void *(*dup_func) (void *), |
521 | | void (*free_func) (void *), |
522 | | void (*clear_free_func) (void *)) |
523 | 0 | { |
524 | 0 | EC_EXTRA_DATA *ex_data; |
525 | |
|
526 | 0 | CRYPTO_w_lock(CRYPTO_LOCK_EC); |
527 | 0 | ex_data = |
528 | 0 | EC_EX_DATA_get_data(key->method_data, dup_func, free_func, |
529 | 0 | clear_free_func); |
530 | 0 | if (ex_data == NULL) |
531 | 0 | EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, |
532 | 0 | clear_free_func); |
533 | 0 | CRYPTO_w_unlock(CRYPTO_LOCK_EC); |
534 | |
|
535 | 0 | return ex_data; |
536 | 0 | } |
537 | | |
538 | | void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) |
539 | 0 | { |
540 | 0 | if (key->group != NULL) |
541 | 0 | EC_GROUP_set_asn1_flag(key->group, flag); |
542 | 0 | } |
543 | | |
544 | | int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) |
545 | 0 | { |
546 | 0 | if (key->group == NULL) |
547 | 0 | return 0; |
548 | 0 | return EC_GROUP_precompute_mult(key->group, ctx); |
549 | 0 | } |
550 | | |
551 | | int EC_KEY_get_flags(const EC_KEY *key) |
552 | 0 | { |
553 | 0 | return key->flags; |
554 | 0 | } |
555 | | |
556 | | void EC_KEY_set_flags(EC_KEY *key, int flags) |
557 | 0 | { |
558 | 0 | key->flags |= flags; |
559 | 0 | } |
560 | | |
561 | | void EC_KEY_clear_flags(EC_KEY *key, int flags) |
562 | 0 | { |
563 | 0 | key->flags &= ~flags; |
564 | 0 | } |