Update LibreSSL from version 2.4.4 => 2.9.1
[dragonfly.git] / crypto / libressl / crypto / ec / ec_ameth.c
1 /* $OpenBSD: ec_ameth.c,v 1.25 2018/08/24 20:22:15 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/ec.h>
65 #include <openssl/err.h>
66 #include <openssl/x509.h>
67
68
69 #include "asn1_locl.h"
70
71 static int 
72 eckey_param2type(int *pptype, void **ppval, EC_KEY * ec_key)
73 {
74         const EC_GROUP *group;
75         int nid;
76         if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
77                 ECerror(EC_R_MISSING_PARAMETERS);
78                 return 0;
79         }
80         if (EC_GROUP_get_asn1_flag(group) &&
81             (nid = EC_GROUP_get_curve_name(group))) {
82                 /* we have a 'named curve' => just set the OID */
83                 *ppval = OBJ_nid2obj(nid);
84                 *pptype = V_ASN1_OBJECT;
85         } else {
86                 /* explicit parameters */
87                 ASN1_STRING *pstr = NULL;
88                 pstr = ASN1_STRING_new();
89                 if (!pstr)
90                         return 0;
91                 pstr->length = i2d_ECParameters(ec_key, &pstr->data);
92                 if (pstr->length <= 0) {
93                         ASN1_STRING_free(pstr);
94                         ECerror(ERR_R_EC_LIB);
95                         return 0;
96                 }
97                 *ppval = pstr;
98                 *pptype = V_ASN1_SEQUENCE;
99         }
100         return 1;
101 }
102
103 static int 
104 eckey_pub_encode(X509_PUBKEY * pk, const EVP_PKEY * pkey)
105 {
106         EC_KEY *ec_key = pkey->pkey.ec;
107         void *pval = NULL;
108         int ptype;
109         unsigned char *penc = NULL, *p;
110         int penclen;
111
112         if (!eckey_param2type(&ptype, &pval, ec_key)) {
113                 ECerror(ERR_R_EC_LIB);
114                 return 0;
115         }
116         penclen = i2o_ECPublicKey(ec_key, NULL);
117         if (penclen <= 0)
118                 goto err;
119         penc = malloc(penclen);
120         if (!penc)
121                 goto err;
122         p = penc;
123         penclen = i2o_ECPublicKey(ec_key, &p);
124         if (penclen <= 0)
125                 goto err;
126         if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
127                 ptype, pval, penc, penclen))
128                 return 1;
129  err:
130         if (ptype == V_ASN1_OBJECT)
131                 ASN1_OBJECT_free(pval);
132         else
133                 ASN1_STRING_free(pval);
134         free(penc);
135         return 0;
136 }
137
138 static EC_KEY *
139 eckey_type2param(int ptype, const void *pval)
140 {
141         EC_KEY *eckey = NULL;
142
143         if (ptype == V_ASN1_SEQUENCE) {
144                 const ASN1_STRING *pstr = pval;
145                 const unsigned char *pm = NULL;
146                 int pmlen;
147
148                 pm = pstr->data;
149                 pmlen = pstr->length;
150                 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
151                         ECerror(EC_R_DECODE_ERROR);
152                         goto ecerr;
153                 }
154         } else if (ptype == V_ASN1_OBJECT) {
155                 const ASN1_OBJECT *poid = pval;
156                 EC_GROUP *group;
157
158                 /*
159                  * type == V_ASN1_OBJECT => the parameters are given by an
160                  * asn1 OID
161                  */
162                 if ((eckey = EC_KEY_new()) == NULL) {
163                         ECerror(ERR_R_MALLOC_FAILURE);
164                         goto ecerr;
165                 }
166                 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
167                 if (group == NULL)
168                         goto ecerr;
169                 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
170                 if (EC_KEY_set_group(eckey, group) == 0)
171                         goto ecerr;
172                 EC_GROUP_free(group);
173         } else {
174                 ECerror(EC_R_DECODE_ERROR);
175                 goto ecerr;
176         }
177
178         return eckey;
179
180  ecerr:
181         if (eckey)
182                 EC_KEY_free(eckey);
183         return NULL;
184 }
185
186 static int 
187 eckey_pub_decode(EVP_PKEY * pkey, X509_PUBKEY * pubkey)
188 {
189         const unsigned char *p = NULL;
190         const void *pval;
191         int ptype, pklen;
192         EC_KEY *eckey = NULL;
193         X509_ALGOR *palg;
194
195         if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
196                 return 0;
197         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
198
199         eckey = eckey_type2param(ptype, pval);
200
201         if (!eckey) {
202                 ECerror(ERR_R_EC_LIB);
203                 return 0;
204         }
205         /* We have parameters now set public key */
206         if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
207                 ECerror(EC_R_DECODE_ERROR);
208                 goto ecerr;
209         }
210         EVP_PKEY_assign_EC_KEY(pkey, eckey);
211         return 1;
212
213  ecerr:
214         if (eckey)
215                 EC_KEY_free(eckey);
216         return 0;
217 }
218
219 static int 
220 eckey_pub_cmp(const EVP_PKEY * a, const EVP_PKEY * b)
221 {
222         int r;
223         const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
224         const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec);
225
226         r = EC_POINT_cmp(group, pa, pb, NULL);
227         if (r == 0)
228                 return 1;
229         if (r == 1)
230                 return 0;
231         return -2;
232 }
233
234 static int 
235 eckey_priv_decode(EVP_PKEY * pkey, const PKCS8_PRIV_KEY_INFO * p8)
236 {
237         const unsigned char *p = NULL;
238         const void *pval;
239         int ptype, pklen;
240         EC_KEY *eckey = NULL;
241         const X509_ALGOR *palg;
242
243         if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
244                 return 0;
245         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
246
247         eckey = eckey_type2param(ptype, pval);
248
249         if (!eckey)
250                 goto ecliberr;
251
252         /* We have parameters now set private key */
253         if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
254                 ECerror(EC_R_DECODE_ERROR);
255                 goto ecerr;
256         }
257         /* calculate public key (if necessary) */
258         if (EC_KEY_get0_public_key(eckey) == NULL) {
259                 const BIGNUM *priv_key;
260                 const EC_GROUP *group;
261                 EC_POINT *pub_key;
262                 /*
263                  * the public key was not included in the SEC1 private key =>
264                  * calculate the public key
265                  */
266                 group = EC_KEY_get0_group(eckey);
267                 pub_key = EC_POINT_new(group);
268                 if (pub_key == NULL) {
269                         ECerror(ERR_R_EC_LIB);
270                         goto ecliberr;
271                 }
272                 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
273                         EC_POINT_free(pub_key);
274                         ECerror(ERR_R_EC_LIB);
275                         goto ecliberr;
276                 }
277                 priv_key = EC_KEY_get0_private_key(eckey);
278                 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
279                         EC_POINT_free(pub_key);
280                         ECerror(ERR_R_EC_LIB);
281                         goto ecliberr;
282                 }
283                 if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
284                         EC_POINT_free(pub_key);
285                         ECerror(ERR_R_EC_LIB);
286                         goto ecliberr;
287                 }
288                 EC_POINT_free(pub_key);
289         }
290         EVP_PKEY_assign_EC_KEY(pkey, eckey);
291         return 1;
292
293  ecliberr:
294         ECerror(ERR_R_EC_LIB);
295  ecerr:
296         if (eckey)
297                 EC_KEY_free(eckey);
298         return 0;
299 }
300
301 static int 
302 eckey_priv_encode(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pkey)
303 {
304         EC_KEY *ec_key;
305         unsigned char *ep, *p;
306         int eplen, ptype;
307         void *pval;
308         unsigned int tmp_flags, old_flags;
309
310         ec_key = pkey->pkey.ec;
311
312         if (!eckey_param2type(&ptype, &pval, ec_key)) {
313                 ECerror(EC_R_DECODE_ERROR);
314                 return 0;
315         }
316         /* set the private key */
317
318         /*
319          * do not include the parameters in the SEC1 private key see PKCS#11
320          * 12.11
321          */
322         old_flags = EC_KEY_get_enc_flags(ec_key);
323         tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
324         EC_KEY_set_enc_flags(ec_key, tmp_flags);
325         eplen = i2d_ECPrivateKey(ec_key, NULL);
326         if (!eplen) {
327                 EC_KEY_set_enc_flags(ec_key, old_flags);
328                 ECerror(ERR_R_EC_LIB);
329                 return 0;
330         }
331         ep = malloc(eplen);
332         if (!ep) {
333                 EC_KEY_set_enc_flags(ec_key, old_flags);
334                 ECerror(ERR_R_MALLOC_FAILURE);
335                 return 0;
336         }
337         p = ep;
338         if (!i2d_ECPrivateKey(ec_key, &p)) {
339                 EC_KEY_set_enc_flags(ec_key, old_flags);
340                 free(ep);
341                 ECerror(ERR_R_EC_LIB);
342                 return 0;
343         }
344         /* restore old encoding flags */
345         EC_KEY_set_enc_flags(ec_key, old_flags);
346
347         if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
348                 ptype, pval, ep, eplen))
349                 return 0;
350
351         return 1;
352 }
353
354 static int 
355 int_ec_size(const EVP_PKEY * pkey)
356 {
357         return ECDSA_size(pkey->pkey.ec);
358 }
359
360 static int 
361 ec_bits(const EVP_PKEY * pkey)
362 {
363         BIGNUM *order = BN_new();
364         const EC_GROUP *group;
365         int ret;
366
367         if (!order) {
368                 ERR_clear_error();
369                 return 0;
370         }
371         group = EC_KEY_get0_group(pkey->pkey.ec);
372         if (!EC_GROUP_get_order(group, order, NULL)) {
373                 BN_free(order);
374                 ERR_clear_error();
375                 return 0;
376         }
377         ret = BN_num_bits(order);
378         BN_free(order);
379         return ret;
380 }
381
382 static int 
383 ec_missing_parameters(const EVP_PKEY * pkey)
384 {
385         if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
386                 return 1;
387         return 0;
388 }
389
390 static int 
391 ec_copy_parameters(EVP_PKEY * to, const EVP_PKEY * from)
392 {
393         return EC_KEY_set_group(to->pkey.ec, EC_KEY_get0_group(from->pkey.ec));
394 }
395
396 static int 
397 ec_cmp_parameters(const EVP_PKEY * a, const EVP_PKEY * b)
398 {
399         const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec);
400         if (EC_GROUP_cmp(group_a, group_b, NULL))
401                 return 0;
402         else
403                 return 1;
404 }
405
406 static void 
407 int_ec_free(EVP_PKEY * pkey)
408 {
409         EC_KEY_free(pkey->pkey.ec);
410 }
411
412 static int 
413 do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype)
414 {
415         unsigned char *buffer = NULL;
416         const char *ecstr;
417         size_t buf_len = 0, i;
418         int ret = 0, reason = ERR_R_BIO_LIB;
419         BIGNUM *pub_key = NULL, *order = NULL;
420         BN_CTX *ctx = NULL;
421         const EC_GROUP *group;
422         const EC_POINT *public_key;
423         const BIGNUM *priv_key;
424
425         if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
426                 reason = ERR_R_PASSED_NULL_PARAMETER;
427                 goto err;
428         }
429         ctx = BN_CTX_new();
430         if (ctx == NULL) {
431                 reason = ERR_R_MALLOC_FAILURE;
432                 goto err;
433         }
434         if (ktype > 0) {
435                 public_key = EC_KEY_get0_public_key(x);
436                 if (public_key != NULL) {
437                         if ((pub_key = EC_POINT_point2bn(group, public_key,
438                             EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) {
439                                 reason = ERR_R_EC_LIB;
440                                 goto err;
441                         }
442                         if (pub_key)
443                                 buf_len = (size_t) BN_num_bytes(pub_key);
444                 }
445         }
446         if (ktype == 2) {
447                 priv_key = EC_KEY_get0_private_key(x);
448                 if (priv_key && (i = (size_t) BN_num_bytes(priv_key)) > buf_len)
449                         buf_len = i;
450         } else
451                 priv_key = NULL;
452
453         if (ktype > 0) {
454                 buf_len += 10;
455                 if ((buffer = malloc(buf_len)) == NULL) {
456                         reason = ERR_R_MALLOC_FAILURE;
457                         goto err;
458                 }
459         }
460         if (ktype == 2)
461                 ecstr = "Private-Key";
462         else if (ktype == 1)
463                 ecstr = "Public-Key";
464         else
465                 ecstr = "ECDSA-Parameters";
466
467         if (!BIO_indent(bp, off, 128))
468                 goto err;
469         if ((order = BN_new()) == NULL)
470                 goto err;
471         if (!EC_GROUP_get_order(group, order, NULL))
472                 goto err;
473         if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
474                 BN_num_bits(order)) <= 0)
475                 goto err;
476
477         if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
478                 buffer, off))
479                 goto err;
480         if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
481                 buffer, off))
482                 goto err;
483         if (!ECPKParameters_print(bp, group, off))
484                 goto err;
485         ret = 1;
486  err:
487         if (!ret)
488                 ECerror(reason);
489         BN_free(pub_key);
490         BN_free(order);
491         BN_CTX_free(ctx);
492         free(buffer);
493         return (ret);
494 }
495
496 static int 
497 eckey_param_decode(EVP_PKEY * pkey,
498     const unsigned char **pder, int derlen)
499 {
500         EC_KEY *eckey;
501         if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
502                 ECerror(ERR_R_EC_LIB);
503                 return 0;
504         }
505         EVP_PKEY_assign_EC_KEY(pkey, eckey);
506         return 1;
507 }
508
509 static int 
510 eckey_param_encode(const EVP_PKEY * pkey, unsigned char **pder)
511 {
512         return i2d_ECParameters(pkey->pkey.ec, pder);
513 }
514
515 static int 
516 eckey_param_print(BIO * bp, const EVP_PKEY * pkey, int indent,
517     ASN1_PCTX * ctx)
518 {
519         return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
520 }
521
522 static int 
523 eckey_pub_print(BIO * bp, const EVP_PKEY * pkey, int indent,
524     ASN1_PCTX * ctx)
525 {
526         return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
527 }
528
529
530 static int 
531 eckey_priv_print(BIO * bp, const EVP_PKEY * pkey, int indent,
532     ASN1_PCTX * ctx)
533 {
534         return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
535 }
536
537 static int 
538 old_ec_priv_decode(EVP_PKEY * pkey,
539     const unsigned char **pder, int derlen)
540 {
541         EC_KEY *ec;
542         if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
543                 ECerror(EC_R_DECODE_ERROR);
544                 return 0;
545         }
546         EVP_PKEY_assign_EC_KEY(pkey, ec);
547         return 1;
548 }
549
550 static int 
551 old_ec_priv_encode(const EVP_PKEY * pkey, unsigned char **pder)
552 {
553         return i2d_ECPrivateKey(pkey->pkey.ec, pder);
554 }
555
556 static int 
557 ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2)
558 {
559         switch (op) {
560         case ASN1_PKEY_CTRL_PKCS7_SIGN:
561                 if (arg1 == 0) {
562                         int snid, hnid;
563                         X509_ALGOR *alg1, *alg2;
564                         PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
565                         if (alg1 == NULL || alg1->algorithm == NULL)
566                                 return -1;
567                         hnid = OBJ_obj2nid(alg1->algorithm);
568                         if (hnid == NID_undef)
569                                 return -1;
570                         if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
571                                 return -1;
572                         X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
573                 }
574                 return 1;
575
576         case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
577                 *(int *) arg2 = NID_sha1;
578                 return 2;
579
580         default:
581                 return -2;
582
583         }
584
585 }
586
587 const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
588         .pkey_id = EVP_PKEY_EC,
589         .pkey_base_id = EVP_PKEY_EC,
590
591         .pem_str = "EC",
592         .info = "OpenSSL EC algorithm",
593
594         .pub_decode = eckey_pub_decode,
595         .pub_encode = eckey_pub_encode,
596         .pub_cmp = eckey_pub_cmp,
597         .pub_print = eckey_pub_print,
598
599         .priv_decode = eckey_priv_decode,
600         .priv_encode = eckey_priv_encode,
601         .priv_print = eckey_priv_print,
602
603         .pkey_size = int_ec_size,
604         .pkey_bits = ec_bits,
605
606         .param_decode = eckey_param_decode,
607         .param_encode = eckey_param_encode,
608         .param_missing = ec_missing_parameters,
609         .param_copy = ec_copy_parameters,
610         .param_cmp = ec_cmp_parameters,
611         .param_print = eckey_param_print,
612
613         .pkey_free = int_ec_free,
614         .pkey_ctrl = ec_pkey_ctrl,
615         .old_priv_decode = old_ec_priv_decode,
616         .old_priv_encode = old_ec_priv_encode
617 };