> 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