static AEP_RV aep_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) { AEP_RV rv = AEP_R_OK; AEP_CONNECTION_HNDL hConnection; /* * Grab a connection from the pool */ rv = aep_get_connection(&hConnection); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_GET_HANDLE_FAILED); return FAIL_TO_SW; } /* * 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) { AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_MOD_EXP_CRT_FAILED); rv = aep_close_connection(hConnection); return FAIL_TO_SW; } /* * Return the connection to the pool */ rv = aep_return_connection(hConnection); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_RETURN_CONNECTION_FAILED); goto err; } err: return rv; }
static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { int to_return = 0; AEP_RV rv = AEP_R_OK; if (!aep_dso) { AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP, AEPHK_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 == FAIL_TO_SW) { const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); goto err; } else if (rv != AEP_R_OK) goto err; } else { if (!rsa->d || !rsa->n) { AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP, AEPHK_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: return to_return; }
static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection) { 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) { /*Remember our pid so we can check if we're in a new process*/ 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) { AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE); recorded_pid = 0; goto end; } /*Set the AEP big num call back functions*/ rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum, &ConvertAEPBigNum); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE); recorded_pid = 0; goto end; } #ifdef AEPRAND /*Reset the rand byte count*/ rand_block_bytes = 0; #endif /*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(phConnection); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE); recorded_pid = 0; goto end; } aep_app_conn_table[0].conn_state = InUse; aep_app_conn_table[0].conn_hndl = *phConnection; goto end; } /*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; *phConnection = aep_app_conn_table[count].conn_hndl; goto end; } } /*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(phConnection); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE); goto end; } aep_app_conn_table[count].conn_state = InUse; aep_app_conn_table[count].conn_hndl = *phConnection; goto end; } } rv = AEP_R_GENERAL_ERROR; end: CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); return rv; }
static int aep_rand(unsigned char *buf,int len ) { AEP_RV rv = AEP_R_OK; AEP_CONNECTION_HNDL hConnection; CRYPTO_w_lock(CRYPTO_LOCK_RAND); /*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; CRYPTO_w_unlock(CRYPTO_LOCK_RAND); } else /*If not the get another block of random bytes*/ { CRYPTO_w_unlock(CRYPTO_LOCK_RAND); rv = aep_get_connection(&hConnection); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED); goto err_nounlock; } if (len > RAND_BLK_SIZE) { rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); goto err_nounlock; } } else { CRYPTO_w_lock(CRYPTO_LOCK_RAND); rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); goto err; } rand_block_bytes = RAND_BLK_SIZE; memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len); rand_block_bytes -= len; CRYPTO_w_unlock(CRYPTO_LOCK_RAND); } rv = aep_return_connection(hConnection); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); goto err_nounlock; } } return 1; err: CRYPTO_w_unlock(CRYPTO_LOCK_RAND); err_nounlock: return 0; }
/* (de)initialisation functions. */ static int aep_init(ENGINE *e) { t_AEP_ModExp *p1; t_AEP_ModExpCrt *p2; #ifdef AEPRAND t_AEP_GenRandom *p3; #endif t_AEP_Finalize *p4; t_AEP_Initialize *p5; t_AEP_OpenConnection *p6; t_AEP_SetBNCallBacks *p7; t_AEP_CloseConnection *p8; int to_return = 0; if(aep_dso != NULL) { AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED); goto err; } /* Attempt to load libaep.so. */ aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0); if(aep_dso == NULL) { AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED); 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)) || #ifdef AEPRAND !(p3 = (t_AEP_GenRandom*) DSO_bind_func( aep_dso,AEP_F3)) || #endif !(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)) || !(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8))) { AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED); goto err; } /* Copy the pointers */ p_AEP_ModExp = p1; p_AEP_ModExpCrt = p2; #ifdef AEPRAND p_AEP_GenRandom = p3; #endif p_AEP_Finalize = p4; p_AEP_Initialize = p5; p_AEP_OpenConnection = p6; p_AEP_SetBNCallBacks = p7; p_AEP_CloseConnection = p8; to_return = 1; return to_return; err: if(aep_dso) DSO_free(aep_dso); aep_dso = NULL; p_AEP_OpenConnection = NULL; p_AEP_ModExp = NULL; p_AEP_ModExpCrt = NULL; #ifdef AEPRAND p_AEP_GenRandom = NULL; #endif p_AEP_Initialize = NULL; p_AEP_Finalize = NULL; p_AEP_SetBNCallBacks = NULL; p_AEP_CloseConnection = NULL; return to_return; }