Use the generated error code files.
[openssl.git] / demos / engines / rsaref / rsaref.c
1 /* Demo of how to construct your own engine and using it.  The basis of this
2    engine is RSAref, an old reference of the RSA algorithm which can still
3    be found a little here and there. */
4
5 #include <stdio.h>
6 #include "./source/global.h"
7 #include "./source/rsaref.h"
8 #include "./source/rsa.h"
9 #include <openssl/err.h>
10 #include <openssl/bn.h>
11 #include <openssl/engine.h>
12
13 #define RSAREF_LIB_NAME "rsaref engine"
14 #include "rsaref_err.c"
15
16 /* Constants used when creating the ENGINE */
17 static const char *engine_rsaref_id = "rsaref";
18 static const char *engine_rsaref_name = "RSAref engine support";
19
20 static int rsaref_destroy(ENGINE *e);
21 static int rsaref_init(ENGINE *e);
22 static int rsaref_finish(ENGINE *e);
23 #if 0
24 static int rsaref_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 
25 #endif
26
27 static int rsaref_private_decrypt(int len, const unsigned char *from,
28         unsigned char *to, RSA *rsa, int padding);
29 static int rsaref_private_encrypt(int len, const unsigned char *from,
30         unsigned char *to, RSA *rsa, int padding);
31 static int rsaref_public_encrypt(int len, const unsigned char *from,
32         unsigned char *to, RSA *rsa, int padding);
33 static int rsaref_public_decrypt(int len, const unsigned char *from,
34         unsigned char *to, RSA *rsa, int padding);
35 static int bnref_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m,
36                           BN_CTX *ctx, BN_MONT_CTX *m_ctx);
37 static int rsaref_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
38
39 static const ENGINE_CMD_DEFN rsaref_cmd_defns[] = {
40         {0, NULL, NULL, 0}
41         };
42
43 static RSA_METHOD rsaref_rsa =
44 {
45   "RSAref PKCS#1 RSA",
46   rsaref_public_encrypt,
47   rsaref_public_decrypt,
48   rsaref_private_encrypt,
49   rsaref_private_decrypt,
50   rsaref_mod_exp,
51   bnref_mod_exp,
52   NULL,
53   NULL,
54   0,
55   NULL,
56   NULL,
57   NULL
58 };
59
60 /* Now, to our own code */
61
62 static int bind_rsaref(ENGINE *e)
63         {
64         const RSA_METHOD *meth1;
65         if(!ENGINE_set_id(e, engine_rsaref_id)
66                 || !ENGINE_set_name(e, engine_rsaref_name)
67                 || !ENGINE_set_RSA(e, &rsaref_rsa)
68                 || !ENGINE_set_destroy_function(e, rsaref_destroy)
69                 || !ENGINE_set_init_function(e, rsaref_init)
70                 || !ENGINE_set_finish_function(e, rsaref_finish)
71                 /* || !ENGINE_set_ctrl_function(e, rsaref_ctrl) */
72                 /* || !ENGINE_set_cmd_defns(e, rsaref_cmd_defns) */)
73                 return 0;
74
75         /* Ensure the rsaref error handling is set up */
76         ERR_load_RSAREF_strings();
77         return 1;
78         }
79
80 #ifdef ENGINE_DYNAMIC_SUPPORT
81 static int bind_helper(ENGINE *e, const char *id)
82         {
83         if(id && (strcmp(id, engine_rsaref_id) != 0))
84                 return 0;
85         if(!bind_rsaref(e))
86                 return 0;
87         return 1;
88         }       
89 IMPLEMENT_DYNAMIC_CHECK_FN()
90 IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
91 #else
92 static ENGINE *engine_rsaref(void)
93         {
94         ENGINE *ret = ENGINE_new();
95         if(!ret)
96                 return NULL;
97         if(!bind_rsaref(ret))
98                 {
99                 ENGINE_free(ret);
100                 return NULL;
101                 }
102         return ret;
103         }
104
105 void ENGINE_load_rsaref(void)
106         {
107         /* Copied from eng_[openssl|dyn].c */
108         ENGINE *toadd = engine_rsaref();
109         if(!toadd) return;
110         ENGINE_add(toadd);
111         ENGINE_free(toadd);
112         ERR_clear_error();
113         }
114 #endif
115
116 /* Initiator which is only present to make sure this engine looks available */
117 static int rsaref_init(ENGINE *e)
118         {
119         return 1;
120         }
121
122 /* Finisher which is only present to make sure this engine looks available */
123 static int rsaref_finish(ENGINE *e)
124         {
125         return 1;
126         }
127
128 /* Destructor (complements the "ENGINE_ncipher()" constructor) */
129 static int rsaref_destroy(ENGINE *e)
130         {
131         ERR_unload_RSAREF_strings();
132         return 1;
133         }
134
135 static int rsaref_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
136         {
137         RSAREFerr(RSAREF_F_RSAREF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
138         return(0);
139         }
140
141 static int bnref_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
142                           const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
143         {
144         RSAREFerr(RSAREF_F_BNREF_MOD_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
145         return(0);
146         }
147
148 /* unsigned char *to:  [max]    */
149 static int RSAref_bn2bin(BIGNUM *from, unsigned char *to, int max)
150         {
151         int i;
152
153         i=BN_num_bytes(from);
154         if (i > max)
155                 {
156                 RSAREFerr(RSAREF_F_RSAREF_BN2BIN,RSAREF_R_LEN);
157                 return(0);
158                 }
159
160         memset(to,0,(unsigned int)max);
161         if (!BN_bn2bin(from,&(to[max-i])))
162                 return(0);
163         return(1);
164         }
165
166 #ifdef undef
167 /* unsigned char *from:  [max]    */
168 static BIGNUM *RSAref_bin2bn(unsigned char *from, BIGNUM *to, int max)
169         {
170         int i;
171         BIGNUM *ret;
172
173         for (i=0; i<max; i++)
174                 if (from[i]) break;
175
176         ret=BN_bin2bn(&(from[i]),max-i,to);
177         return(ret);
178         }
179
180 static int RSAref_Public_ref2eay(RSArefPublicKey *from, RSA *to)
181         {
182         to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN);
183         to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN);
184         if ((to->n == NULL) || (to->e == NULL)) return(0);
185         return(1);
186         }
187 #endif
188
189 static int RSAref_Public_eay2ref(RSA *from, R_RSA_PUBLIC_KEY *to)
190         {
191         to->bits=BN_num_bits(from->n);
192         if (!RSAref_bn2bin(from->n,to->modulus,MAX_RSA_MODULUS_LEN)) return(0);
193         if (!RSAref_bn2bin(from->e,to->exponent,MAX_RSA_MODULUS_LEN)) return(0);
194         return(1);
195         }
196
197 #ifdef undef
198 static int RSAref_Private_ref2eay(RSArefPrivateKey *from, RSA *to)
199         {
200         if ((to->n=RSAref_bin2bn(from->m,NULL,RSAref_MAX_LEN)) == NULL)
201                 return(0);
202         if ((to->e=RSAref_bin2bn(from->e,NULL,RSAref_MAX_LEN)) == NULL)
203                 return(0);
204         if ((to->d=RSAref_bin2bn(from->d,NULL,RSAref_MAX_LEN)) == NULL)
205                 return(0);
206         if ((to->p=RSAref_bin2bn(from->prime[0],NULL,RSAref_MAX_PLEN)) == NULL)
207                 return(0);
208         if ((to->q=RSAref_bin2bn(from->prime[1],NULL,RSAref_MAX_PLEN)) == NULL)
209                 return(0);
210         if ((to->dmp1=RSAref_bin2bn(from->pexp[0],NULL,RSAref_MAX_PLEN))
211                 == NULL)
212                 return(0);
213         if ((to->dmq1=RSAref_bin2bn(from->pexp[1],NULL,RSAref_MAX_PLEN))
214                 == NULL)
215                 return(0);
216         if ((to->iqmp=RSAref_bin2bn(from->coef,NULL,RSAref_MAX_PLEN)) == NULL)
217                 return(0);
218         return(1);
219         }
220 #endif
221
222 static int RSAref_Private_eay2ref(RSA *from, R_RSA_PRIVATE_KEY *to)
223         {
224         to->bits=BN_num_bits(from->n);
225         if (!RSAref_bn2bin(from->n,to->modulus,MAX_RSA_MODULUS_LEN)) return(0);
226         if (!RSAref_bn2bin(from->e,to->publicExponent,MAX_RSA_MODULUS_LEN)) return(0);
227         if (!RSAref_bn2bin(from->d,to->exponent,MAX_RSA_MODULUS_LEN)) return(0);
228         if (!RSAref_bn2bin(from->p,to->prime[0],MAX_RSA_PRIME_LEN)) return(0);
229         if (!RSAref_bn2bin(from->q,to->prime[1],MAX_RSA_PRIME_LEN)) return(0);
230         if (!RSAref_bn2bin(from->dmp1,to->primeExponent[0],MAX_RSA_PRIME_LEN)) return(0);
231         if (!RSAref_bn2bin(from->dmq1,to->primeExponent[1],MAX_RSA_PRIME_LEN)) return(0);
232         if (!RSAref_bn2bin(from->iqmp,to->coefficient,MAX_RSA_PRIME_LEN)) return(0);
233         return(1);
234         }
235
236 static int rsaref_private_decrypt(int len, const unsigned char *from, unsigned char *to,
237              RSA *rsa, int padding)
238         {
239         int i,outlen= -1;
240         R_RSA_PRIVATE_KEY RSAkey;
241
242         if (!RSAref_Private_eay2ref(rsa,&RSAkey))
243                 goto err;
244         if ((i=RSAPrivateDecrypt(to,&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
245                 {
246                 RSAREFerr(RSAREF_F_RSAREF_PRIVATE_DECRYPT,i);
247                 outlen= -1;
248                 }
249 err:
250         memset(&RSAkey,0,sizeof(RSAkey));
251         return(outlen);
252         }
253
254 static int rsaref_private_encrypt(int len, const unsigned char *from, unsigned char *to,
255              RSA *rsa, int padding)
256         {
257         int i,outlen= -1;
258         R_RSA_PRIVATE_KEY RSAkey;
259
260         if (padding != RSA_PKCS1_PADDING)
261                 {
262                 RSAREFerr(RSAREF_F_RSAREF_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
263                 goto err;
264         }
265         if (!RSAref_Private_eay2ref(rsa,&RSAkey))
266                 goto err;
267         if ((i=RSAPrivateEncrypt(to,&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
268                 {
269                 RSAREFerr(RSAREF_F_RSAREF_PRIVATE_ENCRYPT,i);
270                 outlen= -1;
271                 }
272 err:
273         memset(&RSAkey,0,sizeof(RSAkey));
274         return(outlen);
275         }
276
277 static int rsaref_public_decrypt(int len, const unsigned char *from, unsigned char *to,
278              RSA *rsa, int padding)
279         {
280         int i,outlen= -1;
281         R_RSA_PUBLIC_KEY RSAkey;
282
283         if (!RSAref_Public_eay2ref(rsa,&RSAkey))
284                 goto err;
285         if ((i=RSAPublicDecrypt(to,&outlen,(unsigned char *)from,len,&RSAkey)) != 0)
286                 {
287                 RSAREFerr(RSAREF_F_RSAREF_PUBLIC_DECRYPT,i);
288                 outlen= -1;
289                 }
290 err:
291         memset(&RSAkey,0,sizeof(RSAkey));
292         return(outlen);
293         }
294
295 static int rsaref_public_encrypt(int len, const unsigned char *from, unsigned char *to,
296              RSA *rsa, int padding)
297         {
298         int outlen= -1;
299         int i;
300         R_RSA_PUBLIC_KEY RSAkey;
301         R_RANDOM_STRUCT rnd;
302         unsigned char buf[16];
303
304         if (padding != RSA_PKCS1_PADDING && padding != RSA_SSLV23_PADDING) 
305                 {
306                 RSAREFerr(RSAREF_F_RSAREF_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
307                 goto err;
308                 }
309         
310         R_RandomInit(&rnd);
311         R_GetRandomBytesNeeded((unsigned int *)&i,&rnd);
312         while (i > 0)
313                 {
314                 if (RAND_bytes(buf,16) <= 0)
315                         goto err;
316                 R_RandomUpdate(&rnd,buf,(unsigned int)((i>16)?16:i));
317                 i-=16;
318                 }
319
320         if (!RSAref_Public_eay2ref(rsa,&RSAkey))
321                 goto err;
322         if ((i=RSAPublicEncrypt(to,&outlen,(unsigned char *)from,len,&RSAkey,&rnd)) != 0)
323                 {
324                 RSAREFerr(RSAREF_F_RSAREF_PUBLIC_ENCRYPT,i);
325                 outlen= -1;
326                 goto err;
327                 }
328 err:
329         memset(&RSAkey,0,sizeof(RSAkey));
330         R_RandomFinal(&rnd);
331         memset(&rnd,0,sizeof(rnd));
332         return(outlen);
333         }