/* crypto/engine/hw_ncipher.c -*- mode: C; c-file-style: "eay" -*- */
/* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
 * (geoff@geoffthorpe.net) and Dr Stephen N Henson (shenson@bigfoot.com)
 * 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/pem.h>
#include "cryptlib.h"
#include <openssl/dso.h>
#include <openssl/engine.h>
#include <openssl/ui.h>

#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_NCIPHER

/* Attribution notice: nCipher have said several times that it's OK for
 * us to implement a general interface to their boxes, and recently declared
 * their HWCryptoHook to be public, and therefore available for us to use.
 * Thanks, nCipher.
 *
 * The hwcryptohook.h included here is from May 2000.
 * [Richard Levitte]
 */
#ifdef FLAT_INC
#include "hwcryptohook.h"
#else
#include "vendor_defns/hwcryptohook.h"
#endif

static int hwcrhk_destroy(ENGINE *e);
static int hwcrhk_init(ENGINE *e);
static int hwcrhk_finish(ENGINE *e);
static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 

/* Functions to handle mutexes */
static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);

/* BIGNUM stuff */
static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
		const BIGNUM *m, BN_CTX *ctx);

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

/* DH stuff */
/* This function is alised to mod_exp (with the DH and mont dropped). */
static int hwcrhk_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);

/* RAND stuff */
static int hwcrhk_rand_bytes(unsigned char *buf, int num);
static int hwcrhk_rand_status(void);

/* KM stuff */
static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
	UI_METHOD *ui_method, void *callback_data);
static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
	UI_METHOD *ui_method, void *callback_data);
static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
	int ind,long argl, void *argp);

/* Interaction stuff */
static int hwcrhk_insert_card(const char *prompt_info,
	const char *wrong_info,
	HWCryptoHook_PassphraseContext *ppctx,
	HWCryptoHook_CallerContext *cactx);
static int hwcrhk_get_pass(const char *prompt_info,
	int *len_io, char *buf,
	HWCryptoHook_PassphraseContext *ppctx,
	HWCryptoHook_CallerContext *cactx);
static void hwcrhk_log_message(void *logstr, const char *message);

/* The definitions for control commands specific to this engine */
#define HWCRHK_CMD_SO_PATH		ENGINE_CMD_BASE
#define HWCRHK_CMD_FORK_CHECK		(ENGINE_CMD_BASE + 1)
#define HWCRHK_CMD_THREAD_LOCKING	(ENGINE_CMD_BASE + 2)
#define HWCRHK_CMD_SET_USER_INTERFACE   (ENGINE_CMD_BASE + 3)
#define HWCRHK_CMD_SET_CALLBACK_DATA    (ENGINE_CMD_BASE + 4)
static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
	{HWCRHK_CMD_SO_PATH,
		"SO_PATH",
		"Specifies the path to the 'hwcrhk' shared library",
		ENGINE_CMD_FLAG_STRING},
	{HWCRHK_CMD_FORK_CHECK,
		"FORK_CHECK",
		"Turns fork() checking on or off (boolean)",
		ENGINE_CMD_FLAG_NUMERIC},
	{HWCRHK_CMD_THREAD_LOCKING,
		"THREAD_LOCKING",
		"Turns thread-safe locking on or off (boolean)",
		ENGINE_CMD_FLAG_NUMERIC},
	{HWCRHK_CMD_SET_USER_INTERFACE,
		"SET_USER_INTERFACE",
		"Set the global user interface (internal)",
		ENGINE_CMD_FLAG_INTERNAL},
	{HWCRHK_CMD_SET_CALLBACK_DATA,
		"SET_CALLBACK_DATA",
		"Set the global user interface extra data (internal)",
		ENGINE_CMD_FLAG_INTERNAL},
	{0, NULL, NULL, 0}
	};

#ifndef OPENSSL_NO_RSA
/* Our internal RSA_METHOD that we provide pointers to */
static RSA_METHOD hwcrhk_rsa =
	{
	"nCipher RSA method",
	NULL,
	NULL,
	NULL,
	NULL,
	hwcrhk_rsa_mod_exp,
	hwcrhk_mod_exp_mont,
	NULL,
	NULL,
	0,
	NULL,
	NULL,
	NULL
	};
#endif

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

static RAND_METHOD hwcrhk_rand =
	{
	/* "nCipher RAND method", */
	NULL,
	hwcrhk_rand_bytes,
	NULL,
	NULL,
	hwcrhk_rand_bytes,
	hwcrhk_rand_status,
	};

