DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
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


  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