/* ====================================================================
 * Copyright (c) 1999 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 <openssl/bn.h>
#include <string.h>

#include <openssl/e_os2.h>
#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) || defined(__MINGW32__)
#include <sys/types.h>
#include <unistd.h>
#else
#include <process.h>
typedef int pid_t;
#endif

#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
#define getpid GetThreadID
extern int GetThreadID(void);
#elif defined(_WIN32) && !defined(__WATCOMC__)
#define getpid _getpid
#endif

#include <openssl/crypto.h>
#include <openssl/dso.h>
#include <openssl/engine.h>
#include <openssl/buffer.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

#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_AEP
#ifdef FLAT_INC
#include "aep.h"
#else
#include "vendor_defns/aep.h"
#endif

#define AEP_LIB_NAME "aep engine"
#define FAIL_TO_SW 0x10101010

#include "e_aep_err.c"

static int aep_init(ENGINE *e);
static int aep_finish(ENGINE *e);
static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
static int aep_destroy(ENGINE *e);

static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);

/* BIGNUM stuff */
#ifndef OPENSSL_NO_RSA
static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
	const BIGNUM *m, BN_CTX *ctx);

static AEP_RV aep_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

/* RSA stuff */
#ifndef OPENSSL_NO_RSA
static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
#endif

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

/* DSA stuff */
#ifndef OPENSSL_NO_DSA
static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
	BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
	BN_CTX *ctx, BN_MONT_CTX *in_mont);

static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
	BN_MONT_CTX *m_ctx);
#endif

/* DH stuff */
/* This function is aliased to mod_exp (with the DH and mont dropped). */
#ifndef OPENSSL_NO_DH
static int aep_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   */
#ifdef AEPRAND
static int aep_rand(unsigned char *buf, int num);
static int aep_rand_status(void);
#endif

/* Bignum conversion stuff */
static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize);
static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
	unsigned char* AEP_BigNum);
static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
	unsigned char* AEP_BigNum);

