crypto/mlx5: support session operations
authorShiri Kuzin <shirik@nvidia.com>
Tue, 20 Jul 2021 13:09:34 +0000 (16:09 +0300)
committerAkhil Goyal <gakhil@marvell.com>
Tue, 20 Jul 2021 20:26:43 +0000 (22:26 +0200)
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>
Acked-by: Akhil Goyal <gakhil@marvell.com>
doc/guides/cryptodevs/features/mlx5.ini
doc/guides/cryptodevs/mlx5.rst
drivers/crypto/mlx5/mlx5_crypto.c

index ceadd96..bd757b5 100644 (file)
@@ -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.
index ac89a40..ed60a93 100644 (file)
@@ -55,6 +55,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 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
 -------------
 
index ad1d7b6..2fe2e8b 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <rte_malloc.h>
+#include <rte_mempool.h>
 #include <rte_errno.h>
 #include <rte_log.h>
 #include <rte_pci.h>
@@ -22,7 +23,9 @@
 #define MLX5_CRYPTO_MAX_QPS 1024
 
 #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);
@@ -67,6 +70,21 @@ 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)
@@ -134,6 +152,102 @@ mlx5_crypto_dev_close(struct rte_cryptodev *dev)
        return 0;
 }
 
+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_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 int
 mlx5_crypto_queue_pair_release(struct rte_cryptodev *dev, uint16_t qp_id)
 {
@@ -265,9 +379,9 @@ static struct rte_cryptodev_ops mlx5_crypto_ops = {
        .stats_reset                    = NULL,
        .queue_pair_setup               = mlx5_crypto_queue_pair_setup,
        .queue_pair_release             = mlx5_crypto_queue_pair_release,
-       .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,
 };