Coverage Report

Created: 2022-08-24 06:31

/src/libressl/crypto/ec/ec_ameth.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: ec_ameth.c,v 1.33 2022/06/27 12:36:05 tb Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project 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
61
#include <openssl/opensslconf.h>
62
63
#include <openssl/bn.h>
64
#include <openssl/cms.h>
65
#include <openssl/ec.h>
66
#include <openssl/err.h>
67
#include <openssl/x509.h>
68
69
#include "asn1_locl.h"
70
#include "ec_lcl.h"
71
#include "evp_locl.h"
72
73
#ifndef OPENSSL_NO_CMS
74
static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
75
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
76
#endif
77
78
static int 
79
eckey_param2type(int *pptype, void **ppval, EC_KEY * ec_key)
80
0
{
81
0
  const EC_GROUP *group;
82
0
  int nid;
83
0
  if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
84
0
    ECerror(EC_R_MISSING_PARAMETERS);
85
0
    return 0;
86
0
  }
87
0
  if (EC_GROUP_get_asn1_flag(group) &&
88
0
      (nid = EC_GROUP_get_curve_name(group))) {
89
    /* we have a 'named curve' => just set the OID */
90
0
    *ppval = OBJ_nid2obj(nid);
91
0
    *pptype = V_ASN1_OBJECT;
92
0
  } else {
93
    /* explicit parameters */
94
0
    ASN1_STRING *pstr = NULL;
95
0
    pstr = ASN1_STRING_new();
96
0
    if (!pstr)
97
0
      return 0;
98
0
    pstr->length = i2d_ECParameters(ec_key, &pstr->data);
99
0
    if (pstr->length <= 0) {
100
0
      ASN1_STRING_free(pstr);
101
0
      ECerror(ERR_R_EC_LIB);
102
0
      return 0;
103
0
    }
104
0
    *ppval = pstr;
105
0
    *pptype = V_ASN1_SEQUENCE;
106
0
  }
107
0
  return 1;
108
0
}
109
110
static int 
111
eckey_pub_encode(X509_PUBKEY * pk, const EVP_PKEY * pkey)
112
0
{
113
0
  EC_KEY *ec_key = pkey->pkey.ec;
114
0
  void *pval = NULL;
115
0
  int ptype;
116
0
  unsigned char *penc = NULL, *p;
117
0
  int penclen;
118
119
0
  if (!eckey_param2type(&ptype, &pval, ec_key)) {
120
0
    ECerror(ERR_R_EC_LIB);
121
0
    return 0;
122
0
  }
123
0
  penclen = i2o_ECPublicKey(ec_key, NULL);
124
0
  if (penclen <= 0)
125
0
    goto err;
126
0
  penc = malloc(penclen);
127
0
  if (!penc)
128
0
    goto err;
129
0
  p = penc;
130
0
  penclen = i2o_ECPublicKey(ec_key, &p);
131
0
  if (penclen <= 0)
132
0
    goto err;
133
0
  if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
134
0
    ptype, pval, penc, penclen))
135
0
    return 1;
136
0
 err:
137
0
  if (ptype == V_ASN1_OBJECT)
138
0
    ASN1_OBJECT_free(pval);
139
0
  else
140
0
    ASN1_STRING_free(pval);
141
0
  free(penc);
142
0
  return 0;
143
0
}
144
145
static EC_KEY *
146
eckey_type2param(int ptype, const void *pval)
147
12.9k
{
148
12.9k
  EC_GROUP *group = NULL;
149
12.9k
  EC_KEY *eckey = NULL;
150
151
12.9k
  if (ptype == V_ASN1_SEQUENCE) {
152
240
    const ASN1_STRING *pstr = pval;
153
240
    const unsigned char *pm = NULL;
154
240
    int pmlen;
155
156
240
    pm = pstr->data;
157
240
    pmlen = pstr->length;
158
240
    if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
159
240
      ECerror(EC_R_DECODE_ERROR);
160
240
      goto ecerr;
161
240
    }
162
12.7k
  } else if (ptype == V_ASN1_OBJECT) {
163
12.6k
    const ASN1_OBJECT *poid = pval;
164
165
    /*
166
     * type == V_ASN1_OBJECT => the parameters are given by an
167
     * asn1 OID
168
     */
169
12.6k
    if ((eckey = EC_KEY_new()) == NULL) {
170
0
      ECerror(ERR_R_MALLOC_FAILURE);
171
0
      goto ecerr;
172
0
    }
173
12.6k
    group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
174
12.6k
    if (group == NULL)
175
80
      goto ecerr;
176
12.5k
    EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
177
12.5k
    if (EC_KEY_set_group(eckey, group) == 0)
178
0
      goto ecerr;
179
12.5k
  } else {
180
88
    ECerror(EC_R_DECODE_ERROR);
181
88
    goto ecerr;
182
88
  }