/* The definitions for control commands specific to this engine */
#define AEP_CMD_SO_PATH		ENGINE_CMD_BASE
static const ENGINE_CMD_DEFN aep_cmd_defns[] =
	{
	{ AEP_CMD_SO_PATH,
	  "SO_PATH",
	  "Specifies the path to the 'aep' 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 aep_rsa =
	{
	"Aep RSA method",
	NULL,                /*rsa_pub_encrypt*/
	NULL,                /*rsa_pub_decrypt*/
	NULL,                /*rsa_priv_encrypt*/
	NULL,                /*rsa_priv_encrypt*/
	aep_rsa_mod_exp,     /*rsa_mod_exp*/
	aep_mod_exp_mont,    /*bn_mod_exp*/
	NULL,                /*init*/
	NULL,                /*finish*/
	0,                   /*flags*/
	NULL,                /*app_data*/
	NULL,                /*rsa_sign*/
	NULL,                /*rsa_verify*/
	NULL                 /*rsa_keygen*/
	};
#endif

#ifndef OPENSSL_NO_DSA
/* Our internal DSA_METHOD that we provide pointers to */
static DSA_METHOD aep_dsa =
	{
	"Aep DSA method",
	NULL,                /* dsa_do_sign */
	NULL,                /* dsa_sign_setup */
	NULL,                /* dsa_do_verify */
	aep_dsa_mod_exp,     /* dsa_mod_exp */
	aep_mod_exp_dsa,     /* 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 aep_dh =
	{
	"Aep DH method",
	NULL,
	NULL,
	aep_mod_exp_dh,
	NULL,
	NULL,
	0,
	NULL,
	NULL
	};
#endif

#ifdef AEPRAND
/* our internal RAND_method that we provide pointers to  */
static RAND_METHOD aep_random =
	{
	/*"AEP RAND method", */
	NULL,
	aep_rand,
	NULL,
	NULL,
	aep_rand,
	aep_rand_status,
	};
#endif

/*Define an array of structures to hold connections*/
static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];

/*Used to determine if this is a new process*/
static pid_t    recorded_pid = 0;

#ifdef AEPRAND
static AEP_U8   rand_block[RAND_BLK_SIZE];
static AEP_U32  rand_block_bytes = 0;
#endif

/* Constants used when creating the ENGINE */
static const char *engine_aep_id = "aep";
static const char *engine_aep_name = "Aep hardware engine support";

static int max_key_len = 2176;


/* This internal function is used by ENGINE_aep() and possibly by the
 * "dynamic" ENGINE support too */
static int bind_aep(ENGINE *e)
	{
#ifndef OPENSSL_NO_RSA
	const RSA_METHOD  *meth1;
#endif
#ifndef OPENSSL_NO_DSA
	const DSA_METHOD  *meth2;
#endif
#ifndef OPENSSL_NO_DH
	const DH_METHOD	  *meth3;
#endif

	if(!ENGINE_set_id(e, engine_aep_id) ||
		!ENGINE_set_name(e, engine_aep_name) ||
#ifndef OPENSSL_NO_RSA
		!ENGINE_set_RSA(e, &aep_rsa) ||
#endif
#ifndef OPENSSL_NO_DSA
		!ENGINE_set_DSA(e, &aep_dsa) ||
#endif
#ifndef OPENSSL_NO_DH
		!ENGINE_set_DH(e, &aep_dh) ||
#endif
#ifdef AEPRAND
		!ENGINE_set_RAND(e, &aep_random) ||
#endif
		!ENGINE_set_init_function(e, aep_init) ||
		!ENGINE_set_destroy_function(e, aep_destroy) ||
		!ENGINE_set_finish_function(e, aep_finish) ||
		!ENGINE_set_ctrl_function(e, aep_ctrl) ||
		!ENGINE_set_cmd_defns(e, aep_cmd_defns))
		return 0;

#ifndef OPENSSL_NO_RSA
	/* We know that the "PKCS1_SSLeay()" functions hook properly
	 * to the aep-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();
	aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
	aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
	aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
	aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
#endif


#ifndef OPENSSL_NO_DSA
	/* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
	 * bits. */
	meth2 = DSA_OpenSSL();
	aep_dsa.dsa_do_sign    = meth2->dsa_do_sign;
	aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
	aep_dsa.dsa_do_verify  = meth2->dsa_do_verify;

	aep_dsa = *DSA_get_default_method(); 
	aep_dsa.dsa_mod_exp = aep_dsa_mod_exp; 
	aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
#endif

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

	/* Ensure the aep error handling is set up */
	ERR_load_AEPHK_strings();

	return 1;
}

#ifndef OPENSSL_NO_DYNAMIC_ENGINE
static int bind_helper(ENGINE *e, const char *id)
	{
	if(id && (strcmp(id, engine_aep_id) != 0))
		return 0;
	if(!bind_aep(e))
		return 0;
	return 1;
	}       
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
#else
static ENGINE *engine_aep(void)
	{
	ENGINE *ret = ENGINE_new();
	if(!ret)
		return NULL;
	if(!bind_aep(ret))
		{
		ENGINE_free(ret);
		return NULL;
		}
	return ret;
	}

void ENGINE_load_aep(void)
	{
	/* Copied from eng_[openssl|dyn].c */
	ENGINE *toadd = engine_aep();
	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 Aep 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 *aep_dso = NULL;

/* These are the static string constants for the DSO file name and the function
 * symbol names to bind to. 
*/
static const char *AEP_LIBNAME = NULL;
static const char *get_AEP_LIBNAME(void)
	{
	if(AEP_LIBNAME)
		return AEP_LIBNAME;
	return "aep";
	}
static void free_AEP_LIBNAME(void)
	{
	if(AEP_LIBNAME)
		OPENSSL_free((void*)AEP_LIBNAME);
	AEP_LIBNAME = NULL;
	}
static long set_AEP_LIBNAME(const char *name)
	{
	free_AEP_LIBNAME();
	return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
	}

static const char *AEP_F1    = "AEP_ModExp";
static const char *AEP_F2    = "AEP_ModExpCrt";
#ifdef AEPRAND
static const char *AEP_F3    = "AEP_GenRandom";
#endif
static const char *AEP_F4    = "AEP_Finalize";
static const char *AEP_F5    = "AEP_Initialize";
static const char *AEP_F6    = "AEP_OpenConnection";
static const char *AEP_F7    = "AEP_SetBNCallBacks";
static const char *AEP_F8    = "AEP_CloseConnection";

/* These are the function pointers that are (un)set when the library has
 * successfully (un)loaded. */
static t_AEP_OpenConnection    *p_AEP_OpenConnection  = NULL;
static t_AEP_CloseConnection   *p_AEP_CloseConnection = NULL;
static t_AEP_ModExp            *p_AEP_ModExp          = NULL;
static t_AEP_ModExpCrt         *p_AEP_ModExpCrt       = NULL;
#ifdef AEPRAND
static t_AEP_GenRandom         *p_AEP_GenRandom       = NULL;
#endif
static t_AEP_Initialize        *p_AEP_Initialize      = NULL;
static t_AEP_Finalize          *p_AEP_Finalize        = NULL;
static t_AEP_SetBNCallBacks    *p_AEP_SetBNCallBacks  = NULL;

/* (de)initialisation functions. */
static int aep_init(ENGINE *e)
	{
	t_AEP_ModExp          *p1;
	t_AEP_ModExpCrt       *p2;
#ifdef AEPRAND
	t_AEP_GenRandom       *p3;
#endif
	t_AEP_Finalize        *p4;
	t_AEP_Initialize      *p5;
	t_AEP_OpenConnection  *p6;
	t_AEP_SetBNCallBacks  *p7;
	t_AEP_CloseConnection *p8;

	int to_return = 0;
 
	if(aep_dso != NULL)
		{
		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
		goto err;
		}
	/* Attempt to load libaep.so. */

	aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0);
  
	if(aep_dso == NULL)
		{
		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
		goto err;
		}

	if(	!(p1 = (t_AEP_ModExp *)     DSO_bind_func( aep_dso,AEP_F1))  ||
		!(p2 = (t_AEP_ModExpCrt*)   DSO_bind_func( aep_dso,AEP_F2))  ||
#ifdef AEPRAND
		!(p3 = (t_AEP_GenRandom*)   DSO_bind_func( aep_dso,AEP_F3))  ||
#endif
		!(p4 = (t_AEP_Finalize*)    DSO_bind_func( aep_dso,AEP_F4))  ||
		!(p5 = (t_AEP_Initialize*)  DSO_bind_func( aep_dso,AEP_F5))  ||
		!(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6))  ||
		!(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7))  ||
		!(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
		{
		AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
		goto err;
		}

	/* Copy the pointers */
  
	p_AEP_ModExp           = p1;
	p_AEP_ModExpCrt        = p2;
#ifdef AEPRAND
	p_AEP_GenRandom        = p3;
#endif
	p_AEP_Finalize         = p4;
	p_AEP_Initialize       = p5;
	p_AEP_OpenConnection   = p6;
	p_AEP_SetBNCallBacks   = p7;
	p_AEP_CloseConnection  = p8;
 
	to_return = 1;
 
	return to_return;

 err: 

	if(aep_dso)
		DSO_free(aep_dso);
	aep_dso = NULL;
		
	p_AEP_OpenConnection    = NULL;
	p_AEP_ModExp            = NULL;
	p_AEP_ModExpCrt         = NULL;
#ifdef AEPRAND
	p_AEP_GenRandom         = NULL;
#endif
	p_AEP_Initialize        = NULL;
	p_AEP_Finalize          = NULL;
	p_AEP_SetBNCallBacks    = NULL;
	p_AEP_CloseConnection   = NULL;

	return to_return;
	}

/* Destructor (complements the "ENGINE_aep()" constructor) */
static int aep_destroy(ENGINE *e)
	{
	free_AEP_LIBNAME();
	ERR_unload_AEPHK_strings();
	return 1;
	}

static int aep_finish(ENGINE *e)
	{
	int to_return = 0, in_use;
	AEP_RV rv;

	if(aep_dso == NULL)
		{
		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
		goto err;
		}

	rv = aep_close_all_connections(0, &in_use);
	if (rv != AEP_R_OK)
		{
		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
		goto err;
		}
	if (in_use)
		{
		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
		goto err;
		}

	rv = p_AEP_Finalize();
	if (rv != AEP_R_OK)
		{
		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
		goto err;
		}

	if(!DSO_free(aep_dso))
		{
		AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
		goto err;
		}

	aep_dso = NULL;
	p_AEP_CloseConnection   = NULL;
	p_AEP_OpenConnection    = NULL;
	p_AEP_ModExp            = NULL;
	p_AEP_ModExpCrt         = NULL;
#ifdef AEPRAND
	p_AEP_GenRandom         = NULL;
#endif
	p_AEP_Initialize        = NULL;
	p_AEP_Finalize          = NULL;
	p_AEP_SetBNCallBacks    = NULL;

	to_return = 1;
 err:
	return to_return;
	}

static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
	{
	int initialised = ((aep_dso == NULL) ? 0 : 1);
	switch(cmd)
		{
	case AEP_CMD_SO_PATH:
		if(p == NULL)
			{
			AEPHKerr(AEPHK_F_AEP_CTRL,
				ERR_R_PASSED_NULL_PARAMETER);
			return 0;
			}
		if(initialised)
			{
			AEPHKerr(AEPHK_F_AEP_CTRL,
				AEPHK_R_ALREADY_LOADED);
			return 0;
			}
		return set_AEP_LIBNAME((const char*)p);
	default:
		break;
		}
	AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
	return 0;
	}

static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
	const BIGNUM *m, BN_CTX *ctx)
	{
	int to_return = 0;
	int 	r_len = 0;
	AEP_CONNECTION_HNDL hConnection;
	AEP_RV rv;
	
	r_len = BN_num_bits(m);

	/* Perform in software if modulus is too large for hardware. */

	if (r_len > max_key_len){
		AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
		return BN_mod_exp(r, a, p, m, ctx);
	} 

	/*Grab a connection from the pool*/
	rv = aep_get_connection(&hConnection);
	if (rv != AEP_R_OK)
		{     
		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
		return BN_mod_exp(r, a, p, m, ctx);
		}

	/*To the card with the mod exp*/
	rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);

	if (rv !=  AEP_R_OK)
		{
		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
		rv = aep_close_connection(hConnection);
		return BN_mod_exp(r, a, p, m, ctx);
		}

	/*Return the connection to the pool*/
	rv = aep_return_connection(hConnection);
	if (rv != AEP_R_OK)
		{
		AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_RETURN_CONNECTION_FAILED); 
		goto err;
		}

	to_return = 1;
 err:
	return to_return;
	}
	
#ifndef OPENSSL_NO_RSA
static AEP_RV aep_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)
	{
	AEP_RV rv = AEP_R_OK;
	AEP_CONNECTION_HNDL hConnection;

	/*Grab a connection from the pool*/
	rv = aep_get_connection(&hConnection);
	if (rv != AEP_R_OK)
		{
		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
		return FAIL_TO_SW;
		}

	/*To the card with the mod exp*/
	rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
		(void*)iqmp,(void*)r,NULL);
	if (rv != AEP_R_OK)
		{
		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
		rv = aep_close_connection(hConnection);
		return FAIL_TO_SW;
		}

	/*Return the connection to the pool*/
	rv = aep_return_connection(hConnection);
	if (rv != AEP_R_OK)
		{
		AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_RETURN_CONNECTION_FAILED); 
		goto err;
		}
 
 err:
	return rv;
	}
#endif
	

#ifdef AEPRAND
static int aep_rand(unsigned char *buf,int len )
	{
	AEP_RV rv = AEP_R_OK;
	AEP_CONNECTION_HNDL hConnection;

	CRYPTO_w_lock(CRYPTO_LOCK_RAND);

	/*Can the request be serviced with what's already in the buffer?*/
	if (len <= rand_block_bytes)
		{
		memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
		rand_block_bytes -= len;
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
		}
	else
		/*If not the get another block of random bytes*/
		{
		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);

		rv = aep_get_connection(&hConnection);
		if (rv !=  AEP_R_OK)
			{ 
			AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);             
			goto err_nounlock;
			}

		if (len > RAND_BLK_SIZE)
			{
			rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
			if (rv !=  AEP_R_OK)
				{  
				AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
				goto err_nounlock;
				}
			}
		else
			{
			CRYPTO_w_lock(CRYPTO_LOCK_RAND);

			rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
			if (rv !=  AEP_R_OK)
				{       
				AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
	      
				goto err;
				}

			rand_block_bytes = RAND_BLK_SIZE;

			memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
			rand_block_bytes -= len;

			CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
			}

		rv = aep_return_connection(hConnection);
		if (rv != AEP_R_OK)
			{
			AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); 
	  
			goto err_nounlock;
			}
		}
  
	return 1;
 err:
	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
 err_nounlock:
	return 0;
	}
	
