@@ -108,6 +108,8 @@ int odp_queue_term_global(void);
int odp_crypto_init_global(void);
int odp_crypto_term_global(void);
+int odp_crypto_init_local(void);
+int odp_crypto_term_local(void);
int odp_timer_init_global(void);
int odp_timer_term_global(void);
@@ -86,6 +86,52 @@ struct odp_crypto_global_s {
static odp_crypto_global_t *global;
+typedef struct crypto_local_t {
+ HMAC_CTX *hmac;
+ EVP_CIPHER_CTX *cipher;
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ HMAC_CTX hmac_ctx;
+#endif
+} crypto_local_t;
+
+static __thread crypto_local_t local;
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+int odp_crypto_init_local(void)
+{
+ local.hmac = &local.hmac_ctx;
+ HMAC_CTX_init(local.hmac);
+ local.cipher = EVP_CIPHER_CTX_new();
+
+ return ((local.hmac == NULL) || (local.cipher == NULL)) ? -1 : 0;
+}
+
+#define HMAC_CTX_reset(ctx) HMAC_CTX_cleanup(ctx)
+
+int odp_crypto_term_local(void)
+{
+ EVP_CIPHER_CTX_free(local.cipher);
+
+ return 0;
+}
+#else
+int odp_crypto_init_local(void)
+{
+ local.hmac = HMAC_CTX_new();
+ local.cipher = EVP_CIPHER_CTX_new();
+
+ return ((local.hmac == NULL) || (local.cipher == NULL)) ? -1 : 0;
+}
+
+int odp_crypto_term_local(void)
+{
+ HMAC_CTX_free(local.hmac);
+ EVP_CIPHER_CTX_free(local.cipher);
+
+ return 0;
+}
+#endif
+
static
odp_crypto_generic_op_result_t *get_op_result_from_event(odp_event_t ev)
{
@@ -157,33 +203,15 @@ void packet_hmac_calculate(HMAC_CTX *ctx,
HMAC_Final(ctx, hash, NULL);
}
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-static
-void packet_hmac(odp_crypto_op_param_t *param,
- odp_crypto_generic_session_t *session,
- uint8_t *hash)
-{
- HMAC_CTX ctx;
-
- /* Hash it */
- HMAC_CTX_init(&ctx);
- packet_hmac_calculate(&ctx, param, session, hash);
- HMAC_CTX_cleanup(&ctx);
-}
-#else
static
void packet_hmac(odp_crypto_op_param_t *param,
odp_crypto_generic_session_t *session,
uint8_t *hash)
{
- HMAC_CTX *ctx;
-
/* Hash it */
- ctx = HMAC_CTX_new();
- packet_hmac_calculate(ctx, param, session, hash);
- HMAC_CTX_free(ctx);
+ packet_hmac_calculate(local.hmac, param, session, hash);
+ HMAC_CTX_reset(local.hmac);
}
-#endif
static
odp_crypto_alg_err_t auth_gen(odp_crypto_op_param_t *param,
@@ -347,7 +375,7 @@ static
odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param,
odp_crypto_generic_session_t *session)
{
- EVP_CIPHER_CTX *ctx;
+ EVP_CIPHER_CTX *ctx = local.cipher;
void *iv_ptr;
int ret;
@@ -359,7 +387,6 @@ odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param,
return ODP_CRYPTO_ALG_ERR_IV_INVALID;
/* Encrypt it */
- ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL,
session->cipher.key_data, NULL);
EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr);
@@ -367,8 +394,6 @@ odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param,
ret = internal_encrypt(ctx, param);
- EVP_CIPHER_CTX_free(ctx);
-
return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE :
ODP_CRYPTO_ALG_ERR_NONE;
}
@@ -377,7 +402,7 @@ static
odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param,
odp_crypto_generic_session_t *session)
{
- EVP_CIPHER_CTX *ctx;
+ EVP_CIPHER_CTX *ctx = local.cipher;
void *iv_ptr;
int ret;
@@ -389,7 +414,6 @@ odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param,
return ODP_CRYPTO_ALG_ERR_IV_INVALID;
/* Decrypt it */
- ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL,
session->cipher.key_data, NULL);
EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr);
@@ -397,8 +421,6 @@ odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param,
ret = internal_decrypt(ctx, param);
- EVP_CIPHER_CTX_free(ctx);
-
return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE :
ODP_CRYPTO_ALG_ERR_NONE;
}
@@ -434,7 +456,7 @@ static
odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
odp_crypto_generic_session_t *session)
{
- EVP_CIPHER_CTX *ctx;
+ EVP_CIPHER_CTX *ctx = local.cipher;
const uint8_t *aad_head = param->aad.ptr;
uint32_t aad_len = param->aad.length;
void *iv_ptr;
@@ -450,7 +472,6 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
return ODP_CRYPTO_ALG_ERR_IV_INVALID;
/* Encrypt it */
- ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL,
session->cipher.key_data, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN,
@@ -470,8 +491,6 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
odp_packet_copy_from_mem(param->out_pkt, param->hash_result_offset,
session->p.auth_digest_len, block);
- EVP_CIPHER_CTX_free(ctx);
-
return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE :
ODP_CRYPTO_ALG_ERR_NONE;
}
@@ -480,7 +499,7 @@ static
odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
odp_crypto_generic_session_t *session)
{
- EVP_CIPHER_CTX *ctx;
+ EVP_CIPHER_CTX *ctx = local.cipher;
const uint8_t *aad_head = param->aad.ptr;
uint32_t aad_len = param->aad.length;
int dummy_len = 0;
@@ -496,7 +515,6 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
return ODP_CRYPTO_ALG_ERR_IV_INVALID;
/* Decrypt it */
- ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL,
session->cipher.key_data, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN,
@@ -516,8 +534,6 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
ret = internal_decrypt(ctx, param);
- EVP_CIPHER_CTX_free(ctx);
-
return ret <= 0 ? ODP_CRYPTO_ALG_ERR_ICV_CHECK :
ODP_CRYPTO_ALG_ERR_NONE;
}
@@ -300,6 +300,12 @@ int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type)
}
stage = PKTIO_INIT;
+ if (odp_crypto_init_local()) {
+ ODP_ERR("ODP crypto local init failed.\n");
+ goto init_fail;
+ }
+ stage = CRYPTO_INIT;
+
if (odp_pool_init_local()) {
ODP_ERR("ODP pool local init failed.\n");
goto init_fail;
@@ -352,6 +358,13 @@ int _odp_term_local(enum init_stage stage)
}
/* Fall through */
+ case CRYPTO_INIT:
+ if (odp_crypto_term_local()) {
+ ODP_ERR("ODP crypto local term failed.\n");
+ rc = -1;
+ }
+ /* Fall through */
+
case POOL_INIT:
if (odp_pool_term_local()) {
ODP_ERR("ODP buffer pool local term failed.\n");