183
184
12.5k
  EC_GROUP_free(group);
185
12.5k
  return eckey;
186
187
408
 ecerr:
188
408
  EC_KEY_free(eckey);
189
408
  EC_GROUP_free(group);
190
408
  return NULL;
191
12.9k
}
192
193
static int 
194
eckey_pub_decode(EVP_PKEY * pkey, X509_PUBKEY * pubkey)
195
11.5k
{
196
11.5k
  const unsigned char *p = NULL;
197
11.5k
  const void *pval;
198
11.5k
  int ptype, pklen;
199
11.5k
  EC_KEY *eckey = NULL;
200
11.5k
  X509_ALGOR *palg;
201
202
11.5k
  if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
203
0
    return 0;
204
11.5k
  X509_ALGOR_get0(NULL, &ptype, &pval, palg);
205
206
11.5k
  eckey = eckey_type2param(ptype, pval);
207
208
11.5k
  if (!eckey) {
209
401
    ECerror(ERR_R_EC_LIB);
210
401
    return 0;
211
401
  }
212
  /* We have parameters now set public key */
213
11.1k
  if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
214
1.95k
    ECerror(EC_R_DECODE_ERROR);
215
1.95k
    goto ecerr;
216
1.95k
  }
217
9.20k
  EVP_PKEY_assign_EC_KEY(pkey, eckey);
218
9.20k
  return 1;
219
220
1.95k
 ecerr:
221
1.95k
  if (eckey)
222
1.95k
    EC_KEY_free(eckey);
223
1.95k
  return 0;
224
11.1k
}
225
226
static int 
227
eckey_pub_cmp(const EVP_PKEY * a, const EVP_PKEY * b)
228
6.07k
{
229
6.07k
  int r;
230
6.07k
  const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
231
6.07k
  const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec);
232
233
6.07k
  r = EC_POINT_cmp(group, pa, pb, NULL);
234
6.07k
  if (r == 0)
235
6.07k
    return 1;
236
0
  if (r == 1)
237
0
    return 0;
238
0
  return -2;
239
0
}
240
241
static int 
242
eckey_priv_decode(EVP_PKEY * pkey, const PKCS8_PRIV_KEY_INFO * p8)
243
1.41k
{
244
1.41k
  const unsigned char *p = NULL;
245
1.41k
  const void *pval;
246
1.41k
  int ptype, pklen;
247
1.41k
  EC_KEY *eckey = NULL;
248
1.41k
  const X509_ALGOR *palg;
249
250
1.41k
  if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
251
0
    return 0;
252
1.41k
  X509_ALGOR_get0(NULL, &ptype, &pval, palg);
253
254
1.41k
  eckey = eckey_type2param(ptype, pval);
255
256
1.41k
  if (!eckey)
257
7
    goto ecliberr;
258
259
  /* We have parameters now set private key */
260
1.40k
  if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
261
514
    ECerror(EC_R_DECODE_ERROR);
262
514
    goto ecerr;
263
514
  }
264
  /* calculate public key (if necessary) */
265
891
  if (EC_KEY_get0_public_key(eckey) == NULL) {
266
0
    const BIGNUM *priv_key;
267
0
    const EC_GROUP *group;
268
0
    EC_POINT *pub_key;
269
    /*
270
     * the public key was not included in the SEC1 private key =>
271
     * calculate the public key
272
     */
273
0
    group = EC_KEY_get0_group(eckey);
274
0
    pub_key = EC_POINT_new(group);
275
0
    if (pub_key == NULL) {
276
0
      ECerror(ERR_R_EC_LIB);
277
0
      goto ecliberr;
278
0
    }
279
0
    if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
280
0
      EC_POINT_free(pub_key);
281
0
      ECerror(ERR_R_EC_LIB);
282
0
      goto ecliberr;
283
0
    }
284
0
    priv_key = EC_KEY_get0_private_key(eckey);
285
0
    if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
286
0
      EC_POINT_free(pub_key);
287
0
      ECerror(ERR_R_EC_LIB);
288
0
      goto ecliberr;
289
0
    }
290
0
    if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
291
0
      EC_POINT_free(pub_key);
292
0
      ECerror(ERR_R_EC_LIB);
293
0
      goto ecliberr;
294
0
    }
295
0
    EC_POINT_free(pub_key);
296
0
  }
297
891
  EVP_PKEY_assign_EC_KEY(pkey, eckey);
298
891
  return 1;
299
300
7
 ecliberr:
301
7
  ECerror(ERR_R_EC_LIB);
302
521
 ecerr:
303
521
  if (eckey)
304
514
    EC_KEY_free(eckey);
305
521
  return 0;
306
7
}
307
308
static int 
309
eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey)
310
0
{
311
0
  EC_KEY *ec_key;
312
0
  unsigned char *ep, *p;
313
0
  int eplen, ptype;
314
0
  void *pval;
315
0
  unsigned int tmp_flags, old_flags;
316
317
0
  ec_key = pkey->pkey.ec;
318
319
0
  if (!eckey_param2type(&ptype, &pval, ec_key)) {
320
0
    ECerror(EC_R_DECODE_ERROR);
321
0
    return 0;
322
0
  }
323
  /* set the private key */
324
325
  /*
326
   * do not include the parameters in the SEC1 private key see PKCS#11
327
   * 12.11
328
   */
329
0
  old_flags = EC_KEY_get_enc_flags(ec_key);
330
0
  tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
331
0
  EC_KEY_set_enc_flags(ec_key, tmp_flags);
332
0
  eplen = i2d_ECPrivateKey(ec_key, NULL);
333
0
  if (!eplen) {
334
0
    EC_KEY_set_enc_flags(ec_key, old_flags);
335
0
    ECerror(ERR_R_EC_LIB);
336
0
    return 0;
337
0
  }
338
0
  ep = malloc(eplen);
339
0
  if (!ep) {
340
0
    EC_KEY_set_enc_flags(ec_key, old_flags);
341
0
    ECerror(ERR_R_MALLOC_FAILURE);
342
0
    return 0;
343
0
  }
344
0
  p = ep;
345
0
  if (!i2d_ECPrivateKey(ec_key, &p)) {
346
0
    EC_KEY_set_enc_flags(ec_key, old_flags);
347
0
    free(ep);
348
0
    ECerror(ERR_R_EC_LIB);
349
0
    return 0;
350
0
  }
351
  /* restore old encoding flags */
352
0
  EC_KEY_set_enc_flags(ec_key, old_flags);
353
354
0
  if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
355
0
    ptype, pval, ep, eplen))
356
0
    return 0;
357
358
0
  return 1;
359
0
}
360
361
static int 
362
int_ec_size(const EVP_PKEY * pkey)
363
176
{
364
176
  return ECDSA_size(pkey->pkey.ec);
365
176
}
366
367
static int 
368
ec_bits(const EVP_PKEY * pkey)
369
7.06k
{
370
7.06k
  BIGNUM *order = BN_new();
371
7.06k
  const EC_GROUP *group;
372
7.06k
  int ret;
373
374
7.06k
  if (!order) {
375
0
    ERR_clear_error();
376
0
    return 0;
377
0
  }
378
7.06k
  group = EC_KEY_get0_group(pkey->pkey.ec);
379
7.06k
  if (!EC_GROUP_get_order(group, order, NULL)) {
380
0
    BN_free(order);
381
0
    ERR_clear_error();
382
0
    return 0;
383
0
  }
384
7.06k
  ret = BN_num_bits(order);
385
7.06k
  BN_free(order);
386
7.06k
  return ret;
387
7.06k
}
388
389
static int
390
ec_security_bits(const EVP_PKEY *pkey)
391
7.06k
{
392
7.06k
  int ecbits = ec_bits(pkey);
393
394
7.06k
  if (ecbits >= 512)
395
58
    return 256;
396
7.00k
  if (ecbits >= 384)
397
142
    return 192;
398
6.86k
  if (ecbits >= 256)
399
6.77k
    return 128;
400
85
  if (ecbits >= 224)
401
85
    return 112;
402
0
  if (ecbits >= 160)
403
0
    return 80;
404
405
0
  return ecbits / 2;
406
0
}
407
408
static int 
409
ec_missing_parameters(const EVP_PKEY * pkey)
410
6.43k
{
411
6.43k
  if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
412
0
    return 1;
413
6.43k
  return 0;
414
6.43k
}
415
416
static int 
417
ec_copy_parameters(EVP_PKEY * to, const EVP_PKEY * from)
418
6.07k
{
419
6.07k
  return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec));
420
6.07k
}
421
422
static int 
423
ec_cmp_parameters(const EVP_PKEY * a, const EVP_PKEY * b)
424
6.07k
{
425
6.07k
  const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec);
426
6.07k
  if (EC_GROUP_cmp(group_a, group_b, NULL))
427
0
    return 0;
428
6.07k
  else
429
6.07k
    return 1;
430
6.07k
}
431
432
static void 
433
int_ec_free(EVP_PKEY * pkey)
434
28.9k
{
435
28.9k
  EC_KEY_free(pkey->pkey.ec);
436
28.9k
}
437
438
static int 
439
do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype)
440
6.72k
{
441
6.72k
  unsigned char *buffer = NULL;
442
6.72k
  const char *ecstr;
443
6.72k
  size_t buf_len = 0, i;
444
6.72k
  int ret = 0, reason = ERR_R_BIO_LIB;
445
6.72k
  BIGNUM *pub_key = NULL, *order = NULL;
446
6.72k
  BN_CTX *ctx = NULL;
447
6.72k
  const EC_GROUP *group;
448
6.72k
  const EC_POINT *public_key;
449
6.72k
  const BIGNUM *priv_key;
450
451
6.72k
  if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
452
0
    reason = ERR_R_PASSED_NULL_PARAMETER;
453
0
    goto err;
454
0
  }
455
6.72k
  ctx = BN_CTX_new();
456
6.72k
  if (ctx == NULL) {
457
0
    reason = ERR_R_MALLOC_FAILURE;
458
0
    goto err;
459
0
  }
460
6.72k
  if (ktype > 0) {
461
6.61k
    public_key = EC_KEY_get0_public_key(x);
462
6.61k
    if (public_key != NULL) {
463
6.61k
      if ((pub_key = EC_POINT_point2bn(group, public_key,
464
6.61k
          EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) {
465
27
        reason = ERR_R_EC_LIB;
466
27
        goto err;
467
27
      }
468
6.58k
      if (pub_key)
469
6.58k
        buf_len = (size_t) BN_num_bytes(pub_key);
470
6.58k
    }
471
6.61k
  }
472
6.70k
  if (ktype == 2) {
473
3.81k
    priv_key = EC_KEY_get0_private_key(x);
474
3.81k
    if (priv_key && (i = (size_t) BN_num_bytes(priv_key)) > buf_len)
475
80
      buf_len = i;
476
3.81k
  } else
477
2.88k
    priv_key = NULL;
478
479
6.70k
  if (ktype > 0) {
480
6.58k
    buf_len += 10;
481
6.58k
    if ((buffer = malloc(buf_len)) == NULL) {
482
0
      reason = ERR_R_MALLOC_FAILURE;
483
0
      goto err;
484
0
    }
485
6.58k
  }
486
6.70k
  if (ktype == 2)
487
3.81k
    ecstr = "Private-Key";
488
2.88k
  else if (ktype == 1)
489
2.76k
    ecstr = "Public-Key";
490
117
  else
491
117
    ecstr = "ECDSA-Parameters";
492
493
6.70k
  if (!BIO_indent(bp, off, 128))
494
0
    goto err;
495
6.70k
  if ((order = BN_new()) == NULL)
496
0
    goto err;
497
6.70k
  if (!EC_GROUP_get_order(group, order, NULL))
498
0
    goto err;
499
6.70k
  if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
500
6.70k
    BN_num_bits(order)) <= 0)
501
0
    goto err;
502
503
6.70k
  if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
504
3.81k
    buffer, off))
505
0
    goto err;
506
6.70k
  if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
507
6.58k
    buffer, off))
508
0
    goto err;
509
6.70k
  if (!ECPKParameters_print(bp, group, off))
510
69
    goto err;
511
6.63k
  ret = 1;
512
6.72k
 err:
513
6.72k
  if (!ret)
514
6.72k
    ECerror(reason);
515
6.72k
  BN_free(pub_key);
516
6.72k
  BN_free(order);
517
6.72k
  BN_CTX_free(ctx);
518
6.72k
  free(buffer);
519
6.72k
  return (ret);
520
6.63k
}
521
522
static int 
523
eckey_param_decode(EVP_PKEY * pkey,
524
    const unsigned char **pder, int derlen)
