/* crypto/engine/hw_cswift.c */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
 * project 2000.
 */
/* ====================================================================
 * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
#include <openssl/dso.h>
#include <openssl/engine.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
#endif
#include <openssl/rand.h>
#include <openssl/bn.h>

#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_CSWIFT

/* Attribution notice: Rainbow have generously allowed me to reproduce
 * the necessary definitions here from their API. This means the support
 * can build independently of whether application builders have the
 * API or hardware. This will allow developers to easily produce software
 * that has latent hardware support for any users that have accelerators
 * installed, without the developers themselves needing anything extra.
 *
 * I have only clipped the parts from the CryptoSwift header files that
 * are (or seem) relevant to the CryptoSwift support code. This is
 * simply to keep the file sizes reasonable.
 * [Geoff]
 */
#ifdef FLAT_INC
#include "cswift.h"
#else
#include "vendor_defns/cswift.h"
#endif

#define CSWIFT_LIB_NAME "cswift engine"
#include "e_cswift_err.c"

#define DECIMAL_SIZE(type)	((sizeof(type)*8+2)/3+1)

static int cswift_destroy(ENGINE *e);
static int cswift_init(ENGINE *e);
static int cswift_finish(ENGINE *e);
static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
#ifndef OPENSSL_NO_RSA
static int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in);
#endif

/* BIGNUM stuff */
static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
		const BIGNUM *m, BN_CTX *ctx);
#ifndef OPENSSL_NO_RSA
static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
		const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
		const BIGNUM *iqmp, BN_CTX *ctx);
#endif

#ifndef OPENSSL_NO_RSA
/* RSA stuff */
static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
/* This function is aliased to mod_exp (with the mont stuff dropped). */
static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
#endif

#ifndef OPENSSL_NO_DSA
/* DSA stuff */
static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
				DSA_SIG *sig, DSA *dsa);
#endif

#ifndef OPENSSL_NO_DH
/* DH stuff */
/* This function is alised to mod_exp (with the DH and mont dropped). */
static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
		const BIGNUM *a, const BIGNUM *p,
		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
#endif

/* RAND stuff */
static int cswift_rand_bytes(unsigned char *buf, int num);
static int cswift_rand_status(void);

/* The definitions for control commands specific to this engine */
#define CSWIFT_CMD_SO_PATH		ENGINE_CMD_BASE
static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
	{CSWIFT_CMD_SO_PATH,
		"SO_PATH",
		"Specifies the path to the 'cswift' shared library",
		ENGINE_CMD_FLAG_STRING},
	{0, NULL, NULL, 0}
	};

#ifndef OPENSSL_NO_RSA
/* Our internal RSA_METHOD that we provide pointers to */
static RSA_METHOD cswift_rsa =
	{
	"CryptoSwift RSA method",
	NULL,
	NULL,
	NULL,
	NULL,
	cswift_rsa_mod_exp,
	cswift_mod_exp_mont,
	NULL,
	NULL,
	0,
	NULL,
	NULL,
	NULL,
	NULL
	};
#endif

#ifndef OPENSSL_NO_DSA
/* Our internal DSA_METHOD that we provide pointers to */
static DSA_METHOD cswift_dsa =
	{
	"CryptoSwift DSA method",
	cswift_dsa_sign,
	NULL, /* dsa_sign_setup */
	cswift_dsa_verify,
	NULL, /* dsa_mod_exp */
	NULL, /* bn_mod_exp */
	NULL, /* init */
	NULL, /* finish */
	0, /* flags */
	NULL, /* app_data */
	NULL, /* dsa_paramgen */
	NULL /* dsa_keygen */
	};
#endif

#ifndef OPENSSL_NO_DH
/* Our internal DH_METHOD that we provide pointers to */
static DH_METHOD cswift_dh =
	{
	"CryptoSwift DH method",
	NULL,
	NULL,
	cswift_mod_exp_dh,
	NULL,
	NULL,
	0,
	NULL,
	NULL
	};
#endif

static RAND_METHOD cswift_random =
    {
    /* "CryptoSwift RAND method", */
    NULL,
    cswift_rand_bytes,
    NULL,
    NULL,
    cswift_rand_bytes,
    cswift_rand_status,
    };


