diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h
index 515cefaa..9eed87b6 100644
--- a/platform/linux-generic/include/odp_crypto_internal.h
+++ b/platform/linux-generic/include/odp_crypto_internal.h
@@ -43,19 +43,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..5078a3b1 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)
 {
@@ -297,7 +213,7 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param,
 	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);
@@ -361,7 +277,7 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param,
 	/* 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);
@@ -392,14 +308,14 @@ 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 +338,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 +354,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 +587,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 +664,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;