static int aep_rand_status(void)
{
	return 1;
}
#endif

#ifndef OPENSSL_NO_RSA
static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
	{
	int to_return = 0;
	AEP_RV rv = AEP_R_OK;

	if (!aep_dso)
		{
		AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
		goto err;
		}

	/*See if we have all the necessary bits for a crt*/
	if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
		{
		rv =  aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);

		if (rv == FAIL_TO_SW){
			const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
			to_return = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
			goto err;
		}
		else if (rv != AEP_R_OK)
			goto err;
		}
	else
		{
		if (!rsa->d || !rsa->n)
			{
			AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
			goto err;
			}
 
		rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
		if  (rv != AEP_R_OK)
			goto err;
	
		}

	to_return = 1;

 err:
	return to_return;
}
#endif

#ifndef OPENSSL_NO_DSA
static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
	BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
	BN_CTX *ctx, BN_MONT_CTX *in_mont)
	{
	BIGNUM t;
	int to_return = 0;
	BN_init(&t);

	/* let rr = a1 ^ p1 mod m */
	if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
	/* let t = a2 ^ p2 mod m */
	if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end;
	/* let rr = rr * t mod m */
	if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
	to_return = 1;
 end: 
	BN_free(&t);
	return to_return;
	}

static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
	const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
	BN_MONT_CTX *m_ctx)
	{  
	return aep_mod_exp(r, a, p, m, ctx); 
	}
#endif

#ifndef OPENSSL_NO_RSA
/* This function is aliased to mod_exp (with the mont stuff dropped). */
static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
	{
	return aep_mod_exp(r, a, p, m, ctx);
	}
#endif

#ifndef OPENSSL_NO_DH
/* This function is aliased to mod_exp (with the dh and mont dropped). */
static int aep_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 aep_mod_exp(r, a, p, m, ctx);
	}
#endif

static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
	{
	int count;
	AEP_RV rv = AEP_R_OK;

	/*Get the current process id*/
	pid_t curr_pid;

	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);

	curr_pid = getpid();

	/*Check if this is the first time this is being called from the current
	  process*/
	if (recorded_pid != curr_pid)
		{
		/*Remember our pid so we can check if we're in a new process*/
		recorded_pid = curr_pid;

		/*Call Finalize to make sure we have not inherited some data
		  from a parent process*/
		p_AEP_Finalize();
     
		/*Initialise the AEP API*/
		rv = p_AEP_Initialize(NULL);

		if (rv != AEP_R_OK)
			{
			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
			recorded_pid = 0;
			goto end;
			}

		/*Set the AEP big num call back functions*/
		rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
			&ConvertAEPBigNum);

		if (rv != AEP_R_OK)
			{
			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
			recorded_pid = 0;
			goto end;
			}

#ifdef AEPRAND
		/*Reset the rand byte count*/
		rand_block_bytes = 0;
#endif

		/*Init the structures*/
		for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
			{
			aep_app_conn_table[count].conn_state = NotConnected;
			aep_app_conn_table[count].conn_hndl  = 0;
			}

		/*Open a connection*/
		rv = p_AEP_OpenConnection(phConnection);

		if (rv != AEP_R_OK)
			{
			AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
			recorded_pid = 0;
			goto end;
			}

		aep_app_conn_table[0].conn_state = InUse;
		aep_app_conn_table[0].conn_hndl = *phConnection;
		goto end;
		}
	/*Check the existing connections to see if we can find a free one*/
	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
		{
		if (aep_app_conn_table[count].conn_state == Connected)
			{
			aep_app_conn_table[count].conn_state = InUse;
			*phConnection = aep_app_conn_table[count].conn_hndl;
			goto end;
			}
		}
	/*If no connections available, we're going to have to try
	  to open a new one*/
	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
		{
		if (aep_app_conn_table[count].conn_state == NotConnected)
			{
			/*Open a connection*/
			rv = p_AEP_OpenConnection(phConnection);

			if (rv != AEP_R_OK)
				{	      
				AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
				goto end;
				}

			aep_app_conn_table[count].conn_state = InUse;
			aep_app_conn_table[count].conn_hndl = *phConnection;
			goto end;
			}
		}
	rv = AEP_R_GENERAL_ERROR;
 end:
	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
	return rv;
	}


