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