Coverage Report

Created: 2023-09-25 06:42

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