~ubuntu-branches/ubuntu/maverick/openssl/maverick

« back to all changes in this revision

Viewing changes to crypto/ecdsa/ecs_lib.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2005-12-13 21:37:42 UTC
  • mto: (11.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051213213742-d0ydaylf80l16bj1
Tags: upstream-0.9.8a
ImportĀ upstreamĀ versionĀ 0.9.8a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
void ECDSA_set_default_method(const ECDSA_METHOD *meth)
 
73
{
 
74
        default_ECDSA_method = meth;
 
75
}
 
76
 
 
77
const ECDSA_METHOD *ECDSA_get_default_method(void)
 
78
{
 
79
        if(!default_ECDSA_method) 
 
80
                default_ECDSA_method = ECDSA_OpenSSL();
 
81
        return default_ECDSA_method;
 
82
}
 
83
 
 
84
int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
 
85
{
 
86
        const ECDSA_METHOD *mtmp;
 
87
        ECDSA_DATA *ecdsa;
 
88
 
 
89
        ecdsa = ecdsa_check(eckey);
 
90
 
 
91
        if (ecdsa == NULL)
 
92
                return 0;
 
93
 
 
94
        mtmp = ecdsa->meth;
 
95
#ifndef OPENSSL_NO_ENGINE
 
96
        if (ecdsa->engine)
 
97
        {
 
98
                ENGINE_finish(ecdsa->engine);
 
99
                ecdsa->engine = NULL;
 
100
        }
 
101
#endif
 
102
        ecdsa->meth = meth;
 
103
 
 
104
        return 1;
 
105
}
 
106
 
 
107
static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
 
108
{
 
109
        ECDSA_DATA *ret;
 
110
 
 
111
        ret=(ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA));
 
112
        if (ret == NULL)
 
113
        {
 
114
                ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
 
115
                return(NULL);
 
116
        }
 
117
 
 
118
        ret->init = NULL;
 
119
 
 
120
        ret->meth = ECDSA_get_default_method();
 
121
        ret->engine = engine;
 
122
#ifndef OPENSSL_NO_ENGINE
 
123
        if (!ret->engine)
 
124
                ret->engine = ENGINE_get_default_ECDSA();
 
125
        if (ret->engine)
 
126
        {
 
127
                ret->meth = ENGINE_get_ECDSA(ret->engine);
 
128
                if (!ret->meth)
 
129
                {
 
130
                        ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
 
131
                        ENGINE_finish(ret->engine);
 
132
                        OPENSSL_free(ret);
 
133
                        return NULL;
 
134
                }
 
135
        }
 
136
#endif
 
137
 
 
138
        ret->flags = ret->meth->flags;
 
139
        CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
 
140
#if 0
 
141
        if ((ret->meth->init != NULL) && !ret->meth->init(ret))
 
142
        {
 
143
                CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
 
144
                OPENSSL_free(ret);
 
145
                ret=NULL;
 
146
        }
 
147
#endif  
 
148
        return(ret);
 
149
}
 
150
 
 
151
static void *ecdsa_data_new(void)
 
152
{
 
153
        return (void *)ECDSA_DATA_new_method(NULL);
 
154
}
 
155
 
 
156
static void *ecdsa_data_dup(void *data)
 
157
{
 
158
        ECDSA_DATA *r = (ECDSA_DATA *)data;
 
159
 
 
160
        /* XXX: dummy operation */
 
161
        if (r == NULL)
 
162
                return NULL;
 
163
 
 
164
        return ecdsa_data_new();
 
165
}
 
166
 
 
167
static void ecdsa_data_free(void *data)
 
168
{
 
169
        ECDSA_DATA *r = (ECDSA_DATA *)data;
 
170
 
 
171
#ifndef OPENSSL_NO_ENGINE
 
172
        if (r->engine)
 
173
                ENGINE_finish(r->engine);
 
174
#endif
 
175
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
 
176
 
 
177
        OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA));
 
178
 
 
179
        OPENSSL_free(r);
 
180
}
 
181
 
 
182
ECDSA_DATA *ecdsa_check(EC_KEY *key)
 
183
{
 
184
        ECDSA_DATA *ecdsa_data;
 
185
 
 
186
        void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup,
 
187
                                        ecdsa_data_free, ecdsa_data_free);
 
188
        if (data == NULL)
 
189
        {
 
190
                ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
 
191
                if (ecdsa_data == NULL)
 
192
                        return NULL;
 
193
                EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
 
194
                        ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
 
195
        }
 
196
        else
 
197
                ecdsa_data = (ECDSA_DATA *)data;
 
198
        
 
199
 
 
200
        return ecdsa_data;
 
201
}
 
202
 
 
203
int ECDSA_size(const EC_KEY *r)
 
204
{
 
205
        int ret,i;
 
206
        ASN1_INTEGER bs;
 
207
        BIGNUM  *order=NULL;
 
208
        unsigned char buf[4];
 
209
        const EC_GROUP *group = EC_KEY_get0_group(r);
 
210
 
 
211
        if (r == NULL || group == NULL)
 
212
                return 0;
 
213
        if ((order = BN_new()) == NULL) return 0;
 
214
        if (!EC_GROUP_get_order(group,order,NULL))
 
215
        {
 
216
                BN_clear_free(order);
 
217
                return 0;
 
218
        } 
 
219
        i=BN_num_bits(order);
 
220
        bs.length=(i+7)/8;
 
221
        bs.data=buf;
 
222
        bs.type=V_ASN1_INTEGER;
 
223
        /* If the top bit is set the asn1 encoding is 1 larger. */
 
224
        buf[0]=0xff;    
 
225
 
 
226
        i=i2d_ASN1_INTEGER(&bs,NULL);
 
227
        i+=i; /* r and s */
 
228
        ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
 
229
        BN_clear_free(order);
 
230
        return(ret);
 
231
}
 
232
 
 
233
 
 
234
int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
 
235
             CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
 
236
{
 
237
        return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp,
 
238
                                new_func, dup_func, free_func);
 
239
}
 
240
 
 
241
int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg)
 
242
{
 
243
        ECDSA_DATA *ecdsa;
 
244
        ecdsa = ecdsa_check(d);
 
245
        if (ecdsa == NULL)
 
246
                return 0;
 
247
        return(CRYPTO_set_ex_data(&ecdsa->ex_data,idx,arg));
 
248
}
 
249
 
 
250
void *ECDSA_get_ex_data(EC_KEY *d, int idx)
 
251
{
 
252
        ECDSA_DATA *ecdsa;
 
253
        ecdsa = ecdsa_check(d);
 
254
        if (ecdsa == NULL)
 
255
                return NULL;
 
256
        return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx));
 
257
}