#ifndef OPENSSL_NO_ERR
/* Error function codes for use in hwcrhk operation */
#define HWCRHK_F_HWCRHK_INIT			100
#define HWCRHK_F_HWCRHK_FINISH			101
#define HWCRHK_F_HWCRHK_CTRL			102
#define HWCRHK_F_HWCRHK_LOAD_PRIVKEY		103
#define HWCRHK_F_HWCRHK_LOAD_PUBKEY		104
#define HWCRHK_F_HWCRHK_MOD_EXP			105
#define HWCRHK_F_HWCRHK_RSA_MOD_EXP		106
#define HWCRHK_F_HWCRHK_RAND_BYTES		107
#define HWCRHK_F_HWCRHK_GET_PASS		108
#define HWCRHK_F_HWCRHK_INSERT_CARD		109
/* Error reason codes */
#define HWCRHK_R_ALREADY_LOADED			110
#define HWCRHK_R_DSO_FAILURE			111
#define HWCRHK_R_UNIT_FAILURE			112
#define HWCRHK_R_NOT_LOADED			113
#define HWCRHK_R_BIO_WAS_FREED			114
#define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED	115
#define HWCRHK_R_NOT_INITIALISED		116
#define HWCRHK_R_CHIL_ERROR			117
#define HWCRHK_R_NO_KEY				118
#define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 119
#define HWCRHK_R_REQUEST_FALLBACK		120
#define HWCRHK_R_REQUEST_FAILED			121
#define HWCRHK_R_MISSING_KEY_COMPONENTS		122
#define HWCRHK_R_NO_CALLBACK			123
static ERR_STRING_DATA hwcrhk_str_functs[] =
	{
	/* This first element is changed to match the dynamic 'lib' number */
{ERR_PACK(0,0,0),				"hwcrhk engine code"},
{ERR_PACK(0,HWCRHK_F_HWCRHK_INIT,0),		"hwcrhk_init"},
{ERR_PACK(0,HWCRHK_F_HWCRHK_FINISH,0),				""},
{ERR_PACK(0,HWCRHK_F_HWCRHK_CTRL,0),				""},
{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PRIVKEY,0),				""},
{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PUBKEY,0),				""},
{ERR_PACK(0,HWCRHK_F_HWCRHK_MOD_EXP,0),				""},
{ERR_PACK(0,HWCRHK_F_HWCRHK_RSA_MOD_EXP,0),				""},
{ERR_PACK(0,HWCRHK_F_HWCRHK_RAND_BYTES,0),				""},
{ERR_PACK(0,HWCRHK_F_HWCRHK_GET_PASS,0),				""},
{ERR_PACK(0,HWCRHK_F_HWCRHK_INSERT_CARD,0),				""},
/* Error reason codes */
{HWCRHK_R_ALREADY_LOADED		,"already loaded"},
{HWCRHK_R_DSO_FAILURE			,"DSO failure"},
{HWCRHK_R_UNIT_FAILURE			,"unit failure"},
{HWCRHK_R_NOT_LOADED			,"not loaded"},
{HWCRHK_R_BIO_WAS_FREED			,"BIO was freed"},
{HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED	,"ctrl command not implemented"},
{HWCRHK_R_NOT_INITIALISED		,"not initialised"},
{HWCRHK_R_CHIL_ERROR			,"'chil' error"},
{HWCRHK_R_NO_KEY			,"no key"},
{HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED,"private key algorithms disabled"},
{HWCRHK_R_REQUEST_FALLBACK		,"request fallback"},
{HWCRHK_R_REQUEST_FAILED		,"request failed"},
{HWCRHK_R_MISSING_KEY_COMPONENTS	,"missing key components"},
{HWCRHK_R_NO_CALLBACK			,"no callback"},
{0,NULL}
	};
/* The library number we obtain dynamically from the ERR code */
static int hwcrhk_err_lib = -1;
#define HWCRHKerr(f,r) ERR_PUT_error(hwcrhk_err_lib,(f),(r),__FILE__,__LINE__)
static void hwcrhk_load_error_strings(void)
	{
	if(hwcrhk_err_lib < 0)
		{
		if((hwcrhk_err_lib = ERR_get_next_error_library()) <= 0)
			return;
		hwcrhk_str_functs[0].error = ERR_PACK(hwcrhk_err_lib,0,0);
		ERR_load_strings(hwcrhk_err_lib, hwcrhk_str_functs);
		}
	}
static void hwcrhk_unload_error_strings(void)
	{
	if(hwcrhk_err_lib >= 0)
		{
		ERR_unload_strings(hwcrhk_err_lib, hwcrhk_str_functs);
		hwcrhk_err_lib = -1;
		}
	}
#else
#define HWCRHKerr(f,r)					/* NOP */
static void hwcrhk_load_error_strings(void) { }		/* NOP */
static void hwcrhk_unload_error_strings(void) { }	/* NOP */
#endif

