Branch data Line data Source code
1 : : /* crypto/ecdsa/ecs_lib.c */
2 : : /* ====================================================================
3 : : * Copyright (c) 1998-2005 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 : : * openssl-core@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 <string.h>
57 : : #include "ecs_locl.h"
58 : : #ifndef OPENSSL_NO_ENGINE
59 : : #include <openssl/engine.h>
60 : : #endif
61 : : #include <openssl/err.h>
62 : : #include <openssl/bn.h>
63 : :
64 : : const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT;
65 : :
66 : : static const ECDSA_METHOD *default_ECDSA_method = NULL;
67 : :
68 : : static void *ecdsa_data_new(void);
69 : : static void *ecdsa_data_dup(void *);
70 : : static void ecdsa_data_free(void *);
71 : :
72 : 0 : void ECDSA_set_default_method(const ECDSA_METHOD *meth)
73 : : {
74 : 0 : default_ECDSA_method = meth;
75 : 0 : }
76 : :
77 : 138 : const ECDSA_METHOD *ECDSA_get_default_method(void)
78 : : {
79 [ + + ]: 138 : if(!default_ECDSA_method)
80 : 1 : default_ECDSA_method = ECDSA_OpenSSL();
81 : 138 : return default_ECDSA_method;
82 : : }
83 : :
84 : 0 : int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
85 : : {
86 : : ECDSA_DATA *ecdsa;
87 : :
88 : 0 : ecdsa = ecdsa_check(eckey);
89 : :
90 [ # # ]: 0 : if (ecdsa == NULL)
91 : : return 0;
92 : :
93 : : #ifndef OPENSSL_NO_ENGINE
94 [ # # ]: 0 : if (ecdsa->engine)
95 : : {
96 : 0 : ENGINE_finish(ecdsa->engine);
97 : 0 : ecdsa->engine = NULL;
98 : : }
99 : : #endif
100 : 0 : ecdsa->meth = meth;
101 : :
102 : 0 : return 1;
103 : : }
104 : :
105 : 138 : static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
106 : : {
107 : : ECDSA_DATA *ret;
108 : :
109 : 138 : ret=(ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA));
110 [ - + ]: 138 : if (ret == NULL)
111 : : {
112 : 0 : ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
113 : 0 : return(NULL);
114 : : }
115 : :
116 : 138 : ret->init = NULL;
117 : :
118 : 138 : ret->meth = ECDSA_get_default_method();
119 : 138 : ret->engine = engine;
120 : : #ifndef OPENSSL_NO_ENGINE
121 [ + - ]: 138 : if (!ret->engine)
122 : 138 : ret->engine = ENGINE_get_default_ECDSA();
123 [ - + ]: 138 : if (ret->engine)
124 : : {
125 : 0 : ret->meth = ENGINE_get_ECDSA(ret->engine);
126 [ # # ]: 0 : if (!ret->meth)
127 : : {
128 : 0 : ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
129 : 0 : ENGINE_finish(ret->engine);
130 : 0 : OPENSSL_free(ret);
131 : 0 : return NULL;
132 : : }
133 : : }
134 : : #endif
135 : :
136 : 138 : ret->flags = ret->meth->flags;
137 : 138 : CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
138 : : #if 0
139 : : if ((ret->meth->init != NULL) && !ret->meth->init(ret))
140 : : {
141 : : CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
142 : : OPENSSL_free(ret);
143 : : ret=NULL;
144 : : }
145 : : #endif
146 : 138 : return(ret);
147 : : }
148 : :
149 : 138 : static void *ecdsa_data_new(void)
150 : : {
151 : 138 : return (void *)ECDSA_DATA_new_method(NULL);
152 : : }
153 : :
154 : 0 : static void *ecdsa_data_dup(void *data)
155 : : {
156 : 0 : ECDSA_DATA *r = (ECDSA_DATA *)data;
157 : :
158 : : /* XXX: dummy operation */
159 [ # # ]: 0 : if (r == NULL)
160 : : return NULL;
161 : :
162 : 0 : return ecdsa_data_new();
163 : : }
164 : :
165 : 138 : static void ecdsa_data_free(void *data)
166 : : {
167 : 138 : ECDSA_DATA *r = (ECDSA_DATA *)data;
168 : :
169 : : #ifndef OPENSSL_NO_ENGINE
170 [ - + ]: 138 : if (r->engine)
171 : 0 : ENGINE_finish(r->engine);
172 : : #endif
173 : 138 : CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
174 : :
175 : 138 : OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA));
176 : :
177 : 138 : OPENSSL_free(r);
178 : 138 : }
179 : :
180 : 485 : ECDSA_DATA *ecdsa_check(EC_KEY *key)
181 : : {
182 : : ECDSA_DATA *ecdsa_data;
183 : :
184 : 485 : void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup,
185 : : ecdsa_data_free, ecdsa_data_free);
186 [ + + ]: 485 : if (data == NULL)
187 : : {
188 : 138 : ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
189 [ + - ]: 138 : if (ecdsa_data == NULL)
190 : : return NULL;
191 : 138 : data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
192 : : ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
193 [ - + ]: 138 : if (data != NULL)
194 : : {
195 : : /* Another thread raced us to install the key_method
196 : : * data and won. */
197 : 0 : ecdsa_data_free(ecdsa_data);
198 : 0 : ecdsa_data = (ECDSA_DATA *)data;
199 : : }
200 : : }
201 : : else
202 : : ecdsa_data = (ECDSA_DATA *)data;
203 : :
204 : :
205 : 485 : return ecdsa_data;
206 : : }
207 : :
208 : 67 : int ECDSA_size(const EC_KEY *r)
209 : : {
210 : : int ret,i;
211 : : ASN1_INTEGER bs;
212 : 67 : BIGNUM *order=NULL;
213 : : unsigned char buf[4];
214 : : const EC_GROUP *group;
215 : :
216 [ + - ]: 67 : if (r == NULL)
217 : : return 0;
218 : 67 : group = EC_KEY_get0_group(r);
219 [ + - ]: 67 : if (group == NULL)
220 : : return 0;
221 : :
222 [ + - ]: 67 : if ((order = BN_new()) == NULL) return 0;
223 [ - + ]: 67 : if (!EC_GROUP_get_order(group,order,NULL))
224 : : {
225 : 0 : BN_clear_free(order);
226 : 0 : return 0;
227 : : }
228 : 67 : i=BN_num_bits(order);
229 : 67 : bs.length=(i+7)/8;
230 : 67 : bs.data=buf;
231 : 67 : bs.type=V_ASN1_INTEGER;
232 : : /* If the top bit is set the asn1 encoding is 1 larger. */
233 : 67 : buf[0]=0xff;
234 : :
235 : 67 : i=i2d_ASN1_INTEGER(&bs,NULL);
236 : 67 : i+=i; /* r and s */
237 : 67 : ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
238 : 67 : BN_clear_free(order);
239 : 67 : return(ret);
240 : : }
241 : :
242 : :
243 : 0 : int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
244 : : CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
245 : : {
246 : 0 : return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp,
247 : : new_func, dup_func, free_func);
248 : : }
249 : :
250 : 0 : int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg)
251 : : {
252 : : ECDSA_DATA *ecdsa;
253 : 0 : ecdsa = ecdsa_check(d);
254 [ # # ]: 0 : if (ecdsa == NULL)
255 : : return 0;
256 : 0 : return(CRYPTO_set_ex_data(&ecdsa->ex_data,idx,arg));
257 : : }
258 : :
259 : 0 : void *ECDSA_get_ex_data(EC_KEY *d, int idx)
260 : : {
261 : : ECDSA_DATA *ecdsa;
262 : 0 : ecdsa = ecdsa_check(d);
263 [ # # ]: 0 : if (ecdsa == NULL)
264 : : return NULL;
265 : 0 : return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx));
266 : : }
267 : :
268 : 0 : ECDSA_METHOD *ECDSA_METHOD_new(ECDSA_METHOD *ecdsa_meth)
269 : : {
270 : : ECDSA_METHOD *ret;
271 : :
272 : 0 : ret = OPENSSL_malloc(sizeof(ECDSA_METHOD));
273 [ # # ]: 0 : if (ret == NULL)
274 : : {
275 : 0 : ECDSAerr(ECDSA_F_ECDSA_METHOD_NEW, ERR_R_MALLOC_FAILURE);
276 : 0 : return NULL;
277 : : }
278 : :
279 [ # # ]: 0 : if (ecdsa_meth)
280 : 0 : *ret = *ecdsa_meth;
281 : : else
282 : : {
283 : 0 : ret->ecdsa_sign_setup = 0;
284 : 0 : ret->ecdsa_do_sign = 0;
285 : 0 : ret->ecdsa_do_verify = 0;
286 : 0 : ret->name = NULL;
287 : 0 : ret->flags = 0;
288 : : }
289 : 0 : ret->flags |= ECDSA_METHOD_FLAG_ALLOCATED;
290 : 0 : return ret;
291 : : }
292 : :
293 : :
294 : 0 : void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method,
295 : : ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len,
296 : : const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey))
297 : : {
298 : 0 : ecdsa_method->ecdsa_do_sign = ecdsa_do_sign;
299 : 0 : }
300 : :
301 : 0 : void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method,
302 : : int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
303 : : BIGNUM **r))
304 : : {
305 : 0 : ecdsa_method->ecdsa_sign_setup = ecdsa_sign_setup;
306 : 0 : }
307 : :
308 : 0 : void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method,
309 : : int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len,
310 : : const ECDSA_SIG *sig, EC_KEY *eckey))
311 : : {
312 : 0 : ecdsa_method->ecdsa_do_verify = ecdsa_do_verify;
313 : 0 : }
314 : :
315 : 0 : void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags)
316 : : {
317 : 0 : ecdsa_method->flags = flags | ECDSA_METHOD_FLAG_ALLOCATED;
318 : 0 : }
319 : :
320 : 0 : void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name)
321 : : {
322 : 0 : ecdsa_method->name = name;
323 : 0 : }
324 : :
325 : 0 : void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method)
326 : : {
327 [ # # ]: 0 : if (ecdsa_method->flags & ECDSA_METHOD_FLAG_ALLOCATED)
328 : 0 : OPENSSL_free(ecdsa_method);
329 : 0 : }
330 : :
331 : 0 : void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app)
332 : : {
333 : 0 : ecdsa_method->app_data = app;
334 : 0 : }
335 : :
336 : 0 : void * ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method)
337 : : {
338 : 0 : return ecdsa_method->app_data;
339 : : }
|