/* Constants used when creating the ENGINE */
static const char *engine_cswift_id = "cswift";
static const char *engine_cswift_name = "CryptoSwift hardware engine support";

/* This internal function is used by ENGINE_cswift() and possibly by the
 * "dynamic" ENGINE support too */
static int bind_helper(ENGINE *e)
	{
#ifndef OPENSSL_NO_RSA
	const RSA_METHOD *meth1;
#endif
#ifndef OPENSSL_NO_DH
	const DH_METHOD *meth2;
#endif
	if(!ENGINE_set_id(e, engine_cswift_id) ||
			!ENGINE_set_name(e, engine_cswift_name) ||
#ifndef OPENSSL_NO_RSA
			!ENGINE_set_RSA(e, &cswift_rsa) ||
#endif
#ifndef OPENSSL_NO_DSA
			!ENGINE_set_DSA(e, &cswift_dsa) ||
#endif
#ifndef OPENSSL_NO_DH
			!ENGINE_set_DH(e, &cswift_dh) ||
#endif
			!ENGINE_set_RAND(e, &cswift_random) ||
			!ENGINE_set_destroy_function(e, cswift_destroy) ||
			!ENGINE_set_init_function(e, cswift_init) ||
			!ENGINE_set_finish_function(e, cswift_finish) ||
			!ENGINE_set_ctrl_function(e, cswift_ctrl) ||
			!ENGINE_set_cmd_defns(e, cswift_cmd_defns))
		return 0;

#ifndef OPENSSL_NO_RSA
	/* We know that the "PKCS1_SSLeay()" functions hook properly
	 * to the cswift-specific mod_exp and mod_exp_crt so we use
	 * those functions. NB: We don't use ENGINE_openssl() or
	 * anything "more generic" because something like the RSAref
	 * code may not hook properly, and if you own one of these
	 * cards then you have the right to do RSA operations on it
	 * anyway! */ 
	meth1 = RSA_PKCS1_SSLeay();
	cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
	cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
	cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
	cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
#endif

#ifndef OPENSSL_NO_DH
	/* Much the same for Diffie-Hellman */
	meth2 = DH_OpenSSL();
	cswift_dh.generate_key = meth2->generate_key;
	cswift_dh.compute_key = meth2->compute_key;
#endif

	/* Ensure the cswift error handling is set up */
	ERR_load_CSWIFT_strings();
	return 1;
	}

#ifdef OPENSSL_NO_DYNAMIC_ENGINE
static ENGINE *engine_cswift(void)
	{
	ENGINE *ret = ENGINE_new();
	if(!ret)
		return NULL;
	if(!bind_helper(ret))
		{
		ENGINE_free(ret);
		return NULL;
		}
	return ret;
	}

void ENGINE_load_cswift(void)
	{
	/* Copied from eng_[openssl|dyn].c */
	ENGINE *toadd = engine_cswift();
	if(!toadd) return;
	ENGINE_add(toadd);
	ENGINE_free(toadd);
	ERR_clear_error();
	}
#endif

/* This is a process-global DSO handle used for loading and unloading
 * the CryptoSwift library. NB: This is only set (or unset) during an
 * init() or finish() call (reference counts permitting) and they're
 * operating with global locks, so this should be thread-safe
 * implicitly. */
static DSO *cswift_dso = NULL;

/* These are the function pointers that are (un)set when the library has
 * successfully (un)loaded. */
t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;

/* Used in the DSO operations. */
static const char *CSWIFT_LIBNAME = NULL;
static const char *get_CSWIFT_LIBNAME(void)
	{
	if(CSWIFT_LIBNAME)
		return CSWIFT_LIBNAME;
	return "swift";
	}
static void free_CSWIFT_LIBNAME(void)
	{
	if(CSWIFT_LIBNAME)
		OPENSSL_free((void*)CSWIFT_LIBNAME);
	CSWIFT_LIBNAME = NULL;
	}
static long set_CSWIFT_LIBNAME(const char *name)
	{
	free_CSWIFT_LIBNAME();
	return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
	}
static const char *CSWIFT_F1 = "swAcquireAccContext";
static const char *CSWIFT_F2 = "swAttachKeyParam";
static const char *CSWIFT_F3 = "swSimpleRequest";
static const char *CSWIFT_F4 = "swReleaseAccContext";


