Branch data Line data Source code
1 : : /* crypto/rsa/rsa_lib.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : :
59 : : #include <stdio.h>
60 : : #include <openssl/crypto.h>
61 : : #include "cryptlib.h"
62 : : #include <openssl/lhash.h>
63 : : #include <openssl/bn.h>
64 : : #include <openssl/rsa.h>
65 : : #include <openssl/rand.h>
66 : : #ifndef OPENSSL_NO_ENGINE
67 : : #include <openssl/engine.h>
68 : : #endif
69 : :
70 : : const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
71 : :
72 : : static const RSA_METHOD *default_RSA_meth=NULL;
73 : :
74 : 4850 : RSA *RSA_new(void)
75 : : {
76 : 4850 : RSA *r=RSA_new_method(NULL);
77 : :
78 : 4850 : return r;
79 : : }
80 : :
81 : 0 : void RSA_set_default_method(const RSA_METHOD *meth)
82 : : {
83 : 0 : default_RSA_meth = meth;
84 : 0 : }
85 : :
86 : 4850 : const RSA_METHOD *RSA_get_default_method(void)
87 : : {
88 [ + + ]: 4850 : if (default_RSA_meth == NULL)
89 : : {
90 : : #ifdef RSA_NULL
91 : : default_RSA_meth=RSA_null_method();
92 : : #else
93 : 1123 : default_RSA_meth=RSA_PKCS1_SSLeay();
94 : : #endif
95 : : }
96 : :
97 : 4850 : return default_RSA_meth;
98 : : }
99 : :
100 : 0 : const RSA_METHOD *RSA_get_method(const RSA *rsa)
101 : : {
102 : 0 : return rsa->meth;
103 : : }
104 : :
105 : 0 : int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
106 : : {
107 : : /* NB: The caller is specifically setting a method, so it's not up to us
108 : : * to deal with which ENGINE it comes from. */
109 : : const RSA_METHOD *mtmp;
110 : 0 : mtmp = rsa->meth;
111 [ # # ]: 0 : if (mtmp->finish) mtmp->finish(rsa);
112 : : #ifndef OPENSSL_NO_ENGINE
113 [ # # ]: 0 : if (rsa->engine)
114 : : {
115 : 0 : ENGINE_finish(rsa->engine);
116 : 0 : rsa->engine = NULL;
117 : : }
118 : : #endif
119 : 0 : rsa->meth = meth;
120 [ # # ]: 0 : if (meth->init) meth->init(rsa);
121 : 0 : return 1;
122 : : }
123 : :
124 : 4850 : RSA *RSA_new_method(ENGINE *engine)
125 : : {
126 : : RSA *ret;
127 : :
128 : 4850 : ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
129 [ - + ]: 4850 : if (ret == NULL)
130 : : {
131 : 0 : RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
132 : 0 : return NULL;
133 : : }
134 : :
135 : 4850 : ret->meth = RSA_get_default_method();
136 : : #ifndef OPENSSL_NO_ENGINE
137 [ - + ]: 4850 : if (engine)
138 : : {
139 [ # # ]: 0 : if (!ENGINE_init(engine))
140 : : {
141 : 0 : RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
142 : 0 : OPENSSL_free(ret);
143 : 0 : return NULL;
144 : : }
145 : 0 : ret->engine = engine;
146 : : }
147 : : else
148 : 4850 : ret->engine = ENGINE_get_default_RSA();
149 [ - + ]: 4850 : if(ret->engine)
150 : : {
151 : 0 : ret->meth = ENGINE_get_RSA(ret->engine);
152 [ # # ]: 0 : if(!ret->meth)
153 : : {
154 : 0 : RSAerr(RSA_F_RSA_NEW_METHOD,
155 : : ERR_R_ENGINE_LIB);
156 : 0 : ENGINE_finish(ret->engine);
157 : 0 : OPENSSL_free(ret);
158 : 0 : return NULL;
159 : : }
160 : : }
161 : : #endif
162 : :
163 : 4850 : ret->pad=0;
164 : 4850 : ret->version=0;
165 : 4850 : ret->n=NULL;
166 : 4850 : ret->e=NULL;
167 : 4850 : ret->d=NULL;
168 : 4850 : ret->p=NULL;
169 : 4850 : ret->q=NULL;
170 : 4850 : ret->dmp1=NULL;
171 : 4850 : ret->dmq1=NULL;
172 : 4850 : ret->iqmp=NULL;
173 : 4850 : ret->references=1;
174 : 4850 : ret->_method_mod_n=NULL;
175 : 4850 : ret->_method_mod_p=NULL;
176 : 4850 : ret->_method_mod_q=NULL;
177 : 4850 : ret->blinding=NULL;
178 : 4850 : ret->mt_blinding=NULL;
179 : 4850 : ret->bignum_data=NULL;
180 : 4850 : ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
181 [ - + ]: 4850 : if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
182 : : {
183 : : #ifndef OPENSSL_NO_ENGINE
184 [ # # ]: 0 : if (ret->engine)
185 : 0 : ENGINE_finish(ret->engine);
186 : : #endif
187 : 0 : OPENSSL_free(ret);
188 : 0 : return(NULL);
189 : : }
190 : :
191 [ + - ][ - + ]: 4850 : if ((ret->meth->init != NULL) && !ret->meth->init(ret))
192 : : {
193 : : #ifndef OPENSSL_NO_ENGINE
194 [ # # ]: 0 : if (ret->engine)
195 : 0 : ENGINE_finish(ret->engine);
196 : : #endif
197 : 0 : CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
198 : 0 : OPENSSL_free(ret);
199 : 0 : ret=NULL;
200 : : }
201 : 4850 : return(ret);
202 : : }
203 : :
204 : 4889 : void RSA_free(RSA *r)
205 : : {
206 : : int i;
207 : :
208 [ + - ]: 4889 : if (r == NULL) return;
209 : :
210 : 4889 : i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA);
211 : : #ifdef REF_PRINT
212 : : REF_PRINT("RSA",r);
213 : : #endif
214 [ + + ]: 4889 : if (i > 0) return;
215 : : #ifdef REF_CHECK
216 : : if (i < 0)
217 : : {
218 : : fprintf(stderr,"RSA_free, bad reference count\n");
219 : : abort();
220 : : }
221 : : #endif
222 : :
223 [ + - ]: 4850 : if (r->meth->finish)
224 : 4850 : r->meth->finish(r);
225 : : #ifndef OPENSSL_NO_ENGINE
226 [ - + ]: 4850 : if (r->engine)
227 : 0 : ENGINE_finish(r->engine);
228 : : #endif
229 : :
230 : 4850 : CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
231 : :
232 [ + - ]: 4850 : if (r->n != NULL) BN_clear_free(r->n);
233 [ + - ]: 4850 : if (r->e != NULL) BN_clear_free(r->e);
234 [ + + ]: 4850 : if (r->d != NULL) BN_clear_free(r->d);
235 [ + + ]: 4850 : if (r->p != NULL) BN_clear_free(r->p);
236 [ + + ]: 4850 : if (r->q != NULL) BN_clear_free(r->q);
237 [ + + ]: 4850 : if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
238 [ + + ]: 4850 : if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
239 [ + + ]: 4850 : if (r->iqmp != NULL) BN_clear_free(r->iqmp);
240 [ + + ]: 4850 : if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
241 [ - + ]: 4850 : if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
242 [ - + ]: 4850 : if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
243 : 4850 : OPENSSL_free(r);
244 : : }
245 : :
246 : 39 : int RSA_up_ref(RSA *r)
247 : : {
248 : 39 : int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA);
249 : : #ifdef REF_PRINT
250 : : REF_PRINT("RSA",r);
251 : : #endif
252 : : #ifdef REF_CHECK
253 : : if (i < 2)
254 : : {
255 : : fprintf(stderr, "RSA_up_ref, bad reference count\n");
256 : : abort();
257 : : }
258 : : #endif
259 : 39 : return ((i > 1) ? 1 : 0);
260 : : }
261 : :
262 : 0 : int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
263 : : CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
264 : : {
265 : 0 : return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp,
266 : : new_func, dup_func, free_func);
267 : : }
268 : :
269 : 0 : int RSA_set_ex_data(RSA *r, int idx, void *arg)
270 : : {
271 : 0 : return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
272 : : }
273 : :
274 : 0 : void *RSA_get_ex_data(const RSA *r, int idx)
275 : : {
276 : 0 : return(CRYPTO_get_ex_data(&r->ex_data,idx));
277 : : }
278 : :
279 : 0 : int RSA_memory_lock(RSA *r)
280 : : {
281 : : int i,j,k,off;
282 : : char *p;
283 : : BIGNUM *bn,**t[6],*b;
284 : : BN_ULONG *ul;
285 : :
286 [ # # ]: 0 : if (r->d == NULL) return(1);
287 : 0 : t[0]= &r->d;
288 : 0 : t[1]= &r->p;
289 : 0 : t[2]= &r->q;
290 : 0 : t[3]= &r->dmp1;
291 : 0 : t[4]= &r->dmq1;
292 : 0 : t[5]= &r->iqmp;
293 : 0 : k=sizeof(BIGNUM)*6;
294 : 0 : off=k/sizeof(BN_ULONG)+1;
295 : 0 : j=1;
296 [ # # ]: 0 : for (i=0; i<6; i++)
297 : 0 : j+= (*t[i])->top;
298 [ # # ]: 0 : if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
299 : : {
300 : 0 : RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
301 : 0 : return(0);
302 : : }
303 : 0 : bn=(BIGNUM *)p;
304 : 0 : ul=(BN_ULONG *)&(p[off]);
305 [ # # ]: 0 : for (i=0; i<6; i++)
306 : : {
307 : 0 : b= *(t[i]);
308 : 0 : *(t[i])= &(bn[i]);
309 : 0 : memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
310 : 0 : bn[i].flags=BN_FLG_STATIC_DATA;
311 : 0 : bn[i].d=ul;
312 : 0 : memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
313 : 0 : ul+=b->top;
314 : 0 : BN_clear_free(b);
315 : : }
316 : :
317 : : /* I should fix this so it can still be done */
318 : 0 : r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
319 : :
320 : 0 : r->bignum_data=p;
321 : 0 : return(1);
322 : : }
323 : :
324 : 2634 : int RSA_security_bits(const RSA *rsa)
325 : : {
326 : 2634 : return BN_security_bits(BN_num_bits(rsa->n), -1);
327 : : }
|