[v8,03/16] crypto/mlx5: add session operations

Message ID 20210715164126.54073-4-shirik@nvidia.com (mailing list archive)
State Changes Requested, archived
Delegated to: akhil goyal
Headers
Series drivers: introduce mlx5 crypto PMD |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Shiri Kuzin July 15, 2021, 4:41 p.m. UTC
  Sessions are used in symmetric transformations in order to prepare
objects and data for packet processing stage.

A mlx5 session includes iv_offset, pointer to mlx5_crypto_dek struct,
bsf_size, bsf_p_type, block size index, encryption_order and encryption
standard.

Implement the next session operations:
        mlx5_crypto_sym_session_get_size- returns the size of the mlx5
	session struct.
	mlx5_crypto_sym_session_configure- prepares the DEK hash-list
	and saves all the session data.
	mlx5_crypto_sym_session_clear - destroys the DEK hash-list.

Signed-off-by: Shiri Kuzin <shirik@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 doc/guides/cryptodevs/features/mlx5.ini |   5 +
 doc/guides/cryptodevs/mlx5.rst          |  10 ++
 drivers/crypto/mlx5/mlx5_crypto.c       | 172 +++++++++++++++++++++++-
 3 files changed, 182 insertions(+), 5 deletions(-)
  

Comments

Akhil Goyal July 16, 2021, 7:40 p.m. UTC | #1
> Sessions are used in symmetric transformations in order to prepare
> objects and data for packet processing stage.
> 
> A mlx5 session includes iv_offset, pointer to mlx5_crypto_dek struct,
> bsf_size, bsf_p_type, block size index, encryption_order and encryption
> standard.
> 
> Implement the next session operations:
>         mlx5_crypto_sym_session_get_size- returns the size of the mlx5
> 	session struct.
> 	mlx5_crypto_sym_session_configure- prepares the DEK hash-list
> 	and saves all the session data.
> 	mlx5_crypto_sym_session_clear - destroys the DEK hash-list.
> 
> Signed-off-by: Shiri Kuzin <shirik@nvidia.com>
> Acked-by: Matan Azrad <matan@nvidia.com>
> ---
>  doc/guides/cryptodevs/features/mlx5.ini |   5 +
>  doc/guides/cryptodevs/mlx5.rst          |  10 ++
>  drivers/crypto/mlx5/mlx5_crypto.c       | 172 +++++++++++++++++++++++-
>  3 files changed, 182 insertions(+), 5 deletions(-)
> 
> diff --git a/doc/guides/cryptodevs/features/mlx5.ini
> b/doc/guides/cryptodevs/features/mlx5.ini
> index ceadd967b6..bd757b5211 100644
> --- a/doc/guides/cryptodevs/features/mlx5.ini
> +++ b/doc/guides/cryptodevs/features/mlx5.ini
> @@ -4,12 +4,17 @@
>  ; Refer to default.ini for the full list of available PMD features.
>  ;
>  [Features]
> +Symmetric crypto       = Y
>  HW Accelerated         = Y
> +Cipher multiple data units = Y
> +Cipher wrapped key     = Y
> 
>  ;
>  ; Supported crypto algorithms of a mlx5 crypto driver.
>  ;
>  [Cipher]
> +AES XTS (128)  = Y
> +AES XTS (256)  = Y
> 
>  ;
>  ; Supported authentication algorithms of a mlx5 crypto driver.
> diff --git a/doc/guides/cryptodevs/mlx5.rst
> b/doc/guides/cryptodevs/mlx5.rst
> index 05a0a449e2..dd1d1a615d 100644
> --- a/doc/guides/cryptodevs/mlx5.rst
> +++ b/doc/guides/cryptodevs/mlx5.rst
> @@ -53,6 +53,16 @@ Supported NICs
> 
>  * Mellanox\ |reg| ConnectX\ |reg|-6 200G MCX654106A-HCAT (2x200G)
> 
> +
> +Limitations
> +-----------
> +
> +- AES-XTS keys provided in xform must include keytag and should be
> wrappend.

wrapped

