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