/* crypto/engine/hw_ibmca.c */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
 * project 2000.
 */
/* ====================================================================
 * 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).
 *
 */

/* (C) COPYRIGHT International Business Machines Corp. 2001 */

#include <stdio.h>
#include <openssl/crypto.h>
#include <openssl/dso.h>
#include <openssl/engine.h>

#ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_IBMCA

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

#define IBMCA_LIB_NAME "ibmca engine"
#include "hw_ibmca_err.c"

static int ibmca_destroy(ENGINE *e);
static int ibmca_init(ENGINE *e);
static int ibmca_finish(ENGINE *e);
static int ibmca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());

static const char *IBMCA_F1 = "icaOpenAdapter";
static const char *IBMCA_F2 = "icaCloseAdapter";
static const char *IBMCA_F3 = "icaRsaModExpo";
static const char *IBMCA_F4 = "icaRandomNumberGenerate";
static const char *IBMCA_F5 = "icaRsaCrt";

ICA_ADAPTER_HANDLE handle=0;

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

static int ibmca_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);

#ifndef OPENSSL_NO_RSA  
/* RSA stuff */
static int ibmca_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 ibmca_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 ibmca_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 ibmca_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 ibmca_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 ibmca_rand_bytes(unsigned char *buf, int num);
static int ibmca_rand_status(void);


/* WJH - check for more commands, like in nuron */