/* Constants used when creating the ENGINE */
static const char *engine_hwcrhk_id = "chil";
static const char *engine_hwcrhk_name = "nCipher hardware engine support";

/* Internal stuff for HWCryptoHook */

/* Some structures needed for proper use of thread locks */
/* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
   into HWCryptoHook_Mutex */
struct HWCryptoHook_MutexValue
	{
	int lockid;
	};

/* hwcryptohook.h has some typedefs that turn
   struct HWCryptoHook_PassphraseContextValue
   into HWCryptoHook_PassphraseContext */
struct HWCryptoHook_PassphraseContextValue
	{
        UI_METHOD *ui_method;
	void *callback_data;
	};

/* hwcryptohook.h has some typedefs that turn
   struct HWCryptoHook_CallerContextValue
   into HWCryptoHook_CallerContext */
struct HWCryptoHook_CallerContextValue
	{
	pem_password_cb *password_callback; /* Deprecated!  Only present for
                                               backward compatibility! */
        UI_METHOD *ui_method;
	void *callback_data;
	};

/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
   BIGNUM's, so lets define a couple of conversion macros */
#define BN2MPI(mp, bn) \
    {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
#define MPI2BN(bn, mp) \
    {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}

static BIO *logstream = NULL;
static int disable_mutex_callbacks = 0;

/* One might wonder why these are needed, since one can pass down at least
   a UI_METHOD and a pointer to callback data to the key-loading functions.
   The thing is that the ModExp and RSAImmed functions can load keys as well,
   if the data they get is in a special, nCipher-defined format (hint: if you
   look at the private exponent of the RSA data as a string, you'll see this
   string: "nCipher KM tool key id", followed by some bytes, followed a key
   identity string, followed by more bytes.  This happens when you use "embed"
   keys instead of "hwcrhk" keys).  Unfortunately, those functions do not take
   any passphrase or caller context, and our functions can't really take any
   callback data either.  Still, the "insert_card" and "get_passphrase"
   callbacks may be called down the line, and will need to know what user
   interface callbacks to call, and having callback data from the application
   may be a nice thing as well, so we need to keep track of that globally. */
static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };

/* Stuff to pass to the HWCryptoHook library */
static HWCryptoHook_InitInfo hwcrhk_globals = {
	0,			/* Flags */
	&logstream,		/* logstream */
	sizeof(BN_ULONG),	/* limbsize */
	0,			/* mslimb first: false for BNs */
	-1,			/* msbyte first: use native */
	0,			/* Max mutexes, 0 = no small limit */
	0,			/* Max simultaneous, 0 = default */

	/* The next few are mutex stuff: we write wrapper functions
	   around the OS mutex functions.  We initialise them to 0
	   here, and change that to actual function pointers in hwcrhk_init()
	   if dynamic locks are supported (that is, if the application
	   programmer has made sure of setting up callbacks bafore starting
	   this engine) *and* if disable_mutex_callbacks hasn't been set by
	   a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */
	sizeof(HWCryptoHook_Mutex),
	0,
	0,
	0,
	0,

	/* The next few are condvar stuff: we write wrapper functions
	   round the OS functions.  Currently not implemented and not
	   and absolute necessity even in threaded programs, therefore
	   0'ed.  Will hopefully be implemented some day, since it
	   enhances the efficiency of HWCryptoHook.  */
	0, /* sizeof(HWCryptoHook_CondVar), */
	0, /* hwcrhk_cv_init, */
	0, /* hwcrhk_cv_wait, */
	0, /* hwcrhk_cv_signal, */
	0, /* hwcrhk_cv_broadcast, */
	0, /* hwcrhk_cv_destroy, */

	hwcrhk_get_pass,	/* pass phrase */
	hwcrhk_insert_card,	/* insert a card */
	hwcrhk_log_message	/* Log message */
};


/* Now, to our own code */

/* This internal function is used by ENGINE_ncipher() 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_hwcrhk_id) ||
			!ENGINE_set_name(e, engine_hwcrhk_name) ||
#ifndef OPENSSL_NO_RSA
			!ENGINE_set_RSA(e, &hwcrhk_rsa) ||
#endif
#ifndef OPENSSL_NO_DH
			!ENGINE_set_DH(e, &hwcrhk_dh) ||
#endif
			!ENGINE_set_RAND(e, &hwcrhk_rand) ||
			!ENGINE_set_BN_mod_exp(e, hwcrhk_mod_exp) ||
			!ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
			!ENGINE_set_init_function(e, hwcrhk_init) ||
			!ENGINE_set_finish_function(e, hwcrhk_finish) ||
			!ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
			!ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
			!ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
			!ENGINE_set_cmd_defns(e, hwcrhk_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();
	hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
	hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
	hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
	hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
#endif

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

	/* Ensure the hwcrhk error handling is set up */
	hwcrhk_load_error_strings();
	return 1;
	}

