Move zeroing from bn_expand_internal() to bn_expand2() so that it
[openssl.git] / crypto / ecdsa / ecs_asn1.c
1 /* crypto/ecdsa/ecs_asn1.c */
2 /* ====================================================================
3  * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer. 
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this
18  *    software must display the following acknowledgment:
19  *    "This product includes software developed by the OpenSSL Project
20  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21  *
22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23  *    endorse or promote products derived from this software without
24  *    prior written permission. For written permission, please contact
25  *    licensing@OpenSSL.org.
26  *
27  * 5. Products derived from this software may not be called "OpenSSL"
28  *    nor may "OpenSSL" appear in their names without prior written
29  *    permission of the OpenSSL Project.
30  *
31  * 6. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by the OpenSSL Project
34  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47  * OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This product includes cryptographic software written by Eric Young
51  * (eay@cryptsoft.com).  This product includes software written by Tim
52  * Hudson (tjh@cryptsoft.com).
53  *
54  */
55
56 #include "ecdsa.h"
57 #include "cryptlib.h"
58 #include <openssl/asn1.h>
59 #include <openssl/asn1t.h>
60
61 typedef struct ecdsa_priv_key_st {
62         int               version;
63         ECPKPARAMETERS    *parameters;
64         ASN1_OBJECT       *named_curve;
65         ASN1_OCTET_STRING *pub_key;
66         BIGNUM            *priv_key;
67         } ECDSAPrivateKey;
68
69 ASN1_SEQUENCE(ECDSA_SIG) = {
70         ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
71         ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
72 } ASN1_SEQUENCE_END(ECDSA_SIG)
73
74 DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
75 DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
76 IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG)
77
78 ASN1_SEQUENCE(ECDSAPrivateKey) = {
79         ASN1_SIMPLE(ECDSAPrivateKey, version, LONG),
80         ASN1_SIMPLE(ECDSAPrivateKey, parameters, ECPKPARAMETERS),
81         ASN1_SIMPLE(ECDSAPrivateKey, pub_key, ASN1_OCTET_STRING),
82         ASN1_SIMPLE(ECDSAPrivateKey, priv_key, BIGNUM)
83 } ASN1_SEQUENCE_END(ECDSAPrivateKey)
84
85 DECLARE_ASN1_FUNCTIONS_const(ECDSAPrivateKey)
86 DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSAPrivateKey, ecdsaPrivateKey)
87 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(ECDSAPrivateKey, ECDSAPrivateKey, ECDSAPrivateKey)
88 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSAPrivateKey, ECDSAPrivateKey, ecdsaPrivateKey)
89
90 int i2d_ECDSAParameters(ECDSA *a, unsigned char **out)
91         {
92         if (a == NULL)
93                 {
94                 ECDSAerr(ECDSA_F_I2D_ECDSAPARAMETERS, 
95                          ERR_R_PASSED_NULL_PARAMETER);
96                 return 0;
97                 }
98         return i2d_ECPKParameters(a->group, out);
99         }
100
101 ECDSA *d2i_ECDSAParameters(ECDSA **a, const unsigned char **in, long len)
102         {
103         EC_GROUP *group;
104         ECDSA    *ret;
105
106         if (in == NULL || *in == NULL)
107                 {
108                 ECDSAerr(ECDSA_F_D2I_ECDSAPARAMETERS, 
109                          ERR_R_PASSED_NULL_PARAMETER);
110                 return NULL;
111                 }
112
113         group = d2i_ECPKParameters(NULL, in, len);
114
115         if (group == NULL)
116                 {
117                 ECDSAerr(ECDSA_F_D2I_ECDSAPARAMETERS, 
118                          ERR_R_EC_LIB);
119                 return NULL;
120                 }
121
122         if (a == NULL || *a == NULL)
123                 {
124                 if ((ret = ECDSA_new()) == NULL)
125                         {
126                         ECDSAerr(ECDSA_F_D2I_ECDSAPARAMETERS, 
127                                  ERR_R_MALLOC_FAILURE);
128                         return NULL;
129                         }
130                 if (a)
131                         *a = ret;
132                 }
133         else
134                 ret = *a;
135
136         if (ret->group)
137                 EC_GROUP_clear_free(ret->group);
138
139         ret->group = group;
140         
141         return ret;
142         }
143
144 ECDSA *d2i_ECDSAPrivateKey(ECDSA **a, const unsigned char **in, long len)
145         {
146         int             ok=0;
147         ECDSA           *ret=NULL;
148         ECDSAPrivateKey *priv_key=NULL;
149
150         if ((priv_key = ECDSAPrivateKey_new()) == NULL)
151                 {
152                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ERR_R_MALLOC_FAILURE);
153                 return NULL;
154                 }
155
156         if ((priv_key = d2i_ecdsaPrivateKey(&priv_key, in, len)) == NULL)
157                 {
158                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY,
159                          ECDSA_R_D2I_ECDSA_PRIVATEKEY_FAILURE);
160                 ECDSAPrivateKey_free(priv_key);
161                 return NULL;
162                 }
163
164         if (a == NULL || *a == NULL)
165                 {
166                 if ((ret = ECDSA_new()) == NULL)        
167                         {
168                         ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY,
169                                  ERR_R_MALLOC_FAILURE);
170                         goto err;
171                         }
172                 if (a)
173                         *a = ret;
174                 }
175         else
176                 ret = *a;
177
178         if (ret->group)
179                 EC_GROUP_clear_free(ret->group);
180
181         ret->group = EC_ASN1_pkparameters2group(priv_key->parameters);
182         if (ret->group == NULL)
183                 {
184                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ERR_R_EC_LIB);
185                 goto err;
186                 }
187
188         ret->version = priv_key->version;
189         if (priv_key->priv_key)
190                 {
191                 if ((ret->priv_key = BN_dup(priv_key->priv_key)) == NULL)
192                         {
193                         ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY,
194                                  ERR_R_BN_LIB);
195                         goto err;
196                         }
197                 }
198         else
199                 {
200                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, 
201                          ECDSA_R_MISSING_PRIVATE_KEY);
202                 goto err;
203                 }
204
205         if ((ret->pub_key = EC_POINT_new(ret->group)) == NULL)
206                 {
207                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ERR_R_EC_LIB);
208                 goto err;
209                 }
210
211         if (!EC_POINT_oct2point(ret->group, ret->pub_key, 
212                 priv_key->pub_key->data, priv_key->pub_key->length, NULL))
213                 {
214                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ERR_R_EC_LIB);
215                 goto err;
216                 }
217
218         ok = 1;
219
220 err :   if (!ok)
221         {
222                 if (ret) ECDSA_free(ret);
223                 ret = NULL;
224         }
225         if (priv_key)
226                 ECDSAPrivateKey_free(priv_key);
227         return(ret);
228 }
229
230 int     i2d_ECDSAPrivateKey(ECDSA *a, unsigned char **out)
231 {
232         int ret=0, ok=0;
233         unsigned char   *buffer=NULL;
234         size_t          buf_len=0;
235         ECDSAPrivateKey *priv_key=NULL;
236
237         if (a == NULL || a->group == NULL)
238                 {
239                 ECDSAerr(ECDSA_F_I2D_ECDSAPRIVATEKEY,
240                          ERR_R_PASSED_NULL_PARAMETER);
241                 goto err;
242                 }
243
244         if ((priv_key = ECDSAPrivateKey_new()) == NULL)
245                 {
246                 ECDSAerr(ECDSA_F_I2D_ECDSAPRIVATEKEY,
247                          ERR_R_MALLOC_FAILURE);
248                 goto err;
249                 }
250
251         if ((priv_key->parameters = EC_ASN1_group2pkparameters(a->group, 
252                                     priv_key->parameters)) == NULL)
253                 {
254                 ECDSAerr(ECDSA_F_I2D_ECDSAPRIVATEKEY, ERR_R_EC_LIB);
255                 goto err;
256                 }
257
258         priv_key->version      = a->version;
259
260         if (BN_copy(priv_key->priv_key, a->priv_key) == NULL)
261                 {
262                 ECDSAerr(ECDSA_F_I2D_ECDSAPRIVATEKEY, ERR_R_BN_LIB);
263                 goto err;
264                 }
265
266         buf_len = EC_POINT_point2oct(a->group, a->pub_key, 
267                            ECDSA_get_conversion_form(a), NULL, 0, NULL);
268         if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
269                 {
270                 ECDSAerr(ECDSA_F_I2D_ECDSAPRIVATEKEY, ERR_R_MALLOC_FAILURE);
271                 goto err;
272                 }
273         if (!EC_POINT_point2oct(a->group, a->pub_key, 
274                         ECDSA_get_conversion_form(a), buffer, buf_len, NULL))
275                 {
276                 ECDSAerr(ECDSA_F_I2D_ECDSAPRIVATEKEY, ERR_R_EC_LIB);
277                 goto err;
278                 }
279         if (!M_ASN1_OCTET_STRING_set(priv_key->pub_key, buffer, buf_len))
280                 {
281                 ECDSAerr(ECDSA_F_I2D_ECDSAPRIVATEKEY, ERR_R_ASN1_LIB);
282                 goto err;
283                 }
284         if ((ret = i2d_ecdsaPrivateKey(priv_key, out)) == 0)
285                 {
286                 ECDSAerr(ECDSA_F_I2D_ECDSAPRIVATEKEY, 
287                          ECDSA_R_I2D_ECDSA_PRIVATEKEY);
288                 goto err;
289                 }
290         ok=1;
291         
292 err:
293         if (buffer)
294                 OPENSSL_free(buffer);
295         if (priv_key)
296                 ECDSAPrivateKey_free(priv_key); 
297         return(ok?ret:0);
298 }
299
300
301 ECDSA   *ECDSAPublicKey_set_octet_string(ECDSA **a, const unsigned char **in, long len)
302 {
303         ECDSA *ret=NULL;
304
305         if (a == NULL || (*a) == NULL || (*a)->group == NULL)
306         {
307                 /* sorry, but a EC_GROUP-structur is necessary
308                  * to set the public key */
309                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ECDSA_R_MISSING_PARAMETERS);
310                 return 0;
311         }
312         ret = *a;
313         if (ret->pub_key == NULL && (ret->pub_key = EC_POINT_new(ret->group)) == NULL)
314         {
315                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ERR_R_MALLOC_FAILURE);
316                 return 0;
317         }
318         if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
319         {
320                 ECDSAerr(ECDSA_F_D2I_ECDSAPRIVATEKEY, ERR_R_EC_LIB);
321                 return 0;
322         }
323         ECDSA_set_conversion_form(ret, (point_conversion_form_t)(*in[0] & ~0x01));
324         return ret;
325 }
326
327 int     ECDSAPublicKey_get_octet_string(ECDSA *a, unsigned char **out)
328 {
329         size_t  buf_len=0;
330
331         if (a == NULL) 
332         {
333                 ECDSAerr(ECDSA_F_I2D_ECDSAPUBLICKEY, ECDSA_R_MISSING_PARAMETERS);
334                 return 0;
335         }
336         buf_len = EC_POINT_point2oct(a->group, a->pub_key, 
337                               ECDSA_get_conversion_form(a), NULL, 0, NULL);
338         if (out == NULL || buf_len == 0)
339         /* out == NULL => just return the length of the octet string */
340                 return buf_len;
341         if (*out == NULL)
342                 if ((*out = OPENSSL_malloc(buf_len)) == NULL)
343                 {
344                         ECDSAerr(ECDSA_F_I2D_ECDSAPUBLICKEY, ERR_R_MALLOC_FAILURE);
345                         return 0;
346                 }
347         if (!EC_POINT_point2oct(a->group, a->pub_key, ECDSA_get_conversion_form(a),
348                                 *out, buf_len, NULL))
349         {
350                 ECDSAerr(ECDSA_F_I2D_ECDSAPUBLICKEY, ERR_R_EC_LIB);
351                 OPENSSL_free(*out);
352                 *out = NULL;
353                 return 0;
354         }
355         return buf_len;
356 }