Make sure aep_close_connection() is declared and has a prototype that's
[openssl.git] / crypto / engine / hw_aep.c
index e81c4a53fbd67261d8853458dd3b24ab45bb3e85..f25013f787cfd3bde1d9f1f12288922b01e0dd3c 100644 (file)
@@ -81,6 +81,8 @@ typedef int pid_t;
 #endif
 
 #define AEP_LIB_NAME "aep engine"
+#define FAIL_TO_SW 0x10101010
+
 #include "hw_aep_err.c"
 
 static int aep_init(ENGINE *e);
@@ -90,6 +92,7 @@ static int aep_destroy(ENGINE *e);
 
 static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
 static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
+static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
 static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
 
 /* BIGNUM stuff */
@@ -233,6 +236,8 @@ static AEP_U32  rand_block_bytes = 0;
 static const char *engine_aep_id = "aep";
 static const char *engine_aep_name = "Aep hardware engine support";
 
+static int max_key_len = 2176;
+
 
 /* This internal function is used by ENGINE_aep() and possibly by the
  * "dynamic" ENGINE support too */
@@ -307,7 +312,7 @@ static int bind_aep(ENGINE *e)
 #endif
 
        /* Ensure the aep error handling is set up */
-       ERR_load_AEP_strings();
+       ERR_load_AEPHK_strings();
 
        return 1;
 }
@@ -402,7 +407,7 @@ static int aep_init(ENGINE *e)
  
        if(aep_dso != NULL)
                {
-               AEPerr(AEP_F_AEP_INIT,AEP_R_ALREADY_LOADED);
+               AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
                goto err;
                }
        /* Attempt to load libaep.so. */
@@ -411,7 +416,7 @@ static int aep_init(ENGINE *e)
   
        if(aep_dso == NULL)
                {
-               AEPerr(AEP_F_AEP_INIT,AEP_R_NOT_LOADED);
+               AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
                goto err;
                }
 
@@ -426,7 +431,7 @@ static int aep_init(ENGINE *e)
                !(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7))  ||
                !(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
                {
-               AEPerr(AEP_F_AEP_INIT,AEP_R_NOT_LOADED);
+               AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
                goto err;
                }
 
@@ -469,7 +474,7 @@ static int aep_init(ENGINE *e)
 /* Destructor (complements the "ENGINE_aep()" constructor) */
 static int aep_destroy(ENGINE *e)
        {
-       ERR_unload_AEP_strings();
+       ERR_unload_AEPHK_strings();
        return 1;
        }
 
@@ -480,32 +485,32 @@ static int aep_finish(ENGINE *e)
 
        if(aep_dso == NULL)
                {
-               AEPerr(AEP_F_AEP_FINISH,AEP_R_NOT_LOADED);
+               AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
                goto err;
                }
 
        rv = aep_close_all_connections(0, &in_use);
        if (rv != AEP_R_OK)
                {
-               AEPerr(AEP_F_AEP_FINISH,AEP_R_CLOSE_HANDLES_FAILED);
+               AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
                goto err;
                }
        if (in_use)
                {
-               AEPerr(AEP_F_AEP_FINISH,AEP_R_CONNECTIONS_IN_USE);
+               AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
                goto err;
                }
 
        rv = p_AEP_Finalize();
        if (rv != AEP_R_OK)
                {
-               AEPerr(AEP_F_AEP_FINISH,AEP_R_FINALIZE_FAILED);
+               AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
                goto err;
                }
 
        if(!DSO_free(aep_dso))
                {
-               AEPerr(AEP_F_AEP_FINISH,AEP_R_UNIT_FAILURE);
+               AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
                goto err;
                }
 
@@ -534,14 +539,14 @@ static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
        case AEP_CMD_SO_PATH:
                if(p == NULL)
                        {
-                       AEPerr(AEP_F_AEP_CTRL,
+                       AEPHKerr(AEPHK_F_AEP_CTRL,
                                ERR_R_PASSED_NULL_PARAMETER);
                        return 0;
                        }
                if(initialised)
                        {
-                       AEPerr(AEP_F_AEP_CTRL,
-                               AEP_R_ALREADY_LOADED);
+                       AEPHKerr(AEPHK_F_AEP_CTRL,
+                               AEPHK_R_ALREADY_LOADED);
                        return 0;
                        }
                AEP_LIBNAME = (const char *)p;
@@ -549,7 +554,7 @@ static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
        default:
                break;
                }
-       AEPerr(AEP_F_AEP_CTRL,AEP_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+       AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
        return 0;
        }
 
@@ -557,15 +562,25 @@ 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)
                {     
-               AEPerr(AEP_F_AEP_MOD_EXP,AEP_R_GET_HANDLE_FAILED);
-               goto err;
+               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*/
@@ -573,16 +588,16 @@ static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
 
        if (rv !=  AEP_R_OK)
                {
-               AEPerr(AEP_F_AEP_MOD_EXP,AEP_R_MOD_EXP_FAILED);
-               rv = aep_return_connection(hConnection);
-               goto err;
+               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)
                {
-               AEPerr(AEP_F_AEP_RAND,AEP_R_RETURN_CONNECTION_FAILED); 
+               AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); 
                goto err;
                }
 