525
0
{
526
0
  EC_KEY *eckey;
527
0
  if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
528
0
    ECerror(ERR_R_EC_LIB);
529
0
    return 0;
530
0
  }
531
0
  EVP_PKEY_assign_EC_KEY(pkey, eckey);
532
0
  return 1;
533
0
}
534
535
static int 
536
eckey_param_encode(const EVP_PKEY * pkey, unsigned char **pder)
537
0
{
538
0
  return i2d_ECParameters(pkey->pkey.ec, pder);
539
0
}
540
541
static int 
542
eckey_param_print(BIO * bp, const EVP_PKEY * pkey, int indent,
543
    ASN1_PCTX * ctx)
544
117
{
545
117
  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
546
117
}
547
548
static int 
549
eckey_pub_print(BIO * bp, const EVP_PKEY * pkey, int indent,
550
    ASN1_PCTX * ctx)
551
2.77k
{
552
2.77k
  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
553
2.77k
}
554
555
556
static int 
557
eckey_priv_print(BIO * bp, const EVP_PKEY * pkey, int indent,
558
    ASN1_PCTX * ctx)
559
3.83k
{
560
3.83k
  return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
561
3.83k
}
562
563
static int 
564
old_ec_priv_decode(EVP_PKEY * pkey,
565
    const unsigned char **pder, int derlen)
566
7.30k
{
567
7.30k
  EC_KEY *ec;
568
7.30k
  if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
569
745
    ECerror(EC_R_DECODE_ERROR);
570
745
    return 0;
571
745
  }
572
6.56k
  EVP_PKEY_assign_EC_KEY(pkey, ec);
573
6.56k
  return 1;
574
7.30k
}
575
576
static int 
577
old_ec_priv_encode(const EVP_PKEY * pkey, unsigned char **pder)
578
1.38k
{
579
1.38k
  return i2d_ECPrivateKey(pkey->pkey.ec, pder);
580
1.38k
}
581
582
static int 
583
ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2)
584
0
{
585
0
  switch (op) {
586
0
  case ASN1_PKEY_CTRL_PKCS7_SIGN:
587
0
    if (arg1 == 0) {
588
0
      int snid, hnid;
589
0
      X509_ALGOR *alg1, *alg2;
590
0
      PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
591
0
      if (alg1 == NULL || alg1->algorithm == NULL)
592
0
        return -1;
593
0
      hnid = OBJ_obj2nid(alg1->algorithm);
594
0
      if (hnid == NID_undef)
595
0
        return -1;
596
0
      if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
597
0
        return -1;
598
0
      X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
599
0
    }
600
0
    return 1;
601
602
0
#ifndef OPENSSL_NO_CMS
603
0
  case ASN1_PKEY_CTRL_CMS_SIGN:
604
0
    if (arg1 == 0) {
605
0
      X509_ALGOR *alg1, *alg2;
606
0
      int snid, hnid;
607
608
0
      CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
609
0
      if (alg1 == NULL || alg1->algorithm == NULL)
610
0
        return -1;
611
0
      hnid = OBJ_obj2nid(alg1->algorithm);
612
0
      if (hnid == NID_undef)
613
0
        return -1;
614
0
      if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
615
0
        return -1;
616
0
      X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
617
0
    }
618
0
    return 1;
619
620
0
  case ASN1_PKEY_CTRL_CMS_ENVELOPE:
621
0
    if (arg1 == 0)
622
0
      return ecdh_cms_encrypt(arg2);
623
0
    else if (arg1 == 1)
624
0
      return ecdh_cms_decrypt(arg2);
625
0
    return -2;
626
627
0
  case ASN1_PKEY_CTRL_CMS_RI_TYPE:
628
0
    *(int *)arg2 = CMS_RECIPINFO_AGREE;
629
0
    return 1;
630
0
#endif
631
632
0
  case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
633
0
    *(int *) arg2 = NID_sha1;
634
0
    return 2;
635
636
0
  default:
637
0
    return -2;
638
639
0
  }
640
641
0
}
642
643
static int
644
ec_pkey_check(const EVP_PKEY *pkey)
645
0
{
646
0
  EC_KEY *eckey = pkey->pkey.ec;
647
648
0
  if (eckey->priv_key == NULL) {
649
0
    ECerror(EC_R_MISSING_PRIVATE_KEY);
650
0
    return 0;
651
0
  }
652
653
0
  return EC_KEY_check_key(eckey);
654
0
}
655
656
static int
657
ec_pkey_public_check(const EVP_PKEY *pkey)
658
0
{
659
0
  EC_KEY *eckey = pkey->pkey.ec;
660
661
  /* This also checks the private key, but oh, well... */
662
0
  return EC_KEY_check_key(eckey);
663
0
}
664
665
static int
666
ec_pkey_param_check(const EVP_PKEY *pkey)
667
0
{
668
0
  EC_KEY *eckey = pkey->pkey.ec;
669
670
0
  if (eckey->group == NULL) {
671
0
    ECerror(EC_R_MISSING_PARAMETERS);
672
0
    return 0;
673
0
  }
674
675
0
  return EC_GROUP_check(eckey->group, NULL);
676
0
}
677
678
#ifndef OPENSSL_NO_CMS
679
680
static int
681
ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg,
682
    ASN1_BIT_STRING *pubkey)
