Nils Larsch reported that this include is required. Strange that this had
[openssl.git] / 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
102 /* BIGNUM stuff */
103 static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
104                 const BIGNUM *m, BN_CTX *ctx);
105 static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
106                 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
107                 const BIGNUM *iqmp, BN_CTX *ctx);
108
109 #ifndef OPENSSL_NO_RSA
110 /* RSA stuff */
111 static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
112 #endif
113 /* This function is aliased to mod_exp (with the mont stuff dropped). */
114 static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
115                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
116
117 #ifndef OPENSSL_NO_DSA
118 /* DSA stuff */
119 static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
120 static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
121                                 DSA_SIG *sig, DSA *dsa);
122 #endif
123
124 #ifndef OPENSSL_NO_DH
125 /* DH stuff */
126 /* This function is alised to mod_exp (with the DH and mont dropped). */
127 static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
128                 const BIGNUM *a, const BIGNUM *p,
129                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
130 #endif
131
132 /* RAND stuff */
133 static int cswift_rand_bytes(unsigned char *buf, int num);
134 static int cswift_rand_status(void);
135
136 /* The definitions for control commands specific to this engine */
137 #define CSWIFT_CMD_SO_PATH              ENGINE_CMD_BASE
138 static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
139         {CSWIFT_CMD_SO_PATH,
140                 "SO_PATH",
141                 "Specifies the path to the 'cswift' shared library",
142                 ENGINE_CMD_FLAG_STRING},
143         {0, NULL, NULL, 0}
144         };
145
146 #ifndef OPENSSL_NO_RSA
147 /* Our internal RSA_METHOD that we provide pointers to */
148 static RSA_METHOD cswift_rsa =
149         {
150         "CryptoSwift RSA method",
151         NULL,
152         NULL,
153         NULL,
154         NULL,
155         cswift_rsa_mod_exp,
156         cswift_mod_exp_mont,
157         NULL,
158         NULL,
159         0,
160         NULL,
161         NULL,
162         NULL,
163         NULL
164         };
165 #endif
166
167 #ifndef OPENSSL_NO_DSA
168 /* Our internal DSA_METHOD that we provide pointers to */
169 static DSA_METHOD cswift_dsa =
170         {
171         "CryptoSwift DSA method",
172         cswift_dsa_sign,
173         NULL, /* dsa_sign_setup */
174         cswift_dsa_verify,
175         NULL, /* dsa_mod_exp */
176         NULL, /* bn_mod_exp */
177         NULL, /* init */
178         NULL, /* finish */
179         0, /* flags */
180         NULL, /* app_data */
181         NULL, /* dsa_paramgen */
182         NULL /* dsa_keygen */
183         };
184 #endif
185
186 #ifndef OPENSSL_NO_DH
187 /* Our internal DH_METHOD that we provide pointers to */
188 static DH_METHOD cswift_dh =
189         {
190         "CryptoSwift DH method",
191         NULL,
192         NULL,
193         cswift_mod_exp_dh,
194         NULL,
195         NULL,
196         0,
197         NULL,
198         NULL
199         };
200 #endif
201
202 static RAND_METHOD cswift_random =
203     {
204     /* "CryptoSwift RAND method", */
205     NULL,
206     cswift_rand_bytes,
207     NULL,
208     NULL,
209     cswift_rand_bytes,
210     cswift_rand_status,
211     };
212
213
214 /* Constants used when creating the ENGINE */
215 static const char *engine_cswift_id = "cswift";
216 static const char *engine_cswift_name = "CryptoSwift hardware engine support";
217
218 /* This internal function is used by ENGINE_cswift() and possibly by the
219  * "dynamic" ENGINE support too */
220 static int bind_helper(ENGINE *e)
221         {
222 #ifndef OPENSSL_NO_RSA
223         const RSA_METHOD *meth1;
224 #endif
225 #ifndef OPENSSL_NO_DH
226         const DH_METHOD *meth2;
227 #endif
228         if(!ENGINE_set_id(e, engine_cswift_id) ||
229                         !ENGINE_set_name(e, engine_cswift_name) ||
230 #ifndef OPENSSL_NO_RSA
231                         !ENGINE_set_RSA(e, &cswift_rsa) ||
232 #endif
233 #ifndef OPENSSL_NO_DSA
234                         !ENGINE_set_DSA(e, &cswift_dsa) ||
235 #endif
236 #ifndef OPENSSL_NO_DH
237                         !ENGINE_set_DH(e, &cswift_dh) ||
238 #endif
239                         !ENGINE_set_RAND(e, &cswift_random) ||
240                         !ENGINE_set_destroy_function(e, cswift_destroy) ||
241                         !ENGINE_set_init_function(e, cswift_init) ||
242                         !ENGINE_set_finish_function(e, cswift_finish) ||
243                         !ENGINE_set_ctrl_function(e, cswift_ctrl) ||
244                         !ENGINE_set_cmd_defns(e, cswift_cmd_defns))
245                 return 0;
246
247 #ifndef OPENSSL_NO_RSA
248         /* We know that the "PKCS1_SSLeay()" functions hook properly
249          * to the cswift-specific mod_exp and mod_exp_crt so we use
250          * those functions. NB: We don't use ENGINE_openssl() or
251          * anything "more generic" because something like the RSAref
252          * code may not hook properly, and if you own one of these
253          * cards then you have the right to do RSA operations on it
254          * anyway! */ 
255         meth1 = RSA_PKCS1_SSLeay();
256         cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
257         cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
258         cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
259         cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
260 #endif
261
262 #ifndef OPENSSL_NO_DH
263         /* Much the same for Diffie-Hellman */
264         meth2 = DH_OpenSSL();
265         cswift_dh.generate_key = meth2->generate_key;
266         cswift_dh.compute_key = meth2->compute_key;
267 #endif
268
269         /* Ensure the cswift error handling is set up */
270         ERR_load_CSWIFT_strings();
271         return 1;
272         }
273
274 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
275 static ENGINE *engine_cswift(void)
276         {
277         ENGINE *ret = ENGINE_new();
278         if(!ret)
279                 return NULL;
280         if(!bind_helper(ret))
281                 {
282                 ENGINE_free(ret);
283                 return NULL;
284                 }
285         return ret;
286         }
287
288 void ENGINE_load_cswift(void)
289         {
290         /* Copied from eng_[openssl|dyn].c */
291         ENGINE *toadd = engine_cswift();
292         if(!toadd) return;
293         ENGINE_add(toadd);
294         ENGINE_free(toadd);
295         ERR_clear_error();
296         }
297 #endif
298
299 /* This is a process-global DSO handle used for loading and unloading
300  * the CryptoSwift library. NB: This is only set (or unset) during an
301  * init() or finish() call (reference counts permitting) and they're
302  * operating with global locks, so this should be thread-safe
303  * implicitly. */
304 static DSO *cswift_dso = NULL;
305
306 /* These are the function pointers that are (un)set when the library has
307  * successfully (un)loaded. */
308 t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
309 t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
310 t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
311 t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
312
313 /* Used in the DSO operations. */
314 static const char *CSWIFT_LIBNAME = NULL;
315 static const char *get_CSWIFT_LIBNAME(void)
316         {
317         if(CSWIFT_LIBNAME)
318                 return CSWIFT_LIBNAME;
319         return "swift";
320         }
321 static void free_CSWIFT_LIBNAME(void)
322         {
323         if(CSWIFT_LIBNAME)
324                 OPENSSL_free((void*)CSWIFT_LIBNAME);
325         CSWIFT_LIBNAME = NULL;
326         }
327 static long set_CSWIFT_LIBNAME(const char *name)
328         {
329         free_CSWIFT_LIBNAME();
330         return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
331         }
332 static const char *CSWIFT_F1 = "swAcquireAccContext";
333 static const char *CSWIFT_F2 = "swAttachKeyParam";
334 static const char *CSWIFT_F3 = "swSimpleRequest";
335 static const char *CSWIFT_F4 = "swReleaseAccContext";
336
337
338 /* CryptoSwift library functions and mechanics - these are used by the
339  * higher-level functions further down. NB: As and where there's no
340  * error checking, take a look lower down where these functions are
341  * called, the checking and error handling is probably down there. */
342
343 /* utility function to obtain a context */
344 static int get_context(SW_CONTEXT_HANDLE *hac)
345         {
346         SW_STATUS status;
347  
348         status = p_CSwift_AcquireAccContext(hac);
349         if(status != SW_OK)
350                 return 0;
351         return 1;
352         }
353  
354 /* similarly to release one. */
355 static void release_context(SW_CONTEXT_HANDLE hac)
356         {
357         p_CSwift_ReleaseAccContext(hac);
358         }
359
360 /* Destructor (complements the "ENGINE_cswift()" constructor) */
361 static int cswift_destroy(ENGINE *e)
362         {
363         free_CSWIFT_LIBNAME();
364         ERR_unload_CSWIFT_strings();
365         return 1;
366         }
367
368 /* (de)initialisation functions. */
369 static int cswift_init(ENGINE *e)
370         {
371         SW_CONTEXT_HANDLE hac;
372         t_swAcquireAccContext *p1;
373         t_swAttachKeyParam *p2;
374         t_swSimpleRequest *p3;
375         t_swReleaseAccContext *p4;
376
377         if(cswift_dso != NULL)
378                 {
379                 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
380                 goto err;
381                 }
382         /* Attempt to load libswift.so/swift.dll/whatever. */
383         cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
384         if(cswift_dso == NULL)
385                 {
386                 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
387                 goto err;
388                 }
389         if(!(p1 = (t_swAcquireAccContext *)
390                                 DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
391                         !(p2 = (t_swAttachKeyParam *)
392                                 DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
393                         !(p3 = (t_swSimpleRequest *)
394                                 DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
395                         !(p4 = (t_swReleaseAccContext *)
396                                 DSO_bind_func(cswift_dso, CSWIFT_F4)))
397                 {
398                 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
399                 goto err;
400                 }
401         /* Copy the pointers */
402         p_CSwift_AcquireAccContext = p1;
403         p_CSwift_AttachKeyParam = p2;
404         p_CSwift_SimpleRequest = p3;
405         p_CSwift_ReleaseAccContext = p4;
406         /* Try and get a context - if not, we may have a DSO but no
407          * accelerator! */
408         if(!get_context(&hac))
409                 {
410                 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
411                 goto err;
412                 }
413         release_context(hac);
414         /* Everything's fine. */
415         return 1;
416 err:
417         if(cswift_dso)
418                 DSO_free(cswift_dso);
419         p_CSwift_AcquireAccContext = NULL;
420         p_CSwift_AttachKeyParam = NULL;
421         p_CSwift_SimpleRequest = NULL;
422         p_CSwift_ReleaseAccContext = NULL;
423         return 0;
424         }
425
426 static int cswift_finish(ENGINE *e)
427         {
428         free_CSWIFT_LIBNAME();
429         if(cswift_dso == NULL)
430                 {
431                 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
432                 return 0;
433                 }
434         if(!DSO_free(cswift_dso))
435                 {
436                 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
437                 return 0;
438                 }
439         cswift_dso = NULL;
440         p_CSwift_AcquireAccContext = NULL;
441         p_CSwift_AttachKeyParam = NULL;
442         p_CSwift_SimpleRequest = NULL;
443         p_CSwift_ReleaseAccContext = NULL;
444         return 1;
445         }
446
447 static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
448         {
449         int initialised = ((cswift_dso == NULL) ? 0 : 1);
450         switch(cmd)
451                 {
452         case CSWIFT_CMD_SO_PATH:
453                 if(p == NULL)
454                         {
455                         CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
456                         return 0;
457                         }
458                 if(initialised)
459                         {
460                         CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
461                         return 0;
462                         }
463                 return set_CSWIFT_LIBNAME((const char *)p);
464         default:
465                 break;
466                 }
467         CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
468         return 0;
469         }
470
471 /* Un petit mod_exp */
472 static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
473                         const BIGNUM *m, BN_CTX *ctx)
474         {
475         /* I need somewhere to store temporary serialised values for
476          * use with the CryptoSwift API calls. A neat cheat - I'll use
477          * BIGNUMs from the BN_CTX but access their arrays directly as
478          * byte arrays <grin>. This way I don't have to clean anything
479          * up. */
480         BIGNUM *modulus;
481         BIGNUM *exponent;
482         BIGNUM *argument;
483         BIGNUM *result;
484         SW_STATUS sw_status;
485         SW_LARGENUMBER arg, res;
486         SW_PARAM sw_param;
487         SW_CONTEXT_HANDLE hac;
488         int to_return, acquired;
489  
490         modulus = exponent = argument = result = NULL;
491         to_return = 0; /* expect failure */
492         acquired = 0;
493  
494         if(!get_context(&hac))
495                 {
496                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
497                 goto err;
498                 }
499         acquired = 1;
500         /* Prepare the params */
501         BN_CTX_start(ctx);
502         modulus = BN_CTX_get(ctx);
503         exponent = BN_CTX_get(ctx);
504         argument = BN_CTX_get(ctx);
505         result = BN_CTX_get(ctx);
506         if(!result)
507                 {
508                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
509                 goto err;
510                 }
511         if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
512                 !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
513                 {
514                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
515                 goto err;
516                 }
517         sw_param.type = SW_ALG_EXP;
518         sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
519                 (unsigned char *)modulus->d);
520         sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
521         sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
522                 (unsigned char *)exponent->d);
523         sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
524         /* Attach the key params */
525         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
526         switch(sw_status)
527                 {
528         case SW_OK:
529                 break;
530         case SW_ERR_INPUT_SIZE:
531                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
532                 goto err;
533         default:
534                 {
535                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
536                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
537                 sprintf(tmpbuf, "%ld", sw_status);
538                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
539                 }
540                 goto err;
541                 }
542         /* Prepare the argument and response */
543         arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
544         arg.value = (unsigned char *)argument->d;
545         res.nbytes = BN_num_bytes(m);
546         memset(result->d, 0, res.nbytes);
547         res.value = (unsigned char *)result->d;
548         /* Perform the operation */
549         if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
550                 &res, 1)) != SW_OK)
551                 {
552                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
553                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
554                 sprintf(tmpbuf, "%ld", sw_status);
555                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
556                 goto err;
557                 }
558         /* Convert the response */
559         BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
560         to_return = 1;
561 err:
562         if(acquired)
563                 release_context(hac);
564         BN_CTX_end(ctx);
565         return to_return;
566         }
567
568 /* Un petit mod_exp chinois */
569 static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
570                         const BIGNUM *q, const BIGNUM *dmp1,
571                         const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
572         {
573         SW_STATUS sw_status;
574         SW_LARGENUMBER arg, res;
575         SW_PARAM sw_param;
576         SW_CONTEXT_HANDLE hac;
577         BIGNUM *rsa_p = NULL;
578         BIGNUM *rsa_q = NULL;
579         BIGNUM *rsa_dmp1 = NULL;
580         BIGNUM *rsa_dmq1 = NULL;
581         BIGNUM *rsa_iqmp = NULL;
582         BIGNUM *argument = NULL;
583         BIGNUM *result = NULL;
584         int to_return = 0; /* expect failure */
585         int acquired = 0;
586  
587         if(!get_context(&hac))
588                 {
589                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
590                 goto err;
591                 }
592         acquired = 1;
593         /* Prepare the params */
594         BN_CTX_start(ctx);
595         rsa_p = BN_CTX_get(ctx);
596         rsa_q = BN_CTX_get(ctx);
597         rsa_dmp1 = BN_CTX_get(ctx);
598         rsa_dmq1 = BN_CTX_get(ctx);
599         rsa_iqmp = BN_CTX_get(ctx);
600         argument = BN_CTX_get(ctx);
601         result = BN_CTX_get(ctx);
602         if(!result)
603                 {
604                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
605                 goto err;
606                 }
607         if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) ||
608                         !bn_wexpand(rsa_dmp1, dmp1->top) ||
609                         !bn_wexpand(rsa_dmq1, dmq1->top) ||
610                         !bn_wexpand(rsa_iqmp, iqmp->top) ||
611                         !bn_wexpand(argument, a->top) ||
612                         !bn_wexpand(result, p->top + q->top))
613                 {
614                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
615                 goto err;
616                 }
617         sw_param.type = SW_ALG_CRT;
618         sw_param.up.crt.p.nbytes = BN_bn2bin(p, (unsigned char *)rsa_p->d);
619         sw_param.up.crt.p.value = (unsigned char *)rsa_p->d;
620         sw_param.up.crt.q.nbytes = BN_bn2bin(q, (unsigned char *)rsa_q->d);
621         sw_param.up.crt.q.value = (unsigned char *)rsa_q->d;
622         sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1,
623                 (unsigned char *)rsa_dmp1->d);
624         sw_param.up.crt.dmp1.value = (unsigned char *)rsa_dmp1->d;
625         sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1,
626                 (unsigned char *)rsa_dmq1->d);
627         sw_param.up.crt.dmq1.value = (unsigned char *)rsa_dmq1->d;
628         sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp,
629                 (unsigned char *)rsa_iqmp->d);
630         sw_param.up.crt.iqmp.value = (unsigned char *)rsa_iqmp->d;
631         /* Attach the key params */
632         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
633         switch(sw_status)
634                 {
635         case SW_OK:
636                 break;
637         case SW_ERR_INPUT_SIZE:
638                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
639                 goto err;
640         default:
641                 {
642                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
643                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
644                 sprintf(tmpbuf, "%ld", sw_status);
645                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
646                 }
647                 goto err;
648                 }
649         /* Prepare the argument and response */
650         arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
651         arg.value = (unsigned char *)argument->d;
652         res.nbytes = 2 * BN_num_bytes(p);
653         memset(result->d, 0, res.nbytes);
654         res.value = (unsigned char *)result->d;
655         /* Perform the operation */
656         if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
657                 &res, 1)) != SW_OK)
658                 {
659                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
660                 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
661                 sprintf(tmpbuf, "%ld", sw_status);
662                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
663                 goto err;
664                 }
665         /* Convert the response */
666         BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
667         to_return = 1;
668 err:
669         if(acquired)
670                 release_context(hac);
671         BN_CTX_end(ctx);
672         return to_return;
673         }
674  
675 #ifndef OPENSSL_NO_RSA
676 static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
677         {
678         int to_return = 0;
679
680         if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
681                 {
682                 CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
683                 goto err;
684                 }
685         to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
686                 rsa->dmq1, rsa->iqmp, ctx);
687 err:
688         return to_return;
689         }
690 #endif
691
692 /* This function is aliased to mod_exp (with the mont stuff dropped). */
693 static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
694                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
695         {
696         return cswift_mod_exp(r, a, p, m, ctx);
697         }
698
699 #ifndef OPENSSL_NO_DSA
700 static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
701         {
702         SW_CONTEXT_HANDLE hac;
703         SW_PARAM sw_param;
704         SW_STATUS sw_status;
705         SW_LARGENUMBER arg, res;
706         unsigned char *ptr;
707         BN_CTX *ctx;
708         BIGNUM *dsa_p = NULL;
709         BIGNUM *dsa_q = NULL;
710         BIGNUM *dsa_g = NULL;
711         BIGNUM *dsa_key = NULL;
712         BIGNUM *result = NULL;
713         DSA_SIG *to_return = NULL;
714         int acquired = 0;
715
716         if((ctx = BN_CTX_new()) == NULL)
717                 goto err;
718         if(!get_context(&hac))
719                 {
720                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
721                 goto err;
722                 }
723         acquired = 1;
724         /* Prepare the params */
725         BN_CTX_start(ctx);
726         dsa_p = BN_CTX_get(ctx);
727         dsa_q = BN_CTX_get(ctx);
728         dsa_g = BN_CTX_get(ctx);
729         dsa_key = BN_CTX_get(ctx);
730         result = BN_CTX_get(ctx);
731         if(!result)
732                 {
733                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
734                 goto err;
735                 }
736         if(!bn_wexpand(dsa_p, dsa->p->top) ||
737                         !bn_wexpand(dsa_q, dsa->q->top) ||
738                         !bn_wexpand(dsa_g, dsa->g->top) ||
739                         !bn_wexpand(dsa_key, dsa->priv_key->top) ||
740                         !bn_wexpand(result, dsa->p->top))
741                 {
742                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
743                 goto err;
744                 }
745         sw_param.type = SW_ALG_DSA;
746         sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
747                                 (unsigned char *)dsa_p->d);
748         sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
749         sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
750                                 (unsigned char *)dsa_q->d);
751         sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
752         sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
753                                 (unsigned char *)dsa_g->d);
754         sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
755         sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
756                                 (unsigned char *)dsa_key->d);
757         sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
758         /* Attach the key params */
759         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
760         switch(sw_status)
761                 {
762         case SW_OK:
763                 break;
764         case SW_ERR_INPUT_SIZE:
765                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
766                 goto err;
767         default:
768                 {
769                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
770                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
771                 sprintf(tmpbuf, "%ld", sw_status);
772                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
773                 }
774                 goto err;
775                 }
776         /* Prepare the argument and response */
777         arg.nbytes = dlen;
778         arg.value = (unsigned char *)dgst;
779         res.nbytes = BN_num_bytes(dsa->p);
780         memset(result->d, 0, res.nbytes);
781         res.value = (unsigned char *)result->d;
782         /* Perform the operation */
783         sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
784                 &res, 1);
785         if(sw_status != SW_OK)
786                 {
787                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
788                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
789                 sprintf(tmpbuf, "%ld", sw_status);
790                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
791                 goto err;
792                 }
793         /* Convert the response */
794         ptr = (unsigned char *)result->d;
795         if((to_return = DSA_SIG_new()) == NULL)
796                 goto err;
797         to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
798         to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
799
800 err:
801         if(acquired)
802                 release_context(hac);
803         if(ctx)
804                 {
805                 BN_CTX_end(ctx);
806                 BN_CTX_free(ctx);
807                 }
808         return to_return;
809         }
810
811 static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
812                                 DSA_SIG *sig, DSA *dsa)
813         {
814         SW_CONTEXT_HANDLE hac;
815         SW_PARAM sw_param;
816         SW_STATUS sw_status;
817         SW_LARGENUMBER arg[2], res;
818         unsigned long sig_result;
819         BN_CTX *ctx;
820         BIGNUM *dsa_p = NULL;
821         BIGNUM *dsa_q = NULL;
822         BIGNUM *dsa_g = NULL;
823         BIGNUM *dsa_key = NULL;
824         BIGNUM *argument = NULL;
825         int to_return = -1;
826         int acquired = 0;
827
828         if((ctx = BN_CTX_new()) == NULL)
829                 goto err;
830         if(!get_context(&hac))
831                 {
832                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
833                 goto err;
834                 }
835         acquired = 1;
836         /* Prepare the params */
837         BN_CTX_start(ctx);
838         dsa_p = BN_CTX_get(ctx);
839         dsa_q = BN_CTX_get(ctx);
840         dsa_g = BN_CTX_get(ctx);
841         dsa_key = BN_CTX_get(ctx);
842         argument = BN_CTX_get(ctx);
843         if(!argument)
844                 {
845                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
846                 goto err;
847                 }
848         if(!bn_wexpand(dsa_p, dsa->p->top) ||
849                         !bn_wexpand(dsa_q, dsa->q->top) ||
850                         !bn_wexpand(dsa_g, dsa->g->top) ||
851                         !bn_wexpand(dsa_key, dsa->pub_key->top) ||
852                         !bn_wexpand(argument, 40))
853                 {
854                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
855                 goto err;
856                 }
857         sw_param.type = SW_ALG_DSA;
858         sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
859                                 (unsigned char *)dsa_p->d);
860         sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
861         sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
862                                 (unsigned char *)dsa_q->d);
863         sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
864         sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
865                                 (unsigned char *)dsa_g->d);
866         sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
867         sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
868                                 (unsigned char *)dsa_key->d);
869         sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
870         /* Attach the key params */
871         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
872         switch(sw_status)
873                 {
874         case SW_OK:
875                 break;
876         case SW_ERR_INPUT_SIZE:
877                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
878                 goto err;
879         default:
880                 {
881                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
882                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
883                 sprintf(tmpbuf, "%ld", sw_status);
884                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
885                 }
886                 goto err;
887                 }
888         /* Prepare the argument and response */
889         arg[0].nbytes = dgst_len;
890         arg[0].value = (unsigned char *)dgst;
891         arg[1].nbytes = 40;
892         arg[1].value = (unsigned char *)argument->d;
893         memset(arg[1].value, 0, 40);
894         BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
895         BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
896         res.nbytes = 4; /* unsigned long */
897         res.value = (unsigned char *)(&sig_result);
898         /* Perform the operation */
899         sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
900                 &res, 1);
901         if(sw_status != SW_OK)
902                 {
903                 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
904                 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
905                 sprintf(tmpbuf, "%ld", sw_status);
906                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
907                 goto err;
908                 }
909         /* Convert the response */
910         to_return = ((sig_result == 0) ? 0 : 1);
911
912 err:
913         if(acquired)
914                 release_context(hac);
915         if(ctx)
916                 {
917                 BN_CTX_end(ctx);
918                 BN_CTX_free(ctx);
919                 }
920         return to_return;
921         }
922 #endif
923
924 #ifndef OPENSSL_NO_DH
925 /* This function is aliased to mod_exp (with the dh and mont dropped). */
926 static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
927                 const BIGNUM *a, const BIGNUM *p,
928                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
929         {
930         return cswift_mod_exp(r, a, p, m, ctx);
931         }
932 #endif
933
934 /* Random bytes are good */
935 static int cswift_rand_bytes(unsigned char *buf, int num)
936 {
937         SW_CONTEXT_HANDLE hac;
938         SW_STATUS swrc;
939         SW_LARGENUMBER largenum;
940         size_t nbytes = 0;
941         int acquired = 0;
942         int to_return = 0; /* assume failure */
943
944         if (!get_context(&hac))
945         {
946                 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_UNIT_FAILURE);
947                 goto err;
948         }
949         acquired = 1;
950
951         while (nbytes < (size_t)num)
952         {
953                 /* tell CryptoSwift how many bytes we want and where we want it.
954                  * Note: - CryptoSwift cannot do more than 4096 bytes at a time.
955                  *       - CryptoSwift can only do multiple of 32-bits. */
956                 largenum.value = (SW_BYTE *) buf + nbytes;
957                 if (4096 > num - nbytes)
958                         largenum.nbytes = num - nbytes;
959                 else
960                         largenum.nbytes = 4096;
961
962                 swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
963                 if (swrc != SW_OK)
964                 {
965                         char tmpbuf[20];
966                         CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_REQUEST_FAILED);
967                         sprintf(tmpbuf, "%ld", swrc);
968                         ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
969                         goto err;
970                 }
971
972                 nbytes += largenum.nbytes;
973         }
974         to_return = 1;  /* success */
975
976 err:
977         if (acquired)
978                 release_context(hac);
979         return to_return;
980 }
981
982 static int cswift_rand_status(void)
983 {
984         return 1;
985 }
986
987
988 /* This stuff is needed if this ENGINE is being compiled into a self-contained
989  * shared-library. */
990 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
991 static int bind_fn(ENGINE *e, const char *id)
992         {
993         if(id && (strcmp(id, engine_cswift_id) != 0))
994                 return 0;
995         if(!bind_helper(e))
996                 return 0;
997         return 1;
998         }       
999 IMPLEMENT_DYNAMIC_CHECK_FN()
1000 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1001 #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
1002
1003 #endif /* !OPENSSL_NO_HW_CSWIFT */
1004 #endif /* !OPENSSL_NO_HW */