Coverage Report

Created: 2022-11-30 06:20

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