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