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

Reply via email to