Branch data Line data Source code
1 : : /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 : : * project 2006.
3 : : */
4 : : /* ====================================================================
5 : : * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions
9 : : * are met:
10 : : *
11 : : * 1. Redistributions of source code must retain the above copyright
12 : : * notice, this list of conditions and the following disclaimer.
13 : : *
14 : : * 2. Redistributions in binary form must reproduce the above copyright
15 : : * notice, this list of conditions and the following disclaimer in
16 : : * the documentation and/or other materials provided with the
17 : : * distribution.
18 : : *
19 : : * 3. All advertising materials mentioning features or use of this
20 : : * software must display the following acknowledgment:
21 : : * "This product includes software developed by the OpenSSL Project
22 : : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 : : *
24 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 : : * endorse or promote products derived from this software without
26 : : * prior written permission. For written permission, please contact
27 : : * licensing@OpenSSL.org.
28 : : *
29 : : * 5. Products derived from this software may not be called "OpenSSL"
30 : : * nor may "OpenSSL" appear in their names without prior written
31 : : * permission of the OpenSSL Project.
32 : : *
33 : : * 6. Redistributions of any form whatsoever must retain the following
34 : : * acknowledgment:
35 : : * "This product includes software developed by the OpenSSL Project
36 : : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 : : *
38 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
50 : : * ====================================================================
51 : : *
52 : : * This product includes cryptographic software written by Eric Young
53 : : * (eay@cryptsoft.com). This product includes software written by Tim
54 : : * Hudson (tjh@cryptsoft.com).
55 : : *
56 : : */
57 : :
58 : : #include <stdio.h>
59 : : #include "cryptlib.h"
60 : : #include <openssl/asn1t.h>
61 : : #include <openssl/x509.h>
62 : : #include <openssl/ec.h>
63 : : #include "ec_lcl.h"
64 : : #include <openssl/ecdsa.h>
65 : : #include <openssl/evp.h>
66 : : #include "evp_locl.h"
67 : :
68 : : /* EC pkey context structure */
69 : :
70 : : typedef struct
71 : : {
72 : : /* Key and paramgen group */
73 : : EC_GROUP *gen_group;
74 : : /* message digest */
75 : : const EVP_MD *md;
76 : : /* Duplicate key if custom cofactor needed */
77 : : EC_KEY *co_key;
78 : : /* Cofactor mode */
79 : : signed char cofactor_mode;
80 : : /* KDF (if any) to use for ECDH */
81 : : char kdf_type;
82 : : /* Message digest to use for key derivation */
83 : : const EVP_MD *kdf_md;
84 : : /* User key material */
85 : : unsigned char *kdf_ukm;
86 : : size_t kdf_ukmlen;
87 : : /* KDF output length */
88 : : size_t kdf_outlen;
89 : :
90 : : } EC_PKEY_CTX;
91 : :
92 : 9 : static int pkey_ec_init(EVP_PKEY_CTX *ctx)
93 : : {
94 : : EC_PKEY_CTX *dctx;
95 : 9 : dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
96 [ + - ]: 9 : if (!dctx)
97 : : return 0;
98 : 9 : dctx->gen_group = NULL;
99 : 9 : dctx->md = NULL;
100 : :
101 : 9 : dctx->cofactor_mode = -1;
102 : 9 : dctx->co_key = NULL;
103 : 9 : dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
104 : 9 : dctx->kdf_md = NULL;
105 : 9 : dctx->kdf_outlen = 0;
106 : 9 : dctx->kdf_ukm = NULL;
107 : 9 : dctx->kdf_ukmlen = 0;
108 : :
109 : 9 : ctx->data = dctx;
110 : :
111 : 9 : return 1;
112 : : }
113 : :
114 : 0 : static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
115 : : {
116 : : EC_PKEY_CTX *dctx, *sctx;
117 [ # # ]: 0 : if (!pkey_ec_init(dst))
118 : : return 0;
119 : 0 : sctx = src->data;
120 : 0 : dctx = dst->data;
121 [ # # ]: 0 : if (sctx->gen_group)
122 : : {
123 : 0 : dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
124 [ # # ]: 0 : if (!dctx->gen_group)
125 : : return 0;
126 : : }
127 : 0 : dctx->md = sctx->md;
128 : :
129 [ # # ]: 0 : if (sctx->co_key)
130 : : {
131 : 0 : dctx->co_key = EC_KEY_dup(sctx->co_key);
132 [ # # ]: 0 : if (!dctx->co_key)
133 : : return 0;
134 : : }
135 : 0 : dctx->kdf_type = sctx->kdf_type;
136 : 0 : dctx->kdf_md = sctx->kdf_md;
137 : 0 : dctx->kdf_outlen = sctx->kdf_outlen;
138 [ # # ]: 0 : if (sctx->kdf_ukm)
139 : : {
140 : 0 : dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
141 [ # # ]: 0 : if (!dctx->kdf_ukm)
142 : : return 0;
143 : : }
144 : : else
145 : 0 : dctx->kdf_ukm = NULL;
146 : 0 : dctx->kdf_ukmlen = sctx->kdf_ukmlen;
147 : 0 : return 1;
148 : : }
149 : :
150 : 9 : static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
151 : : {
152 : 9 : EC_PKEY_CTX *dctx = ctx->data;
153 [ + - ]: 9 : if (dctx)
154 : : {
155 [ - + ]: 9 : if (dctx->gen_group)
156 : 0 : EC_GROUP_free(dctx->gen_group);
157 [ + + ]: 9 : if (dctx->co_key)
158 : 2 : EC_KEY_free(dctx->co_key);
159 [ + + ]: 9 : if (dctx->kdf_ukm)
160 : 6 : OPENSSL_free(dctx->kdf_ukm);
161 : 9 : OPENSSL_free(dctx);
162 : : }
163 : 9 : }
164 : :
165 : 0 : static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
166 : : const unsigned char *tbs, size_t tbslen)
167 : : {
168 : : int ret, type;
169 : : unsigned int sltmp;
170 : 0 : EC_PKEY_CTX *dctx = ctx->data;
171 : 0 : EC_KEY *ec = ctx->pkey->pkey.ec;
172 : :
173 [ # # ]: 0 : if (!sig)
174 : : {
175 : 0 : *siglen = ECDSA_size(ec);
176 : 0 : return 1;
177 : : }
178 [ # # ]: 0 : else if(*siglen < (size_t)ECDSA_size(ec))
179 : : {
180 : 0 : ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
181 : 0 : return 0;
182 : : }
183 : :
184 [ # # ]: 0 : if (dctx->md)
185 : 0 : type = EVP_MD_type(dctx->md);
186 : : else
187 : : type = NID_sha1;
188 : :
189 : :
190 : 0 : ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
191 : :
192 [ # # ]: 0 : if (ret <= 0)
193 : : return ret;
194 : 0 : *siglen = (size_t)sltmp;
195 : 0 : return 1;
196 : : }
197 : :
198 : 0 : static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
199 : : const unsigned char *sig, size_t siglen,
200 : : const unsigned char *tbs, size_t tbslen)
201 : : {
202 : : int ret, type;
203 : 0 : EC_PKEY_CTX *dctx = ctx->data;
204 : 0 : EC_KEY *ec = ctx->pkey->pkey.ec;
205 : :
206 [ # # ]: 0 : if (dctx->md)
207 : 0 : type = EVP_MD_type(dctx->md);
208 : : else
209 : : type = NID_sha1;
210 : :
211 : 0 : ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
212 : :
213 : 0 : return ret;
214 : : }
215 : :
216 : 12 : static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
217 : : {
218 : : int ret;
219 : : size_t outlen;
220 : 12 : const EC_POINT *pubkey = NULL;
221 : : EC_KEY *eckey;
222 : 12 : EC_PKEY_CTX *dctx = ctx->data;
223 [ + - ][ - + ]: 12 : if (!ctx->pkey || !ctx->peerkey)
224 : : {
225 : 0 : ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
226 : 0 : return 0;
227 : : }
228 : :
229 [ + + ]: 12 : eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
230 : :
231 [ + + ]: 12 : if (!key)
232 : : {
233 : : const EC_GROUP *group;
234 : 6 : group = EC_KEY_get0_group(eckey);
235 : 6 : *keylen = (EC_GROUP_get_degree(group) + 7)/8;
236 : 6 : return 1;
237 : : }
238 : 6 : pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
239 : :
240 : : /* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
241 : : * not an error, the result is truncated.
242 : : */
243 : :
244 : 6 : outlen = *keylen;
245 : :
246 : 6 : ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
247 [ + - ]: 6 : if (ret < 0)
248 : : return ret;
249 : 6 : *keylen = ret;
250 : 6 : return 1;
251 : : }
252 : :
253 : 6 : static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
254 : : unsigned char *key, size_t *keylen)
255 : : {
256 : 6 : EC_PKEY_CTX *dctx = ctx->data;
257 : 6 : unsigned char *ktmp = NULL;
258 : : size_t ktmplen;
259 : 6 : int rv = 0;
260 [ - + ]: 6 : if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
261 : 0 : return pkey_ec_derive(ctx, key, keylen);
262 [ - + ]: 6 : if (!key)
263 : : {
264 : 0 : *keylen = dctx->kdf_outlen;
265 : 0 : return 1;
266 : : }
267 [ + - ]: 6 : if (*keylen != dctx->kdf_outlen)
268 : : return 0;
269 [ + - ]: 6 : if (!pkey_ec_derive(ctx, NULL, &ktmplen))
270 : : return 0;
271 : 6 : ktmp = OPENSSL_malloc(ktmplen);
272 [ + - ]: 6 : if (!ktmp)
273 : : return 0;
274 [ + - ]: 6 : if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
275 : : goto err;
276 : : /* Do KDF stuff */
277 [ + - ]: 6 : if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen,
278 : 6 : dctx->kdf_ukm, dctx->kdf_ukmlen,
279 : : dctx->kdf_md))
280 : : goto err;
281 : 6 : rv = 1;
282 : :
283 : : err:
284 [ + - ]: 6 : if (ktmp)
285 : : {
286 : 6 : OPENSSL_cleanse(ktmp, ktmplen);
287 : 6 : OPENSSL_free(ktmp);
288 : : }
289 : 6 : return rv;
290 : : }
291 : :
292 : 49 : static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
293 : : {
294 : 49 : EC_PKEY_CTX *dctx = ctx->data;
295 : : EC_GROUP *group;
296 [ - - + + : 49 : switch (type)
+ + + - +
- - - -
+ ]
297 : : {
298 : : case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
299 : 0 : group = EC_GROUP_new_by_curve_name(p1);
300 [ # # ]: 0 : if (group == NULL)
301 : : {
302 : 0 : ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
303 : 0 : return 0;
304 : : }
305 [ # # ]: 0 : if (dctx->gen_group)
306 : 0 : EC_GROUP_free(dctx->gen_group);
307 : 0 : dctx->gen_group = group;
308 : 0 : return 1;
309 : :
310 : : case EVP_PKEY_CTRL_EC_PARAM_ENC:
311 [ # # ]: 0 : if (!dctx->gen_group)
312 : : {
313 : 0 : ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
314 : 0 : return 0;
315 : : }
316 : 0 : EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
317 : 0 : return 1;
318 : :
319 : : case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
320 [ + + ]: 7 : if (p1 == -2)
321 : : {
322 [ + + ]: 3 : if (dctx->cofactor_mode != -1)
323 : 1 : return dctx->cofactor_mode;
324 : : else
325 : : {
326 : 2 : EC_KEY *ec_key = ctx->pkey->pkey.ec;
327 : 2 : return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
328 : : }
329 : : }
330 [ + - ]: 4 : else if (p1 < -1 || p1 > 1)
331 : : return -2;
332 : 4 : dctx->cofactor_mode = p1;
333 [ + - ]: 4 : if (p1 != -1)
334 : : {
335 : 4 : EC_KEY *ec_key = ctx->pkey->pkey.ec;
336 [ + - ]: 4 : if (!ec_key->group)
337 : : return -2;
338 : : /* If cofactor is 1 cofactor mode does nothing */
339 [ + - ][ + + ]: 4 : if (BN_is_one(&ec_key->group->cofactor))
[ - + ]
340 : : return 1;
341 [ + - ]: 2 : if (!dctx->co_key)
342 : : {
343 : 2 : dctx->co_key = EC_KEY_dup(ec_key);
344 [ + - ]: 2 : if (!dctx->co_key)
345 : : return 0;
346 : : }
347 [ + - ]: 2 : if (p1)
348 : 2 : EC_KEY_set_flags(dctx->co_key,
349 : : EC_FLAG_COFACTOR_ECDH);
350 : : else
351 : 0 : EC_KEY_clear_flags(dctx->co_key,
352 : : EC_FLAG_COFACTOR_ECDH);
353 : : }
354 [ # # ]: 0 : else if (dctx->co_key)
355 : : {
356 : 0 : EC_KEY_free(dctx->co_key);
357 : 0 : dctx->co_key = NULL;
358 : : }
359 : : return 1;
360 : :
361 : : case EVP_PKEY_CTRL_EC_KDF_TYPE:
362 [ + + ]: 9 : if (p1 == -2)
363 : 3 : return dctx->kdf_type;
364 [ + - ]: 6 : if (p1 != EVP_PKEY_ECDH_KDF_NONE &&
365 : : p1 != EVP_PKEY_ECDH_KDF_X9_62)
366 : : return -2;
367 : 6 : dctx->kdf_type = p1;
368 : 6 : return 1;
369 : :
370 : : case EVP_PKEY_CTRL_EC_KDF_MD:
371 : 6 : dctx->kdf_md = p2;
372 : 6 : return 1;
373 : :
374 : : case EVP_PKEY_CTRL_GET_EC_KDF_MD:
375 : 3 : *(const EVP_MD **)p2 = dctx->kdf_md;
376 : 3 : return 1;
377 : :
378 : : case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
379 [ + - ]: 6 : if (p1 <= 0)
380 : : return -2;
381 : 6 : dctx->kdf_outlen = (size_t)p1;
382 : 6 : return 1;
383 : :
384 : : case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
385 : 0 : *(int *)p2 = dctx->kdf_outlen;
386 : 0 : return 1;
387 : :
388 : : case EVP_PKEY_CTRL_EC_KDF_UKM:
389 [ - + ]: 6 : if (dctx->kdf_ukm)
390 : 0 : OPENSSL_free(dctx->kdf_ukm);
391 : 6 : dctx->kdf_ukm = p2;
392 [ + - ]: 6 : if (p2)
393 : 6 : dctx->kdf_ukmlen = p1;
394 : : else
395 : 0 : dctx->kdf_ukmlen = 0;
396 : : return 1;
397 : :
398 : : case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
399 : 0 : *(unsigned char **)p2 = dctx->kdf_ukm;
400 : 0 : return dctx->kdf_ukmlen;
401 : :
402 : : case EVP_PKEY_CTRL_MD:
403 [ # # # # ]: 0 : if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
404 [ # # ]: 0 : EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
405 [ # # ]: 0 : EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
406 [ # # ]: 0 : EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
407 [ # # ]: 0 : EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
408 : 0 : EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
409 : : {
410 : 0 : ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
411 : 0 : return 0;
412 : : }
413 : 0 : dctx->md = p2;
414 : 0 : return 1;
415 : :
416 : : case EVP_PKEY_CTRL_GET_MD:
417 : 0 : *(const EVP_MD **)p2 = dctx->md;
418 : 0 : return 1;
419 : :
420 : : case EVP_PKEY_CTRL_PEER_KEY:
421 : : /* Default behaviour is OK */
422 : : case EVP_PKEY_CTRL_DIGESTINIT:
423 : : case EVP_PKEY_CTRL_PKCS7_SIGN:
424 : : case EVP_PKEY_CTRL_CMS_SIGN:
425 : : return 1;
426 : :
427 : : default:
428 : 0 : return -2;
429 : :
430 : : }
431 : : }
432 : :
433 : 3 : static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
434 : : const char *type, const char *value)
435 : : {
436 [ - + ]: 3 : if (!strcmp(type, "ec_paramgen_curve"))
437 : : {
438 : : int nid;
439 : 0 : nid = EC_curve_nist2nid(value);
440 [ # # ]: 0 : if (nid == NID_undef)
441 : 0 : nid = OBJ_sn2nid(value);
442 [ # # ]: 0 : if (nid == NID_undef)
443 : 0 : nid = OBJ_ln2nid(value);
444 [ # # ]: 0 : if (nid == NID_undef)
445 : : {
446 : 0 : ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
447 : 0 : return 0;
448 : : }
449 : 0 : return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
450 : : }
451 [ - + ]: 3 : else if (!strcmp(type, "ec_param_enc"))
452 : : {
453 : : int param_enc;
454 [ # # ]: 0 : if (!strcmp(value, "explicit"))
455 : : param_enc = 0;
456 [ # # ]: 0 : else if (!strcmp(value, "named_curve"))
457 : : param_enc = OPENSSL_EC_NAMED_CURVE;
458 : : else
459 : : return -2;
460 : 0 : return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
461 : : }
462 [ + + ]: 3 : else if (!strcmp(type, "ecdh_kdf_md"))
463 : : {
464 : : const EVP_MD *md;
465 [ - + ]: 2 : if (!(md = EVP_get_digestbyname(value)))
466 : : {
467 : 0 : ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST);
468 : 0 : return 0;
469 : : }
470 : 2 : return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
471 : : }
472 [ + - ]: 1 : else if (!strcmp(type, "ecdh_cofactor_mode"))
473 : : {
474 : : int co_mode;
475 : 1 : co_mode = atoi(value);
476 : 1 : return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
477 : : }
478 : :
479 : : return -2;
480 : : }
481 : :
482 : 0 : static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
483 : : {
484 : 0 : EC_KEY *ec = NULL;
485 : 0 : EC_PKEY_CTX *dctx = ctx->data;
486 : 0 : int ret = 0;
487 [ # # ]: 0 : if (dctx->gen_group == NULL)
488 : : {
489 : 0 : ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
490 : 0 : return 0;
491 : : }
492 : 0 : ec = EC_KEY_new();
493 [ # # ]: 0 : if (!ec)
494 : : return 0;
495 : 0 : ret = EC_KEY_set_group(ec, dctx->gen_group);
496 [ # # ]: 0 : if (ret)
497 : 0 : EVP_PKEY_assign_EC_KEY(pkey, ec);
498 : : else
499 : 0 : EC_KEY_free(ec);
500 : 0 : return ret;
501 : : }
502 : :
503 : 3 : static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
504 : : {
505 : 3 : EC_KEY *ec = NULL;
506 : 3 : EC_PKEY_CTX *dctx = ctx->data;
507 [ - + ][ # # ]: 3 : if (ctx->pkey == NULL && dctx->gen_group == NULL)
508 : : {
509 : 0 : ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
510 : 0 : return 0;
511 : : }
512 : 3 : ec = EC_KEY_new();
513 [ + - ]: 3 : if (!ec)
514 : : return 0;
515 : 3 : EVP_PKEY_assign_EC_KEY(pkey, ec);
516 [ + - ]: 3 : if (ctx->pkey)
517 : : {
518 : : /* Note: if error return, pkey is freed by parent routine */
519 [ + - ]: 3 : if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
520 : : return 0;
521 : : }
522 : : else
523 : : {
524 [ # # ]: 0 : if (!EC_KEY_set_group(ec, dctx->gen_group))
525 : : return 0;
526 : : }
527 : 3 : return EC_KEY_generate_key(pkey->pkey.ec);
528 : : }
529 : :
530 : : const EVP_PKEY_METHOD ec_pkey_meth =
531 : : {
532 : : EVP_PKEY_EC,
533 : : 0,
534 : : pkey_ec_init,
535 : : pkey_ec_copy,
536 : : pkey_ec_cleanup,
537 : :
538 : : 0,
539 : : pkey_ec_paramgen,
540 : :
541 : : 0,
542 : : pkey_ec_keygen,
543 : :
544 : : 0,
545 : : pkey_ec_sign,
546 : :
547 : : 0,
548 : : pkey_ec_verify,
549 : :
550 : : 0,0,
551 : :
552 : : 0,0,0,0,
553 : :
554 : : 0,0,
555 : :
556 : : 0,0,
557 : :
558 : : 0,
559 : : pkey_ec_kdf_derive,
560 : :
561 : : pkey_ec_ctrl,
562 : : pkey_ec_ctrl_str
563 : :
564 : : };
|