[v4] cryptodev: make xform key pointer constant

Message ID 20190624133522.80732-1-roy.fan.zhang@intel.com (mailing list archive)
State Accepted, archived
Delegated to: akhil goyal
Headers
Series [v4] cryptodev: make xform key pointer constant |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues
ci/intel-Performance-Testing success Performance Testing PASS
ci/mellanox-Performance-Testing success Performance Testing PASS

Commit Message

Fan Zhang June 24, 2019, 1:35 p.m. UTC
  This patch changes the key pointer data types in cipher, auth,
and aead xforms from "uint8_t *" to "const uint8_t *" for a
more intuitive and safe sessionn creation.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
---
v4:
- Removed deprecation notice and updated release note.
- Updated ABI version.

v3:
- rebased on top of latest dpdk-next-crypto

v2:
- fixed a missed memory free for ixgbe ipsec
 doc/guides/rel_notes/deprecation.rst            |  4 --
 doc/guides/rel_notes/release_19_08.rst          |  4 ++
 drivers/common/cpt/cpt_ucode.h                  | 14 ++---
 drivers/crypto/aesni_gcm/aesni_gcm_pmd.c        |  2 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c      |  2 +-
 drivers/crypto/openssl/rte_openssl_pmd.c        |  8 +--
 drivers/crypto/qat/qat_sym_session.c            |  8 +--
 drivers/crypto/qat/qat_sym_session.h            |  4 +-
 drivers/crypto/snow3g/rte_snow3g_pmd.c          | 23 ++++++--
 drivers/crypto/snow3g/rte_snow3g_pmd_private.h  |  1 +
 drivers/crypto/virtio/virtio_cryptodev.c        | 30 +++++++---
 drivers/crypto/virtio/virtio_cryptodev.h        |  2 +
 drivers/net/ixgbe/ixgbe_ipsec.c                 | 35 +++++++++---
 drivers/net/ixgbe/ixgbe_ipsec.h                 |  3 +-
 drivers/net/softnic/rte_eth_softnic_cli.c       | 74 ++++++++++++-------------
 drivers/net/softnic/rte_eth_softnic_internals.h |  4 ++
 examples/ip_pipeline/cli.c                      | 74 ++++++++++++-------------
 examples/ip_pipeline/cryptodev.c                |  2 -
 examples/ip_pipeline/pipeline.h                 |  6 ++
 examples/l2fwd-crypto/main.c                    | 40 +++++--------
 lib/librte_cryptodev/Makefile                   |  2 +-
 lib/librte_cryptodev/meson.build                |  2 +-
 lib/librte_cryptodev/rte_crypto_sym.h           | 12 ++--
 23 files changed, 196 insertions(+), 160 deletions(-)
  

Comments

Akhil Goyal June 25, 2019, 12:46 p.m. UTC | #1
> 
> This patch changes the key pointer data types in cipher, auth,
> and aead xforms from "uint8_t *" to "const uint8_t *" for a
> more intuitive and safe sessionn creation.
> 
> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> Acked-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
> ---
> v4:
> - Removed deprecation notice and updated release note.
> - Updated ABI version.
> 
> v3:
> - rebased on top of latest dpdk-next-crypto
> 
> v2:
> - fixed a missed memory free for ixgbe ipsec

Applied to dpdk-next-crypto
The changes related to update for ABI version were incomplete in this patch, so they were dropped. Another patch from Anoob was also updating the ABI version, so not required in this patch.

Thanks.
  
Thomas Monjalon July 5, 2019, 12:30 p.m. UTC | #2
25/06/2019 14:46, Akhil Goyal:
> 
> > 
> > This patch changes the key pointer data types in cipher, auth,
> > and aead xforms from "uint8_t *" to "const uint8_t *" for a
> > more intuitive and safe sessionn creation.
> > 
> > Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> > Acked-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> > Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
> > ---
> > v4:
> > - Removed deprecation notice and updated release note.
> > - Updated ABI version.
> > 
> > v3:
> > - rebased on top of latest dpdk-next-crypto
> > 
> > v2:
> > - fixed a missed memory free for ixgbe ipsec
> 
> Applied to dpdk-next-crypto
> The changes related to update for ABI version were incomplete in this patch, so they were dropped. Another patch from Anoob was also updating the ABI version, so not required in this patch.


I think this patch is not complete, because there is a compilation issue
with mvsam PMD when compiling arm64-thunderx-linux-gcc:

	drivers/crypto/mvsam/rte_mrvl_pmd.c:260:35: error:
	assignment discards 'const' qualifier from pointer target type
  

Patch

diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e2721fad6..90b29ab1a 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -76,10 +76,6 @@  Deprecation Notices
 
   The field would be added in v19.08.
 
-* cryptodev: the ``uint8_t *data`` member of ``key`` structure in the xforms
-  structure (``rte_crypto_cipher_xform``, ``rte_crypto_auth_xform``, and
-  ``rte_crypto_aead_xform``) will be changed to ``const uint8_t *data``.
-
 * cryptodev: support for using IV with all sizes is added, J0 still can
   be used but only when IV length in following structs ``rte_crypto_auth_xform``,
   ``rte_crypto_aead_xform`` is set to zero. When IV length is greater or equal
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 8c3932d06..a22e93863 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -124,6 +124,10 @@  API Changes
 * The network structures, definitions and functions have
   been prefixed by ``rte_`` to resolve conflicts with libc headers.
 
+* cryptodev: the ``uint8_t *data`` member of ``key`` structure in the xforms
+  structure (``rte_crypto_cipher_xform``, ``rte_crypto_auth_xform``, and
+  ``rte_crypto_aead_xform``) have been changed to ``const uint8_t *data``.
+
 
 ABI Changes
 -----------
diff --git a/drivers/common/cpt/cpt_ucode.h b/drivers/common/cpt/cpt_ucode.h
index f21352e6c..4f5e5dc88 100644
--- a/drivers/common/cpt/cpt_ucode.h
+++ b/drivers/common/cpt/cpt_ucode.h
@@ -55,7 +55,7 @@  cpt_is_algo_supported(struct rte_crypto_sym_xform *xform)
 }
 
 static __rte_always_inline void
-gen_key_snow3g(uint8_t *ck, uint32_t *keyx)
+gen_key_snow3g(const uint8_t *ck, uint32_t *keyx)
 {
 	int i, base;
 
@@ -174,7 +174,7 @@  cpt_fc_ciph_set_key_set_aes_key_type(mc_fc_context_t *fctx, uint16_t key_len)
 }
 
 static __rte_always_inline void
-cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, uint8_t *key,
+cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, const uint8_t *key,
 		uint16_t key_len)
 {
 	uint32_t keyx[4];
@@ -186,7 +186,7 @@  cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, uint8_t *key,
 }
 
 static __rte_always_inline void
-cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, uint8_t *key,
+cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, const uint8_t *key,
 		uint16_t key_len)
 {
 	cpt_ctx->snow3g = 0;
@@ -197,7 +197,7 @@  cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, uint8_t *key,
 }
 
 static __rte_always_inline void
-cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, uint8_t *key,
+cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, const uint8_t *key,
 		uint16_t key_len)
 {
 	cpt_ctx->k_ecb = 1;
@@ -207,7 +207,7 @@  cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, uint8_t *key,
 }
 
 static __rte_always_inline void
-cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, uint8_t *key,
+cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, const uint8_t *key,
 		uint16_t key_len)
 {
 	memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
@@ -216,7 +216,7 @@  cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, uint8_t *key,
 }
 
 static __rte_always_inline int
-cpt_fc_ciph_set_key(void *ctx, cipher_type_t type, uint8_t *key,
+cpt_fc_ciph_set_key(void *ctx, cipher_type_t type, const uint8_t *key,
 		    uint16_t key_len, uint8_t *salt)
 {
 	struct cpt_ctx *cpt_ctx = ctx;
@@ -2569,7 +2569,7 @@  cpt_fc_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens,
 }
 
 static __rte_always_inline int
-cpt_fc_auth_set_key(void *ctx, auth_type_t type, uint8_t *key,
+cpt_fc_auth_set_key(void *ctx, auth_type_t type, const uint8_t *key,
 		    uint16_t key_len, uint16_t mac_len)
 {
 	struct cpt_ctx *cpt_ctx = ctx;
diff --git a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
index 49ee31708..1006a5c4d 100644
--- a/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
+++ b/drivers/crypto/aesni_gcm/aesni_gcm_pmd.c
@@ -24,7 +24,7 @@  aesni_gcm_set_session_parameters(const struct aesni_gcm_ops *gcm_ops,
 	const struct rte_crypto_sym_xform *auth_xform;
 	const struct rte_crypto_sym_xform *aead_xform;
 	uint8_t key_length;
-	uint8_t *key;
+	const uint8_t *key;
 
 	/* AES-GMAC */
 	if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index edb6608e2..b495a9679 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -35,7 +35,7 @@  typedef void (*aes_keyexp_t)(const void *key, void *enc_exp_keys, void *dec_exp_
 static void
 calculate_auth_precomputes(hash_one_block_t one_block_hash,
 		uint8_t *ipad, uint8_t *opad,
-		uint8_t *hkey, uint16_t hkey_len,
+		const uint8_t *hkey, uint16_t hkey_len,
 		uint16_t blocksize)
 {
 	unsigned i, length;
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 73ce3833c..7c8bf0d9f 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -92,14 +92,14 @@  openssl_get_chain_order(const struct rte_crypto_sym_xform *xform)
 
 /** Get session cipher key from input cipher key */
 static void
-get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key)
+get_cipher_key(const uint8_t *input_key, int keylen, uint8_t *session_key)
 {
 	memcpy(session_key, input_key, keylen);
 }
 
 /** Get key ede 24 bytes standard from input key */
 static int
-get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede)
+get_cipher_key_ede(const uint8_t *key, int keylen, uint8_t *key_ede)
 {
 	int res = 0;
 
@@ -292,7 +292,7 @@  get_aead_algo(enum rte_crypto_aead_algorithm sess_algo, size_t keylen,
 static int
 openssl_set_sess_aead_enc_param(struct openssl_session *sess,
 		enum rte_crypto_aead_algorithm algo,
-		uint8_t tag_len, uint8_t *key)
+		uint8_t tag_len, const uint8_t *key)
 {
 	int iv_type = 0;
 	unsigned int do_ccm;
@@ -352,7 +352,7 @@  openssl_set_sess_aead_enc_param(struct openssl_session *sess,
 static int
 openssl_set_sess_aead_dec_param(struct openssl_session *sess,
 		enum rte_crypto_aead_algorithm algo,
-		uint8_t tag_len, uint8_t *key)
+		uint8_t tag_len, const uint8_t *key)
 {
 	int iv_type = 0;
 	unsigned int do_ccm = 0;
diff --git a/drivers/crypto/qat/qat_sym_session.c b/drivers/crypto/qat/qat_sym_session.c
index f66175d03..e5167b3fa 100644
--- a/drivers/crypto/qat/qat_sym_session.c
+++ b/drivers/crypto/qat/qat_sym_session.c
@@ -35,7 +35,7 @@  bpi_cipher_ctx_free(void *bpi_ctx)
 static int
 bpi_cipher_ctx_init(enum rte_crypto_cipher_algorithm cryptodev_algo,
 		enum rte_crypto_cipher_operation direction __rte_unused,
-		uint8_t *key, void **ctx)
+		const uint8_t *key, void **ctx)
 {
 	const EVP_CIPHER *algo = NULL;
 	int ret;
@@ -510,7 +510,7 @@  qat_sym_session_configure_auth(struct rte_cryptodev *dev,
 {
 	struct rte_crypto_auth_xform *auth_xform = qat_get_auth_xform(xform);
 	struct qat_sym_dev_private *internals = dev->data->dev_private;
-	uint8_t *key_data = auth_xform->key.data;
+	const uint8_t *key_data = auth_xform->key.data;
 	uint8_t key_length = auth_xform->key.length;
 	session->aes_cmac = 0;
 
@@ -1272,7 +1272,7 @@  qat_get_crypto_proto_flag(uint16_t flags)
 }
 
 int qat_sym_session_aead_create_cd_cipher(struct qat_sym_session *cdesc,
-						uint8_t *cipherkey,
+						const uint8_t *cipherkey,
 						uint32_t cipherkeylen)
 {
 	struct icp_qat_hw_cipher_algo_blk *cipher;
@@ -1427,7 +1427,7 @@  int qat_sym_session_aead_create_cd_cipher(struct qat_sym_session *cdesc,
 }
 
 int qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc,
-						uint8_t *authkey,
+						const uint8_t *authkey,
 						uint32_t authkeylen,
 						uint32_t aad_length,
 						uint32_t digestsize,
diff --git a/drivers/crypto/qat/qat_sym_session.h b/drivers/crypto/qat/qat_sym_session.h
index 43e25ceb7..ce1ca5af8 100644
--- a/drivers/crypto/qat/qat_sym_session.h
+++ b/drivers/crypto/qat/qat_sym_session.h
@@ -106,12 +106,12 @@  qat_sym_session_configure_auth(struct rte_cryptodev *dev,
 
 int
 qat_sym_session_aead_create_cd_cipher(struct qat_sym_session *cd,
-						uint8_t *enckey,
+						const uint8_t *enckey,
 						uint32_t enckeylen);
 
 int
 qat_sym_session_aead_create_cd_auth(struct qat_sym_session *cdesc,
-						uint8_t *authkey,
+						const uint8_t *authkey,
 						uint32_t authkeylen,
 						uint32_t aad_length,
 						uint32_t digestsize,
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd.c b/drivers/crypto/snow3g/rte_snow3g_pmd.c
index 5fd94b686..68d7176f4 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd.c
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd.c
@@ -84,6 +84,8 @@  snow3g_set_session_parameters(struct snow3g_session *sess,
 	}
 
 	if (cipher_xform) {
+		uint8_t cipher_key[SNOW3G_MAX_KEY_SIZE];
+
 		/* Only SNOW 3G UEA2 supported */
 		if (cipher_xform->cipher.algo != RTE_CRYPTO_CIPHER_SNOW3G_UEA2)
 			return -ENOTSUP;
@@ -92,14 +94,22 @@  snow3g_set_session_parameters(struct snow3g_session *sess,
 			SNOW3G_LOG(ERR, "Wrong IV length");
 			return -EINVAL;
 		}
+		if (cipher_xform->cipher.key.length > SNOW3G_MAX_KEY_SIZE) {
+			SNOW3G_LOG(ERR, "Not enough memory to store the key");
+			return -ENOMEM;
+		}
+
 		sess->cipher_iv_offset = cipher_xform->cipher.iv.offset;
 
 		/* Initialize key */
-		sso_snow3g_init_key_sched(cipher_xform->cipher.key.data,
-				&sess->pKeySched_cipher);
+		memcpy(cipher_key, cipher_xform->cipher.key.data,
+				cipher_xform->cipher.key.length);
+		sso_snow3g_init_key_sched(cipher_key, &sess->pKeySched_cipher);
 	}
 
 	if (auth_xform) {
+		uint8_t auth_key[SNOW3G_MAX_KEY_SIZE];
+
 		/* Only SNOW 3G UIA2 supported */
 		if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_SNOW3G_UIA2)
 			return -ENOTSUP;
@@ -108,6 +118,10 @@  snow3g_set_session_parameters(struct snow3g_session *sess,
 			SNOW3G_LOG(ERR, "Wrong digest length");
 			return -EINVAL;
 		}
+		if (auth_xform->auth.key.length > SNOW3G_MAX_KEY_SIZE) {
+			SNOW3G_LOG(ERR, "Not enough memory to store the key");
+			return -ENOMEM;
+		}
 
 		sess->auth_op = auth_xform->auth.op;
 
@@ -118,8 +132,9 @@  snow3g_set_session_parameters(struct snow3g_session *sess,
 		sess->auth_iv_offset = auth_xform->auth.iv.offset;
 
 		/* Initialize key */
-		sso_snow3g_init_key_sched(auth_xform->auth.key.data,
-				&sess->pKeySched_hash);
+		memcpy(auth_key, auth_xform->auth.key.data,
+				auth_xform->auth.key.length);
+		sso_snow3g_init_key_sched(auth_key, &sess->pKeySched_hash);
 	}
 
 
diff --git a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
index df5c6092b..95a3eba22 100644
--- a/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
+++ b/drivers/crypto/snow3g/rte_snow3g_pmd_private.h
@@ -19,6 +19,7 @@  int snow3g_logtype_driver;
 					## __VA_ARGS__)
 
 #define SNOW3G_DIGEST_LENGTH 4
+#define SNOW3G_MAX_KEY_SIZE  128
 
 /** private data structure for each virtual SNOW 3G device */
 struct snow3g_private {
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 4bae3b865..f16bdfe57 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -1210,7 +1210,7 @@  static int
 virtio_crypto_sym_pad_op_ctrl_req(
 		struct virtio_crypto_op_ctrl_req *ctrl,
 		struct rte_crypto_sym_xform *xform, bool is_chainned,
-		uint8_t **cipher_key_data, uint8_t **auth_key_data,
+		uint8_t *cipher_key_data, uint8_t *auth_key_data,
 		struct virtio_crypto_session *session)
 {
 	int ret;
@@ -1220,6 +1220,12 @@  virtio_crypto_sym_pad_op_ctrl_req(
 	/* Get cipher xform from crypto xform chain */
 	cipher_xform = virtio_crypto_get_cipher_xform(xform);
 	if (cipher_xform) {
+		if (cipher_xform->key.length > VIRTIO_CRYPTO_MAX_KEY_SIZE) {
+			VIRTIO_CRYPTO_SESSION_LOG_ERR(
+				"cipher key size cannot be longer than %u",
+				VIRTIO_CRYPTO_MAX_KEY_SIZE);
+			return -1;
+		}
 		if (cipher_xform->iv.length > VIRTIO_CRYPTO_MAX_IV_SIZE) {
 			VIRTIO_CRYPTO_SESSION_LOG_ERR(
 				"cipher IV size cannot be longer than %u",
@@ -1241,7 +1247,8 @@  virtio_crypto_sym_pad_op_ctrl_req(
 			return -1;
 		}
 
-		*cipher_key_data = cipher_xform->key.data;
+		memcpy(cipher_key_data, cipher_xform->key.data,
+				cipher_xform->key.length);
 
 		session->iv.offset = cipher_xform->iv.offset;
 		session->iv.length = cipher_xform->iv.length;
@@ -1254,13 +1261,20 @@  virtio_crypto_sym_pad_op_ctrl_req(
 		struct virtio_crypto_alg_chain_session_para *para =
 			&(ctrl->u.sym_create_session.u.chain.para);
 		if (auth_xform->key.length) {
+			if (auth_xform->key.length >
+					VIRTIO_CRYPTO_MAX_KEY_SIZE) {
+				VIRTIO_CRYPTO_SESSION_LOG_ERR(
+				"auth key size cannot be longer than %u",
+					VIRTIO_CRYPTO_MAX_KEY_SIZE);
+				return -1;
+			}
 			para->hash_mode = VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH;
 			para->u.mac_param.auth_key_len =
 				(uint32_t)auth_xform->key.length;
 			para->u.mac_param.hash_result_len =
 				auth_xform->digest_length;
-
-			*auth_key_data = auth_xform->key.data;
+			memcpy(auth_key_data, auth_xform->key.data,
+					auth_xform->key.length);
 		} else {
 			para->hash_mode	= VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN;
 			para->u.hash_param.hash_result_len =
@@ -1310,8 +1324,8 @@  virtio_crypto_sym_configure_session(
 	struct virtio_crypto_session *session;
 	struct virtio_crypto_op_ctrl_req *ctrl_req;
 	enum virtio_crypto_cmd_id cmd_id;
-	uint8_t *cipher_key_data = NULL;
-	uint8_t *auth_key_data = NULL;
+	uint8_t cipher_key_data[VIRTIO_CRYPTO_MAX_KEY_SIZE] = {0};
+	uint8_t auth_key_data[VIRTIO_CRYPTO_MAX_KEY_SIZE] = {0};
 	struct virtio_crypto_hw *hw;
 	struct virtqueue *control_vq;
 
@@ -1355,7 +1369,7 @@  virtio_crypto_sym_configure_session(
 			= VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING;
 
 		ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl_req,
-			xform, true, &cipher_key_data, &auth_key_data, session);
+			xform, true, cipher_key_data, auth_key_data, session);
 		if (ret < 0) {
 			VIRTIO_CRYPTO_SESSION_LOG_ERR(
 				"padding sym op ctrl req failed");
@@ -1373,7 +1387,7 @@  virtio_crypto_sym_configure_session(
 		ctrl_req->u.sym_create_session.op_type
 			= VIRTIO_CRYPTO_SYM_OP_CIPHER;
 		ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl_req, xform,
-			false, &cipher_key_data, &auth_key_data, session);
+			false, cipher_key_data, auth_key_data, session);
 		if (ret < 0) {
 			VIRTIO_CRYPTO_SESSION_LOG_ERR(
 				"padding sym op ctrl req failed");
diff --git a/drivers/crypto/virtio/virtio_cryptodev.h b/drivers/crypto/virtio/virtio_cryptodev.h
index 0fd7b722e..215bce786 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.h
+++ b/drivers/crypto/virtio/virtio_cryptodev.h
@@ -18,6 +18,8 @@ 
 
 #define VIRTIO_CRYPTO_MAX_IV_SIZE 16
 
+#define VIRTIO_CRYPTO_MAX_KEY_SIZE 256
+
 extern uint8_t cryptodev_virtio_driver_id;
 
 enum virtio_crypto_cmd_id {
diff --git a/drivers/net/ixgbe/ixgbe_ipsec.c b/drivers/net/ixgbe/ixgbe_ipsec.c
index 5a416885f..57f2388e2 100644
--- a/drivers/net/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ixgbe/ixgbe_ipsec.c
@@ -97,6 +97,7 @@  ixgbe_crypto_add_sa(struct ixgbe_crypto_session *ic_session)
 
 	if (ic_session->op == IXGBE_OP_AUTHENTICATED_DECRYPTION) {
 		int i, ip_index = -1;
+		uint8_t *key;
 
 		/* Find a match in the IP table*/
 		for (i = 0; i < IPSEC_MAX_RX_IP_COUNT; i++) {
@@ -189,23 +190,32 @@  ixgbe_crypto_add_sa(struct ixgbe_crypto_session *ic_session)
 		IXGBE_WAIT_RWRITE;
 
 		/* write Key table entry*/
+		key = malloc(ic_session->key_len);
+		if (!key)
+			return -ENOMEM;
+
+		memcpy(key, ic_session->key, ic_session->key_len);
+
 		reg_val = IPSRXIDX_RX_EN | IPSRXIDX_WRITE |
 				IPSRXIDX_TABLE_KEY | (sa_index << 3);
 		IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(0),
-			rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[12]));
+			rte_cpu_to_be_32(*(uint32_t *)&key[12]));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(1),
-			rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[8]));
+			rte_cpu_to_be_32(*(uint32_t *)&key[8]));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(2),
-			rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[4]));
+			rte_cpu_to_be_32(*(uint32_t *)&key[4]));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(3),
-			rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[0]));
+			rte_cpu_to_be_32(*(uint32_t *)&key[0]));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSRXSALT,
 				rte_cpu_to_be_32(ic_session->salt));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSRXMOD,
 				priv->rx_sa_tbl[sa_index].mode);
 		IXGBE_WAIT_RWRITE;
 
+		free(key);
+
 	} else { /* sess->dir == RTE_CRYPTO_OUTBOUND */
+		uint8_t *key;
 		int i;
 
 		/* Find a free entry in the SA table*/
@@ -227,19 +237,27 @@  ixgbe_crypto_add_sa(struct ixgbe_crypto_session *ic_session)
 		priv->tx_sa_tbl[i].used = 1;
 		ic_session->sa_index = sa_index;
 
+		key = malloc(ic_session->key_len);
+		if (!key)
+			return -ENOMEM;
+
+		memcpy(key, ic_session->key, ic_session->key_len);
+
 		/* write Key table entry*/
 		reg_val = IPSRXIDX_RX_EN | IPSRXIDX_WRITE | (sa_index << 3);
 		IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(0),
-			rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[12]));
+			rte_cpu_to_be_32(*(uint32_t *)&key[12]));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(1),
-			rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[8]));
+			rte_cpu_to_be_32(*(uint32_t *)&key[8]));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(2),
-			rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[4]));
+			rte_cpu_to_be_32(*(uint32_t *)&key[4]));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(3),
-			rte_cpu_to_be_32(*(uint32_t *)&ic_session->key[0]));
+			rte_cpu_to_be_32(*(uint32_t *)&key[0]));
 		IXGBE_WRITE_REG(hw, IXGBE_IPSTXSALT,
 				rte_cpu_to_be_32(ic_session->salt));
 		IXGBE_WAIT_TWRITE;
