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