/* crypto/engine/hw_atalla.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 <openssl/crypto.h>
#include "cryptlib.h"
#include <openssl/dso.h>
#include <openssl/engine.h>

#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_ATALLA

#ifdef FLAT_INC
#include "atalla.h"
#else
#include "vendor_defns/atalla.h"
#endif

#define ATALLA_LIB_NAME "atalla engine"
#include "hw_atalla_err.c"

static int atalla_destroy(ENGINE *e);
static int atalla_init(ENGINE *e);
static int atalla_finish(ENGINE *e);
static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());

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

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

#ifndef OPENSSL_NO_DSA
/* DSA stuff */
static int atalla_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 atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
		BN_MONT_CTX *m_ctx);
#endif

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

/* The definitions for control commands specific to this engine */
#define ATALLA_CMD_SO_PATH		ENGINE_CMD_BASE
static const ENGINE_CMD_DEFN atalla_cmd_defns[] = {
	{ATALLA_CMD_SO_PATH,
		"SO_PATH",
		"Specifies the path to the 'atasi' 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 atalla_rsa =
	{
	"Atalla RSA method",
	NULL,
	NULL,
	NULL,
	NULL,
	atalla_rsa_mod_exp,
	atalla_mod_exp_mont,
	NULL,
	NULL,
	0,
	NULL,
	NULL,
	NULL
	};
#endif

#ifndef OPENSSL_NO_DSA
/* Our internal DSA_METHOD that we provide pointers to */
static DSA_METHOD atalla_dsa =
	{
	"Atalla DSA method",
	NULL, /* dsa_do_sign */
	NULL, /* dsa_sign_setup */
	NULL, /* dsa_do_verify */
	atalla_dsa_mod_exp, /* dsa_mod_exp */
	atalla_mod_exp_dsa, /* bn_mod_exp */
	NULL, /* init */
	NULL, /* finish */
	0, /* flags */
	NULL /* app_data */
	};
#endif

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

/* Constants used when creating the ENGINE */
static const char *engine_atalla_id = "atalla";
static const char *engine_atalla_name = "Atalla hardware engine support";

/* This internal function is used by ENGINE_atalla() 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_DSA
	const DSA_METHOD *meth2;
#endif
#ifndef OPENSSL_NO_DH
	const DH_METHOD *meth3;
#endif
	if(!ENGINE_set_id(e, engine_atalla_id) ||
			!ENGINE_set_name(e, engine_atalla_name) ||
#ifndef OPENSSL_NO_RSA
			!ENGINE_set_RSA(e, &atalla_rsa) ||
#endif
#ifndef OPENSSL_NO_DSA
			!ENGINE_set_DSA(e, &atalla_dsa) ||
#endif
#ifndef OPENSSL_NO_DH
			!ENGINE_set_DH(e, &atalla_dh) ||
#endif
			!ENGINE_set_destroy_function(e, atalla_destroy) ||
			!ENGINE_set_init_function(e, atalla_init) ||
			!ENGINE_set_finish_function(e, atalla_finish) ||
			!ENGINE_set_ctrl_function(e, atalla_ctrl) ||
			!ENGINE_set_cmd_defns(e, atalla_cmd_defns))
		return 0;

#ifndef OPENSSL_NO_RSA
	/* We know that the "PKCS1_SSLeay()" functions hook properly
	 * to the atalla-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();
	atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
	atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
	atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
	atalla_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();
	atalla_dsa.dsa_do_sign = meth2->dsa_do_sign;
	atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
	atalla_dsa.dsa_do_verify = meth2->dsa_do_verify;
#endif

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

	/* Ensure the atalla error handling is set up */
	ERR_load_ATALLA_strings();
	return 1;
	}

static ENGINE *engine_atalla(void)
	{
	ENGINE *ret = ENGINE_new();
	if(!ret)
		return NULL;
	if(!bind_helper(ret))
		{
		ENGINE_free(ret);
		return NULL;
		}
	return ret;
	}

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

/* This is a process-global DSO handle used for loading and unloading
 * the Atalla 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 *atalla_dso = NULL;

/* These are the function pointers that are (un)set when the library has
 * successfully (un)loaded. */
static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;

/* These are the static string constants for the DSO file name and the function
 * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
 * "atasi.so" rather than something more consistent like "libatasi.so". At the
 * time of writing, I'm not sure what the file name on win32 is but clearly
 * native name translation is not possible (eg libatasi.so on *nix, and
 * atasi.dll on win32). For the purposes of testing, I have created a symbollic
 * link called "libatasi.so" so that we can use native name-translation - a
 * better solution will be needed. */
static const char def_ATALLA_LIBNAME[] = "atasi";
static const char *ATALLA_LIBNAME = def_ATALLA_LIBNAME;
static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";

/* Destructor (complements the "ENGINE_atalla()" constructor) */
static int atalla_destroy(ENGINE *e)
	{
	/* Unload the atalla error strings so any error state including our
	 * functs or reasons won't lead to a segfault (they simply get displayed
	 * without corresponding string data because none will be found). */
	ERR_unload_ATALLA_strings();
	return 1;
	}

/* (de)initialisation functions. */
static int atalla_init(ENGINE *e)
	{
	tfnASI_GetHardwareConfig *p1;
	tfnASI_RSAPrivateKeyOpFn *p2;
	tfnASI_GetPerformanceStatistics *p3;
	/* Not sure of the origin of this magic value, but Ben's code had it
	 * and it seemed to have been working for a few people. :-) */
	unsigned int config_buf[1024];

	if(atalla_dso != NULL)
		{
		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_ALREADY_LOADED);
		goto err;
		}
	/* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
	 * changed unfortunately because the Atalla drivers don't have
	 * standard library names that can be platform-translated well. */
	/* TODO: Work out how to actually map to the names the Atalla
	 * drivers really use - for now a symbollic link needs to be
	 * created on the host system from libatasi.so to atasi.so on
	 * unix variants. */
	atalla_dso = DSO_load(NULL, ATALLA_LIBNAME, NULL, 0);
	if(atalla_dso == NULL)
		{
		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
		goto err;
		}
	if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func(
				atalla_dso, ATALLA_F1)) ||
			!(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func(
				atalla_dso, ATALLA_F2)) ||
			!(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func(
				atalla_dso, ATALLA_F3)))
		{
		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
		goto err;
		}
	/* Copy the pointers */
	p_Atalla_GetHardwareConfig = p1;
	p_Atalla_RSAPrivateKeyOpFn = p2;
	p_Atalla_GetPerformanceStatistics = p3;
	/* Perform a basic test to see if there's actually any unit
	 * running. */
	if(p1(0L, config_buf) != 0)
		{
		ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_UNIT_FAILURE);
		goto err;
		}
	/* Everything's fine. */
	return 1;