683
0
{
684
0
  const ASN1_OBJECT *aoid;
685
0
  int atype;
686
0
  const void *aval;
687
0
  int rv = 0;
688
0
  EVP_PKEY *pkpeer = NULL;
689
0
  EC_KEY *ecpeer = NULL;
690
0
  const unsigned char *p;
691
0
  int plen;
692
693
0
  X509_ALGOR_get0(&aoid, &atype, &aval, alg);
694
0
  if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
695
0
    goto err;
696
697
  /* If absent parameters get group from main key */
698
0
  if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
699
0
    const EC_GROUP *grp;
700
0
    EVP_PKEY *pk;
701
702
0
    pk = EVP_PKEY_CTX_get0_pkey(pctx);
703
0
    if (!pk)
704
0
      goto err;
705
0
    grp = EC_KEY_get0_group(pk->pkey.ec);
706
0
    ecpeer = EC_KEY_new();
707
0
    if (ecpeer == NULL)
708
0
      goto err;
709
0
    if (!EC_KEY_set_group(ecpeer, grp))
710
0
      goto err;
711
0
  } else {
712
0
    ecpeer = eckey_type2param(atype, aval);
713
0
    if (!ecpeer)
714
0
      goto err;
715
0
  }
716
717
  /* We have parameters now set public key */
718
0
  plen = ASN1_STRING_length(pubkey);
719
0
  p = ASN1_STRING_get0_data(pubkey);
720
0
  if (!p || !plen)
721
0
    goto err;
722
0
  if (!o2i_ECPublicKey(&ecpeer, &p, plen))
723
0
    goto err;
724
0
  pkpeer = EVP_PKEY_new();
725
0
  if (pkpeer == NULL)
726
0
    goto err;
727
0
  EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
728
0
  if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
729
0
    rv = 1;
730
0
 err:
731
0
  EC_KEY_free(ecpeer);
732
0
  EVP_PKEY_free(pkpeer);
733
0
  return rv;
734
0
}
735
736
/* Set KDF parameters based on KDF NID */
737
static int
738
ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
739
0
{
740
0
  int kdf_nid, kdfmd_nid, cofactor;
741
0
  const EVP_MD *kdf_md;
742
743
0
  if (eckdf_nid == NID_undef)
744
0
    return 0;
745
746
  /* Lookup KDF type, cofactor mode and digest */
747
0
  if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
748
0
    return 0;
749
750
0
  if (kdf_nid == NID_dh_std_kdf)
751
0
    cofactor = 0;
752
0
  else if (kdf_nid == NID_dh_cofactor_kdf)
753
0
    cofactor = 1;
754
0
  else
755
0
    return 0;
756
757
0
  if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
758
0
    return 0;
759
760
0
  if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
761
0
    return 0;
762
763
0
  kdf_md = EVP_get_digestbynid(kdfmd_nid);
764
0
  if (!kdf_md)
765
0
    return 0;
766
767
0
  if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
768
0
    return 0;
769
770
0
  return 1;
771
0
}
772
773
static int
774
ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
775
0
{
776
0
  X509_ALGOR *alg, *kekalg = NULL;
777
0
  ASN1_OCTET_STRING *ukm;
778
0
  const unsigned char *p;
779
0
  unsigned char *der = NULL;
780
0
  int plen, keylen;
781
0
  const EVP_CIPHER *kekcipher;
782
0
  EVP_CIPHER_CTX *kekctx;
783
0
  int rv = 0;
784
785
0
  if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
786
0
    return 0;
787
788
0
  if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
789
0
    ECerror(EC_R_KDF_PARAMETER_ERROR);
790
0
    return 0;
791
0
  }