/* The definitions for control commands specific to this engine */
#define IBMCA_CMD_SO_PATH		ENGINE_CMD_BASE
static const ENGINE_CMD_DEFN ibmca_cmd_defns[] = {
	{IBMCA_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 ibmca_rsa =
        {
        "Ibmca RSA method",
        NULL,
        NULL,
        NULL,
        NULL,
        ibmca_rsa_mod_exp,
        ibmca_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 ibmca_dsa =
        {
        "Ibmca DSA method",
        NULL, /* dsa_do_sign */
        NULL, /* dsa_sign_setup */
        NULL, /* dsa_do_verify */
        ibmca_dsa_mod_exp, /* dsa_mod_exp */
        ibmca_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 ibmca_dh =
        {
        "Ibmca DH method",
        NULL,
        NULL,
        ibmca_mod_exp_dh,
        NULL,
        NULL,
        0,
        NULL
        };
#endif

static RAND_METHOD ibmca_rand =
        {
        /* "IBMCA RAND method", */
        NULL,
        ibmca_rand_bytes,
        NULL,
        NULL,
        ibmca_rand_bytes,
        ibmca_rand_status,
        };

/* Constants used when creating the ENGINE */
static const char *engine_ibmca_id = "ibmca";
static const char *engine_ibmca_name = "Ibmca hardware engine support";

/* This internal function is used by ENGINE_ibmca() 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_ibmca_id) ||
		!ENGINE_set_name(e, engine_ibmca_name) ||
#ifndef OPENSSL_NO_RSA
		!ENGINE_set_RSA(e, &ibmca_rsa) ||
#endif
#ifndef OPENSSL_NO_DSA
		!ENGINE_set_DSA(e, &ibmca_dsa) ||
#endif
#ifndef OPENSSL_NO_DH
		!ENGINE_set_DH(e, &ibmca_dh) ||
#endif
		!ENGINE_set_RAND(e, &ibmca_rand) ||
		!ENGINE_set_destroy_function(e, ibmca_destroy) ||
		!ENGINE_set_init_function(e, ibmca_init) ||
		!ENGINE_set_finish_function(e, ibmca_finish) ||
		!ENGINE_set_ctrl_function(e, ibmca_ctrl) ||
		!ENGINE_set_cmd_defns(e, ibmca_cmd_defns))
		return 0;

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

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

	/* Ensure the ibmca error handling is set up */
	ERR_load_IBMCA_strings(); 
	return 1;
	}

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

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

/* Destructor (complements the "ENGINE_ibmca()" constructor) */
static int ibmca_destroy(ENGINE *e)
	{
	/* Unload the ibmca 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_IBMCA_strings(); 
	return 1;
	}


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

/* These are the function pointers that are (un)set when the library has
 * successfully (un)loaded. */

static unsigned int    (ICA_CALL *p_icaOpenAdapter)();
static unsigned int    (ICA_CALL *p_icaCloseAdapter)();
static unsigned int    (ICA_CALL *p_icaRsaModExpo)();
static unsigned int    (ICA_CALL *p_icaRandomNumberGenerate)();
static unsigned int    (ICA_CALL *p_icaRsaCrt)();

/* utility function to obtain a context */
static int get_context(ICA_ADAPTER_HANDLE *p_handle)
        {
        unsigned int status=0;

        status = p_icaOpenAdapter(0, p_handle);
        if(status != 0)
                return 0;
        return 1;
        }

/* similarly to release one. */
static void release_context(ICA_ADAPTER_HANDLE handle)
        {
        p_icaCloseAdapter(handle);
        }

/* (de)initialisation functions. */
static int ibmca_init(ENGINE *e)
        {

        void          (*p1)();
        void          (*p2)();
        void          (*p3)();
        void          (*p4)();
        void          (*p5)();

        if(ibmca_dso != NULL)
                {
                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_ALREADY_LOADED);
                goto err;
                }
        /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
         * changed unfortunately because the Ibmca drivers don't have
         * standard library names that can be platform-translated well. */
        /* TODO: Work out how to actually map to the names the Ibmca
         * 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. */

	/* WJH XXX check name translation */

        ibmca_dso = DSO_load(NULL, IBMCA_LIBNAME, NULL,
			     /* DSO_FLAG_NAME_TRANSLATION */ 0);
        if(ibmca_dso == NULL)
                {
                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_DSO_FAILURE);
                goto err;
                }

        if(!(p1 = DSO_bind_func(
                ibmca_dso, IBMCA_F1)) ||
                !(p2 = DSO_bind_func(
                        ibmca_dso, IBMCA_F2)) ||
                !(p3 = DSO_bind_func(
                        ibmca_dso, IBMCA_F3)) ||
                !(p4 = DSO_bind_func(
                        ibmca_dso, IBMCA_F4)) ||
                !(p5 = DSO_bind_func(
                        ibmca_dso, IBMCA_F5)))
                {
                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_DSO_FAILURE);
                goto err;
                }

        /* Copy the pointers */

	p_icaOpenAdapter =           (unsigned int (ICA_CALL *)())p1;
	p_icaCloseAdapter =          (unsigned int (ICA_CALL *)())p2;
	p_icaRsaModExpo =            (unsigned int (ICA_CALL *)())p3;
	p_icaRandomNumberGenerate =  (unsigned int (ICA_CALL *)())p4;
	p_icaRsaCrt =                (unsigned int (ICA_CALL *)())p5;

        if(!get_context(&handle))
                {
                IBMCAerr(IBMCA_F_IBMCA_INIT,IBMCA_R_UNIT_FAILURE);
                goto err;
                }

        return 1;
 err:
        if(ibmca_dso)
                DSO_free(ibmca_dso);

        p_icaOpenAdapter = NULL;
        p_icaCloseAdapter = NULL;
        p_icaRsaModExpo = NULL;
        p_icaRandomNumberGenerate = NULL;

        return 0;
        }

static int ibmca_finish(ENGINE *e)
        {
        if(ibmca_dso == NULL)
                {
                IBMCAerr(IBMCA_F_IBMCA_FINISH,IBMCA_R_NOT_LOADED);
                return 0;
                }
        release_context(handle);
        if(!DSO_free(ibmca_dso))
                {
                IBMCAerr(IBMCA_F_IBMCA_FINISH,IBMCA_R_DSO_FAILURE);
                return 0;
                }
        ibmca_dso = NULL;

        return 1;
        }

static int ibmca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
	{
	int initialised = ((ibmca_dso == NULL) ? 0 : 1);
	switch(cmd)
		{
	case IBMCA_CMD_SO_PATH:
		if(p == NULL)
			{
			IBMCAerr(IBMCA_F_IBMCA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
			return 0;
			}
		if(initialised)
			{
			IBMCAerr(IBMCA_F_IBMCA_CTRL,IBMCA_R_ALREADY_LOADED);
			return 0;
			}
		IBMCA_LIBNAME = (const char *)p;
		return 1;
	default:
		break;
		}
	IBMCAerr(IBMCA_F_IBMCA_CTRL,IBMCA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
	return 0;
	}


static int ibmca_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 Ibmca 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 *argument=NULL;
        BIGNUM *result=NULL;
        BIGNUM *key=NULL;
        int to_return;
	int inLen, outLen, tmpLen;


        ICA_KEY_RSA_MODEXPO *publKey=NULL;
        unsigned int rc;

        to_return = 0; /* expect failure */

        if(!ibmca_dso)
                {
                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_NOT_LOADED);
                goto err;
                }
        /* Prepare the params */
	BN_CTX_start(ctx);
        argument = BN_CTX_get(ctx);
        result = BN_CTX_get(ctx);
        key = BN_CTX_get(ctx);

        if( !argument || !result || !key)
                {
                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_BN_CTX_FULL);
                goto err;
                }


	if(!bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top) ||
                !bn_wexpand(key, sizeof(*publKey)/BN_BYTES))

                {
                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_BN_EXPAND_FAIL);
                goto err;
                }

        publKey = (ICA_KEY_RSA_MODEXPO *)key->d;

        if (publKey == NULL)
                {
                goto err;
                }
        memset(publKey, 0, sizeof(ICA_KEY_RSA_MODEXPO));

        publKey->keyType   =  CORRECT_ENDIANNESS(ME_KEY_TYPE);
        publKey->keyLength =  CORRECT_ENDIANNESS(sizeof(ICA_KEY_RSA_MODEXPO));
        publKey->expOffset =  (char *) publKey->keyRecord - (char *) publKey;

        /* A quirk of the card: the exponent length has to be the same
     as the modulus (key) length */

	outLen = BN_num_bytes(m);