/* As this is only ever called once, there's no need for locking
 * (indeed - the lock will already be held by our caller!!!) */
ENGINE *ENGINE_ncipher(void)
	{
	ENGINE *ret = ENGINE_new();
	if(!ret)
		return NULL;
	if(!bind_helper(ret))
		{
		ENGINE_free(ret);
		return NULL;
		}
	return ret;
	}

/* This is a process-global DSO handle used for loading and unloading
 * the HWCryptoHook 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 *hwcrhk_dso = NULL;
static HWCryptoHook_ContextHandle hwcrhk_context = 0;
#ifndef OPENSSL_NO_RSA
static int hndidx_rsa = -1;    /* Index for KM handle.  Not really used yet. */
#endif

/* These are the function pointers that are (un)set when the library has
 * successfully (un)loaded. */
static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
#ifndef OPENSSL_NO_RSA
static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
#endif
static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
#ifndef OPENSSL_NO_RSA
static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
#endif
static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;

/* Used in the DSO operations. */
static const char def_HWCRHK_LIBNAME[] = "nfhwcrhk";
static const char *HWCRHK_LIBNAME = def_HWCRHK_LIBNAME;
static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
#ifndef OPENSSL_NO_RSA
static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
#endif
static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
#ifndef OPENSSL_NO_RSA
static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
#endif
static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";

/* HWCryptoHook 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(HWCryptoHook_ContextHandle *hac,
        HWCryptoHook_CallerContext *cac)
	{
	char tempbuf[1024];
	HWCryptoHook_ErrMsgBuf rmsg;

	rmsg.buf = tempbuf;
	rmsg.size = 1024;

        *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
		cac);
	if (!*hac)
                return 0;
        return 1;
	}
 
/* similarly to release one. */
static void release_context(HWCryptoHook_ContextHandle hac)
	{
	p_hwcrhk_Finish(hac);
	}

/* Destructor (complements the "ENGINE_ncipher()" constructor) */
static int hwcrhk_destroy(ENGINE *e)
	{
	hwcrhk_unload_error_strings();
	return 1;
	}

/* (de)initialisation functions. */
static int hwcrhk_init(ENGINE *e)
	{
	HWCryptoHook_Init_t *p1;
	HWCryptoHook_Finish_t *p2;
	HWCryptoHook_ModExp_t *p3;
#ifndef OPENSSL_NO_RSA
	HWCryptoHook_RSA_t *p4;
	HWCryptoHook_RSALoadKey_t *p5;
	HWCryptoHook_RSAGetPublicKey_t *p6;
	HWCryptoHook_RSAUnloadKey_t *p7;
#endif
	HWCryptoHook_RandomBytes_t *p8;
	HWCryptoHook_ModExpCRT_t *p9;

	if(hwcrhk_dso != NULL)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
		goto err;
		}
	/* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
	hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, 0);
	if(hwcrhk_dso == NULL)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
		goto err;
		}
	if(!(p1 = (HWCryptoHook_Init_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
		!(p2 = (HWCryptoHook_Finish_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
		!(p3 = (HWCryptoHook_ModExp_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
#ifndef OPENSSL_NO_RSA
		!(p4 = (HWCryptoHook_RSA_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
		!(p5 = (HWCryptoHook_RSALoadKey_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) ||
		!(p6 = (HWCryptoHook_RSAGetPublicKey_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
		!(p7 = (HWCryptoHook_RSAUnloadKey_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
#endif
		!(p8 = (HWCryptoHook_RandomBytes_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
		!(p9 = (HWCryptoHook_ModExpCRT_t *)
			DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
		goto err;
		}
	/* Copy the pointers */
	p_hwcrhk_Init = p1;
	p_hwcrhk_Finish = p2;
	p_hwcrhk_ModExp = p3;
#ifndef OPENSSL_NO_RSA
	p_hwcrhk_RSA = p4;
	p_hwcrhk_RSALoadKey = p5;
	p_hwcrhk_RSAGetPublicKey = p6;
	p_hwcrhk_RSAUnloadKey = p7;
