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