792
793
0
  if (alg->parameter->type != V_ASN1_SEQUENCE)
794
0
    return 0;
795
796
0
  p = alg->parameter->value.sequence->data;
797
0
  plen = alg->parameter->value.sequence->length;
798
0
  kekalg = d2i_X509_ALGOR(NULL, &p, plen);
799
0
  if (!kekalg)
800
0
    goto err;
801
0
  kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
802
0
  if (!kekctx)
803
0
    goto err;
804
0
  kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
805
0
  if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
806
0
    goto err;
807
0
  if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
808
0
    goto err;
809
0
  if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
810
0
    goto err;
811
812
0
  keylen = EVP_CIPHER_CTX_key_length(kekctx);
813
0
  if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
814
0
    goto err;
815
816
0
  plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
817
0
  if (!plen)
818
0
    goto err;
819
820
0
  if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
821
0
    goto err;
822
0
  der = NULL;
823
824
0
  rv = 1;
825
0
 err:
826
0
  X509_ALGOR_free(kekalg);
827
0
  free(der);
828
0
  return rv;
829
0
}
830
831
static int
832
ecdh_cms_decrypt(CMS_RecipientInfo *ri)
833
0
{
834
0
  EVP_PKEY_CTX *pctx;
835
836
0
  pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
837
0
  if (!pctx)
838
0
    return 0;
839
840
  /* See if we need to set peer key */
841
0
  if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
842
0
    X509_ALGOR *alg;
843
0
    ASN1_BIT_STRING *pubkey;
844
845
0
    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
846
0
        NULL, NULL, NULL))
847
0
      return 0;
848
0
    if (!alg || !pubkey)
849
0
      return 0;
850
0
    if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
851
0
      ECerror(EC_R_PEER_KEY_ERROR);
852
0
      return 0;
853
0
    }
854
0
  }
855
856
  /* Set ECDH derivation parameters and initialise unwrap context */
857
0
  if (!ecdh_cms_set_shared_info(pctx, ri)) {
858
0
    ECerror(EC_R_SHARED_INFO_ERROR);
859
0
    return 0;
860
0
  }
861
862
0
  return 1;
863
0
}
864
865
static int
866
ecdh_cms_encrypt(CMS_RecipientInfo *ri)
867
0
{
868
0
  EVP_PKEY_CTX *pctx;
869
0
  EVP_PKEY *pkey;
870
0
  EVP_CIPHER_CTX *ctx;
871
0
  int keylen;
872
0
  X509_ALGOR *talg, *wrap_alg = NULL;
873
0
  const ASN1_OBJECT *aoid;
874
0
  ASN1_BIT_STRING *pubkey;
875
0
  ASN1_STRING *wrap_str;
876
0
  ASN1_OCTET_STRING *ukm;
877
0
  unsigned char *penc = NULL;
878
0
  int penclen;
879
0
  int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
880
0
  const EVP_MD *kdf_md;
881
0
  int rv = 0;
882
883
0
  pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
884
0
  if (!pctx)
885
0
    return 0;
886
  /* Get ephemeral key */
887
0
  pkey = EVP_PKEY_CTX_get0_pkey(pctx);
888
0
  if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
889
0
      NULL, NULL, NULL))
890
0
    goto err;
891
0
  X509_ALGOR_get0(&aoid, NULL, NULL, talg);
892
893
  /* Is everything uninitialised? */
894
0
  if (aoid == OBJ_nid2obj(NID_undef)) {
895
0
    EC_KEY *eckey = pkey->pkey.ec;
896
0
    unsigned char *p;
897
898
    /* Set the key */
899
0
    penclen = i2o_ECPublicKey(eckey, NULL);
900
0
    if (penclen <= 0)
901
0
      goto err;
902
0
    penc = malloc(penclen);
903
0
    if (penc == NULL)
904
0
      goto err;
905
0
    p = penc;
906
0
    penclen = i2o_ECPublicKey(eckey, &p);
907
0
    if (penclen <= 0)
908
0
      goto err;
909
0
    ASN1_STRING_set0(pubkey, penc, penclen);
910
0
    if (!asn1_abs_set_unused_bits(pubkey, 0))
911
0
      goto err;
912
0
    penc = NULL;
913
914
0
    X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
915
0
        V_ASN1_UNDEF, NULL);