#endif
	p_hwcrhk_RandomBytes = p8;
	p_hwcrhk_ModExpCRT = p9;

	/* Check if the application decided to support dynamic locks,
	   and if it does, use them. */
	if (disable_mutex_callbacks == 0 &&
		CRYPTO_get_dynlock_create_callback() != NULL &&
		CRYPTO_get_dynlock_lock_callback() != NULL &&
		CRYPTO_get_dynlock_destroy_callback() != NULL)
		{
		hwcrhk_globals.mutex_init = hwcrhk_mutex_init;
		hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock;
		hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
		hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
		}

	/* Try and get a context - if not, we may have a DSO but no
	 * accelerator! */
	if(!get_context(&hwcrhk_context, &password_context))
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE);
		goto err;
		}
	/* Everything's fine. */
#ifndef OPENSSL_NO_RSA
	if (hndidx_rsa == -1)
		hndidx_rsa = RSA_get_ex_new_index(0,
			"nFast HWCryptoHook RSA key handle",
			NULL, NULL, hwcrhk_ex_free);
#endif
	return 1;
err:
	if(hwcrhk_dso)
		DSO_free(hwcrhk_dso);
	hwcrhk_dso = NULL;
	p_hwcrhk_Init = NULL;
	p_hwcrhk_Finish = NULL;
	p_hwcrhk_ModExp = NULL;
#ifndef OPENSSL_NO_RSA
	p_hwcrhk_RSA = NULL;
	p_hwcrhk_RSALoadKey = NULL;
	p_hwcrhk_RSAGetPublicKey = NULL;
	p_hwcrhk_RSAUnloadKey = NULL;
#endif
	p_hwcrhk_ModExpCRT = NULL;
	p_hwcrhk_RandomBytes = NULL;
	return 0;
	}

static int hwcrhk_finish(ENGINE *e)
	{
	int to_return = 1;
	if(hwcrhk_dso == NULL)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED);
		to_return = 0;
		goto err;
		}
	release_context(hwcrhk_context);
	if(!DSO_free(hwcrhk_dso))
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE);
		to_return = 0;
		goto err;
		}
 err:
	if (logstream)
		BIO_free(logstream);
	hwcrhk_dso = NULL;
	p_hwcrhk_Init = NULL;
	p_hwcrhk_Finish = NULL;
	p_hwcrhk_ModExp = NULL;
#ifndef OPENSSL_NO_RSA
	p_hwcrhk_RSA = NULL;
	p_hwcrhk_RSALoadKey = NULL;
	p_hwcrhk_RSAGetPublicKey = NULL;
	p_hwcrhk_RSAUnloadKey = NULL;
#endif
	p_hwcrhk_ModExpCRT = NULL;
	p_hwcrhk_RandomBytes = NULL;
	return to_return;
	}

static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
	{
	int to_return = 1;

	switch(cmd)
		{
	case HWCRHK_CMD_SO_PATH:
		if(hwcrhk_dso)
			{
			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
			return 0;
			}
		if(p == NULL)
			{
			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
			return 0;
			}
		HWCRHK_LIBNAME = (const char *)p;
		return 1;
	case ENGINE_CTRL_SET_LOGSTREAM:
		{
		BIO *bio = (BIO *)p;

		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
		if (logstream)
			{
			BIO_free(logstream);
			logstream = NULL;
			}
		if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
			logstream = bio;
		else
			HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
		}
		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
		break;
	case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
		password_context.password_callback = (pem_password_cb *)f;
		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
		break;
	case ENGINE_CTRL_SET_USER_INTERFACE:
		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
		password_context.ui_method = (UI_METHOD *)p;
		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
		break;
	case ENGINE_CTRL_SET_CALLBACK_DATA:
		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
		password_context.callback_data = p;
		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
		break;
	/* this enables or disables the "SimpleForkCheck" flag used in the
	 * initialisation structure. */
	case ENGINE_CTRL_CHIL_SET_FORKCHECK:
	case HWCRHK_CMD_FORK_CHECK:
		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
		if(i)
			hwcrhk_globals.flags |=
				HWCryptoHook_InitFlags_SimpleForkCheck;
		else
			hwcrhk_globals.flags &=
				~HWCryptoHook_InitFlags_SimpleForkCheck;
		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
		break;
	/* This will prevent the initialisation function from "installing"
	 * the mutex-handling callbacks, even if they are available from
	 * within the library (or were provided to the library from the
	 * calling application). This is to remove any baggage for
	 * applications not using multithreading. */
	case ENGINE_CTRL_CHIL_NO_LOCKING:
		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
		disable_mutex_callbacks = 1;
		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
		break;
	case HWCRHK_CMD_THREAD_LOCKING:
		CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
		disable_mutex_callbacks = ((i == 0) ? 0 : 1);
		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
		break;

	/* The command isn't understood by this engine */
	default:
		HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
			HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
		to_return = 0;
		break;
		}

	return to_return;
	}

