]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/ec/ec_ameth.c
Merge branch 'master' of git.openssl.org:openssl
[thirdparty/openssl.git] / crypto / ec / ec_ameth.c
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/x509.h>
61 #include <openssl/ec.h>
62 #include <openssl/bn.h>
63 #ifndef OPENSSL_NO_CMS
64 #include <openssl/cms.h>
65 #endif
66 #include <openssl/asn1t.h>
67 #include "asn1_locl.h"
68
69 static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
70 static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
71
72 static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
73 {
74 const EC_GROUP *group;
75 int nid;
76 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL)
77 {
78 ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
79 return 0;
80 }
81 if (EC_GROUP_get_asn1_flag(group)
82 && (nid = EC_GROUP_get_curve_name(group)))
83 /* we have a 'named curve' => just set the OID */
84 {
85 *ppval = OBJ_nid2obj(nid);
86 *pptype = V_ASN1_OBJECT;
87 }
88 else /* explicit parameters */
89 {
90 ASN1_STRING *pstr = NULL;
91 pstr = ASN1_STRING_new();
92 if (!pstr)
93 return 0;
94 pstr->length = i2d_ECParameters(ec_key, &pstr->data);
95 if (pstr->length <= 0)
96 {
97 ASN1_STRING_free(pstr);
98 ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
99 return 0;
100 }
101 *ppval = pstr;
102 *pptype = V_ASN1_SEQUENCE;
103 }
104 return 1;
105 }
106
107 static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
108 {
109 EC_KEY *ec_key = pkey->pkey.ec;
110 void *pval = NULL;
111 int ptype;
112 unsigned char *penc = NULL, *p;
113 int penclen;
114
115 if (!eckey_param2type(&ptype, &pval, ec_key))
116 {
117 ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
118 return 0;
119 }
120 penclen = i2o_ECPublicKey(ec_key, NULL);
121 if (penclen <= 0)
122 goto err;
123 penc = OPENSSL_malloc(penclen);
124 if (!penc)
125 goto err;
126 p = penc;
127 penclen = i2o_ECPublicKey(ec_key, &p);
128 if (penclen <= 0)
129 goto err;
130 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
131 ptype, pval, penc, penclen))
132 return 1;
133 err:
134 if (ptype == V_ASN1_OBJECT)
135 ASN1_OBJECT_free(pval);
136 else
137 ASN1_STRING_free(pval);
138 if (penc)
139 OPENSSL_free(penc);
140 return 0;
141 }
142
143 static EC_KEY *eckey_type2param(int ptype, void *pval)
144 {
145 EC_KEY *eckey = NULL;
146 if (ptype == V_ASN1_SEQUENCE)
147 {
148 ASN1_STRING *pstr = pval;
149 const unsigned char *pm = NULL;
150 int pmlen;
151 pm = pstr->data;
152 pmlen = pstr->length;
153 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
154 {
155 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
156 goto ecerr;
157 }
158 }
159 else if (ptype == V_ASN1_OBJECT)
160 {
161 ASN1_OBJECT *poid = pval;
162 EC_GROUP *group;
163
164 /* type == V_ASN1_OBJECT => the parameters are given
165 * by an asn1 OID
166 */
167 if ((eckey = EC_KEY_new()) == NULL)
168 {
169 ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
170 goto ecerr;
171 }
172 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
173 if (group == NULL)
174 goto ecerr;
175 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
176 if (EC_KEY_set_group(eckey, group) == 0)
177 goto ecerr;
178 EC_GROUP_free(group);
179 }
180 else
181 {
182 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
183 goto ecerr;
184 }
185
186 return eckey;
187
188 ecerr:
189 if (eckey)
190 EC_KEY_free(eckey);
191 return NULL;
192 }
193
194 static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
195 {
196 const unsigned char *p = NULL;
197 void *pval;
198 int ptype, pklen;
199 EC_KEY *eckey = NULL;
200 X509_ALGOR *palg;
201
202 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
203 return 0;
204 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
205
206 eckey = eckey_type2param(ptype, pval);
207
208 if (!eckey)
209 {
210 ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
211 return 0;
212 }
213
214 /* We have parameters now set public key */
215 if (!o2i_ECPublicKey(&eckey, &p, pklen))
216 {
217 ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
218 goto ecerr;
219 }
220
221 EVP_PKEY_assign_EC_KEY(pkey, eckey);
222 return 1;
223
224 ecerr:
225 if (eckey)
226 EC_KEY_free(eckey);
227 return 0;
228 }
229
230 static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
231 {
232 int r;
233 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
234 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
235 *pb = EC_KEY_get0_public_key(b->pkey.ec);
236 r = EC_POINT_cmp(group, pa, pb, NULL);
237 if (r == 0)
238 return 1;
239 if (r == 1)
240 return 0;
241 return -2;
242 }
243
244 static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
245 {
246 const unsigned char *p = NULL;
247 void *pval;
248 int ptype, pklen;
249 EC_KEY *eckey = NULL;
250 X509_ALGOR *palg;
251
252 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
253 return 0;
254 X509_ALGOR_get0(NULL, &ptype, &pval, palg);
255
256 eckey = eckey_type2param(ptype, pval);
257
258 if (!eckey)
259 goto ecliberr;
260
261 /* We have parameters now set private key */
262 if (!d2i_ECPrivateKey(&eckey, &p, pklen))
263 {
264 ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
265 goto ecerr;
266 }
267
268 /* calculate public key (if necessary) */
269 if (EC_KEY_get0_public_key(eckey) == NULL)
270 {
271 const BIGNUM *priv_key;
272 const EC_GROUP *group;
273 EC_POINT *pub_key;
274 /* the public key was not included in the SEC1 private
275 * key => calculate the public key */
276 group = EC_KEY_get0_group(eckey);
277 pub_key = EC_POINT_new(group);
278 if (pub_key == NULL)
279 {
280 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
281 goto ecliberr;
282 }
283 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
284 {
285 EC_POINT_free(pub_key);
286 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
287 goto ecliberr;
288 }
289 priv_key = EC_KEY_get0_private_key(eckey);
290 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
291 {
292 EC_POINT_free(pub_key);
293 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
294 goto ecliberr;
295 }
296 if (EC_KEY_set_public_key(eckey, pub_key) == 0)
297 {
298 EC_POINT_free(pub_key);
299 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
300 goto ecliberr;
301 }
302 EC_POINT_free(pub_key);
303 }
304
305 EVP_PKEY_assign_EC_KEY(pkey, eckey);
306 return 1;
307
308 ecliberr:
309 ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
310 ecerr:
311 if (eckey)
312 EC_KEY_free(eckey);
313 return 0;
314 }
315
316 static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
317 {
318 EC_KEY *ec_key;
319 unsigned char *ep, *p;
320 int eplen, ptype;
321 void *pval;
322 unsigned int tmp_flags, old_flags;
323
324 ec_key = pkey->pkey.ec;
325
326 if (!eckey_param2type(&ptype, &pval, ec_key))
327 {
328 ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
329 return 0;
330 }
331
332 /* set the private key */
333
334 /* do not include the parameters in the SEC1 private key
335 * see PKCS#11 12.11 */
336 old_flags = EC_KEY_get_enc_flags(ec_key);
337 tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
338 EC_KEY_set_enc_flags(ec_key, tmp_flags);
339 eplen = i2d_ECPrivateKey(ec_key, NULL);
340 if (!eplen)
341 {
342 EC_KEY_set_enc_flags(ec_key, old_flags);
343 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
344 return 0;
345 }
346 ep = (unsigned char *) OPENSSL_malloc(eplen);
347 if (!ep)
348 {
349 EC_KEY_set_enc_flags(ec_key, old_flags);
350 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
351 return 0;
352 }
353 p = ep;
354 if (!i2d_ECPrivateKey(ec_key, &p))
355 {
356 EC_KEY_set_enc_flags(ec_key, old_flags);
357 OPENSSL_free(ep);
358 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
359 return 0;
360 }
361 /* restore old encoding flags */
362 EC_KEY_set_enc_flags(ec_key, old_flags);
363
364 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
365 ptype, pval, ep, eplen))
366 return 0;
367
368 return 1;
369 }
370
371 static int int_ec_size(const EVP_PKEY *pkey)
372 {
373 return ECDSA_size(pkey->pkey.ec);
374 }
375
376 static int ec_bits(const EVP_PKEY *pkey)
377 {
378 BIGNUM *order = BN_new();
379 const EC_GROUP *group;
380 int ret;
381
382 if (!order)
383 {
384 ERR_clear_error();
385 return 0;
386 }
387 group = EC_KEY_get0_group(pkey->pkey.ec);
388 if (!EC_GROUP_get_order(group, order, NULL))
389 {
390 ERR_clear_error();
391 return 0;
392 }
393
394 ret = BN_num_bits(order);
395 BN_free(order);
396 return ret;
397 }
398
399 static int ec_security_bits(const EVP_PKEY *pkey)
400 {
401 int ecbits = ec_bits(pkey);
402 if (ecbits >= 512)
403 return 256;
404 if (ecbits >= 384)
405 return 192;
406 if (ecbits >= 256)
407 return 128;
408 if (ecbits >= 224)
409 return 112;
410 if (ecbits >= 160)
411 return 80;
412 return ecbits / 2;
413 }
414
415 static int ec_missing_parameters(const EVP_PKEY *pkey)
416 {
417 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
418 return 1;
419 return 0;
420 }
421
422 static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
423 {
424 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
425 if (group == NULL)
426 return 0;
427 if (EC_KEY_set_group(to->pkey.ec, group) == 0)
428 return 0;
429 EC_GROUP_free(group);
430 return 1;
431 }
432
433 static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
434 {
435 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
436 *group_b = EC_KEY_get0_group(b->pkey.ec);
437 if (EC_GROUP_cmp(group_a, group_b, NULL))
438 return 0;
439 else
440 return 1;
441 }
442
443 static void int_ec_free(EVP_PKEY *pkey)
444 {
445 EC_KEY_free(pkey->pkey.ec);
446 }
447
448 static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
449 {
450 unsigned char *buffer=NULL;
451 const char *ecstr;
452 size_t buf_len=0, i;
453 int ret=0, reason=ERR_R_BIO_LIB;
454 BIGNUM *pub_key=NULL, *order=NULL;
455 BN_CTX *ctx=NULL;
456 const EC_GROUP *group;
457 const EC_POINT *public_key;
458 const BIGNUM *priv_key;
459
460 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
461 {
462 reason = ERR_R_PASSED_NULL_PARAMETER;
463 goto err;
464 }
465
466 ctx = BN_CTX_new();
467 if (ctx == NULL)
468 {
469 reason = ERR_R_MALLOC_FAILURE;
470 goto err;
471 }
472
473 if (ktype > 0)
474 {
475 public_key = EC_KEY_get0_public_key(x);
476 if (public_key != NULL)
477 {
478 if ((pub_key = EC_POINT_point2bn(group, public_key,
479 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
480 {
481 reason = ERR_R_EC_LIB;
482 goto err;
483 }
484 buf_len = (size_t)BN_num_bytes(pub_key);
485 }
486 }
487
488 if (ktype == 2)
489 {
490 priv_key = EC_KEY_get0_private_key(x);
491 if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
492 buf_len = i;
493 }
494 else
495 priv_key = NULL;
496
497 if (ktype > 0)
498 {
499 buf_len += 10;
500 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
501 {
502 reason = ERR_R_MALLOC_FAILURE;
503 goto err;
504 }
505 }
506 if (ktype == 2)
507 ecstr = "Private-Key";
508 else if (ktype == 1)
509 ecstr = "Public-Key";
510 else
511 ecstr = "ECDSA-Parameters";
512
513 if (!BIO_indent(bp, off, 128))
514 goto err;
515 if ((order = BN_new()) == NULL)
516 goto err;
517 if (!EC_GROUP_get_order(group, order, NULL))
518 goto err;
519 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
520 BN_num_bits(order)) <= 0) goto err;
521
522 if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
523 buffer, off))
524 goto err;
525 if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
526 buffer, off))
527 goto err;
528 if (!ECPKParameters_print(bp, group, off))
529 goto err;
530 ret=1;
531 err:
532 if (!ret)
533 ECerr(EC_F_DO_EC_KEY_PRINT, reason);
534 if (pub_key)
535 BN_free(pub_key);
536 if (order)
537 BN_free(order);
538 if (ctx)
539 BN_CTX_free(ctx);
540 if (buffer != NULL)
541 OPENSSL_free(buffer);
542 return(ret);
543 }
544
545 static int eckey_param_decode(EVP_PKEY *pkey,
546 const unsigned char **pder, int derlen)
547 {
548 EC_KEY *eckey;
549 if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
550 {
551 ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
552 return 0;
553 }
554 EVP_PKEY_assign_EC_KEY(pkey, eckey);
555 return 1;
556 }
557
558 static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
559 {
560 return i2d_ECParameters(pkey->pkey.ec, pder);
561 }
562
563 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
564 ASN1_PCTX *ctx)
565 {
566 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
567 }
568
569 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
570 ASN1_PCTX *ctx)
571 {
572 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
573 }
574
575
576 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
577 ASN1_PCTX *ctx)
578 {
579 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
580 }
581
582 static int old_ec_priv_decode(EVP_PKEY *pkey,
583 const unsigned char **pder, int derlen)
584 {
585 EC_KEY *ec;
586 if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
587 {
588 ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
589 return 0;
590 }
591 EVP_PKEY_assign_EC_KEY(pkey, ec);
592 return 1;
593 }
594
595 static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
596 {
597 return i2d_ECPrivateKey(pkey->pkey.ec, pder);
598 }
599
600 static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
601 {
602 switch (op)
603 {
604 case ASN1_PKEY_CTRL_PKCS7_SIGN:
605 if (arg1 == 0)
606 {
607 int snid, hnid;
608 X509_ALGOR *alg1, *alg2;
609 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
610 if (alg1 == NULL || alg1->algorithm == NULL)
611 return -1;
612 hnid = OBJ_obj2nid(alg1->algorithm);
613 if (hnid == NID_undef)
614 return -1;
615 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
616 return -1;
617 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
618 }
619 return 1;
620 #ifndef OPENSSL_NO_CMS
621 case ASN1_PKEY_CTRL_CMS_SIGN:
622 if (arg1 == 0)
623 {
624 int snid, hnid;
625 X509_ALGOR *alg1, *alg2;
626 CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
627 &alg1, &alg2);
628 if (alg1 == NULL || alg1->algorithm == NULL)
629 return -1;
630 hnid = OBJ_obj2nid(alg1->algorithm);
631 if (hnid == NID_undef)
632 return -1;
633 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
634 return -1;
635 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
636 }
637 return 1;
638
639 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
640 if (arg1 == 1)
641 return ecdh_cms_decrypt(arg2);
642 else if (arg1 == 0)
643 return ecdh_cms_encrypt(arg2);
644 return -2;
645
646 case ASN1_PKEY_CTRL_CMS_RI_TYPE:
647 *(int *)arg2 = CMS_RECIPINFO_AGREE;
648 return 1;
649 #endif
650
651 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
652 *(int *)arg2 = NID_sha1;
653 return 2;
654
655 default:
656 return -2;
657
658 }
659
660 }
661
662 const EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
663 {
664 EVP_PKEY_EC,
665 EVP_PKEY_EC,
666 0,
667 "EC",
668 "OpenSSL EC algorithm",
669
670 eckey_pub_decode,
671 eckey_pub_encode,
672 eckey_pub_cmp,
673 eckey_pub_print,
674
675 eckey_priv_decode,
676 eckey_priv_encode,
677 eckey_priv_print,
678
679 int_ec_size,
680 ec_bits,
681 ec_security_bits,
682
683 eckey_param_decode,
684 eckey_param_encode,
685 ec_missing_parameters,
686 ec_copy_parameters,
687 ec_cmp_parameters,
688 eckey_param_print,
689 0,
690
691 int_ec_free,
692 ec_pkey_ctrl,
693 old_ec_priv_decode,
694 old_ec_priv_encode
695 };
696
697 #ifndef OPENSSL_NO_CMS
698
699 static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
700 X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
701 {
702 ASN1_OBJECT *aoid;
703 int atype;
704 void *aval;
705 int rv = 0;
706 EVP_PKEY *pkpeer = NULL;
707 EC_KEY *ecpeer = NULL;
708 const unsigned char *p;
709 int plen;
710 X509_ALGOR_get0(&aoid, &atype, &aval, alg);
711 if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
712 goto err;
713 /* If absent parameters get group from main key */
714 if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL)
715 {
716 const EC_GROUP *grp;
717 EVP_PKEY *pk;
718 pk = EVP_PKEY_CTX_get0_pkey(pctx);
719 if (!pk)
720 goto err;
721 grp = EC_KEY_get0_group(pk->pkey.ec);
722 ecpeer = EC_KEY_new();
723 if (!ecpeer)
724 goto err;
725 if (!EC_KEY_set_group(ecpeer, grp))
726 goto err;
727 }
728 else
729 {
730 ecpeer = eckey_type2param(atype, aval);
731 if (!ecpeer)
732 goto err;
733 }
734 /* We have parameters now set public key */
735 plen = ASN1_STRING_length(pubkey);
736 p = ASN1_STRING_data(pubkey);
737 if (!p || !plen)
738 goto err;
739 if (!o2i_ECPublicKey(&ecpeer, &p, plen))
740 goto err;
741 pkpeer = EVP_PKEY_new();
742 if (!pkpeer)
743 goto err;
744 EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
745 if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
746 rv = 1;
747 err:
748 if (ecpeer)
749 EC_KEY_free(ecpeer);
750 if (pkpeer)
751 EVP_PKEY_free(pkpeer);
752 return rv;
753 }
754 /* Set KDF parameters based on KDF NID */
755 static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
756 {
757 int kdf_nid, kdfmd_nid, cofactor;
758 const EVP_MD *kdf_md;
759 if (eckdf_nid == NID_undef)
760 return 0;
761
762 /* Lookup KDF type, cofactor mode and digest */
763 if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
764 return 0;
765
766 if (kdf_nid == NID_dh_std_kdf)
767 cofactor = 0;
768 else if (kdf_nid == NID_dh_cofactor_kdf)
769 cofactor = 1;
770 else return 0;
771
772 if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
773 return 0;
774
775 if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0)
776 return 0;
777
778 kdf_md = EVP_get_digestbynid(kdfmd_nid);
779 if (!kdf_md)
780 return 0;
781
782 if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
783 return 0;
784 return 1;
785 }
786
787 static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
788 {
789 int rv = 0;
790
791 X509_ALGOR *alg, *kekalg = NULL;
792 ASN1_OCTET_STRING *ukm;
793 const unsigned char *p;
794 unsigned char *der = NULL;
795 int plen, keylen;
796 const EVP_CIPHER *kekcipher;
797 EVP_CIPHER_CTX *kekctx;
798
799 if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
800 return 0;
801
802 if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm)))
803 {
804 ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
805 return 0;
806 }
807
808 if (alg->parameter->type != V_ASN1_SEQUENCE)
809 return 0;
810
811 p = alg->parameter->value.sequence->data;
812 plen = alg->parameter->value.sequence->length;
813 kekalg = d2i_X509_ALGOR(NULL, &p, plen);
814 if (!kekalg)
815 goto err;
816 kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
817 if (!kekctx)
818 goto err;
819 kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
820 if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
821 goto err;
822 if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
823 goto err;
824 if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
825 goto err;
826
827 keylen = EVP_CIPHER_CTX_key_length(kekctx);
828 if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
829 goto err;
830
831 plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
832
833 if (!plen)
834 goto err;
835
836 if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
837 goto err;
838 der = NULL;
839
840 rv = 1;
841 err:
842 if (kekalg)
843 X509_ALGOR_free(kekalg);
844 if (der)
845 OPENSSL_free(der);
846 return rv;
847 }
848
849 static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
850 {
851 EVP_PKEY_CTX *pctx;
852 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
853 if (!pctx)
854 return 0;
855 /* See if we need to set peer key */
856 if (!EVP_PKEY_CTX_get0_peerkey(pctx))
857 {
858 X509_ALGOR *alg;
859 ASN1_BIT_STRING *pubkey;
860 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
861 NULL, NULL, NULL))
862 return 0;
863 if (!alg || !pubkey)
864 return 0;
865 if (!ecdh_cms_set_peerkey(pctx, alg, pubkey))
866 {
867 ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
868 return 0;
869 }
870 }
871 /* Set ECDH derivation parameters and initialise unwrap context */
872 if (!ecdh_cms_set_shared_info(pctx, ri))
873 {
874 ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
875 return 0;
876 }
877 return 1;
878 }
879
880 static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
881 {
882 EVP_PKEY_CTX *pctx;
883 EVP_PKEY *pkey;
884 EVP_CIPHER_CTX *ctx;
885 int keylen;
886 X509_ALGOR *talg, *wrap_alg = NULL;
887 ASN1_OBJECT *aoid;
888 ASN1_BIT_STRING *pubkey;
889 ASN1_STRING *wrap_str;
890 ASN1_OCTET_STRING *ukm;
891 unsigned char *penc = NULL;
892 int penclen;
893 int rv = 0;
894 int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
895 const EVP_MD *kdf_md;
896 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
897 if (!pctx)
898 return 0;
899 /* Get ephemeral key */
900 pkey = EVP_PKEY_CTX_get0_pkey(pctx);
901 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
902 NULL, NULL, NULL))
903 goto err;
904 X509_ALGOR_get0(&aoid, NULL, NULL, talg);
905 /* Is everything uninitialised? */
906 if (aoid == OBJ_nid2obj(NID_undef))
907 {
908
909 EC_KEY *eckey = pkey->pkey.ec;
910 /* Set the key */
911 unsigned char *p;
912
913 penclen = i2o_ECPublicKey(eckey, NULL);
914 if (penclen <= 0)
915 goto err;
916 penc = OPENSSL_malloc(penclen);
917 if (!penc)
918 goto err;
919 p = penc;
920 penclen = i2o_ECPublicKey(eckey, &p);
921 if (penclen <= 0)
922 goto err;
923 ASN1_STRING_set0(pubkey, penc, penclen);
924 pubkey->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
925 pubkey->flags|=ASN1_STRING_FLAG_BITS_LEFT;
926
927 penc = NULL;
928 X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
929 V_ASN1_UNDEF, NULL);
930 }
931
932 /* See if custom paraneters set */
933 kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
934 if (kdf_type <= 0)
935 goto err;
936 if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
937 goto err;
938 ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
939 if (ecdh_nid < 0)
940 goto err;
941 else if (ecdh_nid == 0)
942 ecdh_nid = NID_dh_std_kdf;
943 else if (ecdh_nid == 1)
944 ecdh_nid = NID_dh_cofactor_kdf;
945
946 if (kdf_type == EVP_PKEY_ECDH_KDF_NONE)
947 {
948 kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
949 if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
950 goto err;
951 }
952 else
953 /* Uknown KDF */
954 goto err;
955 if (kdf_md == NULL)
956 {
957 /* Fixme later for better MD */
958 kdf_md = EVP_sha1();
959 if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
960 goto err;
961 }
962
963 if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
964 goto err;
965
966 /* Lookup NID for KDF+cofactor+digest */
967
968 if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
969 goto err;
970 /* Get wrap NID */
971 ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
972 wrap_nid = EVP_CIPHER_CTX_type(ctx);
973 keylen = EVP_CIPHER_CTX_key_length(ctx);
974
975 /* Package wrap algorithm in an AlgorithmIdentifier */
976
977 wrap_alg = X509_ALGOR_new();
978 if (!wrap_alg)
979 goto err;
980 wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
981 wrap_alg->parameter = ASN1_TYPE_new();
982 if (!wrap_alg->parameter)
983 goto err;
984 if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
985 goto err;
986 if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef)
987 {
988 ASN1_TYPE_free(wrap_alg->parameter);
989 wrap_alg->parameter = NULL;
990 }
991
992 if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
993 goto err;
994
995 penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
996
997 if (!penclen)
998 goto err;
999
1000 if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
1001 goto err;
1002 penc = NULL;
1003
1004 /* Now need to wrap encoding of wrap AlgorithmIdentifier into
1005 * parameter of another AlgorithmIdentifier.
1006 */
1007 penclen = i2d_X509_ALGOR(wrap_alg, &penc);
1008 if (!penc || !penclen)
1009 goto err;
1010 wrap_str = ASN1_STRING_new();
1011 if (!wrap_str)
1012 goto err;
1013 ASN1_STRING_set0(wrap_str, penc, penclen);
1014 penc = NULL;
1015 X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
1016
1017 rv = 1;
1018
1019 err:
1020 if (penc)
1021 OPENSSL_free(penc);
1022 if (wrap_alg)
1023 X509_ALGOR_free(wrap_alg);
1024 return rv;
1025 }
1026
1027 #endif