e_cswift.c revision 160815
155682Smarkm/* crypto/engine/hw_cswift.c */
2233294Sstas/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3233294Sstas * project 2000.
4233294Sstas */
555682Smarkm/* ====================================================================
6233294Sstas * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
7233294Sstas *
8233294Sstas * Redistribution and use in source and binary forms, with or without
955682Smarkm * modification, are permitted provided that the following conditions
10233294Sstas * are met:
11233294Sstas *
1255682Smarkm * 1. Redistributions of source code must retain the above copyright
13233294Sstas *    notice, this list of conditions and the following disclaimer.
14233294Sstas *
15233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
1655682Smarkm *    notice, this list of conditions and the following disclaimer in
17233294Sstas *    the documentation and/or other materials provided with the
18233294Sstas *    distribution.
19233294Sstas *
2055682Smarkm * 3. All advertising materials mentioning features or use of this
21233294Sstas *    software must display the following acknowledgment:
22233294Sstas *    "This product includes software developed by the OpenSSL Project
23233294Sstas *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24233294Sstas *
25233294Sstas * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26233294Sstas *    endorse or promote products derived from this software without
27233294Sstas *    prior written permission. For written permission, please contact
28233294Sstas *    licensing@OpenSSL.org.
29233294Sstas *
30233294Sstas * 5. Products derived from this software may not be called "OpenSSL"
31233294Sstas *    nor may "OpenSSL" appear in their names without prior written
3255682Smarkm *    permission of the OpenSSL Project.
3355682Smarkm *
3455682Smarkm * 6. Redistributions of any form whatsoever must retain the following
3555682Smarkm *    acknowledgment:
36233294Sstas *    "This product includes software developed by the OpenSSL Project
3755682Smarkm *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38233294Sstas *
3955682Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4055682Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4155682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42233294Sstas * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43233294Sstas * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4455682Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4555682Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46233294Sstas * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48233294Sstas * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4955682Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50233294Sstas * OF THE POSSIBILITY OF SUCH DAMAGE.
51233294Sstas * ====================================================================
52233294Sstas *
5355682Smarkm * This product includes cryptographic software written by Eric Young
54233294Sstas * (eay@cryptsoft.com).  This product includes software written by Tim
55233294Sstas * Hudson (tjh@cryptsoft.com).
56233294Sstas *
57233294Sstas */
58233294Sstas
5955682Smarkm#include <stdio.h>
6055682Smarkm#include <string.h>
6155682Smarkm#include <openssl/crypto.h>
62233294Sstas#include <openssl/buffer.h>
6355682Smarkm#include <openssl/dso.h>
64178828Sdfr#include <openssl/engine.h>
65233294Sstas#ifndef OPENSSL_NO_RSA
6655682Smarkm#include <openssl/rsa.h>
67233294Sstas#endif
68233294Sstas#ifndef OPENSSL_NO_DSA
69120948Snectar#include <openssl/dsa.h>
70120948Snectar#endif
71233294Sstas#ifndef OPENSSL_NO_DH
72233294Sstas#include <openssl/dh.h>
73233294Sstas#endif
74233294Sstas#include <openssl/rand.h>
75233294Sstas#include <openssl/bn.h>
76120948Snectar
77120948Snectar#ifndef OPENSSL_NO_HW
78120948Snectar#ifndef OPENSSL_NO_HW_CSWIFT
79120948Snectar
80120948Snectar/* Attribution notice: Rainbow have generously allowed me to reproduce
81120948Snectar * the necessary definitions here from their API. This means the support
82233294Sstas * can build independently of whether application builders have the
83120948Snectar * API or hardware. This will allow developers to easily produce software
84120948Snectar * that has latent hardware support for any users that have accelerators
85120948Snectar * installed, without the developers themselves needing anything extra.
86120948Snectar *
87233294Sstas * I have only clipped the parts from the CryptoSwift header files that
88120948Snectar * are (or seem) relevant to the CryptoSwift support code. This is
89233294Sstas * simply to keep the file sizes reasonable.
90120948Snectar * [Geoff]
91120948Snectar */
92120948Snectar#ifdef FLAT_INC
93120948Snectar#include "cswift.h"
94120948Snectar#else
95233294Sstas#include "vendor_defns/cswift.h"
96178828Sdfr#endif
97178828Sdfr
98178828Sdfr#define CSWIFT_LIB_NAME "cswift engine"
99178828Sdfr#include "e_cswift_err.c"
100233294Sstas
101178828Sdfr#define DECIMAL_SIZE(type)	((sizeof(type)*8+2)/3+1)
102233294Sstas
103178828Sdfrstatic int cswift_destroy(ENGINE *e);
104178828Sdfrstatic int cswift_init(ENGINE *e);
105178828Sdfrstatic int cswift_finish(ENGINE *e);
106178828Sdfrstatic int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
107178828Sdfr#ifndef OPENSSL_NO_RSA
108233294Sstasstatic int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in);
10955682Smarkm#endif
11055682Smarkm
11155682Smarkm/* BIGNUM stuff */
11255682Smarkmstatic int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
11355682Smarkm		const BIGNUM *m, BN_CTX *ctx);
114233294Sstas#ifndef OPENSSL_NO_RSA
11578536Sassarstatic int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
116233294Sstas		const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
11778536Sassar		const BIGNUM *iqmp, BN_CTX *ctx);
11855682Smarkm#endif
119233294Sstas
12055682Smarkm#ifndef OPENSSL_NO_RSA
12155682Smarkm/* RSA stuff */
12255682Smarkmstatic int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
12355682Smarkm/* This function is aliased to mod_exp (with the mont stuff dropped). */
12455682Smarkmstatic int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
125233294Sstas		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
12655682Smarkm#endif
12755682Smarkm
12855682Smarkm#ifndef OPENSSL_NO_DSA
12955682Smarkm/* DSA stuff */
13055682Smarkmstatic DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
13155682Smarkmstatic int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
132233294Sstas				DSA_SIG *sig, DSA *dsa);
13355682Smarkm#endif
13455682Smarkm
135233294Sstas#ifndef OPENSSL_NO_DH
136233294Sstas/* DH stuff */
13755682Smarkm/* This function is alised to mod_exp (with the DH and mont dropped). */
138233294Sstasstatic int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
139233294Sstas		const BIGNUM *a, const BIGNUM *p,
140233294Sstas		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
141233294Sstas#endif
142233294Sstas
143233294Sstas/* RAND stuff */
144233294Sstasstatic int cswift_rand_bytes(unsigned char *buf, int num);
14555682Smarkmstatic int cswift_rand_status(void);
14655682Smarkm
14772448Sassar/* The definitions for control commands specific to this engine */
14872448Sassar#define CSWIFT_CMD_SO_PATH		ENGINE_CMD_BASE
14955682Smarkmstatic const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
15078536Sassar	{CSWIFT_CMD_SO_PATH,
151233294Sstas		"SO_PATH",
15255682Smarkm		"Specifies the path to the 'cswift' shared library",
15378536Sassar		ENGINE_CMD_FLAG_STRING},
15455682Smarkm	{0, NULL, NULL, 0}
15555682Smarkm	};
15655682Smarkm
15755682Smarkm#ifndef OPENSSL_NO_RSA
15855682Smarkm/* Our internal RSA_METHOD that we provide pointers to */
15955682Smarkmstatic RSA_METHOD cswift_rsa =
160233294Sstas	{
16155682Smarkm	"CryptoSwift RSA method",
16255682Smarkm	NULL,
16355682Smarkm	NULL,
16455682Smarkm	NULL,
16555682Smarkm	NULL,
16655682Smarkm	cswift_rsa_mod_exp,
16755682Smarkm	cswift_mod_exp_mont,
168233294Sstas	NULL,
169233294Sstas	NULL,
170233294Sstas	0,
17172448Sassar	NULL,
17255682Smarkm	NULL,
17372448Sassar	NULL,
17455682Smarkm	NULL
17555682Smarkm	};
176233294Sstas#endif
177233294Sstas
178233294Sstas#ifndef OPENSSL_NO_DSA
17955682Smarkm/* Our internal DSA_METHOD that we provide pointers to */
18055682Smarkmstatic DSA_METHOD cswift_dsa =
181233294Sstas	{
182233294Sstas	"CryptoSwift DSA method",
183233294Sstas	cswift_dsa_sign,
184233294Sstas	NULL, /* dsa_sign_setup */
18572448Sassar	cswift_dsa_verify,
18655682Smarkm	NULL, /* dsa_mod_exp */
18772448Sassar	NULL, /* bn_mod_exp */
188233294Sstas	NULL, /* init */
189233294Sstas	NULL, /* finish */
19055682Smarkm	0, /* flags */
19155682Smarkm	NULL, /* app_data */
19255682Smarkm	NULL, /* dsa_paramgen */
19355682Smarkm	NULL /* dsa_keygen */
194233294Sstas	};
195233294Sstas#endif
196127811Snectar
197127811Snectar#ifndef OPENSSL_NO_DH
198127811Snectar/* Our internal DH_METHOD that we provide pointers to */
199127811Snectarstatic DH_METHOD cswift_dh =
200127811Snectar	{
201127811Snectar	"CryptoSwift DH method",
202127811Snectar	NULL,
203127811Snectar	NULL,
204127811Snectar	cswift_mod_exp_dh,
205127811Snectar	NULL,
206127811Snectar	NULL,
20755682Smarkm	0,
208233294Sstas	NULL,
209233294Sstas	NULL
210233294Sstas	};
211233294Sstas#endif
21272448Sassar
21355682Smarkmstatic RAND_METHOD cswift_random =
21455682Smarkm    {
21555682Smarkm    /* "CryptoSwift RAND method", */
21655682Smarkm    NULL,
21755682Smarkm    cswift_rand_bytes,
21855682Smarkm    NULL,
21955682Smarkm    NULL,
22055682Smarkm    cswift_rand_bytes,
22155682Smarkm    cswift_rand_status,
22255682Smarkm    };
22355682Smarkm
22455682Smarkm
22572448Sassar/* Constants used when creating the ENGINE */
22672448Sassarstatic const char *engine_cswift_id = "cswift";
227233294Sstasstatic const char *engine_cswift_name = "CryptoSwift hardware engine support";
22855682Smarkm
229233294Sstas/* This internal function is used by ENGINE_cswift() and possibly by the
23072448Sassar * "dynamic" ENGINE support too */
23155682Smarkmstatic int bind_helper(ENGINE *e)
23255682Smarkm	{
23355682Smarkm#ifndef OPENSSL_NO_RSA
23455682Smarkm	const RSA_METHOD *meth1;
235127811Snectar#endif
236127811Snectar#ifndef OPENSSL_NO_DH
23755682Smarkm	const DH_METHOD *meth2;
23855682Smarkm#endif
239233294Sstas	if(!ENGINE_set_id(e, engine_cswift_id) ||
240127811Snectar			!ENGINE_set_name(e, engine_cswift_name) ||
241127811Snectar#ifndef OPENSSL_NO_RSA
242127811Snectar			!ENGINE_set_RSA(e, &cswift_rsa) ||
243127811Snectar#endif
244233294Sstas#ifndef OPENSSL_NO_DSA
245127811Snectar			!ENGINE_set_DSA(e, &cswift_dsa) ||
246127811Snectar#endif
247127811Snectar#ifndef OPENSSL_NO_DH
248233294Sstas			!ENGINE_set_DH(e, &cswift_dh) ||
249233294Sstas#endif
250127811Snectar			!ENGINE_set_RAND(e, &cswift_random) ||
251127811Snectar			!ENGINE_set_destroy_function(e, cswift_destroy) ||
252127811Snectar			!ENGINE_set_init_function(e, cswift_init) ||
253233294Sstas			!ENGINE_set_finish_function(e, cswift_finish) ||
254233294Sstas			!ENGINE_set_ctrl_function(e, cswift_ctrl) ||
255233294Sstas			!ENGINE_set_cmd_defns(e, cswift_cmd_defns))
256127811Snectar		return 0;
257127811Snectar
258127811Snectar#ifndef OPENSSL_NO_RSA
259127811Snectar	/* We know that the "PKCS1_SSLeay()" functions hook properly
260127811Snectar	 * to the cswift-specific mod_exp and mod_exp_crt so we use
261127811Snectar	 * those functions. NB: We don't use ENGINE_openssl() or
262233294Sstas	 * anything "more generic" because something like the RSAref
263127811Snectar	 * code may not hook properly, and if you own one of these
264127811Snectar	 * cards then you have the right to do RSA operations on it
265127811Snectar	 * anyway! */
266127811Snectar	meth1 = RSA_PKCS1_SSLeay();
267127811Snectar	cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
268233294Sstas	cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
269127811Snectar	cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
270233294Sstas	cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
271233294Sstas#endif
272233294Sstas
273233294Sstas#ifndef OPENSSL_NO_DH
274233294Sstas	/* Much the same for Diffie-Hellman */
275233294Sstas	meth2 = DH_OpenSSL();
276233294Sstas	cswift_dh.generate_key = meth2->generate_key;
27755682Smarkm	cswift_dh.compute_key = meth2->compute_key;
278233294Sstas#endif
279120948Snectar
280120948Snectar	/* Ensure the cswift error handling is set up */
281127811Snectar	ERR_load_CSWIFT_strings();
28255682Smarkm	return 1;
283120948Snectar	}
284120948Snectar
285120948Snectar#ifdef OPENSSL_NO_DYNAMIC_ENGINE
286233294Sstasstatic ENGINE *engine_cswift(void)
287127811Snectar	{
288127811Snectar	ENGINE *ret = ENGINE_new();
289120948Snectar	if(!ret)
290233294Sstas		return NULL;
29155682Smarkm	if(!bind_helper(ret))
29255682Smarkm		{
293233294Sstas		ENGINE_free(ret);
29455682Smarkm		return NULL;
29555682Smarkm		}
29655682Smarkm	return ret;
29755682Smarkm	}
29855682Smarkm
29955682Smarkmvoid ENGINE_load_cswift(void)
30055682Smarkm	{
30155682Smarkm	/* Copied from eng_[openssl|dyn].c */
30255682Smarkm	ENGINE *toadd = engine_cswift();
303233294Sstas	if(!toadd) return;
304233294Sstas	ENGINE_add(toadd);
30555682Smarkm	ENGINE_free(toadd);
30655682Smarkm	ERR_clear_error();
307233294Sstas	}
308233294Sstas#endif
309233294Sstas
31055682Smarkm/* This is a process-global DSO handle used for loading and unloading
31155682Smarkm * the CryptoSwift library. NB: This is only set (or unset) during an
31255682Smarkm * init() or finish() call (reference counts permitting) and they're
31355682Smarkm * operating with global locks, so this should be thread-safe
314233294Sstas * implicitly. */
31555682Smarkmstatic DSO *cswift_dso = NULL;
31655682Smarkm
317233294Sstas/* These are the function pointers that are (un)set when the library has
318233294Sstas * successfully (un)loaded. */
31955682Smarkmt_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
32055682Smarkmt_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
32155682Smarkmt_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
32255682Smarkmt_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
32355682Smarkm
32455682Smarkm/* Used in the DSO operations. */
325233294Sstasstatic const char *CSWIFT_LIBNAME = NULL;
32655682Smarkmstatic const char *get_CSWIFT_LIBNAME(void)
32755682Smarkm	{
32878536Sassar	if(CSWIFT_LIBNAME)
329233294Sstas		return CSWIFT_LIBNAME;
33055682Smarkm	return "swift";
33178536Sassar	}
33255682Smarkmstatic void free_CSWIFT_LIBNAME(void)
333233294Sstas	{
33455682Smarkm	if(CSWIFT_LIBNAME)
33555682Smarkm		OPENSSL_free((void*)CSWIFT_LIBNAME);
33655682Smarkm	CSWIFT_LIBNAME = NULL;
33755682Smarkm	}
338233294Sstasstatic long set_CSWIFT_LIBNAME(const char *name)
33955682Smarkm	{
34055682Smarkm	free_CSWIFT_LIBNAME();
34155682Smarkm	return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
34255682Smarkm	}
34355682Smarkmstatic const char *CSWIFT_F1 = "swAcquireAccContext";
34455682Smarkmstatic const char *CSWIFT_F2 = "swAttachKeyParam";
34555682Smarkmstatic const char *CSWIFT_F3 = "swSimpleRequest";
346127811Snectarstatic const char *CSWIFT_F4 = "swReleaseAccContext";
347233294Sstas
348127811Snectar
349127811Snectar/* CryptoSwift library functions and mechanics - these are used by the
350127811Snectar * higher-level functions further down. NB: As and where there's no
351127811Snectar * error checking, take a look lower down where these functions are
352127811Snectar * called, the checking and error handling is probably down there. */
35355682Smarkm
35455682Smarkm/* utility function to obtain a context */
355233294Sstasstatic int get_context(SW_CONTEXT_HANDLE *hac)
35655682Smarkm	{
357233294Sstas        SW_STATUS status;
358178828Sdfr
359233294Sstas        status = p_CSwift_AcquireAccContext(hac);
360178828Sdfr        if(status != SW_OK)
361178828Sdfr                return 0;
36255682Smarkm        return 1;
36378536Sassar	}
364233294Sstas
365233294Sstas/* similarly to release one. */
366233294Sstasstatic void release_context(SW_CONTEXT_HANDLE hac)
367233294Sstas	{
36855682Smarkm        p_CSwift_ReleaseAccContext(hac);
36978536Sassar	}
37072448Sassar
37155682Smarkm/* Destructor (complements the "ENGINE_cswift()" constructor) */
37272448Sassarstatic int cswift_destroy(ENGINE *e)
37372448Sassar	{
37472448Sassar	free_CSWIFT_LIBNAME();
37555682Smarkm	ERR_unload_CSWIFT_strings();
37655682Smarkm	return 1;
377178828Sdfr	}
378178828Sdfr
379178828Sdfr/* (de)initialisation functions. */
380233294Sstasstatic int cswift_init(ENGINE *e)
38155682Smarkm	{
38255682Smarkm        SW_CONTEXT_HANDLE hac;
383127811Snectar        t_swAcquireAccContext *p1;
384233294Sstas        t_swAttachKeyParam *p2;
38555682Smarkm        t_swSimpleRequest *p3;
386127811Snectar        t_swReleaseAccContext *p4;
387127811Snectar
388127811Snectar	if(cswift_dso != NULL)
389127811Snectar		{
390233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
391127811Snectar		goto err;
392127811Snectar		}
393127811Snectar	/* Attempt to load libswift.so/swift.dll/whatever. */
394127811Snectar	cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
395127811Snectar	if(cswift_dso == NULL)
396127811Snectar		{
397127811Snectar		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
398127811Snectar		goto err;
399233294Sstas		}
400127811Snectar	if(!(p1 = (t_swAcquireAccContext *)
40155682Smarkm				DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
402127811Snectar			!(p2 = (t_swAttachKeyParam *)
40378536Sassar				DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
404233294Sstas			!(p3 = (t_swSimpleRequest *)
40578536Sassar				DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
40655682Smarkm			!(p4 = (t_swReleaseAccContext *)
40778536Sassar				DSO_bind_func(cswift_dso, CSWIFT_F4)))
40878536Sassar		{
40978536Sassar		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
41078536Sassar		goto err;
41178536Sassar		}
412233294Sstas	/* Copy the pointers */
413233294Sstas	p_CSwift_AcquireAccContext = p1;
414233294Sstas	p_CSwift_AttachKeyParam = p2;
41555682Smarkm	p_CSwift_SimpleRequest = p3;
41678536Sassar	p_CSwift_ReleaseAccContext = p4;
41755682Smarkm	/* Try and get a context - if not, we may have a DSO but no
418127811Snectar	 * accelerator! */
419127811Snectar	if(!get_context(&hac))
420233294Sstas		{
421127811Snectar		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
422127811Snectar		goto err;
423127811Snectar		}
424127811Snectar	release_context(hac);
425127811Snectar	/* Everything's fine. */
42655682Smarkm	return 1;
42755682Smarkmerr:
42855682Smarkm	if(cswift_dso)
42955682Smarkm	{
43055682Smarkm		DSO_free(cswift_dso);
43155682Smarkm		cswift_dso = NULL;
43255682Smarkm	}
43355682Smarkm	p_CSwift_AcquireAccContext = NULL;
43455682Smarkm	p_CSwift_AttachKeyParam = NULL;
43555682Smarkm	p_CSwift_SimpleRequest = NULL;
43655682Smarkm	p_CSwift_ReleaseAccContext = NULL;
437233294Sstas	return 0;
43855682Smarkm	}
43955682Smarkm
440233294Sstasstatic int cswift_finish(ENGINE *e)
44155682Smarkm	{
442233294Sstas	free_CSWIFT_LIBNAME();
443178828Sdfr	if(cswift_dso == NULL)
444233294Sstas		{
445233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
446233294Sstas		return 0;
44755682Smarkm		}
44878536Sassar	if(!DSO_free(cswift_dso))
44978536Sassar		{
450233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
451233294Sstas		return 0;
452233294Sstas		}
453233294Sstas	cswift_dso = NULL;
454233294Sstas	p_CSwift_AcquireAccContext = NULL;
455233294Sstas	p_CSwift_AttachKeyParam = NULL;
456233294Sstas	p_CSwift_SimpleRequest = NULL;
45755682Smarkm	p_CSwift_ReleaseAccContext = NULL;
45878536Sassar	return 1;
45955682Smarkm	}
460233294Sstas
461233294Sstasstatic int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
462233294Sstas	{
463233294Sstas	int initialised = ((cswift_dso == NULL) ? 0 : 1);
464233294Sstas	switch(cmd)
465233294Sstas		{
466233294Sstas	case CSWIFT_CMD_SO_PATH:
467233294Sstas		if(p == NULL)
468233294Sstas			{
469233294Sstas			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
470234027Sstas			return 0;
471233294Sstas			}
472233294Sstas		if(initialised)
473233294Sstas			{
474233294Sstas			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
475233294Sstas			return 0;
476233294Sstas			}
477233294Sstas		return set_CSWIFT_LIBNAME((const char *)p);
478233294Sstas	default:
47955682Smarkm		break;
480233294Sstas		}
481233294Sstas	CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
482233294Sstas	return 0;
48355682Smarkm	}
48455682Smarkm
485233294Sstas/* Un petit mod_exp */
486233294Sstasstatic int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
487233294Sstas			const BIGNUM *m, BN_CTX *ctx)
488233294Sstas	{
489233294Sstas	/* I need somewhere to store temporary serialised values for
490233294Sstas	 * use with the CryptoSwift API calls. A neat cheat - I'll use
491233294Sstas	 * BIGNUMs from the BN_CTX but access their arrays directly as
492233294Sstas	 * byte arrays <grin>. This way I don't have to clean anything
493233294Sstas	 * up. */
494233294Sstas	BIGNUM *modulus;
495233294Sstas	BIGNUM *exponent;
496233294Sstas	BIGNUM *argument;
497233294Sstas	BIGNUM *result;
498233294Sstas	SW_STATUS sw_status;
499233294Sstas	SW_LARGENUMBER arg, res;
50055682Smarkm	SW_PARAM sw_param;
50155682Smarkm	SW_CONTEXT_HANDLE hac;
50255682Smarkm	int to_return, acquired;
50355682Smarkm
504233294Sstas	modulus = exponent = argument = result = NULL;
505233294Sstas	to_return = 0; /* expect failure */
506233294Sstas	acquired = 0;
507233294Sstas
508233294Sstas	if(!get_context(&hac))
50955682Smarkm		{
510233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
51155682Smarkm		goto err;
512233294Sstas		}
513233294Sstas	acquired = 1;
514233294Sstas	/* Prepare the params */
515233294Sstas	BN_CTX_start(ctx);
51678536Sassar	modulus = BN_CTX_get(ctx);
51755682Smarkm	exponent = BN_CTX_get(ctx);
51878536Sassar	argument = BN_CTX_get(ctx);
51955682Smarkm	result = BN_CTX_get(ctx);
52055682Smarkm	if(!result)
52155682Smarkm		{
52255682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
523233294Sstas		goto err;
52455682Smarkm		}
52555682Smarkm	if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
526233294Sstas		!bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
52755682Smarkm		{
52855682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
52955682Smarkm		goto err;
53055682Smarkm		}
531233294Sstas	sw_param.type = SW_ALG_EXP;
532127811Snectar	sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
533127811Snectar		(unsigned char *)modulus->d);
534233294Sstas	sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
535127811Snectar	sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
536233294Sstas		(unsigned char *)exponent->d);
537233294Sstas	sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
538233294Sstas	/* Attach the key params */
539127811Snectar	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
540127811Snectar	switch(sw_status)
541127811Snectar		{
542127811Snectar	case SW_OK:
543127811Snectar		break;
544233294Sstas	case SW_ERR_INPUT_SIZE:
545127811Snectar		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
546127811Snectar		goto err;
547127811Snectar	default:
548127811Snectar		{
549127811Snectar		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
55055682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
55155682Smarkm		sprintf(tmpbuf, "%ld", sw_status);
552233294Sstas		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
553178828Sdfr		}
554178828Sdfr		goto err;
555178828Sdfr		}
556178828Sdfr	/* Prepare the argument and response */
557233294Sstas	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
558233294Sstas	arg.value = (unsigned char *)argument->d;
559178828Sdfr	res.nbytes = BN_num_bytes(m);
560178828Sdfr	memset(result->d, 0, res.nbytes);
561178828Sdfr	res.value = (unsigned char *)result->d;
562178828Sdfr	/* Perform the operation */
563178828Sdfr	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
564233294Sstas		&res, 1)) != SW_OK)
565178828Sdfr		{
566233294Sstas		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
567233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
568178828Sdfr		sprintf(tmpbuf, "%ld", sw_status);
569233294Sstas		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
570178828Sdfr		goto err;
571178828Sdfr		}
572233294Sstas	/* Convert the response */
573233294Sstas	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
574178828Sdfr	to_return = 1;
575178828Sdfrerr:
576178828Sdfr	if(acquired)
577233294Sstas		release_context(hac);
57855682Smarkm	BN_CTX_end(ctx);
57955682Smarkm	return to_return;
58055682Smarkm	}
58155682Smarkm
582233294Sstas
58378536Sassar#ifndef OPENSSL_NO_RSA
584233294Sstasint cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in)
585233294Sstas{
586233294Sstas	int mod;
58755682Smarkm	int numbytes = BN_num_bytes(in);
58878536Sassar
58955682Smarkm	mod = 0;
59055682Smarkm	while( ((out->nbytes = (numbytes+mod)) % 32) )
59155682Smarkm	{
59255682Smarkm		mod++;
593233294Sstas	}
59455682Smarkm	out->value = (unsigned char*)OPENSSL_malloc(out->nbytes);
59555682Smarkm	if(!out->value)
59655682Smarkm	{
597233294Sstas		return 0;
59878536Sassar	}
599178828Sdfr	BN_bn2bin(in, &out->value[mod]);
600233294Sstas	if(mod)
601233294Sstas		memset(out->value, 0, mod);
602233294Sstas
60355682Smarkm	return 1;
60478536Sassar}
60555682Smarkm#endif
60655682Smarkm
60755682Smarkm#ifndef OPENSSL_NO_RSA
608233294Sstas/* Un petit mod_exp chinois */
60955682Smarkmstatic int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
61055682Smarkm			const BIGNUM *q, const BIGNUM *dmp1,
61155682Smarkm			const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
612233294Sstas	{
61378536Sassar	SW_STATUS sw_status;
614178828Sdfr	SW_LARGENUMBER arg, res;
615233294Sstas	SW_PARAM sw_param;
616233294Sstas	SW_CONTEXT_HANDLE hac;
617233294Sstas	BIGNUM *result = NULL;
61855682Smarkm	BIGNUM *argument = NULL;
61978536Sassar	int to_return = 0; /* expect failure */
62055682Smarkm	int acquired = 0;
62155682Smarkm
62255682Smarkm	sw_param.up.crt.p.value = NULL;
623233294Sstas	sw_param.up.crt.q.value = NULL;
624178828Sdfr	sw_param.up.crt.dmp1.value = NULL;
625178828Sdfr	sw_param.up.crt.dmq1.value = NULL;
626178828Sdfr	sw_param.up.crt.iqmp.value = NULL;
627233294Sstas
628178828Sdfr	if(!get_context(&hac))
629178828Sdfr		{
630233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
631233294Sstas		goto err;
632233294Sstas		}
633178828Sdfr	acquired = 1;
634178828Sdfr
635178828Sdfr	/* Prepare the params */
636178828Sdfr	argument = BN_new();
637178828Sdfr	result = BN_new();
638178828Sdfr	if(!result || !argument)
63955682Smarkm		{
64055682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
64155682Smarkm		goto err;
64255682Smarkm		}
643233294Sstas
644233294Sstas
64555682Smarkm	sw_param.type = SW_ALG_CRT;
646120948Snectar	/************************************************************************/
647233294Sstas	/* 04/02/2003                                                           */
648233294Sstas	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
649233294Sstas	/* limitation of cswift with values not a multiple of 32                */
65055682Smarkm	/************************************************************************/
65155682Smarkm	if(!cswift_bn_32copy(&sw_param.up.crt.p, p))
65255682Smarkm	{
65355682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
654233294Sstas		goto err;
65555682Smarkm	}
65655682Smarkm	if(!cswift_bn_32copy(&sw_param.up.crt.q, q))
65755682Smarkm	{
65855682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
659233294Sstas		goto err;
660233294Sstas	}
66178536Sassar	if(!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1))
662233294Sstas	{
663233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
664233294Sstas		goto err;
665178828Sdfr	}
66655682Smarkm	if(!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1))
66778536Sassar	{
66855682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
66978536Sassar		goto err;
670233294Sstas	}
67155682Smarkm	if(!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp))
67278536Sassar	{
67355682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
67455682Smarkm		goto err;
67555682Smarkm	}
676233294Sstas	if(	!bn_wexpand(argument, a->top) ||
67755682Smarkm			!bn_wexpand(result, p->top + q->top))
67855682Smarkm		{
67955682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
68055682Smarkm		goto err;
68155682Smarkm		}
682233294Sstas
683233294Sstas	/* Attach the key params */
684233294Sstas	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
68555682Smarkm	switch(sw_status)
68655682Smarkm		{
687233294Sstas	case SW_OK:
688233294Sstas		break;
689233294Sstas	case SW_ERR_INPUT_SIZE:
69055682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
69155682Smarkm		goto err;
69255682Smarkm	default:
693233294Sstas		{
69455682Smarkm		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
69555682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
69655682Smarkm		sprintf(tmpbuf, "%ld", sw_status);
69755682Smarkm		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
698233294Sstas		}
69978536Sassar		goto err;
700233294Sstas		}
70178536Sassar	/* Prepare the argument and response */
70255682Smarkm	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
70355682Smarkm	arg.value = (unsigned char *)argument->d;
70455682Smarkm	res.nbytes = 2 * BN_num_bytes(p);
70555682Smarkm	memset(result->d, 0, res.nbytes);
706233294Sstas	res.value = (unsigned char *)result->d;
707233294Sstas	/* Perform the operation */
708233294Sstas	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
709233294Sstas		&res, 1)) != SW_OK)
710233294Sstas		{
711233294Sstas		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
712233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
713233294Sstas		sprintf(tmpbuf, "%ld", sw_status);
714233294Sstas		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
715233294Sstas		goto err;
716233294Sstas		}
717233294Sstas	/* Convert the response */
718233294Sstas	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
71955682Smarkm	to_return = 1;
720233294Sstaserr:
721233294Sstas	if(sw_param.up.crt.p.value)
722233294Sstas		OPENSSL_free(sw_param.up.crt.p.value);
723233294Sstas	if(sw_param.up.crt.q.value)
724233294Sstas		OPENSSL_free(sw_param.up.crt.q.value);
725233294Sstas	if(sw_param.up.crt.dmp1.value)
726233294Sstas		OPENSSL_free(sw_param.up.crt.dmp1.value);
72755682Smarkm	if(sw_param.up.crt.dmq1.value)
728233294Sstas		OPENSSL_free(sw_param.up.crt.dmq1.value);
729233294Sstas	if(sw_param.up.crt.iqmp.value)
730233294Sstas		OPENSSL_free(sw_param.up.crt.iqmp.value);
731233294Sstas	if(result)
732233294Sstas		BN_free(result);
73355682Smarkm	if(argument)
73455682Smarkm		BN_free(argument);
735233294Sstas	if(acquired)
736233294Sstas		release_context(hac);
737233294Sstas	return to_return;
738233294Sstas	}
739233294Sstas#endif
740233294Sstas
741233294Sstas#ifndef OPENSSL_NO_RSA
742233294Sstasstatic int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
743233294Sstas	{
744233294Sstas	int to_return = 0;
74555682Smarkm	const RSA_METHOD * def_rsa_method;
74655682Smarkm
747233294Sstas	if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
748233294Sstas		{
749233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
750233294Sstas		goto err;
751233294Sstas		}
75255682Smarkm
753233294Sstas	/* Try the limits of RSA (2048 bits) */
75455682Smarkm	if(BN_num_bytes(rsa->p) > 128 ||
755233294Sstas		BN_num_bytes(rsa->q) > 128 ||
75655682Smarkm		BN_num_bytes(rsa->dmp1) > 128 ||
757233294Sstas		BN_num_bytes(rsa->dmq1) > 128 ||
758233294Sstas		BN_num_bytes(rsa->iqmp) > 128)
759233294Sstas	{
760233294Sstas#ifdef RSA_NULL
761233294Sstas		def_rsa_method=RSA_null_method();
762233294Sstas#else
763233294Sstas#if 0
76478536Sassar		def_rsa_method=RSA_PKCS1_RSAref();
76555682Smarkm#else
766233294Sstas		def_rsa_method=RSA_PKCS1_SSLeay();
767233294Sstas#endif
768233294Sstas#endif
769233294Sstas		if(def_rsa_method)
77055682Smarkm			return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx);
77155682Smarkm	}
772233294Sstas
773233294Sstas	to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
774233294Sstas		rsa->dmq1, rsa->iqmp, ctx);
775178828Sdfrerr:
776178828Sdfr	return to_return;
777233294Sstas	}
778178828Sdfr
779233294Sstas/* This function is aliased to mod_exp (with the mont stuff dropped). */
780233294Sstasstatic int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
781233294Sstas		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
782178828Sdfr	{
783178828Sdfr	const RSA_METHOD * def_rsa_method;
784178828Sdfr
785233294Sstas	/* Try the limits of RSA (2048 bits) */
786233294Sstas	if(BN_num_bytes(r) > 256 ||
787233294Sstas		BN_num_bytes(a) > 256 ||
788178828Sdfr		BN_num_bytes(m) > 256)
789178828Sdfr	{
790178828Sdfr#ifdef RSA_NULL
791178828Sdfr		def_rsa_method=RSA_null_method();
792178828Sdfr#else
793178828Sdfr#if 0
79455682Smarkm		def_rsa_method=RSA_PKCS1_RSAref();
79555682Smarkm#else
79655682Smarkm		def_rsa_method=RSA_PKCS1_SSLeay();
79755682Smarkm#endif
79855682Smarkm#endif
79955682Smarkm		if(def_rsa_method)
80055682Smarkm			return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx);
80172448Sassar	}
80272448Sassar
80372448Sassar	return cswift_mod_exp(r, a, p, m, ctx);
80472448Sassar	}
80572448Sassar#endif	/* OPENSSL_NO_RSA */
80672448Sassar
80755682Smarkm#ifndef OPENSSL_NO_DSA
80855682Smarkmstatic DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
80955682Smarkm	{
81055682Smarkm	SW_CONTEXT_HANDLE hac;
81155682Smarkm	SW_PARAM sw_param;
81255682Smarkm	SW_STATUS sw_status;
81355682Smarkm	SW_LARGENUMBER arg, res;
81455682Smarkm	unsigned char *ptr;
815178828Sdfr	BN_CTX *ctx;
81655682Smarkm	BIGNUM *dsa_p = NULL;
81772448Sassar	BIGNUM *dsa_q = NULL;
81872448Sassar	BIGNUM *dsa_g = NULL;
81955682Smarkm	BIGNUM *dsa_key = NULL;
82090929Snectar	BIGNUM *result = NULL;
82155682Smarkm	DSA_SIG *to_return = NULL;
82255682Smarkm	int acquired = 0;
82355682Smarkm
824233294Sstas	if((ctx = BN_CTX_new()) == NULL)
825233294Sstas		goto err;
826233294Sstas	if(!get_context(&hac))
82755682Smarkm		{
82855682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
82990929Snectar		goto err;
830120948Snectar		}
83190929Snectar	acquired = 1;
83290929Snectar	/* Prepare the params */
83390929Snectar	BN_CTX_start(ctx);
834233294Sstas	dsa_p = BN_CTX_get(ctx);
83555682Smarkm	dsa_q = BN_CTX_get(ctx);
83690929Snectar	dsa_g = BN_CTX_get(ctx);
837233294Sstas	dsa_key = BN_CTX_get(ctx);
83855682Smarkm	result = BN_CTX_get(ctx);
83955682Smarkm	if(!result)
84055682Smarkm		{
84155682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
842233294Sstas		goto err;
843233294Sstas		}
844127811Snectar	if(!bn_wexpand(dsa_p, dsa->p->top) ||
845233294Sstas			!bn_wexpand(dsa_q, dsa->q->top) ||
84655682Smarkm			!bn_wexpand(dsa_g, dsa->g->top) ||
847233294Sstas			!bn_wexpand(dsa_key, dsa->priv_key->top) ||
84855682Smarkm			!bn_wexpand(result, dsa->p->top))
84955682Smarkm		{
85072448Sassar		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
85172448Sassar		goto err;
852233294Sstas		}
85372448Sassar	sw_param.type = SW_ALG_DSA;
85472448Sassar	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
85590929Snectar				(unsigned char *)dsa_p->d);
85690929Snectar	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
85755682Smarkm	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
85872448Sassar				(unsigned char *)dsa_q->d);
85955682Smarkm	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
86090929Snectar	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
86190929Snectar				(unsigned char *)dsa_g->d);
86255682Smarkm	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
86390929Snectar	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
86490929Snectar				(unsigned char *)dsa_key->d);
86590929Snectar	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
86690929Snectar	/* Attach the key params */
86790929Snectar	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
86855682Smarkm	switch(sw_status)
86990929Snectar		{
87055682Smarkm	case SW_OK:
87190929Snectar		break;
87290929Snectar	case SW_ERR_INPUT_SIZE:
87390929Snectar		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
87490929Snectar		goto err;
87555682Smarkm	default:
87655682Smarkm		{
87790929Snectar		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
87855682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
87955682Smarkm		sprintf(tmpbuf, "%ld", sw_status);
88055682Smarkm		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
881178828Sdfr		}
88255682Smarkm		goto err;
88372448Sassar		}
88472448Sassar	/* Prepare the argument and response */
88555682Smarkm	arg.nbytes = dlen;
88655682Smarkm	arg.value = (unsigned char *)dgst;
88755682Smarkm	res.nbytes = BN_num_bytes(dsa->p);
88855682Smarkm	memset(result->d, 0, res.nbytes);
88955682Smarkm	res.value = (unsigned char *)result->d;
890233294Sstas	/* Perform the operation */
891233294Sstas	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
89278536Sassar		&res, 1);
893233294Sstas	if(sw_status != SW_OK)
89455682Smarkm		{
895120948Snectar		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
89655682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
89778536Sassar		sprintf(tmpbuf, "%ld", sw_status);
898233294Sstas		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
89955682Smarkm		goto err;
90078536Sassar		}
901233294Sstas	/* Convert the response */
90255682Smarkm	ptr = (unsigned char *)result->d;
90355682Smarkm	if((to_return = DSA_SIG_new()) == NULL)
90455682Smarkm		goto err;
90555682Smarkm	to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
90655682Smarkm	to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
90755682Smarkm
90855682Smarkmerr:
909233294Sstas	if(acquired)
910127811Snectar		release_context(hac);
91178536Sassar	if(ctx)
91255682Smarkm		{
913233294Sstas		BN_CTX_end(ctx);
91455682Smarkm		BN_CTX_free(ctx);
91555682Smarkm		}
91655682Smarkm	return to_return;
917233294Sstas	}
91890929Snectar
91955682Smarkmstatic int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
92055682Smarkm				DSA_SIG *sig, DSA *dsa)
92190929Snectar	{
92290929Snectar	SW_CONTEXT_HANDLE hac;
92355682Smarkm	SW_PARAM sw_param;
92455682Smarkm	SW_STATUS sw_status;
92555682Smarkm	SW_LARGENUMBER arg[2], res;
92690929Snectar	unsigned long sig_result;
92790929Snectar	BN_CTX *ctx;
92890929Snectar	BIGNUM *dsa_p = NULL;
92990929Snectar	BIGNUM *dsa_q = NULL;
93055682Smarkm	BIGNUM *dsa_g = NULL;
93155682Smarkm	BIGNUM *dsa_key = NULL;
93255682Smarkm	BIGNUM *argument = NULL;
93355682Smarkm	int to_return = -1;
93455682Smarkm	int acquired = 0;
93555682Smarkm
93655682Smarkm	if((ctx = BN_CTX_new()) == NULL)
93790929Snectar		goto err;
93890929Snectar	if(!get_context(&hac))
93990929Snectar		{
94090929Snectar		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
94155682Smarkm		goto err;
94255682Smarkm		}
94355682Smarkm	acquired = 1;
94472448Sassar	/* Prepare the params */
94572448Sassar	BN_CTX_start(ctx);
94672448Sassar	dsa_p = BN_CTX_get(ctx);
947178828Sdfr	dsa_q = BN_CTX_get(ctx);
94872448Sassar	dsa_g = BN_CTX_get(ctx);
94972448Sassar	dsa_key = BN_CTX_get(ctx);
95072448Sassar	argument = BN_CTX_get(ctx);
95172448Sassar	if(!argument)
952233294Sstas		{
95378536Sassar		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
95472448Sassar		goto err;
95572448Sassar		}
95690929Snectar	if(!bn_wexpand(dsa_p, dsa->p->top) ||
95772448Sassar			!bn_wexpand(dsa_q, dsa->q->top) ||
95872448Sassar			!bn_wexpand(dsa_g, dsa->g->top) ||
95978536Sassar			!bn_wexpand(dsa_key, dsa->pub_key->top) ||
960233294Sstas			!bn_wexpand(argument, 40))
96172448Sassar		{
96278536Sassar		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
96372448Sassar		goto err;
96472448Sassar		}
96572448Sassar	sw_param.type = SW_ALG_DSA;
96672448Sassar	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
96772448Sassar				(unsigned char *)dsa_p->d);
96872448Sassar	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
96990929Snectar	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
97090929Snectar				(unsigned char *)dsa_q->d);
97190929Snectar	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
97290929Snectar	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
97390929Snectar				(unsigned char *)dsa_g->d);
97490929Snectar	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
97572448Sassar	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
97672448Sassar				(unsigned char *)dsa_key->d);
97772448Sassar	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
97872448Sassar	/* Attach the key params */
97972448Sassar	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
98072448Sassar	switch(sw_status)
98155682Smarkm		{
98255682Smarkm	case SW_OK:
98355682Smarkm		break;
98455682Smarkm	case SW_ERR_INPUT_SIZE:
98555682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
98672448Sassar		goto err;
98772448Sassar	default:
98855682Smarkm		{
98955682Smarkm		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
99055682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
99155682Smarkm		sprintf(tmpbuf, "%ld", sw_status);
99255682Smarkm		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
993233294Sstas		}
994233294Sstas		goto err;
99555682Smarkm		}
996233294Sstas	/* Prepare the argument and response */
99772448Sassar	arg[0].nbytes = dgst_len;
998178828Sdfr	arg[0].value = (unsigned char *)dgst;
999233294Sstas	arg[1].nbytes = 40;
1000233294Sstas	arg[1].value = (unsigned char *)argument->d;
1001233294Sstas	memset(arg[1].value, 0, 40);
1002178828Sdfr	BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
100378536Sassar	BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
100472448Sassar	res.nbytes = 4; /* unsigned long */
1005127811Snectar	res.value = (unsigned char *)(&sig_result);
1006233294Sstas	/* Perform the operation */
1007127811Snectar	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
1008127811Snectar		&res, 1);
1009127811Snectar	if(sw_status != SW_OK)
101055682Smarkm		{
101178536Sassar		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
1012233294Sstas		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
101355682Smarkm		sprintf(tmpbuf, "%ld", sw_status);
101478536Sassar		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
101555682Smarkm		goto err;
101655682Smarkm		}
101755682Smarkm	/* Convert the response */
101855682Smarkm	to_return = ((sig_result == 0) ? 0 : 1);
101955682Smarkm
102055682Smarkmerr:
102155682Smarkm	if(acquired)
102255682Smarkm		release_context(hac);
102355682Smarkm	if(ctx)
102455682Smarkm		{
102555682Smarkm		BN_CTX_end(ctx);
102655682Smarkm		BN_CTX_free(ctx);
102755682Smarkm		}
102855682Smarkm	return to_return;
102990929Snectar	}
103090929Snectar#endif
103190929Snectar
103290929Snectar#ifndef OPENSSL_NO_DH
103390929Snectar/* This function is aliased to mod_exp (with the dh and mont dropped). */
103455682Smarkmstatic int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
103555682Smarkm		const BIGNUM *a, const BIGNUM *p,
103655682Smarkm		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
103755682Smarkm	{
103855682Smarkm	return cswift_mod_exp(r, a, p, m, ctx);
103955682Smarkm	}
104055682Smarkm#endif
104155682Smarkm
104255682Smarkm/* Random bytes are good */
104355682Smarkmstatic int cswift_rand_bytes(unsigned char *buf, int num)
104455682Smarkm{
104555682Smarkm	SW_CONTEXT_HANDLE hac;
104655682Smarkm	SW_STATUS swrc;
104755682Smarkm	SW_LARGENUMBER largenum;
104855682Smarkm	int acquired = 0;
104955682Smarkm	int to_return = 0; /* assume failure */
105055682Smarkm	unsigned char buf32[1024];
105155682Smarkm
1052178828Sdfr
105355682Smarkm	if (!get_context(&hac))
1054233294Sstas	{
105555682Smarkm		CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE);
105655682Smarkm		goto err;
105755682Smarkm	}
105855682Smarkm	acquired = 1;
105955682Smarkm
106055682Smarkm	/************************************************************************/
106155682Smarkm	/* 04/02/2003                                                           */
106255682Smarkm	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
106355682Smarkm	/* limitation of cswift with values not a multiple of 32                */
106455682Smarkm	/************************************************************************/
106555682Smarkm
106672448Sassar	while(num >= (int)sizeof(buf32))
106772448Sassar	{
106855682Smarkm		largenum.value = buf;
106955682Smarkm		largenum.nbytes = sizeof(buf32);
107055682Smarkm		/* tell CryptoSwift how many bytes we want and where we want it.
107155682Smarkm		 * Note: - CryptoSwift cannot do more than 4096 bytes at a time.
107255682Smarkm		 *       - CryptoSwift can only do multiple of 32-bits. */
1073233294Sstas		swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
1074233294Sstas		if (swrc != SW_OK)
1075127811Snectar		{
1076233294Sstas			char tmpbuf[20];
1077127811Snectar			CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
1078127811Snectar			sprintf(tmpbuf, "%ld", swrc);
1079233294Sstas			ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
1080233294Sstas			goto err;
1081233294Sstas		}
1082233294Sstas		buf += sizeof(buf32);
1083233294Sstas		num -= sizeof(buf32);
1084233294Sstas	}
1085233294Sstas	if(num)
1086127811Snectar	{
108755682Smarkm		largenum.nbytes = sizeof(buf32);
108878536Sassar		largenum.value = buf32;
1089233294Sstas		swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
109055682Smarkm		if (swrc != SW_OK)
109178536Sassar		{
109255682Smarkm			char tmpbuf[20];
1093233294Sstas			CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
109455682Smarkm			sprintf(tmpbuf, "%ld", swrc);
109555682Smarkm			ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
109655682Smarkm			goto err;
109755682Smarkm		}
109855682Smarkm		memcpy(buf, largenum.value, num);
109990929Snectar	}
110090929Snectar
110190929Snectar	to_return = 1;  /* success */
110290929Snectarerr:
110390929Snectar	if (acquired)
110455682Smarkm		release_context(hac);
110555682Smarkm
110672448Sassar	return to_return;
110772448Sassar}
110855682Smarkm
110955682Smarkmstatic int cswift_rand_status(void)
111078536Sassar{
111155682Smarkm	return 1;
111255682Smarkm}
111355682Smarkm
111455682Smarkm
111555682Smarkm/* This stuff is needed if this ENGINE is being compiled into a self-contained
111655682Smarkm * shared-library. */
111755682Smarkm#ifndef OPENSSL_NO_DYNAMIC_ENGINE
111855682Smarkmstatic int bind_fn(ENGINE *e, const char *id)
111955682Smarkm	{
1120178828Sdfr	if(id && (strcmp(id, engine_cswift_id) != 0))
112155682Smarkm		return 0;
1122233294Sstas	if(!bind_helper(e))
112355682Smarkm		return 0;
112455682Smarkm	return 1;
112555682Smarkm	}
112655682SmarkmIMPLEMENT_DYNAMIC_CHECK_FN()
112755682SmarkmIMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
112855682Smarkm#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
112972448Sassar
113072448Sassar#endif /* !OPENSSL_NO_HW_CSWIFT */
113172448Sassar#endif /* !OPENSSL_NO_HW */
113272448Sassar