/* CryptoSwift library functions and mechanics - these are used by the
 * higher-level functions further down. NB: As and where there's no
 * error checking, take a look lower down where these functions are
 * called, the checking and error handling is probably down there. */

/* utility function to obtain a context */
static int get_context(SW_CONTEXT_HANDLE *hac)
	{
        SW_STATUS status;
 
        status = p_CSwift_AcquireAccContext(hac);
        if(status != SW_OK)
                return 0;
        return 1;
	}
 
/* similarly to release one. */
static void release_context(SW_CONTEXT_HANDLE hac)
	{
        p_CSwift_ReleaseAccContext(hac);
	}

/* Destructor (complements the "ENGINE_cswift()" constructor) */
static int cswift_destroy(ENGINE *e)
	{
	free_CSWIFT_LIBNAME();
	ERR_unload_CSWIFT_strings();
	return 1;
	}

/* (de)initialisation functions. */
static int cswift_init(ENGINE *e)
	{
        SW_CONTEXT_HANDLE hac;
        t_swAcquireAccContext *p1;
        t_swAttachKeyParam *p2;
        t_swSimpleRequest *p3;
        t_swReleaseAccContext *p4;

	if(cswift_dso != NULL)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
		goto err;
		}
	/* Attempt to load libswift.so/swift.dll/whatever. */
	cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
	if(cswift_dso == NULL)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
		goto err;
		}
	if(!(p1 = (t_swAcquireAccContext *)
				DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
			!(p2 = (t_swAttachKeyParam *)
				DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
			!(p3 = (t_swSimpleRequest *)
				DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
			!(p4 = (t_swReleaseAccContext *)
				DSO_bind_func(cswift_dso, CSWIFT_F4)))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
		goto err;
		}
	/* Copy the pointers */
	p_CSwift_AcquireAccContext = p1;
	p_CSwift_AttachKeyParam = p2;
	p_CSwift_SimpleRequest = p3;
	p_CSwift_ReleaseAccContext = p4;
	/* Try and get a context - if not, we may have a DSO but no
	 * accelerator! */
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	release_context(hac);
	/* Everything's fine. */
	return 1;
err:
	if(cswift_dso)
	{
		DSO_free(cswift_dso);
		cswift_dso = NULL;
	}
	p_CSwift_AcquireAccContext = NULL;
	p_CSwift_AttachKeyParam = NULL;
	p_CSwift_SimpleRequest = NULL;
	p_CSwift_ReleaseAccContext = NULL;
	return 0;
	}

static int cswift_finish(ENGINE *e)
	{
	free_CSWIFT_LIBNAME();
	if(cswift_dso == NULL)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
		return 0;
		}
	if(!DSO_free(cswift_dso))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
		return 0;
		}
	cswift_dso = NULL;
	p_CSwift_AcquireAccContext = NULL;
	p_CSwift_AttachKeyParam = NULL;
	p_CSwift_SimpleRequest = NULL;
	p_CSwift_ReleaseAccContext = NULL;
	return 1;
	}

static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
	{
	int initialised = ((cswift_dso == NULL) ? 0 : 1);
	switch(cmd)
		{
	case CSWIFT_CMD_SO_PATH:
		if(p == NULL)
			{
			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
			return 0;
			}
		if(initialised)
			{
			CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
			return 0;
			}
		return set_CSWIFT_LIBNAME((const char *)p);
	default:
		break;
		}
	CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
	return 0;
	}

/* Un petit mod_exp */
static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
			const BIGNUM *m, BN_CTX *ctx)
	{
	/* I need somewhere to store temporary serialised values for
	 * use with the CryptoSwift API calls. A neat cheat - I'll use
	 * BIGNUMs from the BN_CTX but access their arrays directly as
	 * byte arrays <grin>. This way I don't have to clean anything
	 * up. */
	BIGNUM *modulus;
	BIGNUM *exponent;
	BIGNUM *argument;
	BIGNUM *result;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	SW_PARAM sw_param;
	SW_CONTEXT_HANDLE hac;
	int to_return, acquired;
 
	modulus = exponent = argument = result = NULL;
	to_return = 0; /* expect failure */
	acquired = 0;
 
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
	BN_CTX_start(ctx);
	modulus = BN_CTX_get(ctx);
	exponent = BN_CTX_get(ctx);
	argument = BN_CTX_get(ctx);
	result = BN_CTX_get(ctx);
	if(!result)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
		goto err;
		}
	if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
		!bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
		}
	sw_param.type = SW_ALG_EXP;
	sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
		(unsigned char *)modulus->d);
	sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
	sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
		(unsigned char *)exponent->d);
	sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
		goto err;
	default:
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
	arg.value = (unsigned char *)argument->d;
	res.nbytes = BN_num_bytes(m);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
		&res, 1)) != SW_OK)
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
	to_return = 1;
err:
	if(acquired)
		release_context(hac);
	BN_CTX_end(ctx);
	return to_return;
	}


#ifndef OPENSSL_NO_RSA
int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in)
{
	int mod;
	int numbytes = BN_num_bytes(in);

	mod = 0;
	while( ((out->nbytes = (numbytes+mod)) % 32) )
	{
		mod++;
	}
	out->value = (unsigned char*)OPENSSL_malloc(out->nbytes);
	if(!out->value)
	{
		return 0;
	}
	BN_bn2bin(in, &out->value[mod]);
	if(mod)
		memset(out->value, 0, mod);

	return 1;
}
#endif

#ifndef OPENSSL_NO_RSA
/* Un petit mod_exp chinois */
static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
			const BIGNUM *q, const BIGNUM *dmp1,
			const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
	{
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	SW_PARAM sw_param;
	SW_CONTEXT_HANDLE hac;
	BIGNUM *result = NULL;
	BIGNUM *argument = NULL;
	int to_return = 0; /* expect failure */
	int acquired = 0;

	sw_param.up.crt.p.value = NULL;
	sw_param.up.crt.q.value = NULL;
	sw_param.up.crt.dmp1.value = NULL;
	sw_param.up.crt.dmq1.value = NULL;
	sw_param.up.crt.iqmp.value = NULL;
 
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	acquired = 1;

	/* Prepare the params */
	argument = BN_new();
	result = BN_new();
	if(!result || !argument)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
		goto err;
		}


	sw_param.type = SW_ALG_CRT;
	/************************************************************************/
	/* 04/02/2003                                                           */
	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
	/* limitation of cswift with values not a multiple of 32                */
	/************************************************************************/
	if(!cswift_bn_32copy(&sw_param.up.crt.p, p))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(!cswift_bn_32copy(&sw_param.up.crt.q, q))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
	}
	if(	!bn_wexpand(argument, a->top) ||
			!bn_wexpand(result, p->top + q->top))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
		}

	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
		goto err;
	default:
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
	arg.value = (unsigned char *)argument->d;
	res.nbytes = 2 * BN_num_bytes(p);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
		&res, 1)) != SW_OK)
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
	to_return = 1;
err:
	if(sw_param.up.crt.p.value)
		OPENSSL_free(sw_param.up.crt.p.value);
	if(sw_param.up.crt.q.value)
		OPENSSL_free(sw_param.up.crt.q.value);
	if(sw_param.up.crt.dmp1.value)
		OPENSSL_free(sw_param.up.crt.dmp1.value);
	if(sw_param.up.crt.dmq1.value)
		OPENSSL_free(sw_param.up.crt.dmq1.value);
	if(sw_param.up.crt.iqmp.value)
		OPENSSL_free(sw_param.up.crt.iqmp.value);
	if(result)
		BN_free(result);
	if(argument)
		BN_free(argument);
	if(acquired)
		release_context(hac);
	return to_return;
	}
#endif
 
#ifndef OPENSSL_NO_RSA
static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
	{
	int to_return = 0;
	const RSA_METHOD * def_rsa_method;

	if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
		goto err;
		}

	/* Try the limits of RSA (2048 bits) */
	if(BN_num_bytes(rsa->p) > 128 ||
		BN_num_bytes(rsa->q) > 128 ||
		BN_num_bytes(rsa->dmp1) > 128 ||
		BN_num_bytes(rsa->dmq1) > 128 ||
		BN_num_bytes(rsa->iqmp) > 128)
	{
#ifdef RSA_NULL
		def_rsa_method=RSA_null_method();
#else
#if 0
		def_rsa_method=RSA_PKCS1_RSAref();
#else
		def_rsa_method=RSA_PKCS1_SSLeay();
#endif
#endif
		if(def_rsa_method)
			return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx);
	}

	to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
		rsa->dmq1, rsa->iqmp, ctx);
