[1/2] crypto/zuc: support IPSec Multi-buffer lib v0.54
Checks
Commit Message
The latest version of the Intel IPSec Multi-buffer library
adds an API to authenticate multiple buffers in parallel.
The PMD is modified to use this API, improving
performance of the ZUC-EIA3 algorithm.
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
doc/guides/cryptodevs/zuc.rst | 6 +--
doc/guides/rel_notes/release_20_05.rst | 7 ++++
drivers/crypto/zuc/rte_zuc_pmd.c | 72 ++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 3 deletions(-)
Comments
Hi Pablo,
> +#if IMB_VERSION_NUM >= IMB_VERSION(0, 53, 3)
> + processed_ops = process_zuc_hash_op_mb(qp, ops, sessions,
> + num_ops);
> +#else
> processed_ops = process_zuc_hash_op(qp, ops, sessions,
> num_ops);
> +#endif
> break;
Instead of having a separate name for process_zuc_hash_op in case of newer IMB version,
Is it not better to have same name of the function but having different definitions for different
IMB version. This way you can reduce the #ifs in the code.
Regards,
Akhil
Hi Akhil,
> -----Original Message-----
> From: Akhil Goyal <akhil.goyal@nxp.com>
> Sent: Saturday, May 9, 2020 8:05 PM
> To: De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH 1/2] crypto/zuc: support IPSec Multi-buffer lib
> v0.54
>
> Hi Pablo,
>
> > +#if IMB_VERSION_NUM >= IMB_VERSION(0, 53, 3)
> > + processed_ops = process_zuc_hash_op_mb(qp, ops, sessions,
> > + num_ops);
> > +#else
> > processed_ops = process_zuc_hash_op(qp, ops, sessions,
> > num_ops);
> > +#endif
> > break;
>
> Instead of having a separate name for process_zuc_hash_op in case of newer
> IMB version, Is it not better to have same name of the function but having
> different definitions for different IMB version. This way you can reduce the #ifs
> in the code.
Good suggestion. Will send a v2 shortly.
Thanks,
Pablo
>
> Regards,
> Akhil
@@ -35,8 +35,8 @@ Installation
To build DPDK with the ZUC_PMD the user is required to download the multi-buffer
library from `here <https://github.com/01org/intel-ipsec-mb>`_
and compile it on their user system before building DPDK.
-The latest version of the library supported by this PMD is v0.53, which
-can be downloaded from `<https://github.com/01org/intel-ipsec-mb/archive/v0.53.zip>`_.
+The latest version of the library supported by this PMD is v0.54, which
+can be downloaded from `<https://github.com/01org/intel-ipsec-mb/archive/v0.54.zip>`_.
After downloading the library, the user needs to unpack and compile it
on their system before building DPDK:
@@ -63,7 +63,7 @@ and the external crypto libraries supported by them:
DPDK version Crypto library version
============= ================================
16.11 - 19.11 LibSSO ZUC
- 20.02+ Multi-buffer library 0.53
+ 20.02+ Multi-buffer library 0.53 - 0.54
============= ================================
@@ -84,6 +84,13 @@ New Features
* Added support for intel-ipsec-mb version 0.54.
+* **Updated the ZUC crypto PMD.**
+
+ * Added support for intel-ipsec-mb version 0.54.
+ * Updated the PMD to support Multi-buffer ZUC-EIA3,
+ improving performance significantly, when using
+ intel-ipsec-mb version 0.54
+
* **Added QAT intermediate buffer too small handling in QAT compression PMD.**
Added a special way of buffer handling when internal QAT intermediate buffer
@@ -232,6 +232,63 @@ process_zuc_cipher_op(struct zuc_qp *qp, struct rte_crypto_op **ops,
}
/** Generate/verify hash from mbufs. */
+#if IMB_VERSION_NUM >= IMB_VERSION(0, 53, 3)
+static int
+process_zuc_hash_op_mb(struct zuc_qp *qp, struct rte_crypto_op **ops,
+ struct zuc_session **sessions,
+ uint8_t num_ops)
+{
+ unsigned int i;
+ uint8_t processed_ops = 0;
+ uint8_t *src[ZUC_MAX_BURST];
+ uint32_t *dst[ZUC_MAX_BURST];
+ uint32_t length_in_bits[ZUC_MAX_BURST];
+ uint8_t *iv[ZUC_MAX_BURST];
+ const void *hash_keys[ZUC_MAX_BURST];
+ struct zuc_session *sess;
+
+ for (i = 0; i < num_ops; i++) {
+ /* Data must be byte aligned */
+ if ((ops[i]->sym->auth.data.offset % BYTE_LEN) != 0) {
+ ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ ZUC_LOG(ERR, "Offset");
+ break;
+ }
+
+ sess = sessions[i];
+
+ length_in_bits[i] = ops[i]->sym->auth.data.length;
+
+ src[i] = rte_pktmbuf_mtod(ops[i]->sym->m_src, uint8_t *) +
+ (ops[i]->sym->auth.data.offset >> 3);
+ iv[i] = rte_crypto_op_ctod_offset(ops[i], uint8_t *,
+ sess->auth_iv_offset);
+
+ hash_keys[i] = sess->pKey_hash;
+ if (sess->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY)
+ dst[i] = (uint32_t *)qp->temp_digest;
+ else
+ dst[i] = (uint32_t *)ops[i]->sym->auth.digest.data;
+
+ processed_ops++;
+ }
+
+ IMB_ZUC_EIA3_N_BUFFER(qp->mb_mgr, (const void **)hash_keys,
+ (const void **)iv, (const void **)src, length_in_bits,
+ dst, processed_ops);
+
+ /*
+ * If tag needs to be verified, compare generated tag
+ * with attached tag
+ */
+ for (i = 0; i < processed_ops; i++)
+ if (sessions[i]->auth_op == RTE_CRYPTO_AUTH_OP_VERIFY)
+ if (memcmp(dst[i], ops[i]->sym->auth.digest.data,
+ ZUC_DIGEST_LENGTH) != 0)
+ ops[i]->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
+ return processed_ops;
+}
+#else
static int
process_zuc_hash_op(struct zuc_qp *qp, struct rte_crypto_op **ops,
struct zuc_session **sessions,
@@ -284,6 +341,7 @@ process_zuc_hash_op(struct zuc_qp *qp, struct rte_crypto_op **ops,
return processed_ops;
}
+#endif
/** Process a batch of crypto ops which shares the same operation type. */
static int
@@ -301,17 +359,31 @@ process_ops(struct rte_crypto_op **ops, enum zuc_operation op_type,
sessions, num_ops);
break;
case ZUC_OP_ONLY_AUTH:
+#if IMB_VERSION_NUM >= IMB_VERSION(0, 53, 3)
+ processed_ops = process_zuc_hash_op_mb(qp, ops, sessions,
+ num_ops);
+#else
processed_ops = process_zuc_hash_op(qp, ops, sessions,
num_ops);
+#endif
break;
case ZUC_OP_CIPHER_AUTH:
processed_ops = process_zuc_cipher_op(qp, ops, sessions,
num_ops);
+#if IMB_VERSION_NUM >= IMB_VERSION(0, 53, 3)
+ process_zuc_hash_op_mb(qp, ops, sessions, processed_ops);
+#else
process_zuc_hash_op(qp, ops, sessions, processed_ops);
+#endif
break;
case ZUC_OP_AUTH_CIPHER:
+#if IMB_VERSION_NUM >= IMB_VERSION(0, 53, 3)
+ processed_ops = process_zuc_hash_op_mb(qp, ops, sessions,
+ num_ops);
+#else
processed_ops = process_zuc_hash_op(qp, ops, sessions,
num_ops);
+#endif
process_zuc_cipher_op(qp, ops, sessions, processed_ops);
break;
default: