> 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 <shi...@nvidia.com>
> Acked-by: Matan Azrad <ma...@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

Reply via email to