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