cryptodev: make xform key pointer constant

Message ID 20190301134325.30600-1-roy.fan.zhang@intel.com
State Superseded, archived
Delegated to: akhil goyal
Headers show
Series
  • cryptodev: make xform key pointer constant
Related show

Checks

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

Commit Message

Fan Zhang March 1, 2019, 1:43 p.m.
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>
---
Although it is a relative big patch, but I believe it is the
right thing to do towards a safer and better DPDK Cryptodev,
and we should have done this long time ago.

I have been trying to avoid the problems that may cause due
to the bug/missed updates places. However, due to lacking the
hardware I was only able to test the PMDs I have. So
please forgive me if I missed updating certain drivers/tests. I
will amend that.

 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                 | 33 ++++++++---
 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/rte_crypto_sym.h           | 12 ++--
 20 files changed, 189 insertions(+), 155 deletions(-)

Comments

Kusztal, ArkadiuszX March 15, 2019, 4:37 p.m. | #1
Hi Fan,

Only one thing from me (with [AK])
Except for that looks good, I can ack v2.

Arek
> -----Original Message-----
> From: Zhang, Roy Fan
> Sent: Friday, March 1, 2019 2:43 PM
> To: dev@dpdk.org
> Cc: akhil.goyal@nxp.com; Zhang, Roy Fan <roy.fan.zhang@intel.com>;
> Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>;
> jerin.jacob@caviumnetworks.com; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: [PATCH] cryptodev: make xform key pointer constant
> 
> 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>
> ---
> Although it is a relative big patch, but I believe it is the right thing to do
> towards a safer and better DPDK Cryptodev, and we should have done this
> long time ago.
> 
> I have been trying to avoid the problems that may cause due to the
> bug/missed updates places. However, due to lacking the hardware I was only
> able to test the PMDs I have. So please forgive me if I missed updating certain
> drivers/tests. I will amend that.
> 
>  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                 | 33 ++++++++---
>  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/rte_crypto_sym.h           | 12 ++--
>  20 files changed, 189 insertions(+), 155 deletions(-)
> 
> diff --git a/drivers/common/cpt/cpt_ucode.h
> b/drivers/common/cpt/cpt_ucode.h index 5933ea77e..3e1127174 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;
> @@ -2539,7 +2539,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 948ff0763..009885f08 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 48d6ac002..c0670fa40 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 ea5aac69e..f76d081e7 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 4d7ec01d4..917c5e927 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;
> @@ -496,7 +496,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;
> 
> @@ -1258,7 +1258,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; @@ -1413,7 +1413,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..018722100 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,16 +237,22
> @@ 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);
[AK] - This key is not freed after this malloc.
> +		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;
> @@ -388,6 +404,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 76136c2e2..f4df3dc96 100644
> --- a/drivers/net/softnic/rte_eth_softnic_cli.c
> +++ b/drivers/net/softnic/rte_eth_softnic_cli.c
> @@ -4053,24 +4053,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)
> @@ -4085,8 +4079,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;
> @@ -4113,16 +4107,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 */
> @@ -4146,9 +4140,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;
> @@ -4161,8 +4152,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; @@ -4191,17 +4182,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;
> 
> @@ -4210,8 +4205,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;
> 
> @@ -4226,8 +4221,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;
> @@ -4240,8 +4233,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;
> @@ -4270,15 +4263,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 */
> @@ -4320,8 +4314,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;
> @@ -4344,6 +4336,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;
> @@ -4368,20 +4362,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
> a92467e63..6d547efd6 100644
> --- a/examples/ip_pipeline/cli.c
> +++ b/examples/ip_pipeline/cli.c
> @@ -3730,24 +3730,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)
> @@ -3762,8 +3756,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;
> @@ -3790,16 +3784,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 */
> @@ -3823,9 +3817,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;
> @@ -3838,8 +3829,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; @@ -3868,17 +3859,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;
> 
> @@ -3887,8 +3882,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;
> 
> @@ -3903,8 +3898,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;
> @@ -3917,8 +3910,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;
> @@ -3947,15 +3940,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 */
> @@ -3997,8 +3991,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;
> @@ -4021,6 +4013,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;
> @@ -4045,20 +4039,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 9982f07e9..aa8b92e2c 100644
> --- a/examples/l2fwd-crypto/main.c
> +++ b/examples/l2fwd-crypto/main.c
> @@ -135,6 +135,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;
> @@ -143,6 +144,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;
> @@ -151,6 +153,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 859c4f0f1..c20e090a8 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 := 6
> +LIBABIVER := 7
> 
>  # build flags
>  CFLAGS += -O3
> diff --git a/lib/librte_cryptodev/rte_crypto_sym.h
> b/lib/librte_cryptodev/rte_crypto_sym.h
> index eb5afc5ef..00e1b358f 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
>  	 *
> @@ -293,8 +293,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
> @@ -376,8 +376,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 {
> --
> 2.14.5

Patch

diff --git a/drivers/common/cpt/cpt_ucode.h b/drivers/common/cpt/cpt_ucode.h
index 5933ea77e..3e1127174 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;
@@ -2539,7 +2539,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 948ff0763..009885f08 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 48d6ac002..c0670fa40 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 ea5aac69e..f76d081e7 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 4d7ec01d4..917c5e927 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;
@@ -496,7 +496,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;
 
@@ -1258,7 +1258,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;
@@ -1413,7 +1413,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..018722100 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,16 +237,22 @@  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;
@@ -388,6 +404,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 76136c2e2..f4df3dc96 100644
--- a/drivers/net/softnic/rte_eth_softnic_cli.c
+++ b/drivers/net/softnic/rte_eth_softnic_cli.c
@@ -4053,24 +4053,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)
@@ -4085,8 +4079,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;
@@ -4113,16 +4107,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 */
@@ -4146,9 +4140,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;
@@ -4161,8 +4152,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;
@@ -4191,17 +4182,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;
 
@@ -4210,8 +4205,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;
 
@@ -4226,8 +4221,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;
@@ -4240,8 +4233,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;
@@ -4270,15 +4263,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 */
@@ -4320,8 +4314,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;
@@ -4344,6 +4336,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;
@@ -4368,20 +4362,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 a92467e63..6d547efd6 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -3730,24 +3730,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)
@@ -3762,8 +3756,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;
@@ -3790,16 +3784,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 */
@@ -3823,9 +3817,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;
@@ -3838,8 +3829,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;
@@ -3868,17 +3859,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;
 
@@ -3887,8 +3882,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;
 
@@ -3903,8 +3898,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;
@@ -3917,8 +3910,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;
@@ -3947,15 +3940,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 */
@@ -3997,8 +3991,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;
@@ -4021,6 +4013,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;
@@ -4045,20 +4039,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 9982f07e9..aa8b92e2c 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -135,6 +135,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;
@@ -143,6 +144,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;
@@ -151,6 +153,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 859c4f0f1..c20e090a8 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 := 6
+LIBABIVER := 7
 
 # build flags
 CFLAGS += -O3
diff --git a/lib/librte_cryptodev/rte_crypto_sym.h b/lib/librte_cryptodev/rte_crypto_sym.h
index eb5afc5ef..00e1b358f 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
 	 *
@@ -293,8 +293,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
@@ -376,8 +376,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 {