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