Switch AES-CBC and 3DES-CBC to use generic (EVP) interface instad of low level interface (as recommended by OpenSSL documentation). This allows to use the same code path for all non-AEAD ciphers. The only AEAD cipher (AES-GCM) already uses EVP interface. Generalization of that code can happen if there will be more AEAD ciphers.
Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsoleni...@linaro.org> --- .../linux-generic/include/odp_crypto_internal.h | 16 +- platform/linux-generic/odp_crypto.c | 232 +++++---------------- 2 files changed, 52 insertions(+), 196 deletions(-) diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h index 515cefaa..033fa6d9 100644 --- a/platform/linux-generic/include/odp_crypto_internal.h +++ b/platform/linux-generic/include/odp_crypto_internal.h @@ -11,8 +11,6 @@ extern "C" { #endif -#include <openssl/des.h> -#include <openssl/aes.h> #include <openssl/evp.h> #define MAX_IV_LEN 64 @@ -43,19 +41,7 @@ struct odp_crypto_generic_session { /* Copy of session IV data */ uint8_t iv_data[MAX_IV_LEN]; - union { - struct { - DES_key_schedule ks1; - DES_key_schedule ks2; - DES_key_schedule ks3; - } des; - struct { - AES_KEY key; - } aes; - struct { - EVP_CIPHER_CTX *ctx; - } aes_gcm; - } data; + EVP_CIPHER_CTX ctx; crypto_func_t func; } cipher; diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 4d59b827..ad4d169c 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -176,90 +176,6 @@ odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param, } static -odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) -{ - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t len = param->cipher_range.length; - unsigned char iv_enc[AES_BLOCK_SIZE]; - void *iv_ptr; - - if (param->override_iv_ptr) - iv_ptr = param->override_iv_ptr; - else if (session->p.iv.data) - iv_ptr = session->cipher.iv_data; - else - return ODP_CRYPTO_ALG_ERR_IV_INVALID; - - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); - - /* Adjust pointer for beginning of area to cipher */ - data += param->cipher_range.offset; - /* Encrypt it */ - AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key, - iv_enc, AES_ENCRYPT); - - return ODP_CRYPTO_ALG_ERR_NONE; -} - -static -odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) -{ - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t len = param->cipher_range.length; - unsigned char iv_enc[AES_BLOCK_SIZE]; - void *iv_ptr; - - if (param->override_iv_ptr) - iv_ptr = param->override_iv_ptr; - else if (session->p.iv.data) - iv_ptr = session->cipher.iv_data; - else - return ODP_CRYPTO_ALG_ERR_IV_INVALID; - - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); - - /* Adjust pointer for beginning of area to cipher */ - data += param->cipher_range.offset; - /* Encrypt it */ - AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key, - iv_enc, AES_DECRYPT); - - return ODP_CRYPTO_ALG_ERR_NONE; -} - -static int process_aes_param(odp_crypto_generic_session_t *session) -{ - /* Verify IV len is either 0 or 16 */ - if (!((0 == session->p.iv.length) || (16 == session->p.iv.length))) - return -1; - - /* Set function */ - if (ODP_CRYPTO_OP_ENCODE == session->p.op) { - session->cipher.func = aes_encrypt; - AES_set_encrypt_key(session->p.cipher_key.data, 128, - &session->cipher.data.aes.key); - } else { - session->cipher.func = aes_decrypt; - AES_set_decrypt_key(session->p.cipher_key.data, 128, - &session->cipher.data.aes.key); - } - - return 0; -} - -static odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { @@ -269,7 +185,6 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, uint8_t *aad_tail = data + param->cipher_range.offset + param->cipher_range.length; uint32_t auth_len = param->auth_range.length; - unsigned char iv_enc[AES_BLOCK_SIZE]; void *iv_ptr; uint8_t *tag = data + param->hash_result_offset; @@ -286,21 +201,14 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, param->cipher_range.offset + plain_len) return ODP_CRYPTO_ALG_ERR_DATA_SIZE; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); - /* Adjust pointer for beginning of area to cipher/auth */ uint8_t *plaindata = data + param->cipher_range.offset; /* Encrypt it */ - EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx; + EVP_CIPHER_CTX *ctx = &session->cipher.ctx; int cipher_len = 0; - EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_enc); + EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); /* Authenticate header data (if any) without encrypting them */ if (aad_head < plaindata) { @@ -334,7 +242,6 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, uint8_t *aad_tail = data + param->cipher_range.offset + param->cipher_range.length; uint32_t auth_len = param->auth_range.length; - unsigned char iv_enc[AES_BLOCK_SIZE]; void *iv_ptr; uint8_t *tag = data + param->hash_result_offset; @@ -351,20 +258,13 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, param->cipher_range.offset + cipher_len) return ODP_CRYPTO_ALG_ERR_DATA_SIZE; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); - /* Adjust pointer for beginning of area to cipher/auth */ uint8_t *cipherdata = data + param->cipher_range.offset; /* Encrypt it */ - EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx; + EVP_CIPHER_CTX *ctx = &session->cipher.ctx; int plain_len = 0; - EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_enc); + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag); @@ -392,14 +292,15 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, static int process_aes_gcm_param(odp_crypto_generic_session_t *session) { + EVP_CIPHER_CTX *ctx = &session->cipher.ctx; + + EVP_CIPHER_CTX_init(ctx); + /* Verify Key len is 16 */ if (session->p.cipher_key.length != 16) return -1; /* Set function */ - EVP_CIPHER_CTX *ctx = - session->cipher.data.aes_gcm.ctx = EVP_CIPHER_CTX_new(); - if (ODP_CRYPTO_OP_ENCODE == session->p.op) { session->cipher.func = aes_gcm_encrypt; EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); @@ -422,13 +323,14 @@ static int process_aes_gcm_param(odp_crypto_generic_session_t *session) } static -odp_crypto_alg_err_t des_encrypt(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t cipher_crypt(odp_crypto_op_param_t *param, + odp_crypto_generic_session_t *session) { uint8_t *data = odp_packet_data(param->out_pkt); uint32_t len = param->cipher_range.length; - DES_cblock iv; void *iv_ptr; + int cipher_len = 0; + int rc; if (param->override_iv_ptr) iv_ptr = param->override_iv_ptr; @@ -437,86 +339,55 @@ odp_crypto_alg_err_t des_encrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv, iv_ptr, sizeof(iv)); - - /* Adjust pointer for beginning of area to cipher */ - data += param->cipher_range.offset; - /* Encrypt it */ - DES_ede3_cbc_encrypt(data, - data, - len, - &session->cipher.data.des.ks1, - &session->cipher.data.des.ks2, - &session->cipher.data.des.ks3, - &iv, - 1); - - return ODP_CRYPTO_ALG_ERR_NONE; -} - -static -odp_crypto_alg_err_t des_decrypt(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) -{ - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t len = param->cipher_range.length; - DES_cblock iv; - void *iv_ptr; - - if (param->override_iv_ptr) - iv_ptr = param->override_iv_ptr; - else if (session->p.iv.data) - iv_ptr = session->cipher.iv_data; - else + rc = EVP_CipherInit_ex(&session->cipher.ctx, + NULL, NULL, NULL, iv_ptr, -1); + if (odp_unlikely(1 != rc)) return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv, iv_ptr, sizeof(iv)); - /* Adjust pointer for beginning of area to cipher */ data += param->cipher_range.offset; - /* Decrypt it */ - DES_ede3_cbc_encrypt(data, - data, - len, - &session->cipher.data.des.ks1, - &session->cipher.data.des.ks2, - &session->cipher.data.des.ks3, - &iv, - 0); + /* En/Decrypt it */ + EVP_CipherUpdate(&session->cipher.ctx, + data, + &cipher_len, + data, + len); + + EVP_CipherFinal_ex(&session->cipher.ctx, + data + cipher_len, + &cipher_len); return ODP_CRYPTO_ALG_ERR_NONE; } -static int process_des_param(odp_crypto_generic_session_t *session) +static int process_cipher_param(odp_crypto_generic_session_t *session, + const EVP_CIPHER *cipher) { + int rc; + + /* Verify Key len is 16 */ + if ((uint32_t)EVP_CIPHER_key_length(cipher) != + session->p.cipher_key.length) + return -1; + /* Verify IV len is either 0 or 8 */ - if (!((0 == session->p.iv.length) || (8 == session->p.iv.length))) + if (!((0 == session->p.iv.length) || + ((uint32_t)EVP_CIPHER_iv_length(cipher) == session->p.iv.length))) return -1; /* Set function */ - if (ODP_CRYPTO_OP_ENCODE == session->p.op) - session->cipher.func = des_encrypt; - else - session->cipher.func = des_decrypt; - - /* Convert keys */ - DES_set_key((DES_cblock *)&session->p.cipher_key.data[0], - &session->cipher.data.des.ks1); - DES_set_key((DES_cblock *)&session->p.cipher_key.data[8], - &session->cipher.data.des.ks2); - DES_set_key((DES_cblock *)&session->p.cipher_key.data[16], - &session->cipher.data.des.ks3); + session->cipher.func = cipher_crypt; + + EVP_CIPHER_CTX_init(&session->cipher.ctx); + rc = EVP_CipherInit_ex(&session->cipher.ctx, + cipher, + NULL, + session->p.cipher_key.data, + NULL, + (ODP_CRYPTO_OP_ENCODE == session->p.op) ? 1 : 0); + if (odp_unlikely(1 != rc)) + return -1; return 0; } @@ -701,12 +572,12 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, break; case ODP_CIPHER_ALG_DES: case ODP_CIPHER_ALG_3DES_CBC: - rc = process_des_param(session); + rc = process_cipher_param(session, EVP_des_ede3_cbc()); break; case ODP_CIPHER_ALG_AES_CBC: /* deprecated */ case ODP_CIPHER_ALG_AES128_CBC: - rc = process_aes_param(session); + rc = process_cipher_param(session, EVP_aes_128_cbc()); break; case ODP_CIPHER_ALG_AES_GCM: /* deprecated */ @@ -778,9 +649,8 @@ int odp_crypto_session_destroy(odp_crypto_session_t session) odp_crypto_generic_session_t *generic; generic = (odp_crypto_generic_session_t *)(intptr_t)session; - if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES128_GCM || - generic->p.cipher_alg == ODP_CIPHER_ALG_AES_GCM) - EVP_CIPHER_CTX_free(generic->cipher.data.aes_gcm.ctx); + if (ODP_CIPHER_ALG_NULL != generic->p.cipher_alg) + EVP_CIPHER_CTX_cleanup(&generic->cipher.ctx); memset(generic, 0, sizeof(*generic)); free_session(generic); return 0; -- 2.11.0