From c7d827fc902a84b12f1d164fd2f75f48d4d0d776 Mon Sep 17 00:00:00 2001 From: "Mark J. Cox" Date: Mon, 12 Nov 2001 12:11:06 +0000 Subject: [PATCH] Commit missing AEP files (oops) Submitted by: Reviewed by: PR: --- crypto/engine/hw_aep.c | 840 +++++++++++++++++++++++++++++++ crypto/engine/vendor_defns/aep.h | 190 +++++++ 2 files changed, 1030 insertions(+) create mode 100644 crypto/engine/hw_aep.c create mode 100644 crypto/engine/vendor_defns/aep.h diff --git a/crypto/engine/hw_aep.c b/crypto/engine/hw_aep.c new file mode 100644 index 0000000000..92388e4e5e --- /dev/null +++ b/crypto/engine/hw_aep.c @@ -0,0 +1,840 @@ +/* crypto/engine/hw_aep.c */ +/* + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +#include +#include "cryptlib.h" +#include +#include "engine_int.h" +#include + +#ifndef NO_HW +#ifndef NO_HW_AEP +#ifdef FLAT_INC +#include "aep.h" +#else +#include "vendor_defns/aep.h" +#endif + + +static int aep_init(void); +static int aep_finish(void); +static int aep_get_connection(AEP_CONNECTION_HNDL *hConnection); +static int aep_return_connection(AEP_CONNECTION_HNDL hConnection); + +/* BIGNUM stuff */ +static int aep_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +/* RSA stuff */ +static int aep_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int aep_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + +/* DSA stuff */ +static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont); + +static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); + +/* DH stuff */ +/* This function is aliased to mod_exp (with the DH and mont dropped). */ +static int aep_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + +/* rand stuff */ +static int aep_rand(unsigned char *buf, int num); + +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD aep_rsa = +{ + "Aep RSA method", + NULL, /*rsa_pub_encrypt*/ + NULL, /*rsa_pub_decrypt*/ + NULL, /*rsa_priv_encrypt*/ + NULL, /*rsa_priv_encrypt*/ + aep_rsa_mod_exp, /*rsa_mod_exp*/ + aep_mod_exp_mont, /*bn_mod_exp*/ + NULL, /*init*/ + NULL, /*finish*/ + 0, /*flags*/ + NULL, /*app_data*/ + NULL, /*rsa_sign*/ + NULL /*rsa_verify*/ +}; + +/* Our internal DSA_METHOD that we provide pointers to */ +static DSA_METHOD aep_dsa = +{ + "Aep DSA method", + NULL, /* dsa_do_sign */ + NULL, /* dsa_sign_setup */ + NULL, /* dsa_do_verify */ + aep_dsa_mod_exp, /* dsa_mod_exp */ + aep_mod_exp_dsa, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL /* app_data */ +}; + +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD aep_dh = +{ + "Aep DH method", + NULL, + NULL, + aep_mod_exp_dh, + NULL, + NULL, + 0, + NULL +}; +/* our internal RAND_method that we provide pointers to */ +static RAND_METHOD aep_random = +{ + /*"AEP RAND method", */ + NULL, + aep_rand, + NULL, + NULL, + aep_rand, + NULL, +}; + +/* Our ENGINE structure. */ +static ENGINE engine_aep = +{ + "aep", + "Aep hardware engine support", + &aep_rsa, + &aep_dsa, + &aep_dh, + &aep_random, + aep_mod_exp, + NULL, + aep_init, + aep_finish, + NULL, /* no ctrl() */ + NULL, /* no load_privkey() */ + NULL, /* no load_pubkey() */ + 0, /* no flags */ + 0, 0, /* no references */ + NULL, NULL /* unlinked */ +}; + +/*Define an array of structures to hold connections*/ +static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS]; + +/*Used to determine if this is a new process*/ +static pid_t recorded_pid = 0; + +static int rnd_reference; + +static AEP_U8 rand_block[RAND_BLK_SIZE]; +static AEP_U32 rand_block_bytes = 0; + + + +/* 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_aep() +{ + RSA_METHOD *meth1; + DSA_METHOD *meth2; + DH_METHOD *meth3; + + /* We know that the "PKCS1_SSLeay()" functions hook properly + * to the aep-specific mod_exp and mod_exp_crt so we use + * those functions. NB: We don't use ENGINE_openssl() or + * anything "more generic" because something like the RSAref + * code may not hook properly, and if you own one of these + * cards then you have the right to do RSA operations on it + * anyway! */ + meth1 = RSA_PKCS1_SSLeay(); + aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec; + + + /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish + * bits. */ + meth2 = DSA_OpenSSL(); + aep_dsa.dsa_do_sign = meth2->dsa_do_sign; + aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup; + aep_dsa.dsa_do_verify = meth2->dsa_do_verify; + + aep_dsa = *DSA_get_default_openssl_method(); + aep_dsa.dsa_mod_exp = aep_dsa_mod_exp; + aep_dsa.bn_mod_exp = aep_mod_exp_dsa; + + /* Much the same for Diffie-Hellman */ + meth3 = DH_OpenSSL(); + aep_dh.generate_key = meth3->generate_key; + aep_dh.compute_key = meth3->compute_key; + aep_dh.bn_mod_exp = meth3->bn_mod_exp; + + return &engine_aep; +} + +/* This is a process-global DSO handle used for loading and unloading + * the Aep library. NB: This is only set (or unset) during an + * init() or finish() call (reference counts permitting) and they're + * operating with global locks, so this should be thread-safe + * implicitly. */ +static DSO *aep_dso = NULL; + +/* These are the function pointers that are (un)set when the library has + * successfully (un)loaded. */ +static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL; +static t_AEP_ModExp *p_AEP_ModExp = NULL; +static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL; +static t_AEP_GenRandom *p_AEP_GenRandom = NULL; +static t_AEP_Initialize *p_AEP_Initialize = NULL; +static t_AEP_Finalize *p_AEP_Finalize = NULL; +static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL; + +/* (de)initialisation functions. */ +static int aep_init() +{ + t_AEP_ModExp *p1; + t_AEP_ModExpCrt *p2; + t_AEP_GenRandom *p3; + t_AEP_Finalize *p4; + t_AEP_Initialize *p5; + t_AEP_OpenConnection *p6; + t_AEP_SetBNCallBacks *p7; + + unsigned int hConnection,rv; + + int to_return = 0; + + + if(aep_dso != NULL) + { + ENGINEerr(ENGINE_F_AEP_INIT,ENGINE_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libaep.so. */ + + aep_dso = DSO_load(NULL, AEP_LIBNAME, NULL, + DSO_FLAG_NAME_TRANSLATION); + + if(aep_dso == NULL) + { + ENGINEerr(ENGINE_F_AEP_INIT,ENGINE_R_DSO_FAILURE); + goto err; + } + + if(!(p1 = (t_AEP_ModExp *) DSO_bind_func( aep_dso,AEP_F1)) || + !(p2 = (t_AEP_ModExpCrt*) DSO_bind_func( aep_dso,AEP_F2)) || + !(p3 = (t_AEP_GenRandom*) DSO_bind_func( aep_dso,AEP_F3)) || + !(p4 = (t_AEP_Finalize*) DSO_bind_func( aep_dso,AEP_F4)) || + !(p5 = (t_AEP_Initialize*) DSO_bind_func( aep_dso,AEP_F5)) || + !(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6)) || + !(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7))) + { + + ENGINEerr(ENGINE_F_AEP_INIT,ENGINE_R_DSO_FAILURE); + goto err; + } + + /* Copy the pointers */ + + p_AEP_ModExp = p1; + p_AEP_ModExpCrt = p2; + p_AEP_GenRandom = p3; + p_AEP_Finalize = p4; + p_AEP_Initialize = p5; + p_AEP_OpenConnection = p6; + p_AEP_SetBNCallBacks = p7; + + + /* Perform a basic test to see if there's actually any unit + * running. */ + + CRYPTO_add(&rnd_reference, 1, CRYPTO_LOCK_DYNLOCK); + + rv = aep_get_connection(&hConnection); + + if (rv != AEP_R_OK) + goto err; + + /* Everything's fine. */ + + rv = aep_return_connection(hConnection); + + to_return = 1; + + return to_return; + + err: + + if(aep_dso) + DSO_free(aep_dso); + + p_AEP_OpenConnection = NULL; + p_AEP_ModExp = NULL; + p_AEP_ModExpCrt = NULL; + p_AEP_GenRandom = NULL; + p_AEP_Initialize = NULL; + p_AEP_Finalize = NULL; + p_AEP_SetBNCallBacks = NULL; + + return to_return; + +} + +static int aep_finish() +{ + int to_return = 0; + + if(aep_dso == NULL) + { + ENGINEerr(ENGINE_F_AEP_FINISH,ENGINE_R_NOT_LOADED); + goto err; + } + if(!DSO_free(aep_dso)) + { + ENGINEerr(ENGINE_F_AEP_FINISH,ENGINE_R_DSO_FAILURE); + goto err; + } + + aep_dso = NULL; + p_AEP_OpenConnection = NULL; + p_AEP_ModExp = NULL; + p_AEP_ModExpCrt = NULL; + p_AEP_GenRandom = NULL; + p_AEP_Initialize = NULL; + p_AEP_Finalize = NULL; + p_AEP_SetBNCallBacks = NULL; + + CRYPTO_add(&rnd_reference, -1, CRYPTO_LOCK_DYNLOCK); + + to_return = 1; + err: + return to_return; +} + +static int aep_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + int to_return = 0; + + unsigned int hConnection, rv; + + /*Grab a connection from the pool*/ + rv = aep_get_connection(&hConnection); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_MOD_EXP,ENGINE_R_GET_HANDLE_FAILED); + goto err; + } + + /*To the card with the mod exp*/ + rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL); + + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_MOD_EXP,ENGINE_R_MOD_EXP_FAILED); + rv = aep_return_connection(hConnection); + goto err; + } + + /*Return the connection to the pool*/ + rv = aep_return_connection(hConnection); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_RAND,ENGINE_R_RETURN_CONNECTION_FAILED); + goto err; + } + + to_return = 1; + err: + return to_return; +} + +static int aep_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *q , + const BIGNUM *dmp1,const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx) +{ + AEP_RV rv = AEP_R_OK; + AEP_U32 hConnection; + + /*Grab a connection from the pool*/ + rv = aep_get_connection(&hConnection); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_MOD_EXP_CRT,ENGINE_R_GET_HANDLE_FAILED); + goto err; + } + + /*To the card with the mod exp*/ + rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1, + (void*)iqmp,(void*)r,NULL); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_MOD_EXP_CRT,ENGINE_R_MOD_EXP_CRT_FAILED); + rv = aep_return_connection(hConnection); + goto err; + } + + /*Return the connection to the pool*/ + rv = aep_return_connection(hConnection); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_RAND,ENGINE_R_RETURN_CONNECTION_FAILED); + goto err; + } + + err: + return rv; +} + + +static int aep_rand(unsigned char *buf,int len ) +{ + AEP_RV rv = AEP_R_OK; + AEP_U32 hConnection; + + int to_return = 0; + + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + + /*Can the request be serviced with what's already in the buffer?*/ + if (len <= rand_block_bytes) + { + memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len); + rand_block_bytes -= len; + } + else + /*If not the get another block of random bytes*/ + { + rv = aep_get_connection(&hConnection); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_RAND,ENGINE_R_GET_HANDLE_FAILED); + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + goto err; + } + + if (len > RAND_BLK_SIZE) + { + rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_RAND,ENGINE_R_GET_RANDOM_FAILED); + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + goto err; + } + } + else + { + rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_RAND,ENGINE_R_GET_RANDOM_FAILED); + + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + goto err; + } + + rand_block_bytes = RAND_BLK_SIZE; + + memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len); + rand_block_bytes -= len; + } + + rv = aep_return_connection(hConnection); + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_RAND,ENGINE_R_RETURN_CONNECTION_FAILED); + + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + goto err; + } + } + + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + to_return = 1; + err: + return to_return; +} + + +static int aep_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) +{ + BN_CTX *ctx = NULL; + + int to_return = 0; + + AEP_RV rv = AEP_R_OK; + + if (!aep_dso) + { + ENGINEerr(ENGINE_F_AEP_RSA_MOD_EXP,ENGINE_R_NOT_LOADED); + goto err; + } + + /*See if we have all the necessary bits for a crt*/ + if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) + { + rv = aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx); + if (rv != AEP_R_OK) + goto err; + } + else + { + if (!rsa->d || !rsa->n) + { + ENGINEerr(ENGINE_F_AEP_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); + goto err; + } + + rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx); + if (rv != AEP_R_OK) + goto err; + + } + + to_return = 1; + + err: + if(ctx) + BN_CTX_free(ctx); + return to_return; +} + + +static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + BIGNUM t; + int to_return = 0; + BN_init(&t); + + /* let rr = a1 ^ p1 mod m */ + if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end; + /* let t = a2 ^ p2 mod m */ + if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end; + /* let rr = rr * t mod m */ + if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end; + to_return = 1; + end: + BN_free(&t); + return to_return; +} + + +static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return aep_mod_exp(r, a, p, m, ctx); + +} + +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int aep_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return aep_mod_exp(r, a, p, m, ctx); + +} + +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int aep_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return aep_mod_exp(r, a, p, m, ctx); + +} + +static int aep_get_connection(AEP_CONNECTION_HNDL *hConnection) +{ + int count; + AEP_RV rv = AEP_R_OK; + + /*Get the current process id*/ + pid_t curr_pid; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + + curr_pid = getpid(); + + /*Check if this is the first time this is being called from the current + process*/ + if (recorded_pid != curr_pid) + { + recorded_pid = curr_pid; + + /*Call Finalize to make sure we have not inherited some data from a parent + process*/ + p_AEP_Finalize(); + + /*Initialise the AEP API*/ + rv = p_AEP_Initialize(NULL); + + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_INIT,ENGINE_R_AEP_INIT_FAILURE); + recorded_pid = 0; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; + } + + /*Set the AEP big num call back functions*/ + rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum, &ConvertAEPBigNum); + + if (rv != AEP_R_OK) + { + + ENGINEerr(ENGINE_F_AEP_INIT,ENGINE_R_SETBNCALLBACK_FAILURE); + recorded_pid = 0; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; + } + + /*Reset the rand byte count*/ + rand_block_bytes = 0; + + /*Init the structures*/ + for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) + { + aep_app_conn_table[count].conn_state = NotConnected; + aep_app_conn_table[count].conn_hndl = 0; + } + + /*Open a connection*/ + rv = p_AEP_OpenConnection(hConnection); + + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_INIT,ENGINE_R_UNIT_FAILURE); + recorded_pid = 0; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; + } + + aep_app_conn_table[0].conn_state = InUse; + + aep_app_conn_table[0].conn_hndl = *hConnection; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + + return (rv); + } + /*Check the existing connections to see if we can find a free one*/ + for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) + { + + if (aep_app_conn_table[count].conn_state == Connected) + { + aep_app_conn_table[count].conn_state = InUse; + *hConnection = aep_app_conn_table[count].conn_hndl; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; + } + } + /*If no connections available, we're going to have to try to open a new one*/ + for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) + { + if (aep_app_conn_table[count].conn_state == NotConnected) + { + /*Open a connection*/ + rv = p_AEP_OpenConnection(hConnection); + + if (rv != AEP_R_OK) + { + ENGINEerr(ENGINE_F_AEP_INIT,ENGINE_R_UNIT_FAILURE); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; + } + + aep_app_conn_table[count].conn_state = InUse; + + aep_app_conn_table[count].conn_hndl = *hConnection; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; + } + } + + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return AEP_R_GENERAL_ERROR; +} + + +static int aep_return_connection(AEP_CONNECTION_HNDL hConnection) +{ + int count; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + + /*Find the connection item that matches this connection handle*/ + for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) + { + + if (aep_app_conn_table[count].conn_hndl == hConnection) + { + aep_app_conn_table[count].conn_state = Connected; + break; + } + } + + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + + return AEP_R_OK; +} + +/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums. +Note only 32bit Openssl build support*/ + +AEP_RV GetBigNumSize(void* ArbBigNum, AEP_U32* BigNumSize) +{ + BIGNUM* bn; + + /*Cast the ArbBigNum pointer to our BIGNUM struct*/ + bn = (BIGNUM*) ArbBigNum; + +#ifdef SIXTY_FOUR_BIT_LONG + *BigNumSize = bn->top << 3; +#else + /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit words) multiplies by 4*/ + *BigNumSize = bn->top << 2; +#endif + + return AEP_R_OK; +} + +AEP_RV MakeAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum) +{ + BIGNUM* bn; + +#ifndef SIXTY_FOUR_BIT_LONG + unsigned char* buf; + int i; +#endif + + /*Cast the ArbBigNum pointer to our BIGNUM struct*/ + bn = (BIGNUM*) ArbBigNum; + +#ifdef SIXTY_FOUR_BIT_LONG + memcpy(AEP_BigNum, bn->d, BigNumSize); +#else + /*Must copy data into a (monotone) least significant byte first format + performing endian conversion if necessary*/ + for(i=0;itop;i++) + { + buf = (unsigned char*)&bn->d[i]; + + *((AEP_U32*)AEP_BigNum) = (AEP_U32) ((unsigned) buf[1] << 8 | buf[0]) | + ((unsigned) buf[3] << 8 | buf[2]) << 16; + + AEP_BigNum += 4; + } +#endif + + return AEP_R_OK; +} + +/*Turn an AEP Big Num back to a user big num*/ +AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum) +{ + BIGNUM* bn; +#ifndef SIXTY_FOUR_BIT_LONG + int i; +#endif + + bn = (BIGNUM*)ArbBigNum; + + /*Expand the result bn so that it can hold our big num. Size is in bits*/ + bn_expand(bn, (int)(BigNumSize << 3)); + +#ifdef SIXTY_FOUR_BIT_LONG + bn->top = BigNumSize >> 3; + + if((BigNumSize & 7) != 0) + bn->top++; + + memset(bn->d, 0, bn->top << 3); + + memcpy(bn->d, AEP_BigNum, BigNumSize); +#else + bn->top = BigNumSize >> 2; + + for(i=0;itop;i++) + { + bn->d[i] = (AEP_U32) ((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 | + ((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]); + AEP_BigNum += 4; + } +#endif + + return AEP_R_OK; +} + +#endif /* !NO_HW_AEP */ +#endif /* !NO_HW */ diff --git a/crypto/engine/vendor_defns/aep.h b/crypto/engine/vendor_defns/aep.h new file mode 100644 index 0000000000..8e199ea3c1 --- /dev/null +++ b/crypto/engine/vendor_defns/aep.h @@ -0,0 +1,190 @@ +/* This header declares the necessary definitions for using the exponentiation + * acceleration capabilities, and rnd number generation of the AEP card. + * + */ + +/* + * + * Some AEP defines + * + */ + +/*Successful return value*/ +#define AEP_R_OK 0x00000000 + +/*Miscelleanous unsuccessful return value*/ +#define AEP_R_GENERAL_ERROR 0x10000001 + +/*Insufficient host memory*/ +#define AEP_R_HOST_MEMORY 0x10000002 + +#define AEP_R_FUNCTION_FAILED 0x10000006 + +/*Invalid arguments in function call*/ +#define AEP_R_ARGUMENTS_BAD 0x10020000 + +#define AEP_R_NO_TARGET_RESOURCES 0x10030000 + +/*Error occuring on socket operation*/ +#define AEP_R_SOCKERROR 0x10000010 + +/*Socket has been closed from the other end*/ +#define AEP_R_SOCKEOF 0x10000011 + +/*Invalid handles*/ +#define AEP_R_CONNECTION_HANDLE_INVALID 0x100000B3 + +#define AEP_R_TRANSACTION_HANDLE_INVALID 0x10040000 + +/*Transaction has not yet returned from accelerator*/ +#define AEP_R_TRANSACTION_NOT_READY 0x00010000 + +/*There is already a thread waiting on this transaction*/ +#define AEP_R_TRANSACTION_CLAIMED 0x10050000 + +/*The transaction timed out*/ +#define AEP_R_TIMED_OUT 0x10060000 + +#define AEP_R_FXN_NOT_IMPLEMENTED 0x10070000 + +#define AEP_R_TARGET_ERROR 0x10080000 + +/*Error in the AEP daemon process*/ +#define AEP_R_DAEMON_ERROR 0x10090000 + +/*Invalid ctx id*/ +#define AEP_R_INVALID_CTX_ID 0x10009000 + +#define AEP_R_NO_KEY_MANAGER 0x1000a000 + +/*Error obtaining a mutex*/ +#define AEP_R_MUTEX_BAD 0x000001A0 + +/*Fxn call before AEP_Initialise ot after AEP_Finialise*/ +#define AEP_R_AEPAPI_NOT_INITIALIZED 0x10000190 + +/*AEP_Initialise has already been called*/ +#define AEP_R_AEPAPI_ALREADY_INITIALIZED 0x10000191 + +/*Maximum number of connections to daemon reached*/ +#define AEP_R_NO_MORE_CONNECTION_HNDLS 0x10000200 + +/* + * + * Some AEP Type definitions + * + */ + +/* an unsigned 8-bit value */ +typedef unsigned char AEP_U8; + +/* an unsigned 8-bit character */ +typedef char AEP_CHAR; + +/* a BYTE-sized Boolean flag */ +typedef AEP_U8 AEP_BBOOL; + +/*Unsigned value, at least 16 bits long*/ +typedef unsigned short AEP_U16; + +/* an unsigned value, at least 32 bits long */ +typedef unsigned int AEP_U32; + +/*#if defined(AEP_Win32)*/ +/* 64 bit unsigned value */ +/*typedef unsigned _int64 AEP_U64; + +#elif defined(AEP_GENERIC)*/ +/* 64 bit unsigned value */ +typedef unsigned long long AEP_U64; +/*#endif*/ + +/* at least 32 bits; each bit is a Boolean flag */ +typedef AEP_U32 AEP_FLAGS; + +typedef AEP_U8 *AEP_U8_PTR; +typedef AEP_CHAR *AEP_CHAR_PTR; +typedef AEP_U32 *AEP_U32_PTR; +typedef AEP_U64 *AEP_U64_PTR; +typedef void *AEP_VOID_PTR; + +/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */ +typedef AEP_VOID_PTR *AEP_VOID_PTR_PTR; + +/*Used to identify an AEP connection handle*/ +typedef AEP_U32 AEP_CONNECTION_HNDL; + +/*Pointer to an AEP connection handle*/ +typedef AEP_CONNECTION_HNDL *AEP_CONNECTION_HNDL_PTR; + +/*Used by an application (in conjunction with the apps process id) to +identify an individual transaction*/ +typedef AEP_U32 AEP_TRANSACTION_ID; + +/*Pointer to an applications transaction identifier*/ +typedef AEP_TRANSACTION_ID *AEP_TRANSACTION_ID_PTR; + +/*Return value type*/ +typedef AEP_U32 AEP_RV; + +#define MAX_PROCESS_CONNECTIONS 5 + +#define RAND_BLK_SIZE 1024 + +typedef enum{ + NotConnected= 0, + Connected= 1, + InUse= 2 +} AEP_CONNECTION_STATE; + + +typedef struct AEP_CONNECTION_ENTRY{ + AEP_CONNECTION_STATE conn_state; + AEP_CONNECTION_HNDL conn_hndl; +} AEP_CONNECTION_ENTRY; + + +AEP_RV GetBigNumSize(void* ArbBigNum, AEP_U32* BigNumSize); +AEP_RV MakeAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum); +AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum); + + + +typedef unsigned int t_AEP_OpenConnection(unsigned int *phConnection); + +typedef unsigned int t_AEP_ModExp(unsigned int hConnection, void *a, void *p, + void *n, void *r,unsigned long long *tranid); + +typedef unsigned int t_AEP_ModExpCrt(unsigned int hConnection,void *a, void *p, + void *q, void *dmp1, void *dmq1,void *iqmp, + void *r,unsigned long long *tranid); + +typedef unsigned int t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection, + AEP_U32 Len, + AEP_U32 Type, + AEP_VOID_PTR pResult, + AEP_TRANSACTION_ID* pidTransID + ); + + + +typedef unsigned int t_AEP_Initialize(AEP_VOID_PTR pInitArgs); +typedef unsigned int t_AEP_Finalize(); +typedef unsigned int t_AEP_SetBNCallBacks( + AEP_RV (*GetBigNumSizeFunc)(), + AEP_RV (*MakeAEPBigNumFunc)(), + AEP_RV (*ConverAEPBigNumFunc)() + ); + +/* These are the static string constants for the DSO file name and the function + * symbol names to bind to. +*/ +static const char *AEP_LIBNAME = "aep"; + +static const char *AEP_F1 = "AEP_ModExp"; +static const char *AEP_F2 = "AEP_ModExpCrt"; +static const char *AEP_F3 = "AEP_GenRandom"; +static const char *AEP_F4 = "AEP_Finalize"; +static const char *AEP_F5 = "AEP_Initialize"; +static const char *AEP_F6 = "AEP_OpenConnection"; +static const char *AEP_F7 = "AEP_SetBNCallBacks"; -- 2.40.0