static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
	UI_METHOD *ui_method, void *callback_data)
	{
#ifndef OPENSSL_NO_RSA
	RSA *rtmp = NULL;
#endif
	EVP_PKEY *res = NULL;
#ifndef OPENSSL_NO_RSA
	HWCryptoHook_MPI e, n;
	HWCryptoHook_RSAKeyHandle *hptr;
#endif
#if !defined(OPENSSL_NO_RSA)
	HWCryptoHook_ErrMsgBuf rmsg;
#endif
	HWCryptoHook_PassphraseContext ppctx;

	if(!hwcrhk_context)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
			HWCRHK_R_NOT_INITIALISED);
		goto err;
		}
#ifndef OPENSSL_NO_RSA
	hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
	if (!hptr)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
			ERR_R_MALLOC_FAILURE);
		goto err;
		}
        ppctx.ui_method = ui_method;
	ppctx.callback_data = callback_data;
	if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
		&rmsg, &ppctx))
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
			HWCRHK_R_CHIL_ERROR);
		ERR_add_error_data(1,rmsg.buf);
		goto err;
		}
	if (!*hptr)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
			HWCRHK_R_NO_KEY);
		goto err;
		}
#endif
#ifndef OPENSSL_NO_RSA
	rtmp = RSA_new_method(eng);
	RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr);
	rtmp->e = BN_new();
	rtmp->n = BN_new();
	rtmp->flags |= RSA_FLAG_EXT_PKEY;
	MPI2BN(rtmp->e, e);
	MPI2BN(rtmp->n, n);
	if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
		!= HWCRYPTOHOOK_ERROR_MPISIZE)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,HWCRHK_R_CHIL_ERROR);
		ERR_add_error_data(1,rmsg.buf);
		goto err;
		}

	bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
	bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
	MPI2BN(rtmp->e, e);
	MPI2BN(rtmp->n, n);

	if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
			HWCRHK_R_CHIL_ERROR);
		ERR_add_error_data(1,rmsg.buf);
		goto err;
		}
	rtmp->e->top = e.size / sizeof(BN_ULONG);
	bn_fix_top(rtmp->e);
	rtmp->n->top = n.size / sizeof(BN_ULONG);
	bn_fix_top(rtmp->n);

	res = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(res, rtmp);
#endif

        if (!res)
                HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
                        HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);

	return res;
 err:
	if (res)
		EVP_PKEY_free(res);
#ifndef OPENSSL_NO_RSA
	if (rtmp)
		RSA_free(rtmp);
#endif
	return NULL;
	}

static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
	UI_METHOD *ui_method, void *callback_data)
	{
	EVP_PKEY *res = NULL;

#ifndef OPENSSL_NO_RSA
        res = hwcrhk_load_privkey(eng, key_id,
                ui_method, callback_data);
#endif

	if (res)
		switch(res->type)
			{
#ifndef OPENSSL_NO_RSA
		case EVP_PKEY_RSA:
			{
			RSA *rsa = NULL;

			CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
			rsa = res->pkey.rsa;
			res->pkey.rsa = RSA_new();
			res->pkey.rsa->n = rsa->n;
			res->pkey.rsa->e = rsa->e;
			CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
			RSA_free(rsa);
			}
#endif
		default:
			HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
				HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
			goto err;
			}

	return res;
 err:
	if (res)
		EVP_PKEY_free(res);
	return NULL;
	}

/* A little mod_exp */
static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
			const BIGNUM *m, BN_CTX *ctx)
	{
	char tempbuf[1024];
	HWCryptoHook_ErrMsgBuf rmsg;
	/* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's,
	   we use them directly, plus a little macro magic.  We only
	   thing we need to make sure of is that enough space is allocated. */
	HWCryptoHook_MPI m_a, m_p, m_n, m_r;
	int to_return, ret;
 
	to_return = 0; /* expect failure */
	rmsg.buf = tempbuf;
	rmsg.size = 1024;

	if(!hwcrhk_context)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
		goto err;
		}
	/* Prepare the params */
	bn_expand2(r, m->top);	/* Check for error !! */
	BN2MPI(m_a, a);
	BN2MPI(m_p, p);
	BN2MPI(m_n, m);
	MPI2BN(r, m_r);

	/* Perform the operation */
	ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg);

	/* Convert the response */
	r->top = m_r.size / sizeof(BN_ULONG);
	bn_fix_top(r);

	if (ret < 0)
		{
		/* FIXME: When this error is returned, HWCryptoHook is
		   telling us that falling back to software computation
		   might be a good thing. */
		if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
			{
			HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK);
			}
		else
			{
			HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED);
			}
		ERR_add_error_data(1,rmsg.buf);
		goto err;
		}

	to_return = 1;