@@ -602,8 +617,8 @@ static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        rv = aep_get_connection(&hConnection);
        if (rv != AEP_R_OK)
                {
-               AEPerr(AEP_F_AEP_MOD_EXP_CRT,AEP_R_GET_HANDLE_FAILED);
-               goto err;
+               AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
+               return FAIL_TO_SW;
                }
 
        /*To the card with the mod exp*/
@@ -611,16 +626,16 @@ static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                (void*)iqmp,(void*)r,NULL);
        if (rv != AEP_R_OK)
                {
-               AEPerr(AEP_F_AEP_MOD_EXP_CRT,AEP_R_MOD_EXP_CRT_FAILED);
-               rv = aep_return_connection(hConnection);
-               goto err;
+               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)
                {
-               AEPerr(AEP_F_AEP_RAND,AEP_R_RETURN_CONNECTION_FAILED); 
+               AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); 
                goto err;
                }
  
@@ -655,7 +670,7 @@ static int aep_rand(unsigned char *buf,int len )
                rv = aep_get_connection(&hConnection);
                if (rv !=  AEP_R_OK)
                        { 
-                       AEPerr(AEP_F_AEP_RAND,AEP_R_GET_HANDLE_FAILED);             
+                       AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);             
                        goto err_nounlock;
                        }
 
@@ -664,7 +679,7 @@ static int aep_rand(unsigned char *buf,int len )
                        rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
                        if (rv !=  AEP_R_OK)
                                {  
-                               AEPerr(AEP_F_AEP_RAND,AEP_R_GET_RANDOM_FAILED); 
+                               AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
                                goto err_nounlock;
                                }
                        }
@@ -675,7 +690,7 @@ static int aep_rand(unsigned char *buf,int len )
                        rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
                        if (rv !=  AEP_R_OK)
                                {       
-                               AEPerr(AEP_F_AEP_RAND,AEP_R_GET_RANDOM_FAILED); 
+                               AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED); 
              
                                goto err;
                                }
@@ -691,7 +706,7 @@ static int aep_rand(unsigned char *buf,int len )
                rv = aep_return_connection(hConnection);
                if (rv != AEP_R_OK)
                        {
-                       AEPerr(AEP_F_AEP_RAND,AEP_R_RETURN_CONNECTION_FAILED); 
+                       AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED); 
          
                        goto err_nounlock;
                        }
@@ -699,7 +714,7 @@ static int aep_rand(unsigned char *buf,int len )
   
        return 1;
  err:
-       CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+       CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
  err_nounlock:
        return 0;
        }
@@ -722,7 +737,7 @@ static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
 
        if (!aep_dso)
                {
-               AEPerr(AEP_F_AEP_RSA_MOD_EXP,AEP_R_NOT_LOADED);
+               AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
                goto err;
                }
 
@@ -730,14 +745,20 @@ static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
        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)
+
+               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)
                        {
-                       AEPerr(AEP_F_AEP_RSA_MOD_EXP,AEP_R_MISSING_KEY_COMPONENTS);
+                       AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
                        goto err;
                        }
  
@@ -830,7 +851,7 @@ static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
 
                if (rv != AEP_R_OK)
                        {
-                       AEPerr(AEP_F_AEP_INIT,AEP_R_INIT_FAILURE);
+                       AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
                        recorded_pid = 0;
                        goto end;
                        }
@@ -841,7 +862,7 @@ static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
 
                if (rv != AEP_R_OK)
                        {
-                       AEPerr(AEP_F_AEP_INIT,AEP_R_SETBNCALLBACK_FAILURE);
+                       AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
                        recorded_pid = 0;
                        goto end;
                        }
@@ -863,7 +884,7 @@ static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
 
                if (rv != AEP_R_OK)
                        {
-                       AEPerr(AEP_F_AEP_INIT,AEP_R_UNIT_FAILURE);
+                       AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
                        recorded_pid = 0;
                        goto end;
                        }
@@ -893,7 +914,7 @@ static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
 
                        if (rv != AEP_R_OK)
                                {             
-                               AEPerr(AEP_F_AEP_INIT,AEP_R_UNIT_FAILURE);
+                               AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
                                goto end;
                                }
 
@@ -930,6 +951,28 @@ static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
        return AEP_R_OK;
        }
 
+static AEP_RV aep_close_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 = NotConnected;
+                       close(aep_app_conn_table[count].conn_hndl);
+                       break;
+                       }
+               }
+
+       CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+
+       return AEP_R_OK;
+       }
+
 static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
        {
        int count;