/* 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 */
    /* set up for zero padding of next field */
    pkey += pSize - BN_num_bytes(p);

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

    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 */

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

    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 */