static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
	{
	int count;

	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);

	/*Find the connection item that matches this connection handle*/
	for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
		{
		if (aep_app_conn_table[count].conn_hndl == hConnection)
			{
			aep_app_conn_table[count].conn_state = Connected;
			break;
			}
		}

	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);

	return AEP_R_OK;
	}

static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
	{
	int count;
	AEP_RV rv = AEP_R_OK;

	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);

	/*Find the connection item that matches this connection handle*/
	for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
		{
		if (aep_app_conn_table[count].conn_hndl == hConnection)
			{
			rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
			if (rv != AEP_R_OK)
				goto end;
			aep_app_conn_table[count].conn_state = NotConnected;
			aep_app_conn_table[count].conn_hndl  = 0;
			break;
			}
		}

 end:
	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
	return rv;
	}

static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
	{
	int count;
	AEP_RV rv = AEP_R_OK;

	*in_use = 0;
	if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
	for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
		{
		switch (aep_app_conn_table[count].conn_state)
			{
		case Connected:
			rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
			if (rv != AEP_R_OK)
				goto end;
			aep_app_conn_table[count].conn_state = NotConnected;
			aep_app_conn_table[count].conn_hndl  = 0;
			break;
		case InUse:
			(*in_use)++;
			break;
		case NotConnected:
			break;
			}
		}
 end:
	if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
	return rv;
	}

/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
  Note only 32bit Openssl build support*/

static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
	{
	BIGNUM* bn;

	/*Cast the ArbBigNum pointer to our BIGNUM struct*/
	bn = (BIGNUM*) ArbBigNum;

	*BigNumSize = bn->top*BN_BYTES;

	if (BN_BYTES>sizeof(AEP_U32) && (bn->d[bn->top-1]>>BN_BITS4)==0)
		*BigNumSize -= 4;

	return AEP_R_OK;
	}

static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
	unsigned char* AEP_BigNum)
	{
	BIGNUM* bn;
	const union { long one; char little; } is_endian = {1};
	AEP_U32 i,j;

	/*Cast the ArbBigNum pointer to our BIGNUM struct*/
	bn = (BIGNUM*) ArbBigNum;

	/*Must copy data into a (monotone) least significant byte first format
	  performing endian conversion if necessary*/
	if (is_endian.little && sizeof(bn->d[0])==BN_BYTES)
		memcpy(AEP_BigNum, bn->d, BigNumSize);
	else
		{
		BN_ULONG di;

		for (i=0; BigNumSize>=BN_BYTES; i++)
			{
			di = bn->d[i];
			for (j=0; j<BN_BYTES; j++)
				{
				AEP_BigNum[j] = (unsigned char)di;
				di>>=8;
				}
			AEP_BigNum += BN_BYTES;
			BigNumSize -= BN_BYTES;
			}

		if (BigNumSize)
			{
			di = bn->d[i];
			for (j=0; j<BigNumSize; j++)
				{
				AEP_BigNum[j] = (unsigned char)di;
				di>>=8;
				}
			}
		}

	return AEP_R_OK;
	}

/*Turn an AEP Big Num back to a user big num*/
static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
	unsigned char* AEP_BigNum)
	{
	BIGNUM* bn;
	const union { long one; char little; } is_endian = {1};
	int i,j,top;

	bn = (BIGNUM*)ArbBigNum;

	/*Expand the result bn so that it can hold our big num.
	  Size is in bits*/
	top = (BigNumSize+BN_BYTES-1)/BN_BYTES;
	bn_expand(bn, top);
	bn->top = top;
	bn->d[top-1] = 0;

	if (is_endian.little && sizeof(bn->d[0])==BN_BYTES)
		memcpy(bn->d, AEP_BigNum, BigNumSize);
	else
		{
		BN_ULONG di;

		for (i=0; BigNumSize>=BN_BYTES; i++)
			{
			for (di=0,j=BN_BYTES; j!=0; )
				{
				di <<= 8;
				di |= AEP_BigNum[--j];
				}
			bn->d[i] = di;
			AEP_BigNum += BN_BYTES;
			BigNumSize -= BN_BYTES;
			}

		if (BigNumSize)
			{
			for (di=0,j=BigNumSize; j!=0; )
				{
				di <<= 8;
				di |= AEP_BigNum[--j];
				}
			bn->d[i] = di;
			}
		}

	return AEP_R_OK;
}	
	
#endif /* !OPENSSL_NO_HW_AEP */
#endif /* !OPENSSL_NO_HW */
