new locks
[openssl.git] / crypto / engine / hw_sureware.c
1 /* Written by Corinne Dive-Reclus(cdive@baltimore.com)
2
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer. 
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in
13 *    the documentation and/or other materials provided with the
14 *    distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 *    software must display the following acknowledgment:
18 *    "This product includes software developed by the OpenSSL Project
19 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 *    endorse or promote products derived from this software without
23 *    prior written permission. For written permission, please contact
24 *    licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 *    nor may "OpenSSL" appear in their names without prior written
28 *    permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 *    acknowledgment:
32 *    "This product includes software developed by the OpenSSL Project
33 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * Written by Corinne Dive-Reclus(cdive@baltimore.com)
36 *
37 * Copyright@2001 Baltimore Technologies Ltd.
38 * All right Reserved.
39 *                                                                                                                                                                                               *       
40 *               THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND                                                                                                                                                   *
41 *               ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE                                   * 
42 *               IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE                              *
43 *               ARE DISCLAIMED.  IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE                                             *
44 *               FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL                              *
45 *               DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS                                 *
46 *               OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                                   *
47 *               HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT                              *
48 *               LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY                               *
49 *               OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF                                  *
50 *               SUCH DAMAGE.                                                                                                                                                    *
51 ====================================================================*/
52
53 #include <stdio.h>
54 #include <openssl/crypto.h>
55 #include <openssl/pem.h>
56 #include "cryptlib.h"
57 #include <openssl/dso.h>
58 #include "eng_int.h"
59 #include "engine.h"
60 #include <openssl/engine.h>
61
62 #ifndef NO_HW
63 #ifndef NO_HW_SUREWARE
64
65 #ifdef FLAT_INC
66 #include "sureware.h"
67 #else
68 #include "vendor_defns/sureware.h"
69 #endif
70
71 #define SUREWARE_LIB_NAME "sureware engine"
72 #include "hw_sureware_err.c"
73
74 static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
75 static int surewarehk_destroy(ENGINE *e);
76 static int surewarehk_init(ENGINE *e);
77 static int surewarehk_finish(ENGINE *e);
78 static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
79         const BIGNUM *m, BN_CTX *ctx);
80
81 /* RSA stuff */
82 static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
83                         RSA *rsa,int padding);
84 static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
85                             RSA *rsa,int padding);
86
87 /* RAND stuff */
88 static int surewarehk_rand_bytes(unsigned char *buf, int num);
89 static void surewarehk_rand_seed(const void *buf, int num);
90 static void surewarehk_rand_add(const void *buf, int num, double entropy);
91
92 /* KM stuff */
93 static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
94         UI_METHOD *ui_method, void *callback_data);
95 static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
96         UI_METHOD *ui_method, void *callback_data);
97 static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
98         int index,long argl, void *argp);
99 static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
100         int index,long argl, void *argp);
101
102 /* This function is aliased to mod_exp (with the mont stuff dropped). */
103 static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
104                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
105 {
106         return surewarehk_modexp(r, a, p, m, ctx);
107 }
108
109 /* Our internal RSA_METHOD that we provide pointers to */
110 static RSA_METHOD surewarehk_rsa =
111         {
112         "SureWare RSA method",
113         NULL, /* pub_enc*/
114         NULL, /* pub_dec*/
115         surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc*/
116         surewarehk_rsa_priv_dec, /* priv_dec*/
117         NULL, /*mod_exp*/
118         surewarehk_mod_exp_mont, /*mod_exp_mongomery*/
119         NULL, /* init*/
120         NULL, /* finish*/
121         0,      /* RSA flag*/
122         NULL, 
123         NULL, /* OpenSSL sign*/
124         NULL  /* OpenSSL verify*/
125         };
126 /* Our internal DH_METHOD that we provide pointers to */
127 /* This function is aliased to mod_exp (with the dh and mont dropped). */
128 static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
129         const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
130 {
131         return surewarehk_modexp(r, a, p, m, ctx);
132 }
133 static DH_METHOD surewarehk_dh =
134         {
135         "SureWare DH method",
136         NULL,/*gen_key*/
137         NULL,/*agree,*/
138         surewarehk_modexp_dh, /*dh mod exp*/
139         NULL, /* init*/
140         NULL, /* finish*/
141         0,    /* flags*/
142         NULL 
143         };
144 static RAND_METHOD surewarehk_rand =
145         {
146         /* "SureWare RAND method", */
147         surewarehk_rand_seed,
148         surewarehk_rand_bytes,
149         NULL,/*cleanup*/
150         surewarehk_rand_add,
151         surewarehk_rand_bytes,
152         NULL,/*rand_status*/
153         };
154 /* DSA stuff */
155 static  DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
156 static int surewarehk_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
157                 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
158                 BN_CTX *ctx, BN_MONT_CTX *in_mont)
159 {
160         BIGNUM t;
161         int to_return = 0;
162         BN_init(&t);
163         /* let rr = a1 ^ p1 mod m */
164         if (!surewarehk_modexp(rr,a1,p1,m,ctx)) goto end;
165         /* let t = a2 ^ p2 mod m */
166         if (!surewarehk_modexp(&t,a2,p2,m,ctx)) goto end;
167         /* let rr = rr * t mod m */
168         if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
169         to_return = 1;
170 end:
171         BN_free(&t);
172         return to_return;
173 }
174
175 static DSA_METHOD surewarehk_dsa =
176         {
177          "SureWare DSA method", 
178         surewarehk_dsa_do_sign,
179         NULL,/*sign setup*/
180         NULL,/*verify,*/
181         surewarehk_dsa_mod_exp,/*mod exp*/
182         NULL,/*bn mod exp*/
183         NULL, /*init*/
184         NULL,/*finish*/
185         0,
186         NULL,
187         };
188
189 static const char *engine_sureware_id = "sureware";
190 static const char *engine_sureware_name = "SureWare hardware engine support";
191
192 /* Now, to our own code */
193
194 /* As this is only ever called once, there's no need for locking
195  * (indeed - the lock will already be held by our caller!!!) */
196 static int bind_sureware(ENGINE *e)
197 {
198         const RSA_METHOD *meth1;
199         const DSA_METHOD *meth2;
200         const DH_METHOD *meth3;
201
202         if(!ENGINE_set_id(e, engine_sureware_id) ||
203            !ENGINE_set_name(e, engine_sureware_name) ||
204 #ifndef OPENSSL_NO_RSA
205            !ENGINE_set_RSA(e, &surewarehk_rsa) ||
206 #endif
207 #ifndef OPENSSL_NO_DSA
208            !ENGINE_set_DSA(e, &surewarehk_dsa) ||
209 #endif
210 #ifndef OPENSSL_NO_DH
211            !ENGINE_set_DH(e, &surewarehk_dh) ||
212 #endif
213            !ENGINE_set_RAND(e, &surewarehk_rand) ||
214            !ENGINE_set_destroy_function(e, surewarehk_destroy) ||
215            !ENGINE_set_init_function(e, surewarehk_init) ||
216            !ENGINE_set_finish_function(e, surewarehk_finish) ||
217            !ENGINE_set_ctrl_function(e, surewarehk_ctrl) ||
218            !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) ||
219            !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey))
220           return 0;
221
222         /* We know that the "PKCS1_SSLeay()" functions hook properly
223          * to the cswift-specific mod_exp and mod_exp_crt so we use
224          * those functions. NB: We don't use ENGINE_openssl() or
225          * anything "more generic" because something like the RSAref
226          * code may not hook properly, and if you own one of these
227          * cards then you have the right to do RSA operations on it
228          * anyway! */ 
229         meth1 = RSA_PKCS1_SSLeay();
230         if (meth1)
231         {
232                 surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
233                 surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
234         }
235         /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
236          * bits. */
237         meth2 = DSA_OpenSSL();
238         if (meth2)
239         {
240                 surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify;
241         }
242         /* Much the same for Diffie-Hellman */
243         meth3 = DH_OpenSSL();
244         if (meth3)
245         {
246                 surewarehk_dh.generate_key = meth3->generate_key;
247                 surewarehk_dh.compute_key = meth3->compute_key;
248         }
249
250         /* Ensure the sureware error handling is set up */
251         ERR_load_SUREWARE_strings();
252         return 1;
253 }
254
255 #ifdef ENGINE_DYNAMIC_SUPPORT
256 static int bind_helper(ENGINE *e, const char *id)
257         {
258         if(id && (strcmp(id, engine_sureware_id) != 0))
259                 return 0;
260         if(!bind_sureware(e))
261                 return 0;
262         return 1;
263         }       
264 IMPLEMENT_DYNAMIC_CHECK_FN()
265 IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
266 #else
267 static ENGINE *engine_sureware(void)
268         {
269         ENGINE *ret = ENGINE_new();
270         if(!ret)
271                 return NULL;
272         if(!bind_sureware(ret))
273                 {
274                 ENGINE_free(ret);
275                 return NULL;
276                 }
277         return ret;
278         }
279
280 void ENGINE_load_sureware(void)
281         {
282         /* Copied from eng_[openssl|dyn].c */
283         ENGINE *toadd = engine_sureware();
284         if(!toadd) return;
285         ENGINE_add(toadd);
286         ENGINE_free(toadd);
287         ERR_clear_error();
288         }
289 #endif
290
291 /* This is a process-global DSO handle used for loading and unloading
292  * the SureWareHook library. NB: This is only set (or unset) during an
293  * init() or finish() call (reference counts permitting) and they're
294  * operating with global locks, so this should be thread-safe
295  * implicitly. */
296 static DSO *surewarehk_dso = NULL;
297 static int rsaHndidx = -1;      /* Index for KM handle.  Not really used yet. */
298 static int dsaHndidx = -1;      /* Index for KM handle.  Not really used yet. */
299
300 /* These are the function pointers that are (un)set when the library has
301  * successfully (un)loaded. */
302 static SureWareHook_Init_t *p_surewarehk_Init = NULL;
303 static SureWareHook_Finish_t *p_surewarehk_Finish = NULL;
304 static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL;
305 static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL;
306 static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL;
307 static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL;
308 static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL;
309 static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL;
310 static SureWareHook_Free_t *p_surewarehk_Free=NULL;
311 static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec=NULL;
312 static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign=NULL;
313 static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign=NULL;
314 static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp=NULL;
315
316 /* Used in the DSO operations. */
317 static const char *surewarehk_LIBNAME = "SureWareHook";
318 static const char *n_surewarehk_Init = "SureWareHook_Init";
319 static const char *n_surewarehk_Finish = "SureWareHook_Finish";
320 static const char *n_surewarehk_Rand_Bytes="SureWareHook_Rand_Bytes";
321 static const char *n_surewarehk_Rand_Seed="SureWareHook_Rand_Seed";
322 static const char *n_surewarehk_Load_Privkey="SureWareHook_Load_Privkey";
323 static const char *n_surewarehk_Info_Pubkey="SureWareHook_Info_Pubkey";
324 static const char *n_surewarehk_Load_Rsa_Pubkey="SureWareHook_Load_Rsa_Pubkey";
325 static const char *n_surewarehk_Load_Dsa_Pubkey="SureWareHook_Load_Dsa_Pubkey";
326 static const char *n_surewarehk_Free="SureWareHook_Free";
327 static const char *n_surewarehk_Rsa_Priv_Dec="SureWareHook_Rsa_Priv_Dec";
328 static const char *n_surewarehk_Rsa_Sign="SureWareHook_Rsa_Sign";
329 static const char *n_surewarehk_Dsa_Sign="SureWareHook_Dsa_Sign";
330 static const char *n_surewarehk_Mod_Exp="SureWareHook_Mod_Exp";
331 static BIO *logstream = NULL;
332
333 /* SureWareHook library functions and mechanics - these are used by the
334  * higher-level functions further down. NB: As and where there's no
335  * error checking, take a look lower down where these functions are
336  * called, the checking and error handling is probably down there. 
337 */
338 static int threadsafe=1;
339 static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
340 {
341         int to_return = 1;
342
343         switch(cmd)
344         {
345                 case ENGINE_CTRL_SET_LOGSTREAM:
346                 {
347                         BIO *bio = (BIO *)p;
348                         CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
349                         if (logstream)
350                         {
351                                 BIO_free(logstream);
352                                 logstream = NULL;
353                         }
354                         if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
355                                 logstream = bio;
356                         else
357                                 SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,SUREWARE_R_BIO_WAS_FREED);
358                 }
359                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
360                 break;
361         /* This will prevent the initialisation function from "installing"
362          * the mutex-handling callbacks, even if they are available from
363          * within the library (or were provided to the library from the
364          * calling application). This is to remove any baggage for
365          * applications not using multithreading. */
366         case ENGINE_CTRL_CHIL_NO_LOCKING:
367                 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
368                 threadsafe = 0;
369                 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
370                 break;
371
372         /* The command isn't understood by this engine */
373         default:
374                 SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,
375                         ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
376                 to_return = 0;
377                 break;
378                 }
379
380         return to_return;
381 }
382
383 /* Destructor (complements the "ENGINE_surewarehk()" constructor) */
384 static int surewarehk_destroy(ENGINE *e)
385 {
386         ERR_unload_SUREWARE_strings();
387         return 1;
388 }
389
390 /* (de)initialisation functions. */
391 static int surewarehk_init(ENGINE *e)
392 {
393         char msg[64]="ENGINE_init";
394         SureWareHook_Init_t *p1=NULL;
395         SureWareHook_Finish_t *p2=NULL;
396         SureWareHook_Rand_Bytes_t *p3=NULL;
397         SureWareHook_Rand_Seed_t *p4=NULL;
398         SureWareHook_Load_Privkey_t *p5=NULL;
399         SureWareHook_Load_Rsa_Pubkey_t *p6=NULL;
400         SureWareHook_Free_t *p7=NULL;
401         SureWareHook_Rsa_Priv_Dec_t *p8=NULL;
402         SureWareHook_Rsa_Sign_t *p9=NULL;
403         SureWareHook_Dsa_Sign_t *p12=NULL;
404         SureWareHook_Info_Pubkey_t *p13=NULL;
405         SureWareHook_Load_Dsa_Pubkey_t *p14=NULL;
406         SureWareHook_Mod_Exp_t *p15=NULL;
407
408         if(surewarehk_dso != NULL)
409         {
410                 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_ALREADY_LOADED);
411                 goto err;
412         }
413         /* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */
414         surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0);
415         if(surewarehk_dso == NULL)
416         {
417                 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
418                 goto err;
419         }
420         if(!(p1=(SureWareHook_Init_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Init)) ||
421            !(p2=(SureWareHook_Finish_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Finish)) ||
422            !(p3=(SureWareHook_Rand_Bytes_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Bytes)) ||
423            !(p4=(SureWareHook_Rand_Seed_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Seed)) ||
424            !(p5=(SureWareHook_Load_Privkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Privkey)) ||
425            !(p6=(SureWareHook_Load_Rsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Rsa_Pubkey)) ||
426            !(p7=(SureWareHook_Free_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) ||
427            !(p8=(SureWareHook_Rsa_Priv_Dec_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Priv_Dec)) ||
428            !(p9=(SureWareHook_Rsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Sign)) ||
429            !(p12=(SureWareHook_Dsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Dsa_Sign)) ||
430            !(p13=(SureWareHook_Info_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Info_Pubkey)) ||
431            !(p14=(SureWareHook_Load_Dsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Dsa_Pubkey)) ||
432            !(p15=(SureWareHook_Mod_Exp_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Mod_Exp)))
433         {
434                 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
435                 goto err;
436         }
437         /* Copy the pointers */
438         p_surewarehk_Init = p1;
439         p_surewarehk_Finish = p2;
440         p_surewarehk_Rand_Bytes = p3;
441         p_surewarehk_Rand_Seed = p4;
442         p_surewarehk_Load_Privkey = p5;
443         p_surewarehk_Load_Rsa_Pubkey = p6;
444         p_surewarehk_Free = p7;
445         p_surewarehk_Rsa_Priv_Dec = p8;
446         p_surewarehk_Rsa_Sign = p9;
447         p_surewarehk_Dsa_Sign = p12;
448         p_surewarehk_Info_Pubkey = p13;
449         p_surewarehk_Load_Dsa_Pubkey = p14;
450         p_surewarehk_Mod_Exp = p15;
451         /* Contact the hardware and initialises it. */
452         if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
453         {
454                 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
455                 goto err;
456         }
457         if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
458         {
459                 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
460                 goto err;
461         }
462         /* try to load the default private key, if failed does not return a failure but
463            wait for an explicit ENGINE_load_privakey */
464         surewarehk_load_privkey(e,NULL,NULL,NULL);
465
466         /* Everything's fine. */
467         if (rsaHndidx == -1)
468                 rsaHndidx = RSA_get_ex_new_index(0,
469                                                 "SureWareHook RSA key handle",
470                                                 NULL, NULL, surewarehk_ex_free);
471         if (dsaHndidx == -1)
472                 dsaHndidx = DSA_get_ex_new_index(0,
473                                                 "SureWareHook DSA key handle",
474                                                 NULL, NULL, surewarehk_ex_free);
475         return 1;
476 err:
477         if(surewarehk_dso)
478                 DSO_free(surewarehk_dso);
479         surewarehk_dso = NULL;
480         p_surewarehk_Init = NULL;
481         p_surewarehk_Finish = NULL;
482         p_surewarehk_Rand_Bytes = NULL;
483         p_surewarehk_Rand_Seed = NULL;
484         p_surewarehk_Load_Privkey = NULL;
485         p_surewarehk_Load_Rsa_Pubkey = NULL;
486         p_surewarehk_Free = NULL;
487         p_surewarehk_Rsa_Priv_Dec = NULL;
488         p_surewarehk_Rsa_Sign = NULL;
489         p_surewarehk_Dsa_Sign = NULL;
490         p_surewarehk_Info_Pubkey = NULL;
491         p_surewarehk_Load_Dsa_Pubkey = NULL;
492         p_surewarehk_Mod_Exp = NULL;
493         return 0;
494 }
495
496 static int surewarehk_finish(ENGINE *e)
497 {
498         int to_return = 1;
499         if(surewarehk_dso == NULL)
500                 {
501                 SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_NOT_LOADED);
502                 to_return = 0;
503                 goto err;
504                 }
505         p_surewarehk_Finish();
506         if(!DSO_free(surewarehk_dso))
507                 {
508                 SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_DSO_FAILURE);
509                 to_return = 0;
510                 goto err;
511                 }
512  err:
513         if (logstream)
514                 BIO_free(logstream);
515         surewarehk_dso = NULL;
516         p_surewarehk_Init = NULL;
517         p_surewarehk_Finish = NULL;
518         p_surewarehk_Rand_Bytes = NULL;
519         p_surewarehk_Rand_Seed = NULL;
520         p_surewarehk_Load_Privkey = NULL;
521         p_surewarehk_Load_Rsa_Pubkey = NULL;
522         p_surewarehk_Free = NULL;
523         p_surewarehk_Rsa_Priv_Dec = NULL;
524         p_surewarehk_Rsa_Sign = NULL;
525         p_surewarehk_Dsa_Sign = NULL;
526         p_surewarehk_Info_Pubkey = NULL;
527         p_surewarehk_Load_Dsa_Pubkey = NULL;
528         p_surewarehk_Mod_Exp = NULL;
529         return to_return;
530 }
531 static void surewarehk_error_handling(char *const msg,int func,int ret)
532 {
533         switch (ret)
534         {
535                 case SUREWAREHOOK_ERROR_UNIT_FAILURE:
536                         ENGINEerr(func,SUREWARE_R_UNIT_FAILURE);
537                         break;
538                 case SUREWAREHOOK_ERROR_FALLBACK:
539                         ENGINEerr(func,SUREWARE_R_REQUEST_FALLBACK);
540                         break;
541                 case SUREWAREHOOK_ERROR_DATA_SIZE:
542                         ENGINEerr(func,SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
543                         break;
544                 case SUREWAREHOOK_ERROR_INVALID_PAD:
545                         ENGINEerr(func,RSA_R_PADDING_CHECK_FAILED);
546                         break;
547                 default:
548                         ENGINEerr(func,SUREWARE_R_REQUEST_FAILED);
549                         break;
550                 case 1:/*nothing*/
551                         msg[0]='\0';
552         }
553         if (*msg)
554         {
555                 ERR_add_error_data(1,msg);
556                 if (logstream)
557                 {
558                         CRYPTO_w_lock(CRYPTO_LOCK_BIO);
559                         BIO_write(logstream, msg, strlen(msg));
560                         CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
561                 }
562         }
563 }
564 static int surewarehk_rand_bytes(unsigned char *buf, int num)
565 {
566         int ret=0;
567         char msg[64]="ENGINE_rand_bytes";
568         if(!p_surewarehk_Rand_Bytes)
569         {
570                 SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED);
571         }
572         else
573         {
574                 ret = p_surewarehk_Rand_Bytes(msg,buf, num);
575                 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_BYTES,ret);
576         }
577         return ret==1 ? 1 : 0;
578 }
579
580 static void surewarehk_rand_seed(const void *buf, int num)
581 {
582         int ret=0;
583         char msg[64]="ENGINE_rand_seed";
584         if(!p_surewarehk_Rand_Seed)
585         {
586                 SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED,ENGINE_R_NOT_INITIALISED);
587         }
588         else
589         {
590                 ret = p_surewarehk_Rand_Seed(msg,buf, num);
591                 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_SEED,ret);
592         }
593 }
594 static void surewarehk_rand_add(const void *buf, int num, double entropy)
595 {
596         surewarehk_rand_seed(buf,num);
597 }
598 static EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,unsigned long el,char keytype)
599 {
600         EVP_PKEY *res = NULL;
601         RSA *rsatmp = NULL;
602         DSA *dsatmp=NULL;
603         char msg[64]="sureware_load_public";
604         int ret=0;
605         if(!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey)
606         {
607                 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_NOT_INITIALISED);
608                 goto err;
609         }
610         switch (keytype)
611         {
612         case 1: /*RSA*/
613                 /* set private external reference */
614                 rsatmp = RSA_new_method(e);
615                 RSA_set_ex_data(rsatmp,rsaHndidx,hptr);
616                 rsatmp->flags |= RSA_FLAG_EXT_PKEY;
617
618                 /* set public big nums*/
619                 rsatmp->e = BN_new();
620                 rsatmp->n = BN_new();
621                 bn_expand2(rsatmp->e, el/sizeof(BN_ULONG));
622                 bn_expand2(rsatmp->n, el/sizeof(BN_ULONG));
623                 if (!rsatmp->e || rsatmp->e->dmax!=(int)(el/sizeof(BN_ULONG))|| 
624                         !rsatmp->n || rsatmp->n->dmax!=(int)(el/sizeof(BN_ULONG)))
625                         goto err;
626                 ret=p_surewarehk_Load_Rsa_Pubkey(msg,key_id,el,rsatmp->n->d, rsatmp->e->d);
627                 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ret);
628                 if (ret!=1)
629                 {
630                         SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
631                         goto err;
632                 }
633                 /* normalise pub e and pub n */
634                 rsatmp->e->top=el/sizeof(BN_ULONG);
635                 bn_fix_top(rsatmp->e);
636                 rsatmp->n->top=el/sizeof(BN_ULONG);
637                 bn_fix_top(rsatmp->n);
638                 /* create an EVP object: engine + rsa key */
639                 res = EVP_PKEY_new();
640                 EVP_PKEY_assign_RSA(res, rsatmp);
641                 break;
642         case 2:/*DSA*/
643                 /* set private/public external reference */
644                 dsatmp = DSA_new_method(e);
645                 DSA_set_ex_data(dsatmp,dsaHndidx,hptr);
646                 /*dsatmp->flags |= DSA_FLAG_EXT_PKEY;*/
647
648                 /* set public key*/
649                 dsatmp->pub_key = BN_new();
650                 dsatmp->p = BN_new();
651                 dsatmp->q = BN_new();
652                 dsatmp->g = BN_new();
653                 bn_expand2(dsatmp->pub_key, el/sizeof(BN_ULONG));
654                 bn_expand2(dsatmp->p, el/sizeof(BN_ULONG));
655                 bn_expand2(dsatmp->q, 20/sizeof(BN_ULONG));
656                 bn_expand2(dsatmp->g, el/sizeof(BN_ULONG));
657                 if (!dsatmp->pub_key || dsatmp->pub_key->dmax!=(int)(el/sizeof(BN_ULONG))|| 
658                         !dsatmp->p || dsatmp->p->dmax!=(int)(el/sizeof(BN_ULONG)) ||
659                         !dsatmp->q || dsatmp->q->dmax!=20/sizeof(BN_ULONG) ||
660                         !dsatmp->g || dsatmp->g->dmax!=(int)(el/sizeof(BN_ULONG)))
661                         goto err;
662
663                 ret=p_surewarehk_Load_Dsa_Pubkey(msg,key_id,el,
664                                                                                 dsatmp->pub_key->d, 
665                                                                                 dsatmp->p->d,
666                                                                                 dsatmp->q->d,
667                                                                                 dsatmp->g->d);
668                 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ret);
669                 if (ret!=1)
670                 {
671                         SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
672                         goto err;
673                 }
674                 /* set parameters */
675                 /* normalise pubkey and parameters in case of */
676                 dsatmp->pub_key->top=el/sizeof(BN_ULONG);
677                 bn_fix_top(dsatmp->pub_key);
678                 dsatmp->p->top=el/sizeof(BN_ULONG);
679                 bn_fix_top(dsatmp->p);
680                 dsatmp->q->top=20/sizeof(BN_ULONG);
681                 bn_fix_top(dsatmp->q);
682                 dsatmp->g->top=el/sizeof(BN_ULONG);
683                 bn_fix_top(dsatmp->g);
684
685                 /* create an EVP object: engine + rsa key */
686                 res = EVP_PKEY_new();
687                 EVP_PKEY_assign_DSA(res, dsatmp);
688                 break;
689         default:
690                 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
691                 goto err;
692         }
693         return res;
694  err:
695         if (res)
696                 EVP_PKEY_free(res);
697         if (rsatmp)
698                 RSA_free(rsatmp);
699         if (dsatmp)
700                 DSA_free(dsatmp);
701         return NULL;
702 }
703 static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
704                                          UI_METHOD *ui_method, void *callback_data)
705 {
706         EVP_PKEY *res = NULL;
707         int ret=0;
708         unsigned long el=0;
709         char *hptr=NULL;
710         char keytype=0;
711         char msg[64]="ENGINE_load_privkey";
712
713         if(!p_surewarehk_Load_Privkey)
714         {
715                 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_NOT_INITIALISED);
716         }
717         else
718         {
719                 ret=p_surewarehk_Load_Privkey(msg,key_id,&hptr,&el,&keytype);
720                 if (ret!=1)
721                 {
722                         SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
723                         ERR_add_error_data(1,msg);              
724                 }
725                 else
726                         res=sureware_load_public(e,key_id,hptr,el,keytype);
727         }
728         return res;
729 }
730 static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
731                                          UI_METHOD *ui_method, void *callback_data)
732 {
733         EVP_PKEY *res = NULL;
734         int ret=0;
735         unsigned long el=0;
736         char *hptr=NULL;
737         char keytype=0;
738         char msg[64]="ENGINE_load_pubkey";
739
740         if(!p_surewarehk_Info_Pubkey)
741         {
742                 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_NOT_INITIALISED);
743         }
744         else
745         {
746                 /* call once to identify if DSA or RSA */
747                 ret=p_surewarehk_Info_Pubkey(msg,key_id,&el,&keytype);
748                 if (ret!=1)
749                 {
750                         SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
751                         ERR_add_error_data(1,msg);
752                 }
753                 else
754                         res=sureware_load_public(e,key_id,hptr,el,keytype);
755         }
756         return res;
757 }
758
759 /* This cleans up an RSA/DSA KM key(do not destroy the key into the hardware)
760 , called when ex_data is freed */
761 static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
762         int index,long argl, void *argp)
763 {
764         if(!p_surewarehk_Free)
765         {
766                 SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED);
767         }
768         else
769                 p_surewarehk_Free((char *)item,0);
770 }
771 /* This cleans up an DH KM key (destroys the key into hardware), 
772 called when ex_data is freed */
773 static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
774         int index,long argl, void *argp)
775 {
776         if(!p_surewarehk_Free)
777         {
778                 SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED);
779         }
780         else
781                 p_surewarehk_Free((char *)item,1);
782 }
783 /*
784 * return number of decrypted bytes
785 */
786 static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
787                         RSA *rsa,int padding)
788 {
789         int ret=0,tlen;
790         char *buf=NULL,*hptr=NULL;
791         char msg[64]="ENGINE_rsa_priv_dec";
792         if (!p_surewarehk_Rsa_Priv_Dec)
793         {
794                 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ENGINE_R_NOT_INITIALISED);
795         }
796         /* extract ref to private key */
797         else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
798         {
799                 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_MISSING_KEY_COMPONENTS);
800                 goto err;
801         }
802         /* analyse what padding we can do into the hardware */
803         if (padding==RSA_PKCS1_PADDING)
804         {
805                 /* do it one shot */
806                 ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
807                 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
808                 if (ret!=1)
809                         goto err;
810                 ret=tlen;
811         }
812         else /* do with no padding into hardware */
813         {
814                 ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_NO_PAD);
815                 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
816                 if (ret!=1)
817                         goto err;
818                 /* intermediate buffer for padding */
819                 if ((buf=OPENSSL_malloc(tlen)) == NULL)
820                 {
821                         RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ERR_R_MALLOC_FAILURE);
822                         goto err;
823                 }
824                 memcpy(buf,to,tlen);/* transfert to into buf */
825                 switch (padding) /* check padding in software */
826                 {
827 #ifndef NO_SHA
828                 case RSA_PKCS1_OAEP_PADDING:
829                         ret=RSA_padding_check_PKCS1_OAEP(to,tlen,(unsigned char *)buf,tlen,tlen,NULL,0);
830                         break;
831 #endif
832                 case RSA_SSLV23_PADDING:
833                         ret=RSA_padding_check_SSLv23(to,tlen,(unsigned char *)buf,flen,tlen);
834                         break;
835                 case RSA_NO_PADDING:
836                         ret=RSA_padding_check_none(to,tlen,(unsigned char *)buf,flen,tlen);
837                         break;
838                 default:
839                         RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,RSA_R_UNKNOWN_PADDING_TYPE);
840                         goto err;
841                 }
842                 if (ret < 0)
843                         RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,RSA_R_PADDING_CHECK_FAILED);
844         }
845 err:
846         if (buf)
847         {
848                 memset(buf,0,tlen);
849                 OPENSSL_free(buf);
850         }
851         return ret;
852 }
853 /*
854 * Does what OpenSSL rsa_priv_enc does.
855 */
856 static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
857                             RSA *rsa,int padding)
858 {
859         int ret=0,tlen;
860         char *hptr=NULL;
861         char msg[64]="ENGINE_rsa_sign";
862         if (!p_surewarehk_Rsa_Sign)
863         {
864                 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,ENGINE_R_NOT_INITIALISED);
865         }
866         /* extract ref to private key */
867         else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
868         {
869                 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,SUREWARE_R_MISSING_KEY_COMPONENTS);
870         }
871         else
872         {
873                 switch (padding)
874                 {
875                 case RSA_PKCS1_PADDING: /* do it in one shot */
876                         ret=p_surewarehk_Rsa_Sign(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
877                         surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,ret);
878                         break;
879                 case RSA_NO_PADDING:
880                 default:
881                         RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,RSA_R_UNKNOWN_PADDING_TYPE);
882                 }
883         }
884         return ret==1 ? tlen : ret;
885 }
886 /* DSA sign and verify */
887 static  DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa)
888 {
889         int ret=0;
890         char *hptr=NULL;
891         DSA_SIG *psign=NULL;
892         char msg[64]="ENGINE_dsa_do_sign";
893         if (!p_surewarehk_Dsa_Sign)
894         {
895                 SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED);
896         }
897         /* extract ref to private key */
898         else if (!(hptr=DSA_get_ex_data(dsa, dsaHndidx)))
899         {
900                 SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS);
901         }
902         else
903         {
904                 if((psign = DSA_SIG_new()) == NULL)
905                 {
906                         SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE);
907                         goto err;
908                 }
909                 psign->r=BN_new();
910                 psign->s=BN_new();
911                 bn_expand2(psign->r, 20/sizeof(BN_ULONG));
912                 bn_expand2(psign->s, 20/sizeof(BN_ULONG));
913                 if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) ||
914                         !psign->s || psign->s->dmax!=20/sizeof(BN_ULONG))
915                         goto err;
916                 ret=p_surewarehk_Dsa_Sign(msg,flen,from,psign->r->d,psign->s->d,hptr);
917                 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret);
918         }
919         psign->r->top=20/sizeof(BN_ULONG);
920         bn_fix_top(psign->r);
921         psign->s->top=20/sizeof(BN_ULONG);
922         bn_fix_top(psign->s);
923
924 err:    
925         if (psign)
926         {
927                 DSA_SIG_free(psign);
928                 psign=NULL;
929         }
930         return psign;
931 }
932 static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
933                              const BIGNUM *m, BN_CTX *ctx)
934 {
935         int ret=0;
936         char msg[64]="ENGINE_modexp";
937         if (!p_surewarehk_Mod_Exp)
938         {
939                 SUREWAREerr(SUREWARE_F_SUREWAREHK_MOD_EXP,ENGINE_R_NOT_INITIALISED);
940         }
941         else
942         {
943                 bn_expand2(r,m->top);
944                 if (r && r->dmax==m->top)
945                 {
946                         /* do it*/
947                         ret=p_surewarehk_Mod_Exp(msg,m->top*sizeof(BN_ULONG),m->d,p->top*sizeof(BN_ULONG),
948                                                                         p->d,a->top*sizeof(BN_ULONG),a->d,r->d);
949                         surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_MOD_EXP,ret);
950                         if (ret==1)
951                         {
952                                 /* normalise result */
953                                 r->top=m->top;
954                                 bn_fix_top(r);
955                         }
956                 }
957         }
958         return ret;
959 }
960 #endif /* !NO_HW_SureWare */
961 #endif /* !NO_HW */