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