err:
	return to_return;
	}

#ifndef OPENSSL_NO_RSA 
static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa)
	{
	char tempbuf[1024];
	HWCryptoHook_ErrMsgBuf rmsg;
	HWCryptoHook_RSAKeyHandle *hptr;
	int to_return = 0, ret;

	if(!hwcrhk_context)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
		goto err;
		}

	/* This provides support for nForce keys.  Since that's opaque data
	   all we do is provide a handle to the proper key and let HWCryptoHook
	   take care of the rest. */
	if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa))
		!= NULL)
		{
		HWCryptoHook_MPI m_a, m_r;

		if(!rsa->n)
			{
			HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
				HWCRHK_R_MISSING_KEY_COMPONENTS);
			goto err;
			}

		rmsg.buf = tempbuf;
		rmsg.size = 1024;

		/* Prepare the params */
		bn_expand2(r, rsa->n->top); /* Check for error !! */
		BN2MPI(m_a, I);
		MPI2BN(r, m_r);

		/* Perform the operation */
		ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg);

		/* Convert the response */
		r->top = m_r.size / sizeof(BN_ULONG);
		bn_fix_top(r);

		if (ret < 0)
			{
			/* FIXME: When this error is returned, HWCryptoHook is
			   telling us that falling back to software computation
			   might be a good thing. */
			if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
				{
				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
					HWCRHK_R_REQUEST_FALLBACK);
				}
			else
				{
				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
					HWCRHK_R_REQUEST_FAILED);
				}
			ERR_add_error_data(1,rmsg.buf);
			goto err;
			}
		}
	else
		{
		HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r;

		if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
			{
			HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
				HWCRHK_R_MISSING_KEY_COMPONENTS);
			goto err;
			}

		rmsg.buf = tempbuf;
		rmsg.size = 1024;

		/* Prepare the params */
		bn_expand2(r, rsa->n->top); /* Check for error !! */
		BN2MPI(m_a, I);
		BN2MPI(m_p, rsa->p);
		BN2MPI(m_q, rsa->q);
		BN2MPI(m_dmp1, rsa->dmp1);
		BN2MPI(m_dmq1, rsa->dmq1);
		BN2MPI(m_iqmp, rsa->iqmp);
		MPI2BN(r, m_r);

		/* Perform the operation */
		ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q,
			m_dmp1, m_dmq1, m_iqmp, &m_r, NULL);

		/* Convert the response */
		r->top = m_r.size / sizeof(BN_ULONG);
		bn_fix_top(r);

		if (ret < 0)
			{
			/* FIXME: When this error is returned, HWCryptoHook is
			   telling us that falling back to software computation
			   might be a good thing. */
			if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
				{
				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
					HWCRHK_R_REQUEST_FALLBACK);
				}
			else
				{
				HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
					HWCRHK_R_REQUEST_FAILED);
				}
			ERR_add_error_data(1,rmsg.buf);
			goto err;
			}
		}
	/* If we're here, we must be here with some semblance of success :-) */
	to_return = 1;
err:
	return to_return;
	}
#endif

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

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

/* Random bytes are good */
static int hwcrhk_rand_bytes(unsigned char *buf, int num)
	{
	char tempbuf[1024];
	HWCryptoHook_ErrMsgBuf rmsg;
	int to_return = 0; /* assume failure */
	int ret;

	rmsg.buf = tempbuf;
	rmsg.size = 1024;

	if(!hwcrhk_context)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED);
		goto err;
		}

	ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg);
	if (ret < 0)
		{
		/* FIXME: When this error is returned, HWCryptoHook is
		   telling us that falling back to software computation
		   might be a good thing. */
		if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
			{
			HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
				HWCRHK_R_REQUEST_FALLBACK);
			}
		else
			{
			HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
				HWCRHK_R_REQUEST_FAILED);
			}
		ERR_add_error_data(1,rmsg.buf);
		goto err;
		}
	to_return = 1;
 err:
	return to_return;
	}

static int hwcrhk_rand_status(void)
	{
	return 1;
	}

/* This cleans up an RSA KM key, called when ex_data is freed */

static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
	int ind,long argl, void *argp)
{
	char tempbuf[1024];
	HWCryptoHook_ErrMsgBuf rmsg;
#ifndef OPENSSL_NO_RSA
	HWCryptoHook_RSAKeyHandle *hptr;
#endif
#if !defined(OPENSSL_NO_RSA)
	int ret;
#endif

	rmsg.buf = tempbuf;
	rmsg.size = 1024;

#ifndef OPENSSL_NO_RSA
	hptr = (HWCryptoHook_RSAKeyHandle *) item;
	if(hptr)
                {
                ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL);
                OPENSSL_free(hptr);
                }
