From: Radu Nicolau <radu.nicolau@intel.com>
To: dev@dpdk.org
Cc: Radu Nicolau <radu.nicolau@intel.com>, Kai Ji <kai.ji@intel.com>,
Pablo de Lara <pablo.de.lara.guarch@intel.com>
Subject: [PATCH 3/4] crypto/ipsec_mb: add support for ML-KEM and ML-DSA
Date: Fri, 2 Oct 2026 09:56:23 +0000 [thread overview]
Message-ID: <20261002095652.1540556-4-radu.nicolau@intel.com> (raw)
In-Reply-To: <20261002095652.1540556-1-radu.nicolau@intel.com>
Enable basic support for asymmetric crypto operations.
Add support for ML-KEM and ML-DSA algorithms.
IPsecMB release 3.0 and newer required.
Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
---
doc/guides/cryptodevs/aesni_mb.rst | 6 +
doc/guides/cryptodevs/features/aesni_mb.ini | 3 +
doc/guides/rel_notes/release_26_11.rst | 3 +
drivers/crypto/ipsec_mb/ipsec_mb_ops.c | 58 +++
drivers/crypto/ipsec_mb/ipsec_mb_private.h | 20 ++
drivers/crypto/ipsec_mb/pmd_aesni_mb.c | 372 +++++++++++++++++++-
drivers/crypto/ipsec_mb/pmd_aesni_mb_priv.h | 86 ++++-
7 files changed, 532 insertions(+), 16 deletions(-)
diff --git a/doc/guides/cryptodevs/aesni_mb.rst b/doc/guides/cryptodevs/aesni_mb.rst
index 5fb73e31b4..395bdc77da 100644
--- a/doc/guides/cryptodevs/aesni_mb.rst
+++ b/doc/guides/cryptodevs/aesni_mb.rst
@@ -78,6 +78,12 @@ AEAD algorithms:
* RTE_CRYPTO_AEAD_AES_NCA5
* RTE_CRYPTO_AEAD_ZUC_NCA6
+PQC Asymmetric Crypto algorithms
+
+* RTE_CRYPTO_ASYM_XFORM_ML_KEM
+* RTE_CRYPTO_ASYM_XFORM_ML_DSA
+
+
Protocol offloads:
* RTE_SECURITY_PROTOCOL_DOCSIS
diff --git a/doc/guides/cryptodevs/features/aesni_mb.ini b/doc/guides/cryptodevs/features/aesni_mb.ini
index e64818bf46..c6a28987dd 100644
--- a/doc/guides/cryptodevs/features/aesni_mb.ini
+++ b/doc/guides/cryptodevs/features/aesni_mb.ini
@@ -21,6 +21,7 @@ CPU crypto = Y
Symmetric sessionless = Y
Non-Byte aligned data = Y
Digest encrypted = Y
+Asymmetric crypto = Y
;
; Supported crypto algorithms of the 'aesni_mb' crypto driver.
@@ -95,6 +96,8 @@ ZUC-256 NCA6 = Y
; Supported Asymmetric algorithms of the 'aesni_mb' crypto driver.
;
[Asymmetric]
+ML-KEM = Y
+ML-DSA = Y
;
; Supported Operating systems of the 'aesni_mb' crypto driver.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 1ee3cdfba3..7dd8231706 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -40,6 +40,9 @@ New Features
- NEA4, NIA4, NCA4: Snow 5G confidentiality, integrity and AEAD modes.
- NEA5, NIA5, NCA5: AES 256 confidentiality, integrity and AEAD modes.
- NEA6, NIA6, NCA6: ZUC 256 confidentiality, integrity and AEAD modes.
+ * Added support for the following PQC asymmetric algorithms:
+ - ML-KEM: Module-Lattice-Based Key-Encapsulation Mechanism.
+ - ML-DSA: Module-Lattice-Based Digital Signature Algorithm.
.. This section should contain new features added in this release.
diff --git a/drivers/crypto/ipsec_mb/ipsec_mb_ops.c b/drivers/crypto/ipsec_mb/ipsec_mb_ops.c
index 50ee140ccd..308775882c 100644
--- a/drivers/crypto/ipsec_mb/ipsec_mb_ops.c
+++ b/drivers/crypto/ipsec_mb/ipsec_mb_ops.c
@@ -453,3 +453,61 @@ void
ipsec_mb_sym_session_clear(struct rte_cryptodev *dev __rte_unused,
struct rte_cryptodev_sym_session *sess __rte_unused)
{}
+
+/** Configure pmd specific multi-buffer asym session from a crypto xform chain */
+int
+ipsec_mb_asym_session_configure(
+ struct rte_cryptodev *dev, struct rte_crypto_asym_xform *xform,
+ struct rte_cryptodev_asym_session *sess)
+{
+ struct ipsec_mb_dev_private *internals = dev->data->dev_private;
+ struct ipsec_mb_internals *pmd_data =
+ &ipsec_mb_pmds[internals->pmd_type];
+ struct ipsec_mb_qp *qp = dev->data->queue_pairs[0];
+ IMB_MGR *mb_mgr;
+ int ret = 0;
+
+ if (qp != NULL)
+ mb_mgr = qp->mb_mgr;
+ else
+ mb_mgr = alloc_init_mb_mgr();
+
+ if (!mb_mgr)
+ return -ENOMEM;
+
+ if (unlikely(sess == NULL)) {
+ IPSEC_MB_LOG(ERR, "invalid session struct");
+ if (qp == NULL)
+ free_mb_mgr(mb_mgr);
+ return -EINVAL;
+ }
+
+ ret = (*pmd_data->asym_session_configure)(mb_mgr,
+ CRYPTODEV_GET_ASYM_SESS_PRIV(sess), xform);
+ if (ret != 0) {
+ IPSEC_MB_LOG(ERR, "failed configure asym session parameters");
+
+ /* Return session to mempool */
+ if (qp == NULL)
+ free_mb_mgr(mb_mgr);
+ return ret;
+ }
+
+ if (qp == NULL)
+ free_mb_mgr(mb_mgr);
+
+ pmd_data->asym_session_created = true;
+ return 0;
+}
+
+/** Clear the asym session memory */
+void
+ipsec_mb_asym_session_clear(struct rte_cryptodev *dev __rte_unused,
+ struct rte_cryptodev_asym_session *sess)
+{
+ struct ipsec_mb_dev_private *internals = dev->data->dev_private;
+ struct ipsec_mb_internals *pmd_data =
+ &ipsec_mb_pmds[internals->pmd_type];
+
+ (*pmd_data->asym_session_clear)(CRYPTODEV_GET_ASYM_SESS_PRIV(sess));
+}
diff --git a/drivers/crypto/ipsec_mb/ipsec_mb_private.h b/drivers/crypto/ipsec_mb/ipsec_mb_private.h
index fc7d6f5f06..5509dc21f3 100644
--- a/drivers/crypto/ipsec_mb/ipsec_mb_private.h
+++ b/drivers/crypto/ipsec_mb/ipsec_mb_private.h
@@ -356,6 +356,12 @@ typedef int (*ipsec_mb_session_configure_t)(IMB_MGR *mbr_mgr,
void *session_private,
const struct rte_crypto_sym_xform *xform);
+typedef int (*ipsec_mb_asym_session_configure_t)(IMB_MGR *mbr_mgr,
+ void *session_private,
+ const struct rte_crypto_asym_xform *xform);
+
+typedef void (*ipsec_mb_asym_session_clear_t)(void *session_private);
+
/** Configure internals PMD type specific data */
typedef int (*ipsec_mb_dev_configure_t)(struct rte_cryptodev *dev);
@@ -366,6 +372,9 @@ struct ipsec_mb_internals {
ipsec_mb_dev_configure_t dev_config;
ipsec_mb_queue_pair_configure_t queue_pair_configure;
ipsec_mb_session_configure_t session_configure;
+ ipsec_mb_asym_session_configure_t asym_session_configure;
+ ipsec_mb_asym_session_clear_t asym_session_clear;
+ bool asym_session_created;
const struct rte_cryptodev_capabilities *caps;
struct rte_cryptodev_ops *ops;
struct rte_security_ops *security_ops;
@@ -423,11 +432,22 @@ int ipsec_mb_sym_session_configure(
struct rte_crypto_sym_xform *xform,
struct rte_cryptodev_sym_session *sess);
+/** Configure an aesni multi-buffer asym session from a crypto xform chain */
+int ipsec_mb_asym_session_configure(
+ struct rte_cryptodev *dev,
+ struct rte_crypto_asym_xform *xform,
+ struct rte_cryptodev_asym_session *sess);
+
/** Clear the memory of session so it does not leave key material behind */
void
ipsec_mb_sym_session_clear(struct rte_cryptodev *dev,
struct rte_cryptodev_sym_session *sess);
+/** Clear the asym session memory */
+void
+ipsec_mb_asym_session_clear(struct rte_cryptodev *dev,
+ struct rte_cryptodev_asym_session *sess);
+
/** Get session from op. If sessionless create a session */
static __rte_always_inline void *
ipsec_mb_get_session_private(struct ipsec_mb_qp *qp, struct rte_crypto_op *op)
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
index a49a82d561..ab65316978 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
@@ -874,7 +874,7 @@ aesni_mb_set_session_aead_parameters(IMB_MGR *mb_mgr,
}
/** Configure a aesni multi-buffer session from a crypto xform chain */
-int
+static int
aesni_mb_session_configure(IMB_MGR *mb_mgr,
void *priv_sess,
const struct rte_crypto_sym_xform *xform)
@@ -965,6 +965,97 @@ aesni_mb_session_configure(IMB_MGR *mb_mgr,
return 0;
}
+#if IMB_VERSION(3, 0, 0) <= IMB_VERSION_NUM
+/** Configure a aesni multi-buffer asym session from a crypto xform chain */
+static int
+aesni_mb_asym_session_configure(IMB_MGR *mb_mgr,
+ void *priv_sess,
+ const struct rte_crypto_asym_xform *xform)
+{
+ (void)mb_mgr;
+ struct aesni_mb_session *sess = (struct aesni_mb_session *) priv_sess;
+ int ret = 0;
+
+ sess->asym.xform_type = xform->xform_type;
+
+ switch (sess->asym.xform_type) {
+ case RTE_CRYPTO_ASYM_XFORM_ML_KEM:
+ {
+ switch (xform->mlkem.type) {
+ case RTE_CRYPTO_ML_KEM_512:
+ sess->asym.ml_kem.alg = IMB_ML_KEM_512;
+ break;
+ case RTE_CRYPTO_ML_KEM_768:
+ sess->asym.ml_kem.alg = IMB_ML_KEM_768;
+ break;
+ case RTE_CRYPTO_ML_KEM_1024:
+ sess->asym.ml_kem.alg = IMB_ML_KEM_1024;
+ break;
+ default:
+ ret = -ENOTSUP;
+ IPSEC_MB_LOG(ERR, "Unsupported type");
+ return ret;
+ }
+ ret = imb_ml_kem_new(mb_mgr, sess->asym.ml_kem.alg, &sess->asym.ml_kem.ctx);
+ if (ret) {
+ IPSEC_MB_LOG(ERR, "Failed to create ML KEM session");
+ return ret;
+ }
+ IMB_ML_KEM_KEYGEN_PARAMS_INIT(&sess->asym.ml_kem.keygen_params);
+ IMB_ML_KEM_ENCAP_PARAMS_INIT(&sess->asym.ml_kem.encap_params);
+ }
+ break;
+ case RTE_CRYPTO_ASYM_XFORM_ML_DSA:
+ {
+ switch (xform->mldsa.type) {
+ case RTE_CRYPTO_ML_DSA_44:
+ sess->asym.ml_dsa.alg = IMB_ML_DSA_44;
+ break;
+ case RTE_CRYPTO_ML_DSA_65:
+ sess->asym.ml_dsa.alg = IMB_ML_DSA_65;
+ break;
+ case RTE_CRYPTO_ML_DSA_87:
+ sess->asym.ml_dsa.alg = IMB_ML_DSA_87;
+ break;
+ default:
+ ret = -ENOTSUP;
+ IPSEC_MB_LOG(ERR, "Unsupported type");
+ return ret;
+ }
+ ret = imb_ml_dsa_new(mb_mgr, sess->asym.ml_dsa.alg, &sess->asym.ml_dsa.ctx);
+ if (ret) {
+ IPSEC_MB_LOG(ERR, "Failed to create ML DSA session");
+ return ret;
+ }
+ IMB_ML_DSA_KEYGEN_PARAMS_INIT(&sess->asym.ml_dsa.keygen_params);
+ IMB_ML_DSA_SIGN_PARAMS_INIT(&sess->asym.ml_dsa.sign_params);
+ IMB_ML_DSA_VERIFY_PARAMS_INIT(&sess->asym.ml_dsa.verify_params);
+ }
+ break;
+ default:
+ ret = -ENOTSUP;
+ IPSEC_MB_LOG(ERR, "Unsupported algorithm");
+ return ret;
+ };
+
+ return ret;
+}
+
+static void
+aesni_mb_asym_session_clear(void *priv_sess)
+{
+ struct aesni_mb_session *sess = (struct aesni_mb_session *) priv_sess;
+ if (sess->asym.xform_type == RTE_CRYPTO_ASYM_XFORM_ML_KEM) {
+ imb_ml_kem_free(sess->asym.ml_kem.ctx);
+ sess->asym.ml_kem.ctx = NULL;
+ } else if (sess->asym.xform_type == RTE_CRYPTO_ASYM_XFORM_ML_DSA) {
+ imb_ml_dsa_free(sess->asym.ml_dsa.ctx);
+ sess->asym.ml_dsa.ctx = NULL;
+ }
+}
+
+#endif
+
/** Check DOCSIS security session configuration is valid */
static int
check_docsis_sec_session(struct rte_security_session_conf *conf)
@@ -2391,7 +2482,237 @@ set_job_null_op(IMB_JOB *job, struct rte_crypto_op *op)
return job;
}
-uint16_t
+#if IMB_VERSION(3, 0, 0) <= IMB_VERSION_NUM
+static inline size_t aesni_mb_ml_kem_ek_sz(const IMB_ML_KEM_ALG alg)
+{
+ switch (alg) {
+ case IMB_ML_KEM_512:
+ return IMB_ML_KEM_512_PUBKEY_BYTES;
+ case IMB_ML_KEM_768:
+ return IMB_ML_KEM_768_PUBKEY_BYTES;
+ case IMB_ML_KEM_1024:
+ return IMB_ML_KEM_1024_PUBKEY_BYTES;
+ }
+ return 0;
+}
+static inline size_t aesni_mb_ml_kem_dk_sz(const IMB_ML_KEM_ALG alg)
+{
+ switch (alg) {
+ case IMB_ML_KEM_512:
+ return IMB_ML_KEM_512_PRIVKEY_BYTES;
+ case IMB_ML_KEM_768:
+ return IMB_ML_KEM_768_PRIVKEY_BYTES;
+ case IMB_ML_KEM_1024:
+ return IMB_ML_KEM_1024_PRIVKEY_BYTES;
+ }
+ return 0;
+}
+static inline size_t aesni_mb_ml_kem_ct_sz(const IMB_ML_KEM_ALG alg)
+{
+ switch (alg) {
+ case IMB_ML_KEM_512:
+ return IMB_ML_KEM_512_CIPHERTEXT_BYTES;
+ case IMB_ML_KEM_768:
+ return IMB_ML_KEM_768_CIPHERTEXT_BYTES;
+ case IMB_ML_KEM_1024:
+ return IMB_ML_KEM_1024_CIPHERTEXT_BYTES;
+ }
+ return 0;
+}
+static inline size_t aesni_mb_ml_dsa_pk_sz(const IMB_ML_DSA_ALG alg)
+{
+ switch (alg) {
+ case IMB_ML_DSA_44:
+ return IMB_ML_DSA_44_PUBKEY_BYTES;
+ case IMB_ML_DSA_65:
+ return IMB_ML_DSA_65_PUBKEY_BYTES;
+ case IMB_ML_DSA_87:
+ return IMB_ML_DSA_87_PUBKEY_BYTES;
+ }
+ return 0;
+}
+static inline size_t aesni_mb_ml_dsa_sk_sz(const IMB_ML_DSA_ALG alg)
+{
+ switch (alg) {
+ case IMB_ML_DSA_44:
+ return IMB_ML_DSA_44_PRIVKEY_BYTES;
+ case IMB_ML_DSA_65:
+ return IMB_ML_DSA_65_PRIVKEY_BYTES;
+ case IMB_ML_DSA_87:
+ return IMB_ML_DSA_87_PRIVKEY_BYTES;
+ }
+ return 0;
+}
+static inline size_t aesni_mb_ml_dsa_sig_sz(const IMB_ML_DSA_ALG alg)
+{
+ switch (alg) {
+ case IMB_ML_DSA_44:
+ return IMB_ML_DSA_44_SIG_BYTES;
+ case IMB_ML_DSA_65:
+ return IMB_ML_DSA_65_SIG_BYTES;
+ case IMB_ML_DSA_87:
+ return IMB_ML_DSA_87_SIG_BYTES;
+ }
+ return 0;
+}
+
+static void
+aesni_mb_asym_process(struct rte_crypto_op *op)
+{
+ struct rte_crypto_asym_op *aop = op->asym;
+ struct aesni_mb_session *sess =
+ CRYPTODEV_GET_ASYM_SESS_PRIV(aop->session);
+ op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+ int rc = 0;
+
+ switch (sess->asym.xform_type) {
+ case RTE_CRYPTO_ASYM_XFORM_ML_KEM:
+ {
+ struct rte_crypto_ml_kem_op *mlkem = &aop->mlkem;
+ switch (mlkem->op) {
+ case RTE_CRYPTO_ML_KEM_OP_KEYGEN:
+ {
+ uint8_t seed_d_z[64];
+ struct rte_crypto_ml_kem_keygen_op *keygen = &mlkem->keygen;
+ memcpy(seed_d_z, keygen->d.data, 32);
+ memcpy(&seed_d_z[32], keygen->z.data, 32);
+ sess->asym.ml_kem.keygen_params.seed_d_z = seed_d_z;
+ sess->asym.ml_kem.keygen_params.seed_d_z_len = 64;
+ keygen->ek.length = aesni_mb_ml_kem_ek_sz(sess->asym.ml_kem.alg);
+ keygen->dk.length = aesni_mb_ml_kem_dk_sz(sess->asym.ml_kem.alg);
+ rc = imb_ml_kem_keypair(sess->asym.ml_kem.ctx,
+ keygen->ek.data, keygen->ek.length,
+ keygen->dk.data, keygen->dk.length,
+ &sess->asym.ml_kem.keygen_params);
+ }
+ break;
+ case RTE_CRYPTO_ML_KEM_OP_ENCAP:
+ {
+ struct rte_crypto_ml_kem_encap_op *encap = &mlkem->encap;
+ sess->asym.ml_kem.encap_params.m_32 = encap->message.data;
+ sess->asym.ml_kem.encap_params.m_len = encap->message.length;
+ encap->ek.length = aesni_mb_ml_kem_ek_sz(sess->asym.ml_kem.alg);
+ encap->cipher.length = aesni_mb_ml_kem_ct_sz(sess->asym.ml_kem.alg);
+ rc = imb_ml_kem_set_pubkey(sess->asym.ml_kem.ctx,
+ encap->ek.data, encap->ek.length);
+ if (rc == 0)
+ rc = imb_ml_kem_encap(sess->asym.ml_kem.ctx,
+ encap->cipher.data, encap->cipher.length,
+ encap->sk.data, encap->sk.length,
+ &sess->asym.ml_kem.encap_params);
+ }
+ break;
+ case RTE_CRYPTO_ML_KEM_OP_DECAP:
+ {
+ struct rte_crypto_ml_kem_decap_op *decap = &mlkem->decap;
+ decap->dk.length = aesni_mb_ml_kem_dk_sz(sess->asym.ml_kem.alg);
+ decap->cipher.length = aesni_mb_ml_kem_ct_sz(sess->asym.ml_kem.alg);
+ rc = imb_ml_kem_set_privkey(sess->asym.ml_kem.ctx,
+ decap->dk.data, decap->dk.length);
+ if (rc == 0)
+ rc = imb_ml_kem_decap(sess->asym.ml_kem.ctx,
+ decap->sk.data, decap->sk.length,
+ decap->cipher.data, decap->cipher.length,
+ NULL);
+ }
+ break;
+ default:
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ break;
+ };
+ }
+ break;
+ case RTE_CRYPTO_ASYM_XFORM_ML_DSA:
+ {
+ struct rte_crypto_ml_dsa_op *mldsa = &aop->mldsa;
+ switch (mldsa->op) {
+ case RTE_CRYPTO_ML_DSA_OP_KEYGEN:
+ {
+ struct rte_crypto_ml_dsa_keygen_op *keygen = &mldsa->keygen;
+ sess->asym.ml_dsa.keygen_params.xi_32 = keygen->seed.data;
+ sess->asym.ml_dsa.keygen_params.xi_len = keygen->seed.length;
+ keygen->pubkey.length =
+ aesni_mb_ml_dsa_pk_sz(sess->asym.ml_dsa.alg);
+ keygen->privkey.length =
+ aesni_mb_ml_dsa_sk_sz(sess->asym.ml_dsa.alg);
+ rc = imb_ml_dsa_keypair(sess->asym.ml_dsa.ctx,
+ keygen->pubkey.data, keygen->pubkey.length,
+ keygen->privkey.data, keygen->privkey.length,
+ &sess->asym.ml_dsa.keygen_params);
+ }
+ break;
+ case RTE_CRYPTO_ML_DSA_OP_SIGN:
+ {
+ struct rte_crypto_ml_dsa_siggen_op *siggen = &mldsa->siggen;
+ void *md;
+ size_t md_len;
+ sess->asym.ml_dsa.sign_params.ctx = siggen->ctx.data;
+ sess->asym.ml_dsa.sign_params.ctx_len = siggen->ctx.length;
+ sess->asym.ml_dsa.sign_params.rnd_32 = siggen->seed.data;
+ sess->asym.ml_dsa.sign_params.rnd_len = siggen->seed.length;
+ if (siggen->mu.length) {
+ md = siggen->mu.data;
+ md_len = siggen->mu.length;
+ sess->asym.ml_dsa.sign_params.msg_is_mu = 1;
+ } else {
+ md = siggen->message.data;
+ md_len = siggen->message.length;
+ sess->asym.ml_dsa.sign_params.msg_is_mu = 0;
+ }
+ rc = imb_ml_dsa_set_privkey(sess->asym.ml_dsa.ctx,
+ siggen->privkey.data, siggen->privkey.length);
+ if (rc == 0)
+ rc = imb_ml_dsa_sign(sess->asym.ml_dsa.ctx,
+ siggen->sign.data, &siggen->sign.length,
+ md, md_len, &sess->asym.ml_dsa.sign_params);
+ }
+ break;
+ case RTE_CRYPTO_ML_DSA_OP_VERIFY:
+ {
+ struct rte_crypto_ml_dsa_sigver_op *sigver = &mldsa->sigver;
+ void *md;
+ size_t md_len;
+ sess->asym.ml_dsa.verify_params.ctx = sigver->ctx.data;
+ sess->asym.ml_dsa.verify_params.ctx_len = sigver->ctx.length;
+ if (sigver->mu.length) {
+ md = sigver->mu.data;
+ md_len = sigver->mu.length;
+ sess->asym.ml_dsa.verify_params.msg_is_mu = 1;
+ } else {
+ md = sigver->message.data;
+ md_len = sigver->message.length;
+ sess->asym.ml_dsa.verify_params.msg_is_mu = 0;
+ }
+ rc = imb_ml_dsa_set_pubkey(sess->asym.ml_dsa.ctx,
+ sigver->pubkey.data, sigver->pubkey.length);
+ if (rc == 0)
+ rc = imb_ml_dsa_verify(sess->asym.ml_dsa.ctx,
+ md, md_len, sigver->sign.data, sigver->sign.length,
+ &sess->asym.ml_dsa.verify_params);
+ }
+ break;
+ default:
+ op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+ break;
+ };
+
+ }
+ break;
+ default:
+ op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+ break;
+ }
+ if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
+ op->status = (rc == 0) ? RTE_CRYPTO_OP_STATUS_SUCCESS :
+ RTE_CRYPTO_OP_STATUS_ERROR;
+#ifdef RTE_LIBRTE_PMD_AESNI_MB_DEBUG
+ if (rc)
+ IPSEC_MB_LOG(ERR, "%s", imb_get_strerror(rc));
+#endif
+}
+#endif
+
+static uint16_t
aesni_mb_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
uint16_t nb_ops)
{
@@ -2456,8 +2777,38 @@ aesni_mb_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
* the IMB_MGR can use that pointer again in next
* get_next calls.
*/
+#if IMB_VERSION(3, 0, 0) <= IMB_VERSION_NUM
+ {
+ struct ipsec_mb_internals *pmd_data =
+ &ipsec_mb_pmds[qp->pmd_type];
+ /* If there is at least one asym session created process
+ * the asym ops here and copy the sym ops to deqd_ops array
+ */
+ if (pmd_data->asym_session_created) {
+ struct rte_crypto_op *tmp_dq[IMB_MAX_BURST_SIZE];
+ uint16_t sym_cnt = 0;
+ nb_submit_ops = rte_ring_dequeue_burst(qp->ingress_queue,
+ (void **)tmp_dq, n, NULL);
+ for (i = 0; i < nb_submit_ops; i++) {
+ if (tmp_dq[i]->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
+ aesni_mb_asym_process(tmp_dq[i]);
+ ops[processed_jobs++] = tmp_dq[i];
+ } else {
+ deqd_ops[sym_cnt++] = tmp_dq[i];
+ }
+ }
+ /* What remains are only symmetric ops. */
+ nb_submit_ops = sym_cnt;
+ } else {
+ /* No asym session created, all ops are sym*/
+ nb_submit_ops = rte_ring_dequeue_burst(qp->ingress_queue,
+ (void **)deqd_ops, n, NULL);
+ }
+ }
+#else
nb_submit_ops = rte_ring_dequeue_burst(qp->ingress_queue,
(void **)deqd_ops, n, NULL);
+#endif
for (i = 0; i < nb_submit_ops; i++) {
job = jobs[i];
op = deqd_ops[i];
@@ -2587,7 +2938,7 @@ verify_sync_dgst(struct rte_crypto_sym_vec *vec,
return k;
}
-uint32_t
+static uint32_t
aesni_mb_process_bulk(struct rte_cryptodev *dev __rte_unused,
struct rte_cryptodev_sym_session *sess, union rte_crypto_sym_ofs sofs,
struct rte_crypto_sym_vec *vec)
@@ -2674,7 +3025,12 @@ struct rte_cryptodev_ops aesni_mb_pmd_ops = {
.sym_session_get_size = ipsec_mb_sym_session_get_size,
.sym_session_configure = ipsec_mb_sym_session_configure,
- .sym_session_clear = ipsec_mb_sym_session_clear
+ .sym_session_clear = ipsec_mb_sym_session_clear,
+#if IMB_VERSION(3, 0, 0) <= IMB_VERSION_NUM
+ .asym_session_get_size = ipsec_mb_sym_session_get_size,
+ .asym_session_configure = ipsec_mb_asym_session_configure,
+ .asym_session_clear = ipsec_mb_asym_session_clear,
+#endif
};
/**
@@ -2800,7 +3156,11 @@ RTE_INIT(ipsec_mb_register_aesni_mb)
RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO |
#if IMB_VERSION(3, 0, 0) > IMB_VERSION_NUM
+ /* removed in 3.0 */
RTE_CRYPTODEV_FF_NON_BYTE_ALIGNED_DATA |
+#else
+ /* added in 3.0 */
+ RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
#endif
RTE_CRYPTODEV_FF_SYM_SESSIONLESS |
RTE_CRYPTODEV_FF_IN_PLACE_SGL |
@@ -2817,5 +3177,9 @@ RTE_INIT(ipsec_mb_register_aesni_mb)
aesni_mb_data->security_ops = &aesni_mb_pmd_sec_ops;
aesni_mb_data->dev_config = aesni_mb_configure_dev;
aesni_mb_data->session_configure = aesni_mb_session_configure;
+#if IMB_VERSION(3, 0, 0) <= IMB_VERSION_NUM
+ aesni_mb_data->asym_session_configure = aesni_mb_asym_session_configure;
+ aesni_mb_data->asym_session_clear = aesni_mb_asym_session_clear;
+#endif
aesni_mb_data->session_priv_size = sizeof(struct aesni_mb_session);
}
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_mb_priv.h b/drivers/crypto/ipsec_mb/pmd_aesni_mb_priv.h
index 9390bad208..99ca4e49e6 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_mb_priv.h
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_mb_priv.h
@@ -28,18 +28,6 @@
#define IMB_AUTH_ZUC256_EIA3 IMB_AUTH_ZUC256_EIA3_BITLEN
#endif
-int
-aesni_mb_session_configure(IMB_MGR * m __rte_unused, void *priv_sess,
- const struct rte_crypto_sym_xform *xform);
-
-uint16_t
-aesni_mb_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
- uint16_t nb_ops);
-
-uint32_t
-aesni_mb_process_bulk(struct rte_cryptodev *dev __rte_unused,
- struct rte_cryptodev_sym_session *sess, union rte_crypto_sym_ofs sofs,
- struct rte_crypto_sym_vec *vec);
static const struct rte_cryptodev_capabilities aesni_mb_capabilities[] = {
{ /* MD5 HMAC */
@@ -1108,6 +1096,60 @@ static const struct rte_cryptodev_capabilities aesni_mb_capabilities[] = {
}, }
}, }
},
+ {
+ /* ML-KEM */
+ .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+ .asym = {
+ .xform_capa = {
+ .xform_type = RTE_CRYPTO_ASYM_XFORM_ML_KEM,
+ .op_types =
+ ((1 << RTE_CRYPTO_ML_KEM_OP_KEYGEN) |
+ (1 << RTE_CRYPTO_ML_KEM_OP_ENCAP) |
+ (1 << RTE_CRYPTO_ML_KEM_OP_DECAP)),
+ .mlkem_capa = {
+ [RTE_CRYPTO_ML_KEM_OP_KEYGEN] =
+ (1 << RTE_CRYPTO_ML_KEM_512) |
+ (1 << RTE_CRYPTO_ML_KEM_768) |
+ (1 << RTE_CRYPTO_ML_KEM_1024),
+ [RTE_CRYPTO_ML_KEM_OP_ENCAP] =
+ (1 << RTE_CRYPTO_ML_KEM_512) |
+ (1 << RTE_CRYPTO_ML_KEM_768) |
+ (1 << RTE_CRYPTO_ML_KEM_1024),
+ [RTE_CRYPTO_ML_KEM_OP_DECAP] =
+ (1 << RTE_CRYPTO_ML_KEM_512) |
+ (1 << RTE_CRYPTO_ML_KEM_768) |
+ (1 << RTE_CRYPTO_ML_KEM_1024)
+ }
+ }
+ }
+ },
+ {
+ /* ML-DSA */
+ .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+ .asym = {
+ .xform_capa = {
+ .xform_type = RTE_CRYPTO_ASYM_XFORM_ML_DSA,
+ .op_types =
+ ((1 << RTE_CRYPTO_ML_DSA_OP_SIGN) |
+ (1 << RTE_CRYPTO_ML_DSA_OP_KEYGEN) |
+ (1 << RTE_CRYPTO_ML_DSA_OP_VERIFY)),
+ .mldsa_capa = {
+ [RTE_CRYPTO_ML_DSA_OP_KEYGEN] =
+ (1 << RTE_CRYPTO_ML_DSA_44) |
+ (1 << RTE_CRYPTO_ML_DSA_65) |
+ (1 << RTE_CRYPTO_ML_DSA_87),
+ [RTE_CRYPTO_ML_DSA_OP_SIGN] =
+ (1 << RTE_CRYPTO_ML_DSA_44) |
+ (1 << RTE_CRYPTO_ML_DSA_65) |
+ (1 << RTE_CRYPTO_ML_DSA_87),
+ [RTE_CRYPTO_ML_DSA_OP_VERIFY] =
+ (1 << RTE_CRYPTO_ML_DSA_44) |
+ (1 << RTE_CRYPTO_ML_DSA_65) |
+ (1 << RTE_CRYPTO_ML_DSA_87)
+ }
+ }
+ }
+ },
#endif
RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
};
@@ -1339,6 +1381,26 @@ struct __rte_cache_aligned aesni_mb_session {
uint16_t req_digest_len;
} auth;
+#if IMB_VERSION(3, 0, 0) <= IMB_VERSION_NUM
+ struct {
+ enum rte_crypto_asym_xform_type xform_type;
+ union {
+ struct {
+ IMB_ML_KEM *ctx;
+ IMB_ML_KEM_ALG alg;
+ IMB_ML_KEM_KEYGEN_PARAMS keygen_params;
+ IMB_ML_KEM_ENCAP_PARAMS encap_params;
+ } ml_kem;
+ struct {
+ IMB_ML_DSA *ctx;
+ IMB_ML_DSA_ALG alg;
+ IMB_ML_DSA_KEYGEN_PARAMS keygen_params;
+ IMB_ML_DSA_SIGN_PARAMS sign_params;
+ IMB_ML_DSA_VERIFY_PARAMS verify_params;
+ } ml_dsa;
+ };
+ } asym;
+ #endif
};
typedef void (*hash_one_block_t)(const void *data, void *digest);
--
2.52.0
next prev parent reply other threads:[~2026-10-02 9:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-02 9:56 [PATCH 0/4] crypto/ipsec_mb: add support for IPsecMB 3.0 Radu Nicolau
2026-10-02 9:56 ` [PATCH 1/4] " Radu Nicolau
2026-10-06 12:06 ` Ji, Kai
2026-10-02 9:56 ` [PATCH 2/4] crypto/ipsec_mb: add support for 256-NxA4/5/6 algorithms Radu Nicolau
2026-10-02 9:56 ` Radu Nicolau [this message]
2026-10-02 9:56 ` [PATCH 4/4] test/crypto: add asym test suite for AESNI_MB Radu Nicolau
2026-10-06 13:08 ` [PATCH 0/4] crypto/ipsec_mb: add support for IPsecMB 3.0 Ji, Kai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261002095652.1540556-4-radu.nicolau@intel.com \
--to=radu.nicolau@intel.com \
--cc=dev@dpdk.org \
--cc=kai.ji@intel.com \
--cc=pablo.de.lara.guarch@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox