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