err:
	return to_return;
	}

/* This function is aliased to mod_exp (with the mont stuff dropped). */
static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
	{
	const RSA_METHOD * def_rsa_method;

	/* Try the limits of RSA (2048 bits) */
	if(BN_num_bytes(r) > 256 ||
		BN_num_bytes(a) > 256 ||
		BN_num_bytes(m) > 256)
	{
#ifdef RSA_NULL
		def_rsa_method=RSA_null_method();
#else
#if 0
		def_rsa_method=RSA_PKCS1_RSAref();
#else
		def_rsa_method=RSA_PKCS1_SSLeay();
#endif
#endif
		if(def_rsa_method)
			return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx);
	}

	return cswift_mod_exp(r, a, p, m, ctx);
	}
#endif	/* OPENSSL_NO_RSA */

#ifndef OPENSSL_NO_DSA
static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
	{
	SW_CONTEXT_HANDLE hac;
	SW_PARAM sw_param;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg, res;
	unsigned char *ptr;
	BN_CTX *ctx;
	BIGNUM *dsa_p = NULL;
	BIGNUM *dsa_q = NULL;
	BIGNUM *dsa_g = NULL;
	BIGNUM *dsa_key = NULL;
	BIGNUM *result = NULL;
	DSA_SIG *to_return = NULL;
	int acquired = 0;

	if((ctx = BN_CTX_new()) == NULL)
		goto err;
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
	BN_CTX_start(ctx);
	dsa_p = BN_CTX_get(ctx);
	dsa_q = BN_CTX_get(ctx);
	dsa_g = BN_CTX_get(ctx);
	dsa_key = BN_CTX_get(ctx);
	result = BN_CTX_get(ctx);
	if(!result)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
		goto err;
		}
	if(!bn_wexpand(dsa_p, dsa->p->top) ||
			!bn_wexpand(dsa_q, dsa->q->top) ||
			!bn_wexpand(dsa_g, dsa->g->top) ||
			!bn_wexpand(dsa_key, dsa->priv_key->top) ||
			!bn_wexpand(result, dsa->p->top))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
		}
	sw_param.type = SW_ALG_DSA;
	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
				(unsigned char *)dsa_p->d);
	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
				(unsigned char *)dsa_q->d);
	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
				(unsigned char *)dsa_g->d);
	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
				(unsigned char *)dsa_key->d);
	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
		goto err;
	default:
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg.nbytes = dlen;
	arg.value = (unsigned char *)dgst;
	res.nbytes = BN_num_bytes(dsa->p);
	memset(result->d, 0, res.nbytes);
	res.value = (unsigned char *)result->d;
	/* Perform the operation */
	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
		&res, 1);
	if(sw_status != SW_OK)
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	ptr = (unsigned char *)result->d;
	if((to_return = DSA_SIG_new()) == NULL)
		goto err;
	to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
	to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);

err:
	if(acquired)
		release_context(hac);
	if(ctx)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	return to_return;
	}