916
0
  }
917
918
  /* See if custom parameters set */
919
0
  kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
920
0
  if (kdf_type <= 0)
921
0
    goto err;
922
0
  if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
923
0
    goto err;
924
0
  ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
925
0
  if (ecdh_nid < 0)
926
0
    goto err;
927
0
  else if (ecdh_nid == 0)
928
0
    ecdh_nid = NID_dh_std_kdf;
929
0
  else if (ecdh_nid == 1)
930
0
    ecdh_nid = NID_dh_cofactor_kdf;
931
932
0
  if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
933
0
    kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
934
0
    if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
935
0
      goto err;
936
0
  } else {
937
    /* Unknown KDF */
938
0
    goto err;
939
0
  }
940
0
  if (kdf_md == NULL) {
941
    /* Fixme later for better MD */
942
0
    kdf_md = EVP_sha1();
943
0
    if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
944
0
      goto err;
945
0
  }
946
947
0
  if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
948
0
    goto err;
949
950
  /* Lookup NID for KDF+cofactor+digest */
951
0
  if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
952
0
    goto err;
953
954
  /* Get wrap NID */
955
0
  ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
956
0
  wrap_nid = EVP_CIPHER_CTX_type(ctx);
957
0
  keylen = EVP_CIPHER_CTX_key_length(ctx);
958
959
  /* Package wrap algorithm in an AlgorithmIdentifier */
960
961
0
  wrap_alg = X509_ALGOR_new();
962
0
  if (wrap_alg == NULL)
963
0
    goto err;
964
0
  wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
965
0
  wrap_alg->parameter = ASN1_TYPE_new();
966
0
  if (wrap_alg->parameter == NULL)
967
0
    goto err;
968
0
  if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
969
0
    goto err;
970
0
  if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
971
0
    ASN1_TYPE_free(wrap_alg->parameter);
972
0
    wrap_alg->parameter = NULL;
973
0
  }
974
975
0
  if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
976
0
    goto err;
977
978
0
  penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
979
0
  if (!penclen)
980
0
    goto err;
981
982
0
  if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
983
0
    goto err;
984
0
  penc = NULL;
985
986
  /*
987
   * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
988
   * of another AlgorithmIdentifier.
989
   */
990
0
  penclen = i2d_X509_ALGOR(wrap_alg, &penc);
991
0
  if (!penc || !penclen)
992
0
    goto err;
993
0
  wrap_str = ASN1_STRING_new();
994
0
  if (wrap_str == NULL)
995
0
    goto err;
996
0
  ASN1_STRING_set0(wrap_str, penc, penclen);
997
0
  penc = NULL;
998
0
  X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
999
1000
0
  rv = 1;
1001
1002
0
 err:
1003
0
  free(penc);
1004
0
  X509_ALGOR_free(wrap_alg);
1005
0
  return rv;
1006
0
}
1007
1008
#endif
1009
1010
const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
1011
  .pkey_id = EVP_PKEY_EC,
1012
  .pkey_base_id = EVP_PKEY_EC,
1013
1014
  .pem_str = "EC",
1015
  .info = "OpenSSL EC algorithm",
1016
1017
  .pub_decode = eckey_pub_decode,
1018
  .pub_encode = eckey_pub_encode,
1019
  .pub_cmp = eckey_pub_cmp,
1020
  .pub_print = eckey_pub_print,
1021
1022
  .priv_decode = eckey_priv_decode,
1023
  .priv_encode = eckey_priv_encode,
1024
  .priv_print = eckey_priv_print,
1025
1026
  .pkey_size = int_ec_size,
1027
  .pkey_bits = ec_bits,
1028
  .pkey_security_bits = ec_security_bits,
1029
1030
  .param_decode = eckey_param_decode,
1031
  .param_encode = eckey_param_encode,
1032
  .param_missing = ec_missing_parameters,
1033
  .param_copy = ec_copy_parameters,
1034
  .param_cmp = ec_cmp_parameters,
1035
  .param_print = eckey_param_print,
1036
1037
  .pkey_free = int_ec_free,
1038
  .pkey_ctrl = ec_pkey_ctrl,
1039
  .old_priv_decode = old_ec_priv_decode,
1040
  .old_priv_encode = old_ec_priv_encode,
1041
1042
  .pkey_check = ec_pkey_check,
1043
  .pkey_public_check = ec_pkey_public_check,
1044
  .pkey_param_check = ec_pkey_param_check,
1045
};