> +- The supported data-unit lengths are 512B and 1KB. In case the
> `dataunit_len`
> +  is not provided in the cipher xform, the OP length is limited to the above
> +  values and 1MB.
> +
> +
>  Prerequisites
>  -------------
> 
> diff --git a/drivers/crypto/mlx5/mlx5_crypto.c
> b/drivers/crypto/mlx5/mlx5_crypto.c
> index d2d82c7b15..3f0c97d081 100644
> --- a/drivers/crypto/mlx5/mlx5_crypto.c
> +++ b/drivers/crypto/mlx5/mlx5_crypto.c
> @@ -3,6 +3,7 @@
>   */
> 
>  #include <rte_malloc.h>
> +#include <rte_mempool.h>
>  #include <rte_errno.h>
>  #include <rte_log.h>
>  #include <rte_pci.h>
> @@ -20,7 +21,9 @@
>  #define MLX5_CRYPTO_LOG_NAME pmd.crypto.mlx5
> 
>  #define MLX5_CRYPTO_FEATURE_FLAGS \
> -	RTE_CRYPTODEV_FF_HW_ACCELERATED
> +	(RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
> RTE_CRYPTODEV_FF_HW_ACCELERATED | \
> +	 RTE_CRYPTODEV_FF_CIPHER_WRAPPED_KEY | \
> +	 RTE_CRYPTODEV_FF_CIPHER_MULTIPLE_DATA_UNITS)
> 
>  TAILQ_HEAD(mlx5_crypto_privs, mlx5_crypto_priv) mlx5_crypto_priv_list =
> 
> 	TAILQ_HEAD_INITIALIZER(mlx5_crypto_priv_list);
> @@ -30,6 +33,32 @@ int mlx5_crypto_logtype;
> 
>  uint8_t mlx5_crypto_driver_id;
> 
> +const struct rte_cryptodev_capabilities mlx5_crypto_caps[] = {
> +	{		/* AES XTS */
> +		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
> +		{.sym = {
> +			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
> +			{.cipher = {
> +				.algo = RTE_CRYPTO_CIPHER_AES_XTS,
> +				.block_size = 16,
> +				.key_size = {
> +					.min = 32,
> +					.max = 64,
> +					.increment = 32
> +				},
> +				.iv_size = {
> +					.min = 16,
> +					.max = 16,
> +					.increment = 0
> +				},
> +				.dataunit_set =
> +
> 	RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_512_BYTES |
> +
> 	RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_4096_BYTES,
> +			}, }
> +		}, }
> +	},
> +};
> +
>  static const char mlx5_crypto_drv_name[] =
> RTE_STR(MLX5_CRYPTO_DRIVER_NAME);
> 
>  static const struct rte_driver mlx5_drv = {
> @@ -39,6 +68,49 @@ static const struct rte_driver mlx5_drv = {
> 
>  static struct cryptodev_driver mlx5_cryptodev_driver;
> 
> +struct mlx5_crypto_session {
> +	uint32_t bs_bpt_eo_es;
> +	/*
> +	 * bsf_size, bsf_p_type, encryption_order and encryption standard,
> +	 * saved in big endian format.
> +	 */

Normally the comments are added before the variable. Or add
/**< for post comment.

> +	uint32_t bsp_res;
> +	/*
> +	 * crypto_block_size_pointer and reserved 24 bits saved in big endian
> +	 * format.
> +	 */
> +	uint32_t iv_offset:16;
> +	/* Starting point for Initialisation Vector. */
> +	struct mlx5_crypto_dek *dek; /* Pointer to dek struct. */
> +	uint32_t dek_id; /* DEK ID */
> +} __rte_packed;
> +
> +static void
> +mlx5_crypto_dev_infos_get(struct rte_cryptodev *dev,
> +			  struct rte_cryptodev_info *dev_info)
> +{
> +	RTE_SET_USED(dev);
> +	if (dev_info != NULL) {
> +		dev_info->driver_id = mlx5_crypto_driver_id;
> +		dev_info->feature_flags = MLX5_CRYPTO_FEATURE_FLAGS;
> +		dev_info->capabilities = mlx5_crypto_caps;
> +		dev_info->max_nb_queue_pairs = 0;
> +		dev_info->min_mbuf_headroom_req = 0;
> +		dev_info->min_mbuf_tailroom_req = 0;
> +		dev_info->sym.max_nb_sessions = 0;
> +		/*
> +		 * If 0, the device does not have any limitation in number of
> +		 * sessions that can be used.
> +		 */
> +	}
> +}
> +
> +static unsigned int
> +mlx5_crypto_sym_session_get_size(struct rte_cryptodev *dev
> __rte_unused)
> +{
> +	return sizeof(struct mlx5_crypto_session);
> +}
> +
>  static int
>  mlx5_crypto_dev_configure(struct rte_cryptodev *dev,
>  		struct rte_cryptodev_config *config __rte_unused)
> @@ -61,19 +133,109 @@ mlx5_crypto_dev_close(struct rte_cryptodev *dev)
>  	return 0;
>  }
> 
> +static int
> +mlx5_crypto_sym_session_configure(struct rte_cryptodev *dev,
> +				  struct rte_crypto_sym_xform *xform,
> +				  struct rte_cryptodev_sym_session *session,
> +				  struct rte_mempool *mp)
> +{
> +	struct mlx5_crypto_priv *priv = dev->data->dev_private;
> +	struct mlx5_crypto_session *sess_private_data;
> +	struct rte_crypto_cipher_xform *cipher;
> +	uint8_t encryption_order;
> +	int ret;
> +
> +	if (unlikely(xform->next != NULL)) {
> +		DRV_LOG(ERR, "Xform next is not supported.");
> +		return -ENOTSUP;
> +	}
> +	if (unlikely((xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) ||
> +		     (xform->cipher.algo != RTE_CRYPTO_CIPHER_AES_XTS))) {
> +		DRV_LOG(ERR, "Only AES-XTS algorithm is supported.");
> +		return -ENOTSUP;
> +	}
> +	ret = rte_mempool_get(mp, (void *)&sess_private_data);
> +	if (ret != 0) {
> +		DRV_LOG(ERR,
> +			"Failed to get session %p private data from
> mempool.",
> +			sess_private_data);
> +		return -ENOMEM;
> +	}
> +	cipher = &xform->cipher;
> +	sess_private_data->dek = mlx5_crypto_dek_prepare(priv, cipher);
> +	if (sess_private_data->dek == NULL) {
> +		rte_mempool_put(mp, sess_private_data);
> +		DRV_LOG(ERR, "Failed to prepare dek.");
> +		return -ENOMEM;
> +	}
> +	if (cipher->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
> +		encryption_order =
> MLX5_ENCRYPTION_ORDER_ENCRYPTED_RAW_MEMORY;
> +	else
> +		encryption_order =
> MLX5_ENCRYPTION_ORDER_ENCRYPTED_RAW_WIRE;
> +	sess_private_data->bs_bpt_eo_es = rte_cpu_to_be_32
> +			(MLX5_BSF_SIZE_64B << MLX5_BSF_SIZE_OFFSET |
> +			 MLX5_BSF_P_TYPE_CRYPTO <<
> MLX5_BSF_P_TYPE_OFFSET |
> +			 encryption_order <<
> MLX5_ENCRYPTION_ORDER_OFFSET |
> +			 MLX5_ENCRYPTION_STANDARD_AES_XTS);
> +	switch (xform->cipher.dataunit_len) {
> +	case 0:
> +		sess_private_data->bsp_res = 0;
> +		break;
> +	case 512:
> +		sess_private_data->bsp_res = rte_cpu_to_be_32
> +
> ((uint32_t)MLX5_BLOCK_SIZE_512B <<
> +					     MLX5_BLOCK_SIZE_OFFSET);
> +		break;
> +	case 4096:
> +		sess_private_data->bsp_res = rte_cpu_to_be_32
> +
> ((uint32_t)MLX5_BLOCK_SIZE_4096B <<
> +					     MLX5_BLOCK_SIZE_OFFSET);
> +		break;
> +	default:
> +		DRV_LOG(ERR, "Cipher data unit length is not supported.");
> +		return -ENOTSUP;
> +	}
> +	sess_private_data->iv_offset = cipher->iv.offset;
> +	sess_private_data->dek_id =
> +			rte_cpu_to_be_32(sess_private_data->dek->obj->id
> &
> +					 0xffffff);
> +	set_sym_session_private_data(session, dev->driver_id,
> +				     sess_private_data);
> +	DRV_LOG(DEBUG, "Session %p was configured.", sess_private_data);
> +	return 0;
> +}
> +
> +static void
> +mlx5_crypto_sym_session_clear(struct rte_cryptodev *dev,
> +			      struct rte_cryptodev_sym_session *sess)
> +{
> +	struct mlx5_crypto_priv *priv = dev->data->dev_private;
> +	struct mlx5_crypto_session *spriv =
> get_sym_session_private_data(sess,
> +								dev-
> >driver_id);
> +
> +	if (unlikely(spriv == NULL)) {
> +		DRV_LOG(ERR, "Failed to get session %p private data.",
> spriv);
> +		return;
> +	}
> +	mlx5_crypto_dek_destroy(priv, spriv->dek);
> +	set_sym_session_private_data(sess, dev->driver_id, NULL);
> +	rte_mempool_put(rte_mempool_from_obj(spriv), spriv);
> +	DRV_LOG(DEBUG, "Session %p was cleared.", spriv);
> +}
> +
>  static struct rte_cryptodev_ops mlx5_crypto_ops = {
>  	.dev_configure			= mlx5_crypto_dev_configure,
>  	.dev_start			= NULL,
>  	.dev_stop			= NULL,
>  	.dev_close			= mlx5_crypto_dev_close,
> -	.dev_infos_get			= NULL,
> +	.dev_infos_get			= mlx5_crypto_dev_infos_get,
>  	.stats_get			= NULL,
>  	.stats_reset			= NULL,
>  	.queue_pair_setup		= NULL,
>  	.queue_pair_release		= NULL,
> -	.sym_session_get_size		= NULL,
> -	.sym_session_configure		= NULL,
> -	.sym_session_clear		= NULL,
> +	.sym_session_get_size		= mlx5_crypto_sym_session_get_size,
> +	.sym_session_configure		=
> mlx5_crypto_sym_session_configure,
> +	.sym_session_clear		= mlx5_crypto_sym_session_clear,
>  	.sym_get_raw_dp_ctx_size	= NULL,
>  	.sym_configure_raw_dp_ctx	= NULL,
>  };
> --
> 2.27.0
  
Akhil Goyal July 16, 2021, 7:43 p.m. UTC | #2
> Sessions are used in symmetric transformations in order to prepare
> objects and data for packet processing stage.
> 
> A mlx5 session includes iv_offset, pointer to mlx5_crypto_dek struct,
> bsf_size, bsf_p_type, block size index, encryption_order and encryption
> standard.
> 
> Implement the next session operations:
>         mlx5_crypto_sym_session_get_size- returns the size of the mlx5
> 	session struct.
> 	mlx5_crypto_sym_session_configure- prepares the DEK hash-list
> 	and saves all the session data.
> 	mlx5_crypto_sym_session_clear - destroys the DEK hash-list.
> 
> Signed-off-by: Shiri Kuzin <shirik@nvidia.com>
> Acked-by: Matan Azrad <matan@nvidia.com>
> ---
>  doc/guides/cryptodevs/features/mlx5.ini |   5 +
>  doc/guides/cryptodevs/mlx5.rst          |  10 ++

Documentation update is done in 3/16 which means the feature is complete.
But basic operations and queue pair initialization is done later.
This is not good. Please move this patch after QP additions.
Please take reference of other drivers for sequence of patches.

>  drivers/crypto/mlx5/mlx5_crypto.c       | 172 +++++++++++++++++++++++-
>  3 files changed, 182 insertions(+), 5 deletions(-)
>
  
Suanming Mou July 20, 2021, 8:59 a.m. UTC | #3
> -----Original Message-----
> From: Akhil Goyal <gakhil@marvell.com>
> Sent: Saturday, July 17, 2021 3:40 AM
> To: Shiri Kuzin <shirik@nvidia.com>; dev@dpdk.org
> Cc: Matan Azrad <matan@nvidia.com>; Suanming Mou
> <suanmingm@nvidia.com>; david.marchand@redhat.com
> Subject: RE: [EXT] [PATCH v8 03/16] crypto/mlx5: add session operations
> >  doc/guides/cryptodevs/mlx5.rst          |  10 ++
> >  drivers/crypto/mlx5/mlx5_crypto.c       | 172 +++++++++++++++++++++++-
> >  3 files changed, 182 insertions(+), 5 deletions(-)
> >
> >  static const struct rte_driver mlx5_drv = { @@ -39,6 +68,49 @@ static
> > const struct rte_driver mlx5_drv = {
> >
> >  static struct cryptodev_driver mlx5_cryptodev_driver;
> >
> > +struct mlx5_crypto_session {
> > +	uint32_t bs_bpt_eo_es;
> > +	/*
> > +	 * bsf_size, bsf_p_type, encryption_order and encryption standard,
> > +	 * saved in big endian format.
> > +	 */
> 
> Normally the comments are added before the variable. Or add /**< for post
> comment.

Yes, you are right for the "normal" case, I think the main reason here is that all the mlx related PMDs are putting the comment after the variable, so in fact put the comments after the variable is the normal case for mlx PMDs.
Let's try to keep it in normal case to not make other mlx PMD familiar developers confusing.

> 
> > +	uint32_t bsp_res;
> > +	/*
> > +	 * crypto_block_size_pointer and reserved 24 bits saved in big endian
> > +	 * format.
> > +	 */
> > +	uint32_t iv_offset:16;
> > +	/* Starting point for Initialisation Vector. */
> > +	struct mlx5_crypto_dek *dek; /* Pointer to dek struct. */
> > +	uint32_t dek_id; /* DEK ID */
> > +} __rte_packed;
> > +
> > --
> > 2.27.0
  
Akhil Goyal July 20, 2021, 9:01 a.m. UTC | #4
> -----Original Message-----
> From: Suanming Mou <suanmingm@nvidia.com>
> Sent: Tuesday, July 20, 2021 2:29 PM
> To: Akhil Goyal <gakhil@marvell.com>; Shiri Kuzin <shirik@nvidia.com>;
> dev@dpdk.org
> Cc: Matan Azrad <matan@nvidia.com>; david.marchand@redhat.com
> Subject: RE: [EXT] [PATCH v8 03/16] crypto/mlx5: add session operations
> 
> 
> 
> > -----Original Message-----
> > From: Akhil Goyal <gakhil@marvell.com>
> > Sent: Saturday, July 17, 2021 3:40 AM
> > To: Shiri Kuzin <shirik@nvidia.com>; dev@dpdk.org
> > Cc: Matan Azrad <matan@nvidia.com>; Suanming Mou
> > <suanmingm@nvidia.com>; david.marchand@redhat.com
> > Subject: RE: [EXT] [PATCH v8 03/16] crypto/mlx5: add session operations
> > >  doc/guides/cryptodevs/mlx5.rst          |  10 ++
> > >  drivers/crypto/mlx5/mlx5_crypto.c       | 172 +++++++++++++++++++++++-
> > >  3 files changed, 182 insertions(+), 5 deletions(-)
> > >
> > >  static const struct rte_driver mlx5_drv = { @@ -39,6 +68,49 @@ static
> > > const struct rte_driver mlx5_drv = {
> > >
> > >  static struct cryptodev_driver mlx5_cryptodev_driver;
> > >
> > > +struct mlx5_crypto_session {
> > > +	uint32_t bs_bpt_eo_es;
> > > +	/*
> > > +	 * bsf_size, bsf_p_type, encryption_order and encryption standard,
> > > +	 * saved in big endian format.
> > > +	 */
> >
> > Normally the comments are added before the variable. Or add /**< for
> post
> > comment.
> 
> Yes, you are right for the "normal" case, I think the main reason here is that
> all the mlx related PMDs are putting the comment after the variable, so in
> fact put the comments after the variable is the normal case for mlx PMDs.
> Let's try to keep it in normal case to not make other mlx PMD familiar
> developers confusing.
> 
Please use "/**<" for post commenting.
  
Suanming Mou July 20, 2021, 9:07 a.m. UTC | #5
> -----Original Message-----
> From: Akhil Goyal <gakhil@marvell.com>
> Sent: Saturday, July 17, 2021 3:44 AM
> To: Shiri Kuzin <shirik@nvidia.com>; dev@dpdk.org
> Cc: Matan Azrad <matan@nvidia.com>; Suanming Mou
> <suanmingm@nvidia.com>; david.marchand@redhat.com
> Subject: RE: [EXT] [PATCH v8 03/16] crypto/mlx5: add session operations
> 
> > Sessions are used in symmetric transformations in order to prepare
> > objects and data for packet processing stage.
> >
> > A mlx5 session includes iv_offset, pointer to mlx5_crypto_dek struct,
> > bsf_size, bsf_p_type, block size index, encryption_order and
> > encryption standard.
> >
> > Implement the next session operations:
> >         mlx5_crypto_sym_session_get_size- returns the size of the mlx5
> > 	session struct.
> > 	mlx5_crypto_sym_session_configure- prepares the DEK hash-list
> > 	and saves all the session data.
> > 	mlx5_crypto_sym_session_clear - destroys the DEK hash-list.
> >
> > Signed-off-by: Shiri Kuzin <shirik@nvidia.com>
> > Acked-by: Matan Azrad <matan@nvidia.com>
> > ---
> >  doc/guides/cryptodevs/features/mlx5.ini |   5 +
> >  doc/guides/cryptodevs/mlx5.rst          |  10 ++
> 
> Documentation update is done in 3/16 which means the feature is complete.
> But basic operations and queue pair initialization is done later.
> This is not good. Please move this patch after QP additions.
> Please take reference of other drivers for sequence of patches.

I'm not sure what was discussed before for suitable documentation places, but as you suggested here and in other patches, can we be aligned to put all this documentation related pieces to the (13/16) final PMD patch?

> 
> >  drivers/crypto/mlx5/mlx5_crypto.c       | 172 +++++++++++++++++++++++-
> >  3 files changed, 182 insertions(+), 5 deletions(-)
> >
  
Akhil Goyal July 20, 2021, 9:43 a.m. UTC | #6
> > > Sessions are used in symmetric transformations in order to prepare
> > > objects and data for packet processing stage.
> > >
> > > A mlx5 session includes iv_offset, pointer to mlx5_crypto_dek struct,
> > > bsf_size, bsf_p_type, block size index, encryption_order and
> > > encryption standard.
> > >
> > > Implement the next session operations:
> > >         mlx5_crypto_sym_session_get_size- returns the size of the mlx5
> > > 	session struct.
> > > 	mlx5_crypto_sym_session_configure- prepares the DEK hash-list
> > > 	and saves all the session data.
> > > 	mlx5_crypto_sym_session_clear - destroys the DEK hash-list.
> > >
> > > Signed-off-by: Shiri Kuzin <shirik@nvidia.com>
> > > Acked-by: Matan Azrad <matan@nvidia.com>
> > > ---
> > >  doc/guides/cryptodevs/features/mlx5.ini |   5 +
> > >  doc/guides/cryptodevs/mlx5.rst          |  10 ++
> >
> > Documentation update is done in 3/16 which means the feature is
> complete.
> > But basic operations and queue pair initialization is done later.
> > This is not good. Please move this patch after QP additions.
> > Please take reference of other drivers for sequence of patches.
> 
> I'm not sure what was discussed before for suitable documentation places,
> but as you suggested here and in other patches, can we be aligned to put all
> this documentation related pieces to the (13/16) final PMD patch?
> 
Introduction of the PMD in mlx5.rst can be part of initial patch.
You can also add empty .ini file also in the initial patch.
Now as and when the feature/algo is added, .ini file need to be updated.
And while adding the test app changes in the last patch, you can update
mlx5.rst.
For reference see cnxk patches.
  

Patch

diff --git a/doc/guides/cryptodevs/features/mlx5.ini b/doc/guides/cryptodevs/features/mlx5.ini
index ceadd967b6..bd757b5211 100644
--- a/doc/guides/cryptodevs/features/mlx5.ini
+++ b/doc/guides/cryptodevs/features/mlx5.ini
@@ -4,12 +4,17 @@ 
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Symmetric crypto       = Y
 HW Accelerated         = Y
+Cipher multiple data units = Y
+Cipher wrapped key     = Y
 
 ;
 ; Supported crypto algorithms of a mlx5 crypto driver.
 ;
 [Cipher]
+AES XTS (128)  = Y
+AES XTS (256)  = Y
 
 ;
 ; Supported authentication algorithms of a mlx5 crypto driver.
diff --git a/doc/guides/cryptodevs/mlx5.rst b/doc/guides/cryptodevs/mlx5.rst
index 05a0a449e2..dd1d1a615d 100644
--- a/doc/guides/cryptodevs/mlx5.rst
+++ b/doc/guides/cryptodevs/mlx5.rst
@@ -53,6 +53,16 @@  Supported NICs
 
 * Mellanox\ |reg| ConnectX\ |reg|-6 200G MCX654106A-HCAT (2x200G)
 
+
+Limitations
+-----------
+
+- AES-XTS keys provided in xform must include keytag and should be wrappend.
+- The supported data-unit lengths are 512B and 1KB. In case the `dataunit_len`
+  is not provided in the cipher xform, the OP length is limited to the above
+  values and 1MB.
+
+
 Prerequisites
 -------------
 
diff --git a/drivers/crypto/mlx5/mlx5_crypto.c b/drivers/crypto/mlx5/mlx5_crypto.c
index d2d82c7b15..3f0c97d081 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.c
+++ b/drivers/crypto/mlx5/mlx5_crypto.c
@@ -3,6 +3,7 @@ 
  */
 
 #include <rte_malloc.h>
+#include <rte_mempool.h>
 #include <rte_errno.h>
 #include <rte_log.h>
 #include <rte_pci.h>
@@ -20,7 +21,9 @@ 
 #define MLX5_CRYPTO_LOG_NAME pmd.crypto.mlx5
 
 #define MLX5_CRYPTO_FEATURE_FLAGS \
-	RTE_CRYPTODEV_FF_HW_ACCELERATED
+	(RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | RTE_CRYPTODEV_FF_HW_ACCELERATED | \
+	 RTE_CRYPTODEV_FF_CIPHER_WRAPPED_KEY | \
+	 RTE_CRYPTODEV_FF_CIPHER_MULTIPLE_DATA_UNITS)
 
 TAILQ_HEAD(mlx5_crypto_privs, mlx5_crypto_priv) mlx5_crypto_priv_list =
 				TAILQ_HEAD_INITIALIZER(mlx5_crypto_priv_list);
@@ -30,6 +33,32 @@  int mlx5_crypto_logtype;
 
 uint8_t mlx5_crypto_driver_id;
 
+const struct rte_cryptodev_capabilities mlx5_crypto_caps[] = {
+	{		/* AES XTS */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_AES_XTS,
+				.block_size = 16,
+				.key_size = {
+					.min = 32,
+					.max = 64,
+					.increment = 32
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.dataunit_set =
+				RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_512_BYTES |
+				RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_4096_BYTES,
+			}, }
+		}, }
+	},
+};
+
 static const char mlx5_crypto_drv_name[] = RTE_STR(MLX5_CRYPTO_DRIVER_NAME);
 
 static const struct rte_driver mlx5_drv = {
@@ -39,6 +68,49 @@  static const struct rte_driver mlx5_drv = {
 
 static struct cryptodev_driver mlx5_cryptodev_driver;
 
+struct mlx5_crypto_session {
+	uint32_t bs_bpt_eo_es;
+	/*
+	 * bsf_size, bsf_p_type, encryption_order and encryption standard,
+	 * saved in big endian format.
+	 */
+	uint32_t bsp_res;
+	/*
+	 * crypto_block_size_pointer and reserved 24 bits saved in big endian
+	 * format.
+	 */
+	uint32_t iv_offset:16;
+	/* Starting point for Initialisation Vector. */
+	struct mlx5_crypto_dek *dek; /* Pointer to dek struct. */
+	uint32_t dek_id; /* DEK ID */
+} __rte_packed;
+
+static void
+mlx5_crypto_dev_infos_get(struct rte_cryptodev *dev,
+			  struct rte_cryptodev_info *dev_info)
+{
+	RTE_SET_USED(dev);
+	if (dev_info != NULL) {
+		dev_info->driver_id = mlx5_crypto_driver_id;
+		dev_info->feature_flags = MLX5_CRYPTO_FEATURE_FLAGS;
+		dev_info->capabilities = mlx5_crypto_caps;
+		dev_info->max_nb_queue_pairs = 0;
+		dev_info->min_mbuf_headroom_req = 0;
+		dev_info->min_mbuf_tailroom_req = 0;
+		dev_info->sym.max_nb_sessions = 0;
+		/*
+		 * If 0, the device does not have any limitation in number of
+		 * sessions that can be used.
+		 */
+	}
+}
+
+static unsigned int
+mlx5_crypto_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
+{
+	return sizeof(struct mlx5_crypto_session);
+}
+
 static int
 mlx5_crypto_dev_configure(struct rte_cryptodev *dev,
 		struct rte_cryptodev_config *config __rte_unused)
@@ -61,19 +133,109 @@  mlx5_crypto_dev_close(struct rte_cryptodev *dev)
 	return 0;
 }
 
+static int
+mlx5_crypto_sym_session_configure(struct rte_cryptodev *dev,
+				  struct rte_crypto_sym_xform *xform,
+				  struct rte_cryptodev_sym_session *session,
+				  struct rte_mempool *mp)
+{
+	struct mlx5_crypto_priv *priv = dev->data->dev_private;
+	struct mlx5_crypto_session *sess_private_data;
+	struct rte_crypto_cipher_xform *cipher;
+	uint8_t encryption_order;
+	int ret;
+
+	if (unlikely(xform->next != NULL)) {
+		DRV_LOG(ERR, "Xform next is not supported.");
+		return -ENOTSUP;
+	}
+	if (unlikely((xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) ||
+		     (xform->cipher.algo != RTE_CRYPTO_CIPHER_AES_XTS))) {
+		DRV_LOG(ERR, "Only AES-XTS algorithm is supported.");
+		return -ENOTSUP;
+	}
+	ret = rte_mempool_get(mp, (void *)&sess_private_data);
+	if (ret != 0) {
+		DRV_LOG(ERR,
+			"Failed to get session %p private data from mempool.",
+			sess_private_data);
+		return -ENOMEM;
+	}
+	cipher = &xform->cipher;
+	sess_private_data->dek = mlx5_crypto_dek_prepare(priv, cipher);
+	if (sess_private_data->dek == NULL) {
+		rte_mempool_put(mp, sess_private_data);
+		DRV_LOG(ERR, "Failed to prepare dek.");
+		return -ENOMEM;
+	}
+	if (cipher->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+		encryption_order = MLX5_ENCRYPTION_ORDER_ENCRYPTED_RAW_MEMORY;
+	else
+		encryption_order = MLX5_ENCRYPTION_ORDER_ENCRYPTED_RAW_WIRE;
+	sess_private_data->bs_bpt_eo_es = rte_cpu_to_be_32
+			(MLX5_BSF_SIZE_64B << MLX5_BSF_SIZE_OFFSET |
+			 MLX5_BSF_P_TYPE_CRYPTO << MLX5_BSF_P_TYPE_OFFSET |
+			 encryption_order << MLX5_ENCRYPTION_ORDER_OFFSET |
+			 MLX5_ENCRYPTION_STANDARD_AES_XTS);
+	switch (xform->cipher.dataunit_len) {
+	case 0:
+		sess_private_data->bsp_res = 0;
+		break;
+	case 512:
+		sess_private_data->bsp_res = rte_cpu_to_be_32
+					     ((uint32_t)MLX5_BLOCK_SIZE_512B <<
+					     MLX5_BLOCK_SIZE_OFFSET);
+		break;
+	case 4096:
+		sess_private_data->bsp_res = rte_cpu_to_be_32
+					     ((uint32_t)MLX5_BLOCK_SIZE_4096B <<
+					     MLX5_BLOCK_SIZE_OFFSET);
+		break;
+	default:
+		DRV_LOG(ERR, "Cipher data unit length is not supported.");
+		return -ENOTSUP;
+	}
+	sess_private_data->iv_offset = cipher->iv.offset;
+	sess_private_data->dek_id =
+			rte_cpu_to_be_32(sess_private_data->dek->obj->id &
+					 0xffffff);
+	set_sym_session_private_data(session, dev->driver_id,
+				     sess_private_data);
+	DRV_LOG(DEBUG, "Session %p was configured.", sess_private_data);
+	return 0;
+}
+
+static void
+mlx5_crypto_sym_session_clear(struct rte_cryptodev *dev,
+			      struct rte_cryptodev_sym_session *sess)
+{
+	struct mlx5_crypto_priv *priv = dev->data->dev_private;
+	struct mlx5_crypto_session *spriv = get_sym_session_private_data(sess,
+								dev->driver_id);
+
+	if (unlikely(spriv == NULL)) {
+		DRV_LOG(ERR, "Failed to get session %p private data.", spriv);
+		return;
+	}
+	mlx5_crypto_dek_destroy(priv, spriv->dek);
+	set_sym_session_private_data(sess, dev->driver_id, NULL);
+	rte_mempool_put(rte_mempool_from_obj(spriv), spriv);
+	DRV_LOG(DEBUG, "Session %p was cleared.", spriv);
+}
+
 static struct rte_cryptodev_ops mlx5_crypto_ops = {
 	.dev_configure			= mlx5_crypto_dev_configure,
 	.dev_start			= NULL,
 	.dev_stop			= NULL,
 	.dev_close			= mlx5_crypto_dev_close,
-	.dev_infos_get			= NULL,
+	.dev_infos_get			= mlx5_crypto_dev_infos_get,
 	.stats_get			= NULL,
 	.stats_reset			= NULL,
 	.queue_pair_setup		= NULL,
 	.queue_pair_release		= NULL,
-	.sym_session_get_size		= NULL,
-	.sym_session_configure		= NULL,
-	.sym_session_clear		= NULL,
+	.sym_session_get_size		= mlx5_crypto_sym_session_get_size,
+	.sym_session_configure		= mlx5_crypto_sym_session_configure,
+	.sym_session_clear		= mlx5_crypto_sym_session_clear,
 	.sym_get_raw_dp_ctx_size	= NULL,
 	.sym_configure_raw_dp_ctx	= NULL,
 };