/* check for modulus length SAB*/
	if (outLen > 256 ) {
		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_MEXP_LENGTH_TO_LARGE);
		goto err;
	}
/* check for modulus length SAB*/


	publKey->expLength = publKey->nLength = outLen;
/* SAB Check for underflow condition
    the size of the exponent is less than the size of the parameter
    then we have a big problem and will underflow the keyRecord
   buffer.  Bad stuff could happen then
*/
if (outLen < BN_num_bytes(p)){
	IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_UNDERFLOW_KEYRECORD);
	goto err;
}
/* SAB End check for underflow */


        BN_bn2bin(p, &publKey->keyRecord[publKey->expLength -
                BN_num_bytes(p)]);
        BN_bn2bin(m, &publKey->keyRecord[publKey->expLength]);



        publKey->modulusBitLength = CORRECT_ENDIANNESS(publKey->nLength * 8);
        publKey->nOffset   = CORRECT_ENDIANNESS(publKey->expOffset + 
						publKey->expLength);

        publKey->expOffset = CORRECT_ENDIANNESS((char *) publKey->keyRecord - 
						(char *) publKey);

	tmpLen = outLen;
	publKey->expLength = publKey->nLength = CORRECT_ENDIANNESS(tmpLen);

  /* Prepare the argument */

	memset(argument->d, 0, outLen);
	BN_bn2bin(a, (unsigned char *)argument->d + outLen -
                 BN_num_bytes(a));

	inLen = outLen;

  /* Perform the operation */

          if( (rc = p_icaRsaModExpo(handle, inLen,(unsigned char *)argument->d,
                publKey, &outLen, (unsigned char *)result->d))
                !=0 )

                {
                printf("rc = %d\n", rc);
                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP,IBMCA_R_REQUEST_FAILED);
                goto err;
                }


        /* Convert the response */
        BN_bin2bn((unsigned char *)result->d, outLen, r);
        to_return = 1;
 err:
	BN_CTX_end(ctx);
        return to_return;
        }

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

        if((ctx = BN_CTX_new()) == NULL)
                goto err;
        if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
                {
                if(!rsa->d || !rsa->n)
                        {
                        IBMCAerr(IBMCA_F_IBMCA_RSA_MOD_EXP,
                                IBMCA_R_MISSING_KEY_COMPONENTS);
                        goto err;
                        }
                to_return = ibmca_mod_exp(r0, I, rsa->d, rsa->n, ctx);
                }
        else
                {
                to_return = ibmca_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
                        rsa->dmq1, rsa->iqmp, ctx);
                }
 err:
        if(ctx)
                BN_CTX_free(ctx);
        return to_return;
        }
