@@ -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;
@@ -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;
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.ereminsolenikov@linaro.org> --- .../linux-generic/include/odp_crypto_internal.h | 16 +- platform/linux-generic/odp_crypto.c | 232 +++++---------------- 2 files changed, 52 insertions(+), 196 deletions(-) -- 2.11.0