Skip to content

Commit

Permalink
crypto/mlx5: enable AES-GCM capability
Browse files Browse the repository at this point in the history
This commit generates AES-GCM capability based on the NIC
attributes and enables AES-GCM algo.

An new devarg "algo" is added to identify if the crypto PMD will
be initialized as AES-GCM(algo=1) or AES-XTS(algo=0, default).

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
Signed-off-by: 0-day Robot <robot@bytheb.org>
  • Loading branch information
smou-mlnx authored and ovsrobot committed Jun 20, 2023
1 parent 8921867 commit dbc837b
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 5 deletions.
2 changes: 2 additions & 0 deletions doc/guides/cryptodevs/features/mlx5.ini
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ AES XTS (256) = Y
; Supported AEAD algorithms of a mlx5 crypto driver.
;
[AEAD]
AES GCM (128) = Y
AES GCM (256) = Y

;
; Supported Asymmetric algorithms of a mlx5 crypto driver.
Expand Down
48 changes: 47 additions & 1 deletion doc/guides/cryptodevs/mlx5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ and **NVIDIA BlueField-3** family adapters.
Overview
--------

Nvidia MLX5 crypto driver supports AES-XTs and AES-GCM cryption.

AES-XTS
-------

The device can provide disk encryption services,
allowing data encryption and decryption towards a disk.
Having all encryption/decryption operations done in a single device
Expand All @@ -38,13 +43,19 @@ The encryption does not require text to be aligned to the AES block size (128b).

See :doc:`../../platform/mlx5` guide for more design details.

AES-GCM
-------
The encryption and decryption processes the traffic as standard RTE crypto
API defines. The supported AAD/digest/key size can be read from dev_info.


Configuration
-------------

See the :ref:`mlx5 common configuration <mlx5_common_env>`.

A device comes out of NVIDIA factory with pre-defined import methods.
There are two possible import methods: wrapped or plaintext.
There are two possible import methods: wrapped or plaintext(valid to AES-XTS only).

In case the device is in wrapped mode, it needs to be moved to crypto operational mode.
In order to move the device to crypto operational mode, credential and KEK
Expand Down Expand Up @@ -120,24 +131,36 @@ Driver options
Please refer to :ref:`mlx5 common options <mlx5_common_driver_options>`
for an additional list of options shared with other mlx5 drivers.

- ``algo`` parameter [int]

- 0. AES-XTS crypto.

- 1. AES-GCM crypto.

Set to zero(AES-XTS) by default.

- ``wcs_file`` parameter [string] - mandatory in wrapped mode

File path including only the wrapped credential in string format of hexadecimal
numbers, represent 48 bytes (8 bytes IV added by the AES key wrap algorithm).
This option is valid only to AES-XTS.

- ``import_kek_id`` parameter [int]

The identifier of the KEK, default value is 0 represents the operational
register import_kek..
This option is valid only to AES-XTS.

- ``credential_id`` parameter [int]

The identifier of the credential, default value is 0 represents the operational
register credential.
This option is valid only to AES-XTS.

- ``keytag`` parameter [int]

The plaintext of the keytag appended to the AES-XTS keys, default value is 0.
This option is valid only to AES-XTS.

- ``max_segs_num`` parameter [int]

Expand All @@ -161,6 +184,8 @@ Limitations
- The supported data-unit lengths are 512B and 4KB and 1MB. In case the `dataunit_len`
is not provided in the cipher xform, the OP length is limited to the above
values.
- AES-GCM is only supported on BlueField-3.
- AES-GCM only supported key import plaintext mode.


Prerequisites
Expand All @@ -172,6 +197,7 @@ FW Prerequisites
- xx.31.0328 for ConnectX-6.
- xx.32.0108 for ConnectX-6 Dx and BlueField-2.
- xx.36.xxxx for ConnectX-7 and BlueField-3.
- xx.37.3010 for BlueField-3 and newer for AES-GCM.

Linux Prerequisites
~~~~~~~~~~~~~~~~~~~
Expand All @@ -186,3 +212,23 @@ Windows Prerequisites

- NVIDIA WINOF-2 version: **2.60** or higher.
See :ref:`mlx5 common prerequisites <mlx5_windows_prerequisites>` for more details.


Notes for rte_crypto AES-GCM
----------------------------

In AES-GCM mode, the HW requires continuous input and output of Additional
Authenticated Data (AAD), payload, and digest (if needed). However, the RTE
API only provides a single AAD input, which means that in the out-of-place
mode, the AAD will be used in both input and output. This reuse of AAD in the
out-of-place mode breaks the continuous output, which degrades the performance
and introduces extra UMR WQE. If digest is not continuous after payload will
also lead to that extra UMR WQE.

To address this issue, current RTE API provides min_mbuf_headroom_req and
min_mbuf_tailroom_req in rte_cryptodev_info as a hint to the PMD. It
indicates the PMD can use the buffer before and after the mbuf payload as AAD
and digest space. With this hint, the PMD will use the buffer before and
after the mbuf payload directly via copying AAD and digest. However, the
application must ensure that there is enough headroom and tailroom reserved
for the mbuf. Or, for non-continuous operations, extra UMR WQE will be used.
1 change: 1 addition & 0 deletions doc/guides/rel_notes/release_23_07.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ New Features
* Added support for CQE compression on Windows.
* Added support for enhanced multi-packet write on Windows.
* Added support for quota flow action and item.
* Added support for AES-GCM crypto.

* **Added vmxnet3 version 7 support.**

Expand Down
26 changes: 22 additions & 4 deletions drivers/crypto/mlx5/mlx5_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,14 @@ mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
attr->credential_pointer = (uint32_t)tmp;
} else if (strcmp(key, "keytag") == 0) {
devarg_prms->keytag = tmp;
} else if (strcmp(key, "algo") == 0) {
if (tmp == 1) {
devarg_prms->is_aes_gcm = 1;
} else if (tmp > 1) {
DRV_LOG(ERR, "Invalid algo.");
rte_errno = EINVAL;
return -rte_errno;
}
}
return 0;
}
Expand All @@ -285,6 +293,7 @@ mlx5_crypto_parse_devargs(struct mlx5_kvargs_ctrl *mkvlist,
"keytag",
"max_segs_num",
"wcs_file",
"algo",
NULL,
};