#endif

/* Ein kleines chinesisches "Restessen"  */
static int ibmca_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)
        {

        BIGNUM *argument = NULL;
        BIGNUM *result = NULL;
        BIGNUM *key = NULL;

        int to_return = 0; /* expect failure */

        char                *pkey=NULL;
        ICA_KEY_RSA_CRT     *privKey=NULL;
        int inLen, outLen;

        int rc;
        unsigned int        offset, pSize, qSize;
/* SAB New variables */
	unsigned int keyRecordSize;
	unsigned int pbytes = BN_num_bytes(p);
	unsigned int qbytes = BN_num_bytes(q);
	unsigned int dmp1bytes = BN_num_bytes(dmp1);
	unsigned int dmq1bytes = BN_num_bytes(dmq1);
	unsigned int iqmpbytes = BN_num_bytes(iqmp);

        /* Prepare the params */

	BN_CTX_start(ctx);
        argument = BN_CTX_get(ctx);
        result = BN_CTX_get(ctx);
        key = BN_CTX_get(ctx);

        if(!argument || !result || !key)
                {
                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_BN_CTX_FULL);
                goto err;
                }

	if(!bn_wexpand(argument, p->top + q->top) ||
                !bn_wexpand(result, p->top + q->top) ||
                !bn_wexpand(key, sizeof(*privKey)/BN_BYTES ))
                {
                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_BN_EXPAND_FAIL);
                goto err;
                }


        privKey = (ICA_KEY_RSA_CRT *)key->d;
/* SAB Add check for total size in bytes of the parms does not exceed
   the buffer space we have
   do this first
*/
      keyRecordSize = pbytes+qbytes+dmp1bytes+dmq1bytes+iqmpbytes;
     if (  keyRecordSize > sizeof(privKey->keyRecord )) {
	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);
         goto err;
     }

     if ( (qbytes + dmq1bytes)  > 256 ){
	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);
         goto err;
     }

     if ( pbytes + dmp1bytes > 256 ) {
	 IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OPERANDS_TO_LARGE);
         goto err;
     }

/* end SAB additions */
  
        memset(privKey, 0, sizeof(ICA_KEY_RSA_CRT));
        privKey->keyType =  CORRECT_ENDIANNESS(CRT_KEY_TYPE);
        privKey->keyLength = CORRECT_ENDIANNESS(sizeof(ICA_KEY_RSA_CRT));
        privKey->modulusBitLength = 
	  CORRECT_ENDIANNESS(BN_num_bytes(q) * 2 * 8);

        /*
         * p,dp & qInv are 1 QWORD Larger
         */
        privKey->pLength = CORRECT_ENDIANNESS(BN_num_bytes(p)+8);
        privKey->qLength = CORRECT_ENDIANNESS(BN_num_bytes(q));
        privKey->dpLength = CORRECT_ENDIANNESS(BN_num_bytes(dmp1)+8);
        privKey->dqLength = CORRECT_ENDIANNESS(BN_num_bytes(dmq1));
        privKey->qInvLength = CORRECT_ENDIANNESS(BN_num_bytes(iqmp)+8);

        offset = (char *) privKey->keyRecord
                  - (char *) privKey;

        qSize = BN_num_bytes(q);
        pSize = qSize + 8;   /*  1 QWORD larger */


/* SAB  probably aittle redundant, but we'll verify that each of the
   components which make up a key record sent ot the card does not exceed
   the space that is allocated for it.  this handles the case where even if
   the total length does not exceed keyrecord zied, if the operands are funny sized
they could cause potential side affects on either the card or the result */

     if ( (pbytes > pSize) || (dmp1bytes > pSize) ||
          (iqmpbytes > pSize) || ( qbytes >qSize) ||
          (dmq1bytes > qSize) ) {
		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT, IBMCA_R_OPERANDS_TO_LARGE);
		goto err;

	}
     

        privKey->dpOffset = CORRECT_ENDIANNESS(offset);

	offset += pSize;
	privKey->dqOffset = CORRECT_ENDIANNESS(offset);

	offset += qSize;
	privKey->pOffset = CORRECT_ENDIANNESS(offset);

	offset += pSize;
	privKey->qOffset = CORRECT_ENDIANNESS(offset);

	offset += qSize;
	privKey->qInvOffset = CORRECT_ENDIANNESS(offset);

        pkey = (char *) privKey->keyRecord;


