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