Merge from vendor branch GROFF:
[dragonfly.git] / crypto / openssl-0.9 / engines / e_cswift.c
1 /* crypto/engine/hw_cswift.c */
2 /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3  * project 2000.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer. 
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58
59 #include <stdio.h>
60 #include <string.h>
61 #include <openssl/crypto.h>
62 #include <openssl/buffer.h>
63 #include <openssl/dso.h>
64 #include <openssl/engine.h>
65 #include <openssl/rsa.h>
66 #include <openssl/dsa.h>
67 #include <openssl/dh.h>
68 #include <openssl/rand.h>
69 #include <openssl/bn.h>
70
71 #ifndef OPENSSL_NO_HW
72 #ifndef OPENSSL_NO_HW_CSWIFT
73
74 /* Attribution notice: Rainbow have generously allowed me to reproduce
75  * the necessary definitions here from their API. This means the support
76  * can build independently of whether application builders have the
77  * API or hardware. This will allow developers to easily produce software
78  * that has latent hardware support for any users that have accelerators
79  * installed, without the developers themselves needing anything extra.
80  *
81  * I have only clipped the parts from the CryptoSwift header files that
82  * are (or seem) relevant to the CryptoSwift support code. This is
83  * simply to keep the file sizes reasonable.
84  * [Geoff]
85  */
86 #ifdef FLAT_INC
87 #include "cswift.h"
88 #else
89 #include "vendor_defns/cswift.h"
90 #endif
91
92 #define CSWIFT_LIB_NAME "cswift engine"
93 #include "e_cswift_err.c"
94
95 #define DECIMAL_SIZE(type)      ((sizeof(type)*8+2)/3+1)
96
97 static int cswift_destroy(ENGINE *e);
98 static int cswift_init(ENGINE *e);
99 static int cswift_finish(ENGINE *e);
100 static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
101 static int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in);
102
103 /* BIGNUM stuff */
104 static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
105                 const BIGNUM *m, BN_CTX *ctx);
106 static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
107                 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
108                 const BIGNUM *iqmp, BN_CTX *ctx);
109
110 #ifndef OPENSSL_NO_RSA
111 /* RSA stuff */
112 static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
113 #endif
114 /* This function is aliased to mod_exp (with the mont stuff dropped). */
115 static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
116                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
117
118 #ifndef OPENSSL_NO_DSA
119 /* DSA stuff */
120 static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
121 static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
122                                 DSA_SIG *sig, DSA *dsa);
123 #endif
124
125 #ifndef OPENSSL_NO_DH
126 /* DH stuff */
127 /* This function is alised to mod_exp (with the DH and mont dropped). */
128 static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
129                 const BIGNUM *a, const BIGNUM *p,
130                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
131 #endif
132
133 /* RAND stuff */
134 static int cswift_rand_bytes(unsigned char *buf, int num);
135 static int cswift_rand_status(void);
136
137 /* The definitions for control commands specific to this engine */
138 #define CSWIFT_CMD_SO_PATH              ENGINE_CMD_BASE
139 static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
140         {CSWIFT_CMD_SO_PATH,
141                 "SO_PATH",
142                 "Specifies the path to the 'cswift' shared library",
143                 ENGINE_CMD_FLAG_STRING},
144         {0, NULL, NULL, 0}
145         };
146
147 #ifndef OPENSSL_NO_RSA
148 /* Our internal RSA_METHOD that we provide pointers to */
149 static RSA_METHOD cswift_rsa =
150         {
151         "CryptoSwift RSA method",
152         NULL,
153         NULL,
154         NULL,
155         NULL,
156         cswift_rsa_mod_exp,
157         cswift_mod_exp_mont,
158         NULL,
159         NULL,
160         0,
161         NULL,
162         NULL,
163         NULL,
164         NULL
165         };
166 #endif
167
168 #ifndef OPENSSL_NO_DSA
169 /* Our internal DSA_METHOD that we provide pointers to */
170 static DSA_METHOD cswift_dsa =
171         {
172         "CryptoSwift DSA method",
173         cswift_dsa_sign,
174         NULL, /* dsa_sign_setup */
175         cswift_dsa_verify,
176         NULL, /* dsa_mod_exp */
177         NULL, /* bn_mod_exp */
178         NULL, /* init */
179         NULL, /* finish */
180         0, /* flags */
181         NULL, /* app_data */
182         NULL, /* dsa_paramgen */
183         NULL /* dsa_keygen */
184         };
185 #endif
186
187 #ifndef OPENSSL_NO_DH
188 /* Our internal DH_METHOD that we provide pointers to */
189 static DH_METHOD cswift_dh =
190         {
191         "CryptoSwift DH method",
192         NULL,
193         NULL,
194         cswift_mod_exp_dh,
195         NULL,
196         NULL,
197         0,
198         NULL,
199         NULL
200         };
201 #endif
202
203 static RAND_METHOD cswift_random =
204     {
205     /* "CryptoSwift RAND method", */
206     NULL,
207     cswift_rand_bytes,
208     NULL,
209     NULL,
210     cswift_rand_bytes,
211     cswift_rand_status,
212     };
213
214
215 /* Constants used when creating the ENGINE */
216 static const char *engine_cswift_id = "cswift";
217 static const char *engine_cswift_name = "CryptoSwift hardware engine support";
218
219 /* This internal function is used by ENGINE_cswift() and possibly by the
220  * "dynamic" ENGINE support too */
221 static int bind_helper(ENGINE *e)
222         {
223 #ifndef OPENSSL_NO_RSA
224         const RSA_METHOD *meth1;
225 #endif
226 #ifndef OPENSSL_NO_DH
227         const DH_METHOD *meth2;
228 #endif
229         if(!ENGINE_set_id(e, engine_cswift_id) ||
230                         !ENGINE_set_name(e, engine_cswift_name) ||
231 #ifndef OPENSSL_NO_RSA
232                         !ENGINE_set_RSA(e, &cswift_rsa) ||
233 #endif
234 #ifndef OPENSSL_NO_DSA
235                         !ENGINE_set_DSA(e, &cswift_dsa) ||
236 #endif
237 #ifndef OPENSSL_NO_DH
238                         !ENGINE_set_DH(e, &cswift_dh) ||
239 #endif
240                         !ENGINE_set_RAND(e, &cswift_random) ||
241                         !ENGINE_set_destroy_function(e, cswift_destroy) ||
242                         !ENGINE_set_init_function(e, cswift_init) ||
243                         !ENGINE_set_finish_function(e, cswift_finish) ||
244                         !ENGINE_set_ctrl_function(e, cswift_ctrl) ||
245                         !ENGINE_set_cmd_defns(e, cswift_cmd_defns))
246                 return 0;
247
248 #ifndef OPENSSL_NO_RSA
249         /* We know that the "PKCS1_SSLeay()" functions hook properly
250          * to the cswift-specific mod_exp and mod_exp_crt so we use
251          * those functions. NB: We don't use ENGINE_openssl() or
252          * anything "more generic" because something like the RSAref
253          * code may not hook properly, and if you own one of these
254          * cards then you have the right to do RSA operations on it
255          * anyway! */ 
256         meth1 = RSA_PKCS1_SSLeay();
257         cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
258         cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
259         cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
260         cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
261 #endif
262
263 #ifndef OPENSSL_NO_DH
264         /* Much the same for Diffie-Hellman */
265         meth2 = DH_OpenSSL();
266         cswift_dh.generate_key = meth2->generate_key;
267         cswift_dh.compute_key = meth2->compute_key;
268 #endif
269
270         /* Ensure the cswift error handling is set up */
271         ERR_load_CSWIFT_strings();
272         return 1;
273         }
274
275 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
276 static ENGINE *engine_cswift(void)
277         {
278         ENGINE *ret = ENGINE_new();
279         if(!ret)
280                 return NULL;
281         if(!bind_helper(ret))
282                 {
283                 ENGINE_free(ret);
284                 return NULL;
285                 }
286         return ret;
287         }
288
289 void ENGINE_load_cswift(void)
290         {
291         /* Copied from eng_[openssl|dyn].c */
292         ENGINE *toadd = engine_cswift();
293         if(!toadd) return;
294         ENGINE_add(toadd);
295         ENGINE_free(toadd);
296         ERR_clear_error();
297         }
298 #endif
299
300 /* This is a process-global DSO handle used for loading and unloading
301  * the CryptoSwift library. NB: This is only set (or unset) during an
302  * init() or finish() call (reference counts permitting) and they're
303  * operating with global locks, so this should be thread-safe
304  * implicitly. */
305 static DSO *cswift_dso = NULL;
306
307 /* These are the function pointers that are (un)set when the library has
308  * successfully (un)loaded. */
309 t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
310 t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
311 t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
312 t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
313
314 /* Used in the DSO operations. */
315 static const char *CSWIFT_LIBNAME = NULL;
316 static const char *get_CSWIFT_LIBNAME(void)
317         {
318         if(CSWIFT_LIBNAME)
319                 return CSWIFT_LIBNAME;
320         return "swift";
321         }
322 static void free_CSWIFT_LIBNAME(void)
323         {
324         if(CSWIFT_LIBNAME)
325                 OPENSSL_free((void*)CSWIFT_LIBNAME);
326         CSWIFT_LIBNAME = NULL;
327         }
328 static long set_CSWIFT_LIBNAME(const char *name)
329         {
330         free_CSWIFT_LIBNAME();
331         return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
332         }
333 static const char *CSWIFT_F1 = "swAcquireAccContext";
334 static const char *CSWIFT_F2 = "swAttachKeyParam";
335 static const char *CSWIFT_F3 = "swSimpleRequest";
336 static const char *CSWIFT_F4 = "swReleaseAccContext";
337
338
339 /* CryptoSwift library functions and mechanics - these are used by the
340  * higher-level functions further down. NB: As and where there's no
341  * error checking, take a look lower down where these functions are
342  * called, the checking and error handling is probably down there. */
343
344 /* utility function to obtain a context */
345 static int get_context(SW_CONTEXT_HANDLE *hac)
346         {
347         SW_STATUS status;
348  
349         status = p_CSwift_AcquireAccContext(hac);
350         if(status != SW_OK)
351                 return 0;
352         return 1;
353         }
354  
355 /* similarly to release one. */
356 static void release_context(SW_CONTEXT_HANDLE hac)
357         {
358         p_CSwift_ReleaseAccContext(hac);
359         }
360
361 /* Destructor (complements the "ENGINE_cswift()" constructor) */
362 static int cswift_destroy(ENGINE *e)
363         {
364         free_CSWIFT_LIBNAME();
365         ERR_unload_CSWIFT_strings();
366         return 1;
367         }
368
369 /* (de)initialisation functions. */
370 static int cswift_init(ENGINE *e)
371         {
372         SW_CONTEXT_HANDLE hac;
373         t_swAcquireAccContext *p1;
374         t_swAttachKeyParam *p2;
375         t_swSimpleRequest *p3;
376         t_swReleaseAccContext *p4;
377
378         if(cswift_dso != NULL)
379                 {
380                 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
381                 goto err;
382                 }
383         /* Attempt to load libswift.so/swift.dll/whatever. */
384         cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
385         if(cswift_dso == NULL)
386                 {
387                 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
388                 goto err;
389                 }
390         if(!(p1 = (t_swAcquireAccContext *)
391                                 DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
392                         !(p2 = (t_swAttachKeyParam *)
393                                 DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
394                         !(p3 = (t_swSimpleRequest *)
395                                 DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
396                         !(p4 = (t_swReleaseAccContext *)
397                                 DSO_bind_func(cswift_dso, CSWIFT_F4)))
398                 {
399                 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
400                 goto err;
401                 }
402         /* Copy the pointers */
403         p_CSwift_AcquireAccContext = p1;
404         p_CSwift_AttachKeyParam = p2;
405         p_CSwift_SimpleRequest = p3;
406         p_CSwift_ReleaseAccContext = p4;
407         /* Try and get a context - if not, we may have a DSO but no
408          * accelerator! */
409         if(!get_context(&hac))
410                 {
411                 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
412                 goto err;
413                 }
414         release_context(hac);
415         /* Everything's fine. */
416         return 1;
417 err:
418         if(cswift_dso)
419         {
420                 DSO_free(cswift_dso);
421                 cswift_dso = NULL;
422         }
423         p_CSwift_AcquireAccContext = NULL;
424         p_CSwift_AttachKeyParam = NULL;
425         p_CSwift_SimpleRequest = NULL;
426         p_CSwift_ReleaseAccContext = NULL;
427         return 0;
428         }
429
430 static int cswift_finish(ENGINE *e)
431         {
432         free_CSWIFT_LIBNAME();
433         if(cswift_dso == NULL)
434                 {
435                 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
436                 return 0;
437                 }
438         if(!DSO_free(cswift_dso))
439                 {
440                 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
441                 return 0;
442                 }
443         cswift_dso = NULL;
444         p_CSwift_AcquireAccContext = NULL;
445         p_CSwift_AttachKeyParam = NULL;
446         p_CSwift_SimpleRequest = NULL;
447         p_CSwift_ReleaseAccContext = NULL;
448         return 1;
449         }
450
451 static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
452         {
453         int initialised = ((cswift_dso == NULL) ? 0 : 1);
454         switch(cmd)
455                 {
456         case CSWIFT_CMD_SO_PATH:
457                 if(p == NULL)
458                         {
459                         CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
460                         return 0;
461                         }
462                 if(initialised)
463                         {
464                         CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
465                         return 0;
466                         }
467                 return set_CSWIFT_LIBNAME((const char *)p);
468         default:
469                 break;
470                 }
471         CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
472         return 0;
473         }
474
475 /* Un petit mod_exp */
476 static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
477                         const BIGNUM *m, BN_CTX *ctx)
478         {
479         /* I need somewhere to store temporary serialised values for
480          * use with the CryptoSwift API calls. A neat cheat - I'll use
481          * BIGNUMs from the BN_CTX but access their arrays directly as
482          * byte arrays <grin>. This way I don't have to clean anything
483          * up. */
484         BIGNUM *modulus;
485         BIGNUM *exponent;
486         BIGNUM *argument;
487         BIGNUM *result;
488         SW_STATUS sw_status;
489         SW_LARGENUMBER arg, res;
490         SW_PARAM sw_param;
491         SW_CONTEXT_HANDLE hac;
492         int to_return, acquired;
493  
494         modulus = exponent = argument = result = NULL;
495         to_return = 0; /* expect failure */
496         acquired = 0;
497  
498         if(!get_context(&hac))
499                 {
500                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
501                 goto err;
502                 }
503         acquired = 1;
504         /* Prepare the params */
505         BN_CTX_start(ctx);
506         modulus = BN_CTX_get(ctx);
507         exponent = BN_CTX_get(ctx);
508         argument = BN_CTX_get(ctx);
509         result = BN_CTX_get(ctx);
510         if(!result)
511                 {
512                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
513                 goto err;
514                 }
515         if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
516                 !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
517                 {
518                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
519                 goto err;
520                 }
521         sw_param.type = SW_ALG_EXP;
522         sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
523                 (unsigned char *)modulus->d);
524         sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
525         sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
526                 (unsigned char *)exponent->d);
527         sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
528         /* Attach the key params */
529         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
530         switch(sw_status)
531                 {
532         case SW_OK:
533                 break;
534         case SW_ERR_INPUT_SIZE:
535                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
536                 goto err;
537         default:
538                 {
539                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
540                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
541                 sprintf(tmpbuf, "%ld", sw_status);
542                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
543                 }
544                 goto err;
545                 }
546         /* Prepare the argument and response */
547         arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
548         arg.value = (unsigned char *)argument->d;
549         res.nbytes = BN_num_bytes(m);
550         memset(result->d, 0, res.nbytes);
551         res.value = (unsigned char *)result->d;
552         /* Perform the operation */
553         if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
554                 &res, 1)) != SW_OK)
555                 {
556                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
557                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
558                 sprintf(tmpbuf, "%ld", sw_status);
559                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
560                 goto err;
561                 }
562         /* Convert the response */
563         BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
564         to_return = 1;
565 err:
566         if(acquired)
567                 release_context(hac);
568         BN_CTX_end(ctx);
569         return to_return;
570         }
571
572
573 int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in)
574 {
575         int mod;
576         int numbytes = BN_num_bytes(in);
577
578         mod = 0;
579         while( ((out->nbytes = (numbytes+mod)) % 32) )
580         {
581                 mod++;
582         }
583         out->value = (unsigned char*)OPENSSL_malloc(out->nbytes);
584         if(!out->value)
585         {
586                 return 0;
587         }
588         BN_bn2bin(in, &out->value[mod]);
589         if(mod)
590                 memset(out->value, 0, mod);
591
592         return 1;
593 }
594
595 /* Un petit mod_exp chinois */
596 static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
597                         const BIGNUM *q, const BIGNUM *dmp1,
598                         const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
599         {
600         SW_STATUS sw_status;
601         SW_LARGENUMBER arg, res;
602         SW_PARAM sw_param;
603         SW_CONTEXT_HANDLE hac;
604         BIGNUM *result = NULL;
605         BIGNUM *argument = NULL;
606         int to_return = 0; /* expect failure */
607         int acquired = 0;
608
609         sw_param.up.crt.p.value = NULL;
610         sw_param.up.crt.q.value = NULL;
611         sw_param.up.crt.dmp1.value = NULL;
612         sw_param.up.crt.dmq1.value = NULL;
613         sw_param.up.crt.iqmp.value = NULL;
614  
615         if(!get_context(&hac))
616                 {
617                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
618                 goto err;
619                 }
620         acquired = 1;
621
622         /* Prepare the params */
623         argument = BN_new();
624         result = BN_new();
625         if(!result || !argument)
626                 {
627                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
628                 goto err;
629                 }
630
631
632         sw_param.type = SW_ALG_CRT;
633         /************************************************************************/
634         /* 04/02/2003                                                           */
635         /* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
636         /* limitation of cswift with values not a multiple of 32                */
637         /************************************************************************/
638         if(!cswift_bn_32copy(&sw_param.up.crt.p, p))
639         {
640                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
641                 goto err;
642         }
643         if(!cswift_bn_32copy(&sw_param.up.crt.q, q))
644         {
645                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
646                 goto err;
647         }
648         if(!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1))
649         {
650                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
651                 goto err;
652         }
653         if(!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1))
654         {
655                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
656                 goto err;
657         }
658         if(!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp))
659         {
660                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
661                 goto err;
662         }
663         if(     !bn_wexpand(argument, a->top) ||
664                         !bn_wexpand(result, p->top + q->top))
665                 {
666                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
667                 goto err;
668                 }
669
670         /* Attach the key params */
671         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
672         switch(sw_status)
673                 {
674         case SW_OK:
675                 break;
676         case SW_ERR_INPUT_SIZE:
677                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
678                 goto err;
679         default:
680                 {
681                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
682                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
683                 sprintf(tmpbuf, "%ld", sw_status);
684                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
685                 }
686                 goto err;
687                 }
688         /* Prepare the argument and response */
689         arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
690         arg.value = (unsigned char *)argument->d;
691         res.nbytes = 2 * BN_num_bytes(p);
692         memset(result->d, 0, res.nbytes);
693         res.value = (unsigned char *)result->d;
694         /* Perform the operation */
695         if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
696                 &res, 1)) != SW_OK)
697                 {
698                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
699                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
700                 sprintf(tmpbuf, "%ld", sw_status);
701                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
702                 goto err;
703                 }
704         /* Convert the response */
705         BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
706         to_return = 1;
707 err:
708         if(sw_param.up.crt.p.value)
709                 OPENSSL_free(sw_param.up.crt.p.value);
710         if(sw_param.up.crt.q.value)
711                 OPENSSL_free(sw_param.up.crt.q.value);
712         if(sw_param.up.crt.dmp1.value)
713                 OPENSSL_free(sw_param.up.crt.dmp1.value);
714         if(sw_param.up.crt.dmq1.value)
715                 OPENSSL_free(sw_param.up.crt.dmq1.value);
716         if(sw_param.up.crt.iqmp.value)
717                 OPENSSL_free(sw_param.up.crt.iqmp.value);
718         if(result)
719                 BN_free(result);
720         if(argument)
721                 BN_free(argument);
722         if(acquired)
723                 release_context(hac);
724         return to_return;
725         }
726  
727 #ifndef OPENSSL_NO_RSA
728 static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
729         {
730         int to_return = 0;
731         const RSA_METHOD * def_rsa_method;
732
733         /* Try the limits of RSA (2048 bits) */
734         if(BN_num_bytes(rsa->p) > 128 ||
735                 BN_num_bytes(rsa->q) > 128 ||
736                 BN_num_bytes(rsa->dmp1) > 128 ||
737                 BN_num_bytes(rsa->dmq1) > 128 ||
738                 BN_num_bytes(rsa->iqmp) > 128)
739         {
740 #ifdef RSA_NULL
741                 def_rsa_method=RSA_null_method();
742 #else
743 #if 0
744                 def_rsa_method=RSA_PKCS1_RSAref();
745 #else
746                 def_rsa_method=RSA_PKCS1_SSLeay();
747 #endif
748 #endif
749                 if(def_rsa_method)
750                         return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx);
751         }
752
753         if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
754                 {
755                 CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
756                 goto err;
757                 }
758         to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
759                 rsa->dmq1, rsa->iqmp, ctx);
760 err:
761         return to_return;
762         }
763 #endif
764
765 /* This function is aliased to mod_exp (with the mont stuff dropped). */
766 static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
767                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
768         {
769         const RSA_METHOD * def_rsa_method;
770
771         /* Try the limits of RSA (2048 bits) */
772         if(BN_num_bytes(r) > 256 ||
773                 BN_num_bytes(a) > 256 ||
774                 BN_num_bytes(m) > 256)
775         {
776 #ifdef RSA_NULL
777                 def_rsa_method=RSA_null_method();
778 #else
779 #if 0
780                 def_rsa_method=RSA_PKCS1_RSAref();
781 #else
782                 def_rsa_method=RSA_PKCS1_SSLeay();
783 #endif
784 #endif
785                 if(def_rsa_method)
786                         return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx);
787         }
788
789         return cswift_mod_exp(r, a, p, m, ctx);
790         }
791
792 #ifndef OPENSSL_NO_DSA
793 static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
794         {
795         SW_CONTEXT_HANDLE hac;
796         SW_PARAM sw_param;
797         SW_STATUS sw_status;
798         SW_LARGENUMBER arg, res;
799         unsigned char *ptr;
800         BN_CTX *ctx;
801         BIGNUM *dsa_p = NULL;
802         BIGNUM *dsa_q = NULL;
803         BIGNUM *dsa_g = NULL;
804         BIGNUM *dsa_key = NULL;
805         BIGNUM *result = NULL;
806         DSA_SIG *to_return = NULL;
807         int acquired = 0;
808
809         if((ctx = BN_CTX_new()) == NULL)
810                 goto err;
811         if(!get_context(&hac))
812                 {
813                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
814                 goto err;
815                 }
816         acquired = 1;
817         /* Prepare the params */
818         BN_CTX_start(ctx);
819         dsa_p = BN_CTX_get(ctx);
820         dsa_q = BN_CTX_get(ctx);
821         dsa_g = BN_CTX_get(ctx);
822         dsa_key = BN_CTX_get(ctx);
823         result = BN_CTX_get(ctx);
824         if(!result)
825                 {
826                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
827                 goto err;
828                 }
829         if(!bn_wexpand(dsa_p, dsa->p->top) ||
830                         !bn_wexpand(dsa_q, dsa->q->top) ||
831                         !bn_wexpand(dsa_g, dsa->g->top) ||
832                         !bn_wexpand(dsa_key, dsa->priv_key->top) ||
833                         !bn_wexpand(result, dsa->p->top))
834                 {
835                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
836                 goto err;
837                 }
838         sw_param.type = SW_ALG_DSA;
839         sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
840                                 (unsigned char *)dsa_p->d);
841         sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
842         sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
843                                 (unsigned char *)dsa_q->d);
844         sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
845         sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
846                                 (unsigned char *)dsa_g->d);
847         sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
848         sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
849                                 (unsigned char *)dsa_key->d);
850         sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
851         /* Attach the key params */
852         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
853         switch(sw_status)
854                 {
855         case SW_OK:
856                 break;
857         case SW_ERR_INPUT_SIZE:
858                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
859                 goto err;
860         default:
861                 {
862                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
863                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
864                 sprintf(tmpbuf, "%ld", sw_status);
865                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
866                 }
867                 goto err;
868                 }
869         /* Prepare the argument and response */
870         arg.nbytes = dlen;
871         arg.value = (unsigned char *)dgst;
872         res.nbytes = BN_num_bytes(dsa->p);
873         memset(result->d, 0, res.nbytes);
874         res.value = (unsigned char *)result->d;
875         /* Perform the operation */
876         sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
877                 &res, 1);
878         if(sw_status != SW_OK)
879                 {
880                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
881                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
882                 sprintf(tmpbuf, "%ld", sw_status);
883                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
884                 goto err;
885                 }
886         /* Convert the response */
887         ptr = (unsigned char *)result->d;
888         if((to_return = DSA_SIG_new()) == NULL)
889                 goto err;
890         to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
891         to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
892
893 err:
894         if(acquired)
895                 release_context(hac);
896         if(ctx)
897                 {
898                 BN_CTX_end(ctx);
899                 BN_CTX_free(ctx);
900                 }
901         return to_return;
902         }
903
904 static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
905                                 DSA_SIG *sig, DSA *dsa)
906         {
907         SW_CONTEXT_HANDLE hac;
908         SW_PARAM sw_param;
909         SW_STATUS sw_status;
910         SW_LARGENUMBER arg[2], res;
911         unsigned long sig_result;
912         BN_CTX *ctx;
913         BIGNUM *dsa_p = NULL;
914         BIGNUM *dsa_q = NULL;
915         BIGNUM *dsa_g = NULL;
916         BIGNUM *dsa_key = NULL;
917         BIGNUM *argument = NULL;
918         int to_return = -1;
919         int acquired = 0;
920
921         if((ctx = BN_CTX_new()) == NULL)
922                 goto err;
923         if(!get_context(&hac))
924                 {
925                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
926                 goto err;
927                 }
928         acquired = 1;
929         /* Prepare the params */
930         BN_CTX_start(ctx);
931         dsa_p = BN_CTX_get(ctx);
932         dsa_q = BN_CTX_get(ctx);
933         dsa_g = BN_CTX_get(ctx);
934         dsa_key = BN_CTX_get(ctx);
935         argument = BN_CTX_get(ctx);
936         if(!argument)
937                 {
938                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
939                 goto err;
940                 }
941         if(!bn_wexpand(dsa_p, dsa->p->top) ||
942                         !bn_wexpand(dsa_q, dsa->q->top) ||
943                         !bn_wexpand(dsa_g, dsa->g->top) ||
944                         !bn_wexpand(dsa_key, dsa->pub_key->top) ||
945                         !bn_wexpand(argument, 40))
946                 {
947                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
948                 goto err;
949                 }
950         sw_param.type = SW_ALG_DSA;
951         sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
952                                 (unsigned char *)dsa_p->d);
953         sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
954         sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
955                                 (unsigned char *)dsa_q->d);
956         sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
957         sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
958                                 (unsigned char *)dsa_g->d);
959         sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
960         sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
961                                 (unsigned char *)dsa_key->d);
962         sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
963         /* Attach the key params */
964         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
965         switch(sw_status)
966                 {
967         case SW_OK:
968                 break;
969         case SW_ERR_INPUT_SIZE:
970                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
971                 goto err;
972         default:
973                 {
974                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
975                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
976                 sprintf(tmpbuf, "%ld", sw_status);
977                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
978                 }
979                 goto err;
980                 }
981         /* Prepare the argument and response */
982         arg[0].nbytes = dgst_len;
983         arg[0].value = (unsigned char *)dgst;
984         arg[1].nbytes = 40;
985         arg[1].value = (unsigned char *)argument->d;
986         memset(arg[1].value, 0, 40);
987         BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
988         BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
989         res.nbytes = 4; /* unsigned long */
990         res.value = (unsigned char *)(&sig_result);
991         /* Perform the operation */
992         sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
993                 &res, 1);
994         if(sw_status != SW_OK)
995                 {
996                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
997                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
998                 sprintf(tmpbuf, "%ld", sw_status);
999                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
1000                 goto err;
1001                 }
1002         /* Convert the response */
1003         to_return = ((sig_result == 0) ? 0 : 1);
1004
1005 err:
1006         if(acquired)
1007                 release_context(hac);
1008         if(ctx)
1009                 {
1010                 BN_CTX_end(ctx);
1011                 BN_CTX_free(ctx);
1012                 }
1013         return to_return;
1014         }
1015 #endif
1016
1017 #ifndef OPENSSL_NO_DH
1018 /* This function is aliased to mod_exp (with the dh and mont dropped). */
1019 static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
1020                 const BIGNUM *a, const BIGNUM *p,
1021                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1022         {
1023         return cswift_mod_exp(r, a, p, m, ctx);
1024         }
1025 #endif
1026
1027 /* Random bytes are good */
1028 static int cswift_rand_bytes(unsigned char *buf, int num)
1029 {
1030         SW_CONTEXT_HANDLE hac;
1031         SW_STATUS swrc;
1032         SW_LARGENUMBER largenum;
1033         int acquired = 0;
1034         int to_return = 0; /* assume failure */
1035         unsigned char buf32[1024];
1036
1037
1038         if (!get_context(&hac))
1039         {
1040                 CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE);
1041                 goto err;
1042         }
1043         acquired = 1;
1044
1045         /************************************************************************/
1046         /* 04/02/2003                                                           */
1047         /* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
1048         /* limitation of cswift with values not a multiple of 32                */
1049         /************************************************************************/
1050
1051         while(num >= sizeof(buf32))
1052         {
1053                 largenum.value = buf;
1054                 largenum.nbytes = sizeof(buf32);
1055                 /* tell CryptoSwift how many bytes we want and where we want it.
1056                  * Note: - CryptoSwift cannot do more than 4096 bytes at a time.
1057                  *       - CryptoSwift can only do multiple of 32-bits. */
1058                 swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
1059                 if (swrc != SW_OK)
1060                 {
1061                         char tmpbuf[20];
1062                         CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
1063                         sprintf(tmpbuf, "%ld", swrc);
1064                         ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
1065                         goto err;
1066                 }
1067                 buf += sizeof(buf32);
1068                 num -= sizeof(buf32);
1069         }
1070         if(num)
1071         {
1072                 largenum.nbytes = sizeof(buf32);
1073                 largenum.value = buf32;
1074                 swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
1075                 if (swrc != SW_OK)
1076                 {
1077                         char tmpbuf[20];
1078                         CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_REQUEST_FAILED);
1079                         sprintf(tmpbuf, "%ld", swrc);
1080                         ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
1081                         goto err;
1082                 }
1083                 memcpy(buf, largenum.value, num);
1084         }
1085
1086         to_return = 1;  /* success */
1087 err:
1088         if (acquired)
1089                 release_context(hac);
1090
1091         return to_return;
1092 }
1093
1094 static int cswift_rand_status(void)
1095 {
1096         return 1;
1097 }
1098
1099
1100 /* This stuff is needed if this ENGINE is being compiled into a self-contained
1101  * shared-library. */
1102 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
1103 static int bind_fn(ENGINE *e, const char *id)
1104         {
1105         if(id && (strcmp(id, engine_cswift_id) != 0))
1106                 return 0;
1107         if(!bind_helper(e))
1108                 return 0;
1109         return 1;
1110         }       
1111 IMPLEMENT_DYNAMIC_CHECK_FN()
1112 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1113 #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
1114
1115 #endif /* !OPENSSL_NO_HW_CSWIFT */
1116 #endif /* !OPENSSL_NO_HW */