/* SAB first check that we don;t under flow the buffer */
	if ( pSize < pbytes ) {
		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT, IBMCA_R_UNDERFLOW_CONDITION);
		goto err;
	}

        /* pkey += pSize - BN_num_bytes(p); WROING this should be dmp1) */
        pkey += pSize - BN_num_bytes(dmp1);
        BN_bn2bin(dmp1, pkey);   
        pkey += BN_num_bytes(dmp1);  /* move the pointer */

        BN_bn2bin(dmq1, pkey);  /* Copy over dmq1 */

        pkey += qSize;     /* move pointer */
	pkey += pSize - BN_num_bytes(p);  /* set up for zero padding of next field */

        BN_bn2bin(p, pkey);
        pkey += BN_num_bytes(p);  /* increment pointer by number of bytes moved  */

        BN_bn2bin(q, pkey);
        pkey += qSize ;  /* move the pointer */
	pkey +=  pSize - BN_num_bytes(iqmp); /* Adjust for padding */
        BN_bn2bin(iqmp, pkey);

        /* Prepare the argument and response */

	outLen = CORRECT_ENDIANNESS(privKey->qLength) * 2;  /* Correct endianess is used 
						because the fields were converted above */

        if (outLen > 256) {
		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_OUTLEN_TO_LARGE);
		goto err;
	}

	/* SAB check for underflow here on the argeument */
	if ( outLen < BN_num_bytes(a)) {
		IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_UNDERFLOW_CONDITION);
		goto err;
	}

        BN_bn2bin(a, (unsigned char *)argument->d + outLen -
                          BN_num_bytes(a));
        inLen = outLen;

        memset(result->d, 0, outLen);

        /* Perform the operation */

        if ( (rc = p_icaRsaCrt(handle, inLen, (unsigned char *)argument->d,
                privKey, &outLen, (unsigned char *)result->d)) != 0)
                {
                printf("rc = %d\n", rc);
                IBMCAerr(IBMCA_F_IBMCA_MOD_EXP_CRT,IBMCA_R_REQUEST_FAILED);
                goto err;
                }

        /* Convert the response */

        BN_bin2bn((unsigned char *)result->d, outLen, r);
        to_return = 1;

 err:
	BN_CTX_end(ctx);
        return to_return;

        }

#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 Ibmca acceleration
 * (it doesn't have a CRT form for RSA), this function means that an
 * Ibmca 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 ibmca dsa1024 rsa1024". */
static int ibmca_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 (!ibmca_mod_exp(rr,a1,p1,m,ctx)) goto end;
        /* let t = a2 ^ p2 mod m */
        if (!ibmca_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 ibmca_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
        const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
        BN_MONT_CTX *m_ctx)
        {
        return ibmca_mod_exp(r, a, p, m, ctx);
        }
#endif

/* This function is aliased to mod_exp (with the mont stuff dropped). */
static int ibmca_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        {
        return ibmca_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 ibmca_mod_exp_dh(DH const *dh, BIGNUM *r, 
	const BIGNUM *a, const BIGNUM *p, 
	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
        {
        return ibmca_mod_exp(r, a, p, m, ctx);
        }
#endif

/* Random bytes are good */
static int ibmca_rand_bytes(unsigned char *buf, int num)
        {
        int to_return = 0; /* assume failure */
        unsigned int ret;


        if(handle == 0)
                {
                IBMCAerr(IBMCA_F_IBMCA_RAND_BYTES,IBMCA_R_NOT_INITIALISED);
                goto err;
                }

        ret = p_icaRandomNumberGenerate(handle, num, buf);
        if (ret < 0)
                {
                IBMCAerr(IBMCA_F_IBMCA_RAND_BYTES,IBMCA_R_REQUEST_FAILED);
                goto err;
                }
        to_return = 1;
 err:
        return to_return;
        }

static int ibmca_rand_status(void)
        {
        return 1;
        }

/* 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_ibmca_id) != 0))  /* WJH XXX */
		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_IBMCA */
#endif /* !OPENSSL_NO_HW */