Expand Down Expand Up @@ -370,10 +379,19 @@ mlx5_crypto_dev_probe(struct mlx5_common_device *cdev,
priv->crypto_dev = crypto_dev;
priv->is_wrapped_mode = wrapped_mode;
priv->max_segs_num = devarg_prms.max_segs_num;
ret = mlx5_crypto_xts_init(priv);
if (ret) {
DRV_LOG(ERR, "Failed to init AES-XTS crypto.");
return -ENOTSUP;
/* Init and override AES-GCM configuration. */
if (devarg_prms.is_aes_gcm) {
ret = mlx5_crypto_gcm_init(priv);
if (ret) {
DRV_LOG(ERR, "Failed to init AES-GCM crypto.");
return -ENOTSUP;
}
} else {
ret = mlx5_crypto_xts_init(priv);
if (ret) {
DRV_LOG(ERR, "Failed to init AES-XTS crypto.");
return -ENOTSUP;
}
}
if (mlx5_devx_uar_prepare(cdev, &priv->uar) != 0) {
rte_cryptodev_pmd_destroy(priv->crypto_dev);
Expand Down
1 change: 1 addition & 0 deletions drivers/crypto/mlx5/mlx5_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ struct mlx5_crypto_devarg_params {
struct mlx5_devx_crypto_login_attr login_attr;
uint64_t keytag;
uint32_t max_segs_num;
uint32_t is_aes_gcm:1;
};

struct mlx5_crypto_session {
Expand Down
63 changes: 63 additions & 0 deletions drivers/crypto/mlx5/mlx5_crypto_gcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,60 @@ mlx5_crypto_dek_fill_gcm_attr(struct mlx5_crypto_dek *dek,
return 0;
}

static int
mlx5_crypto_generate_gcm_cap(struct mlx5_hca_crypto_mmo_attr *mmo_attr,
struct rte_cryptodev_capabilities *cap)
{
/* Init key size. */
if (mmo_attr->gcm_128_encrypt && mmo_attr->gcm_128_decrypt &&
mmo_attr->gcm_256_encrypt && mmo_attr->gcm_256_decrypt) {
cap->sym.aead.key_size.min = 16;
cap->sym.aead.key_size.max = 32;
cap->sym.aead.key_size.increment = 16;
} else if (mmo_attr->gcm_256_encrypt && mmo_attr->gcm_256_decrypt) {
cap->sym.aead.key_size.min = 32;
cap->sym.aead.key_size.max = 32;
cap->sym.aead.key_size.increment = 0;
} else if (mmo_attr->gcm_128_encrypt && mmo_attr->gcm_128_decrypt) {
cap->sym.aead.key_size.min = 16;
cap->sym.aead.key_size.max = 16;
cap->sym.aead.key_size.increment = 0;
} else {
DRV_LOG(ERR, "No available AES-GCM encryption/decryption supported.");
return -1;
}
/* Init tag size. */
if (mmo_attr->gcm_auth_tag_128 && mmo_attr->gcm_auth_tag_96) {
cap->sym.aead.digest_size.min = 12;
cap->sym.aead.digest_size.max = 16;
cap->sym.aead.digest_size.increment = 4;
} else if (mmo_attr->gcm_auth_tag_96) {
cap->sym.aead.digest_size.min = 12;
cap->sym.aead.digest_size.max = 12;
cap->sym.aead.digest_size.increment = 0;
} else if (mmo_attr->gcm_auth_tag_128) {
cap->sym.aead.digest_size.min = 16;
cap->sym.aead.digest_size.max = 16;
cap->sym.aead.digest_size.increment = 0;
} else {
DRV_LOG(ERR, "No available AES-GCM tag size supported.");
return -1;
}
/* Init AAD size. */
cap->sym.aead.aad_size.min = 0;
cap->sym.aead.aad_size.max = UINT16_MAX;
cap->sym.aead.aad_size.increment = 1;
/* Init IV size. */
cap->sym.aead.iv_size.min = 12;
cap->sym.aead.iv_size.max = 12;
cap->sym.aead.iv_size.increment = 0;
/* Init left items. */
cap->op = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
cap->sym.xform_type = RTE_CRYPTO_SYM_XFORM_AEAD;
cap->sym.aead.algo = RTE_CRYPTO_AEAD_AES_GCM;
return 0;
}

static int
mlx5_crypto_sym_gcm_session_configure(struct rte_cryptodev *dev,
struct rte_crypto_sym_xform *xform,
Expand Down Expand Up @@ -917,8 +971,10 @@ mlx5_crypto_gcm_dequeue_burst(void *queue_pair,
int
mlx5_crypto_gcm_init(struct mlx5_crypto_priv *priv)
{
struct mlx5_common_device *cdev = priv->cdev;
struct rte_cryptodev *crypto_dev = priv->crypto_dev;
struct rte_cryptodev_ops *dev_ops = crypto_dev->dev_ops;
int ret;

/* Override AES-GCM specified ops. */
dev_ops->sym_session_configure = mlx5_crypto_sym_gcm_session_configure;
Expand All @@ -928,6 +984,13 @@ mlx5_crypto_gcm_init(struct mlx5_crypto_priv *priv)
crypto_dev->dequeue_burst = mlx5_crypto_gcm_dequeue_burst;
crypto_dev->enqueue_burst = mlx5_crypto_gcm_enqueue_burst;
priv->max_klm_num = RTE_ALIGN((priv->max_segs_num + 1) * 2 + 1, MLX5_UMR_KLM_NUM_ALIGN);
/* Generate GCM capability. */
ret = mlx5_crypto_generate_gcm_cap(&cdev->config.hca_attr.crypto_mmo,
mlx5_crypto_gcm_caps);
if (ret) {
DRV_LOG(ERR, "No enough AES-GCM cap.");
return -1;
}
priv->caps = mlx5_crypto_gcm_caps;
return 0;
}
Expand Down

0 comments on commit dbc837b

Please sign in to comment.