#endif
}

/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
 * these just wrap the POSIX functions and add some logging.
 */

static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
	HWCryptoHook_CallerContext *cactx)
	{
	mt->lockid = CRYPTO_get_new_dynlockid();
	if (mt->lockid == 0)
		return -1;
	return 0;
	}

static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
	{
	CRYPTO_w_lock(mt->lockid);
	return 0;
	}

void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
	{
	CRYPTO_w_unlock(mt->lockid);
	}

static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
	{
	CRYPTO_destroy_dynlockid(mt->lockid);
	}

static int hwcrhk_get_pass(const char *prompt_info,
	int *len_io, char *buf,
	HWCryptoHook_PassphraseContext *ppctx,
	HWCryptoHook_CallerContext *cactx)
	{
	pem_password_cb *callback = NULL;
	void *callback_data = NULL;
        UI_METHOD *ui_method = NULL;

        if (cactx)
                {
                if (cactx->ui_method)
                        ui_method = cactx->ui_method;
		if (cactx->password_callback)
			callback = cactx->password_callback;
		if (cactx->callback_data)
			callback_data = cactx->callback_data;
                }
	if (ppctx)
		{
                if (ppctx->ui_method)
                        {
                        ui_method = ppctx->ui_method;
                        callback = NULL;
                        }
		if (ppctx->callback_data)
			callback_data = ppctx->callback_data;
		}
	if (callback == NULL && ui_method == NULL)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK);
		return -1;
		}

        if (ui_method)
                {
                UI *ui = UI_new_method(ui_method);
                if (ui)
                        {
                        int ok;
                        char *prompt = UI_construct_prompt(ui,
                                "pass phrase", prompt_info);

                        ok = UI_add_input_string(ui,prompt,
                                UI_INPUT_FLAG_DEFAULT_PWD,
				buf,0,(*len_io) - 1);
                        UI_add_user_data(ui, callback_data);
			UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);

			if (ok >= 0)
				do
					{
					ok=UI_process(ui);
					}
				while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));

                        if (ok >= 0)
                                *len_io = strlen(buf);

                        UI_free(ui);
                        OPENSSL_free(prompt);
                        }
                }
        else
                {
                *len_io = callback(buf, *len_io, 0, callback_data);
                }
	if(!*len_io)
		return -1;
	return 0;
	}

static int hwcrhk_insert_card(const char *prompt_info,
		      const char *wrong_info,
		      HWCryptoHook_PassphraseContext *ppctx,
		      HWCryptoHook_CallerContext *cactx)
        {
        int ok = -1;
        UI *ui;
	void *callback_data = NULL;
        UI_METHOD *ui_method = NULL;

        if (cactx)
                {
                if (cactx->ui_method)
                        ui_method = cactx->ui_method;
		if (cactx->callback_data)
			callback_data = cactx->callback_data;
                }
	if (ppctx)
		{
                if (ppctx->ui_method)
                        ui_method = ppctx->ui_method;
		if (ppctx->callback_data)
			callback_data = ppctx->callback_data;
		}
	if (ui_method == NULL)
		{
		HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD,
			HWCRHK_R_NO_CALLBACK);
		return -1;
		}

	ui = UI_new_method(ui_method);

	if (ui)
		{
		char answer;
		char buf[BUFSIZ];

		if (wrong_info)
			BIO_snprintf(buf, sizeof(buf)-1,
				"Current card: \"%s\"\n", wrong_info);
		ok = UI_dup_info_string(ui, buf);
		if (ok >= 0 && prompt_info)
			{
			BIO_snprintf(buf, sizeof(buf)-1,
				"Insert card \"%s\"", prompt_info);
			ok = UI_dup_input_boolean(ui, buf,
				"\n then hit <enter> or C<enter> to cancel\n",
				"\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer);
			}
		UI_add_user_data(ui, callback_data);

		if (ok >= 0)
			ok = UI_process(ui);
		UI_free(ui);

		if (ok == -2 || (ok >= 0 && answer == 'C'))
			ok = 1;
		else if (ok < 0)
			ok = -1;
		else
			ok = 0;
		}
	return ok;
	}

static void hwcrhk_log_message(void *logstr, const char *message)
	{
	BIO *lstream = NULL;

	CRYPTO_w_lock(CRYPTO_LOCK_BIO);
	if (logstr)
		lstream=*(BIO **)logstr;
	if (lstream)
		{
		BIO_write(lstream, message, strlen(message));
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
	}

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

#endif /* !OPENSSL_NO_HW_NCIPHER */
#endif /* !OPENSSL_NO_HW */
