]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/ec/ec_ameth.c
Add functions returning security bits.
[thirdparty/openssl.git] / crypto / ec / ec_ameth.c
CommitLineData
2e597528 1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
448be743
DSH
2 * project 2006.
3 */
4/* ====================================================================
35208f36 5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
448be743
DSH
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>
1e26a8ba 62#include <openssl/bn.h>
8931b30d
DSH
63#ifndef OPENSSL_NO_CMS
64#include <openssl/cms.h>
65#endif
88e20b85 66#include <openssl/asn1t.h>
18e377b4 67#include "asn1_locl.h"
448be743 68
88e20b85
DSH
69static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
70static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
71
448be743
DSH
72static 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);
94782e0e 95 if (pstr->length <= 0)
448be743
DSH
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
6f81892e 107static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
448be743
DSH
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;
bd50e313 130 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
448be743
DSH
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
143static 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
194static 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
6f81892e
DSH
230static 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
448be743
DSH
244static 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
6f81892e 316static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
448be743
DSH
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 }
360 /* restore old encoding flags */
361 EC_KEY_set_enc_flags(ec_key, old_flags);
362
363 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
364 ptype, pval, ep, eplen))
365 return 0;
366
367 return 1;
368}
369
6f81892e
DSH
370static int int_ec_size(const EVP_PKEY *pkey)
371 {
372 return ECDSA_size(pkey->pkey.ec);
373 }
374
375static int ec_bits(const EVP_PKEY *pkey)
376 {
377 BIGNUM *order = BN_new();
378 const EC_GROUP *group;
379 int ret;
380
381 if (!order)
382 {
383 ERR_clear_error();
384 return 0;
385 }
386 group = EC_KEY_get0_group(pkey->pkey.ec);
387 if (!EC_GROUP_get_order(group, order, NULL))
388 {
389 ERR_clear_error();
390 return 0;
391 }
392
393 ret = BN_num_bits(order);
394 BN_free(order);
395 return ret;
396 }
397
2514fa79
DSH
398static int ec_security_bits(const EVP_PKEY *pkey)
399 {
400 int ecbits = ec_bits(pkey);
401 if (ecbits >= 512)
402 return 256;
403 if (ecbits >= 384)
404 return 192;
405 if (ecbits >= 256)
406 return 128;
407 if (ecbits >= 224)
408 return 112;
409 if (ecbits >= 160)
410 return 80;
411 return ecbits / 2;
412 }
413
6f81892e
DSH
414static int ec_missing_parameters(const EVP_PKEY *pkey)
415 {
416 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
417 return 1;
418 return 0;
419 }
420
930b0c4b 421static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
6f81892e
DSH
422 {
423 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
424 if (group == NULL)
425 return 0;
426 if (EC_KEY_set_group(to->pkey.ec, group) == 0)
427 return 0;
428 EC_GROUP_free(group);
429 return 1;
430 }
431
930b0c4b 432static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
6f81892e
DSH
433 {
434 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
435 *group_b = EC_KEY_get0_group(b->pkey.ec);
436 if (EC_GROUP_cmp(group_a, group_b, NULL))
437 return 0;
438 else
439 return 1;
440 }
441
442static void int_ec_free(EVP_PKEY *pkey)
443 {
444 EC_KEY_free(pkey->pkey.ec);
445 }
446
35208f36
DSH
447static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
448 {
449 unsigned char *buffer=NULL;
450 const char *ecstr;
451 size_t buf_len=0, i;
452 int ret=0, reason=ERR_R_BIO_LIB;
453 BIGNUM *pub_key=NULL, *order=NULL;
454 BN_CTX *ctx=NULL;
455 const EC_GROUP *group;
456 const EC_POINT *public_key;
457 const BIGNUM *priv_key;
458
459 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
460 {
461 reason = ERR_R_PASSED_NULL_PARAMETER;
462 goto err;
463 }
464
465 ctx = BN_CTX_new();
466 if (ctx == NULL)
467 {
468 reason = ERR_R_MALLOC_FAILURE;
469 goto err;
470 }
471
35208f36
DSH
472 if (ktype > 0)
473 {
474 public_key = EC_KEY_get0_public_key(x);
475 if ((pub_key = EC_POINT_point2bn(group, public_key,
476 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
477 {
478 reason = ERR_R_EC_LIB;
479 goto err;
480 }
b2c0518e
DSH
481 if (pub_key)
482 buf_len = (size_t)BN_num_bytes(pub_key);
35208f36 483 }
35208f36
DSH
484
485 if (ktype == 2)
486 {
35208f36 487 priv_key = EC_KEY_get0_private_key(x);
b2c0518e
DSH
488 if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
489 buf_len = i;
35208f36
DSH
490 }
491 else
492 priv_key = NULL;
493
494 if (ktype > 0)
495 {
496 buf_len += 10;
497 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
498 {
499 reason = ERR_R_MALLOC_FAILURE;
500 goto err;
501 }
502 }
503 if (ktype == 2)
504 ecstr = "Private-Key";
505 else if (ktype == 1)
506 ecstr = "Public-Key";
507 else
508 ecstr = "ECDSA-Parameters";
509
510 if (!BIO_indent(bp, off, 128))
511 goto err;
512 if ((order = BN_new()) == NULL)
513 goto err;
514 if (!EC_GROUP_get_order(group, order, NULL))
515 goto err;
516 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
517 BN_num_bits(order)) <= 0) goto err;
518
519 if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
520 buffer, off))
521 goto err;
522 if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
523 buffer, off))
524 goto err;
525 if (!ECPKParameters_print(bp, group, off))
526 goto err;
527 ret=1;
528err:
529 if (!ret)
5c95c2ac 530 ECerr(EC_F_DO_EC_KEY_PRINT, reason);
35208f36
DSH
531 if (pub_key)
532 BN_free(pub_key);
533 if (order)
534 BN_free(order);
535 if (ctx)
536 BN_CTX_free(ctx);
537 if (buffer != NULL)
538 OPENSSL_free(buffer);
539 return(ret);
540 }
541
3e4585c8 542static int eckey_param_decode(EVP_PKEY *pkey,
6343829a 543 const unsigned char **pder, int derlen)
3e4585c8
DSH
544 {
545 EC_KEY *eckey;
546 if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
547 {
548 ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
549 return 0;
550 }
551 EVP_PKEY_assign_EC_KEY(pkey, eckey);
552 return 1;
553 }
554
555static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
556 {
557 return i2d_ECParameters(pkey->pkey.ec, pder);
558 }
559
35208f36
DSH
560static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
561 ASN1_PCTX *ctx)
562 {
563 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
564 }
565
566static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
567 ASN1_PCTX *ctx)
568 {
569 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
570 }
571
572
573static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
574 ASN1_PCTX *ctx)
575 {
576 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
577 }
578
e4263314 579static int old_ec_priv_decode(EVP_PKEY *pkey,
6343829a 580 const unsigned char **pder, int derlen)
e4263314
DSH
581 {
582 EC_KEY *ec;
583 if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
584 {
5c95c2ac 585 ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
e4263314
DSH
586 return 0;
587 }
588 EVP_PKEY_assign_EC_KEY(pkey, ec);
589 return 1;
590 }
591
592static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
593 {
594 return i2d_ECPrivateKey(pkey->pkey.ec, pder);
595 }
596
492a9e24
DSH
597static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
598 {
599 switch (op)
600 {
601 case ASN1_PKEY_CTRL_PKCS7_SIGN:
602 if (arg1 == 0)
603 {
06e2dd03 604 int snid, hnid;
492a9e24
DSH
605 X509_ALGOR *alg1, *alg2;
606 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
06e2dd03
NL
607 if (alg1 == NULL || alg1->algorithm == NULL)
608 return -1;
609 hnid = OBJ_obj2nid(alg1->algorithm);
610 if (hnid == NID_undef)
611 return -1;
612 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
613 return -1;
614 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
492a9e24
DSH
615 }
616 return 1;
8931b30d
DSH
617#ifndef OPENSSL_NO_CMS
618 case ASN1_PKEY_CTRL_CMS_SIGN:
619 if (arg1 == 0)
620 {
621 int snid, hnid;
622 X509_ALGOR *alg1, *alg2;
623 CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
624 &alg1, &alg2);
625 if (alg1 == NULL || alg1->algorithm == NULL)
626 return -1;
627 hnid = OBJ_obj2nid(alg1->algorithm);
628 if (hnid == NID_undef)
629 return -1;
630 if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
631 return -1;
632 X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
633 }
634 return 1;
88e20b85
DSH
635
636 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
637 if (arg1 == 1)
638 return ecdh_cms_decrypt(arg2);
639 else if (arg1 == 0)
640 return ecdh_cms_encrypt(arg2);
641 return -2;
642
643 case ASN1_PKEY_CTRL_CMS_RI_TYPE:
644 *(int *)arg2 = CMS_RECIPINFO_AGREE;
645 return 1;
8931b30d 646#endif
492a9e24 647
03919683
DSH
648 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
649 *(int *)arg2 = NID_sha1;
650 return 2;
651
492a9e24
DSH
652 default:
653 return -2;
654
655 }
656
657 }
658
560b79cb 659const EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
448be743
DSH
660 {
661 EVP_PKEY_EC,
d82e2718 662 EVP_PKEY_EC,
448be743 663 0,
e4263314 664 "EC",
d82e2718 665 "OpenSSL EC algorithm",
6f81892e 666
448be743
DSH
667 eckey_pub_decode,
668 eckey_pub_encode,
6f81892e 669 eckey_pub_cmp,
35208f36 670 eckey_pub_print,
6f81892e 671
448be743
DSH
672 eckey_priv_decode,
673 eckey_priv_encode,
35208f36 674 eckey_priv_print,
6f81892e
DSH
675
676 int_ec_size,
677 ec_bits,
2514fa79 678 ec_security_bits,
6f81892e 679
3e4585c8
DSH
680 eckey_param_decode,
681 eckey_param_encode,
6f81892e
DSH
682 ec_missing_parameters,
683 ec_copy_parameters,
684 ec_cmp_parameters,
35208f36 685 eckey_param_print,
fa1ba589 686 0,
6f81892e
DSH
687
688 int_ec_free,
492a9e24 689 ec_pkey_ctrl,
e4263314
DSH
690 old_ec_priv_decode,
691 old_ec_priv_encode
448be743 692 };
88e20b85
DSH
693
694#ifndef OPENSSL_NO_CMS
695
696static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
697 X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
698 {
699 ASN1_OBJECT *aoid;
700 int atype;
701 void *aval;
702 int rv = 0;
703 EVP_PKEY *pkpeer = NULL;
704 EC_KEY *ecpeer = NULL;
705 const unsigned char *p;
706 int plen;
707 X509_ALGOR_get0(&aoid, &atype, &aval, alg);
708 if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
709 goto err;
710 /* If absent parameters get group from main key */
711 if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL)
712 {
713 const EC_GROUP *grp;
714 EVP_PKEY *pk;
715 pk = EVP_PKEY_CTX_get0_pkey(pctx);
716 if (!pk)
717 goto err;
718 grp = EC_KEY_get0_group(pk->pkey.ec);
719 ecpeer = EC_KEY_new();
720 if (!ecpeer)
721 goto err;
722 if (!EC_KEY_set_group(ecpeer, grp))
723 goto err;
724 }
725 else
726 {
727 ecpeer = eckey_type2param(atype, aval);
728 if (!ecpeer)
729 goto err;
730 }
731 /* We have parameters now set public key */
732 plen = ASN1_STRING_length(pubkey);
733 p = ASN1_STRING_data(pubkey);
734 if (!p || !plen)
735 goto err;
736 if (!o2i_ECPublicKey(&ecpeer, &p, plen))
737 goto err;
738 pkpeer = EVP_PKEY_new();
739 if (!pkpeer)
740 goto err;
741 EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
742 if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
743 rv = 1;
744 err:
745 if (ecpeer)
746 EC_KEY_free(ecpeer);
747 if (pkpeer)
748 EVP_PKEY_free(pkpeer);
749 return rv;
750 }
751/* Set KDF parameters based on KDF NID */
752static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
753 {
754 int kdf_nid, kdfmd_nid, cofactor;
755 const EVP_MD *kdf_md;
756 if (eckdf_nid == NID_undef)
757 return 0;
758
759 /* Lookup KDF type, cofactor mode and digest */
760 if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
761 return 0;
762
763 if (kdf_nid == NID_dh_std_kdf)
764 cofactor = 0;
765 else if (kdf_nid == NID_dh_cofactor_kdf)
766 cofactor = 1;
767 else return 0;
768
769 if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
770 return 0;
771
772 if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0)
773 return 0;
774
775 kdf_md = EVP_get_digestbynid(kdfmd_nid);
776 if (!kdf_md)
777 return 0;
778
779 if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
780 return 0;
781 return 1;
782 }
783
88e20b85
DSH
784static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
785 {
786 int rv = 0;
787
788 X509_ALGOR *alg, *kekalg = NULL;
789 ASN1_OCTET_STRING *ukm;
790 const unsigned char *p;
dc1ce3bc 791 unsigned char *der = NULL;
88e20b85
DSH
792 int plen, keylen;
793 const EVP_CIPHER *kekcipher;
794 EVP_CIPHER_CTX *kekctx;
795
796 if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
797 return 0;
798
799 if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm)))
800 {
801 ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
802 return 0;
803 }
804
805 if (alg->parameter->type != V_ASN1_SEQUENCE)
806 return 0;
807
808 p = alg->parameter->value.sequence->data;
809 plen = alg->parameter->value.sequence->length;
810 kekalg = d2i_X509_ALGOR(NULL, &p, plen);
811 if (!kekalg)
812 goto err;
813 kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
814 if (!kekctx)
815 goto err;
816 kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
817 if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
818 goto err;
819 if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
820 goto err;
e61f5d55
DSH
821 if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
822 goto err;
88e20b85
DSH
823
824 keylen = EVP_CIPHER_CTX_key_length(kekctx);
825 if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
826 goto err;
827
dc1ce3bc
DSH
828 plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
829
830 if (!plen)
88e20b85
DSH
831 goto err;
832
dc1ce3bc
DSH
833 if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
834 goto err;
835 der = NULL;
836
88e20b85
DSH
837 rv = 1;
838 err:
839 if (kekalg)
840 X509_ALGOR_free(kekalg);
dc1ce3bc
DSH
841 if (der)
842 OPENSSL_free(der);
88e20b85
DSH
843 return rv;
844 }
845
846static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
847 {
848 EVP_PKEY_CTX *pctx;
849 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
850 if (!pctx)
851 return 0;
852 /* See if we need to set peer key */
853 if (!EVP_PKEY_CTX_get0_peerkey(pctx))
854 {
855 X509_ALGOR *alg;
856 ASN1_BIT_STRING *pubkey;
857 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
858 NULL, NULL, NULL))
859 return 0;
860 if (!alg || !pubkey)
861 return 0;
862 if (!ecdh_cms_set_peerkey(pctx, alg, pubkey))
863 {
864 ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
865 return 0;
866 }
867 }
868 /* Set ECDH derivation parameters and initialise unwrap context */
869 if (!ecdh_cms_set_shared_info(pctx, ri))
870 {
871 ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
872 return 0;
873 }
874 return 1;
875 }
876
877static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
878 {
879 EVP_PKEY_CTX *pctx;
880 EVP_PKEY *pkey;
881 EVP_CIPHER_CTX *ctx;
882 int keylen;
883 X509_ALGOR *talg, *wrap_alg = NULL;
884 ASN1_OBJECT *aoid;
885 ASN1_BIT_STRING *pubkey;
886 ASN1_STRING *wrap_str;
887 ASN1_OCTET_STRING *ukm;
888 unsigned char *penc = NULL;
889 int penclen;
890 int rv = 0;
891 int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
892 const EVP_MD *kdf_md;
893 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
894 if (!pctx)
895 return 0;
896 /* Get ephemeral key */
897 pkey = EVP_PKEY_CTX_get0_pkey(pctx);
898 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
899 NULL, NULL, NULL))
900 goto err;
901 X509_ALGOR_get0(&aoid, NULL, NULL, talg);
902 /* Is everything uninitialised? */
903 if (aoid == OBJ_nid2obj(NID_undef))
904 {
905
906 EC_KEY *eckey = pkey->pkey.ec;
907 /* Set the key */
908 unsigned char *p;
909
910 penclen = i2o_ECPublicKey(eckey, NULL);
911 if (penclen <= 0)
912 goto err;
913 penc = OPENSSL_malloc(penclen);
914 if (!penc)
915 goto err;
916 p = penc;
917 penclen = i2o_ECPublicKey(eckey, &p);
918 if (penclen <= 0)
919 goto err;
920 ASN1_STRING_set0(pubkey, penc, penclen);
921 pubkey->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
922 pubkey->flags|=ASN1_STRING_FLAG_BITS_LEFT;
923
924 penc = NULL;
925 X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
926 V_ASN1_UNDEF, NULL);
927 }
928
929 /* See if custom paraneters set */
930 kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
931 if (kdf_type <= 0)
932 goto err;
933 if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
934 goto err;
935 ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
936 if (ecdh_nid < 0)
937 goto err;
938 else if (ecdh_nid == 0)
939 ecdh_nid = NID_dh_std_kdf;
940 else if (ecdh_nid == 1)
941 ecdh_nid = NID_dh_cofactor_kdf;
942
943 if (kdf_type == EVP_PKEY_ECDH_KDF_NONE)
944 {
945 kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
946 if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
947 goto err;
948 }
949 else
950 /* Uknown KDF */
951 goto err;
952 if (kdf_md == NULL)
953 {
954 /* Fixme later for better MD */
955 kdf_md = EVP_sha1();
956 if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
957 goto err;
958 }
959
960 if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
961 goto err;
962
963 /* Lookup NID for KDF+cofactor+digest */
964
965 if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
966 goto err;
967 /* Get wrap NID */
968 ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
969 wrap_nid = EVP_CIPHER_CTX_type(ctx);
970 keylen = EVP_CIPHER_CTX_key_length(ctx);
971
972 /* Package wrap algorithm in an AlgorithmIdentifier */
973
974 wrap_alg = X509_ALGOR_new();
975 if (!wrap_alg)
976 goto err;
e61f5d55
DSH
977 wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
978 wrap_alg->parameter = ASN1_TYPE_new();
979 if (!wrap_alg->parameter)
980 goto err;
981 if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
982 goto err;
983 if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef)
984 {
985 ASN1_TYPE_free(wrap_alg->parameter);
986 wrap_alg->parameter = NULL;
987 }
88e20b85
DSH
988
989 if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
990 goto err;
dc1ce3bc
DSH
991
992 penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
993
994 if (!penclen)
88e20b85
DSH
995 goto err;
996
dc1ce3bc
DSH
997 if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
998 goto err;
999 penc = NULL;
1000
88e20b85
DSH
1001 /* Now need to wrap encoding of wrap AlgorithmIdentifier into
1002 * parameter of another AlgorithmIdentifier.
1003 */
88e20b85
DSH
1004 penclen = i2d_X509_ALGOR(wrap_alg, &penc);
1005 if (!penc || !penclen)
1006 goto err;
1007 wrap_str = ASN1_STRING_new();
1008 if (!wrap_str)
1009 goto err;
1010 ASN1_STRING_set0(wrap_str, penc, penclen);
1011 penc = NULL;
1012 X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
1013
1014 rv = 1;
1015
1016 err:
1017 if (penc)
1018 OPENSSL_free(penc);
1019 if (wrap_alg)
1020 X509_ALGOR_free(wrap_alg);
1021 return rv;
1022 }
1023
1024#endif