static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
				DSA_SIG *sig, DSA *dsa)
	{
	SW_CONTEXT_HANDLE hac;
	SW_PARAM sw_param;
	SW_STATUS sw_status;
	SW_LARGENUMBER arg[2], res;
	unsigned long sig_result;
	BN_CTX *ctx;
	BIGNUM *dsa_p = NULL;
	BIGNUM *dsa_q = NULL;
	BIGNUM *dsa_g = NULL;
	BIGNUM *dsa_key = NULL;
	BIGNUM *argument = NULL;
	int to_return = -1;
	int acquired = 0;

	if((ctx = BN_CTX_new()) == NULL)
		goto err;
	if(!get_context(&hac))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
		goto err;
		}
	acquired = 1;
	/* Prepare the params */
	BN_CTX_start(ctx);
	dsa_p = BN_CTX_get(ctx);
	dsa_q = BN_CTX_get(ctx);
	dsa_g = BN_CTX_get(ctx);
	dsa_key = BN_CTX_get(ctx);
	argument = BN_CTX_get(ctx);
	if(!argument)
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
		goto err;
		}
	if(!bn_wexpand(dsa_p, dsa->p->top) ||
			!bn_wexpand(dsa_q, dsa->q->top) ||
			!bn_wexpand(dsa_g, dsa->g->top) ||
			!bn_wexpand(dsa_key, dsa->pub_key->top) ||
			!bn_wexpand(argument, 40))
		{
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
		goto err;
		}
	sw_param.type = SW_ALG_DSA;
	sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
				(unsigned char *)dsa_p->d);
	sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
	sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
				(unsigned char *)dsa_q->d);
	sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
	sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
				(unsigned char *)dsa_g->d);
	sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
	sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
				(unsigned char *)dsa_key->d);
	sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
	/* Attach the key params */
	sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
	switch(sw_status)
		{
	case SW_OK:
		break;
	case SW_ERR_INPUT_SIZE:
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
		goto err;
	default:
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		}
		goto err;
		}
	/* Prepare the argument and response */
	arg[0].nbytes = dgst_len;
	arg[0].value = (unsigned char *)dgst;
	arg[1].nbytes = 40;
	arg[1].value = (unsigned char *)argument->d;
	memset(arg[1].value, 0, 40);
	BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
	BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
	res.nbytes = 4; /* unsigned long */
	res.value = (unsigned char *)(&sig_result);
	/* Perform the operation */
	sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
		&res, 1);
	if(sw_status != SW_OK)
		{
		char tmpbuf[DECIMAL_SIZE(sw_status)+1];
		CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
		sprintf(tmpbuf, "%ld", sw_status);
		ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
		goto err;
		}
	/* Convert the response */
	to_return = ((sig_result == 0) ? 0 : 1);

err:
	if(acquired)
		release_context(hac);
	if(ctx)
		{
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
		}
	return to_return;
	}
#endif

#ifndef OPENSSL_NO_DH
/* This function is aliased to mod_exp (with the dh and mont dropped). */
static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
		const BIGNUM *a, const BIGNUM *p,
		const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
	{
	return cswift_mod_exp(r, a, p, m, ctx);
	}
#endif

/* Random bytes are good */
static int cswift_rand_bytes(unsigned char *buf, int num)
{
	SW_CONTEXT_HANDLE hac;
	SW_STATUS swrc;
	SW_LARGENUMBER largenum;
	int acquired = 0;
	int to_return = 0; /* assume failure */
	unsigned char buf32[1024];


	if (!get_context(&hac))
	{
		CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE);
		goto err;
	}
	acquired = 1;

	/************************************************************************/
	/* 04/02/2003                                                           */
	/* Modified by Frederic Giudicelli (deny-all.com) to overcome the       */
	/* limitation of cswift with values not a multiple of 32                */
	/************************************************************************/

	while(num >= (int)sizeof(buf32))
	{
		largenum.value = buf;
		largenum.nbytes = sizeof(buf32);
		/* tell CryptoSwift how many bytes we want and where we want it.
		 * Note: - CryptoSwift cannot do more than 4096 bytes at a time.
		 *       - CryptoSwift can only do multiple of 32-bits. */
		swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
		if (swrc != SW_OK)
		{
			char tmpbuf[20];
			CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
			sprintf(tmpbuf, "%ld", swrc);
			ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
			goto err;
		}
		buf += sizeof(buf32);
		num -= sizeof(buf32);
	}
	if(num)
	{
		largenum.nbytes = sizeof(buf32);
		largenum.value = buf32;
		swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
		if (swrc != SW_OK)
		{
			char tmpbuf[20];
			CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED);
			sprintf(tmpbuf, "%ld", swrc);
			ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
			goto err;
		}
		memcpy(buf, largenum.value, num);
	}

	to_return = 1;  /* success */
err:
	if (acquired)
		release_context(hac);

	return to_return;
}

static int cswift_rand_status(void)
{
	return 1;
}


/* This stuff is needed if this ENGINE is being compiled into a self-contained
 * shared-library. */
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
static int bind_fn(ENGINE *e, const char *id)
	{
	if(id && (strcmp(id, engine_cswift_id) != 0))
		return 0;
	if(!bind_helper(e))
		return 0;
	return 1;
	}       
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
#endif /* OPENSSL_NO_DYNAMIC_ENGINE */

#endif /* !OPENSSL_NO_HW_CSWIFT */
#endif /* !OPENSSL_NO_HW */
