Circumvent an exploitable buffer overrun error in RSA Security's RSAREF
[openssl.git] / rsaref / rsaref.c
1 /* rsaref/rsaref.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 #ifndef NO_RSA
60 #include <stdio.h>
61 #include "cryptlib.h"
62 #include <openssl/bn.h>
63 #include <openssl/rsa.h>
64 #include <openssl/rsaref.h>
65 #include <openssl/rand.h>
66
67 static int RSAref_bn2bin(BIGNUM * from, unsigned char* to, int max);
68 #ifdef undef
69 static BIGNUM* RSAref_bin2bn(unsigned char* from, BIGNUM * to, int max);
70 #endif
71 static int RSAref_Public_eay2ref(RSA * from, RSArefPublicKey * to);
72 static int RSAref_Private_eay2ref(RSA * from, RSArefPrivateKey * to);
73 int RSA_ref_private_decrypt(int len, unsigned char *from,
74         unsigned char *to, RSA *rsa, int padding);
75 int RSA_ref_private_encrypt(int len, unsigned char *from,
76         unsigned char *to, RSA *rsa, int padding);
77 int RSA_ref_public_encrypt(int len, unsigned char *from,
78         unsigned char *to, RSA *rsa, int padding);
79 int RSA_ref_public_decrypt(int len, unsigned char *from,
80         unsigned char *to, RSA *rsa, int padding);
81 static int BN_ref_mod_exp(BIGNUM *r,BIGNUM *a,const BIGNUM *p,const BIGNUM *m,
82                           BN_CTX *ctx, BN_MONT_CTX *m_ctx);
83 static int RSA_ref_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa);
84 static RSA_METHOD rsa_pkcs1_ref_meth={
85         "RSAref PKCS#1 RSA",
86         RSA_ref_public_encrypt,
87         RSA_ref_public_decrypt,
88         RSA_ref_private_encrypt,
89         RSA_ref_private_decrypt,
90         RSA_ref_mod_exp,
91         BN_ref_mod_exp,
92         NULL,
93         NULL,
94         0,
95         NULL,
96         };
97
98 RSA_METHOD *RSA_PKCS1_RSAref(void)
99         {
100         return(&rsa_pkcs1_ref_meth);
101         }
102
103 static int RSA_ref_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
104         {
105         RSAREFerr(RSAREF_F_RSA_REF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
106         return(0);
107         }
108
109 static int BN_ref_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
110                           const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
111         {
112         RSAREFerr(RSAREF_F_BN_REF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
113         return(0);
114         }
115
116 /* unsigned char *to:  [max]    */
117 static int RSAref_bn2bin(BIGNUM *from, unsigned char *to, int max)
118         {
119         int i;
120
121         i=BN_num_bytes(from);
122         if (i > max)
123                 {
124                 RSAREFerr(RSAREF_F_RSAREF_BN2BIN,RSAREF_R_LEN);
125                 return(0);
126                 }
127
128         memset(to,0,(unsigned int)max);
129         if (!BN_bn2bin(from,&(to[max-i])))
130                 return(0);
131         return(1);
132         }
133
134 #ifdef undef
135 /* unsigned char *from:  [max]    */
136 static BIGNUM *RSAref_bin2bn(unsigned char *from, BIGNUM *to, int max)
137         {
138         int i;
139         BIGNUM *ret;
140
141         for (i=0; i<max; i++)
142                 if (from[i]) break;
143
144         ret=BN_bin2bn(&(from[i]),max-i,to);
145         return(ret);
146         }
147
148 static int RSAref_Public_ref2eay(RSArefPublicKey *from, RSA *to)
149         {
150         to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN);
151         to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN);
152         if ((to->n == NULL) || (to->e == NULL)) return(0);
153         return(1);
154         }
155 #endif
156
157 static int RSAref_Public_eay2ref(RSA *from, RSArefPublicKey *to)
158         {
159         to->bits=BN_num_bits(from->n);
160         if (!RSAref_bn2bin(from->n,to->m,RSAref_MAX_LEN)) return(0);
161         if (!RSAref_bn2bin(from->e,to->e,RSAref_MAX_LEN)) return(0);
162         return(1);
163         }
164
165 #ifdef undef
166 static int RSAref_Private_ref2eay(RSArefPrivateKey *from, RSA *to)
167         {
168         if ((to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN)) == NULL)
169                 return(0);
170         if ((to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN)) == NULL)
171                 return(0);
172         if ((to->d=RSAref_bin2bn(from->d,NULL,RSAref_MAX_LEN)) == NULL)
173                 return(0);
174         if ((to->p=RSAref_bin2bn(from->prime[0],NULL,RSAref_MAX_PLEN)) == NULL)
175                 return(0);
176         if ((to->q=RSAref_bin2bn(from->prime[1],NULL,RSAref_MAX_PLEN)) == NULL)
177                 return(0);
178         if ((to->dmp1=RSAref_bin2bn(from->pexp[0],NULL,RSAref_MAX_PLEN))
179                 == NULL)
180                 return(0);
181         if ((to->dmq1=RSAref_bin2bn(from->pexp[1],NULL,RSAref_MAX_PLEN))
182                 == NULL)
183                 return(0);
184         if ((to->iqmp=RSAref_bin2bn(from->coef,NULL,RSAref_MAX_PLEN)) == NULL)
185                 return(0);
186         return(1);
187         }
188 #endif
189
190 static int RSAref_Private_eay2ref(RSA *from, RSArefPrivateKey *to)
191         {
192         to->bits=BN_num_bits(from->n);
193         if (!RSAref_bn2bin(from->n,to->m,RSAref_MAX_LEN)) return(0);
194         if (!RSAref_bn2bin(from->e,to->e,RSAref_MAX_LEN)) return(0);
195         if (!RSAref_bn2bin(from->d,to->d,RSAref_MAX_LEN)) return(0);
196         if (!RSAref_bn2bin(from->p,to->prime[0],RSAref_MAX_PLEN)) return(0);
197         if (!RSAref_bn2bin(from->q,to->prime[1],RSAref_MAX_PLEN)) return(0);
198         if (!RSAref_bn2bin(from->dmp1,to->pexp[0],RSAref_MAX_PLEN)) return(0);
199         if (!RSAref_bn2bin(from->dmq1,to->pexp[1],RSAref_MAX_PLEN)) return(0);
200         if (!RSAref_bn2bin(from->iqmp,to->coef,RSAref_MAX_PLEN)) return(0);
201         return(1);
202         }
203
204 int RSA_ref_private_decrypt(int len, unsigned char *from, unsigned char *to,
205              RSA *rsa, int padding)
206         {
207         int i,outlen= -1;
208         RSArefPrivateKey RSAkey;
209
210         if (!RSAref_Private_eay2ref(rsa,&RSAkey))
211                 goto err;
212         if (len > RSAref_MAX_LEN)
213                 {
214                 RSAREFerr(RSAREF_F_RSA_REF_PRIVATE_DECRYPT,RSAREF_R_LEN);
215                 goto err;
216                 }
217         if ((i=RSAPrivateDecrypt(to,&outlen,from,len,&RSAkey)) != 0)
218                 {
219                 RSAREFerr(RSAREF_F_RSA_REF_PRIVATE_DECRYPT,i);
220                 outlen= -1;
221                 }
222 err:
223         memset(&RSAkey,0,sizeof(RSAkey));
224         return(outlen);
225         }
226
227 int RSA_ref_private_encrypt(int len, unsigned char *from, unsigned char *to,
228              RSA *rsa, int padding)
229         {
230         int i,outlen= -1;
231         RSArefPrivateKey RSAkey;
232
233         if (padding != RSA_PKCS1_PADDING)
234                 {
235                 RSAREFerr(RSAREF_F_RSA_REF_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
236                 goto err;
237         }
238         if (!RSAref_Private_eay2ref(rsa,&RSAkey))
239                 goto err;
240         if (len + 3 > RSAref_MAX_LEN)
241                 {
242                 RSAREFerr(RSAREF_F_RSA_REF_PRIVATE_ENCRYPT,RSAREF_R_LEN);
243                 goto err;
244                 }
245         if ((i=RSAPrivateEncrypt(to,&outlen,from,len,&RSAkey)) != 0)
246                 {
247                 RSAREFerr(RSAREF_F_RSA_REF_PRIVATE_ENCRYPT,i);
248                 outlen= -1;
249                 }
250 err:
251         memset(&RSAkey,0,sizeof(RSAkey));
252         return(outlen);
253         }
254
255 int RSA_ref_public_decrypt(int len, unsigned char *from, unsigned char *to,
256              RSA *rsa, int padding)
257         {
258         int i,outlen= -1;
259         RSArefPublicKey RSAkey;
260
261         if (!RSAref_Public_eay2ref(rsa,&RSAkey))
262                 goto err;
263         if (len > RSAref_MAX_LEN)
264                 {
265                 RSAREFerr(RSAREF_F_RSA_REF_PUBLIC_DECRYPT,RSAREF_R_LEN);
266                 goto err;
267                 }
268                 goto err;
269         if ((i=RSAPublicDecrypt(to,&outlen,from,len,&RSAkey)) != 0)
270                 {
271                 RSAREFerr(RSAREF_F_RSA_REF_PUBLIC_DECRYPT,i);
272                 outlen= -1;
273                 }
274 err:
275         memset(&RSAkey,0,sizeof(RSAkey));
276         return(outlen);
277         }
278
279 int RSA_ref_public_encrypt(int len, unsigned char *from, unsigned char *to,
280              RSA *rsa, int padding)
281         {
282         int outlen= -1;
283         int i;
284         RSArefPublicKey RSAkey;
285         RSARandomState rnd;
286         unsigned char buf[16];
287
288         if (padding != RSA_PKCS1_PADDING && padding != RSA_SSLV23_PADDING) 
289                 {
290                 RSAREFerr(RSAREF_F_RSA_REF_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
291                 goto err;
292                 }
293         
294         R_RandomInit(&rnd);
295         R_GetRandomBytesNeeded((unsigned int *)&i,&rnd);
296         while (i > 0)
297                 {
298                 RAND_bytes(buf,16);
299                 R_RandomUpdate(&rnd,buf,(unsigned int)((i>16)?16:i));
300                 i-=16;
301                 }
302
303         if (!RSAref_Public_eay2ref(rsa,&RSAkey))
304                 goto err;
305         if (len + 3 > RSAref_MAX_LEN)
306                 {
307                 RSAREFerr(RSAREF_F_RSA_REF_PUBLIC_ENCRYPT,RSAREF_R_LEN);
308                 goto err;
309                 }
310         if ((i=RSAPublicEncrypt(to,&outlen,from,len,&RSAkey,&rnd)) != 0)
311                 {
312                 RSAREFerr(RSAREF_F_RSA_REF_PUBLIC_ENCRYPT,i);
313                 outlen= -1;
314                 goto err;
315                 }
316 err:
317         memset(&RSAkey,0,sizeof(RSAkey));
318         R_RandomFinal(&rnd);
319         memset(&rnd,0,sizeof(rnd));
320         return(outlen);
321         }
322 #endif