+
+		free(key);
 	}
 
 	return 0;
@@ -388,6 +406,7 @@  ixgbe_crypto_create_session(void *device,
 	}
 
 	ic_session->key = aead_xform->key.data;
+	ic_session->key_len = aead_xform->key.length;
 	memcpy(&ic_session->salt,
 	       &aead_xform->key.data[aead_xform->key.length], 4);
 	ic_session->spi = conf->ipsec.spi;
diff --git a/drivers/net/ixgbe/ixgbe_ipsec.h b/drivers/net/ixgbe/ixgbe_ipsec.h
index c73e18069..e218c0a4a 100644
--- a/drivers/net/ixgbe/ixgbe_ipsec.h
+++ b/drivers/net/ixgbe/ixgbe_ipsec.h
@@ -62,7 +62,8 @@  struct ipaddr {
 /** inline crypto crypto private session structure */
 struct ixgbe_crypto_session {
 	enum ixgbe_operation op;
-	uint8_t *key;
+	const uint8_t *key;
+	uint32_t key_len;
 	uint32_t salt;
 	uint32_t sa_index;
 	uint32_t spi;
diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c
index 56fc92ba2..88e0a848e 100644
--- a/drivers/net/softnic/rte_eth_softnic_cli.c
+++ b/drivers/net/softnic/rte_eth_softnic_cli.c
@@ -4095,24 +4095,18 @@  parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
 
 		switch (xform[i]->type) {
 		case RTE_CRYPTO_SYM_XFORM_CIPHER:
-			if (xform[i]->cipher.key.data)
-				free(xform[i]->cipher.key.data);
 			if (p->cipher_auth.cipher_iv.val)
 				free(p->cipher_auth.cipher_iv.val);
 			if (p->cipher_auth.cipher_iv_update.val)
 				free(p->cipher_auth.cipher_iv_update.val);
 			break;
 		case RTE_CRYPTO_SYM_XFORM_AUTH:
-			if (xform[i]->auth.key.data)
-				free(xform[i]->cipher.key.data);
 			if (p->cipher_auth.auth_iv.val)
 				free(p->cipher_auth.cipher_iv.val);
 			if (p->cipher_auth.auth_iv_update.val)
 				free(p->cipher_auth.cipher_iv_update.val);
 			break;
 		case RTE_CRYPTO_SYM_XFORM_AEAD:
-			if (xform[i]->aead.key.data)
-				free(xform[i]->cipher.key.data);
 			if (p->aead.iv.val)
 				free(p->aead.iv.val);
 			if (p->aead.aad.val)
@@ -4127,8 +4121,8 @@  parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
 
 static struct rte_crypto_sym_xform *
 parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
-		char **tokens, uint32_t n_tokens, uint32_t encrypt,
-		uint32_t *used_n_tokens)
+		uint8_t *key, uint32_t max_key_len, char **tokens,
+		uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
 {
 	struct rte_crypto_sym_xform *xform_cipher;
 	int status;
@@ -4155,16 +4149,16 @@  parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
 
 	/* cipher_key */
 	len = strlen(tokens[4]);
-	xform_cipher->cipher.key.data = calloc(1, len / 2 + 1);
-	if (xform_cipher->cipher.key.data == NULL)
+	if (len / 2 > max_key_len) {
+		status = -ENOMEM;
 		goto error_exit;
+	}
 
-	status = softnic_parse_hex_string(tokens[4],
-			xform_cipher->cipher.key.data,
-			(uint32_t *)&len);
+	status = softnic_parse_hex_string(tokens[4], key, (uint32_t *)&len);
 	if (status < 0)
 		goto error_exit;
 
+	xform_cipher->cipher.key.data = key;
 	xform_cipher->cipher.key.length = (uint16_t)len;
 
 	/* cipher_iv */
@@ -4188,9 +4182,6 @@  parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
 	return xform_cipher;
 
 error_exit:
-	if (xform_cipher->cipher.key.data)
-		free(xform_cipher->cipher.key.data);
-
 	if (p->cipher_auth.cipher_iv.val) {
 		free(p->cipher_auth.cipher_iv.val);
 		p->cipher_auth.cipher_iv.val = NULL;
@@ -4203,8 +4194,8 @@  parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
 
 static struct rte_crypto_sym_xform *
 parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
-		char **tokens, uint32_t n_tokens, uint32_t encrypt,
-		uint32_t *used_n_tokens)
+		uint8_t *key, uint32_t max_key_len, char **tokens,
+		uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
 {
 	struct rte_crypto_sym_xform *xform_cipher;
 	struct rte_crypto_sym_xform *xform_auth;
@@ -4233,17 +4224,21 @@  parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
 
 	/* auth_key */
 	len = strlen(tokens[10]);
-	xform_auth->auth.key.data = calloc(1, len / 2 + 1);
-	if (xform_auth->auth.key.data == NULL)
+	if (len / 2 > max_key_len) {
+		status = -ENOMEM;
 		goto error_exit;
+	}
 
-	status = softnic_parse_hex_string(tokens[10],
-			xform_auth->auth.key.data, (uint32_t *)&len);
+	status = softnic_parse_hex_string(tokens[10], key, (uint32_t *)&len);
 	if (status < 0)
 		goto error_exit;
 
+	xform_auth->auth.key.data = key;
 	xform_auth->auth.key.length = (uint16_t)len;
 
+	key += xform_auth->auth.key.length;
+	max_key_len -= xform_auth->auth.key.length;
+
 	if (strcmp(tokens[11], "digest_size"))
 		goto error_exit;
 
@@ -4252,8 +4247,8 @@  parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
 	if (status < 0)
 		goto error_exit;
 
-	xform_cipher = parse_table_action_cipher(p, tokens, 7, encrypt,
-			used_n_tokens);
+	xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens, 7,
+			encrypt, used_n_tokens);
 	if (xform_cipher == NULL)
 		goto error_exit;
 
@@ -4268,8 +4263,6 @@  parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
 	}
 
 error_exit:
-	if (xform_auth->auth.key.data)
-		free(xform_auth->auth.key.data);
 	if (p->cipher_auth.auth_iv.val) {
 		free(p->cipher_auth.auth_iv.val);
 		p->cipher_auth.auth_iv.val = 0;
@@ -4282,8 +4275,8 @@  parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
 
 static struct rte_crypto_sym_xform *
 parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
-		char **tokens, uint32_t n_tokens, uint32_t encrypt,
-		uint32_t *used_n_tokens)
+		uint8_t *key, uint32_t max_key_len, char **tokens,
+		uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
 {
 	struct rte_crypto_sym_xform *xform_aead;
 	int status;
@@ -4312,15 +4305,16 @@  parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
 
 	/* aead_key */
 	len = strlen(tokens[4]);
-	xform_aead->aead.key.data = calloc(1, len / 2 + 1);
-	if (xform_aead->aead.key.data == NULL)
+	if (len / 2 > max_key_len) {
+		status = -ENOMEM;
 		goto error_exit;
+	}
 
-	status = softnic_parse_hex_string(tokens[4], xform_aead->aead.key.data,
-			(uint32_t *)&len);
+	status = softnic_parse_hex_string(tokens[4], key, (uint32_t *)&len);
 	if (status < 0)
 		goto error_exit;
 
+	xform_aead->aead.key.data = key;
 	xform_aead->aead.key.length = (uint16_t)len;
 
 	/* aead_iv */
@@ -4362,8 +4356,6 @@  parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
 	return xform_aead;
 
 error_exit:
-	if (xform_aead->aead.key.data)
-		free(xform_aead->aead.key.data);
 	if (p->aead.iv.val) {
 		free(p->aead.iv.val);
 		p->aead.iv.val = NULL;
@@ -4386,6 +4378,8 @@  parse_table_action_sym_crypto(char **tokens,
 {
 	struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
 	struct rte_crypto_sym_xform *xform = NULL;
+	uint8_t *key = a->sym_crypto_key;
+	uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
 	uint32_t used_n_tokens;
 	uint32_t encrypt;
 	int status;
@@ -4410,20 +4404,20 @@  parse_table_action_sym_crypto(char **tokens,
 		tokens += 3;
 		n_tokens -= 3;
 
-		xform = parse_table_action_cipher(p, tokens, n_tokens, encrypt,
-				&used_n_tokens);
+		xform = parse_table_action_cipher(p, key, max_key_len, tokens,
+				n_tokens, encrypt, &used_n_tokens);
 	} else if (strcmp(tokens[3], "cipher_auth") == 0) {
 		tokens += 3;
 		n_tokens -= 3;
 
-		xform = parse_table_action_cipher_auth(p, tokens, n_tokens,
-				encrypt, &used_n_tokens);
+		xform = parse_table_action_cipher_auth(p, key, max_key_len,
+				tokens, n_tokens, encrypt, &used_n_tokens);
 	} else if (strcmp(tokens[3], "aead") == 0) {
 		tokens += 3;
 		n_tokens -= 3;
 
-		xform = parse_table_action_aead(p, tokens, n_tokens, encrypt,
-				&used_n_tokens);
+		xform = parse_table_action_aead(p, key, max_key_len, tokens,
+				n_tokens, encrypt, &used_n_tokens);
 	}
 
 	if (xform == NULL)
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 415434d0d..08bc66051 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -948,6 +948,9 @@  struct softnic_table_rule_match {
 	} match;
 };
 
+#ifndef SYM_CRYPTO_MAX_KEY_SIZE
+#define SYM_CRYPTO_MAX_KEY_SIZE		(256)
+#endif
 struct softnic_table_rule_action {
 	uint64_t action_mask;
 	struct rte_table_action_fwd_params fwd;
@@ -962,6 +965,7 @@  struct softnic_table_rule_action {
 	struct rte_table_action_tag_params tag;
 	struct rte_table_action_decap_params decap;
 	struct rte_table_action_sym_crypto_params sym_crypto;
+	uint8_t sym_crypto_key[SYM_CRYPTO_MAX_KEY_SIZE];
 };
 
 struct rte_flow {
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 309b2936e..770b3bcd4 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -3772,24 +3772,18 @@  parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
 
 		switch (xform[i]->type) {
 		case RTE_CRYPTO_SYM_XFORM_CIPHER:
-			if (xform[i]->cipher.key.data)
-				free(xform[i]->cipher.key.data);
 			if (p->cipher_auth.cipher_iv.val)
 				free(p->cipher_auth.cipher_iv.val);
 			if (p->cipher_auth.cipher_iv_update.val)
 				free(p->cipher_auth.cipher_iv_update.val);
 			break;
 		case RTE_CRYPTO_SYM_XFORM_AUTH:
-			if (xform[i]->auth.key.data)
-				free(xform[i]->cipher.key.data);
 			if (p->cipher_auth.auth_iv.val)
 				free(p->cipher_auth.cipher_iv.val);
 			if (p->cipher_auth.auth_iv_update.val)
 				free(p->cipher_auth.cipher_iv_update.val);
 			break;
 		case RTE_CRYPTO_SYM_XFORM_AEAD:
-			if (xform[i]->aead.key.data)
-				free(xform[i]->cipher.key.data);
 			if (p->aead.iv.val)
 				free(p->aead.iv.val);
 			if (p->aead.aad.val)
@@ -3804,8 +3798,8 @@  parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
 
 static struct rte_crypto_sym_xform *
 parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
-		char **tokens, uint32_t n_tokens, uint32_t encrypt,
-		uint32_t *used_n_tokens)
+		uint8_t *key, uint32_t max_key_len, char **tokens,
+		uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
 {
 	struct rte_crypto_sym_xform *xform_cipher;
 	int status;
@@ -3832,16 +3826,16 @@  parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
 
 	/* cipher_key */
 	len = strlen(tokens[4]);
-	xform_cipher->cipher.key.data = calloc(1, len / 2 + 1);
-	if (xform_cipher->cipher.key.data == NULL)
+	if (len / 2 > max_key_len) {
+		status = -ENOMEM;
 		goto error_exit;
+	}
 
-	status = parse_hex_string(tokens[4],
-			xform_cipher->cipher.key.data,
-			(uint32_t *)&len);
+	status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
 	if (status < 0)
 		goto error_exit;
 
+	xform_cipher->cipher.key.data = key;
 	xform_cipher->cipher.key.length = (uint16_t)len;
 
 	/* cipher_iv */
@@ -3865,9 +3859,6 @@  parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
 	return xform_cipher;
 
 error_exit:
-	if (xform_cipher->cipher.key.data)
-		free(xform_cipher->cipher.key.data);
-
 	if (p->cipher_auth.cipher_iv.val) {
 		free(p->cipher_auth.cipher_iv.val);
 		p->cipher_auth.cipher_iv.val = NULL;
@@ -3880,8 +3871,8 @@  parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
 
 static struct rte_crypto_sym_xform *
 parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
-		char **tokens, uint32_t n_tokens, uint32_t encrypt,
-		uint32_t *used_n_tokens)
+		uint8_t *key, uint32_t max_key_len, char **tokens,
+		uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
 {
 	struct rte_crypto_sym_xform *xform_cipher;
 	struct rte_crypto_sym_xform *xform_auth;
@@ -3910,17 +3901,21 @@  parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
 
 	/* auth_key */
 	len = strlen(tokens[10]);
-	xform_auth->auth.key.data = calloc(1, len / 2 + 1);
-	if (xform_auth->auth.key.data == NULL)
+	if (len / 2 > max_key_len) {
+		status = -ENOMEM;
 		goto error_exit;
+	}
 
-	status = parse_hex_string(tokens[10],
-			xform_auth->auth.key.data, (uint32_t *)&len);
+	status = parse_hex_string(tokens[10], key, (uint32_t *)&len);
 	if (status < 0)
 		goto error_exit;
 
+	xform_auth->auth.key.data = key;
 	xform_auth->auth.key.length = (uint16_t)len;
 
+	key += xform_auth->auth.key.length;
+	max_key_len -= xform_auth->auth.key.length;
+
 	if (strcmp(tokens[11], "digest_size"))
 		goto error_exit;
 
@@ -3929,8 +3924,8 @@  parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
 	if (status < 0)
 		goto error_exit;
 
-	xform_cipher = parse_table_action_cipher(p, tokens, 7, encrypt,
-			used_n_tokens);
+	xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens,
+			7, encrypt, used_n_tokens);
 	if (xform_cipher == NULL)
 		goto error_exit;
 
@@ -3945,8 +3940,6 @@  parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
 	}
 
 error_exit:
-	if (xform_auth->auth.key.data)
-		free(xform_auth->auth.key.data);
 	if (p->cipher_auth.auth_iv.val) {
 		free(p->cipher_auth.auth_iv.val);
 		p->cipher_auth.auth_iv.val = 0;
@@ -3959,8 +3952,8 @@  parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
 
 static struct rte_crypto_sym_xform *
 parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
-		char **tokens, uint32_t n_tokens, uint32_t encrypt,
-		uint32_t *used_n_tokens)
+		uint8_t *key, uint32_t max_key_len, char **tokens,
+		uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
 {
 	struct rte_crypto_sym_xform *xform_aead;
 	int status;
@@ -3989,15 +3982,16 @@  parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
 
 	/* aead_key */
 	len = strlen(tokens[4]);
-	xform_aead->aead.key.data = calloc(1, len / 2 + 1);
-	if (xform_aead->aead.key.data == NULL)
+	if (len / 2 > max_key_len) {
+		status = -ENOMEM;
 		goto error_exit;
+	}
 
-	status = parse_hex_string(tokens[4], xform_aead->aead.key.data,
-			(uint32_t *)&len);
+	status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
 	if (status < 0)
 		goto error_exit;
 
+	xform_aead->aead.key.data = key;
 	xform_aead->aead.key.length = (uint16_t)len;
 
 	/* aead_iv */
@@ -4039,8 +4033,6 @@  parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
 	return xform_aead;
 
 error_exit:
-	if (xform_aead->aead.key.data)
-		free(xform_aead->aead.key.data);
 	if (p->aead.iv.val) {
 		free(p->aead.iv.val);
 		p->aead.iv.val = NULL;
@@ -4063,6 +4055,8 @@  parse_table_action_sym_crypto(char **tokens,
 {
 	struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
 	struct rte_crypto_sym_xform *xform = NULL;
+	uint8_t *key = a->sym_crypto_key;
+	uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
 	uint32_t used_n_tokens;
 	uint32_t encrypt;
 	int status;
@@ -4087,20 +4081,20 @@  parse_table_action_sym_crypto(char **tokens,
 		tokens += 3;
 		n_tokens -= 3;
 
-		xform = parse_table_action_cipher(p, tokens, n_tokens, encrypt,
-				&used_n_tokens);
+		xform = parse_table_action_cipher(p, key, max_key_len, tokens,
+				n_tokens, encrypt, &used_n_tokens);
 	} else if (strcmp(tokens[3], "cipher_auth") == 0) {
 		tokens += 3;
 		n_tokens -= 3;
 
-		xform = parse_table_action_cipher_auth(p, tokens, n_tokens,
-				encrypt, &used_n_tokens);
+		xform = parse_table_action_cipher_auth(p, key, max_key_len,
+				tokens, n_tokens, encrypt, &used_n_tokens);
 	} else if (strcmp(tokens[3], "aead") == 0) {
 		tokens += 3;
 		n_tokens -= 3;
 
-		xform = parse_table_action_aead(p, tokens, n_tokens, encrypt,
-				&used_n_tokens);
+		xform = parse_table_action_aead(p, key, max_key_len, tokens,
+				n_tokens, encrypt, &used_n_tokens);
 	}
 
 	if (xform == NULL)
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
index ac1e38d6a..94a0462d0 100644
--- a/examples/ip_pipeline/cryptodev.c
+++ b/examples/ip_pipeline/cryptodev.c
@@ -90,8 +90,6 @@  cryptodev_create(const char *name, struct cryptodev_params *params)
 
 	if (dev_info.max_nb_queue_pairs < params->n_queues)
 		return NULL;
-	if (dev_info.feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)
-		return NULL;
 
 	dev_conf.socket_id = socket_id;
 	dev_conf.nb_queue_pairs = params->n_queues;
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 278775c2d..4d2ee29a5 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -276,6 +276,10 @@  struct table_rule_match {
 	} match;
 };
 
+#ifndef SYM_CRYPTO_MAX_KEY_SIZE
+#define SYM_CRYPTO_MAX_KEY_SIZE                (256)
+#endif
+
 struct table_rule_action {
 	uint64_t action_mask;
 	struct rte_table_action_fwd_params fwd;
@@ -288,8 +292,10 @@  struct table_rule_action {
 	struct rte_table_action_stats_params stats;
 	struct rte_table_action_time_params time;
 	struct rte_table_action_sym_crypto_params sym_crypto;
+	uint8_t sym_crypto_key[SYM_CRYPTO_MAX_KEY_SIZE];
 	struct rte_table_action_tag_params tag;
 	struct rte_table_action_decap_params decap;
+
 };
 
 struct table_rule {
diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index e282cb7bf..09cd4c9a2 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -136,6 +136,7 @@  struct l2fwd_crypto_options {
 	struct rte_crypto_sym_xform cipher_xform;
 	unsigned ckey_param;
 	int ckey_random_size;
+	uint8_t cipher_key[MAX_KEY_SIZE];
 
 	struct l2fwd_iv cipher_iv;
 	unsigned int cipher_iv_param;
@@ -144,6 +145,7 @@  struct l2fwd_crypto_options {
 	struct rte_crypto_sym_xform auth_xform;
 	uint8_t akey_param;
 	int akey_random_size;
+	uint8_t auth_key[MAX_KEY_SIZE];
 
 	struct l2fwd_iv auth_iv;
 	unsigned int auth_iv_param;
@@ -152,6 +154,7 @@  struct l2fwd_crypto_options {
 	struct rte_crypto_sym_xform aead_xform;
 	unsigned int aead_key_param;
 	int aead_key_random_size;
+	uint8_t aead_key[MAX_KEY_SIZE];
 
 	struct l2fwd_iv aead_iv;
 	unsigned int aead_iv_param;
@@ -1219,8 +1222,7 @@  l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options,
 	else if (strcmp(lgopts[option_index].name, "cipher_key") == 0) {
 		options->ckey_param = 1;
 		options->cipher_xform.cipher.key.length =
-			parse_bytes(options->cipher_xform.cipher.key.data, optarg,
-					MAX_KEY_SIZE);
+			parse_bytes(options->cipher_key, optarg, MAX_KEY_SIZE);
 		if (options->cipher_xform.cipher.key.length > 0)
 			return 0;
 		else
@@ -1256,8 +1258,7 @@  l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options,
 	else if (strcmp(lgopts[option_index].name, "auth_key") == 0) {
 		options->akey_param = 1;
 		options->auth_xform.auth.key.length =
-			parse_bytes(options->auth_xform.auth.key.data, optarg,
-					MAX_KEY_SIZE);
+			parse_bytes(options->auth_key, optarg, MAX_KEY_SIZE);
 		if (options->auth_xform.auth.key.length > 0)
 			return 0;
 		else
@@ -1294,8 +1295,7 @@  l2fwd_crypto_parse_args_long_options(struct l2fwd_crypto_options *options,
 	else if (strcmp(lgopts[option_index].name, "aead_key") == 0) {
 		options->aead_key_param = 1;
 		options->aead_xform.aead.key.length =
-			parse_bytes(options->aead_xform.aead.key.data, optarg,
-					MAX_KEY_SIZE);
+			parse_bytes(options->aead_key, optarg, MAX_KEY_SIZE);
 		if (options->aead_xform.aead.key.length > 0)
 			return 0;
 		else
@@ -2348,8 +2348,7 @@  initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
 					options->aead_xform.aead.key.length =
 						cap->sym.aead.key_size.min;
 
-				generate_random_key(
-					options->aead_xform.aead.key.data,
+				generate_random_key(options->aead_key,
 					options->aead_xform.aead.key.length);
 			}
 
@@ -2406,8 +2405,7 @@  initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
 					options->cipher_xform.cipher.key.length =
 						cap->sym.cipher.key_size.min;
 
-				generate_random_key(
-					options->cipher_xform.cipher.key.data,
+				generate_random_key(options->cipher_key,
 					options->cipher_xform.cipher.key.length);
 			}
 		}
@@ -2440,8 +2438,7 @@  initialize_cryptodevs(struct l2fwd_crypto_options *options, unsigned nb_ports,
 					options->auth_xform.auth.key.length =
 						cap->sym.auth.key_size.min;
 
-				generate_random_key(
-					options->auth_xform.auth.key.data,
+				generate_random_key(options->auth_key,
 					options->auth_xform.auth.key.length);
 			}
 
@@ -2612,20 +2609,11 @@  initialize_ports(struct l2fwd_crypto_options *options)
 static void
 reserve_key_memory(struct l2fwd_crypto_options *options)
 {
-	options->cipher_xform.cipher.key.data = rte_malloc("crypto key",
-						MAX_KEY_SIZE, 0);
-	if (options->cipher_xform.cipher.key.data == NULL)
-		rte_exit(EXIT_FAILURE, "Failed to allocate memory for cipher key");
-
-	options->auth_xform.auth.key.data = rte_malloc("auth key",
-						MAX_KEY_SIZE, 0);
-	if (options->auth_xform.auth.key.data == NULL)
-		rte_exit(EXIT_FAILURE, "Failed to allocate memory for auth key");
-
-	options->aead_xform.aead.key.data = rte_malloc("aead key",
-						MAX_KEY_SIZE, 0);
-	if (options->aead_xform.aead.key.data == NULL)
-		rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD key");
+	options->cipher_xform.cipher.key.data = options->cipher_key;
+
+	options->auth_xform.auth.key.data = options->auth_key;
+
+	options->aead_xform.aead.key.data = options->aead_key;
 
 	options->cipher_iv.data = rte_malloc("cipher iv", MAX_KEY_SIZE, 0);
 	if (options->cipher_iv.data == NULL)
diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
index c20e090a8..55d352a23 100644
--- a/lib/librte_cryptodev/Makefile
+++ b/lib/librte_cryptodev/Makefile
@@ -7,7 +7,7 @@  include $(RTE_SDK)/mk/rte.vars.mk
 LIB = librte_cryptodev.a
 
 # library version
-LIBABIVER := 7
+LIBABIVER := 8
 
 # build flags
 CFLAGS += -O3
diff --git a/lib/librte_cryptodev/meson.build b/lib/librte_cryptodev/meson.build
index 9e009d466..0a2275d75 100644
--- a/lib/librte_cryptodev/meson.build
+++ b/lib/librte_cryptodev/meson.build
@@ -1,7 +1,7 @@ 
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2017-2019 Intel Corporation
 
-version = 7
+version = 8
 allow_experimental_apis = true
 sources = files('rte_cryptodev.c', 'rte_cryptodev_pmd.c')
 headers = files('rte_cryptodev.h',
diff --git a/lib/librte_cryptodev/rte_crypto_sym.h b/lib/librte_cryptodev/rte_crypto_sym.h
index bfce84a35..4a6adbeef 100644
--- a/lib/librte_cryptodev/rte_crypto_sym.h
+++ b/lib/librte_cryptodev/rte_crypto_sym.h
@@ -114,8 +114,8 @@  struct rte_crypto_cipher_xform {
 	/**< Cipher algorithm */
 
 	struct {
-		uint8_t *data;	/**< pointer to key data */
-		uint16_t length;/**< key length in bytes */
+		const uint8_t *data;	/**< pointer to key data */
+		uint16_t length;	/**< key length in bytes */
 	} key;
 	/**< Cipher key
 	 *
@@ -282,8 +282,8 @@  struct rte_crypto_auth_xform {
 	/**< Authentication algorithm selection */
 
 	struct {
-		uint8_t *data;	/**< pointer to key data */
-		uint16_t length;/**< key length in bytes */
+		const uint8_t *data;	/**< pointer to key data */
+		uint16_t length;	/**< key length in bytes */
 	} key;
 	/**< Authentication key data.
 	 * The authentication key length MUST be less than or equal to the
@@ -374,8 +374,8 @@  struct rte_crypto_aead_xform {
 	/**< AEAD algorithm selection */
 
 	struct {
-		uint8_t *data;  /**< pointer to key data */
-		uint16_t length;/**< key length in bytes */
+		const uint8_t *data;	/**< pointer to key data */
+		uint16_t length;	/**< key length in bytes */
 	} key;
 
 	struct {