err:
	if(atalla_dso)
		DSO_free(atalla_dso);
	p_Atalla_GetHardwareConfig = NULL;
	p_Atalla_RSAPrivateKeyOpFn = NULL;
	p_Atalla_GetPerformanceStatistics = NULL;
	return 0;
	}

static int atalla_finish(ENGINE *e)
	{
	if(atalla_dso == NULL)
		{
		ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_NOT_LOADED);
		return 0;
		}
	if(!DSO_free(atalla_dso))
		{
		ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_UNIT_FAILURE);
		return 0;
		}
	atalla_dso = NULL;
	p_Atalla_GetHardwareConfig = NULL;
	p_Atalla_RSAPrivateKeyOpFn = NULL;
	p_Atalla_GetPerformanceStatistics = NULL;
	return 1;
	}

static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
	{
	int initialised = ((atalla_dso == NULL) ? 0 : 1);
	switch(cmd)
		{
	case ATALLA_CMD_SO_PATH:
		if(p == NULL)
			{
			ATALLAerr(ATALLA_F_ATALLA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
			return 0;
			}
		if(initialised)
			{
			ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_ALREADY_LOADED);
			return 0;
			}
		ATALLA_LIBNAME = (const char *)p;
		return 1;
	default:
		break;
		}
	ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
	return 0;
	}

static int atalla_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 Atalla 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;
	RSAPrivateKey keydata;
	int to_return, numbytes;

	modulus = exponent = argument = result = NULL;
	to_return = 0; /* expect failure */

	if(!atalla_dso)
		{
		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_NOT_LOADED);
		goto err;
		}
	/* 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)
		{
		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_CTX_FULL);
		goto err;
		}
	if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) ||
	   !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top))
		{
		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_EXPAND_FAIL);
		goto err;
		}
	/* Prepare the key-data */
	memset(&keydata, 0,sizeof keydata);
	numbytes = BN_num_bytes(m);
	memset(exponent->d, 0, numbytes);
	memset(modulus->d, 0, numbytes);
	BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p));
	BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m));
	keydata.privateExponent.data = (unsigned char *)exponent->d;
	keydata.privateExponent.len = numbytes;
	keydata.modulus.data = (unsigned char *)modulus->d;
	keydata.modulus.len = numbytes;
	/* Prepare the argument */
	memset(argument->d, 0, numbytes);
	memset(result->d, 0, numbytes);
	BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a));
	/* Perform the operation */
	if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d,
			(unsigned char *)argument->d,
			keydata.modulus.len) != 0)
		{
		ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_REQUEST_FAILED);
		goto err;
		}
	/* Convert the response */
	BN_bin2bn((unsigned char *)result->d, numbytes, r);
	to_return = 1;
err:
	BN_CTX_end(ctx);
	return to_return;
	}

#ifndef OPENSSL_NO_RSA
static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
	{
	BN_CTX *ctx = NULL;
	int to_return = 0;

	if(!atalla_dso)
		{
		ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_NOT_LOADED);
		goto err;
		}
	if((ctx = BN_CTX_new()) == NULL)
		goto err;
	if(!rsa->d || !rsa->n)
		{
		ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_MISSING_KEY_COMPONENTS);
		goto err;
		}
	to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
err:
	if(ctx)
		BN_CTX_free(ctx);
	return to_return;
	}
#endif

#ifndef OPENSSL_NO_DSA
/* This code was liberated and adapted from the commented-out code in
 * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
 * (it doesn't have a CRT form for RSA), this function means that an
 * Atalla system running with a DSA server certificate can handshake
 * around 5 or 6 times faster/more than an equivalent system running with
 * RSA. Just check out the "signs" statistics from the RSA and DSA parts
 * of "openssl speed -engine atalla dsa1024 rsa1024". */
static int atalla_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 (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end;
	/* let t = a2 ^ p2 mod m */
	if (!atalla_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 atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
		const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
		BN_MONT_CTX *m_ctx)
	{
	return atalla_mod_exp(r, a, p, m, ctx);
	}
#endif

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

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

/* 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_atalla_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_ATALLA */
#endif /* !OPENSSL_NO_HW */
