cc723ac08ee5e87b1dd94bb8c3ed2faa142dc93c
[openssl.git] / crypto / engine / hw_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 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 <openssl/crypto.h>
61 #include "cryptlib.h"
62 #include <openssl/dso.h>
63 #include "engine_int.h"
64 #include <openssl/engine.h>
65
66 #ifndef NO_HW
67 #ifndef 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 static int cswift_init(void);
88 static int cswift_finish(void);
89
90 /* BIGNUM stuff */
91 static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
92                 const BIGNUM *m, BN_CTX *ctx);
93 static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
94                 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
95                 const BIGNUM *iqmp, BN_CTX *ctx);
96
97 /* RSA stuff */
98 static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
99 /* This function is aliased to mod_exp (with the mont stuff dropped). */
100 static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
101                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
102
103 /* DSA stuff */
104 static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
105 static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
106                                 DSA_SIG *sig, DSA *dsa);
107
108 /* DH stuff */
109 /* This function is alised to mod_exp (with the DH and mont dropped). */
110 static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
111                 const BIGNUM *a, const BIGNUM *p,
112                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
113
114
115 /* Our internal RSA_METHOD that we provide pointers to */
116 static RSA_METHOD cswift_rsa =
117         {
118         "CryptoSwift RSA method",
119         NULL,
120         NULL,
121         NULL,
122         NULL,
123         cswift_rsa_mod_exp,
124         cswift_mod_exp_mont,
125         NULL,
126         NULL,
127         0,
128         NULL,
129         NULL,
130         NULL
131         };
132
133 /* Our internal DSA_METHOD that we provide pointers to */
134 static DSA_METHOD cswift_dsa =
135         {
136         "CryptoSwift DSA method",
137         cswift_dsa_sign,
138         NULL, /* dsa_sign_setup */
139         cswift_dsa_verify,
140         NULL, /* dsa_mod_exp */
141         NULL, /* bn_mod_exp */
142         NULL, /* init */
143         NULL, /* finish */
144         0, /* flags */
145         NULL /* app_data */
146         };
147
148 /* Our internal DH_METHOD that we provide pointers to */
149 static DH_METHOD cswift_dh =
150         {
151         "CryptoSwift DH method",
152         NULL,
153         NULL,
154         cswift_mod_exp_dh,
155         NULL,
156         NULL,
157         0,
158         NULL
159         };
160
161 /* Our ENGINE structure. */
162 static ENGINE engine_cswift =
163         {
164         "cswift",
165         "CryptoSwift hardware engine support",
166         &cswift_rsa,
167         &cswift_dsa,
168         &cswift_dh,
169         NULL,
170         cswift_mod_exp,
171         cswift_mod_exp_crt,
172         cswift_init,
173         cswift_finish,
174         NULL, /* no ctrl() */
175         NULL, /* no load_privkey() */
176         NULL, /* no load_pubkey() */
177         0, /* no flags */
178         0, 0, /* no references */
179         NULL, NULL /* unlinked */
180         };
181
182 /* As this is only ever called once, there's no need for locking
183  * (indeed - the lock will already be held by our caller!!!) */
184 ENGINE *ENGINE_cswift()
185         {
186         const RSA_METHOD *meth1;
187         const DH_METHOD *meth2;
188
189         /* We know that the "PKCS1_SSLeay()" functions hook properly
190          * to the cswift-specific mod_exp and mod_exp_crt so we use
191          * those functions. NB: We don't use ENGINE_openssl() or
192          * anything "more generic" because something like the RSAref
193          * code may not hook properly, and if you own one of these
194          * cards then you have the right to do RSA operations on it
195          * anyway! */ 
196         meth1 = RSA_PKCS1_SSLeay();
197         cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
198         cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
199         cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
200         cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
201
202         /* Much the same for Diffie-Hellman */
203         meth2 = DH_OpenSSL();
204         cswift_dh.generate_key = meth2->generate_key;
205         cswift_dh.compute_key = meth2->compute_key;
206         return &engine_cswift;
207         }
208
209 /* This is a process-global DSO handle used for loading and unloading
210  * the CryptoSwift library. NB: This is only set (or unset) during an
211  * init() or finish() call (reference counts permitting) and they're
212  * operating with global locks, so this should be thread-safe
213  * implicitly. */
214 static DSO *cswift_dso = NULL;
215
216 /* These are the function pointers that are (un)set when the library has
217  * successfully (un)loaded. */
218 t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
219 t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
220 t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
221 t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
222
223 /* Used in the DSO operations. */
224 static const char *CSWIFT_LIBNAME = "swift";
225 static const char *CSWIFT_F1 = "swAcquireAccContext";
226 static const char *CSWIFT_F2 = "swAttachKeyParam";
227 static const char *CSWIFT_F3 = "swSimpleRequest";
228 static const char *CSWIFT_F4 = "swReleaseAccContext";
229
230
231 /* CryptoSwift library functions and mechanics - these are used by the
232  * higher-level functions further down. NB: As and where there's no
233  * error checking, take a look lower down where these functions are
234  * called, the checking and error handling is probably down there. */
235
236 /* utility function to obtain a context */
237 static int get_context(SW_CONTEXT_HANDLE *hac)
238         {
239         SW_STATUS status;
240  
241         status = p_CSwift_AcquireAccContext(hac);
242         if(status != SW_OK)
243                 return 0;
244         return 1;
245         }
246  
247 /* similarly to release one. */
248 static void release_context(SW_CONTEXT_HANDLE hac)
249         {
250         p_CSwift_ReleaseAccContext(hac);
251         }
252
253 /* (de)initialisation functions. */
254 static int cswift_init()
255         {
256         SW_CONTEXT_HANDLE hac;
257         t_swAcquireAccContext *p1;
258         t_swAttachKeyParam *p2;
259         t_swSimpleRequest *p3;
260         t_swReleaseAccContext *p4;
261
262         if(cswift_dso != NULL)
263                 {
264                 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_ALREADY_LOADED);
265                 goto err;
266                 }
267         /* Attempt to load libswift.so/swift.dll/whatever. */
268         cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL, 0);
269         if(cswift_dso == NULL)
270                 {
271                 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE);
272                 goto err;
273                 }
274         if(!(p1 = (t_swAcquireAccContext *)
275                                 DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
276                         !(p2 = (t_swAttachKeyParam *)
277                                 DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
278                         !(p3 = (t_swSimpleRequest *)
279                                 DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
280                         !(p4 = (t_swReleaseAccContext *)
281                                 DSO_bind_func(cswift_dso, CSWIFT_F4)))
282                 {
283                 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE);
284                 goto err;
285                 }
286         /* Copy the pointers */
287         p_CSwift_AcquireAccContext = p1;
288         p_CSwift_AttachKeyParam = p2;
289         p_CSwift_SimpleRequest = p3;
290         p_CSwift_ReleaseAccContext = p4;
291         /* Try and get a context - if not, we may have a DSO but no
292          * accelerator! */
293         if(!get_context(&hac))
294                 {
295                 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_UNIT_FAILURE);
296                 goto err;
297                 }
298         release_context(hac);
299         /* Everything's fine. */
300         return 1;
301 err:
302         if(cswift_dso)
303                 DSO_free(cswift_dso);
304         p_CSwift_AcquireAccContext = NULL;
305         p_CSwift_AttachKeyParam = NULL;
306         p_CSwift_SimpleRequest = NULL;
307         p_CSwift_ReleaseAccContext = NULL;
308         return 0;
309         }
310
311 static int cswift_finish()
312         {
313         if(cswift_dso == NULL)
314                 {
315                 ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_NOT_LOADED);
316                 return 0;
317                 }
318         if(!DSO_free(cswift_dso))
319                 {
320                 ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_DSO_FAILURE);
321                 return 0;
322                 }
323         cswift_dso = NULL;
324         p_CSwift_AcquireAccContext = NULL;
325         p_CSwift_AttachKeyParam = NULL;
326         p_CSwift_SimpleRequest = NULL;
327         p_CSwift_ReleaseAccContext = NULL;
328         return 1;
329         }
330
331 /* Un petit mod_exp */
332 static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
333                         const BIGNUM *m, BN_CTX *ctx)
334         {
335         /* I need somewhere to store temporary serialised values for
336          * use with the CryptoSwift API calls. A neat cheat - I'll use
337          * BIGNUMs from the BN_CTX but access their arrays directly as
338          * byte arrays <grin>. This way I don't have to clean anything
339          * up. */
340         BIGNUM *modulus;
341         BIGNUM *exponent;
342         BIGNUM *argument;
343         BIGNUM *result;
344         SW_STATUS sw_status;
345         SW_LARGENUMBER arg, res;
346         SW_PARAM sw_param;
347         SW_CONTEXT_HANDLE hac;
348         int to_return, acquired;
349  
350         modulus = exponent = argument = result = NULL;
351         to_return = 0; /* expect failure */
352         acquired = 0;
353  
354         if(!get_context(&hac))
355                 {
356                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_GET_HANDLE_FAILED);
357                 goto err;
358                 }
359         acquired = 1;
360         /* Prepare the params */
361         modulus = BN_CTX_get(ctx);
362         exponent = BN_CTX_get(ctx);
363         argument = BN_CTX_get(ctx);
364         result = BN_CTX_get(ctx);
365         if(!modulus || !exponent || !argument || !result)
366                 {
367                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_CTX_FULL);
368                 goto err;
369                 }
370         if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
371                 !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
372                 {
373                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL);
374                 goto err;
375                 }
376         sw_param.type = SW_ALG_EXP;
377         sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
378                 (unsigned char *)modulus->d);
379         sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
380         sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
381                 (unsigned char *)exponent->d);
382         sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
383         /* Attach the key params */
384         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
385         switch(sw_status)
386                 {
387         case SW_OK:
388                 break;
389         case SW_ERR_INPUT_SIZE:
390                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,
391                         ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
392                 goto err;
393         default:
394                 {
395                 char tmpbuf[20];
396                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED);
397                 sprintf(tmpbuf, "%ld", sw_status);
398                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
399                 }
400                 goto err;
401                 }
402         /* Prepare the argument and response */
403         arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
404         arg.value = (unsigned char *)argument->d;
405         res.nbytes = BN_num_bytes(m);
406         memset(result->d, 0, res.nbytes);
407         res.value = (unsigned char *)result->d;
408         /* Perform the operation */
409         if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
410                 &res, 1)) != SW_OK)
411                 {
412                 char tmpbuf[20];
413                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED);
414                 sprintf(tmpbuf, "%ld", sw_status);
415                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
416                 goto err;
417                 }
418         /* Convert the response */
419         BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
420         to_return = 1;
421 err:
422         if(acquired)
423                 release_context(hac);
424         if(modulus) ctx->tos--;
425         if(exponent) ctx->tos--;
426         if(argument) ctx->tos--;
427         if(result) ctx->tos--;
428         return to_return;
429         }
430
431 /* Un petit mod_exp chinois */
432 static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
433                         const BIGNUM *q, const BIGNUM *dmp1,
434                         const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
435         {
436         SW_STATUS sw_status;
437         SW_LARGENUMBER arg, res;
438         SW_PARAM sw_param;
439         SW_CONTEXT_HANDLE hac;
440         BIGNUM *rsa_p = NULL;
441         BIGNUM *rsa_q = NULL;
442         BIGNUM *rsa_dmp1 = NULL;
443         BIGNUM *rsa_dmq1 = NULL;
444         BIGNUM *rsa_iqmp = NULL;
445         BIGNUM *argument = NULL;
446         BIGNUM *result = NULL;
447         int to_return = 0; /* expect failure */
448         int acquired = 0;
449  
450         if(!get_context(&hac))
451                 {
452                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_GET_HANDLE_FAILED);
453                 goto err;
454                 }
455         acquired = 1;
456         /* Prepare the params */
457         rsa_p = BN_CTX_get(ctx);
458         rsa_q = BN_CTX_get(ctx);
459         rsa_dmp1 = BN_CTX_get(ctx);
460         rsa_dmq1 = BN_CTX_get(ctx);
461         rsa_iqmp = BN_CTX_get(ctx);
462         argument = BN_CTX_get(ctx);
463         result = BN_CTX_get(ctx);
464         if(!rsa_p || !rsa_q || !rsa_dmp1 || !rsa_dmq1 || !rsa_iqmp ||
465                         !argument || !result)
466                 {
467                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_CTX_FULL);
468                 goto err;
469                 }
470         if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) ||
471                         !bn_wexpand(rsa_dmp1, dmp1->top) ||
472                         !bn_wexpand(rsa_dmq1, dmq1->top) ||
473                         !bn_wexpand(rsa_iqmp, iqmp->top) ||
474                         !bn_wexpand(argument, a->top) ||
475                         !bn_wexpand(result, p->top + q->top))
476                 {
477                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_EXPAND_FAIL);
478                 goto err;
479                 }
480         sw_param.type = SW_ALG_CRT;
481         sw_param.up.crt.p.nbytes = BN_bn2bin(p, (unsigned char *)rsa_p->d);
482         sw_param.up.crt.p.value = (unsigned char *)rsa_p->d;
483         sw_param.up.crt.q.nbytes = BN_bn2bin(q, (unsigned char *)rsa_q->d);
484         sw_param.up.crt.q.value = (unsigned char *)rsa_q->d;
485         sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1,
486                 (unsigned char *)rsa_dmp1->d);
487         sw_param.up.crt.dmp1.value = (unsigned char *)rsa_dmp1->d;
488         sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1,
489                 (unsigned char *)rsa_dmq1->d);
490         sw_param.up.crt.dmq1.value = (unsigned char *)rsa_dmq1->d;
491         sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp,
492                 (unsigned char *)rsa_iqmp->d);
493         sw_param.up.crt.iqmp.value = (unsigned char *)rsa_iqmp->d;
494         /* Attach the key params */
495         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
496         switch(sw_status)
497                 {
498         case SW_OK:
499                 break;
500         case SW_ERR_INPUT_SIZE:
501                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,
502                         ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
503                 goto err;
504         default:
505                 {
506                 char tmpbuf[20];
507                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED);
508                 sprintf(tmpbuf, "%ld", sw_status);
509                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
510                 }
511                 goto err;
512                 }
513         /* Prepare the argument and response */
514         arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
515         arg.value = (unsigned char *)argument->d;
516         res.nbytes = 2 * BN_num_bytes(p);
517         memset(result->d, 0, res.nbytes);
518         res.value = (unsigned char *)result->d;
519         /* Perform the operation */
520         if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
521                 &res, 1)) != SW_OK)
522                 {
523                 char tmpbuf[20];
524                 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED);
525                 sprintf(tmpbuf, "%ld", sw_status);
526                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
527                 goto err;
528                 }
529         /* Convert the response */
530         BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
531         to_return = 1;
532 err:
533         if(acquired)
534                 release_context(hac);
535         if(rsa_p) ctx->tos--;
536         if(rsa_q) ctx->tos--;
537         if(rsa_dmp1) ctx->tos--;
538         if(rsa_dmq1) ctx->tos--;
539         if(rsa_iqmp) ctx->tos--;
540         if(argument) ctx->tos--;
541         if(result) ctx->tos--;
542         return to_return;
543         }
544  
545 static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
546         {
547         BN_CTX *ctx;
548         int to_return = 0;
549
550         if((ctx = BN_CTX_new()) == NULL)
551                 goto err;
552         if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
553                 {
554                 ENGINEerr(ENGINE_F_CSWIFT_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS);
555                 goto err;
556                 }
557         to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
558                 rsa->dmq1, rsa->iqmp, ctx);
559 err:
560         if(ctx)
561                 BN_CTX_free(ctx);
562         return to_return;
563         }
564
565 /* This function is aliased to mod_exp (with the mont stuff dropped). */
566 static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
567                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
568         {
569         return cswift_mod_exp(r, a, p, m, ctx);
570         }
571
572 static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
573         {
574         SW_CONTEXT_HANDLE hac;
575         SW_PARAM sw_param;
576         SW_STATUS sw_status;
577         SW_LARGENUMBER arg, res;
578         unsigned char *ptr;
579         BN_CTX *ctx;
580         BIGNUM *dsa_p = NULL;
581         BIGNUM *dsa_q = NULL;
582         BIGNUM *dsa_g = NULL;
583         BIGNUM *dsa_key = NULL;
584         BIGNUM *result = NULL;
585         DSA_SIG *to_return = NULL;
586         int acquired = 0;
587
588         if((ctx = BN_CTX_new()) == NULL)
589                 goto err;
590         if(!get_context(&hac))
591                 {
592                 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_GET_HANDLE_FAILED);
593                 goto err;
594                 }
595         acquired = 1;
596         /* Prepare the params */
597         dsa_p = BN_CTX_get(ctx);
598         dsa_q = BN_CTX_get(ctx);
599         dsa_g = BN_CTX_get(ctx);
600         dsa_key = BN_CTX_get(ctx);
601         result = BN_CTX_get(ctx);
602         if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !result)
603                 {
604                 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_CTX_FULL);
605                 goto err;
606                 }
607         if(!bn_wexpand(dsa_p, dsa->p->top) ||
608                         !bn_wexpand(dsa_q, dsa->q->top) ||
609                         !bn_wexpand(dsa_g, dsa->g->top) ||
610                         !bn_wexpand(dsa_key, dsa->priv_key->top) ||
611                         !bn_wexpand(result, dsa->p->top))
612                 {
613                 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_EXPAND_FAIL);
614                 goto err;
615                 }
616         sw_param.type = SW_ALG_DSA;
617         sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
618                                 (unsigned char *)dsa_p->d);
619         sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
620         sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
621                                 (unsigned char *)dsa_q->d);
622         sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
623         sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
624                                 (unsigned char *)dsa_g->d);
625         sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
626         sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
627                                 (unsigned char *)dsa_key->d);
628         sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
629         /* Attach the key params */
630         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
631         switch(sw_status)
632                 {
633         case SW_OK:
634                 break;
635         case SW_ERR_INPUT_SIZE:
636                 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,
637                         ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
638                 goto err;
639         default:
640                 {
641                 char tmpbuf[20];
642                 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED);
643                 sprintf(tmpbuf, "%ld", sw_status);
644                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
645                 }
646                 goto err;
647                 }
648         /* Prepare the argument and response */
649         arg.nbytes = dlen;
650         arg.value = (unsigned char *)dgst;
651         res.nbytes = BN_num_bytes(dsa->p);
652         memset(result->d, 0, res.nbytes);
653         res.value = (unsigned char *)result->d;
654         /* Perform the operation */
655         sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
656                 &res, 1);
657         if(sw_status != SW_OK)
658                 {
659                 char tmpbuf[20];
660                 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_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         ptr = (unsigned char *)result->d;
667         if((to_return = DSA_SIG_new()) == NULL)
668                 goto err;
669         to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
670         to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
671
672 err:
673         if(acquired)
674                 release_context(hac);
675         if(dsa_p) ctx->tos--;
676         if(dsa_q) ctx->tos--;
677         if(dsa_g) ctx->tos--;
678         if(dsa_key) ctx->tos--;
679         if(result) ctx->tos--;
680         if(ctx)
681                 BN_CTX_free(ctx);
682         return to_return;
683         }
684
685 static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
686                                 DSA_SIG *sig, DSA *dsa)
687         {
688         SW_CONTEXT_HANDLE hac;
689         SW_PARAM sw_param;
690         SW_STATUS sw_status;
691         SW_LARGENUMBER arg[2], res;
692         unsigned long sig_result;
693         BN_CTX *ctx;
694         BIGNUM *dsa_p = NULL;
695         BIGNUM *dsa_q = NULL;
696         BIGNUM *dsa_g = NULL;
697         BIGNUM *dsa_key = NULL;
698         BIGNUM *argument = NULL;
699         int to_return = -1;
700         int acquired = 0;
701
702         if((ctx = BN_CTX_new()) == NULL)
703                 goto err;
704         if(!get_context(&hac))
705                 {
706                 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_GET_HANDLE_FAILED);
707                 goto err;
708                 }
709         acquired = 1;
710         /* Prepare the params */
711         dsa_p = BN_CTX_get(ctx);
712         dsa_q = BN_CTX_get(ctx);
713         dsa_g = BN_CTX_get(ctx);
714         dsa_key = BN_CTX_get(ctx);
715         argument = BN_CTX_get(ctx);
716         if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !argument)
717                 {
718                 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_CTX_FULL);
719                 goto err;
720                 }
721         if(!bn_wexpand(dsa_p, dsa->p->top) ||
722                         !bn_wexpand(dsa_q, dsa->q->top) ||
723                         !bn_wexpand(dsa_g, dsa->g->top) ||
724                         !bn_wexpand(dsa_key, dsa->pub_key->top) ||
725                         !bn_wexpand(argument, 40))
726                 {
727                 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_EXPAND_FAIL);
728                 goto err;
729                 }
730         sw_param.type = SW_ALG_DSA;
731         sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
732                                 (unsigned char *)dsa_p->d);
733         sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
734         sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
735                                 (unsigned char *)dsa_q->d);
736         sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
737         sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
738                                 (unsigned char *)dsa_g->d);
739         sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
740         sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
741                                 (unsigned char *)dsa_key->d);
742         sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
743         /* Attach the key params */
744         sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
745         switch(sw_status)
746                 {
747         case SW_OK:
748                 break;
749         case SW_ERR_INPUT_SIZE:
750                 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,
751                         ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
752                 goto err;
753         default:
754                 {
755                 char tmpbuf[20];
756                 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED);
757                 sprintf(tmpbuf, "%ld", sw_status);
758                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
759                 }
760                 goto err;
761                 }
762         /* Prepare the argument and response */
763         arg[0].nbytes = dgst_len;
764         arg[0].value = (unsigned char *)dgst;
765         arg[1].nbytes = 40;
766         arg[1].value = (unsigned char *)argument->d;
767         memset(arg[1].value, 0, 40);
768         BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
769         BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
770         res.nbytes = 4; /* unsigned long */
771         res.value = (unsigned char *)(&sig_result);
772         /* Perform the operation */
773         sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
774                 &res, 1);
775         if(sw_status != SW_OK)
776                 {
777                 char tmpbuf[20];
778                 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED);
779                 sprintf(tmpbuf, "%ld", sw_status);
780                 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
781                 goto err;
782                 }
783         /* Convert the response */
784         to_return = ((sig_result == 0) ? 0 : 1);
785
786 err:
787         if(acquired)
788                 release_context(hac);
789         if(dsa_p) ctx->tos--;
790         if(dsa_q) ctx->tos--;
791         if(dsa_g) ctx->tos--;
792         if(dsa_key) ctx->tos--;
793         if(argument) ctx->tos--;
794         if(ctx)
795                 BN_CTX_free(ctx);
796         return to_return;
797         }
798
799 /* This function is aliased to mod_exp (with the dh and mont dropped). */
800 static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
801                 const BIGNUM *a, const BIGNUM *p,
802                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
803         {
804         return cswift_mod_exp(r, a, p, m, ctx);
805         }
806
807 #endif /* !NO_HW_CSWIFT */
808 #endif /* !NO_HW */