📄 hw_aep.c
字号:
AEPHKerr(AEPHK_F_AEP_CTRL, ERR_R_PASSED_NULL_PARAMETER); return 0; } if(initialised) { AEPHKerr(AEPHK_F_AEP_CTRL, AEPHK_R_ALREADY_LOADED); return 0; } return set_AEP_LIBNAME((const char*)p); default: break; } AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); return 0; }static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { int to_return = 0; int r_len = 0; AEP_CONNECTION_HNDL hConnection; AEP_RV rv; r_len = BN_num_bits(m); /* Perform in software if modulus is too large for hardware. */ if (r_len > max_key_len){ AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL); return BN_mod_exp(r, a, p, m, ctx); } /*Grab a connection from the pool*/ rv = aep_get_connection(&hConnection); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED); return BN_mod_exp(r, a, p, m, ctx); } /*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) { AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED); rv = aep_close_connection(hConnection); return BN_mod_exp(r, a, p, m, ctx); } /*Return the connection to the pool*/ rv = aep_return_connection(hConnection); if (rv != AEP_R_OK) { AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); goto err; } to_return = 1; err: return to_return; } 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_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); goto err; } err: return rv; } #ifdef AEPRANDstatic 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; } static int aep_rand_status(void){ return 1;}#endif#ifndef OPENSSL_NO_RSAstatic int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) { BN_CTX *ctx = NULL; int to_return = 0; AEP_RV rv = AEP_R_OK; if ((ctx = BN_CTX_new()) == NULL) goto err; 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); 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: if(ctx) BN_CTX_free(ctx); return to_return;}#endif#ifndef OPENSSL_NO_DSAstatic 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); }#endif/* This function is aliased to mod_exp (with the mont stuff dropped). */static int aep_mod_exp_mont(BIGNUM *r, const 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); }#ifndef OPENSSL_NO_DH/* This function is aliased to mod_exp (with the dh and mont dropped). */static int aep_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 aep_mod_exp(r, a, p, m, ctx); }#endifstatic 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 AEP_RV 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; }static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection) { int count; AEP_RV rv = AEP_R_OK; 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) { rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl); if (rv != AEP_R_OK) goto end; aep_app_conn_table[count].conn_state = NotConnected; aep_app_conn_table[count].conn_hndl = 0; break; } } end: CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); return rv; }static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use) { int count; AEP_RV rv = AEP_R_OK; *in_use = 0; if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) { switch (aep_app_conn_table[count].conn_state) { case Connected: rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl); if (rv != AEP_R_OK) goto end; aep_app_conn_table[count].conn_state = NotConnected; aep_app_conn_table[count].conn_hndl = 0; break; case InUse: (*in_use)++; break; case NotConnected: break; } } end: if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); return rv; }/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums. Note only 32bit Openssl build support*/static AEP_RV GetBigNumSize(AEP_VOID_PTR 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; }static AEP_RV MakeAEPBigNum(AEP_VOID_PTR 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;i<bn->top;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*/static 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;i<bn->top;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 /* !OPENSSL_NO_HW_AEP */#endif /* !OPENSSL_NO_HW */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -