DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH v1 1/3] cryptodev: add EDDSA asymmetric crypto algorithm
@ 2023-11-29 16:10 Gowrishankar Muthukrishnan
  2023-11-29 16:10 ` [PATCH v1 2/3] crypto/openssl: add EDDSA support Gowrishankar Muthukrishnan
                   ` (3 more replies)
  0 siblings, 4 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-29 16:10 UTC (permalink / raw)
  To: dev; +Cc: anoobj, Akhil Goyal, Fan Zhang, Kai Ji, Gowrishankar Muthukrishnan

Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
https://datatracker.ietf.org/doc/html/rfc8032

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
 lib/cryptodev/rte_crypto_asym.h            | 51 +++++++++++++++++++++-
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index f411d4bab7..3073753911 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -130,6 +130,7 @@ ECDSA                   =
 ECPM                    =
 ECDH                    =
 SM2                     =
+EDDSA                   =
 
 ;
 ; Supported Operating systems of a default crypto driver.
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 2b513bbf82..dd636ba5ef 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -927,7 +927,7 @@ Asymmetric Cryptography
 The cryptodev library currently provides support for the following asymmetric
 Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman and
 Elliptic Curve Diffie-Hellman public and/or private key generation and shared
-secret compute, DSA Signature generation and verification.
+secret compute, DSA and EdDSA Signature generation and verification.
 
 Session and Session Management
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index 39d3da3952..7813d28b7a 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -65,9 +65,22 @@ enum rte_crypto_curve_id {
 	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
 	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
 	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
+	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
+	RTE_CRYPTO_EC_GROUP_ED448     = 30,
 	RTE_CRYPTO_EC_GROUP_SM2       = 41,
 };
 
+/**
+ * List of Edwards curve instances as per RFC 8032 (Section 5).
+ */
+enum rte_crypto_edward_instance {
+	RTE_CRYPTO_EDCURVE_25519,
+	RTE_CRYPTO_EDCURVE_25519CTX,
+	RTE_CRYPTO_EDCURVE_25519PH,
+	RTE_CRYPTO_EDCURVE_448,
+	RTE_CRYPTO_EDCURVE_448PH
+};
+
 /**
  * Asymmetric crypto transformation types.
  * Each xform type maps to one asymmetric algorithm
@@ -108,6 +121,10 @@ enum rte_crypto_asym_xform_type {
 	/**< Elliptic Curve Digital Signature Algorithm
 	 * Perform Signature Generation and Verification.
 	 */
+	RTE_CRYPTO_ASYM_XFORM_EDDSA,
+	/**< Edwards Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_ECDH,
 	/**< Elliptic Curve Diffie Hellman */
 	RTE_CRYPTO_ASYM_XFORM_ECPM,
@@ -376,7 +393,13 @@ struct rte_crypto_ec_xform {
 	rte_crypto_uint pkey;
 	/**< Private key */
 
-	struct rte_crypto_ec_point q;
+	union {
+		struct rte_crypto_ec_point q;
+		/**< Elliptic curve point */
+
+		rte_crypto_uint qcomp;
+		/**< Elliptic curve point compressed */
+	};
 	/**< Public key */
 };
 
@@ -585,6 +608,31 @@ struct rte_crypto_ecdsa_op_param {
 	 */
 };
 
+/**
+ * EDDSA operation params
+ */
+struct rte_crypto_eddsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param message;
+	/**< Input message digest to be signed or verified */
+
+	rte_crypto_param context;
+	/**< Context value for the sign op.
+	 *   Must not be empty for Ed25519ctx instance.
+	 */
+
+	enum rte_crypto_edward_instance instance;
+	/**< Type of Edwards curve. */
+
+	rte_crypto_uint sign;
+	/**< Edward curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Structure for EC point multiplication operation param
  */
@@ -718,6 +766,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_ecdh_op_param ecdh;
 		struct rte_crypto_dsa_op_param dsa;
 		struct rte_crypto_ecdsa_op_param ecdsa;
+		struct rte_crypto_eddsa_op_param eddsa;
 		struct rte_crypto_ecpm_op_param ecpm;
 		struct rte_crypto_sm2_op_param sm2;
 	};
-- 
2.25.1


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v1 2/3] crypto/openssl: add EDDSA support
  2023-11-29 16:10 [PATCH v1 1/3] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
@ 2023-11-29 16:10 ` Gowrishankar Muthukrishnan
  2023-11-29 16:10 ` [PATCH v1 3/3] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-29 16:10 UTC (permalink / raw)
  To: dev; +Cc: anoobj, Akhil Goyal, Fan Zhang, Kai Ji, Gowrishankar Muthukrishnan

Add EDDSA support in OpenSSL PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
For openssl library support, refer:
https://github.com/openssl/openssl/commit/4f8b7c2319523f8e83b8b2fa31127832fa092552
---
 drivers/crypto/openssl/openssl_pmd_private.h |   6 +
 drivers/crypto/openssl/rte_openssl_pmd.c     | 165 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c |  80 +++++++++
 3 files changed, 251 insertions(+)

diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index 334912d335..7061a1b85b 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -212,6 +212,12 @@ struct openssl_asym_session {
 			OSSL_PARAM * params;
 #endif
 		} sm2;
+		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			OSSL_PARAM *params;
+#endif
+		} eddsa;
 	} u;
 } __rte_cache_aligned;
 /** Set and validate OPENSSL crypto session parameters */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index e8cb09defc..61c1f95202 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2890,6 +2890,155 @@ process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 	return ret;
 }
 
+static int
+process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	static const char * const instance[] = {"Ed25519", "Ed25519ctx", "Ed25519ph",
+						"Ed448", "Ed448ph"};
+	EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
+	const uint8_t curve_id = sess->u.eddsa.curve_id;
+	struct rte_crypto_asym_op *op = cop->asym;
+	OSSL_PARAM *params = sess->u.eddsa.params;
+	OSSL_PARAM_BLD *iparam_bld = NULL;
+	OSSL_PARAM *iparams = NULL;
+	uint8_t signbuf[128] = {0};
+	EVP_MD_CTX *md_ctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	size_t signlen;
+	int ret = -1;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	iparam_bld = OSSL_PARAM_BLD_new();
+	if (!iparam_bld)
+		goto err_eddsa;
+
+	OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-string",
+		op->eddsa.context.data, op->eddsa.context.length);
+
+	OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
+		instance[op->eddsa.instance], strlen(instance[op->eddsa.instance]));
+
+	iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
+	if (!iparams)
+		goto err_eddsa;
+
+	switch (op->eddsa.op_type) {
+	case RTE_CRYPTO_ASYM_OP_SIGN:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			if (!EVP_DigestSign(md_ctx, NULL, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			if (signlen > RTE_DIM(signbuf))
+				goto err_eddsa;
+
+			if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
+			op->eddsa.sign.length = signlen;
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_VERIFY:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			signlen = op->eddsa.sign.length;
+			memcpy(&signbuf[0], op->eddsa.sign.data, op->eddsa.sign.length);
+
+			ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op->eddsa.message.data,
+					op->eddsa.message.length);
+			if (ret == 0)
+				goto err_eddsa;
+		}
+		break;
+	default:
+		/* allow ops with invalid args to be pushed to
+		 * completion queue
+		 */
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		goto err_eddsa;
+	}
+
+	ret = 0;
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+err_eddsa:
+	OSSL_PARAM_BLD_free(iparam_bld);
+
+	if (sctx)
+		EVP_PKEY_CTX_free(sctx);
+
+	if (cctx)
+		EVP_PKEY_CTX_free(cctx);
+
+	if (pkey)
+		EVP_PKEY_free(pkey);
+
+	return ret;
+}
 #else
 static int
 process_openssl_rsa_op(struct rte_crypto_op *cop,
@@ -2998,6 +3147,15 @@ process_openssl_sm2_op(struct rte_crypto_op *cop,
 	RTE_SET_USED(sess);
 	return -ENOTSUP;
 }
+
+static int
+process_openssl_eddsa_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
 #endif
 
 static int
@@ -3053,6 +3211,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 		retval = process_openssl_sm2_op_evp(op, sess);
 #else
 		retval = process_openssl_sm2_op(op, sess);
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_eddsa_op_evp(op, sess);
+#else
+		retval = process_openssl_eddsa_op(op, sess);
 #endif
 		break;
 	default:
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index b16baaa08f..36c4c68da9 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -610,6 +610,20 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		}
 		}
 	},
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types =
+				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
+				 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+			}
+		}
+		}
+	},
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1413,6 +1427,66 @@ static int openssl_set_asym_session_parameters(
 #else
 		OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL Version < 3.0");
 		return -ENOTSUP;
+#endif
+	}
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		OSSL_PARAM_BLD *param_bld = NULL;
+		OSSL_PARAM *params = NULL;
+		int ret = -1;
+
+		asym_session->u.eddsa.curve_id = xform->ec.curve_id;
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+			  OSSL_PKEY_PARAM_GROUP_NAME, "ED25519", sizeof("ED25519"));
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PRIV_KEY,
+				xform->ec.pkey.data, xform->ec.pkey.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
+				xform->ec.qcomp.data, xform->ec.qcomp.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		params = OSSL_PARAM_BLD_to_param(param_bld);
+		if (!params) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		asym_session->u.eddsa.params = params;
+		OSSL_PARAM_BLD_free(param_bld);
+
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		break;
+err_eddsa:
+		if (param_bld)
+			OSSL_PARAM_BLD_free(param_bld);
+
+		if (asym_session->u.eddsa.params)
+			OSSL_PARAM_free(asym_session->u.eddsa.params);
+
+		return -1;
+#else
+		OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL Version < 3.0");
+		return -ENOTSUP;
 #endif
 	}
 	default:
@@ -1511,6 +1585,12 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 		OSSL_PARAM_free(sess->u.sm2.params);
 #endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		OSSL_PARAM_free(sess->u.eddsa.params);
+#endif
+		break;
 	default:
 		break;
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v1 3/3] test/crypto: add asymmetric EDDSA test cases
  2023-11-29 16:10 [PATCH v1 1/3] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2023-11-29 16:10 ` [PATCH v1 2/3] crypto/openssl: add EDDSA support Gowrishankar Muthukrishnan
@ 2023-11-29 16:10 ` Gowrishankar Muthukrishnan
  2024-09-05 13:36 ` [PATCH v2 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-09-05 13:39 ` Gowrishankar Muthukrishnan
  3 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-29 16:10 UTC (permalink / raw)
  To: dev; +Cc: anoobj, Akhil Goyal, Fan Zhang, Kai Ji, Gowrishankar Muthukrishnan

Add test cases to validate EDDSA sign and verify ops,
as per RFC 8032.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test/test_cryptodev_asym.c               | 339 +++++++++++++++++++
 app/test/test_cryptodev_eddsa_test_vectors.h | 330 ++++++++++++++++++
 2 files changed, 669 insertions(+)
 create mode 100644 app/test/test_cryptodev_eddsa_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index 17daf734e8..93ce75b7c9 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -20,6 +20,7 @@
 #include "test_cryptodev_ecdh_test_vectors.h"
 #include "test_cryptodev_ecdsa_test_vectors.h"
 #include "test_cryptodev_ecpm_test_vectors.h"
+#include "test_cryptodev_eddsa_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_sm2_test_vectors.h"
@@ -3171,6 +3172,343 @@ test_sm2_dec(void)
 	return status;
 };
 
+static int
+test_eddsa_sign(enum rte_crypto_edward_instance instance)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct crypto_testsuite_eddsa_params input_params;
+	struct rte_cryptodev_asym_capability_idx idx;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	switch (instance) {
+	case RTE_CRYPTO_EDCURVE_25519:
+		input_params = eddsa_param_ed25519;
+		break;
+	case RTE_CRYPTO_EDCURVE_25519CTX:
+		input_params = eddsa_param_ed25519ctx;
+		ctx = true;
+		break;
+	case RTE_CRYPTO_EDCURVE_25519PH:
+		input_params = eddsa_param_ed25519ph;
+		break;
+	case RTE_CRYPTO_EDCURVE_448:
+		input_params = eddsa_param_ed448;
+		break;
+	case RTE_CRYPTO_EDCURVE_448PH:
+		input_params = eddsa_param_ed448ph;
+		break;
+	default:
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Unsupported curve id\n");
+		status = TEST_SKIPPED;
+		goto exit;
+	}
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return -ENOTSUP;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params.curve;
+	xform.ec.pkey.data = input_params.pkey.data;
+	xform.ec.pkey.length = input_params.pkey.length;
+	xform.ec.qcomp.data = input_params.pubkey.data;
+	xform.ec.qcomp.length = input_params.pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	asym_op->eddsa.instance = input_params.instance;
+	asym_op->eddsa.message.data = input_params.message.data;
+	asym_op->eddsa.message.length = input_params.message.length;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params.context.data;
+		asym_op->eddsa.context.length = input_params.context.length;
+	}
+
+	/* Init out buf */
+	asym_op->eddsa.sign.data = output_buf_r;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "sign:",
+			asym_op->eddsa.sign.data, asym_op->eddsa.sign.length);
+
+	/* Verify sign (by comparison). */
+	if (memcmp(input_params.sign.data, asym_op->eddsa.sign.data,
+			   asym_op->eddsa.sign.length) != 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"EDDSA sign failed.\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_verify(enum rte_crypto_edward_instance instance)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct crypto_testsuite_eddsa_params input_params;
+	struct rte_cryptodev_asym_capability_idx idx;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	switch (instance) {
+	case RTE_CRYPTO_EDCURVE_25519:
+		input_params = eddsa_param_ed25519;
+		break;
+	case RTE_CRYPTO_EDCURVE_25519CTX:
+		input_params = eddsa_param_ed25519ctx;
+		ctx = true;
+		break;
+	case RTE_CRYPTO_EDCURVE_25519PH:
+		input_params = eddsa_param_ed25519ph;
+		break;
+	case RTE_CRYPTO_EDCURVE_448:
+		input_params = eddsa_param_ed448;
+		break;
+	case RTE_CRYPTO_EDCURVE_448PH:
+		input_params = eddsa_param_ed448ph;
+		break;
+	default:
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Unsupported curve id\n");
+		status = TEST_SKIPPED;
+		goto exit;
+	}
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return -ENOTSUP;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params.curve;
+	xform.ec.pkey.data = input_params.pkey.data;
+	xform.ec.pkey.length = input_params.pkey.length;
+	xform.ec.qcomp.data = input_params.pubkey.data;
+	xform.ec.qcomp.length = input_params.pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	asym_op->eddsa.instance = input_params.instance;
+	asym_op->eddsa.message.data = input_params.message.data;
+	asym_op->eddsa.message.length = input_params.message.length;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params.context.data;
+		asym_op->eddsa.context.length = input_params.context.length;
+	}
+
+	/* Init out buf */
+	asym_op->eddsa.sign.data = input_params.sign.data;
+	asym_op->eddsa.sign.length = input_params.sign.length;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "sign:",
+			asym_op->eddsa.sign.data, asym_op->eddsa.sign.length);
+
+	/* Verify sign (by comparison). */
+	if (memcmp(input_params.sign.data, asym_op->eddsa.sign.data,
+			   asym_op->eddsa.sign.length) != 0) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"EDDSA sign failed.\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_sign_verify_all_curve(void)
+{
+	static const char * const edcurve[] = {"ed25519", "ed25519ctx", "ed25519ph",
+					       "ed448", "ed448ph"};
+	int status, overall_status = TEST_SUCCESS;
+	enum rte_crypto_edward_instance ins;
+	int test_index = 0;
+	const char *msg;
+
+	for (ins = RTE_CRYPTO_EDCURVE_25519; ins <= RTE_CRYPTO_EDCURVE_448PH; ins++) {
+		status = test_eddsa_sign(ins);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Sign Curve %s  %s\n",
+		       test_index ++, edcurve[ins], msg);
+	}
+
+	for (ins = RTE_CRYPTO_EDCURVE_25519; ins <= RTE_CRYPTO_EDCURVE_448PH; ins++) {
+		status = test_eddsa_verify(ins);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Verify Curve %s  %s\n",
+		       test_index ++, edcurve[ins], msg);
+	}
+
+	return overall_status;
+}
+
 static int send_one(void)
 {
 	int ticks = 0;
@@ -3513,6 +3851,7 @@ static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 			"Modex Group 18 test",
 			ut_setup_asym, ut_teardown_asym,
 			modular_exponentiation, &modex_group_test_cases[5]),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_eddsa_test_vectors.h b/app/test/test_cryptodev_eddsa_test_vectors.h
new file mode 100644
index 0000000000..11b17e6c62
--- /dev/null
+++ b/app/test/test_cryptodev_eddsa_test_vectors.h
@@ -0,0 +1,330 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell.
+ */
+
+#ifndef __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+struct crypto_testsuite_eddsa_params {
+	rte_crypto_param pubkey;
+	rte_crypto_param pkey;
+	rte_crypto_param sign;
+	rte_crypto_param message;
+	rte_crypto_param context;
+	enum rte_crypto_curve_id curve;
+	enum rte_crypto_edward_instance instance;
+};
+
+static uint8_t ed25519_pkey[] = {
+	0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+	0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+	0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+	0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+};
+
+static uint8_t ed25519_pubkey[] = {
+	0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+	0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+	0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+	0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+};
+
+static uint8_t ed25519_sign[] = {
+	0xdc, 0x2a, 0x44, 0x59, 0xe7, 0x36, 0x96, 0x33,
+	0xa5, 0x2b, 0x1b, 0xf2, 0x77, 0x83, 0x9a, 0x00,
+	0x20, 0x10, 0x09, 0xa3, 0xef, 0xbf, 0x3e, 0xcb,
+	0x69, 0xbe, 0xa2, 0x18, 0x6c, 0x26, 0xb5, 0x89,
+	0x09, 0x35, 0x1f, 0xc9, 0xac, 0x90, 0xb3, 0xec,
+	0xfd, 0xfb, 0xc7, 0xc6, 0x64, 0x31, 0xe0, 0x30,
+	0x3d, 0xca, 0x17, 0x9c, 0x13, 0x8a, 0xc1, 0x7a,
+	0xd9, 0xbe, 0xf1, 0x17, 0x73, 0x31, 0xa7, 0x04
+};
+
+static uint8_t ed25519_message[] = {
+	0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
+	0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+	0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+	0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
+	0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
+	0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+	0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
+	0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
+};
+
+/** EDDSA ed25519 curve test params (RFC 8032) */
+struct crypto_testsuite_eddsa_params eddsa_param_ed25519 = {
+	.pkey = {
+		.data = ed25519_pkey,
+		.length = sizeof(ed25519_pkey),
+	},
+	.pubkey = {
+		.data = ed25519_pubkey,
+		.length = sizeof(ed25519_pubkey),
+	},
+	.sign = {
+		.data = ed25519_sign,
+		.length = sizeof(ed25519_sign),
+	},
+	.message = {
+		.data = ed25519_message,
+		.length = sizeof(ed25519_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+};
+
+static uint8_t ed25519ctx_pkey[] = {
+	0x03, 0x05, 0x33, 0x4e, 0x38, 0x1a, 0xf7, 0x8f,
+	0x14, 0x1c, 0xb6, 0x66, 0xf6, 0x19, 0x9f, 0x57,
+	0xbc, 0x34, 0x95, 0x33, 0x5a, 0x25, 0x6a, 0x95,
+	0xbd, 0x2a, 0x55, 0xbf, 0x54, 0x66, 0x63, 0xf6
+};
+
+static uint8_t ed25519ctx_pubkey[] = {
+	0xdf, 0xc9, 0x42, 0x5e, 0x4f, 0x96, 0x8f, 0x7f,
+	0x0c, 0x29, 0xf0, 0x25, 0x9c, 0xf5, 0xf9, 0xae,
+	0xd6, 0x85, 0x1c, 0x2b, 0xb4, 0xad, 0x8b, 0xfb,
+	0x86, 0x0c, 0xfe, 0xe0, 0xab, 0x24, 0x82, 0x92
+};
+
+static uint8_t ed25519ctx_sign[] = {
+	0x55, 0xa4, 0xcc, 0x2f, 0x70, 0xa5, 0x4e, 0x04,
+	0x28, 0x8c, 0x5f, 0x4c, 0xd1, 0xe4, 0x5a, 0x7b,
+	0xb5, 0x20, 0xb3, 0x62, 0x92, 0x91, 0x18, 0x76,
+	0xca, 0xda, 0x73, 0x23, 0x19, 0x8d, 0xd8, 0x7a,
+	0x8b, 0x36, 0x95, 0x0b, 0x95, 0x13, 0x00, 0x22,
+	0x90, 0x7a, 0x7f, 0xb7, 0xc4, 0xe9, 0xb2, 0xd5,
+	0xf6, 0xcc, 0xa6, 0x85, 0xa5, 0x87, 0xb4, 0xb2,
+	0x1f, 0x4b, 0x88, 0x8e, 0x4e, 0x7e, 0xdb, 0x0d
+};
+
+static uint8_t ed25519ctx_message[] = {
+	0xf7, 0x26, 0x93, 0x6d, 0x19, 0xc8, 0x00, 0x49,
+	0x4e, 0x3f, 0xda, 0xff, 0x20, 0xb2, 0x76, 0xa8
+};
+
+static uint8_t ed25519ctx_context[] = {
+	0x66, 0x6f, 0x6f
+};
+
+/** EDDSA ed25519ctx curve test params (RFC 8032) */
+struct crypto_testsuite_eddsa_params eddsa_param_ed25519ctx = {
+	.pkey = {
+		.data = ed25519ctx_pkey,
+		.length = sizeof(ed25519ctx_pkey),
+	},
+	.pubkey = {
+		.data = ed25519ctx_pubkey,
+		.length = sizeof(ed25519ctx_pubkey),
+	},
+	.sign = {
+		.data = ed25519ctx_sign,
+		.length = sizeof(ed25519ctx_sign),
+	},
+	.message = {
+		.data = ed25519ctx_message,
+		.length = sizeof(ed25519ctx_message),
+	},
+	.context = {
+		.data = ed25519ctx_context,
+		.length = sizeof(ed25519ctx_context),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519CTX
+};
+
+static uint8_t ed25519ph_pkey[] = {
+	0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+	0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+	0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+	0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+};
+
+static uint8_t ed25519ph_pubkey[] = {
+	0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+	0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+	0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+	0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+};
+
+static uint8_t ed25519ph_sign[] = {
+	0x98, 0xa7, 0x02, 0x22, 0xf0, 0xb8, 0x12, 0x1a,
+	0xa9, 0xd3, 0x0f, 0x81, 0x3d, 0x68, 0x3f, 0x80,
+	0x9e, 0x46, 0x2b, 0x46, 0x9c, 0x7f, 0xf8, 0x76,
+	0x39, 0x49, 0x9b, 0xb9, 0x4e, 0x6d, 0xae, 0x41,
+	0x31, 0xf8, 0x50, 0x42, 0x46, 0x3c, 0x2a, 0x35,
+	0x5a, 0x20, 0x03, 0xd0, 0x62, 0xad, 0xf5, 0xaa,
+	0xa1, 0x0b, 0x8c, 0x61, 0xe6, 0x36, 0x06, 0x2a,
+	0xaa, 0xd1, 0x1c, 0x2a, 0x26, 0x08, 0x34, 0x06
+};
+
+static uint8_t ed25519ph_message[] = {
+	0x61, 0x62, 0x63
+};
+
+/** EDDSA ed25519ph curve test params (RFC 8032) */
+struct crypto_testsuite_eddsa_params eddsa_param_ed25519ph = {
+	.pkey = {
+		.data = ed25519ph_pkey,
+		.length = sizeof(ed25519ph_pkey),
+	},
+	.pubkey = {
+		.data = ed25519ph_pubkey,
+		.length = sizeof(ed25519ph_pubkey),
+	},
+	.sign = {
+		.data = ed25519ph_sign,
+		.length = sizeof(ed25519ph_sign),
+	},
+	.message = {
+		.data = ed25519ph_message,
+		.length = sizeof(ed25519ph_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519PH
+};
+
+static uint8_t ed448_pkey[] = {
+	0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+	0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+	0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+	0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+	0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+	0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+	0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+	0x01
+};
+
+static uint8_t ed448_pubkey[] = {
+	0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+	0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+	0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+	0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+	0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+	0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+	0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+	0x00
+};
+
+static uint8_t ed448_sign[] = {
+	0x55, 0x4b, 0xc2, 0x48, 0x08, 0x60, 0xb4, 0x9e,
+	0xab, 0x85, 0x32, 0xd2, 0xa5, 0x33, 0xb7, 0xd5,
+	0x78, 0xef, 0x47, 0x3e, 0xeb, 0x58, 0xc9, 0x8b,
+	0xb2, 0xd0, 0xe1, 0xce, 0x48, 0x8a, 0x98, 0xb1,
+	0x8d, 0xfd, 0xe9, 0xb9, 0xb9, 0x07, 0x75, 0xe6,
+	0x7f, 0x47, 0xd4, 0xa1, 0xc3, 0x48, 0x20, 0x58,
+	0xef, 0xc9, 0xf4, 0x0d, 0x2c, 0xa0, 0x33, 0xa0,
+	0x80,
+	0x1b, 0x63, 0xd4, 0x5b, 0x3b, 0x72, 0x2e, 0xf5,
+	0x52, 0xba, 0xd3, 0xb4, 0xcc, 0xb6, 0x67, 0xda,
+	0x35, 0x01, 0x92, 0xb6, 0x1c, 0x50, 0x8c, 0xf7,
+	0xb6, 0xb5, 0xad, 0xad, 0xc2, 0xc8, 0xd9, 0xa4,
+	0x46, 0xef, 0x00, 0x3f, 0xb0, 0x5c, 0xba, 0x5f,
+	0x30, 0xe8, 0x8e, 0x36, 0xec, 0x27, 0x03, 0xb3,
+	0x49, 0xca, 0x22, 0x9c, 0x26, 0x70, 0x83, 0x39,
+	0x00
+};
+
+static uint8_t ed448_message[] = {
+	0xbd, 0x0f, 0x6a, 0x37, 0x47, 0xcd, 0x56, 0x1b,
+	0xdd, 0xdf, 0x46, 0x40, 0xa3, 0x32, 0x46, 0x1a,
+	0x4a, 0x30, 0xa1, 0x2a, 0x43, 0x4c, 0xd0, 0xbf,
+	0x40, 0xd7, 0x66, 0xd9, 0xc6, 0xd4, 0x58, 0xe5,
+	0x51, 0x22, 0x04, 0xa3, 0x0c, 0x17, 0xd1, 0xf5,
+	0x0b, 0x50, 0x79, 0x63, 0x1f, 0x64, 0xeb, 0x31,
+	0x12, 0x18, 0x2d, 0xa3, 0x00, 0x58, 0x35, 0x46,
+	0x11, 0x13, 0x71, 0x8d, 0x1a, 0x5e, 0xf9, 0x44
+};
+
+/** EDDSA ed448 curve test params (RFC 8032) */
+struct crypto_testsuite_eddsa_params eddsa_param_ed448 = {
+	.pkey = {
+		.data = ed448_pkey,
+		.length = sizeof(ed448_pkey),
+	},
+	.pubkey = {
+		.data = ed448_pubkey,
+		.length = sizeof(ed448_pubkey),
+	},
+	.sign = {
+		.data = ed448_sign,
+		.length = sizeof(ed448_sign),
+	},
+	.message = {
+		.data = ed448_message,
+		.length = sizeof(ed448_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+};
+
+static uint8_t ed448ph_pkey[] = {
+	0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+	0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+	0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+	0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42,
+	0xef, 0x78, 0x22, 0xe0, 0xd5, 0x10, 0x41, 0x27,
+	0xdc, 0x05, 0xd6, 0xdb, 0xef, 0xde, 0x69, 0xe3,
+	0xab, 0x2c, 0xec, 0x7c, 0x86, 0x7c, 0x6e, 0x2c,
+	0x49
+};
+
+static uint8_t ed448ph_pubkey[] = {
+	0x25, 0x9b, 0x71, 0xc1, 0x9f, 0x83, 0xef, 0x77,
+	0xa7, 0xab, 0xd2, 0x65, 0x24, 0xcb, 0xdb, 0x31,
+	0x61, 0xb5, 0x90, 0xa4, 0x8f, 0x7d, 0x17, 0xde,
+	0x3e, 0xe0, 0xba, 0x9c, 0x52, 0xbe, 0xb7, 0x43,
+	0xc0, 0x94, 0x28, 0xa1, 0x31, 0xd6, 0xb1, 0xb5,
+	0x73, 0x03, 0xd9, 0x0d, 0x81, 0x32, 0xc2, 0x76,
+	0xd5, 0xed, 0x3d, 0x5d, 0x01, 0xc0, 0xf5, 0x38,
+	0x80
+};
+
+static uint8_t ed448ph_sign[] = {
+	0x82, 0x2f, 0x69, 0x01, 0xf7, 0x48, 0x0f, 0x3d,
+	0x5f, 0x56, 0x2c, 0x59, 0x29, 0x94, 0xd9, 0x69,
+	0x36, 0x02, 0x87, 0x56, 0x14, 0x48, 0x32, 0x56,
+	0x50, 0x56, 0x00, 0xbb, 0xc2, 0x81, 0xae, 0x38,
+	0x1f, 0x54, 0xd6, 0xbc, 0xe2, 0xea, 0x91, 0x15,
+	0x74, 0x93, 0x2f, 0x52, 0xa4, 0xe6, 0xca, 0xdd,
+	0x78, 0x76, 0x93, 0x75, 0xec, 0x3f, 0xfd, 0x1b,
+	0x80,
+	0x1a, 0x0d, 0x9b, 0x3f, 0x40, 0x30, 0xcd, 0x43,
+	0x39, 0x64, 0xb6, 0x45, 0x7e, 0xa3, 0x94, 0x76,
+	0x51, 0x12, 0x14, 0xf9, 0x74, 0x69, 0xb5, 0x7d,
+	0xd3, 0x2d, 0xbc, 0x56, 0x0a, 0x9a, 0x94, 0xd0,
+	0x0b, 0xff, 0x07, 0x62, 0x04, 0x64, 0xa3, 0xad,
+	0x20, 0x3d, 0xf7, 0xdc, 0x7c, 0xe3, 0x60, 0xc3,
+	0xcd, 0x36, 0x96, 0xd9, 0xd9, 0xfa, 0xb9, 0x0f,
+	0x00
+};
+
+static uint8_t ed448ph_message[] = {
+	0x61, 0x62, 0x63
+};
+
+/** EDDSA ed448ph curve test params (RFC 8032) */
+struct crypto_testsuite_eddsa_params eddsa_param_ed448ph = {
+	.pkey = {
+		.data = ed448ph_pkey,
+		.length = sizeof(ed448ph_pkey),
+	},
+	.pubkey = {
+		.data = ed448ph_pubkey,
+		.length = sizeof(ed448ph_pubkey),
+	},
+	.sign = {
+		.data = ed448ph_sign,
+		.length = sizeof(ed448ph_sign),
+	},
+	.message = {
+		.data = ed448ph_message,
+		.length = sizeof(ed448ph_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448PH
+};
+
+#endif /* __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__ */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v2 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2023-11-29 16:10 [PATCH v1 1/3] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2023-11-29 16:10 ` [PATCH v1 2/3] crypto/openssl: add EDDSA support Gowrishankar Muthukrishnan
  2023-11-29 16:10 ` [PATCH v1 3/3] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
@ 2024-09-05 13:36 ` Gowrishankar Muthukrishnan
  2024-09-05 13:39 ` Gowrishankar Muthukrishnan
  3 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-05 13:36 UTC (permalink / raw)
  To: dev, bruce.richardson, ciara.power, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal
  Cc: Anoob Joseph, Gowrishankar Muthukrishnan

Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
https://datatracker.ietf.org/doc/html/rfc8032

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
 lib/cryptodev/rte_crypto_asym.h            | 47 ++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index f411d4bab7..3073753911 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -130,6 +130,7 @@ ECDSA                   =
 ECPM                    =
 ECDH                    =
 SM2                     =
+EDDSA                   =
 
 ;
 ; Supported Operating systems of a default crypto driver.
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 2b513bbf82..dd636ba5ef 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -927,7 +927,7 @@ Asymmetric Cryptography
 The cryptodev library currently provides support for the following asymmetric
 Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman and
 Elliptic Curve Diffie-Hellman public and/or private key generation and shared
-secret compute, DSA Signature generation and verification.
+secret compute, DSA and EdDSA Signature generation and verification.
 
 Session and Session Management
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index 39d3da3952..11bb885d64 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -49,6 +49,10 @@ rte_crypto_asym_op_strings[];
  * and if the flag is not set, shared secret will be padded to the left with
  * zeros to the size of the underlying algorithm (default)
  */
+#define RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED		RTE_BIT32(2)
+/**<
+ * Flag to denote public key will be returned in compressed form
+ */
 
 /**
  * List of elliptic curves. This enum aligns with
@@ -65,9 +69,22 @@ enum rte_crypto_curve_id {
 	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
 	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
 	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
+	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
+	RTE_CRYPTO_EC_GROUP_ED448     = 30,
 	RTE_CRYPTO_EC_GROUP_SM2       = 41,
 };
 
+/**
+ * List of Edwards curve instances as per RFC 8032 (Section 5).
+ */
+enum rte_crypto_edward_instance {
+	RTE_CRYPTO_EDCURVE_25519,
+	RTE_CRYPTO_EDCURVE_25519CTX,
+	RTE_CRYPTO_EDCURVE_25519PH,
+	RTE_CRYPTO_EDCURVE_448,
+	RTE_CRYPTO_EDCURVE_448PH
+};
+
 /**
  * Asymmetric crypto transformation types.
  * Each xform type maps to one asymmetric algorithm
@@ -119,6 +136,10 @@ enum rte_crypto_asym_xform_type {
 	 * Performs Encrypt, Decrypt, Sign and Verify.
 	 * Refer to rte_crypto_asym_op_type.
 	 */
+	RTE_CRYPTO_ASYM_XFORM_EDDSA,
+	/**< Edwards Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -585,6 +606,31 @@ struct rte_crypto_ecdsa_op_param {
 	 */
 };
 
+/**
+ * EDDSA operation params
+ */
+struct rte_crypto_eddsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param message;
+	/**< Input message digest to be signed or verified */
+
+	rte_crypto_param context;
+	/**< Context value for the sign op.
+	 *   Must not be empty for Ed25519ctx instance.
+	 */
+
+	enum rte_crypto_edward_instance instance;
+	/**< Type of Edwards curve. */
+
+	rte_crypto_uint sign;
+	/**< Edward curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Structure for EC point multiplication operation param
  */
@@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_ecdsa_op_param ecdsa;
 		struct rte_crypto_ecpm_op_param ecpm;
 		struct rte_crypto_sm2_op_param sm2;
+		struct rte_crypto_eddsa_op_param eddsa;
 	};
 	uint16_t flags;
 	/**<
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v2 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2023-11-29 16:10 [PATCH v1 1/3] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                   ` (2 preceding siblings ...)
  2024-09-05 13:36 ` [PATCH v2 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
@ 2024-09-05 13:39 ` Gowrishankar Muthukrishnan
  2024-09-05 13:39   ` [PATCH v2 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
                     ` (4 more replies)
  3 siblings, 5 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-05 13:39 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, ciara.power, jerinj,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Gowrishankar Muthukrishnan

Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
https://datatracker.ietf.org/doc/html/rfc8032

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
 lib/cryptodev/rte_crypto_asym.h            | 47 ++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index f411d4bab7..3073753911 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -130,6 +130,7 @@ ECDSA                   =
 ECPM                    =
 ECDH                    =
 SM2                     =
+EDDSA                   =
 
 ;
 ; Supported Operating systems of a default crypto driver.
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 2b513bbf82..dd636ba5ef 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -927,7 +927,7 @@ Asymmetric Cryptography
 The cryptodev library currently provides support for the following asymmetric
 Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman and
 Elliptic Curve Diffie-Hellman public and/or private key generation and shared
-secret compute, DSA Signature generation and verification.
+secret compute, DSA and EdDSA Signature generation and verification.
 
 Session and Session Management
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index 39d3da3952..11bb885d64 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -49,6 +49,10 @@ rte_crypto_asym_op_strings[];
  * and if the flag is not set, shared secret will be padded to the left with
  * zeros to the size of the underlying algorithm (default)
  */
+#define RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED		RTE_BIT32(2)
+/**<
+ * Flag to denote public key will be returned in compressed form
+ */
 
 /**
  * List of elliptic curves. This enum aligns with
@@ -65,9 +69,22 @@ enum rte_crypto_curve_id {
 	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
 	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
 	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
+	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
+	RTE_CRYPTO_EC_GROUP_ED448     = 30,
 	RTE_CRYPTO_EC_GROUP_SM2       = 41,
 };
 
+/**
+ * List of Edwards curve instances as per RFC 8032 (Section 5).
+ */
+enum rte_crypto_edward_instance {
+	RTE_CRYPTO_EDCURVE_25519,
+	RTE_CRYPTO_EDCURVE_25519CTX,
+	RTE_CRYPTO_EDCURVE_25519PH,
+	RTE_CRYPTO_EDCURVE_448,
+	RTE_CRYPTO_EDCURVE_448PH
+};
+
 /**
  * Asymmetric crypto transformation types.
  * Each xform type maps to one asymmetric algorithm
@@ -119,6 +136,10 @@ enum rte_crypto_asym_xform_type {
 	 * Performs Encrypt, Decrypt, Sign and Verify.
 	 * Refer to rte_crypto_asym_op_type.
 	 */
+	RTE_CRYPTO_ASYM_XFORM_EDDSA,
+	/**< Edwards Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -585,6 +606,31 @@ struct rte_crypto_ecdsa_op_param {
 	 */
 };
 
+/**
+ * EDDSA operation params
+ */
+struct rte_crypto_eddsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param message;
+	/**< Input message digest to be signed or verified */
+
+	rte_crypto_param context;
+	/**< Context value for the sign op.
+	 *   Must not be empty for Ed25519ctx instance.
+	 */
+
+	enum rte_crypto_edward_instance instance;
+	/**< Type of Edwards curve. */
+
+	rte_crypto_uint sign;
+	/**< Edward curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Structure for EC point multiplication operation param
  */
@@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_ecdsa_op_param ecdsa;
 		struct rte_crypto_ecpm_op_param ecpm;
 		struct rte_crypto_sm2_op_param sm2;
+		struct rte_crypto_eddsa_op_param eddsa;
 	};
 	uint16_t flags;
 	/**<
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v2 2/6] crypto/openssl: support EDDSA
  2024-09-05 13:39 ` Gowrishankar Muthukrishnan
@ 2024-09-05 13:39   ` Gowrishankar Muthukrishnan
  2024-09-09  9:56     ` Jack Bond-Preston
  2024-09-05 13:39   ` [PATCH v2 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-05 13:39 UTC (permalink / raw)
  To: dev, Kai Ji
  Cc: Anoob Joseph, bruce.richardson, ciara.power, jerinj,
	fanzhang.oss, arkadiuszx.kusztal, jack.bond-preston,
	david.marchand, hemant.agrawal, pablo.de.lara.guarch,
	fiona.trahe, declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in OpenSSL PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
 drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
 3 files changed, 367 insertions(+)

diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index a50e4d4918..a613988dbe 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -231,10 +231,23 @@ struct __rte_cache_aligned openssl_asym_session {
 #endif
 		} s;
 		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			EC_GROUP * group;
+			BIGNUM *priv_key;
+#endif
+		} ec;
+		struct {
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 			OSSL_PARAM * params;
 #endif
 		} sm2;
+		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			OSSL_PARAM * params;
+#endif
+		} eddsa;
 	} u;
 };
 /** Set and validate OPENSSL crypto session parameters */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 101111e85b..cbc10b27d4 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2849,6 +2849,45 @@ process_openssl_rsa_op_evp(struct rte_crypto_op *cop,
 
 }
 
+static int
+process_openssl_ecfpm_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	const EC_GROUP *ecgrp = sess->u.ec.group;
+	EC_POINT *ecpt = NULL;
+	BN_CTX *ctx = NULL;
+	BIGNUM *n = NULL;
+	int ret = -1;
+
+	n = BN_bin2bn((const unsigned char *)
+			cop->asym->ecpm.scalar.data,
+			cop->asym->ecpm.scalar.length,
+			BN_new());
+
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto err_ecfpm;
+
+	if (!EC_POINT_mul(ecgrp, ecpt, n, NULL, NULL, ctx))
+		goto err_ecfpm;
+
+	if (cop->asym->flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED) {
+		unsigned char *buf = cop->asym->ecpm.r.x.data;
+		size_t sz;
+
+		sz = EC_POINT_point2oct(ecgrp, ecpt, POINT_CONVERSION_COMPRESSED, buf, 0, ctx);
+		if (!sz)
+			goto err_ecfpm;
+
+		cop->asym->ecpm.r.x.length = sz;
+	}
+
+err_ecfpm:
+	BN_CTX_free(ctx);
+	BN_free(n);
+	return ret;
+}
+
 static int
 process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3074,6 +3113,158 @@ process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 	return ret;
 }
 
+static int
+process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	static const char * const instance[] = {"Ed25519", "Ed25519ctx", "Ed25519ph",
+						"Ed448", "Ed448ph"};
+	EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
+	const uint8_t curve_id = sess->u.eddsa.curve_id;
+	struct rte_crypto_asym_op *op = cop->asym;
+	OSSL_PARAM *params = sess->u.eddsa.params;
+	OSSL_PARAM_BLD *iparam_bld = NULL;
+	OSSL_PARAM *iparams = NULL;
+	uint8_t signbuf[128] = {0};
+	EVP_MD_CTX *md_ctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	size_t signlen;
+	int ret = -1;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	iparam_bld = OSSL_PARAM_BLD_new();
+	if (!iparam_bld)
+		goto err_eddsa;
+
+	if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519CTX) {
+		OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-string",
+			op->eddsa.context.data, op->eddsa.context.length);
+
+	}
+
+	OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
+		instance[op->eddsa.instance], strlen(instance[op->eddsa.instance]));
+
+	iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
+	if (!iparams)
+		goto err_eddsa;
+
+	switch (op->eddsa.op_type) {
+	case RTE_CRYPTO_ASYM_OP_SIGN:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			if (!EVP_DigestSign(md_ctx, NULL, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			if (signlen > RTE_DIM(signbuf))
+				goto err_eddsa;
+
+			if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
+			op->eddsa.sign.length = signlen;
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_VERIFY:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			signlen = op->eddsa.sign.length;
+			memcpy(&signbuf[0], op->eddsa.sign.data, op->eddsa.sign.length);
+
+			ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op->eddsa.message.data,
+					op->eddsa.message.length);
+			if (ret == 0)
+				goto err_eddsa;
+		}
+		break;
+	default:
+		/* allow ops with invalid args to be pushed to
+		 * completion queue
+		 */
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		goto err_eddsa;
+	}
+
+	ret = 0;
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+err_eddsa:
+	OSSL_PARAM_BLD_free(iparam_bld);
+
+	if (sctx)
+		EVP_PKEY_CTX_free(sctx);
+
+	if (cctx)
+		EVP_PKEY_CTX_free(cctx);
+
+	if (pkey)
+		EVP_PKEY_free(pkey);
+
+	return ret;
+}
 #else
 static int
 process_openssl_rsa_op(struct rte_crypto_op *cop,
@@ -3174,6 +3365,15 @@ process_openssl_rsa_op(struct rte_crypto_op *cop,
 	return 0;
 }
 
+static int
+process_openssl_ecfpm_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
+
 static int
 process_openssl_sm2_op(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3182,6 +3382,15 @@ process_openssl_sm2_op(struct rte_crypto_op *cop,
 	RTE_SET_USED(sess);
 	return -ENOTSUP;
 }
+
+static int
+process_openssl_eddsa_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
 #endif
 
 static int
@@ -3230,6 +3439,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 				process_openssl_dsa_verify_op(op, sess);
 		else
 			op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_ecfpm_op_evp(op, sess);
+#else
+		retval = process_openssl_ecfpm_op(op, sess);
 #endif
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
@@ -3237,6 +3453,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 		retval = process_openssl_sm2_op_evp(op, sess);
 #else
 		retval = process_openssl_sm2_op(op, sess);
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_eddsa_op_evp(op, sess);
+#else
+		retval = process_openssl_eddsa_op(op, sess);
 #endif
 		break;
 	default:
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index 1bbb855a59..bc41717e83 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -593,6 +593,16 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		},
 		}
 	},
+	{	/* ECFPM */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM,
+				.op_types = 0
+				}
+			}
+		}
+	},
 	{	/* SM2 */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
@@ -610,6 +620,20 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		}
 		}
 	},
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types =
+				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
+				 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+			}
+		}
+		}
+	},
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1356,6 +1380,47 @@ static int openssl_set_asym_session_parameters(
 		BN_free(pub_key);
 		return -1;
 	}
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		EC_GROUP *ecgrp = NULL;
+
+		asym_session->xfrm_type = xform->xform_type;
+
+		switch (xform->ec.curve_id) {
+		case RTE_CRYPTO_EC_GROUP_SECP192R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp192k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP224R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp224r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP256R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP384R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp384r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP521R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp521r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED25519:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED25519);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED448:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED448);
+			break;
+		default:
+			break;
+		}
+
+		asym_session->u.ec.curve_id = xform->ec.curve_id;
+		asym_session->u.ec.group = ecgrp;
+		break;
+#else
+		OPENSSL_LOG(WARNING, "ECFPM unsupported for OpenSSL Version < 3.0");
+		return -ENOTSUP;
+#endif
+	}
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 	{
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
@@ -1440,6 +1505,66 @@ static int openssl_set_asym_session_parameters(
 #else
 		OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL Version < 3.0");
 		return -ENOTSUP;
+#endif
+	}
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		OSSL_PARAM_BLD *param_bld = NULL;
+		OSSL_PARAM *params = NULL;
+		int ret = -1;
+
+		asym_session->u.eddsa.curve_id = xform->ec.curve_id;
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+			  OSSL_PKEY_PARAM_GROUP_NAME, "ED25519", sizeof("ED25519"));
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PRIV_KEY,
+				xform->ec.pkey.data, xform->ec.pkey.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
+				xform->ec.q.x.data, xform->ec.q.x.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		params = OSSL_PARAM_BLD_to_param(param_bld);
+		if (!params) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		asym_session->u.eddsa.params = params;
+		OSSL_PARAM_BLD_free(param_bld);
+
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		break;
+err_eddsa:
+		if (param_bld)
+			OSSL_PARAM_BLD_free(param_bld);
+
+		if (asym_session->u.eddsa.params)
+			OSSL_PARAM_free(asym_session->u.eddsa.params);
+
+		return -1;
+#else
+		OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL Version < 3.0");
+		return -ENOTSUP;
 #endif
 	}
 	default:
@@ -1538,6 +1663,12 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 		OSSL_PARAM_free(sess->u.sm2.params);
 #endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		OSSL_PARAM_free(sess->u.eddsa.params);
+#endif
+		break;
 	default:
 		break;
 	}
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v2 3/6] crypto/cnxk: support EDDSA
  2024-09-05 13:39 ` Gowrishankar Muthukrishnan
  2024-09-05 13:39   ` [PATCH v2 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
@ 2024-09-05 13:39   ` Gowrishankar Muthukrishnan
  2024-09-20 13:09     ` [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-09-05 13:39   ` [PATCH v2 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-05 13:39 UTC (permalink / raw)
  To: dev, Ankur Dwivedi, Anoob Joseph, Tejasree Kondoj,
	Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: bruce.richardson, ciara.power, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in CNXK PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/cn10k.ini      |   1 +
 drivers/common/cnxk/hw/cpt.h                  |   3 +-
 drivers/common/cnxk/roc_ae.c                  |  52 +-
 drivers/common/cnxk/roc_ae.h                  |  10 +
 drivers/common/cnxk/roc_ae_fpm_tables.c       | 580 +++++++++++++++++-
 drivers/crypto/cnxk/cnxk_ae.h                 | 473 +++++++++++++-
 drivers/crypto/cnxk/cnxk_cryptodev.h          |   2 +-
 .../crypto/cnxk/cnxk_cryptodev_capabilities.c |  19 +
 8 files changed, 1129 insertions(+), 11 deletions(-)

diff --git a/doc/guides/cryptodevs/features/cn10k.ini b/doc/guides/cryptodevs/features/cn10k.ini
index 39f4b56b9f..bb7d265005 100644
--- a/doc/guides/cryptodevs/features/cn10k.ini
+++ b/doc/guides/cryptodevs/features/cn10k.ini
@@ -107,6 +107,7 @@ ECDH                    = Y
 ECDSA                   = Y
 ECPM                    = Y
 SM2                     = Y
+EDDSA                   = Y
 
 ;
 ; Supported Operating systems of the 'cn10k' crypto driver.
diff --git a/drivers/common/cnxk/hw/cpt.h b/drivers/common/cnxk/hw/cpt.h
index 2620965606..47df3fbf9f 100644
--- a/drivers/common/cnxk/hw/cpt.h
+++ b/drivers/common/cnxk/hw/cpt.h
@@ -81,7 +81,8 @@ union cpt_eng_caps {
 		uint64_t __io sm2 : 1;
 		uint64_t __io pdcp_chain_zuc256 : 1;
 		uint64_t __io tls : 1;
-		uint64_t __io reserved_39_63 : 25;
+		uint64_t __io eddsa : 1;
+		uint64_t __io reserved_40_63 : 24;
 	};
 };
 
diff --git a/drivers/common/cnxk/roc_ae.c b/drivers/common/cnxk/roc_ae.c
index 7ef0efe2b3..2c563c30de 100644
--- a/drivers/common/cnxk/roc_ae.c
+++ b/drivers/common/cnxk/roc_ae.c
@@ -179,7 +179,57 @@ const struct roc_ae_ec_group ae_ec_grp[ROC_AE_EC_ID_PMAX] = {
 				    0xAB, 0x8F, 0x92, 0xDD, 0xBC, 0xBD, 0x41,
 				    0x4D, 0x94, 0x0E, 0x93},
 			   .length = 32},
-	}};
+	},
+	{
+		.prime = {.data = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0x7F},
+			  .length = 32},
+		.order = {.data = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12,
+				   0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9,
+				   0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x10},
+			  .length = 32},
+		.consta = {.data = {0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb,
+				    0x75, 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a,
+				    0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79,
+				    0x40, 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b,
+				    0xee, 0x6c, 0x03, 0x52},
+			   .length = 32},
+	},
+	{
+		.prime = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			  .length = 56},
+		.order = {.data = {0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78,
+				   0x23, 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2,
+				   0x6c, 0x21, 0x90, 0x36, 0xd6, 0xae, 0x49,
+				   0xdb, 0x4e, 0xc4, 0xe9, 0x23, 0xca, 0x7c,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f},
+			  .length = 56},
+		.consta = {.data = {0x56, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			   .length = 56},
+	},
+};
 
 int
 roc_ae_ec_grp_get(struct roc_ae_ec_group **tbl)
diff --git a/drivers/common/cnxk/roc_ae.h b/drivers/common/cnxk/roc_ae.h
index 7886b9d107..880ed5f75a 100644
--- a/drivers/common/cnxk/roc_ae.h
+++ b/drivers/common/cnxk/roc_ae.h
@@ -12,6 +12,7 @@
 #define ROC_AE_MAJOR_OP_MODEX	     0x03
 #define ROC_AE_MAJOR_OP_EC	     0x04
 #define ROC_AE_MAJOR_OP_ECC	     0x05
+#define ROC_AE_MAJOR_OP_EDDSA	     0x0A
 #define ROC_AE_MINOR_OP_RANDOM	     0x00
 #define ROC_AE_MINOR_OP_MODEX	     0x01
 #define ROC_AE_MINOR_OP_PKCS_ENC     0x02
@@ -23,6 +24,9 @@
 #define ROC_AE_MINOR_OP_EC_VERIFY    0x02
 #define ROC_AE_MINOR_OP_ECC_UMP	     0x03
 #define ROC_AE_MINOR_OP_ECC_FPM	     0x04
+#define ROC_AE_MINOR_OP_ED_SIGN      0x00
+#define ROC_AE_MINOR_OP_ED_VERIFY    0x01
+#define ROC_AE_MINOR_OP_ED_KEYGEN    0x02
 
 /**
  * Enumeration roc_ae_ec_id
@@ -39,6 +43,8 @@ typedef enum {
 	ROC_AE_EC_ID_P320 = 6,
 	ROC_AE_EC_ID_P512 = 7,
 	ROC_AE_EC_ID_SM2  = 8,
+	ROC_AE_EC_ID_ED25519 = 9,
+	ROC_AE_EC_ID_ED448   = 10,
 	ROC_AE_EC_ID_PMAX
 } roc_ae_ec_id;
 
@@ -47,6 +53,10 @@ typedef enum {
 #define ROC_AE_EC_PARAM1_SM2       (1 << 7)
 #define ROC_AE_EC_PARAM1_NIST      (0 << 6)
 #define ROC_AE_EC_PARAM1_NONNIST   (1 << 6)
+#define ROC_AE_ED_PARAM1_25519     (1 << 1)
+#define ROC_AE_ED_PARAM1_448       (1 << 3)
+#define ROC_AE_ED_PARAM1_KEYGEN_BIT      4
+#define ROC_AE_EC_PARAM1_PH_BIT          5
 
 typedef enum {
 	ROC_AE_ERR_ECC_PAI = 0x0b,
diff --git a/drivers/common/cnxk/roc_ae_fpm_tables.c b/drivers/common/cnxk/roc_ae_fpm_tables.c
index 942657b56a..0a5e8d0ec4 100644
--- a/drivers/common/cnxk/roc_ae_fpm_tables.c
+++ b/drivers/common/cnxk/roc_ae_fpm_tables.c
@@ -21,7 +21,9 @@ typedef enum {
 	AE_FPM_P224_LEN = 2160,
 	AE_FPM_P256_LEN = 2160,
 	AE_FPM_P384_LEN = 2520,
-	AE_FPM_P521_LEN = 3240
+	AE_FPM_P521_LEN = 3240,
+	AE_FPM_ED25519_LEN = 2880,
+	AE_FPM_ED448_LEN   = 3840,
 } ae_fpm_len;
 
 /* FPM table address and length */
@@ -1240,6 +1242,572 @@ const uint8_t ae_fpm_tbl_p256_sm2[AE_FPM_P256_LEN] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+const uint8_t ae_fpm_tbl_ed25519[AE_FPM_ED25519_LEN] = {
+	0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a, 0x69, 0x2c, 0xc7, 0x60,
+	0x95, 0x25, 0xa7, 0xb2, 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c,
+	0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6d, 0xde, 0x8a, 0xb3, 0xa5, 0xb7, 0xdd, 0xa3, 0x20, 0xf0, 0x9f, 0x80,
+	0x77, 0x51, 0x52, 0xf5, 0x66, 0xea, 0x4e, 0x8e, 0x64, 0xab, 0xe3, 0x7d,
+	0x67, 0x87, 0x5f, 0x0f, 0xd7, 0x8b, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x18, 0xc0, 0x0c, 0x55, 0x07, 0xed, 0xf1, 0x0d, 0x69, 0xbe, 0x61, 0x3a,
+	0x4f, 0x82, 0xd2, 0xc4, 0x3e, 0xf0, 0xa1, 0x4e, 0xf1, 0xba, 0xd8, 0xb1,
+	0x5a, 0x8a, 0x5a, 0x58, 0xbe, 0xf1, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x63, 0xce, 0x54, 0x79, 0x0e, 0x45, 0x3f, 0x73, 0xe9, 0x33, 0xff, 0xc7,
+	0xec, 0xab, 0xc7, 0x4b, 0x6b, 0x43, 0x64, 0x02, 0x45, 0xcf, 0x64, 0xfa,
+	0x1a, 0xd2, 0xdd, 0x57, 0x64, 0x55, 0xf6, 0x78, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x8c, 0x9d, 0x04, 0xac, 0x84, 0x05, 0xe0, 0xe7, 0xa5, 0x17, 0x56,
+	0x92, 0x2e, 0xbd, 0x07, 0x96, 0x72, 0x74, 0xa7, 0xd8, 0x1d, 0x8d, 0x30,
+	0x42, 0x4d, 0xa3, 0xd2, 0x15, 0xae, 0xf3, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x19, 0xcf, 0x23, 0xc1, 0x1f, 0x40, 0x15, 0x86, 0x4d, 0xd5, 0x99, 0x64,
+	0x9b, 0x94, 0x9e, 0x8e, 0x22, 0x68, 0xc6, 0xcf, 0xf4, 0xe4, 0xf9, 0xd9,
+	0x75, 0xe4, 0xce, 0xc7, 0xf1, 0xc8, 0x41, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x98, 0x8c, 0x87, 0x10, 0xcd, 0x87, 0x55, 0x95, 0x52, 0x83, 0xad, 0xc1,
+	0x83, 0x92, 0xcf, 0xa4, 0x28, 0x4a, 0x93, 0xe5, 0x21, 0x53, 0xaa, 0x3d,
+	0x33, 0x97, 0x60, 0xe6, 0xcb, 0xdc, 0xf5, 0xd4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe6, 0xf2, 0x50, 0x1e, 0x50, 0x14, 0x12, 0xd8, 0x45, 0xcc, 0xd0, 0xd4,
+	0x75, 0x78, 0xec, 0xae, 0x42, 0x10, 0x45, 0x12, 0x74, 0x2b, 0x26, 0xde,
+	0x41, 0xea, 0x80, 0x41, 0x7f, 0xb3, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x75, 0x61, 0x33, 0xad, 0x0c, 0x22, 0xe4, 0x7f, 0xd7, 0x18, 0xb3,
+	0xf9, 0xd3, 0x55, 0x9e, 0x96, 0x2d, 0xa3, 0xfa, 0x7d, 0xfb, 0x1e, 0xb6,
+	0x4e, 0xd0, 0xb6, 0x26, 0xa7, 0x32, 0x09, 0x87, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaf, 0x7f, 0xd1, 0x3e, 0xfe, 0xa5, 0xa5, 0x96, 0x3c, 0x42, 0xec, 0x0e,
+	0xef, 0x69, 0x4e, 0x62, 0xf5, 0xb9, 0xc2, 0xad, 0x65, 0x7b, 0x91, 0x6f,
+	0x25, 0x55, 0x0a, 0xc3, 0x9c, 0xfb, 0x1a, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2a, 0xf9, 0xfb, 0x16, 0x90, 0xe8, 0x72, 0x7e, 0x98, 0x92, 0x1f, 0xc5,
+	0x97, 0x96, 0xc5, 0x0c, 0x8a, 0x12, 0x0b, 0xf3, 0x98, 0xc0, 0x5f, 0x4d,
+	0x38, 0x56, 0x94, 0x41, 0xa1, 0xf5, 0xcd, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0x39, 0xdb, 0x96, 0xf7, 0x8d, 0x2e, 0x7c, 0xb1, 0xc0, 0x51, 0x3b,
+	0xa4, 0xc4, 0x55, 0x12, 0x75, 0x29, 0xd9, 0x29, 0x65, 0x02, 0x36, 0x8d,
+	0x0a, 0x97, 0xdf, 0xad, 0x58, 0xfa, 0x26, 0x19, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0x4b, 0xb5, 0xe5, 0x13, 0xa5, 0x45, 0x40, 0x2c, 0xba, 0x4d, 0x3b,
+	0x1e, 0x5f, 0x55, 0xb8, 0x04, 0xa2, 0xce, 0x24, 0x52, 0x7e, 0xb7, 0x3c,
+	0x78, 0xd9, 0x8e, 0xba, 0xc3, 0x3b, 0xd9, 0x46, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb2, 0x1d, 0x1e, 0x95, 0xfb, 0x8d, 0x9a, 0xdd, 0xdb, 0xfc, 0xa8, 0xca,
+	0x0f, 0x51, 0x54, 0x75, 0x72, 0x53, 0xc9, 0xca, 0xe4, 0x6b, 0x0a, 0x2f,
+	0x3d, 0xc4, 0xd8, 0x0a, 0x0c, 0x80, 0x9a, 0xb6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0xc6, 0x8e, 0xea, 0x63, 0xb3, 0x17, 0x45, 0x1b, 0xc9, 0x4f, 0xf2,
+	0xb9, 0xce, 0xab, 0x28, 0x84, 0x84, 0x27, 0x82, 0x6e, 0x59, 0x5d, 0x0d,
+	0x57, 0x1c, 0xd9, 0x4b, 0x55, 0xf8, 0xa2, 0xd1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x76, 0xd4, 0x7d, 0xa8, 0x8a, 0xfd, 0x34, 0xf3, 0x5e, 0xa7, 0x1b, 0x7c,
+	0x94, 0x84, 0x05, 0x81, 0x7f, 0x9d, 0x55, 0x08, 0x06, 0x03, 0x5e, 0x42,
+	0x42, 0xe8, 0x55, 0x9a, 0xac, 0x90, 0x41, 0xf2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x74, 0xd2, 0x01, 0x61, 0xc0, 0x1f, 0x88, 0x8b, 0xcb, 0xca, 0xf5, 0xd3,
+	0x63, 0x58, 0x4b, 0xbb, 0x66, 0xc6, 0x4e, 0xab, 0x8c, 0x6c, 0x68, 0x22,
+	0x66, 0xca, 0x84, 0x72, 0x7e, 0x3c, 0x0b, 0xa2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0x0b, 0xdb, 0xf8, 0x8a, 0x48, 0x29, 0x71, 0x03, 0xf7, 0xcf, 0x4d,
+	0xb1, 0x85, 0x7a, 0x22, 0x97, 0xbe, 0x2e, 0xd9, 0xa1, 0xee, 0x20, 0x13,
+	0x2f, 0x5e, 0x07, 0xda, 0x24, 0x97, 0xb3, 0x43, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xec, 0x5e, 0x68, 0xad, 0xfe, 0x26, 0x70, 0x65, 0xfa, 0x03, 0x3f, 0x24,
+	0x56, 0xa2, 0x51, 0xc9, 0x79, 0x88, 0x89, 0x08, 0x86, 0x02, 0x18, 0x39,
+	0x59, 0x77, 0x53, 0x1b, 0xf7, 0x2c, 0x65, 0x3c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x23, 0xb1, 0xc4, 0x4d, 0xad, 0xf1, 0xae, 0x7a, 0x52, 0xba, 0x48,
+	0xd0, 0x0a, 0xc1, 0x94, 0x34, 0x41, 0x1b, 0x3d, 0x93, 0x49, 0xf0, 0x8d,
+	0x25, 0xf2, 0x72, 0x56, 0xd7, 0xb7, 0x05, 0x81, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0x05, 0x2c, 0x85, 0xc5, 0x52, 0xad, 0x02, 0xbd, 0xb7, 0x5d, 0x21,
+	0xcd, 0xbd, 0xce, 0x01, 0xd3, 0xd9, 0x12, 0xba, 0xc6, 0x7f, 0x45, 0x31,
+	0x00, 0x33, 0x8c, 0x20, 0x63, 0x4d, 0xf5, 0x22, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1a, 0x38, 0xa7, 0xf1, 0x5b, 0xd0, 0xb8, 0x54, 0x3c, 0x33, 0x27, 0x32,
+	0xca, 0x04, 0x38, 0x5e, 0xa0, 0xf8, 0x81, 0x06, 0xa0, 0xe7, 0x47, 0x1d,
+	0x16, 0xcb, 0xaa, 0x68, 0xb5, 0x6a, 0xd2, 0xaa, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3e, 0x69, 0x14, 0xef, 0xc0, 0x82, 0x94, 0x72, 0x09, 0x07, 0xb5, 0xa6,
+	0x98, 0x1d, 0xb2, 0xd7, 0xcb, 0xe4, 0x6c, 0xb7, 0x88, 0x78, 0x8b, 0xd9,
+	0x34, 0x5a, 0xdb, 0xae, 0x55, 0x6a, 0x6b, 0x1f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf1, 0x20, 0x49, 0xc6, 0xda, 0x47, 0x7a, 0x25, 0x9e, 0xce, 0xf6, 0x2e,
+	0xd4, 0x76, 0xb6, 0x0f, 0x41, 0x54, 0x08, 0xb8, 0x29, 0x08, 0x96, 0xd0,
+	0x01, 0x23, 0x34, 0xb6, 0x1e, 0xfe, 0xb0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd1, 0x6c, 0x52, 0xd3, 0x5f, 0x6a, 0x74, 0x18, 0x9b, 0xfe, 0xf3, 0x73,
+	0x74, 0xb8, 0x05, 0xa2, 0x29, 0x9d, 0x41, 0x53, 0x72, 0xa2, 0x93, 0x7c,
+	0x0a, 0xa8, 0xe8, 0x48, 0x89, 0x8f, 0x6f, 0x60, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x21, 0x4a, 0xd6, 0xa6, 0x0b, 0x51, 0xf6, 0x1d, 0xa2, 0x5c, 0xa5, 0x23,
+	0x6a, 0x1e, 0x34, 0x7d, 0xc5, 0xfe, 0xba, 0x77, 0x9d, 0xe5, 0x40, 0x9c,
+	0x38, 0x4e, 0xab, 0x29, 0x0d, 0x17, 0x7e, 0x48, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1e, 0x04, 0x03, 0xaf, 0xbd, 0x77, 0xba, 0x7d, 0x53, 0xe9, 0x14, 0x63,
+	0x40, 0xa7, 0xba, 0x26, 0x00, 0x55, 0x42, 0xff, 0x7c, 0x0d, 0xde, 0xd1,
+	0x59, 0xa2, 0x72, 0x6d, 0x1a, 0x92, 0x7e, 0x56, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x6d, 0x5c, 0x1d, 0x19, 0xf5, 0x09, 0x6d, 0x18, 0xa1, 0x69, 0x87,
+	0xad, 0x52, 0x19, 0x1e, 0xf1, 0x83, 0x14, 0xea, 0x85, 0x1c, 0xeb, 0xe0,
+	0x09, 0x34, 0x4b, 0x8a, 0xd2, 0x98, 0x25, 0x20, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4c, 0x5a, 0xf1, 0x8b, 0x60, 0xa3, 0xef, 0xfb, 0xe6, 0x9a, 0x9e, 0x2a,
+	0x7c, 0x79, 0x13, 0x18, 0x9b, 0x68, 0xed, 0x3d, 0x9c, 0x96, 0x87, 0x75,
+	0x7d, 0x03, 0x00, 0x62, 0x8a, 0x38, 0x69, 0x58, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8e, 0x21, 0xc4, 0x17, 0x0e, 0x2d, 0x4e, 0x01, 0xb5, 0xfb, 0x2e, 0x65,
+	0x3f, 0x32, 0xd7, 0x18, 0x50, 0x70, 0x81, 0x6b, 0xf7, 0xab, 0xc2, 0xfc,
+	0x4b, 0xa9, 0x21, 0x10, 0x37, 0x21, 0xbf, 0xbb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xda, 0x5a, 0x33, 0xeb, 0x21, 0x36, 0x7c, 0x40, 0x16, 0x1d, 0xd5, 0x6e,
+	0xe1, 0xe4, 0x79, 0x2b, 0x9f, 0x9f, 0x06, 0x89, 0x80, 0x93, 0xc6, 0x0f,
+	0x61, 0xbe, 0x0b, 0x75, 0xdb, 0x7c, 0x78, 0x50, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8b, 0xdc, 0x45, 0xa9, 0x5e, 0xbc, 0xf3, 0xb4, 0xcc, 0x3c, 0xba, 0xbd,
+	0x65, 0x2f, 0x2f, 0xd7, 0xd5, 0x15, 0x7f, 0x7e, 0x03, 0x0b, 0xc6, 0xc7,
+	0x6b, 0x6b, 0x6e, 0x77, 0x30, 0xcb, 0xc0, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2e, 0xf0, 0x16, 0xcd, 0xf9, 0x23, 0xf9, 0x10, 0xe0, 0x5d, 0xa7, 0x26,
+	0xbb, 0xf1, 0x53, 0x06, 0xea, 0x81, 0x2f, 0x38, 0x9e, 0x53, 0x67, 0x40,
+	0x74, 0x2a, 0xd5, 0x6e, 0xec, 0xc8, 0xa5, 0xcb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe2, 0x1f, 0xc1, 0xee, 0x82, 0xd5, 0x6e, 0x58, 0x81, 0x97, 0x4c, 0xf3,
+	0x0b, 0x90, 0x1e, 0x1f, 0xf8, 0xdc, 0x2b, 0xc0, 0x58, 0x3b, 0x2a, 0x28,
+	0x56, 0xc1, 0xe7, 0xb4, 0x40, 0x44, 0x5b, 0x54, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x85, 0x49, 0x08, 0xe7, 0xfa, 0x5d, 0x0c, 0xf9, 0xa3, 0x6e, 0xe5,
+	0x34, 0x8e, 0x83, 0xf2, 0xd0, 0xf1, 0xa4, 0x13, 0x32, 0x52, 0x86, 0x50,
+	0x75, 0xcd, 0xb5, 0xfc, 0xe9, 0x7b, 0x7c, 0xf6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2c, 0x85, 0x09, 0xe3, 0xd9, 0x4a, 0x91, 0xa2, 0x10, 0xf7, 0x7f, 0x5b,
+	0xde, 0x9a, 0xb7, 0x87, 0x32, 0x7d, 0x63, 0xf6, 0x7e, 0x0c, 0x3e, 0xcc,
+	0x4a, 0xa4, 0x9e, 0x35, 0x6b, 0x55, 0x50, 0x2e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xde, 0x9c, 0x80, 0x75, 0xc0, 0x21, 0x92, 0xf7, 0x30, 0x72, 0x1c, 0x15,
+	0xb2, 0x00, 0x0e, 0xc4, 0xa1, 0xa6, 0x1a, 0x6d, 0xd1, 0x63, 0x6b, 0xa8,
+	0x4b, 0x01, 0x10, 0x6f, 0x61, 0xe7, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7f, 0xdd, 0x3e, 0x2e, 0x6d, 0x7e, 0xed, 0x72, 0x65, 0xf7, 0x8d, 0x29,
+	0xba, 0x75, 0xa3, 0x07, 0x93, 0x86, 0xb4, 0xee, 0xcd, 0xd8, 0x5d, 0x19,
+	0x22, 0x02, 0x39, 0xba, 0xc5, 0x05, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa2, 0x01, 0xed, 0x74, 0x47, 0xd9, 0x0b, 0x18, 0x73, 0x4d, 0xcd, 0x41,
+	0x9a, 0xe4, 0xf1, 0xee, 0x33, 0x8a, 0x74, 0x8b, 0x26, 0xfd, 0x6e, 0x02,
+	0x2e, 0x5c, 0xc7, 0xf5, 0xa1, 0xeb, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3a, 0x3c, 0x00, 0x91, 0x80, 0xf2, 0x0f, 0x07, 0xf5, 0x02, 0xdc, 0xfa,
+	0xb7, 0x6e, 0x74, 0xdc, 0x3a, 0x78, 0xc5, 0x28, 0x8e, 0x17, 0x4f, 0xf1,
+	0x54, 0x40, 0x61, 0xfa, 0x46, 0x6c, 0x6d, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0x5f, 0xf2, 0x5a, 0x62, 0xbc, 0x77, 0xc1, 0xea, 0xbb, 0x38, 0xc2,
+	0x7e, 0x63, 0xac, 0x59, 0xc9, 0xd1, 0x37, 0xea, 0xeb, 0x09, 0x77, 0xa1,
+	0x6b, 0x49, 0x7e, 0x17, 0xc3, 0xab, 0x03, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xce, 0x14, 0xe5, 0x45, 0x4b, 0x16, 0x3e, 0x4a, 0xec, 0x3d, 0x52, 0x21,
+	0x35, 0xff, 0xe5, 0x33, 0x06, 0x46, 0x11, 0x32, 0x96, 0xc0, 0x34, 0x06,
+	0x04, 0x31, 0x37, 0x31, 0x25, 0xde, 0xde, 0xd8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x11, 0xbe, 0x6b, 0x47, 0xcd, 0x4a, 0xfd, 0xc3, 0x0d, 0x90, 0x1c, 0xc0,
+	0xd4, 0x70, 0x96, 0x72, 0xec, 0x42, 0xd6, 0x1d, 0x25, 0x5a, 0x9c, 0xd2,
+	0x23, 0xd6, 0x8e, 0xaf, 0x95, 0x7e, 0xfb, 0xd3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xdf, 0x28, 0x49, 0xeb, 0xa9, 0x5a, 0x0b, 0xf6, 0xf0, 0x9f, 0x4a,
+	0x47, 0x70, 0xf3, 0x49, 0x5f, 0x6f, 0xac, 0x86, 0x40, 0xfb, 0x0d, 0xf7,
+	0x72, 0xab, 0x23, 0x3d, 0x91, 0x08, 0x8c, 0x32, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0xb9, 0xe2, 0xb7, 0x4e, 0x62, 0xde, 0xcc, 0xd7, 0x68, 0xbd, 0x60,
+	0x83, 0x7d, 0x9c, 0x61, 0xfd, 0xd8, 0x5e, 0xb7, 0x64, 0x9b, 0xce, 0xa5,
+	0x23, 0x81, 0x2c, 0xcd, 0x9b, 0x5a, 0xaa, 0xd6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1d, 0x4a, 0x45, 0xf9, 0x1b, 0x9f, 0xa9, 0xfd, 0x38, 0x86, 0x31, 0x53,
+	0x9a, 0x2f, 0xb5, 0x5d, 0x2d, 0xed, 0x31, 0x75, 0x30, 0xd6, 0xbb, 0xdd,
+	0x53, 0x9b, 0x5f, 0xe0, 0xab, 0xd7, 0xaf, 0xe0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xee, 0xb3, 0x3b, 0xf0, 0x8a, 0x11, 0xd5, 0x5e, 0x37, 0xfd, 0x5a, 0x03,
+	0xaf, 0xaf, 0x0c, 0x99, 0xcc, 0x62, 0x92, 0x12, 0x30, 0x52, 0xac, 0x72,
+	0x7f, 0x51, 0x65, 0x44, 0x19, 0xf9, 0xe4, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x95, 0x4b, 0x50, 0xb3, 0x76, 0xa6, 0xa4, 0xb1, 0x9a, 0x39, 0x1e,
+	0x0d, 0x64, 0xfe, 0xc0, 0xf4, 0x43, 0xef, 0x85, 0x0a, 0xc2, 0xe3, 0xb0,
+	0x58, 0xc3, 0xf0, 0xf8, 0xdb, 0x67, 0xfc, 0x36, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xba, 0x4f, 0xbc, 0x66, 0x32, 0xd4, 0x4e, 0xec, 0x3f, 0x92, 0xfb, 0x0e,
+	0x92, 0x9b, 0x52, 0xe8, 0x27, 0xd9, 0xbb, 0xaa, 0x9c, 0x54, 0x70, 0x82,
+	0x4f, 0xad, 0xca, 0xbc, 0x9e, 0x01, 0x7e, 0x1c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5e, 0xe3, 0x0c, 0xca, 0xa3, 0xaa, 0xd6, 0x3f, 0x90, 0xcc, 0xef, 0xcd,
+	0x74, 0x59, 0xb3, 0xc5, 0xba, 0x35, 0xa8, 0x7e, 0x7e, 0xec, 0x4b, 0x6b,
+	0x00, 0x21, 0xfb, 0xa1, 0x6e, 0x53, 0xc4, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9d, 0xd3, 0xb3, 0xeb, 0xcf, 0xa0, 0x6d, 0xb1, 0x88, 0xab, 0x33, 0xc4,
+	0x0f, 0xd7, 0xb0, 0x76, 0x02, 0x8e, 0x71, 0x61, 0x18, 0x63, 0x07, 0xdc,
+	0x3e, 0x0d, 0xb9, 0xa8, 0x32, 0x75, 0x7a, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0xab, 0xf5, 0x7e, 0x0b, 0x4c, 0x08, 0x30, 0x08, 0x80, 0xc1, 0x9b,
+	0x69, 0x6a, 0x0e, 0xfc, 0x16, 0x81, 0xf1, 0xa9, 0xd4, 0x85, 0x35, 0x94,
+	0x26, 0xc5, 0x23, 0xb4, 0xa8, 0xb1, 0x8a, 0xb8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc5, 0x6d, 0x50, 0x49, 0x27, 0x8d, 0x35, 0x47, 0x0d, 0x73, 0x18, 0xae,
+	0xaf, 0x38, 0xef, 0xfa, 0xdd, 0x70, 0x48, 0x15, 0x39, 0xf0, 0x1c, 0x6e,
+	0x79, 0xd1, 0x13, 0x9f, 0xe4, 0xb3, 0xb2, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x39, 0xeb, 0xfb, 0x14, 0x3f, 0xf0, 0xa0, 0x0b, 0x5e, 0x41, 0x20, 0x0c,
+	0xfe, 0x36, 0x0c, 0x7f, 0xf0, 0xaf, 0xaa, 0xdd, 0x61, 0x66, 0x65, 0x30,
+	0x6b, 0x10, 0x18, 0x28, 0x30, 0xb6, 0x47, 0x3e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf7, 0xa8, 0x12, 0x06, 0x64, 0xfa, 0x90, 0xfa, 0x0c, 0xfb, 0x26, 0xf2,
+	0x2a, 0x1a, 0xc4, 0xf9, 0xae, 0x5c, 0x1b, 0x24, 0xf3, 0xf2, 0x87, 0xa2,
+	0x5c, 0x0a, 0x2a, 0x2b, 0x17, 0xa7, 0x2b, 0x7e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0x6d, 0x30, 0x7d, 0xb2, 0xd1, 0x40, 0xb7, 0x4f, 0x05, 0xac, 0x1a,
+	0xa1, 0x66, 0xa6, 0x19, 0x18, 0xf8, 0xcd, 0xf3, 0x3c, 0xf6, 0x84, 0xc3,
+	0x4d, 0x46, 0x49, 0xf1, 0xf7, 0x28, 0xa6, 0x0c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xf2, 0x0b, 0x90, 0x0d, 0xeb, 0x5c, 0x0b, 0x70, 0x2f, 0x54, 0x26,
+	0x1a, 0x7d, 0x6e, 0x72, 0x67, 0x95, 0x28, 0x03, 0x01, 0x37, 0xfa, 0xc6,
+	0x00, 0x45, 0xa7, 0xda, 0x5b, 0xbf, 0xf0, 0x24, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa9, 0x6c, 0x1d, 0x2b, 0x7e, 0xea, 0x35, 0x8b, 0x92, 0x12, 0x42, 0xf9,
+	0x8f, 0x67, 0x38, 0xf5, 0xf7, 0x1a, 0xe2, 0x8f, 0xb4, 0x40, 0x45, 0x2a,
+	0x47, 0xca, 0x9d, 0xbf, 0xbd, 0x85, 0xc0, 0xd2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+const uint8_t ae_fpm_tbl_ed448[AE_FPM_ED448_LEN] = {
+	0x26, 0x26, 0xa8, 0x2b, 0xc7, 0x0c, 0xc0, 0x5e, 0x43, 0x3b, 0x80, 0xe1,
+	0x8b, 0x00, 0x93, 0x8e, 0x12, 0xae, 0x1a, 0xf7, 0x2a, 0xb6, 0x65, 0x11,
+	0xea, 0x6d, 0xe3, 0x24, 0xa3, 0xd3, 0xa4, 0x64, 0x9e, 0x14, 0x65, 0x70,
+	0x47, 0x0f, 0x17, 0x67, 0x22, 0x1d, 0x15, 0xa6, 0x22, 0xbf, 0x36, 0xda,
+	0x4f, 0x19, 0x70, 0xc6, 0x6b, 0xed, 0x0d, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x98, 0x08, 0x79, 0x5b, 0xf2, 0x30, 0xfa, 0x14,
+	0xfd, 0xbd, 0x13, 0x2c, 0x4e, 0xd7, 0xc8, 0xad, 0x3a, 0xd3, 0xff, 0x1c,
+	0xe6, 0x7c, 0x39, 0xc4, 0x87, 0x78, 0x9c, 0x1e, 0x05, 0xa0, 0xc2, 0xd7,
+	0x4b, 0xea, 0x73, 0x73, 0x6c, 0xa3, 0x98, 0x40, 0x88, 0x76, 0x20, 0x37,
+	0x56, 0xc9, 0xc7, 0x62, 0x69, 0x3f, 0x46, 0x71, 0x6e, 0xb6, 0xbc, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xeb, 0x06, 0x62, 0x4e, 0x82, 0xaf, 0x95, 0xf3, 0xf7, 0x8f, 0xa0, 0x7d,
+	0x85, 0x66, 0x2d, 0x1d, 0xf1, 0x79, 0xde, 0x90, 0xb5, 0xb2, 0x7d, 0xa1,
+	0x60, 0xd7, 0x16, 0x67, 0xe2, 0x35, 0x6d, 0x58, 0xc5, 0x05, 0x6a, 0x18,
+	0x3f, 0x84, 0x51, 0xd2, 0xce, 0xc3, 0x9d, 0x2d, 0x50, 0x8d, 0x91, 0xc9,
+	0xc7, 0x5e, 0xb5, 0x8a, 0xee, 0x22, 0x1c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x12, 0x77, 0x1a, 0x0d, 0x31, 0xc0, 0x77, 0xbf,
+	0xc4, 0x24, 0x04, 0xed, 0x68, 0x36, 0xd7, 0x42, 0x6a, 0x65, 0x11, 0x30,
+	0x9d, 0xd9, 0x3a, 0x78, 0x3d, 0x16, 0x5b, 0x3f, 0x5b, 0x32, 0xdd, 0x27,
+	0x70, 0xf9, 0x81, 0x8f, 0x1b, 0xc6, 0x4d, 0xd1, 0x36, 0xf5, 0xf8, 0x56,
+	0x3e, 0x48, 0x3a, 0xc1, 0x28, 0x41, 0x27, 0x74, 0x35, 0xd1, 0x4b, 0x0f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x69, 0x81, 0x50,
+	0x38, 0xfb, 0x26, 0xe1, 0x68, 0x82, 0xe5, 0x52, 0x90, 0x23, 0xc2, 0x5e,
+	0xb3, 0x5e, 0x42, 0x06, 0x65, 0xea, 0x9f, 0x0c, 0x94, 0x4c, 0x92, 0x1f,
+	0x2d, 0x18, 0x4c, 0x04, 0xbe, 0x79, 0xf0, 0x74, 0x2d, 0x5a, 0x0b, 0x29,
+	0xa7, 0x46, 0xb8, 0x80, 0xdf, 0x83, 0x8f, 0x06, 0xe6, 0xe0, 0x8f, 0x72,
+	0x53, 0xfa, 0x6d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb4, 0x85, 0xa6, 0xed, 0xe6, 0xa8, 0x12, 0xd5, 0x7d, 0x97, 0xf7, 0xc8,
+	0xac, 0x2c, 0x4d, 0x2b, 0xfc, 0x53, 0x3e, 0xd0, 0x9f, 0x45, 0xd1, 0x52,
+	0xac, 0x85, 0x4f, 0xf8, 0x36, 0x7c, 0xcd, 0xa6, 0x6c, 0xb8, 0x0f, 0x8f,
+	0xdc, 0xde, 0x54, 0xc3, 0x23, 0x7b, 0xcc, 0xd9, 0xfe, 0x97, 0x19, 0x86,
+	0xa6, 0x17, 0xcd, 0x9b, 0xfe, 0x08, 0xf6, 0x3f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5c, 0xeb, 0x54, 0x97, 0x02, 0x55, 0xed, 0x8f,
+	0xfe, 0x3f, 0xe6, 0x24, 0x26, 0x1e, 0x3a, 0xc8, 0xdf, 0x28, 0xfc, 0xf9,
+	0xb9, 0x1b, 0x9c, 0xc8, 0x1b, 0x5f, 0xb0, 0x08, 0x2b, 0x19, 0x1e, 0x92,
+	0x29, 0xd9, 0x49, 0xa8, 0xb4, 0x61, 0xcc, 0xf3, 0x18, 0x35, 0x0a, 0x40,
+	0x2a, 0xe3, 0x2c, 0x09, 0x21, 0x81, 0x22, 0x38, 0xaf, 0xc2, 0xf4, 0x20,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x2d, 0x7c, 0xe2,
+	0x41, 0xc3, 0x10, 0x65, 0x01, 0x4a, 0x4f, 0xd5, 0x07, 0x2b, 0xa5, 0xd6,
+	0x7c, 0xc0, 0x57, 0x50, 0xc3, 0xf5, 0x63, 0xa0, 0x03, 0x8b, 0x79, 0xa9,
+	0xb1, 0xdd, 0xc4, 0x2f, 0xbe, 0xfa, 0x48, 0x92, 0xca, 0x8e, 0xd7, 0x0d,
+	0xdf, 0xcf, 0x2d, 0x40, 0xa3, 0xbc, 0x7e, 0xe7, 0x2e, 0xbe, 0xe9, 0x21,
+	0x83, 0xc8, 0x79, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xac, 0xdf, 0x2c, 0x05, 0x92, 0x8e, 0xe1, 0x3b, 0xc0, 0x57, 0xd9, 0xb4,
+	0x16, 0x0c, 0x80, 0x17, 0x03, 0x5a, 0x29, 0x4d, 0xef, 0x36, 0x9b, 0x11,
+	0x3b, 0xe2, 0xef, 0xca, 0x7f, 0xdd, 0xd3, 0xa3, 0xd7, 0x7f, 0x2b, 0x64,
+	0xa9, 0x7f, 0x62, 0x72, 0x71, 0x7d, 0x9e, 0x9f, 0xde, 0x2b, 0xcb, 0xd4,
+	0x3e, 0x95, 0x6f, 0x9d, 0x0c, 0x1f, 0x1a, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x92, 0xef, 0x93, 0x8e, 0xe7, 0x0a, 0x10,
+	0x7b, 0xc3, 0xdc, 0x46, 0xd9, 0x96, 0x27, 0x92, 0x91, 0xa4, 0x98, 0x89,
+	0x2d, 0xf2, 0x17, 0x03, 0x8c, 0xdb, 0x98, 0xed, 0xda, 0xb3, 0x15, 0xd5,
+	0xba, 0x58, 0x01, 0x38, 0x6e, 0x54, 0xd7, 0x46, 0x9c, 0x2b, 0x94, 0x5b,
+	0x60, 0x9e, 0x5b, 0x3b, 0xc3, 0x4c, 0x7e, 0xc3, 0xbc, 0x4d, 0xa9, 0xdd,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xd6, 0x93, 0x46,
+	0x63, 0x4b, 0xb6, 0x15, 0x73, 0x5f, 0xe8, 0x44, 0x1f, 0x89, 0x7c, 0xfe,
+	0x83, 0x79, 0xcb, 0x73, 0x83, 0x58, 0xce, 0x9c, 0x87, 0xad, 0x17, 0xe5,
+	0xfa, 0xdd, 0x04, 0x86, 0x55, 0x71, 0xf7, 0xb8, 0x6b, 0xcd, 0x5d, 0xfc,
+	0x9c, 0x49, 0xe6, 0x3f, 0x3e, 0x87, 0x3b, 0x37, 0x65, 0x32, 0x11, 0x5c,
+	0x6e, 0x65, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x3f, 0x74, 0xbc, 0x23, 0x5e, 0x87, 0xc7, 0x6f, 0xe1, 0x4d, 0x31,
+	0x75, 0x2a, 0x1e, 0xa9, 0x8e, 0xa2, 0x11, 0x3d, 0xfb, 0x62, 0xb8, 0x22,
+	0xdb, 0x4d, 0xb6, 0x29, 0x78, 0x4b, 0xc7, 0xa8, 0xba, 0x9b, 0xd8, 0x39,
+	0x03, 0xb6, 0x66, 0x26, 0xd2, 0xce, 0x26, 0x5d, 0x68, 0x1d, 0xca, 0x51,
+	0x14, 0x75, 0x66, 0xbd, 0xc2, 0xd0, 0xbc, 0xdb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x99, 0x33, 0x2c, 0x81, 0xaa, 0xcd, 0x8e, 0x4a,
+	0x04, 0xdf, 0xf4, 0x24, 0x98, 0x6b, 0x6e, 0x0f, 0xb1, 0xc0, 0x97, 0x61,
+	0x12, 0xbb, 0xa6, 0xd2, 0x67, 0x28, 0x33, 0xbb, 0xe7, 0x56, 0x5f, 0xc1,
+	0xa1, 0x23, 0xad, 0x1f, 0x3c, 0x75, 0x9c, 0x20, 0x92, 0x72, 0xe4, 0xfb,
+	0x60, 0x6c, 0xac, 0x5c, 0x25, 0x89, 0xe9, 0x2c, 0xb0, 0x29, 0x52, 0x1d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x78, 0xf8, 0x9f,
+	0x6b, 0x68, 0x93, 0x3b, 0xd8, 0x27, 0xa4, 0xb3, 0x34, 0x37, 0x63, 0x7b,
+	0x60, 0x22, 0x8b, 0xab, 0x06, 0x92, 0xed, 0x9e, 0x4d, 0xc7, 0x5b, 0xf1,
+	0x23, 0x65, 0x05, 0xc4, 0x6d, 0x7d, 0x04, 0x67, 0xc0, 0x27, 0x29, 0x05,
+	0x23, 0x7f, 0xf8, 0x30, 0xfe, 0x6e, 0xf3, 0x0b, 0x3a, 0x85, 0x47, 0x45,
+	0xa5, 0x1c, 0x9a, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x30, 0x7d, 0x8f, 0x0d, 0xcb, 0xce, 0x3a, 0x48, 0xd3, 0x2f, 0x09, 0xf8,
+	0xdd, 0x49, 0x49, 0x3d, 0x9f, 0x65, 0xb4, 0x4d, 0xcd, 0xa6, 0x93, 0xb2,
+	0x72, 0xe2, 0x98, 0x6e, 0xa7, 0xae, 0x0a, 0x9d, 0xcb, 0xb0, 0xc9, 0x75,
+	0x3b, 0x41, 0x79, 0x71, 0x63, 0xce, 0x55, 0x70, 0xde, 0x2a, 0x0f, 0x07,
+	0x30, 0xe5, 0x7e, 0xb9, 0xf3, 0xdf, 0x50, 0x39, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xce, 0x5b, 0xd0, 0x27, 0x82, 0x18, 0x8e, 0x41,
+	0x4b, 0x43, 0x8a, 0x62, 0x3e, 0x21, 0xce, 0x31, 0x28, 0xe2, 0xc5, 0x53,
+	0xbd, 0x97, 0xec, 0xa0, 0xc8, 0x85, 0xa4, 0x7a, 0x1e, 0xdb, 0x22, 0xc1,
+	0xbc, 0xc8, 0xa3, 0x74, 0xda, 0xd2, 0xd7, 0xa8, 0x96, 0x9e, 0x51, 0xfd,
+	0xa5, 0x74, 0x8f, 0xab, 0x55, 0x4b, 0x95, 0xb6, 0xfc, 0x3d, 0x16, 0x7d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x70, 0x9e, 0xad,
+	0xfb, 0x64, 0xff, 0xc6, 0xe7, 0x78, 0x37, 0x89, 0x04, 0x9f, 0x01, 0x16,
+	0xa1, 0x68, 0x38, 0xf0, 0xf3, 0x01, 0x25, 0xfd, 0xfa, 0xa1, 0xd3, 0x7e,
+	0x6f, 0xb6, 0x33, 0xa7, 0x44, 0x62, 0x83, 0x19, 0xec, 0x5b, 0xfe, 0x17,
+	0xa1, 0x7d, 0xe4, 0xa2, 0x7d, 0x47, 0xa5, 0x1d, 0x1f, 0x31, 0x55, 0x2d,
+	0xe2, 0x3c, 0x9a, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5f, 0xfd, 0xfd, 0x31, 0xc2, 0x6d, 0x22, 0x75, 0x97, 0x37, 0x39, 0x32,
+	0x1a, 0x88, 0x65, 0x16, 0xe9, 0xb8, 0x94, 0x35, 0xd7, 0x1e, 0x32, 0x32,
+	0x29, 0xf8, 0xfd, 0xef, 0x97, 0x26, 0xe9, 0x87, 0x32, 0xf4, 0xc9, 0x2b,
+	0x94, 0x2c, 0x85, 0x28, 0x8e, 0xb5, 0x4c, 0xf8, 0xae, 0xbf, 0xdf, 0x1a,
+	0xe3, 0xff, 0xbf, 0x0d, 0x3a, 0x8f, 0x86, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xb2, 0x45, 0xf4, 0xc9, 0xee, 0x82, 0x26, 0x2e,
+	0xe6, 0xd0, 0x97, 0x07, 0xfb, 0x72, 0xd1, 0x73, 0x98, 0x46, 0x05, 0x88,
+	0x1c, 0xba, 0xa2, 0x06, 0xd0, 0xe5, 0x49, 0xde, 0x1c, 0x6b, 0xa3, 0xe5,
+	0x5b, 0xea, 0x44, 0x4b, 0xe1, 0x5f, 0xa2, 0x77, 0x46, 0xed, 0xe6, 0x8c,
+	0x33, 0x20, 0x8e, 0x54, 0x74, 0x2f, 0x80, 0x95, 0x11, 0x50, 0x6b, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x6f, 0x6f, 0xa4,
+	0xe3, 0x4b, 0x95, 0xa3, 0x98, 0x3f, 0x0a, 0xfa, 0xf3, 0x9d, 0x9b, 0x7d,
+	0x78, 0xf9, 0x3e, 0x56, 0xd2, 0xd9, 0xb4, 0x2e, 0xd8, 0x39, 0xfb, 0x35,
+	0xe3, 0x25, 0xc5, 0xba, 0xfc, 0x18, 0xab, 0x08, 0x2d, 0x38, 0xe9, 0x4e,
+	0x68, 0xd6, 0x98, 0xad, 0x58, 0xfa, 0xd1, 0xe0, 0x55, 0x8f, 0x21, 0x1a,
+	0x11, 0x7e, 0x13, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x33, 0x19, 0x04, 0x18, 0xcf, 0x4b, 0x06, 0xf1, 0x32, 0x0f, 0xb9, 0xcb,
+	0x13, 0x81, 0x9b, 0xaf, 0x4e, 0x55, 0xaa, 0x8b, 0xea, 0x88, 0x95, 0x66,
+	0x9b, 0xf7, 0xd3, 0x58, 0xb5, 0x4b, 0x2c, 0xee, 0x18, 0xca, 0x8a, 0x94,
+	0xc9, 0x82, 0x98, 0x5d, 0x3d, 0xbc, 0xb7, 0x3c, 0x73, 0xab, 0x6c, 0x76,
+	0x7c, 0x25, 0x62, 0xfc, 0x8a, 0xef, 0xd7, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x59, 0x2d, 0xbb, 0xa7, 0xf0, 0x49, 0x6f, 0xc2,
+	0x69, 0xb1, 0xc3, 0x94, 0xf3, 0x8e, 0xf4, 0xac, 0xe3, 0x2c, 0xd9, 0x94,
+	0xfd, 0x15, 0x46, 0x54, 0x49, 0x19, 0xbc, 0x27, 0xb4, 0x8b, 0x85, 0xf5,
+	0x54, 0x81, 0x10, 0x03, 0x99, 0x13, 0x58, 0x6d, 0x0a, 0x2f, 0x6d, 0xbc,
+	0x76, 0x34, 0xd1, 0x12, 0xfe, 0xa6, 0x75, 0xf0, 0x54, 0x39, 0xb4, 0x33,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x52, 0x64, 0x73,
+	0x17, 0xb4, 0xc4, 0xcc, 0x4b, 0x72, 0xf2, 0x4d, 0xf6, 0x31, 0xb3, 0xf8,
+	0x25, 0x64, 0xdb, 0x94, 0xa7, 0x83, 0x86, 0x66, 0xad, 0xc1, 0x9f, 0x9e,
+	0xa7, 0xc9, 0x87, 0x84, 0x9c, 0x80, 0x82, 0x94, 0x36, 0xcd, 0x2a, 0xba,
+	0x04, 0x9f, 0x25, 0x9c, 0x56, 0x1a, 0x3e, 0x09, 0x07, 0xf4, 0x27, 0xae,
+	0xf2, 0x21, 0x0a, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd5, 0xe9, 0x2b, 0xb0, 0x25, 0x50, 0x73, 0x45, 0x24, 0xb4, 0xfe, 0x97,
+	0x6c, 0xaf, 0xb8, 0x72, 0xbf, 0xe2, 0xcf, 0x5d, 0xe8, 0x66, 0x84, 0x74,
+	0xd6, 0xff, 0x14, 0xc9, 0x07, 0x63, 0x58, 0x2e, 0xd2, 0x81, 0x83, 0xc9,
+	0x05, 0x9d, 0x5c, 0x9e, 0x62, 0xd2, 0x90, 0x3a, 0x6c, 0x16, 0x66, 0x7c,
+	0x2d, 0xe1, 0x2b, 0x55, 0x51, 0x2b, 0x25, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xea, 0x86, 0x65, 0xcb, 0x55, 0x08, 0x23, 0x8b,
+	0x3e, 0xd3, 0xa7, 0x88, 0x0f, 0xb1, 0xd3, 0x7f, 0xe7, 0xb8, 0x61, 0xfa,
+	0x58, 0x96, 0x51, 0x4c, 0xea, 0x4d, 0x95, 0xcd, 0x1a, 0x3e, 0x3c, 0x95,
+	0xd3, 0x07, 0xc9, 0x00, 0x66, 0x68, 0x8d, 0x25, 0x9e, 0x1c, 0x82, 0xae,
+	0x5e, 0x48, 0xea, 0xf3, 0x01, 0x27, 0x7b, 0xf2, 0xb2, 0x9b, 0x16, 0xef,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1c, 0x38, 0xc3,
+	0x1f, 0x7b, 0x41, 0x2d, 0x5d, 0xdf, 0xd9, 0xea, 0xbf, 0xad, 0x45, 0xa2,
+	0x25, 0x0b, 0xb6, 0xa3, 0xef, 0xa5, 0xdc, 0xc5, 0xe0, 0xb8, 0x4a, 0xb3,
+	0xfa, 0xb5, 0x36, 0x35, 0x77, 0xdc, 0xf4, 0xa6, 0x88, 0x53, 0xe1, 0xa3,
+	0x1e, 0xf6, 0xa6, 0x8e, 0x7a, 0xc5, 0x0b, 0xc2, 0x16, 0x3e, 0xe2, 0x27,
+	0x0f, 0x9b, 0xc4, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x81, 0x54, 0x75, 0x7f, 0xdb, 0x06, 0xbd, 0xa2, 0x4a, 0x5b, 0xa0, 0x85,
+	0xf8, 0xc5, 0x12, 0x5b, 0xbb, 0x4b, 0xa1, 0x58, 0xa5, 0xd6, 0x1d, 0x98,
+	0x04, 0x21, 0x7a, 0x30, 0x31, 0x00, 0x2c, 0x99, 0x90, 0xcf, 0x80, 0xfe,
+	0xd1, 0x6b, 0x27, 0x93, 0xef, 0x89, 0x06, 0x1b, 0x95, 0x21, 0x8b, 0xbe,
+	0x0b, 0x8d, 0x1b, 0xa0, 0x23, 0x87, 0xf0, 0xe1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x76, 0x74, 0xb2, 0xb2, 0x25, 0x00, 0x07, 0xf9,
+	0x01, 0x30, 0x2b, 0xb8, 0xf2, 0x4e, 0xb2, 0x26, 0x04, 0x11, 0x3c, 0x79,
+	0xeb, 0x4a, 0xdf, 0x53, 0x55, 0xe6, 0x6e, 0x59, 0x60, 0xcd, 0xf2, 0xa4,
+	0xd7, 0xc3, 0x0d, 0x70, 0x9d, 0x6c, 0x64, 0x2a, 0xdd, 0x9d, 0x4d, 0x83,
+	0x95, 0x94, 0xd2, 0x38, 0xd1, 0xcd, 0x6e, 0xdb, 0x33, 0x32, 0x62, 0xd4,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x62, 0x25, 0x5e,
+	0xe0, 0x13, 0x80, 0x39, 0x31, 0x0e, 0x59, 0x15, 0x9c, 0xe8, 0x75, 0xbc,
+	0x60, 0x90, 0x34, 0x3a, 0x5f, 0x7d, 0x7c, 0x0b, 0x6c, 0x3d, 0x02, 0xfd,
+	0xfa, 0xb1, 0xf7, 0xce, 0x1b, 0xec, 0x37, 0x06, 0xaf, 0xc1, 0x9f, 0x93,
+	0x6f, 0x2d, 0x40, 0x9f, 0x22, 0x52, 0xb6, 0x73, 0x8f, 0x91, 0xe1, 0x85,
+	0xfe, 0x57, 0xa6, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x42, 0xde, 0xbe, 0xf5, 0xb7, 0xca, 0x60, 0x2e, 0x10, 0x88, 0xb7, 0xfc,
+	0xbe, 0x7f, 0x06, 0x8a, 0x7d, 0xcd, 0xb1, 0xde, 0x34, 0x43, 0x19, 0x70,
+	0xab, 0xa7, 0x62, 0x0e, 0x37, 0xee, 0x28, 0x2b, 0xd7, 0x5e, 0x4c, 0x5b,
+	0x30, 0x99, 0xc3, 0x3c, 0x47, 0xfb, 0x4d, 0x92, 0xb2, 0x6c, 0xa4, 0xd9,
+	0x9d, 0xe5, 0x74, 0xe2, 0xb2, 0xec, 0x6c, 0xc9, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x60, 0x24, 0xe8, 0xa8, 0xae, 0x35, 0x55, 0x83,
+	0x99, 0xe9, 0x6e, 0xdd, 0xdb, 0x48, 0x26, 0xee, 0x7a, 0x82, 0xdc, 0xa9,
+	0xb5, 0xda, 0xf3, 0xda, 0x21, 0x36, 0x87, 0xc0, 0xc9, 0xa0, 0x0c, 0xb1,
+	0xad, 0xc8, 0x5f, 0x1e, 0x68, 0x40, 0xd9, 0x2c, 0xdb, 0x15, 0x29, 0xfd,
+	0x8f, 0x80, 0xde, 0x8b, 0xad, 0xfa, 0xd4, 0x59, 0x20, 0x94, 0x40, 0x5f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x44, 0x63, 0x52,
+	0x42, 0xef, 0x04, 0x95, 0x0b, 0xbc, 0x2e, 0xc5, 0x6d, 0x67, 0x5a, 0x26,
+	0x24, 0x8e, 0x97, 0x4c, 0x1c, 0x52, 0x85, 0xe2, 0x65, 0x2e, 0xdf, 0xc0,
+	0xe1, 0x38, 0xb2, 0x2d, 0x90, 0xd7, 0x28, 0x31, 0x88, 0xbd, 0xbd, 0x45,
+	0x1e, 0x07, 0x53, 0x0c, 0x31, 0xe3, 0x60, 0x60, 0x96, 0xdd, 0x3f, 0x14,
+	0x3d, 0xb0, 0x03, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x7b, 0x41, 0x1e, 0xcf, 0xd4, 0xa0, 0xf3, 0x55, 0xa5, 0x02, 0x3e,
+	0x43, 0xf3, 0xfe, 0x6c, 0xf5, 0x39, 0x77, 0xfe, 0x5a, 0x9d, 0xa3, 0x43,
+	0xab, 0xa4, 0x11, 0xb7, 0x3c, 0xba, 0x8e, 0xf2, 0x96, 0x22, 0x30, 0x7e,
+	0x3a, 0x89, 0xf4, 0x37, 0xc8, 0x16, 0x4a, 0xcd, 0x29, 0x3f, 0xd0, 0x6c,
+	0x96, 0x68, 0x9d, 0xac, 0x7e, 0x04, 0xee, 0xb3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x50, 0x29, 0x41, 0xcb, 0x86, 0xe0, 0xe6, 0x50,
+	0x09, 0x74, 0xf3, 0xf4, 0x79, 0x40, 0x23, 0xd8, 0xd0, 0xd8, 0xe1, 0xc2,
+	0xe4, 0xe7, 0x87, 0xbf, 0x87, 0x98, 0xff, 0x1e, 0xa1, 0x18, 0xa9, 0x11,
+	0xdd, 0x0d, 0x89, 0xdb, 0x97, 0xb2, 0xd4, 0x93, 0x13, 0x32, 0xd9, 0x48,
+	0x46, 0x4e, 0xe4, 0x7f, 0x1c, 0x3b, 0x6f, 0x60, 0xd0, 0x75, 0x88, 0x6f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xdd, 0xf3, 0xdb,
+	0xc6, 0xc8, 0xca, 0x07, 0x40, 0xe9, 0x72, 0xa3, 0x87, 0xac, 0x4e, 0x08,
+	0xa0, 0x1d, 0xd8, 0xdc, 0x23, 0xf4, 0xe1, 0xcb, 0xca, 0x2a, 0xcd, 0xbb,
+	0x23, 0xf2, 0x52, 0x92, 0x5c, 0x29, 0x62, 0x39, 0x51, 0x66, 0x09, 0x3f,
+	0x96, 0x5c, 0x2e, 0xc7, 0x50, 0xa6, 0x56, 0x07, 0x66, 0x3f, 0x2b, 0x27,
+	0x02, 0x5d, 0x43, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x16, 0x87, 0x89, 0x08, 0x15, 0xbf, 0xb4, 0xbb, 0x04, 0xb9, 0xdf, 0x77,
+	0x4e, 0x6f, 0xde, 0x97, 0x61, 0x3c, 0x6a, 0xa5, 0xef, 0x5b, 0x4e, 0x15,
+	0x26, 0xe9, 0xbc, 0x92, 0xd9, 0xd3, 0xe3, 0xbd, 0x41, 0x3f, 0xb0, 0xe3,
+	0xc6, 0xfc, 0x75, 0xef, 0xb8, 0xb1, 0x31, 0x88, 0x1e, 0x95, 0x6a, 0xa1,
+	0x54, 0x0d, 0x4f, 0xfd, 0xb3, 0xa8, 0xe8, 0x9e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc5, 0xa6, 0xa2, 0xaa, 0x79, 0x6b,
+	0xdc, 0xc8, 0x5b, 0xe6, 0xda, 0xff, 0x69, 0x22, 0x19, 0x5f, 0x5e, 0x32,
+	0x31, 0xc4, 0x83, 0x30, 0xf6, 0xa6, 0xe3, 0x3d, 0xd4, 0xc8, 0xda, 0x4c,
+	0x33, 0xef, 0x38, 0x64, 0x4a, 0x92, 0x8e, 0x83, 0x04, 0xbc, 0x79, 0x12,
+	0x5d, 0x32, 0x59, 0x71, 0xa9, 0xc8, 0x7e, 0x55, 0xc7, 0x5f, 0x98, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x56, 0x48, 0xfa,
+	0x0b, 0x31, 0x1e, 0xdf, 0xfb, 0x40, 0x81, 0xce, 0x2a, 0xf1, 0xf0, 0x85,
+	0x74, 0x0b, 0xd8, 0x5a, 0x63, 0xf0, 0xad, 0x4b, 0xc2, 0x30, 0xf5, 0x1f,
+	0xdb, 0xad, 0x34, 0xb0, 0xe5, 0xac, 0x0f, 0x59, 0xcd, 0x7f, 0x59, 0xcb,
+	0xac, 0xda, 0x7d, 0x3e, 0x2b, 0x77, 0x7c, 0x45, 0x88, 0x66, 0xe4, 0x87,
+	0x77, 0xba, 0x6e, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x38, 0x0e, 0xcd, 0x3e, 0x5c, 0x70, 0xdb, 0xb4, 0xf2, 0x59, 0x37, 0x36,
+	0xc6, 0xf6, 0x78, 0xa8, 0xfa, 0x67, 0xad, 0xad, 0x96, 0x50, 0xf4, 0xe1,
+	0x3c, 0x65, 0xd0, 0x01, 0x59, 0x08, 0x86, 0x96, 0x67, 0x9f, 0x1f, 0x27,
+	0xd4, 0xa5, 0x9d, 0xd7, 0xf2, 0x57, 0xc2, 0x81, 0x3b, 0x1d, 0xe7, 0xaa,
+	0x10, 0xfb, 0x10, 0xa0, 0xe1, 0x25, 0x5a, 0x55, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa9, 0xd1, 0x51, 0x65, 0x95, 0xdd, 0x6f, 0x89,
+	0xad, 0xcc, 0x2a, 0x76, 0xc3, 0x98, 0x26, 0x37, 0x51, 0x07, 0x98, 0x8f,
+	0x85, 0xad, 0x55, 0x38, 0x5e, 0x15, 0x4f, 0x1c, 0xe6, 0x0b, 0xe5, 0x28,
+	0x9c, 0xac, 0xc2, 0x5a, 0x73, 0x23, 0x14, 0x01, 0x71, 0x71, 0x04, 0x47,
+	0xb4, 0xd2, 0x8a, 0x77, 0x2e, 0x22, 0x42, 0xfa, 0xf0, 0x82, 0x86, 0x70,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x1a, 0x11, 0x5a,
+	0x4a, 0xea, 0xae, 0x0a, 0x88, 0x53, 0x09, 0x1a, 0x75, 0xc4, 0x40, 0x1d,
+	0x74, 0x03, 0x44, 0xc8, 0xe3, 0xca, 0x1b, 0xab, 0xee, 0x22, 0xb3, 0xc1,
+	0xef, 0xe6, 0xb8, 0x16, 0x29, 0x07, 0xd8, 0x0b, 0x7e, 0x67, 0xcb, 0xea,
+	0xbd, 0x27, 0x8e, 0x0f, 0x28, 0xac, 0xe6, 0x6d, 0x47, 0x5d, 0x6f, 0x17,
+	0xa2, 0xf8, 0x5d, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x48, 0xea, 0x89, 0x16, 0x74, 0x70, 0x2c, 0x27, 0x93, 0x3a, 0xe7, 0x20,
+	0x03, 0xd8, 0x35, 0x5c, 0xae, 0xaa, 0x2e, 0xc8, 0x45, 0xf3, 0x13, 0xcf,
+	0x65, 0x8d, 0x10, 0x93, 0x53, 0xac, 0x9b, 0x68, 0xf9, 0x03, 0x46, 0x41,
+	0xf4, 0xc5, 0x9e, 0x04, 0x94, 0x79, 0x6e, 0x6f, 0x8c, 0xf5, 0x09, 0x0d,
+	0xfe, 0x92, 0x82, 0x98, 0x01, 0x68, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0x7c, 0x5d, 0xa1, 0x01, 0x26, 0xe6, 0x0a,
+	0x7d, 0x9c, 0xb0, 0xbf, 0x8b, 0xd0, 0x64, 0x3c, 0x38, 0x19, 0x81, 0x43,
+	0x4a, 0x57, 0xfd, 0x7a, 0x93, 0xc7, 0xc8, 0x0a, 0x2e, 0x56, 0x49, 0x07,
+	0x6e, 0x7d, 0x64, 0xed, 0x2b, 0x86, 0x53, 0x9f, 0x95, 0x74, 0xa7, 0x69,
+	0x3d, 0x96, 0x41, 0xb8, 0xca, 0x02, 0xfd, 0xf0, 0xa4, 0xc7, 0x18, 0x49,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x54, 0xe4, 0x81,
+	0xa7, 0xb6, 0x5e, 0x08, 0xe6, 0x8b, 0xc5, 0xb0, 0xad, 0x5a, 0xe3, 0x09,
+	0x31, 0xe5, 0x2b, 0x5d, 0xa1, 0x4f, 0xac, 0x93, 0x49, 0x22, 0xac, 0xfc,
+	0x61, 0x47, 0x51, 0xde, 0xae, 0x8a, 0xd9, 0x9f, 0xcb, 0x9f, 0xcf, 0x78,
+	0xa5, 0x13, 0xf5, 0xcf, 0xd3, 0xc1, 0x49, 0x5a, 0x7b, 0x8e, 0xf0, 0x5e,
+	0xad, 0x9d, 0x6e, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x94, 0x0a, 0x05, 0x03, 0x02, 0x48, 0xa0, 0x7a, 0xd0, 0x3e, 0x53, 0x73,
+	0x6a, 0x9c, 0xee, 0x03, 0x98, 0xe2, 0x60, 0x2a, 0x65, 0x78, 0xbd, 0x89,
+	0x8b, 0x00, 0x67, 0x61, 0x20, 0x81, 0x49, 0xbc, 0xc9, 0x3b, 0x4f, 0x19,
+	0x91, 0x54, 0xba, 0x9d, 0x7c, 0xe1, 0x80, 0xed, 0x74, 0x4f, 0x88, 0x04,
+	0xf5, 0x9b, 0x56, 0xd3, 0x3c, 0x9c, 0xfb, 0xc0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xac, 0x49, 0xa7, 0x7e, 0x71, 0xf8, 0xba, 0x16,
+	0xaa, 0xda, 0x08, 0x92, 0x96, 0xbc, 0xa5, 0x33, 0x3e, 0xbc, 0xff, 0x50,
+	0xe0, 0xba, 0x41, 0x43, 0xeb, 0x2c, 0x10, 0x58, 0x9f, 0x85, 0xa7, 0xd9,
+	0xb1, 0x2d, 0x3a, 0xb4, 0x62, 0x08, 0x91, 0x73, 0xaa, 0x42, 0x1e, 0x96,
+	0x63, 0xf3, 0x1b, 0xaf, 0xcf, 0x76, 0x7b, 0x41, 0x8b, 0x69, 0x26, 0x05,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xa3, 0x1f, 0xb3,
+	0x67, 0xef, 0x7b, 0xfb, 0x4b, 0xfc, 0x59, 0x9e, 0xe7, 0xab, 0xb6, 0x35,
+	0xa2, 0xf1, 0xdf, 0xd6, 0x1d, 0x9e, 0xbb, 0xfd, 0x91, 0x6a, 0x7f, 0x0c,
+	0xc6, 0x2c, 0x07, 0x69, 0x64, 0xd0, 0xda, 0xb3, 0xc6, 0xbf, 0x62, 0x1e,
+	0x4d, 0x48, 0xd5, 0xb4, 0xa4, 0x43, 0xff, 0x91, 0x87, 0xc6, 0x54, 0x10,
+	0xf9, 0xd6, 0xb3, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4f, 0x95, 0x17, 0xe1, 0xf7, 0x38, 0x63, 0x16, 0x3b, 0x02, 0x2f, 0x5a,
+	0x45, 0x64, 0xf1, 0x93, 0xa1, 0xf1, 0xe4, 0x29, 0x62, 0x7c, 0x0c, 0x50,
+	0x3b, 0x49, 0x55, 0x86, 0x9d, 0xc3, 0xe7, 0xf8, 0xc4, 0x65, 0x30, 0x58,
+	0xee, 0x3e, 0x1f, 0x9b, 0x6f, 0x2a, 0xea, 0x23, 0x27, 0x9a, 0x0e, 0xe7,
+	0x6b, 0x96, 0x4b, 0xcb, 0x21, 0xae, 0x1b, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa6, 0x88, 0x80, 0x5b, 0xfb, 0x9f, 0xee, 0x70,
+	0x2b, 0xd4, 0xb4, 0x7d, 0x2c, 0x05, 0x9a, 0xea, 0x0b, 0xa5, 0xeb, 0xc0,
+	0x9f, 0x6c, 0x66, 0x8c, 0xc5, 0x6a, 0x36, 0x87, 0x04, 0xd2, 0x1a, 0x83,
+	0xa5, 0xcf, 0x38, 0xd9, 0x74, 0x52, 0xd3, 0x9c, 0xeb, 0xa4, 0xf9, 0x26,
+	0xf3, 0xc0, 0xdc, 0x94, 0xc0, 0x7f, 0x54, 0x87, 0x62, 0x77, 0x2d, 0x4c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x16, 0x58, 0x49,
+	0xb1, 0x96, 0x15, 0x03, 0x33, 0x7e, 0x44, 0xc4, 0xd6, 0xa6, 0xcb, 0x61,
+	0x57, 0x2b, 0x93, 0x72, 0x8b, 0xad, 0x37, 0xbf, 0x80, 0x3d, 0x79, 0x52,
+	0x0c, 0x18, 0x30, 0x38, 0xc9, 0x69, 0xec, 0x11, 0x45, 0x14, 0x9e, 0xe5,
+	0x47, 0x4d, 0xbb, 0x1b, 0x2c, 0x91, 0x6d, 0x6e, 0x09, 0xf7, 0xbc, 0xc9,
+	0x25, 0x12, 0x98, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc1, 0x16, 0xd7, 0xe8, 0x42, 0x8e, 0xa5, 0x9a, 0xc4, 0x93, 0xc7, 0x86,
+	0x84, 0x45, 0x8e, 0x0f, 0x05, 0x20, 0xfa, 0x16, 0xad, 0xcc, 0x8a, 0x10,
+	0x99, 0x1b, 0x69, 0x56, 0x19, 0xb2, 0x99, 0xc3, 0x2f, 0x4a, 0xf8, 0x11,
+	0x87, 0x99, 0x26, 0x14, 0x81, 0x71, 0xc6, 0x77, 0x84, 0x6b, 0x8d, 0xe2,
+	0xc8, 0xf1, 0x9a, 0x5a, 0x66, 0x67, 0x7d, 0x52, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xbd, 0xd3, 0x7a, 0x37, 0x12, 0x9e, 0xc2, 0x18,
+	0x96, 0x1d, 0x51, 0x31, 0xd9, 0x28, 0xcd, 0x7d, 0xc3, 0x07, 0x9d, 0x98,
+	0xcf, 0x06, 0x82, 0x77, 0xa7, 0xbf, 0xb0, 0xae, 0x7d, 0x8a, 0xc3, 0x0d,
+	0x65, 0xe9, 0x66, 0x91, 0xb6, 0xff, 0x97, 0xb8, 0x67, 0xad, 0x51, 0xd0,
+	0xae, 0x5b, 0x70, 0x7a, 0x25, 0x6e, 0x41, 0x58, 0x62, 0xc3, 0xc8, 0xcb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xb1, 0x7f,
+	0xfd, 0x70, 0x84, 0xba, 0x1e, 0xcf, 0x48, 0x23, 0xcd, 0x84, 0xdf, 0x17,
+	0x06, 0x1e, 0x97, 0x93, 0xad, 0x67, 0x18, 0x97, 0xee, 0xc8, 0xd8, 0x6a,
+	0x20, 0x89, 0x5a, 0x9e, 0x54, 0x9c, 0xd7, 0x22, 0x4b, 0xde, 0x69, 0xfd,
+	0x6b, 0x28, 0xbb, 0x68, 0xfa, 0x05, 0x42, 0xe7, 0x79, 0x65, 0xe5, 0x6d,
+	0x16, 0x71, 0x76, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6c, 0x12, 0x82, 0xb8, 0x7e, 0x03, 0x01, 0x68, 0x5a, 0x51, 0x60, 0xf1,
+	0xe3, 0xd0, 0x45, 0x67, 0x2f, 0x47, 0x4d, 0xb4, 0x97, 0x5c, 0xbd, 0x13,
+	0x50, 0x89, 0xfe, 0x19, 0x4e, 0x4f, 0xad, 0x05, 0x17, 0x3a, 0x84, 0x33,
+	0xaa, 0x15, 0x75, 0xdb, 0x59, 0x34, 0x4c, 0x01, 0xa2, 0x54, 0xc3, 0x21,
+	0x4e, 0xbd, 0x2b, 0xf3, 0x23, 0x19, 0xef, 0xa0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfa, 0x3e, 0x81, 0xb5, 0xd9, 0xe3, 0x5e, 0x50,
+	0xa9, 0x76, 0xc7, 0x31, 0x06, 0x82, 0xf1, 0xc8, 0xc6, 0x6c, 0x9f, 0xa6,
+	0xad, 0x6b, 0x6d, 0x1b, 0x1d, 0x2f, 0xa1, 0x01, 0xd7, 0x72, 0x99, 0x08,
+	0xc1, 0x2f, 0x29, 0xe4, 0x63, 0xc0, 0x32, 0x66, 0x7f, 0x32, 0x55, 0xbd,
+	0x93, 0x0f, 0x10, 0xef, 0x83, 0x29, 0x35, 0x55, 0xba, 0xe0, 0x8c, 0x3f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x71, 0x81, 0x3f,
+	0x62, 0x01, 0xb6, 0x6d, 0xe0, 0x21, 0xac, 0x3a, 0x82, 0x88, 0x77, 0x61,
+	0x3c, 0xea, 0xa0, 0x07, 0x7d, 0x10, 0xd7, 0xaf, 0x17, 0xef, 0x0a, 0x4e,
+	0x44, 0xb4, 0x8b, 0x65, 0x3b, 0x58, 0xc6, 0xb0, 0xec, 0x88, 0x69, 0xb5,
+	0x7a, 0x03, 0xf1, 0xdc, 0x36, 0x05, 0x20, 0xfc, 0xcd, 0xe5, 0x6c, 0x3a,
+	0x19, 0xb3, 0x62, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5c, 0x7c, 0x07, 0xc6, 0xb7, 0x1f, 0x25, 0xdf, 0x7d, 0x8d, 0x81, 0x61,
+	0xeb, 0x3e, 0xbf, 0xe7, 0x10, 0x81, 0xf1, 0x85, 0x40, 0xcb, 0x60, 0xf1,
+	0xae, 0x1a, 0xba, 0xc5, 0xda, 0x60, 0x1c, 0x0f, 0x6d, 0x47, 0xfd, 0xa2,
+	0x56, 0x13, 0x67, 0x02, 0x7c, 0xd9, 0xc5, 0x56, 0x32, 0x69, 0x12, 0xc7,
+	0x8f, 0x2f, 0x31, 0x2c, 0x0f, 0xd2, 0x94, 0x69, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0x20, 0x93, 0x21, 0xb2, 0x35, 0xf1,
+	0x80, 0x14, 0x8e, 0xf1, 0x0c, 0x28, 0x62, 0x8d, 0xb8, 0xcf, 0x6c, 0x9e,
+	0xf6, 0xdb, 0x18, 0x16, 0x0b, 0xbd, 0xe9, 0xb4, 0xa3, 0x75, 0xee, 0xb2,
+	0x55, 0x1e, 0x4c, 0xc7, 0xa7, 0x74, 0xe8, 0x0e, 0x8f, 0xb7, 0xa8, 0x04,
+	0xf3, 0xeb, 0x1c, 0x35, 0xd6, 0x1d, 0x1b, 0x2a, 0x51, 0x10, 0xa2, 0x67,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x1c, 0x40, 0x29,
+	0xfa, 0x43, 0x18, 0x0c, 0x4c, 0xc0, 0xcd, 0x55, 0x99, 0xd0, 0xb9, 0xb4,
+	0x55, 0x69, 0x7d, 0xad, 0x99, 0xb8, 0xec, 0x62, 0x0c, 0x3b, 0x71, 0x11,
+	0xf0, 0xba, 0x59, 0x19, 0x93, 0xef, 0xcd, 0x2c, 0x29, 0x02, 0x8b, 0x76,
+	0x85, 0x21, 0xc1, 0xad, 0x72, 0x67, 0x87, 0xd1, 0x8f, 0xc6, 0x05, 0xe7,
+	0x82, 0x4e, 0x95, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
 const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p192,
@@ -1267,7 +1835,15 @@ const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p256_sm2,
 		.len = sizeof(ae_fpm_tbl_p256_sm2)
-	}
+	},
+	{
+		.data = ae_fpm_tbl_ed25519,
+		.len = sizeof(ae_fpm_tbl_ed25519)
+	},
+	{
+		.data = ae_fpm_tbl_ed448,
+		.len = sizeof(ae_fpm_tbl_ed448)
+	},
 };
 
 int
diff --git a/drivers/crypto/cnxk/cnxk_ae.h b/drivers/crypto/cnxk/cnxk_ae.h
index ef9cb5eb91..431d66c535 100644
--- a/drivers/crypto/cnxk/cnxk_ae.h
+++ b/drivers/crypto/cnxk/cnxk_ae.h
@@ -205,6 +205,12 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_EC_GROUP_SM2:
 		ec->curveid = ROC_AE_EC_ID_SM2;
 		break;
+	case RTE_CRYPTO_EC_GROUP_ED25519:
+		ec->curveid = ROC_AE_EC_ID_ED25519;
+		break;
+	case RTE_CRYPTO_EC_GROUP_ED448:
+		ec->curveid = ROC_AE_EC_ID_ED448;
+		break;
 	default:
 		/* Only NIST curves (FIPS 186-4) and SM2 are supported */
 		return -EINVAL;
@@ -225,6 +231,12 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	if (ec->q.x.length)
 		rte_memcpy(ec->q.x.data, xform->ec.q.x.data, ec->q.x.length);
 
+	/* Use q.x to store compressed public key. q.y is set to 0 */
+	if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_EDDSA) {
+		ec->q.y.length = 0;
+		return 0;
+	}
+
 	ec->q.y.length = xform->ec.q.y.length;
 	if (ec->q.y.length > ROC_AE_EC_DATA_MAX)
 		ec->q.y.length = ROC_AE_EC_DATA_MAX;
@@ -255,6 +267,7 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
 	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
 		ret = cnxk_ae_fill_ec_params(sess, xform);
 		break;
 	default:
@@ -736,6 +749,330 @@ cnxk_ae_enqueue_ecdsa_op(struct rte_crypto_op *op,
 	return 0;
 }
 
+static __rte_always_inline void
+cnxk_ae_eddsa_sign_prep(struct rte_crypto_eddsa_op_param *eddsa,
+			struct roc_ae_buf_ptr *meta_buf,
+			uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
+			struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t pkey_len = sess->ec_ctx.pkey.length;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint16_t ctx_align, k_align;
+	uint16_t prime_bit, iv_len;
+	uint8_t pub = 0, ph = 0;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint8_t ctx_len = 0;
+	uint64_t ctrl = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	if (pubkey_len)
+		pub = 1;
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pkey_len, 8);
+
+	/* Set control word */
+	ctrl |= message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	rte_memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(priv and
+	 * pubkey len), ROUNDUP8(context len) and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) +
+		sizeof(ctrl) + prime_len * 3 + k_align * 2 +
+		ctx_align + iv_len;
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.pkey.data, pkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_SIGN;
+
+	w4.s.param1 = prime_bit |
+					(pub << ROC_AE_ED_PARAM1_KEYGEN_BIT) |
+					(ph << ROC_AE_EC_PARAM1_PH_BIT);
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline void
+cnxk_ae_eddsa_verify_prep(struct rte_crypto_eddsa_op_param *eddsa,
+			  struct roc_ae_buf_ptr *meta_buf,
+			  uint64_t fpm_table_iova,
+			  struct roc_ae_ec_group *ec_grp, struct cnxk_ae_sess *sess,
+			  struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t s_len = eddsa->sign.length / 2;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	uint16_t ctx_align, k_align, s_align;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint16_t prime_bit, iv_len;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint8_t ctx_len = 0;
+	uint64_t ctrl = 0;
+	uint8_t ph = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pubkey_len, 8);
+	s_align = RTE_ALIGN_CEIL(s_len, 8);
+
+	/* Set control word */
+	ctrl |= message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	rte_memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(pub key len),
+	 * ROUNDUP8(s and r len), context and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) +
+		sizeof(ctrl) + prime_len * 3 + k_align + s_align * 2 +
+		ctx_align + iv_len;
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, eddsa->sign.data, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, eddsa->sign.data + s_len, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_VERIFY;
+
+	w4.s.param1 = prime_bit |
+					(ph << ROC_AE_EC_PARAM1_PH_BIT);
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline int __rte_hot
+cnxk_ae_enqueue_eddsa_op(struct rte_crypto_op *op,
+			 struct roc_ae_buf_ptr *meta_buf,
+			 struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
+			 struct roc_ae_ec_group **ec_grp,
+			 struct cpt_inst_s *inst)
+{
+	struct rte_crypto_eddsa_op_param *eddsa = &op->asym->eddsa;
+	uint8_t curveid = sess->ec_ctx.curveid;
+
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+		cnxk_ae_eddsa_sign_prep(eddsa, meta_buf, fpm_iova[curveid],
+					ec_grp[curveid], sess, inst);
+	else if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		cnxk_ae_eddsa_verify_prep(eddsa, meta_buf, fpm_iova[curveid],
+					  ec_grp[curveid], sess, inst);
+	else {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static __rte_always_inline void
 cnxk_ae_sm2_sign_prep(struct rte_crypto_sm2_op_param *sm2,
 			struct roc_ae_buf_ptr *meta_buf,
@@ -1004,6 +1341,88 @@ cnxk_ae_ecfpm_prep(rte_crypto_param *scalar,
 	return 0;
 }
 
+static __rte_always_inline int
+cnxk_ae_edfpm_prep(rte_crypto_param *scalar,
+		   struct roc_ae_buf_ptr *meta_buf, uint64_t *fpm_iova,
+		   struct roc_ae_ec_group *ec_grp, uint8_t curveid,
+		   struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	uint16_t dlen, prime_len, order_len, iv_len;
+	uint16_t scalar_align, p_align, o_offset;
+	uint64_t fpm_table_iova;
+	union cpt_inst_w4 w4;
+	uint16_t prime_bit;
+	uint8_t *dptr;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	fpm_table_iova = (uint64_t)fpm_iova[curveid];
+
+	/* Input buffer */
+	dptr = meta_buf->vaddr;
+	inst->dptr = (uintptr_t)dptr;
+
+	p_align = RTE_ALIGN_CEIL(prime_len, 8);
+	scalar_align = RTE_ALIGN_CEIL(scalar->length, 8);
+
+	/* Set write offset for order and key */
+	o_offset = p_align - order_len;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(prime len, order len, constant,
+	 * private key len and iv len (if ED25519))).
+	 */
+	dlen = sizeof(fpm_table_iova) + 3 * p_align + scalar_align + iv_len;
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += p_align;
+	memcpy(dptr + o_offset, ec_grp->order.data, order_len);
+	dptr += p_align;
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += p_align;
+	memcpy(dptr, scalar->data, scalar->length);
+	dptr += scalar_align;
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, sizeof(iv_sha512));
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_KEYGEN;
+
+	w4.s.param1 = prime_bit;
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+
+	return 0;
+}
+
 static __rte_always_inline int
 cnxk_ae_ecpm_prep(rte_crypto_param *scalar, struct rte_crypto_ec_point *p,
 		  struct roc_ae_buf_ptr *meta_buf,
@@ -1112,8 +1531,12 @@ cnxk_ae_enqueue_ecdh_op(struct rte_crypto_op *op,
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		scalar.data = sess->ec_ctx.pkey.data;
 		scalar.length = sess->ec_ctx.pkey.length;
-		cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
-			curveid, inst);
+		if (curveid == ROC_AE_EC_ID_ED25519 || curveid == ROC_AE_EC_ID_ED448)
+			cnxk_ae_edfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
+		else
+			cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		scalar.data = ec_grp[curveid]->order.data;
@@ -1212,6 +1635,30 @@ cnxk_ae_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa, uint8_t *rptr,
 	ecdsa->s.length = prime_len;
 }
 
+static __rte_always_inline void
+cnxk_ae_dequeue_eddsa_op(struct rte_crypto_eddsa_op_param *eddsa, uint8_t *rptr,
+			 struct roc_ae_ec_ctx *ec,
+			 struct roc_ae_ec_group **ec_grp)
+{
+	RTE_SET_USED(ec);
+	RTE_SET_USED(ec_grp);
+
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519 ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519CTX ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH) {
+		eddsa->sign.length = 64;
+		rte_memcpy(eddsa->sign.data, rptr, eddsa->sign.length);
+	} else {
+		eddsa->sign.length = 114;
+		rte_memcpy(eddsa->sign.data, rptr, 57);
+		rte_memcpy(eddsa->sign.data + 57, rptr + 64, 57);
+	}
+}
+
 static __rte_always_inline void
 cnxk_ae_dequeue_sm2_op(struct rte_crypto_sm2_op_param *sm2, uint8_t *rptr,
 			 struct roc_ae_ec_ctx *ec,
@@ -1245,7 +1692,7 @@ cnxk_ae_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param *ecpm, uint8_t *rptr,
 static __rte_always_inline void
 cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 			struct roc_ae_ec_ctx *ec,
-			struct roc_ae_ec_group **ec_grp)
+			struct roc_ae_ec_group **ec_grp, uint16_t flags)
 {
 	int prime_len = ec_grp[ec->curveid]->prime.length;
 
@@ -1256,9 +1703,12 @@ cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		memcpy(ecdh->pub_key.x.data, rptr, prime_len);
-		memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
 		ecdh->pub_key.x.length = prime_len;
-		ecdh->pub_key.y.length = prime_len;
+		if (!(flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED)) {
+			memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8),
+				prime_len);
+			ecdh->pub_key.y.length = prime_len;
+		}
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		break;
@@ -1328,6 +1778,13 @@ cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		ret = cnxk_ae_enqueue_eddsa_op(op, &meta_buf, sess,
+					       sess->cnxk_fpm_iova,
+					       sess->ec_grp, inst);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		ret = cnxk_ae_enqueue_sm2_op(op, &meta_buf, sess,
 					       sess->cnxk_fpm_iova,
@@ -1390,6 +1847,10 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		cnxk_ae_dequeue_ecdsa_op(&op->ecdsa, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		cnxk_ae_dequeue_eddsa_op(&op->eddsa, rptr, &sess->ec_ctx,
+					 sess->ec_grp);
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		cnxk_ae_dequeue_sm2_op(&op->sm2, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
@@ -1401,7 +1862,7 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_ECDH:
 		cnxk_ae_dequeue_ecdh_op(&op->ecdh, rptr, &sess->ec_ctx,
-					sess->ec_grp);
+					sess->ec_grp, op->flags);
 		break;
 	default:
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index 4000e84a7e..5cec64c2e1 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -11,7 +11,7 @@
 #include "roc_ae.h"
 #include "roc_cpt.h"
 
-#define CNXK_CPT_MAX_CAPS		 55
+#define CNXK_CPT_MAX_CAPS		 56
 #define CNXK_SEC_IPSEC_CRYPTO_MAX_CAPS	 16
 #define CNXK_SEC_TLS_1_3_CRYPTO_MAX_CAPS 3
 #define CNXK_SEC_TLS_1_2_CRYPTO_MAX_CAPS 7
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index 0d5d64b6e7..3897feacb8 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -1201,6 +1201,22 @@ static const struct rte_cryptodev_capabilities caps_sm2[] = {
 	}
 };
 
+static const struct rte_cryptodev_capabilities caps_eddsa[] = {
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					     (1 << RTE_CRYPTO_ASYM_OP_VERIFY))
+			}
+		}
+		}
+	}
+};
+
 static const struct rte_cryptodev_capabilities caps_end[] = {
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1940,6 +1956,9 @@ cn10k_crypto_caps_add(struct rte_cryptodev_capabilities cnxk_caps[],
 
 	if (hw_caps[CPT_ENG_TYPE_AE].sm2)
 		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, sm2);
+
+	if (hw_caps[CPT_ENG_TYPE_AE].eddsa)
+		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, eddsa);
 }
 
 static void
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v2 4/6] test/crypto: add asymmetric EDDSA test cases
  2024-09-05 13:39 ` Gowrishankar Muthukrishnan
  2024-09-05 13:39   ` [PATCH v2 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
  2024-09-05 13:39   ` [PATCH v2 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
@ 2024-09-05 13:39   ` Gowrishankar Muthukrishnan
  2024-09-05 13:39   ` [PATCH v2 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
  2024-09-05 13:39   ` [PATCH v2 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
  4 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-05 13:39 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, ciara.power, jerinj,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Gowrishankar Muthukrishnan

Add test cases to validate EDDSA sign and verify ops,
as per RFC 8032.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test/test_cryptodev_asym.c               | 357 +++++++++++-
 app/test/test_cryptodev_ecdh_test_vectors.h  |  94 +++-
 app/test/test_cryptodev_ecdsa_test_vectors.h |   4 +
 app/test/test_cryptodev_eddsa_test_vectors.h | 556 +++++++++++++++++++
 4 files changed, 1005 insertions(+), 6 deletions(-)
 create mode 100644 app/test/test_cryptodev_eddsa_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index f0b5d38543..23fd3537bc 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -20,6 +20,7 @@
 #include "test_cryptodev_ecdh_test_vectors.h"
 #include "test_cryptodev_ecdsa_test_vectors.h"
 #include "test_cryptodev_ecpm_test_vectors.h"
+#include "test_cryptodev_eddsa_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_sm2_test_vectors.h"
@@ -1631,6 +1632,9 @@ test_ecdsa_sign_verify_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
+		if (curve_id == ED25519 || curve_id == ED448)
+			continue;
+
 		status = test_ecdsa_sign_verify(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
@@ -1792,7 +1796,7 @@ test_ecpm_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecpm(curve_id);
@@ -1987,6 +1991,12 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	case SECP521R1:
 		input_params = ecdh_param_secp521r1;
 		break;
+	case ED25519:
+		input_params = ecdh_param_ed25519;
+		break;
+	case ED448:
+		input_params = ecdh_param_ed448;
+		break;
 	default:
 		RTE_LOG(ERR, USER1,
 				"line %u FAILED: %s", __LINE__,
@@ -2031,6 +2041,8 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 
 	/* Populate op with operational details */
 	asym_op->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
 
 	/* Init out buf */
 	asym_op->ecdh.pub_key.x.data = output_buf_x;
@@ -2073,8 +2085,13 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	debug_hexdump(stdout, "qy:",
 		asym_op->ecdh.pub_key.y.data, asym_op->ecdh.pub_key.y.length);
 
-	ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
+	if (curve_id == ED25519 || curve_id == ED448)
+		ret = memcmp(input_params.pubkey_qA_x.data, result_op->asym->ecdh.pub_key.x.data,
+			   result_op->asym->ecdh.pub_key.x.length);
+	else
+		ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
 				input_params.pubkey_qA_y.data, result_op);
+
 	if (ret) {
 		status = TEST_FAILED;
 		RTE_LOG(ERR, USER1,
@@ -2484,7 +2501,7 @@ test_ecdh_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_priv_key_generate(curve_id);
@@ -2514,7 +2531,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_pub_key_verify(curve_id);
@@ -2529,7 +2546,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_shared_secret(curve_id);
@@ -3167,6 +3184,334 @@ test_sm2_dec(void)
 	return status;
 };
 
+static int
+test_eddsa_sign(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct rte_cryptodev_asym_capability_idx idx;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return -ENOTSUP;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.data = input_params->pkey.data;
+	xform.ec.pkey.length = input_params->pkey.length;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	/* Init out buf */
+	asym_op->eddsa.sign.data = output_buf_r;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "sign:",
+			asym_op->eddsa.sign.data, asym_op->eddsa.sign.length);
+
+	/* Verify sign (by comparison). */
+	if (memcmp(input_params->sign.data, asym_op->eddsa.sign.data,
+			   asym_op->eddsa.sign.length) != 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"EDDSA sign failed.\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_verify(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct rte_cryptodev_asym_capability_idx idx;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return -ENOTSUP;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.data = input_params->pkey.data;
+	xform.ec.pkey.length = input_params->pkey.length;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	/* Init out buf */
+	asym_op->eddsa.sign.data = input_params->sign.data;
+	asym_op->eddsa.sign.length = input_params->sign.length;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "sign:",
+			asym_op->eddsa.sign.data, asym_op->eddsa.sign.length);
+
+	/* Verify sign (by comparison). */
+	if (memcmp(input_params->sign.data, asym_op->eddsa.sign.data,
+			   asym_op->eddsa.sign.length) != 0) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"EDDSA sign failed.\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_sign_verify_all_curve(void)
+{
+	struct crypto_testsuite_eddsa_params input_params;
+	int status, overall_status = TEST_SUCCESS;
+	uint8_t i, tc = 0;
+	const char *msg;
+
+	/* Sign tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_sign(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Sign %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Verify tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_verify(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Verify %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Negative tests */
+	memcpy(&input_params, &eddsa_test_params[1],
+			sizeof(input_params));
+	input_params.pubkey.data[0] ^= 0x01;
+
+	status = test_eddsa_sign(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else if (status == TEST_SKIPPED) {
+		msg = "skipped";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Sign %s  %s\n",
+			tc++, input_params.description, msg);
+
+	status = test_eddsa_verify(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else if (status == TEST_SKIPPED) {
+		msg = "skipped";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Verify %s  %s\n",
+			tc++, input_params.description, msg);
+
+	return overall_status;
+}
+
 static int send_one(void)
 {
 	int ticks = 0;
@@ -3543,6 +3888,7 @@ static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 			"Modex Group 18 test",
 			ut_setup_asym, ut_teardown_asym,
 			modular_exponentiation, &modex_group_test_cases[5]),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
@@ -3634,6 +3980,7 @@ static struct unit_test_suite cryptodev_octeontx_asym_testsuite  = {
 				test_ecdh_all_curve),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
 				test_ecpm_all_curve),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_ecdh_test_vectors.h b/app/test/test_cryptodev_ecdh_test_vectors.h
index b577c179c8..4e587a3b01 100644
--- a/app/test/test_cryptodev_ecdh_test_vectors.h
+++ b/app/test/test_cryptodev_ecdh_test_vectors.h
@@ -553,4 +553,96 @@ struct crypto_testsuite_ecdh_params ecdh_param_secp521r1 = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP521R1
 };
 
-#endif /* __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__ */
+/** ED25519 test vector */
+
+static uint8_t dA_ed25519[] = {
+	0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+	0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+	0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+	0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+};
+
+static uint8_t x_qA_ed25519[] = {
+	0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+	0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+	0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+	0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+};
+
+/** ECDH ED25519 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed25519 = {
+	.pubkey_qA_x = {
+		.data = x_qA_ed25519,
+		.length = sizeof(x_qA_ed25519),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = dA_ed25519,
+		.length = sizeof(dA_ed25519),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519
+};
+
+/** ED448 test vector */
+
+static uint8_t dA_ed448[] = {
+	0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+	0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+	0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+	0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+	0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+	0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+	0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+	0x01
+};
+
+static uint8_t x_qA_ed448[] = {
+	0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+	0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+	0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+	0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+	0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+	0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+	0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+	0x00
+};
+
+/** ECDH ED448 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed448 = {
+	.pubkey_qA_x = {
+		.data = x_qA_ed448,
+		.length = sizeof(x_qA_ed448),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = dA_ed448,
+		.length = sizeof(dA_ed448),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448
+};
+
+#endif /* __TEST_CRYPTODEV_ECDH_TEST_VECTORS_H__ */
diff --git a/app/test/test_cryptodev_ecdsa_test_vectors.h b/app/test/test_cryptodev_ecdsa_test_vectors.h
index f1477639ba..636a1ab1b2 100644
--- a/app/test/test_cryptodev_ecdsa_test_vectors.h
+++ b/app/test/test_cryptodev_ecdsa_test_vectors.h
@@ -15,6 +15,8 @@ enum curve {
 	SECP384R1,
 	SECP521R1,
 	SECP521R1_UA,
+	ED25519,
+	ED448,
 	END_OF_CURVE_LIST
 };
 
@@ -24,6 +26,8 @@ const char *curve[] = {"SECP192R1",
 		       "SECP384R1",
 		       "SECP521R1",
 		       "SECP521R1(unaligned)",
+		       "ED25519",
+		       "ED448",
 };
 
 struct crypto_testsuite_ecdsa_params {
diff --git a/app/test/test_cryptodev_eddsa_test_vectors.h b/app/test/test_cryptodev_eddsa_test_vectors.h
new file mode 100644
index 0000000000..47e5355ec7
--- /dev/null
+++ b/app/test/test_cryptodev_eddsa_test_vectors.h
@@ -0,0 +1,556 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifndef __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+#define DATA_SIZE 1024
+
+struct crypto_testsuite_eddsa_params {
+	enum rte_crypto_edward_instance instance;
+	enum rte_crypto_curve_id curve;
+	const char *description;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pubkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} sign;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} message;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} context;
+};
+
+/** EDDSA curve test params (RFC 8032) */
+static const struct
+crypto_testsuite_eddsa_params eddsa_test_params[] = {
+{
+	.description = "EDDSA 25519 (msg=0)",
+	.pkey = {
+		.data = {
+			0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
+			0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4,
+			0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19,
+			0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7,
+			0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a,
+			0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25,
+			0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72,
+			0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a,
+			0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74,
+			0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55,
+			0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
+			0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b,
+			0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
+			0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1)",
+	.pkey = {
+		.data = {
+			0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+			0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+			0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+			0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+			0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+			0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+			0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+			0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+			0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+			0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+			0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+			0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+			0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+			0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x72
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1023)",
+	.pkey = {
+		.data = {
+			0xf5, 0xe5, 0x76, 0x7c, 0xf1, 0x53, 0x31, 0x95,
+			0x17, 0x63, 0x0f, 0x22, 0x68, 0x76, 0xb8, 0x6c,
+			0x81, 0x60, 0xcc, 0x58, 0x3b, 0xc0, 0x13, 0x74,
+			0x4c, 0x6b, 0xf2, 0x55, 0xf5, 0xcc, 0x0e, 0xe5
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x27, 0x81, 0x17, 0xfc, 0x14, 0x4c, 0x72, 0x34,
+			0x0f, 0x67, 0xd0, 0xf2, 0x31, 0x6e, 0x83, 0x86,
+			0xce, 0xff, 0xbf, 0x2b, 0x24, 0x28, 0xc9, 0xc5,
+			0x1f, 0xef, 0x7c, 0x59, 0x7f, 0x1d, 0x42, 0x6e
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x0a, 0xab, 0x4c, 0x90, 0x05, 0x01, 0xb3, 0xe2,
+			0x4d, 0x7c, 0xdf, 0x46, 0x63, 0x32, 0x6a, 0x3a,
+			0x87, 0xdf, 0x5e, 0x48, 0x43, 0xb2, 0xcb, 0xdb,
+			0x67, 0xcb, 0xf6, 0xe4, 0x60, 0xfe, 0xc3, 0x50,
+			0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45,
+			0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b,
+			0x5e, 0x8f, 0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6,
+			0xac, 0x00, 0xa9, 0x70, 0x4a, 0x18, 0x8a, 0x03
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x08, 0xb8, 0xb2, 0xb7, 0x33, 0x42, 0x42, 0x43,
+			0x76, 0x0f, 0xe4, 0x26, 0xa4, 0xb5, 0x49, 0x08,
+			0x63, 0x21, 0x10, 0xa6, 0x6c, 0x2f, 0x65, 0x91,
+			0xea, 0xbd, 0x33, 0x45, 0xe3, 0xe4, 0xeb, 0x98,
+			0xfa, 0x6e, 0x26, 0x4b, 0xf0, 0x9e, 0xfe, 0x12,
+			0xee, 0x50, 0xf8, 0xf5, 0x4e, 0x9f, 0x77, 0xb1,
+			0xe3, 0x55, 0xf6, 0xc5, 0x05, 0x44, 0xe2, 0x3f,
+			0xb1, 0x43, 0x3d, 0xdf, 0x73, 0xbe, 0x84, 0xd8,
+			0x79, 0xde, 0x7c, 0x00, 0x46, 0xdc, 0x49, 0x96,
+			0xd9, 0xe7, 0x73, 0xf4, 0xbc, 0x9e, 0xfe, 0x57,
+			0x38, 0x82, 0x9a, 0xdb, 0x26, 0xc8, 0x1b, 0x37,
+			0xc9, 0x3a, 0x1b, 0x27, 0x0b, 0x20, 0x32, 0x9d,
+			0x65, 0x86, 0x75, 0xfc, 0x6e, 0xa5, 0x34, 0xe0,
+			0x81, 0x0a, 0x44, 0x32, 0x82, 0x6b, 0xf5, 0x8c,
+			0x94, 0x1e, 0xfb, 0x65, 0xd5, 0x7a, 0x33, 0x8b,
+			0xbd, 0x2e, 0x26, 0x64, 0x0f, 0x89, 0xff, 0xbc,
+			0x1a, 0x85, 0x8e, 0xfc, 0xb8, 0x55, 0x0e, 0xe3,
+			0xa5, 0xe1, 0x99, 0x8b, 0xd1, 0x77, 0xe9, 0x3a,
+			0x73, 0x63, 0xc3, 0x44, 0xfe, 0x6b, 0x19, 0x9e,
+			0xe5, 0xd0, 0x2e, 0x82, 0xd5, 0x22, 0xc4, 0xfe,
+			0xba, 0x15, 0x45, 0x2f, 0x80, 0x28, 0x8a, 0x82,
+			0x1a, 0x57, 0x91, 0x16, 0xec, 0x6d, 0xad, 0x2b,
+			0x3b, 0x31, 0x0d, 0xa9, 0x03, 0x40, 0x1a, 0xa6,
+			0x21, 0x00, 0xab, 0x5d, 0x1a, 0x36, 0x55, 0x3e,
+			0x06, 0x20, 0x3b, 0x33, 0x89, 0x0c, 0xc9, 0xb8,
+			0x32, 0xf7, 0x9e, 0xf8, 0x05, 0x60, 0xcc, 0xb9,
+			0xa3, 0x9c, 0xe7, 0x67, 0x96, 0x7e, 0xd6, 0x28,
+			0xc6, 0xad, 0x57, 0x3c, 0xb1, 0x16, 0xdb, 0xef,
+			0xef, 0xd7, 0x54, 0x99, 0xda, 0x96, 0xbd, 0x68,
+			0xa8, 0xa9, 0x7b, 0x92, 0x8a, 0x8b, 0xbc, 0x10,
+			0x3b, 0x66, 0x21, 0xfc, 0xde, 0x2b, 0xec, 0xa1,
+			0x23, 0x1d, 0x20, 0x6b, 0xe6, 0xcd, 0x9e, 0xc7,
+			0xaf, 0xf6, 0xf6, 0xc9, 0x4f, 0xcd, 0x72, 0x04,
+			0xed, 0x34, 0x55, 0xc6, 0x8c, 0x83, 0xf4, 0xa4,
+			0x1d, 0xa4, 0xaf, 0x2b, 0x74, 0xef, 0x5c, 0x53,
+			0xf1, 0xd8, 0xac, 0x70, 0xbd, 0xcb, 0x7e, 0xd1,
+			0x85, 0xce, 0x81, 0xbd, 0x84, 0x35, 0x9d, 0x44,
+			0x25, 0x4d, 0x95, 0x62, 0x9e, 0x98, 0x55, 0xa9,
+			0x4a, 0x7c, 0x19, 0x58, 0xd1, 0xf8, 0xad, 0xa5,
+			0xd0, 0x53, 0x2e, 0xd8, 0xa5, 0xaa, 0x3f, 0xb2,
+			0xd1, 0x7b, 0xa7, 0x0e, 0xb6, 0x24, 0x8e, 0x59,
+			0x4e, 0x1a, 0x22, 0x97, 0xac, 0xbb, 0xb3, 0x9d,
+			0x50, 0x2f, 0x1a, 0x8c, 0x6e, 0xb6, 0xf1, 0xce,
+			0x22, 0xb3, 0xde, 0x1a, 0x1f, 0x40, 0xcc, 0x24,
+			0x55, 0x41, 0x19, 0xa8, 0x31, 0xa9, 0xaa, 0xd6,
+			0x07, 0x9c, 0xad, 0x88, 0x42, 0x5d, 0xe6, 0xbd,
+			0xe1, 0xa9, 0x18, 0x7e, 0xbb, 0x60, 0x92, 0xcf,
+			0x67, 0xbf, 0x2b, 0x13, 0xfd, 0x65, 0xf2, 0x70,
+			0x88, 0xd7, 0x8b, 0x7e, 0x88, 0x3c, 0x87, 0x59,
+			0xd2, 0xc4, 0xf5, 0xc6, 0x5a, 0xdb, 0x75, 0x53,
+			0x87, 0x8a, 0xd5, 0x75, 0xf9, 0xfa, 0xd8, 0x78,
+			0xe8, 0x0a, 0x0c, 0x9b, 0xa6, 0x3b, 0xcb, 0xcc,
+			0x27, 0x32, 0xe6, 0x94, 0x85, 0xbb, 0xc9, 0xc9,
+			0x0b, 0xfb, 0xd6, 0x24, 0x81, 0xd9, 0x08, 0x9b,
+			0xec, 0xcf, 0x80, 0xcf, 0xe2, 0xdf, 0x16, 0xa2,
+			0xcf, 0x65, 0xbd, 0x92, 0xdd, 0x59, 0x7b, 0x07,
+			0x07, 0xe0, 0x91, 0x7a, 0xf4, 0x8b, 0xbb, 0x75,
+			0xfe, 0xd4, 0x13, 0xd2, 0x38, 0xf5, 0x55, 0x5a,
+			0x7a, 0x56, 0x9d, 0x80, 0xc3, 0x41, 0x4a, 0x8d,
+			0x08, 0x59, 0xdc, 0x65, 0xa4, 0x61, 0x28, 0xba,
+			0xb2, 0x7a, 0xf8, 0x7a, 0x71, 0x31, 0x4f, 0x31,
+			0x8c, 0x78, 0x2b, 0x23, 0xeb, 0xfe, 0x80, 0x8b,
+			0x82, 0xb0, 0xce, 0x26, 0x40, 0x1d, 0x2e, 0x22,
+			0xf0, 0x4d, 0x83, 0xd1, 0x25, 0x5d, 0xc5, 0x1a,
+			0xdd, 0xd3, 0xb7, 0x5a, 0x2b, 0x1a, 0xe0, 0x78,
+			0x45, 0x04, 0xdf, 0x54, 0x3a, 0xf8, 0x96, 0x9b,
+			0xe3, 0xea, 0x70, 0x82, 0xff, 0x7f, 0xc9, 0x88,
+			0x8c, 0x14, 0x4d, 0xa2, 0xaf, 0x58, 0x42, 0x9e,
+			0xc9, 0x60, 0x31, 0xdb, 0xca, 0xd3, 0xda, 0xd9,
+			0xaf, 0x0d, 0xcb, 0xaa, 0xaf, 0x26, 0x8c, 0xb8,
+			0xfc, 0xff, 0xea, 0xd9, 0x4f, 0x3c, 0x7c, 0xa4,
+			0x95, 0xe0, 0x56, 0xa9, 0xb4, 0x7a, 0xcd, 0xb7,
+			0x51, 0xfb, 0x73, 0xe6, 0x66, 0xc6, 0xc6, 0x55,
+			0xad, 0xe8, 0x29, 0x72, 0x97, 0xd0, 0x7a, 0xd1,
+			0xba, 0x5e, 0x43, 0xf1, 0xbc, 0xa3, 0x23, 0x01,
+			0x65, 0x13, 0x39, 0xe2, 0x29, 0x04, 0xcc, 0x8c,
+			0x42, 0xf5, 0x8c, 0x30, 0xc0, 0x4a, 0xaf, 0xdb,
+			0x03, 0x8d, 0xda, 0x08, 0x47, 0xdd, 0x98, 0x8d,
+			0xcd, 0xa6, 0xf3, 0xbf, 0xd1, 0x5c, 0x4b, 0x4c,
+			0x45, 0x25, 0x00, 0x4a, 0xa0, 0x6e, 0xef, 0xf8,
+			0xca, 0x61, 0x78, 0x3a, 0xac, 0xec, 0x57, 0xfb,
+			0x3d, 0x1f, 0x92, 0xb0, 0xfe, 0x2f, 0xd1, 0xa8,
+			0x5f, 0x67, 0x24, 0x51, 0x7b, 0x65, 0xe6, 0x14,
+			0xad, 0x68, 0x08, 0xd6, 0xf6, 0xee, 0x34, 0xdf,
+			0xf7, 0x31, 0x0f, 0xdc, 0x82, 0xae, 0xbf, 0xd9,
+			0x04, 0xb0, 0x1e, 0x1d, 0xc5, 0x4b, 0x29, 0x27,
+			0x09, 0x4b, 0x2d, 0xb6, 0x8d, 0x6f, 0x90, 0x3b,
+			0x68, 0x40, 0x1a, 0xde, 0xbf, 0x5a, 0x7e, 0x08,
+			0xd7, 0x8f, 0xf4, 0xef, 0x5d, 0x63, 0x65, 0x3a,
+			0x65, 0x04, 0x0c, 0xf9, 0xbf, 0xd4, 0xac, 0xa7,
+			0x98, 0x4a, 0x74, 0xd3, 0x71, 0x45, 0x98, 0x67,
+			0x80, 0xfc, 0x0b, 0x16, 0xac, 0x45, 0x16, 0x49,
+			0xde, 0x61, 0x88, 0xa7, 0xdb, 0xdf, 0x19, 0x1f,
+			0x64, 0xb5, 0xfc, 0x5e, 0x2a, 0xb4, 0x7b, 0x57,
+			0xf7, 0xf7, 0x27, 0x6c, 0xd4, 0x19, 0xc1, 0x7a,
+			0x3c, 0xa8, 0xe1, 0xb9, 0x39, 0xae, 0x49, 0xe4,
+			0x88, 0xac, 0xba, 0x6b, 0x96, 0x56, 0x10, 0xb5,
+			0x48, 0x01, 0x09, 0xc8, 0xb1, 0x7b, 0x80, 0xe1,
+			0xb7, 0xb7, 0x50, 0xdf, 0xc7, 0x59, 0x8d, 0x5d,
+			0x50, 0x11, 0xfd, 0x2d, 0xcc, 0x56, 0x00, 0xa3,
+			0x2e, 0xf5, 0xb5, 0x2a, 0x1e, 0xcc, 0x82, 0x0e,
+			0x30, 0x8a, 0xa3, 0x42, 0x72, 0x1a, 0xac, 0x09,
+			0x43, 0xbf, 0x66, 0x86, 0xb6, 0x4b, 0x25, 0x79,
+			0x37, 0x65, 0x04, 0xcc, 0xc4, 0x93, 0xd9, 0x7e,
+			0x6a, 0xed, 0x3f, 0xb0, 0xf9, 0xcd, 0x71, 0xa4,
+			0x3d, 0xd4, 0x97, 0xf0, 0x1f, 0x17, 0xc0, 0xe2,
+			0xcb, 0x37, 0x97, 0xaa, 0x2a, 0x2f, 0x25, 0x66,
+			0x56, 0x16, 0x8e, 0x6c, 0x49, 0x6a, 0xfc, 0x5f,
+			0xb9, 0x32, 0x46, 0xf6, 0xb1, 0x11, 0x63, 0x98,
+			0xa3, 0x46, 0xf1, 0xa6, 0x41, 0xf3, 0xb0, 0x41,
+			0xe9, 0x89, 0xf7, 0x91, 0x4f, 0x90, 0xcc, 0x2c,
+			0x7f, 0xff, 0x35, 0x78, 0x76, 0xe5, 0x06, 0xb5,
+			0x0d, 0x33, 0x4b, 0xa7, 0x7c, 0x22, 0x5b, 0xc3,
+			0x07, 0xba, 0x53, 0x71, 0x52, 0xf3, 0xf1, 0x61,
+			0x0e, 0x4e, 0xaf, 0xe5, 0x95, 0xf6, 0xd9, 0xd9,
+			0x0d, 0x11, 0xfa, 0xa9, 0x33, 0xa1, 0x5e, 0xf1,
+			0x36, 0x95, 0x46, 0x86, 0x8a, 0x7f, 0x3a, 0x45,
+			0xa9, 0x67, 0x68, 0xd4, 0x0f, 0xd9, 0xd0, 0x34,
+			0x12, 0xc0, 0x91, 0xc6, 0x31, 0x5c, 0xf4, 0xfd,
+			0xe7, 0xcb, 0x68, 0x60, 0x69, 0x37, 0x38, 0x0d,
+			0xb2, 0xea, 0xaa, 0x70, 0x7b, 0x4c, 0x41, 0x85,
+			0xc3, 0x2e, 0xdd, 0xcd, 0xd3, 0x06, 0x70, 0x5e,
+			0x4d, 0xc1, 0xff, 0xc8, 0x72, 0xee, 0xee, 0x47,
+			0x5a, 0x64, 0xdf, 0xac, 0x86, 0xab, 0xa4, 0x1c,
+			0x06, 0x18, 0x98, 0x3f, 0x87, 0x41, 0xc5, 0xef,
+			0x68, 0xd3, 0xa1, 0x01, 0xe8, 0xa3, 0xb8, 0xca,
+			0xc6, 0x0c, 0x90, 0x5c, 0x15, 0xfc, 0x91, 0x08,
+			0x40, 0xb9, 0x4c, 0x00, 0xa0, 0xb9, 0xd0
+		},
+		.length = 1023,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519CTX (msg=16, ctx=3)",
+	.pkey = {
+		.data = {
+			0x03, 0x05, 0x33, 0x4e, 0x38, 0x1a, 0xf7, 0x8f,
+			0x14, 0x1c, 0xb6, 0x66, 0xf6, 0x19, 0x9f, 0x57,
+			0xbc, 0x34, 0x95, 0x33, 0x5a, 0x25, 0x6a, 0x95,
+			0xbd, 0x2a, 0x55, 0xbf, 0x54, 0x66, 0x63, 0xf6
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xdf, 0xc9, 0x42, 0x5e, 0x4f, 0x96, 0x8f, 0x7f,
+			0x0c, 0x29, 0xf0, 0x25, 0x9c, 0xf5, 0xf9, 0xae,
+			0xd6, 0x85, 0x1c, 0x2b, 0xb4, 0xad, 0x8b, 0xfb,
+			0x86, 0x0c, 0xfe, 0xe0, 0xab, 0x24, 0x82, 0x92
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x55, 0xa4, 0xcc, 0x2f, 0x70, 0xa5, 0x4e, 0x04,
+			0x28, 0x8c, 0x5f, 0x4c, 0xd1, 0xe4, 0x5a, 0x7b,
+			0xb5, 0x20, 0xb3, 0x62, 0x92, 0x91, 0x18, 0x76,
+			0xca, 0xda, 0x73, 0x23, 0x19, 0x8d, 0xd8, 0x7a,
+			0x8b, 0x36, 0x95, 0x0b, 0x95, 0x13, 0x00, 0x22,
+			0x90, 0x7a, 0x7f, 0xb7, 0xc4, 0xe9, 0xb2, 0xd5,
+			0xf6, 0xcc, 0xa6, 0x85, 0xa5, 0x87, 0xb4, 0xb2,
+			0x1f, 0x4b, 0x88, 0x8e, 0x4e, 0x7e, 0xdb, 0x0d
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0xf7, 0x26, 0x93, 0x6d, 0x19, 0xc8, 0x00, 0x49,
+			0x4e, 0x3f, 0xda, 0xff, 0x20, 0xb2, 0x76, 0xa8,
+		},
+		.length = 16,
+	},
+	.context = {
+		.data = {
+			0x66, 0x6f, 0x6f
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519CTX
+},
+{
+	.description = "EDDSA 25519PH (msg=1, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+			0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+			0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+			0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x98, 0xa7, 0x02, 0x22, 0xf0, 0xb8, 0x12, 0x1a,
+			0xa9, 0xd3, 0x0f, 0x81, 0x3d, 0x68, 0x3f, 0x80,
+			0x9e, 0x46, 0x2b, 0x46, 0x9c, 0x7f, 0xf8, 0x76,
+			0x39, 0x49, 0x9b, 0xb9, 0x4e, 0x6d, 0xae, 0x41,
+			0x31, 0xf8, 0x50, 0x42, 0x46, 0x3c, 0x2a, 0x35,
+			0x5a, 0x20, 0x03, 0xd0, 0x62, 0xad, 0xf5, 0xaa,
+			0xa1, 0x0b, 0x8c, 0x61, 0xe6, 0x36, 0x06, 0x2a,
+			0xaa, 0xd1, 0x1c, 0x2a, 0x26, 0x08, 0x34, 0x06
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519PH
+},
+{
+	.description = "EDDSA 448 (msg=0)",
+	.pkey = {
+		.data = {
+			0x6C, 0x82, 0xA5, 0x62, 0xCB, 0x80, 0x8D, 0x10,
+			0xD6, 0x32, 0xBE, 0x89, 0xC8, 0x51, 0x3E, 0xBF,
+			0x6C, 0x92, 0x9F, 0x34, 0xDD, 0xFA, 0x8C, 0x9F,
+			0x63, 0xC9, 0x96, 0x0E, 0xF6, 0xE3, 0x48, 0xA3,
+			0x52, 0x8C, 0x8A, 0x3F, 0xCC, 0x2F, 0x04, 0x4E,
+			0x39, 0xA3, 0xFC, 0x5B, 0x94, 0x49, 0x2F, 0x8F,
+			0x03, 0x2E, 0x75, 0x49, 0xA2, 0x00, 0x98, 0xF9,
+			0x5B,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x5F, 0xD7, 0x44, 0x9B, 0x59, 0xB4, 0x61, 0xFD,
+			0x2C, 0xE7, 0x87, 0xEC, 0x61, 0x6A, 0xD4, 0x6A,
+			0x1D, 0xA1, 0x34, 0x24, 0x85, 0xA7, 0x0E, 0x1F,
+			0x8A, 0x0E, 0xA7, 0x5D, 0x80, 0xE9, 0x67, 0x78,
+			0xED, 0xF1, 0x24, 0x76, 0x9B, 0x46, 0xC7, 0x06,
+			0x1B, 0xD6, 0x78, 0x3D, 0xF1, 0xE5, 0x0F, 0x6C,
+			0xD1, 0xFA, 0x1A, 0xBE, 0xAF, 0xE8, 0x25, 0x61,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25,
+			0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae,
+			0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2,
+			0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f,
+			0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81,
+			0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78,
+			0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39,
+			0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a,
+			0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d,
+			0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41,
+			0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd,
+			0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb,
+			0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26,
+			0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65,
+			0x26, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=1)",
+	.pkey = {
+		.data = {
+			0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6,
+			0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92, 0x4d,
+			0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d,
+			0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c, 0x46, 0x3a,
+			0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c,
+			0x5e, 0x3b, 0xc3, 0x97, 0xa6, 0x59, 0x94, 0x9e,
+			0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27,
+			0x4e,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45,
+			0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd, 0x0a,
+			0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37,
+			0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98, 0xc0, 0x86,
+			0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02,
+			0xb8, 0x43, 0x8e, 0xa4, 0xcb, 0x82, 0x16, 0x9c,
+			0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x26, 0xb8, 0xf9, 0x17, 0x27, 0xbd, 0x62, 0x89,
+			0x7a, 0xf1, 0x5e, 0x41, 0xeb, 0x43, 0xc3, 0x77,
+			0xef, 0xb9, 0xc6, 0x10, 0xd4, 0x8f, 0x23, 0x35,
+			0xcb, 0x0b, 0xd0, 0x08, 0x78, 0x10, 0xf4, 0x35,
+			0x25, 0x41, 0xb1, 0x43, 0xc4, 0xb9, 0x81, 0xb7,
+			0xe1, 0x8f, 0x62, 0xde, 0x8c, 0xcd, 0xf6, 0x33,
+			0xfc, 0x1b, 0xf0, 0x37, 0xab, 0x7c, 0xd7, 0x79,
+			0x80, 0x5e, 0x0d, 0xbc, 0xc0, 0xaa, 0xe1, 0xcb,
+			0xce, 0xe1, 0xaf, 0xb2, 0xe0, 0x27, 0xdf, 0x36,
+			0xbc, 0x04, 0xdc, 0xec, 0xbf, 0x15, 0x43, 0x36,
+			0xc1, 0x9f, 0x0a, 0xf7, 0xe0, 0xa6, 0x47, 0x29,
+			0x05, 0xe7, 0x99, 0xf1, 0x95, 0x3d, 0x2a, 0x0f,
+			0xf3, 0x34, 0x8a, 0xb2, 0x1a, 0xa4, 0xad, 0xaf,
+			0xd1, 0xd2, 0x34, 0x44, 0x1c, 0xf8, 0x07, 0xc0,
+			0x3a, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x03
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=3, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42,
+			0xef, 0x78, 0x22, 0xe0, 0xd5, 0x10, 0x41, 0x27,
+			0xdc, 0x05, 0xd6, 0xdb, 0xef, 0xde, 0x69, 0xe3,
+			0xab, 0x2c, 0xec, 0x7c, 0x86, 0x7c, 0x6e, 0x2c,
+			0x49
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x25, 0x9b, 0x71, 0xc1, 0x9f, 0x83, 0xef, 0x77,
+			0xa7, 0xab, 0xd2, 0x65, 0x24, 0xcb, 0xdb, 0x31,
+			0x61, 0xb5, 0x90, 0xa4, 0x8f, 0x7d, 0x17, 0xde,
+			0x3e, 0xe0, 0xba, 0x9c, 0x52, 0xbe, 0xb7, 0x43,
+			0xc0, 0x94, 0x28, 0xa1, 0x31, 0xd6, 0xb1, 0xb5,
+			0x73, 0x03, 0xd9, 0x0d, 0x81, 0x32, 0xc2, 0x76,
+			0xd5, 0xed, 0x3d, 0x5d, 0x01, 0xc0, 0xf5, 0x38,
+			0x80
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x82, 0x2f, 0x69, 0x01, 0xf7, 0x48, 0x0f, 0x3d,
+			0x5f, 0x56, 0x2c, 0x59, 0x29, 0x94, 0xd9, 0x69,
+			0x36, 0x02, 0x87, 0x56, 0x14, 0x48, 0x32, 0x56,
+			0x50, 0x56, 0x00, 0xbb, 0xc2, 0x81, 0xae, 0x38,
+			0x1f, 0x54, 0xd6, 0xbc, 0xe2, 0xea, 0x91, 0x15,
+			0x74, 0x93, 0x2f, 0x52, 0xa4, 0xe6, 0xca, 0xdd,
+			0x78, 0x76, 0x93, 0x75, 0xec, 0x3f, 0xfd, 0x1b,
+			0x80, 0x1a, 0x0d, 0x9b, 0x3f, 0x40, 0x30, 0xcd,
+			0x43, 0x39, 0x64, 0xb6, 0x45, 0x7e, 0xa3, 0x94,
+			0x76, 0x51, 0x12, 0x14, 0xf9, 0x74, 0x69, 0xb5,
+			0x7d, 0xd3, 0x2d, 0xbc, 0x56, 0x0a, 0x9a, 0x94,
+			0xd0, 0x0b, 0xff, 0x07, 0x62, 0x04, 0x64, 0xa3,
+			0xad, 0x20, 0x3d, 0xf7, 0xdc, 0x7c, 0xe3, 0x60,
+			0xc3, 0xcd, 0x36, 0x96, 0xd9, 0xd9, 0xfa, 0xb9,
+			0x0f, 0x00
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448PH
+},
+};
+
+#endif /* __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__ */
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v2 5/6] examples/fips_validation: support EDDSA
  2024-09-05 13:39 ` Gowrishankar Muthukrishnan
                     ` (2 preceding siblings ...)
  2024-09-05 13:39   ` [PATCH v2 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
@ 2024-09-05 13:39   ` Gowrishankar Muthukrishnan
  2024-09-05 13:39   ` [PATCH v2 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
  4 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-05 13:39 UTC (permalink / raw)
  To: dev, Brian Dooley, Gowrishankar Muthukrishnan
  Cc: Anoob Joseph, bruce.richardson, ciara.power, jerinj,
	fanzhang.oss, arkadiuszx.kusztal, kai.ji, jack.bond-preston,
	david.marchand, hemant.agrawal, pablo.de.lara.guarch,
	fiona.trahe, declan.doherty, matan, ruifeng.wang, Akhil Goyal

Add EDDSA support in fips_validation app.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 examples/fips_validation/fips_validation.c    |   2 +
 examples/fips_validation/fips_validation.h    |  23 ++
 .../fips_validation/fips_validation_eddsa.c   | 307 +++++++++++++++++
 examples/fips_validation/main.c               | 323 ++++++++++++++++--
 examples/fips_validation/meson.build          |   1 +
 5 files changed, 623 insertions(+), 33 deletions(-)
 create mode 100644 examples/fips_validation/fips_validation_eddsa.c

diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c
index c15178e55b..43d1e55532 100644
--- a/examples/fips_validation/fips_validation.c
+++ b/examples/fips_validation/fips_validation.c
@@ -475,6 +475,8 @@ fips_test_parse_one_json_vector_set(void)
 		info.algo = FIPS_TEST_ALGO_RSA;
 	else if (strstr(algo_str, "ECDSA"))
 		info.algo = FIPS_TEST_ALGO_ECDSA;
+	else if (strstr(algo_str, "EDDSA"))
+		info.algo = FIPS_TEST_ALGO_EDDSA;
 	else
 		return -EINVAL;
 
diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h
index abc1d64742..795cf834e8 100644
--- a/examples/fips_validation/fips_validation.h
+++ b/examples/fips_validation/fips_validation.h
@@ -46,6 +46,7 @@ enum fips_test_algorithms {
 		FIPS_TEST_ALGO_SHA,
 		FIPS_TEST_ALGO_RSA,
 		FIPS_TEST_ALGO_ECDSA,
+		FIPS_TEST_ALGO_EDDSA,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -106,6 +107,12 @@ struct fips_test_vector {
 		struct fips_val s;
 		struct fips_val k;
 	} ecdsa;
+	struct {
+		struct fips_val pkey;
+		struct fips_val q;
+		struct fips_val ctx;
+		struct fips_val sign;
+	} eddsa;
 
 	struct fips_val pt;
 	struct fips_val ct;
@@ -177,6 +184,11 @@ enum fips_ecdsa_test_types {
 	ECDSA_AFT = 0,
 };
 
+enum fips_eddsa_test_types {
+	EDDSA_AFT = 0,
+	EDDSA_BFT
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -241,6 +253,13 @@ struct ecdsa_interim_data {
 	uint8_t pubkey_gen;
 };
 
+struct eddsa_interim_data {
+	enum rte_crypto_curve_id curve_id;
+	uint8_t curve_len;
+	uint8_t pubkey_gen;
+	bool prehash;
+};
+
 #ifdef USE_JANSSON
 /*
  * Maximum length of buffer to hold any json string.
@@ -288,6 +307,7 @@ struct fips_test_interim_info {
 		struct xts_interim_data xts_data;
 		struct rsa_interim_data rsa_data;
 		struct ecdsa_interim_data ecdsa_data;
+		struct eddsa_interim_data eddsa_data;
 	} interim_info;
 
 	enum fips_test_op op;
@@ -374,6 +394,9 @@ parse_test_rsa_json_init(void);
 int
 parse_test_ecdsa_json_init(void);
 
+int
+parse_test_eddsa_json_init(void);
+
 int
 fips_test_randomize_message(struct fips_val *msg, struct fips_val *rand);
 #endif /* USE_JANSSON */
diff --git a/examples/fips_validation/fips_validation_eddsa.c b/examples/fips_validation/fips_validation_eddsa.c
new file mode 100644
index 0000000000..8ccf7501bd
--- /dev/null
+++ b/examples/fips_validation/fips_validation_eddsa.c
@@ -0,0 +1,307 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell.
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef USE_OPENSSL
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#endif /* USE_OPENSSL */
+
+#include <rte_cryptodev.h>
+#include <rte_malloc.h>
+
+#include "fips_validation.h"
+
+#define TESTTYPE_JSON_STR "testType"
+#define CURVE_JSON_STR    "curve"
+#define PH_JSON_STR       "preHash"
+
+#define MSG_JSON_STR "message"
+#define CTX_JSON_STR "context"
+#define Q_JSON_STR	 "q"
+#define SIG_JSON_STR "signature"
+
+#ifdef USE_JANSSON
+struct {
+	uint8_t type;
+	const char *desc;
+} eddsa_test_types[] = {
+	{EDDSA_AFT, "AFT"},
+	{EDDSA_BFT, "BFT"}
+};
+
+struct {
+	enum rte_crypto_curve_id curve_id;
+	const char *desc;
+} eddsa_curve_ids[] = {
+	{RTE_CRYPTO_EC_GROUP_ED25519, "ED-25519"},
+	{RTE_CRYPTO_EC_GROUP_ED448, "ED-448"},
+};
+
+struct {
+	uint8_t curve_len;
+	const char *desc;
+} eddsa_curve_len[] = {
+	{32, "ED-25519"},
+	{64, "ED-448"},
+};
+
+#ifdef USE_OPENSSL
+#define MAX_TRIES 10
+static int
+prepare_vec_eddsa(void)
+{
+	BIGNUM *pkey = NULL, *order = NULL;
+	int ret = -1, j;
+	unsigned long pid;
+
+	/* For EDDSA prime fields, order of base points (RFC 8032 Section 5.1 and 5.2).
+	 */
+	static const char * const orderstr[] = {
+			"7237005577332262213973186563042994240857116359379907606001950938285454250989",
+			"181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779",
+	};
+
+	pid = getpid();
+	RAND_seed(&pid, sizeof(pid));
+
+	if (!RAND_status())
+		return -1;
+
+	order = BN_new();
+	if (!order)
+		goto err;
+
+	j = info.interim_info.eddsa_data.curve_id - RTE_CRYPTO_EC_GROUP_ED25519;
+	if (!BN_hex2bn(&order, orderstr[j]))
+		goto err;
+
+	pkey = BN_new();
+	if (!pkey)
+		goto err;
+
+	for (j = 0; j < MAX_TRIES; j++) {
+		/* pkey should be in [1, order - 1] */
+		if (!BN_rand_range(pkey, order))
+			goto err;
+
+		if (!BN_is_zero(pkey))
+			break;
+	}
+
+	if (j == MAX_TRIES)
+		goto err;
+
+	parse_uint8_hex_str("", BN_bn2hex(pkey), &vec.eddsa.pkey);
+
+	ret = 0;
+err:
+	BN_free(order);
+	BN_free(pkey);
+	return ret;
+}
+#else
+static int
+prepare_vec_eddsa(void)
+{
+	/*
+	 * Generate EDDSA values.
+	 */
+	return -ENOTSUP;
+}
+#endif /* USE_OPENSSL */
+
+static int
+parse_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		/* For siggen tests, EDDSA values can be created soon after
+		 * the test group data are parsed.
+		 */
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+static int
+post_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_group, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_test_eddsa_json_writeback(struct fips_val *val)
+{
+	json_t *tcId;
+
+	RTE_SET_USED(val);
+
+	tcId = json_object_get(json_info.json_test_case, "tcId");
+
+	json_info.json_write_case = json_object();
+	json_object_set(json_info.json_write_case, "tcId", tcId);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.sign);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "signature", obj);
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)
+			json_object_set_new(json_info.json_write_case, "testPassed", json_true());
+		else
+			json_object_set_new(json_info.json_write_case, "testPassed", json_false());
+	} else if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.pkey);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "d", obj);
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_interim_str(const char *key, char *src, struct fips_val *val)
+{
+	uint32_t i;
+
+	RTE_SET_USED(val);
+
+	if (strcmp(key, TESTTYPE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_test_types); i++)
+			if (strstr(src, eddsa_test_types[i].desc)) {
+				info.parse_writeback = parse_test_eddsa_json_writeback;
+				break;
+			}
+
+		if (!info.parse_writeback || i >= RTE_DIM(eddsa_test_types))
+			return -EINVAL;
+
+	} else if (strcmp(key, CURVE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_curve_ids); i++)
+			if (strstr(src, eddsa_curve_ids[i].desc)) {
+				info.interim_info.eddsa_data.curve_id = eddsa_curve_ids[i].curve_id;
+				info.interim_info.eddsa_data.curve_len =
+					eddsa_curve_len[i].curve_len;
+				break;
+			}
+
+		if (i >= RTE_DIM(eddsa_curve_ids))
+			return -EINVAL;
+	} else if (strcmp(key, PH_JSON_STR) == 0) {
+		info.interim_info.eddsa_data.prehash = false;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+parse_keygen_tc_str(const char *key, char *src, struct fips_val *val)
+{
+	RTE_SET_USED(key);
+	RTE_SET_USED(src);
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+struct fips_test_callback eddsa_interim_json_vectors[] = {
+		{TESTTYPE_JSON_STR, parse_interim_str, NULL},
+		{CURVE_JSON_STR, parse_interim_str, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_siggen_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{CTX_JSON_STR, parse_uint8_hex_str, &vec.eddsa.ctx},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_sigver_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{Q_JSON_STR, parse_uint8_hex_str, &vec.eddsa.q},
+		{SIG_JSON_STR, parse_uint8_hex_str, &vec.eddsa.sign},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_keygen_json_vectors[] = {
+		{"tcId", parse_keygen_tc_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+int
+parse_test_eddsa_json_init(void)
+{
+	json_t *mode_obj = json_object_get(json_info.json_vector_set, "mode");
+	const char *mode_str = json_string_value(mode_obj);
+
+	info.callbacks = NULL;
+	info.parse_writeback = NULL;
+
+	info.interim_callbacks = eddsa_interim_json_vectors;
+	info.post_interim_writeback = post_test_eddsa_json_interim_writeback;
+	info.parse_interim_writeback = parse_test_eddsa_json_interim_writeback;
+	if (strcmp(mode_str, "sigGen") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGGEN;
+		info.callbacks = eddsa_siggen_json_vectors;
+	} else if (strcmp(mode_str, "sigVer") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGVER;
+		info.callbacks = eddsa_sigver_json_vectors;
+	} else if (strcmp(mode_str, "keyGen") == 0) {
+		info.op = FIPS_TEST_ASYM_KEYGEN;
+		info.callbacks = eddsa_keygen_json_vectors;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif /* USE_JANSSON */
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index 7ae2c6c007..522373ac1d 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -1041,6 +1041,64 @@ prepare_ecdsa_op(void)
 	return 0;
 }
 
+static int
+prepare_eddsa_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+	struct fips_val msg;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	if (env.digest) {
+		msg.val = env.digest;
+		msg.len = env.digest_len;
+	} else {
+		msg.val = vec.pt.val;
+		msg.len = vec.pt.len;
+	}
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.context.data = vec.eddsa.ctx.val;
+		asym->eddsa.context.length = vec.eddsa.ctx.len;
+
+		rte_free(vec.eddsa.sign.val);
+
+		vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len;
+		vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0);
+
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = 0;
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = vec.eddsa.sign.len;
+	} else {
+		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
+		return -EINVAL;
+	}
+
+	if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH;
+		if (vec.eddsa.ctx.len > 0)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX;
+	} else {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH;
+	}
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_ecfpm_op(void)
 {
@@ -1072,6 +1130,31 @@ prepare_ecfpm_op(void)
 	return 0;
 }
 
+static int
+prepare_edfpm_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	asym->ecpm.scalar.data = vec.eddsa.pkey.val;
+	asym->ecpm.scalar.length = vec.eddsa.pkey.len;
+
+	rte_free(vec.eddsa.q.val);
+
+	vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len;
+	vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0);
+
+	asym->ecpm.r.x.data = vec.eddsa.q.val;
+	asym->ecpm.r.x.length = 0;
+	asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
@@ -1589,6 +1672,56 @@ prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_eddsa_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	switch (info.op) {
+	case FIPS_TEST_ASYM_SIGGEN:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_SIGN)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
+			return -EPERM;
+		}
+
+		xform->ec.pkey.data = vec.eddsa.pkey.val;
+		xform->ec.pkey.length = vec.eddsa.pkey.len;
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	case FIPS_TEST_ASYM_SIGVER:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_VERIFY)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
+			return -EPERM;
+		}
+
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	default:
+		break;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 {
@@ -1610,6 +1743,27 @@ prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_edfpm_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 get_writeback_data(struct fips_val *val)
 {
@@ -1709,7 +1863,9 @@ fips_run_asym_test(void)
 	struct rte_crypto_op *deqd_op;
 	int ret;
 
-	if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != FIPS_TEST_ALGO_ECDSA) {
+	if (info.op == FIPS_TEST_ASYM_KEYGEN &&
+		(info.algo != FIPS_TEST_ALGO_ECDSA &&
+		 info.algo != FIPS_TEST_ALGO_EDDSA)) {
 		RTE_SET_USED(asym);
 		ret = 0;
 		goto exit;
@@ -1758,53 +1914,140 @@ fips_run_test(void)
 {
 	int ret;
 
-	env.op = env.sym.op;
-	if (env.is_asym_test) {
-		if (info.op == FIPS_TEST_ASYM_KEYGEN &&
-			info.algo == FIPS_TEST_ALGO_ECDSA) {
-			env.op = env.asym.op;
+	env.op = NULL;
+	if (!env.is_asym_test) {
+		env.op = env.sym.op;
+		return fips_run_sym_test();
+	}
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (info.algo == FIPS_TEST_ALGO_ECDSA) {
 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
 			test_ops.prepare_asym_op = prepare_ecfpm_op;
-			ret = fips_run_asym_test();
-			if (ret < 0)
-				return ret;
-
 			info.interim_info.ecdsa_data.pubkey_gen = 0;
-			return ret;
+
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA) {
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			info.interim_info.eddsa_data.pubkey_gen = 0;
 		}
 
-		vec.cipher_auth.digest.len = parse_test_sha_hash_size(
-						info.interim_info.rsa_data.auth);
+		env.op = env.asym.op;
+		return fips_run_asym_test();
+	}
+
+	if (info.algo == FIPS_TEST_ALGO_ECDSA) {
+		vec.cipher_auth.digest.len =
+			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
 		test_ops.prepare_sym_xform = prepare_sha_xform;
 		test_ops.prepare_sym_op = prepare_auth_op;
+
+		env.op = env.sym.op;
 		ret = fips_run_sym_test();
 		if (ret < 0)
 			return ret;
-	} else {
-		return fips_run_sym_test();
 	}
 
 	env.op = env.asym.op;
-	if (info.op == FIPS_TEST_ASYM_SIGGEN &&
-		info.algo == FIPS_TEST_ALGO_ECDSA &&
-		info.interim_info.ecdsa_data.pubkey_gen == 1) {
-		fips_prepare_asym_xform_t ecdsa_xform;
-		fips_prepare_op_t ecdsa_op;
-
-		ecdsa_xform = test_ops.prepare_asym_xform;
-		ecdsa_op = test_ops.prepare_asym_op;
-		info.op = FIPS_TEST_ASYM_KEYGEN;
-		test_ops.prepare_asym_xform = prepare_ecfpm_xform;
-		test_ops.prepare_asym_op = prepare_ecfpm_op;
-		ret = fips_run_asym_test();
-		if (ret < 0)
-			return ret;
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		fips_prepare_asym_xform_t old_xform;
+		fips_prepare_op_t old_op;
+
+		old_xform = test_ops.prepare_asym_xform;
+		old_op = test_ops.prepare_asym_op;
+
+		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
+		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
+			test_ops.prepare_asym_op = prepare_ecfpm_op;
 
-		info.post_interim_writeback(NULL);
-		info.interim_info.ecdsa_data.pubkey_gen = 0;
+			ret = fips_run_asym_test();
+			if (ret < 0)
+				return ret;
+
+			info.post_interim_writeback(NULL);
+			info.interim_info.ecdsa_data.pubkey_gen = 0;
 
-		test_ops.prepare_asym_xform = ecdsa_xform;
-		test_ops.prepare_asym_op = ecdsa_op;
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
+				   info.interim_info.eddsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+
+			const struct rte_cryptodev_asymmetric_xform_capability *cap;
+			struct rte_cryptodev_asym_capability_idx cap_idx;
+
+			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+			if (!cap) {
+				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+						env.dev_id);
+				return -EINVAL;
+			}
+
+			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
+				ret = fips_run_asym_test();
+				if (ret < 0)
+					return ret;
+			} else {
+				/* Below is only a workaround by using known keys. */
+				struct rte_crypto_asym_xform xform = {0};
+
+				prepare_edfpm_xform(&xform);
+				prepare_edfpm_op();
+				uint8_t pkey25519[] = {
+					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+				};
+				uint8_t q25519[] = {
+					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+				};
+				uint8_t pkey448[] = {
+					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+					0x01
+				};
+				uint8_t q448[] = {
+					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+					0x00
+				};
+				if (info.interim_info.eddsa_data.curve_id ==
+					RTE_CRYPTO_EC_GROUP_ED25519) {
+					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
+					vec.eddsa.q.len = 32;
+				} else {
+					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
+					vec.eddsa.q.len = 32;
+				}
+			}
+			info.post_interim_writeback(NULL);
+			info.interim_info.eddsa_data.pubkey_gen = 0;
+
+		}
+
+		test_ops.prepare_asym_xform = old_xform;
+		test_ops.prepare_asym_op = old_op;
 		info.op = FIPS_TEST_ASYM_SIGGEN;
 		ret = fips_run_asym_test();
 	} else {
@@ -2536,6 +2779,17 @@ init_test_ops(void)
 			test_ops.test = fips_generic_test;
 		}
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.test = fips_generic_test;
+		} else {
+			test_ops.prepare_asym_op = prepare_eddsa_op;
+			test_ops.prepare_asym_xform = prepare_eddsa_xform;
+			test_ops.test = fips_generic_test;
+		}
+		break;
 	default:
 		if (strstr(info.file_name, "TECB") ||
 				strstr(info.file_name, "TCBC")) {
@@ -2719,6 +2973,9 @@ fips_test_one_test_group(void)
 	case FIPS_TEST_ALGO_ECDSA:
 		ret = parse_test_ecdsa_json_init();
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		ret = parse_test_eddsa_json_init();
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build
index 34d3c7c8ca..7d4e440c6c 100644
--- a/examples/fips_validation/meson.build
+++ b/examples/fips_validation/meson.build
@@ -20,6 +20,7 @@ sources = files(
         'fips_validation_xts.c',
         'fips_validation_rsa.c',
         'fips_validation_ecdsa.c',
+        'fips_validation_eddsa.c',
         'fips_dev_self_test.c',
         'main.c',
 )
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v2 6/6] app/crypto-perf: support EDDSA
  2024-09-05 13:39 ` Gowrishankar Muthukrishnan
                     ` (3 preceding siblings ...)
  2024-09-05 13:39   ` [PATCH v2 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
@ 2024-09-05 13:39   ` Gowrishankar Muthukrishnan
  4 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-05 13:39 UTC (permalink / raw)
  To: dev, Ciara Power
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Added support for EDDSA 25519 curve SIGN and VERIFY operations.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test-crypto-perf/cperf_ops.c             | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_options.h         |  2 +
 app/test-crypto-perf/cperf_options_parsing.c |  9 +++-
 app/test-crypto-perf/cperf_test_common.c     |  1 +
 app/test-crypto-perf/cperf_test_vectors.c    | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_test_vectors.h    | 10 ++++
 app/test-crypto-perf/main.c                  | 13 +++++
 doc/guides/tools/cryptoperf.rst              |  1 +
 8 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index f139ec5331..220c3acac7 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -67,6 +67,36 @@ cperf_set_ops_asym_ecdsa(struct rte_crypto_op **ops,
 	}
 }
 
+static void
+cperf_set_ops_asym_eddsa(struct rte_crypto_op **ops,
+		   uint32_t src_buf_offset __rte_unused,
+		   uint32_t dst_buf_offset __rte_unused, uint16_t nb_ops,
+		   void *sess,
+		   const struct cperf_options *options,
+		   const struct cperf_test_vector *test_vector __rte_unused,
+		   uint16_t iv_offset __rte_unused,
+		   uint32_t *imix_idx __rte_unused,
+		   uint64_t *tsc_start __rte_unused)
+{
+	uint16_t i;
+
+	for (i = 0; i < nb_ops; i++) {
+		struct rte_crypto_asym_op *asym_op = ops[i]->asym;
+
+		ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		rte_crypto_op_attach_asym_session(ops[i], sess);
+
+		asym_op->eddsa.op_type = options->asym_op_type;
+		asym_op->eddsa.message.data = options->eddsa_data->message.data;
+		asym_op->eddsa.message.length = options->eddsa_data->message.length;
+
+		asym_op->eddsa.instance = options->eddsa_data->instance;
+
+		asym_op->eddsa.sign.data = options->eddsa_data->sign.data;
+		asym_op->eddsa.sign.length = options->eddsa_data->sign.length;
+	}
+}
+
 static void
 cperf_set_ops_asym_sm2(struct rte_crypto_op **ops,
 		   uint32_t src_buf_offset __rte_unused,
@@ -1031,6 +1061,25 @@ cperf_create_session(struct rte_mempool *sess_mp,
 		return asym_sess;
 	}
 
+	if (options->op_type == CPERF_ASYM_ED25519) {
+		xform.next = NULL;
+		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		xform.ec.curve_id = options->eddsa_data->curve;
+		xform.ec.pkey.data = options->eddsa_data->pkey.data;
+		xform.ec.pkey.length = options->eddsa_data->pkey.length;
+		xform.ec.q.x.data = options->eddsa_data->pubkey.data;
+		xform.ec.q.x.length = options->eddsa_data->pubkey.length;
+
+		ret = rte_cryptodev_asym_session_create(dev_id, &xform,
+				sess_mp, &asym_sess);
+		if (ret < 0) {
+			RTE_LOG(ERR, USER1, "EDDSA Asym session create failed\n");
+			return NULL;
+		}
+
+		return asym_sess;
+	}
+
 	if (options->op_type == CPERF_ASYM_SM2) {
 		xform.next = NULL;
 		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
@@ -1354,6 +1403,9 @@ cperf_get_op_functions(const struct cperf_options *options,
 	case CPERF_ASYM_SECP256R1:
 		op_fns->populate_ops = cperf_set_ops_asym_ecdsa;
 		break;
+	case CPERF_ASYM_ED25519:
+		op_fns->populate_ops = cperf_set_ops_asym_eddsa;
+		break;
 	case CPERF_ASYM_SM2:
 		op_fns->populate_ops = cperf_set_ops_asym_sm2;
 		break;
diff --git a/app/test-crypto-perf/cperf_options.h b/app/test-crypto-perf/cperf_options.h
index 131ecfdffb..dbc9f5a97b 100644
--- a/app/test-crypto-perf/cperf_options.h
+++ b/app/test-crypto-perf/cperf_options.h
@@ -89,6 +89,7 @@ enum cperf_op_type {
 	CPERF_IPSEC,
 	CPERF_ASYM_MODEX,
 	CPERF_ASYM_SECP256R1,
+	CPERF_ASYM_ED25519,
 	CPERF_ASYM_SM2,
 	CPERF_TLS,
 };
@@ -169,6 +170,7 @@ struct cperf_options {
 	struct cperf_modex_test_data *modex_data;
 	uint16_t modex_len;
 	struct cperf_ecdsa_test_data *secp256r1_data;
+	struct cperf_eddsa_test_data *eddsa_data;
 	struct cperf_sm2_test_data *sm2_data;
 	enum rte_crypto_asym_op_type asym_op_type;
 	enum rte_crypto_auth_algorithm asym_hash_alg;
diff --git a/app/test-crypto-perf/cperf_options_parsing.c b/app/test-crypto-perf/cperf_options_parsing.c
index c91fcf0479..59ea66c06d 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -38,7 +38,7 @@ usage(char *progname)
 		" --desc-nb N: set number of descriptors for each crypto device\n"
 		" --devtype TYPE: set crypto device type to use\n"
 		" --optype cipher-only / auth-only / cipher-then-auth / auth-then-cipher /\n"
-		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / sm2 / tls-record : set operation type\n"
+		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / eddsa / sm2 / tls-record : set operation type\n"
 		" --sessionless: enable session-less crypto operations\n"
 		" --shared-session: share 1 session across all queue pairs on crypto device\n"
 		" --out-of-place: enable out-of-place crypto operations\n"
@@ -489,6 +489,10 @@ parse_op_type(struct cperf_options *opts, const char *arg)
 			cperf_op_type_strs[CPERF_ASYM_SECP256R1],
 			CPERF_ASYM_SECP256R1
 		},
+		{
+			cperf_op_type_strs[CPERF_ASYM_ED25519],
+			CPERF_ASYM_ED25519
+		},
 		{
 			cperf_op_type_strs[CPERF_ASYM_SM2],
 			CPERF_ASYM_SM2
@@ -1080,6 +1084,7 @@ cperf_options_default(struct cperf_options *opts)
 	opts->modex_data = (struct cperf_modex_test_data *)&modex_perf_data[0];
 
 	opts->secp256r1_data = &secp256r1_perf_data;
+	opts->eddsa_data = &ed25519_perf_data;
 	opts->sm2_data = &sm2_perf_data;
 	opts->asym_op_type = RTE_CRYPTO_ASYM_OP_SIGN;
 }
@@ -1513,7 +1518,7 @@ cperf_options_dump(struct cperf_options *opts)
 	printf("#\n");
 	printf("# number of queue pairs per device: %u\n", opts->nb_qps);
 	printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
-	if (opts->op_type == CPERF_ASYM_SM2 || opts->op_type == CPERF_ASYM_SECP256R1)
+	if (cperf_is_asym_test(opts))
 		printf("# asym operation type: %s\n",
 				rte_crypto_asym_op_strings[opts->asym_op_type]);
 	printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
diff --git a/app/test-crypto-perf/cperf_test_common.c b/app/test-crypto-perf/cperf_test_common.c
index 33bee43c93..ae06ccfc76 100644
--- a/app/test-crypto-perf/cperf_test_common.c
+++ b/app/test-crypto-perf/cperf_test_common.c
@@ -307,6 +307,7 @@ cperf_is_asym_test(const struct cperf_options *options)
 {
 	if (options->op_type == CPERF_ASYM_MODEX ||
 	    options->op_type == CPERF_ASYM_SECP256R1 ||
+		options->op_type == CPERF_ASYM_ED25519 ||
 	    options->op_type == CPERF_ASYM_SM2)
 		return true;
 
diff --git a/app/test-crypto-perf/cperf_test_vectors.c b/app/test-crypto-perf/cperf_test_vectors.c
index 19c56b46bd..64720d50c3 100644
--- a/app/test-crypto-perf/cperf_test_vectors.c
+++ b/app/test-crypto-perf/cperf_test_vectors.c
@@ -853,6 +853,35 @@ static uint8_t secp256r1_message[] = {
 	0xdb, 0xc4, 0xe7, 0xa6, 0xa1, 0x33, 0xec, 0x56
 };
 
+static uint8_t ed25519_pkey[] = {
+	0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+	0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+	0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+	0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+};
+
+static uint8_t ed25519_pubkey[] = {
+	0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+	0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+	0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+	0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+};
+
+static uint8_t ed25519_sign[] = {
+	0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+	0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+	0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+	0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+	0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+	0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+	0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+	0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+};
+
+static uint8_t ed25519_message[] = {
+	0x72
+};
+
 static uint8_t fp256_pkey[] = {
 	0x77, 0x84, 0x35, 0x65, 0x4c, 0x7a, 0x6d, 0xb1,
 	0x1e, 0x63, 0x0b, 0x41, 0x97, 0x36, 0x04, 0xf4,
@@ -1365,6 +1394,29 @@ cperf_ecdsa_test_data secp256r1_perf_data = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP256R1
 };
 
+/** EDDSA 25519 elliptic curve test params */
+struct
+cperf_eddsa_test_data ed25519_perf_data = {
+	.pubkey = {
+		.data = ed25519_pubkey,
+		.length = sizeof(ed25519_pubkey),
+	},
+	.pkey = {
+		.data = ed25519_pkey,
+		.length = sizeof(ed25519_pkey),
+	},
+	.sign = {
+		.data = ed25519_sign,
+		.length = sizeof(ed25519_sign),
+	},
+	.message = {
+		.data = ed25519_message,
+		.length = sizeof(ed25519_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+};
+
 /** SM2 Fp256 elliptic curve test params */
 struct
 cperf_sm2_test_data sm2_perf_data = {
diff --git a/app/test-crypto-perf/cperf_test_vectors.h b/app/test-crypto-perf/cperf_test_vectors.h
index d46cbbc2c8..f83a17c176 100644
--- a/app/test-crypto-perf/cperf_test_vectors.h
+++ b/app/test-crypto-perf/cperf_test_vectors.h
@@ -118,6 +118,15 @@ struct cperf_ecdsa_test_data {
 	int curve;
 };
 
+struct cperf_eddsa_test_data {
+	rte_crypto_param pubkey;
+	rte_crypto_param pkey;
+	rte_crypto_param sign;
+	rte_crypto_param message;
+	int curve;
+	int instance;
+};
+
 struct cperf_sm2_test_data {
 	rte_crypto_param pubkey_qx;
 	rte_crypto_param pubkey_qy;
@@ -147,6 +156,7 @@ extern uint8_t digest[2048];
 
 extern struct cperf_modex_test_data modex_perf_data[10];
 extern struct cperf_ecdsa_test_data secp256r1_perf_data;
+extern struct cperf_eddsa_test_data ed25519_perf_data;
 extern struct cperf_sm2_test_data sm2_perf_data;
 
 #endif
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 75810dbf0b..d93b30bcaa 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -46,6 +46,7 @@ const char *cperf_op_type_strs[] = {
 	[CPERF_IPSEC] = "ipsec",
 	[CPERF_ASYM_MODEX] = "modex",
 	[CPERF_ASYM_SECP256R1] = "ecdsa_p256r1",
+	[CPERF_ASYM_ED25519] = "eddsa_25519",
 	[CPERF_ASYM_SM2] = "sm2",
 	[CPERF_TLS] = "tls-record"
 };
@@ -227,6 +228,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
 
 		switch (opts->op_type) {
 		case CPERF_ASYM_SECP256R1:
+		case CPERF_ASYM_ED25519:
 		case CPERF_ASYM_SM2:
 		case CPERF_ASYM_MODEX:
 			conf.ff_disable |= (RTE_CRYPTODEV_FF_SECURITY |
@@ -382,6 +384,17 @@ cperf_verify_devices_capabilities(struct cperf_options *opts,
 			}
 		}
 
+		if (opts->op_type == CPERF_ASYM_ED25519) {
+			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
+			if (asym_capability == NULL)
+				return -1;
+
+			if (!rte_cryptodev_asym_xform_capability_check_optype(asym_capability,
+						opts->asym_op_type))
+				return -1;
+		}
+
 		if (opts->op_type == CPERF_ASYM_SM2) {
 			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_SM2;
 			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst
index 0510a3bb89..9a20a73f03 100644
--- a/doc/guides/tools/cryptoperf.rst
+++ b/doc/guides/tools/cryptoperf.rst
@@ -176,6 +176,7 @@ The following are the application command-line options:
            docsis
            modex
            ecdsa_p256r1
+           eddsa_25519
            sm2
            ipsec
            tls-record
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v2 2/6] crypto/openssl: support EDDSA
  2024-09-05 13:39   ` [PATCH v2 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
@ 2024-09-09  9:56     ` Jack Bond-Preston
  0 siblings, 0 replies; 47+ messages in thread
From: Jack Bond-Preston @ 2024-09-09  9:56 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev, Kai Ji
  Cc: Anoob Joseph, bruce.richardson, ciara.power, jerinj,
	fanzhang.oss, arkadiuszx.kusztal, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Akhil Goyal

Hi,

On 05/09/2024 14:39, Gowrishankar Muthukrishnan wrote:
> Support EDDSA crypto algorithm in OpenSSL PMD.
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> ---
>   drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
>   drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
>   drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
>   3 files changed, 367 insertions(+)
<snip>
> +	ctx = BN_CTX_new();
> +	if (!ctx)
> +		goto err_ecfpm;
> +
<snip>
> +
> +err_ecfpm:
> +	BN_CTX_free(ctx);
> +	BN_free(n);
> +	return ret;
> +}
<snip>
> +
> +			md_ctx = EVP_MD_CTX_new();
> +			if (!md_ctx)
> +				goto err_eddsa;
> +
<snip>
> +	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
> +err_eddsa:
> +	OSSL_PARAM_BLD_free(iparam_bld);
> +
> +	if (sctx)
> +		EVP_PKEY_CTX_free(sctx);
> +
> +	if (cctx)
> +		EVP_PKEY_CTX_free(cctx);
> +
> +	if (pkey)
> +		EVP_PKEY_free(pkey);
> +
> +	return ret;
<etc..>

This (allocating and freeing ctxs for every operation) has pretty bad 
performance, refer to 
https://patches.dpdk.org/project/dpdk/cover/20240703134552.1439633-1-jack.bond-preston@foss.arm.com/ 
for more information.

I suppose for an initial implementation this could be ok - it's correct, 
just slow.

Cheers,
Jack


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-09-05 13:39   ` [PATCH v2 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
@ 2024-09-20 13:09     ` Gowrishankar Muthukrishnan
  2024-09-20 13:09       ` [PATCH v3 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
                         ` (5 more replies)
  0 siblings, 6 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-20 13:09 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, jerinj, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Gowrishankar Muthukrishnan

Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
https://datatracker.ietf.org/doc/html/rfc8032

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
 lib/cryptodev/rte_crypto_asym.h            | 47 ++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index f411d4bab7..3073753911 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -130,6 +130,7 @@ ECDSA                   =
 ECPM                    =
 ECDH                    =
 SM2                     =
+EDDSA                   =
 
 ;
 ; Supported Operating systems of a default crypto driver.
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 2b513bbf82..dd636ba5ef 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -927,7 +927,7 @@ Asymmetric Cryptography
 The cryptodev library currently provides support for the following asymmetric
 Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman and
 Elliptic Curve Diffie-Hellman public and/or private key generation and shared
-secret compute, DSA Signature generation and verification.
+secret compute, DSA and EdDSA Signature generation and verification.
 
 Session and Session Management
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index 39d3da3952..11bb885d64 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -49,6 +49,10 @@ rte_crypto_asym_op_strings[];
  * and if the flag is not set, shared secret will be padded to the left with
  * zeros to the size of the underlying algorithm (default)
  */
+#define RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED		RTE_BIT32(2)
+/**<
+ * Flag to denote public key will be returned in compressed form
+ */
 
 /**
  * List of elliptic curves. This enum aligns with
@@ -65,9 +69,22 @@ enum rte_crypto_curve_id {
 	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
 	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
 	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
+	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
+	RTE_CRYPTO_EC_GROUP_ED448     = 30,
 	RTE_CRYPTO_EC_GROUP_SM2       = 41,
 };
 
+/**
+ * List of Edwards curve instances as per RFC 8032 (Section 5).
+ */
+enum rte_crypto_edward_instance {
+	RTE_CRYPTO_EDCURVE_25519,
+	RTE_CRYPTO_EDCURVE_25519CTX,
+	RTE_CRYPTO_EDCURVE_25519PH,
+	RTE_CRYPTO_EDCURVE_448,
+	RTE_CRYPTO_EDCURVE_448PH
+};
+
 /**
  * Asymmetric crypto transformation types.
  * Each xform type maps to one asymmetric algorithm
@@ -119,6 +136,10 @@ enum rte_crypto_asym_xform_type {
 	 * Performs Encrypt, Decrypt, Sign and Verify.
 	 * Refer to rte_crypto_asym_op_type.
 	 */
+	RTE_CRYPTO_ASYM_XFORM_EDDSA,
+	/**< Edwards Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -585,6 +606,31 @@ struct rte_crypto_ecdsa_op_param {
 	 */
 };
 
+/**
+ * EDDSA operation params
+ */
+struct rte_crypto_eddsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param message;
+	/**< Input message digest to be signed or verified */
+
+	rte_crypto_param context;
+	/**< Context value for the sign op.
+	 *   Must not be empty for Ed25519ctx instance.
+	 */
+
+	enum rte_crypto_edward_instance instance;
+	/**< Type of Edwards curve. */
+
+	rte_crypto_uint sign;
+	/**< Edward curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Structure for EC point multiplication operation param
  */
@@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_ecdsa_op_param ecdsa;
 		struct rte_crypto_ecpm_op_param ecpm;
 		struct rte_crypto_sm2_op_param sm2;
+		struct rte_crypto_eddsa_op_param eddsa;
 	};
 	uint16_t flags;
 	/**<
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v3 2/6] crypto/openssl: support EDDSA
  2024-09-20 13:09     ` [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
@ 2024-09-20 13:09       ` Gowrishankar Muthukrishnan
  2024-09-20 14:36         ` Akhil Goyal
  2024-09-20 13:09       ` [PATCH v3 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
                         ` (4 subsequent siblings)
  5 siblings, 1 reply; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-20 13:09 UTC (permalink / raw)
  To: dev, Kai Ji
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in OpenSSL PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
 drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
 3 files changed, 367 insertions(+)

diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index a50e4d4918..a613988dbe 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -231,10 +231,23 @@ struct __rte_cache_aligned openssl_asym_session {
 #endif
 		} s;
 		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			EC_GROUP * group;
+			BIGNUM *priv_key;
+#endif
+		} ec;
+		struct {
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 			OSSL_PARAM * params;
 #endif
 		} sm2;
+		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			OSSL_PARAM * params;
+#endif
+		} eddsa;
 	} u;
 };
 /** Set and validate OPENSSL crypto session parameters */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 101111e85b..cbc10b27d4 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2849,6 +2849,45 @@ process_openssl_rsa_op_evp(struct rte_crypto_op *cop,
 
 }
 
+static int
+process_openssl_ecfpm_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	const EC_GROUP *ecgrp = sess->u.ec.group;
+	EC_POINT *ecpt = NULL;
+	BN_CTX *ctx = NULL;
+	BIGNUM *n = NULL;
+	int ret = -1;
+
+	n = BN_bin2bn((const unsigned char *)
+			cop->asym->ecpm.scalar.data,
+			cop->asym->ecpm.scalar.length,
+			BN_new());
+
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto err_ecfpm;
+
+	if (!EC_POINT_mul(ecgrp, ecpt, n, NULL, NULL, ctx))
+		goto err_ecfpm;
+
+	if (cop->asym->flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED) {
+		unsigned char *buf = cop->asym->ecpm.r.x.data;
+		size_t sz;
+
+		sz = EC_POINT_point2oct(ecgrp, ecpt, POINT_CONVERSION_COMPRESSED, buf, 0, ctx);
+		if (!sz)
+			goto err_ecfpm;
+
+		cop->asym->ecpm.r.x.length = sz;
+	}
+
+err_ecfpm:
+	BN_CTX_free(ctx);
+	BN_free(n);
+	return ret;
+}
+
 static int
 process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3074,6 +3113,158 @@ process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 	return ret;
 }
 
+static int
+process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	static const char * const instance[] = {"Ed25519", "Ed25519ctx", "Ed25519ph",
+						"Ed448", "Ed448ph"};
+	EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
+	const uint8_t curve_id = sess->u.eddsa.curve_id;
+	struct rte_crypto_asym_op *op = cop->asym;
+	OSSL_PARAM *params = sess->u.eddsa.params;
+	OSSL_PARAM_BLD *iparam_bld = NULL;
+	OSSL_PARAM *iparams = NULL;
+	uint8_t signbuf[128] = {0};
+	EVP_MD_CTX *md_ctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	size_t signlen;
+	int ret = -1;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	iparam_bld = OSSL_PARAM_BLD_new();
+	if (!iparam_bld)
+		goto err_eddsa;
+
+	if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519CTX) {
+		OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-string",
+			op->eddsa.context.data, op->eddsa.context.length);
+
+	}
+
+	OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
+		instance[op->eddsa.instance], strlen(instance[op->eddsa.instance]));
+
+	iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
+	if (!iparams)
+		goto err_eddsa;
+
+	switch (op->eddsa.op_type) {
+	case RTE_CRYPTO_ASYM_OP_SIGN:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			if (!EVP_DigestSign(md_ctx, NULL, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			if (signlen > RTE_DIM(signbuf))
+				goto err_eddsa;
+
+			if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
+			op->eddsa.sign.length = signlen;
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_VERIFY:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			signlen = op->eddsa.sign.length;
+			memcpy(&signbuf[0], op->eddsa.sign.data, op->eddsa.sign.length);
+
+			ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op->eddsa.message.data,
+					op->eddsa.message.length);
+			if (ret == 0)
+				goto err_eddsa;
+		}
+		break;
+	default:
+		/* allow ops with invalid args to be pushed to
+		 * completion queue
+		 */
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		goto err_eddsa;
+	}
+
+	ret = 0;
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+err_eddsa:
+	OSSL_PARAM_BLD_free(iparam_bld);
+
+	if (sctx)
+		EVP_PKEY_CTX_free(sctx);
+
+	if (cctx)
+		EVP_PKEY_CTX_free(cctx);
+
+	if (pkey)
+		EVP_PKEY_free(pkey);
+
+	return ret;
+}
 #else
 static int
 process_openssl_rsa_op(struct rte_crypto_op *cop,
@@ -3174,6 +3365,15 @@ process_openssl_rsa_op(struct rte_crypto_op *cop,
 	return 0;
 }
 
+static int
+process_openssl_ecfpm_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
+
 static int
 process_openssl_sm2_op(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3182,6 +3382,15 @@ process_openssl_sm2_op(struct rte_crypto_op *cop,
 	RTE_SET_USED(sess);
 	return -ENOTSUP;
 }
+
+static int
+process_openssl_eddsa_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
 #endif
 
 static int
@@ -3230,6 +3439,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 				process_openssl_dsa_verify_op(op, sess);
 		else
 			op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_ecfpm_op_evp(op, sess);
+#else
+		retval = process_openssl_ecfpm_op(op, sess);
 #endif
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
@@ -3237,6 +3453,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 		retval = process_openssl_sm2_op_evp(op, sess);
 #else
 		retval = process_openssl_sm2_op(op, sess);
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_eddsa_op_evp(op, sess);
+#else
+		retval = process_openssl_eddsa_op(op, sess);
 #endif
 		break;
 	default:
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index 1bbb855a59..bc41717e83 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -593,6 +593,16 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		},
 		}
 	},
+	{	/* ECFPM */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM,
+				.op_types = 0
+				}
+			}
+		}
+	},
 	{	/* SM2 */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
@@ -610,6 +620,20 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		}
 		}
 	},
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types =
+				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
+				 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+			}
+		}
+		}
+	},
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1356,6 +1380,47 @@ static int openssl_set_asym_session_parameters(
 		BN_free(pub_key);
 		return -1;
 	}
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		EC_GROUP *ecgrp = NULL;
+
+		asym_session->xfrm_type = xform->xform_type;
+
+		switch (xform->ec.curve_id) {
+		case RTE_CRYPTO_EC_GROUP_SECP192R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp192k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP224R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp224r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP256R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP384R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp384r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP521R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp521r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED25519:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED25519);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED448:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED448);
+			break;
+		default:
+			break;
+		}
+
+		asym_session->u.ec.curve_id = xform->ec.curve_id;
+		asym_session->u.ec.group = ecgrp;
+		break;
+#else
+		OPENSSL_LOG(WARNING, "ECFPM unsupported for OpenSSL Version < 3.0");
+		return -ENOTSUP;
+#endif
+	}
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 	{
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
@@ -1440,6 +1505,66 @@ static int openssl_set_asym_session_parameters(
 #else
 		OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL Version < 3.0");
 		return -ENOTSUP;
+#endif
+	}
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		OSSL_PARAM_BLD *param_bld = NULL;
+		OSSL_PARAM *params = NULL;
+		int ret = -1;
+
+		asym_session->u.eddsa.curve_id = xform->ec.curve_id;
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+			  OSSL_PKEY_PARAM_GROUP_NAME, "ED25519", sizeof("ED25519"));
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PRIV_KEY,
+				xform->ec.pkey.data, xform->ec.pkey.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
+				xform->ec.q.x.data, xform->ec.q.x.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		params = OSSL_PARAM_BLD_to_param(param_bld);
+		if (!params) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		asym_session->u.eddsa.params = params;
+		OSSL_PARAM_BLD_free(param_bld);
+
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		break;
+err_eddsa:
+		if (param_bld)
+			OSSL_PARAM_BLD_free(param_bld);
+
+		if (asym_session->u.eddsa.params)
+			OSSL_PARAM_free(asym_session->u.eddsa.params);
+
+		return -1;
+#else
+		OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL Version < 3.0");
+		return -ENOTSUP;
 #endif
 	}
 	default:
@@ -1538,6 +1663,12 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 		OSSL_PARAM_free(sess->u.sm2.params);
 #endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		OSSL_PARAM_free(sess->u.eddsa.params);
+#endif
+		break;
 	default:
 		break;
 	}
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v3 3/6] crypto/cnxk: support EDDSA
  2024-09-20 13:09     ` [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-09-20 13:09       ` [PATCH v3 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
@ 2024-09-20 13:09       ` Gowrishankar Muthukrishnan
  2024-09-20 13:09       ` [PATCH v3 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
                         ` (3 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-20 13:09 UTC (permalink / raw)
  To: dev, Ankur Dwivedi, Anoob Joseph, Tejasree Kondoj,
	Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
	Harman Kalra
  Cc: bruce.richardson, jerinj, fanzhang.oss, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Akhil Goyal, Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in CNXK PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/cn10k.ini      |   1 +
 drivers/common/cnxk/hw/cpt.h                  |   3 +-
 drivers/common/cnxk/roc_ae.c                  |  52 +-
 drivers/common/cnxk/roc_ae.h                  |  10 +
 drivers/common/cnxk/roc_ae_fpm_tables.c       | 580 +++++++++++++++++-
 drivers/crypto/cnxk/cnxk_ae.h                 | 473 +++++++++++++-
 drivers/crypto/cnxk/cnxk_cryptodev.h          |   2 +-
 .../crypto/cnxk/cnxk_cryptodev_capabilities.c |  19 +
 8 files changed, 1129 insertions(+), 11 deletions(-)

diff --git a/doc/guides/cryptodevs/features/cn10k.ini b/doc/guides/cryptodevs/features/cn10k.ini
index 39f4b56b9f..bb7d265005 100644
--- a/doc/guides/cryptodevs/features/cn10k.ini
+++ b/doc/guides/cryptodevs/features/cn10k.ini
@@ -107,6 +107,7 @@ ECDH                    = Y
 ECDSA                   = Y
 ECPM                    = Y
 SM2                     = Y
+EDDSA                   = Y
 
 ;
 ; Supported Operating systems of the 'cn10k' crypto driver.
diff --git a/drivers/common/cnxk/hw/cpt.h b/drivers/common/cnxk/hw/cpt.h
index 2620965606..47df3fbf9f 100644
--- a/drivers/common/cnxk/hw/cpt.h
+++ b/drivers/common/cnxk/hw/cpt.h
@@ -81,7 +81,8 @@ union cpt_eng_caps {
 		uint64_t __io sm2 : 1;
 		uint64_t __io pdcp_chain_zuc256 : 1;
 		uint64_t __io tls : 1;
-		uint64_t __io reserved_39_63 : 25;
+		uint64_t __io eddsa : 1;
+		uint64_t __io reserved_40_63 : 24;
 	};
 };
 
diff --git a/drivers/common/cnxk/roc_ae.c b/drivers/common/cnxk/roc_ae.c
index 7ef0efe2b3..2c563c30de 100644
--- a/drivers/common/cnxk/roc_ae.c
+++ b/drivers/common/cnxk/roc_ae.c
@@ -179,7 +179,57 @@ const struct roc_ae_ec_group ae_ec_grp[ROC_AE_EC_ID_PMAX] = {
 				    0xAB, 0x8F, 0x92, 0xDD, 0xBC, 0xBD, 0x41,
 				    0x4D, 0x94, 0x0E, 0x93},
 			   .length = 32},
-	}};
+	},
+	{
+		.prime = {.data = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0x7F},
+			  .length = 32},
+		.order = {.data = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12,
+				   0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9,
+				   0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x10},
+			  .length = 32},
+		.consta = {.data = {0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb,
+				    0x75, 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a,
+				    0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79,
+				    0x40, 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b,
+				    0xee, 0x6c, 0x03, 0x52},
+			   .length = 32},
+	},
+	{
+		.prime = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			  .length = 56},
+		.order = {.data = {0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78,
+				   0x23, 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2,
+				   0x6c, 0x21, 0x90, 0x36, 0xd6, 0xae, 0x49,
+				   0xdb, 0x4e, 0xc4, 0xe9, 0x23, 0xca, 0x7c,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f},
+			  .length = 56},
+		.consta = {.data = {0x56, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			   .length = 56},
+	},
+};
 
 int
 roc_ae_ec_grp_get(struct roc_ae_ec_group **tbl)
diff --git a/drivers/common/cnxk/roc_ae.h b/drivers/common/cnxk/roc_ae.h
index 7886b9d107..880ed5f75a 100644
--- a/drivers/common/cnxk/roc_ae.h
+++ b/drivers/common/cnxk/roc_ae.h
@@ -12,6 +12,7 @@
 #define ROC_AE_MAJOR_OP_MODEX	     0x03
 #define ROC_AE_MAJOR_OP_EC	     0x04
 #define ROC_AE_MAJOR_OP_ECC	     0x05
+#define ROC_AE_MAJOR_OP_EDDSA	     0x0A
 #define ROC_AE_MINOR_OP_RANDOM	     0x00
 #define ROC_AE_MINOR_OP_MODEX	     0x01
 #define ROC_AE_MINOR_OP_PKCS_ENC     0x02
@@ -23,6 +24,9 @@
 #define ROC_AE_MINOR_OP_EC_VERIFY    0x02
 #define ROC_AE_MINOR_OP_ECC_UMP	     0x03
 #define ROC_AE_MINOR_OP_ECC_FPM	     0x04
+#define ROC_AE_MINOR_OP_ED_SIGN      0x00
+#define ROC_AE_MINOR_OP_ED_VERIFY    0x01
+#define ROC_AE_MINOR_OP_ED_KEYGEN    0x02
 
 /**
  * Enumeration roc_ae_ec_id
@@ -39,6 +43,8 @@ typedef enum {
 	ROC_AE_EC_ID_P320 = 6,
 	ROC_AE_EC_ID_P512 = 7,
 	ROC_AE_EC_ID_SM2  = 8,
+	ROC_AE_EC_ID_ED25519 = 9,
+	ROC_AE_EC_ID_ED448   = 10,
 	ROC_AE_EC_ID_PMAX
 } roc_ae_ec_id;
 
@@ -47,6 +53,10 @@ typedef enum {
 #define ROC_AE_EC_PARAM1_SM2       (1 << 7)
 #define ROC_AE_EC_PARAM1_NIST      (0 << 6)
 #define ROC_AE_EC_PARAM1_NONNIST   (1 << 6)
+#define ROC_AE_ED_PARAM1_25519     (1 << 1)
+#define ROC_AE_ED_PARAM1_448       (1 << 3)
+#define ROC_AE_ED_PARAM1_KEYGEN_BIT      4
+#define ROC_AE_EC_PARAM1_PH_BIT          5
 
 typedef enum {
 	ROC_AE_ERR_ECC_PAI = 0x0b,
diff --git a/drivers/common/cnxk/roc_ae_fpm_tables.c b/drivers/common/cnxk/roc_ae_fpm_tables.c
index 942657b56a..0a5e8d0ec4 100644
--- a/drivers/common/cnxk/roc_ae_fpm_tables.c
+++ b/drivers/common/cnxk/roc_ae_fpm_tables.c
@@ -21,7 +21,9 @@ typedef enum {
 	AE_FPM_P224_LEN = 2160,
 	AE_FPM_P256_LEN = 2160,
 	AE_FPM_P384_LEN = 2520,
-	AE_FPM_P521_LEN = 3240
+	AE_FPM_P521_LEN = 3240,
+	AE_FPM_ED25519_LEN = 2880,
+	AE_FPM_ED448_LEN   = 3840,
 } ae_fpm_len;
 
 /* FPM table address and length */
@@ -1240,6 +1242,572 @@ const uint8_t ae_fpm_tbl_p256_sm2[AE_FPM_P256_LEN] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+const uint8_t ae_fpm_tbl_ed25519[AE_FPM_ED25519_LEN] = {
+	0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a, 0x69, 0x2c, 0xc7, 0x60,
+	0x95, 0x25, 0xa7, 0xb2, 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c,
+	0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6d, 0xde, 0x8a, 0xb3, 0xa5, 0xb7, 0xdd, 0xa3, 0x20, 0xf0, 0x9f, 0x80,
+	0x77, 0x51, 0x52, 0xf5, 0x66, 0xea, 0x4e, 0x8e, 0x64, 0xab, 0xe3, 0x7d,
+	0x67, 0x87, 0x5f, 0x0f, 0xd7, 0x8b, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x18, 0xc0, 0x0c, 0x55, 0x07, 0xed, 0xf1, 0x0d, 0x69, 0xbe, 0x61, 0x3a,
+	0x4f, 0x82, 0xd2, 0xc4, 0x3e, 0xf0, 0xa1, 0x4e, 0xf1, 0xba, 0xd8, 0xb1,
+	0x5a, 0x8a, 0x5a, 0x58, 0xbe, 0xf1, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x63, 0xce, 0x54, 0x79, 0x0e, 0x45, 0x3f, 0x73, 0xe9, 0x33, 0xff, 0xc7,
+	0xec, 0xab, 0xc7, 0x4b, 0x6b, 0x43, 0x64, 0x02, 0x45, 0xcf, 0x64, 0xfa,
+	0x1a, 0xd2, 0xdd, 0x57, 0x64, 0x55, 0xf6, 0x78, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x8c, 0x9d, 0x04, 0xac, 0x84, 0x05, 0xe0, 0xe7, 0xa5, 0x17, 0x56,
+	0x92, 0x2e, 0xbd, 0x07, 0x96, 0x72, 0x74, 0xa7, 0xd8, 0x1d, 0x8d, 0x30,
+	0x42, 0x4d, 0xa3, 0xd2, 0x15, 0xae, 0xf3, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x19, 0xcf, 0x23, 0xc1, 0x1f, 0x40, 0x15, 0x86, 0x4d, 0xd5, 0x99, 0x64,
+	0x9b, 0x94, 0x9e, 0x8e, 0x22, 0x68, 0xc6, 0xcf, 0xf4, 0xe4, 0xf9, 0xd9,
+	0x75, 0xe4, 0xce, 0xc7, 0xf1, 0xc8, 0x41, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x98, 0x8c, 0x87, 0x10, 0xcd, 0x87, 0x55, 0x95, 0x52, 0x83, 0xad, 0xc1,
+	0x83, 0x92, 0xcf, 0xa4, 0x28, 0x4a, 0x93, 0xe5, 0x21, 0x53, 0xaa, 0x3d,
+	0x33, 0x97, 0x60, 0xe6, 0xcb, 0xdc, 0xf5, 0xd4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe6, 0xf2, 0x50, 0x1e, 0x50, 0x14, 0x12, 0xd8, 0x45, 0xcc, 0xd0, 0xd4,
+	0x75, 0x78, 0xec, 0xae, 0x42, 0x10, 0x45, 0x12, 0x74, 0x2b, 0x26, 0xde,
+	0x41, 0xea, 0x80, 0x41, 0x7f, 0xb3, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x75, 0x61, 0x33, 0xad, 0x0c, 0x22, 0xe4, 0x7f, 0xd7, 0x18, 0xb3,
+	0xf9, 0xd3, 0x55, 0x9e, 0x96, 0x2d, 0xa3, 0xfa, 0x7d, 0xfb, 0x1e, 0xb6,
+	0x4e, 0xd0, 0xb6, 0x26, 0xa7, 0x32, 0x09, 0x87, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaf, 0x7f, 0xd1, 0x3e, 0xfe, 0xa5, 0xa5, 0x96, 0x3c, 0x42, 0xec, 0x0e,
+	0xef, 0x69, 0x4e, 0x62, 0xf5, 0xb9, 0xc2, 0xad, 0x65, 0x7b, 0x91, 0x6f,
+	0x25, 0x55, 0x0a, 0xc3, 0x9c, 0xfb, 0x1a, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2a, 0xf9, 0xfb, 0x16, 0x90, 0xe8, 0x72, 0x7e, 0x98, 0x92, 0x1f, 0xc5,
+	0x97, 0x96, 0xc5, 0x0c, 0x8a, 0x12, 0x0b, 0xf3, 0x98, 0xc0, 0x5f, 0x4d,
+	0x38, 0x56, 0x94, 0x41, 0xa1, 0xf5, 0xcd, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0x39, 0xdb, 0x96, 0xf7, 0x8d, 0x2e, 0x7c, 0xb1, 0xc0, 0x51, 0x3b,
+	0xa4, 0xc4, 0x55, 0x12, 0x75, 0x29, 0xd9, 0x29, 0x65, 0x02, 0x36, 0x8d,
+	0x0a, 0x97, 0xdf, 0xad, 0x58, 0xfa, 0x26, 0x19, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0x4b, 0xb5, 0xe5, 0x13, 0xa5, 0x45, 0x40, 0x2c, 0xba, 0x4d, 0x3b,
+	0x1e, 0x5f, 0x55, 0xb8, 0x04, 0xa2, 0xce, 0x24, 0x52, 0x7e, 0xb7, 0x3c,
+	0x78, 0xd9, 0x8e, 0xba, 0xc3, 0x3b, 0xd9, 0x46, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb2, 0x1d, 0x1e, 0x95, 0xfb, 0x8d, 0x9a, 0xdd, 0xdb, 0xfc, 0xa8, 0xca,
+	0x0f, 0x51, 0x54, 0x75, 0x72, 0x53, 0xc9, 0xca, 0xe4, 0x6b, 0x0a, 0x2f,
+	0x3d, 0xc4, 0xd8, 0x0a, 0x0c, 0x80, 0x9a, 0xb6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0xc6, 0x8e, 0xea, 0x63, 0xb3, 0x17, 0x45, 0x1b, 0xc9, 0x4f, 0xf2,
+	0xb9, 0xce, 0xab, 0x28, 0x84, 0x84, 0x27, 0x82, 0x6e, 0x59, 0x5d, 0x0d,
+	0x57, 0x1c, 0xd9, 0x4b, 0x55, 0xf8, 0xa2, 0xd1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x76, 0xd4, 0x7d, 0xa8, 0x8a, 0xfd, 0x34, 0xf3, 0x5e, 0xa7, 0x1b, 0x7c,
+	0x94, 0x84, 0x05, 0x81, 0x7f, 0x9d, 0x55, 0x08, 0x06, 0x03, 0x5e, 0x42,
+	0x42, 0xe8, 0x55, 0x9a, 0xac, 0x90, 0x41, 0xf2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x74, 0xd2, 0x01, 0x61, 0xc0, 0x1f, 0x88, 0x8b, 0xcb, 0xca, 0xf5, 0xd3,
+	0x63, 0x58, 0x4b, 0xbb, 0x66, 0xc6, 0x4e, 0xab, 0x8c, 0x6c, 0x68, 0x22,
+	0x66, 0xca, 0x84, 0x72, 0x7e, 0x3c, 0x0b, 0xa2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0x0b, 0xdb, 0xf8, 0x8a, 0x48, 0x29, 0x71, 0x03, 0xf7, 0xcf, 0x4d,
+	0xb1, 0x85, 0x7a, 0x22, 0x97, 0xbe, 0x2e, 0xd9, 0xa1, 0xee, 0x20, 0x13,
+	0x2f, 0x5e, 0x07, 0xda, 0x24, 0x97, 0xb3, 0x43, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xec, 0x5e, 0x68, 0xad, 0xfe, 0x26, 0x70, 0x65, 0xfa, 0x03, 0x3f, 0x24,
+	0x56, 0xa2, 0x51, 0xc9, 0x79, 0x88, 0x89, 0x08, 0x86, 0x02, 0x18, 0x39,
+	0x59, 0x77, 0x53, 0x1b, 0xf7, 0x2c, 0x65, 0x3c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x23, 0xb1, 0xc4, 0x4d, 0xad, 0xf1, 0xae, 0x7a, 0x52, 0xba, 0x48,
+	0xd0, 0x0a, 0xc1, 0x94, 0x34, 0x41, 0x1b, 0x3d, 0x93, 0x49, 0xf0, 0x8d,
+	0x25, 0xf2, 0x72, 0x56, 0xd7, 0xb7, 0x05, 0x81, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0x05, 0x2c, 0x85, 0xc5, 0x52, 0xad, 0x02, 0xbd, 0xb7, 0x5d, 0x21,
+	0xcd, 0xbd, 0xce, 0x01, 0xd3, 0xd9, 0x12, 0xba, 0xc6, 0x7f, 0x45, 0x31,
+	0x00, 0x33, 0x8c, 0x20, 0x63, 0x4d, 0xf5, 0x22, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1a, 0x38, 0xa7, 0xf1, 0x5b, 0xd0, 0xb8, 0x54, 0x3c, 0x33, 0x27, 0x32,
+	0xca, 0x04, 0x38, 0x5e, 0xa0, 0xf8, 0x81, 0x06, 0xa0, 0xe7, 0x47, 0x1d,
+	0x16, 0xcb, 0xaa, 0x68, 0xb5, 0x6a, 0xd2, 0xaa, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3e, 0x69, 0x14, 0xef, 0xc0, 0x82, 0x94, 0x72, 0x09, 0x07, 0xb5, 0xa6,
+	0x98, 0x1d, 0xb2, 0xd7, 0xcb, 0xe4, 0x6c, 0xb7, 0x88, 0x78, 0x8b, 0xd9,
+	0x34, 0x5a, 0xdb, 0xae, 0x55, 0x6a, 0x6b, 0x1f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf1, 0x20, 0x49, 0xc6, 0xda, 0x47, 0x7a, 0x25, 0x9e, 0xce, 0xf6, 0x2e,
+	0xd4, 0x76, 0xb6, 0x0f, 0x41, 0x54, 0x08, 0xb8, 0x29, 0x08, 0x96, 0xd0,
+	0x01, 0x23, 0x34, 0xb6, 0x1e, 0xfe, 0xb0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd1, 0x6c, 0x52, 0xd3, 0x5f, 0x6a, 0x74, 0x18, 0x9b, 0xfe, 0xf3, 0x73,
+	0x74, 0xb8, 0x05, 0xa2, 0x29, 0x9d, 0x41, 0x53, 0x72, 0xa2, 0x93, 0x7c,
+	0x0a, 0xa8, 0xe8, 0x48, 0x89, 0x8f, 0x6f, 0x60, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x21, 0x4a, 0xd6, 0xa6, 0x0b, 0x51, 0xf6, 0x1d, 0xa2, 0x5c, 0xa5, 0x23,
+	0x6a, 0x1e, 0x34, 0x7d, 0xc5, 0xfe, 0xba, 0x77, 0x9d, 0xe5, 0x40, 0x9c,
+	0x38, 0x4e, 0xab, 0x29, 0x0d, 0x17, 0x7e, 0x48, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1e, 0x04, 0x03, 0xaf, 0xbd, 0x77, 0xba, 0x7d, 0x53, 0xe9, 0x14, 0x63,
+	0x40, 0xa7, 0xba, 0x26, 0x00, 0x55, 0x42, 0xff, 0x7c, 0x0d, 0xde, 0xd1,
+	0x59, 0xa2, 0x72, 0x6d, 0x1a, 0x92, 0x7e, 0x56, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x6d, 0x5c, 0x1d, 0x19, 0xf5, 0x09, 0x6d, 0x18, 0xa1, 0x69, 0x87,
+	0xad, 0x52, 0x19, 0x1e, 0xf1, 0x83, 0x14, 0xea, 0x85, 0x1c, 0xeb, 0xe0,
+	0x09, 0x34, 0x4b, 0x8a, 0xd2, 0x98, 0x25, 0x20, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4c, 0x5a, 0xf1, 0x8b, 0x60, 0xa3, 0xef, 0xfb, 0xe6, 0x9a, 0x9e, 0x2a,
+	0x7c, 0x79, 0x13, 0x18, 0x9b, 0x68, 0xed, 0x3d, 0x9c, 0x96, 0x87, 0x75,
+	0x7d, 0x03, 0x00, 0x62, 0x8a, 0x38, 0x69, 0x58, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8e, 0x21, 0xc4, 0x17, 0x0e, 0x2d, 0x4e, 0x01, 0xb5, 0xfb, 0x2e, 0x65,
+	0x3f, 0x32, 0xd7, 0x18, 0x50, 0x70, 0x81, 0x6b, 0xf7, 0xab, 0xc2, 0xfc,
+	0x4b, 0xa9, 0x21, 0x10, 0x37, 0x21, 0xbf, 0xbb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xda, 0x5a, 0x33, 0xeb, 0x21, 0x36, 0x7c, 0x40, 0x16, 0x1d, 0xd5, 0x6e,
+	0xe1, 0xe4, 0x79, 0x2b, 0x9f, 0x9f, 0x06, 0x89, 0x80, 0x93, 0xc6, 0x0f,
+	0x61, 0xbe, 0x0b, 0x75, 0xdb, 0x7c, 0x78, 0x50, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8b, 0xdc, 0x45, 0xa9, 0x5e, 0xbc, 0xf3, 0xb4, 0xcc, 0x3c, 0xba, 0xbd,
+	0x65, 0x2f, 0x2f, 0xd7, 0xd5, 0x15, 0x7f, 0x7e, 0x03, 0x0b, 0xc6, 0xc7,
+	0x6b, 0x6b, 0x6e, 0x77, 0x30, 0xcb, 0xc0, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2e, 0xf0, 0x16, 0xcd, 0xf9, 0x23, 0xf9, 0x10, 0xe0, 0x5d, 0xa7, 0x26,
+	0xbb, 0xf1, 0x53, 0x06, 0xea, 0x81, 0x2f, 0x38, 0x9e, 0x53, 0x67, 0x40,
+	0x74, 0x2a, 0xd5, 0x6e, 0xec, 0xc8, 0xa5, 0xcb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe2, 0x1f, 0xc1, 0xee, 0x82, 0xd5, 0x6e, 0x58, 0x81, 0x97, 0x4c, 0xf3,
+	0x0b, 0x90, 0x1e, 0x1f, 0xf8, 0xdc, 0x2b, 0xc0, 0x58, 0x3b, 0x2a, 0x28,
+	0x56, 0xc1, 0xe7, 0xb4, 0x40, 0x44, 0x5b, 0x54, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x85, 0x49, 0x08, 0xe7, 0xfa, 0x5d, 0x0c, 0xf9, 0xa3, 0x6e, 0xe5,
+	0x34, 0x8e, 0x83, 0xf2, 0xd0, 0xf1, 0xa4, 0x13, 0x32, 0x52, 0x86, 0x50,
+	0x75, 0xcd, 0xb5, 0xfc, 0xe9, 0x7b, 0x7c, 0xf6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2c, 0x85, 0x09, 0xe3, 0xd9, 0x4a, 0x91, 0xa2, 0x10, 0xf7, 0x7f, 0x5b,
+	0xde, 0x9a, 0xb7, 0x87, 0x32, 0x7d, 0x63, 0xf6, 0x7e, 0x0c, 0x3e, 0xcc,
+	0x4a, 0xa4, 0x9e, 0x35, 0x6b, 0x55, 0x50, 0x2e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xde, 0x9c, 0x80, 0x75, 0xc0, 0x21, 0x92, 0xf7, 0x30, 0x72, 0x1c, 0x15,
+	0xb2, 0x00, 0x0e, 0xc4, 0xa1, 0xa6, 0x1a, 0x6d, 0xd1, 0x63, 0x6b, 0xa8,
+	0x4b, 0x01, 0x10, 0x6f, 0x61, 0xe7, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7f, 0xdd, 0x3e, 0x2e, 0x6d, 0x7e, 0xed, 0x72, 0x65, 0xf7, 0x8d, 0x29,
+	0xba, 0x75, 0xa3, 0x07, 0x93, 0x86, 0xb4, 0xee, 0xcd, 0xd8, 0x5d, 0x19,
+	0x22, 0x02, 0x39, 0xba, 0xc5, 0x05, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa2, 0x01, 0xed, 0x74, 0x47, 0xd9, 0x0b, 0x18, 0x73, 0x4d, 0xcd, 0x41,
+	0x9a, 0xe4, 0xf1, 0xee, 0x33, 0x8a, 0x74, 0x8b, 0x26, 0xfd, 0x6e, 0x02,
+	0x2e, 0x5c, 0xc7, 0xf5, 0xa1, 0xeb, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3a, 0x3c, 0x00, 0x91, 0x80, 0xf2, 0x0f, 0x07, 0xf5, 0x02, 0xdc, 0xfa,
+	0xb7, 0x6e, 0x74, 0xdc, 0x3a, 0x78, 0xc5, 0x28, 0x8e, 0x17, 0x4f, 0xf1,
+	0x54, 0x40, 0x61, 0xfa, 0x46, 0x6c, 0x6d, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0x5f, 0xf2, 0x5a, 0x62, 0xbc, 0x77, 0xc1, 0xea, 0xbb, 0x38, 0xc2,
+	0x7e, 0x63, 0xac, 0x59, 0xc9, 0xd1, 0x37, 0xea, 0xeb, 0x09, 0x77, 0xa1,
+	0x6b, 0x49, 0x7e, 0x17, 0xc3, 0xab, 0x03, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xce, 0x14, 0xe5, 0x45, 0x4b, 0x16, 0x3e, 0x4a, 0xec, 0x3d, 0x52, 0x21,
+	0x35, 0xff, 0xe5, 0x33, 0x06, 0x46, 0x11, 0x32, 0x96, 0xc0, 0x34, 0x06,
+	0x04, 0x31, 0x37, 0x31, 0x25, 0xde, 0xde, 0xd8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x11, 0xbe, 0x6b, 0x47, 0xcd, 0x4a, 0xfd, 0xc3, 0x0d, 0x90, 0x1c, 0xc0,
+	0xd4, 0x70, 0x96, 0x72, 0xec, 0x42, 0xd6, 0x1d, 0x25, 0x5a, 0x9c, 0xd2,
+	0x23, 0xd6, 0x8e, 0xaf, 0x95, 0x7e, 0xfb, 0xd3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xdf, 0x28, 0x49, 0xeb, 0xa9, 0x5a, 0x0b, 0xf6, 0xf0, 0x9f, 0x4a,
+	0x47, 0x70, 0xf3, 0x49, 0x5f, 0x6f, 0xac, 0x86, 0x40, 0xfb, 0x0d, 0xf7,
+	0x72, 0xab, 0x23, 0x3d, 0x91, 0x08, 0x8c, 0x32, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0xb9, 0xe2, 0xb7, 0x4e, 0x62, 0xde, 0xcc, 0xd7, 0x68, 0xbd, 0x60,
+	0x83, 0x7d, 0x9c, 0x61, 0xfd, 0xd8, 0x5e, 0xb7, 0x64, 0x9b, 0xce, 0xa5,
+	0x23, 0x81, 0x2c, 0xcd, 0x9b, 0x5a, 0xaa, 0xd6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1d, 0x4a, 0x45, 0xf9, 0x1b, 0x9f, 0xa9, 0xfd, 0x38, 0x86, 0x31, 0x53,
+	0x9a, 0x2f, 0xb5, 0x5d, 0x2d, 0xed, 0x31, 0x75, 0x30, 0xd6, 0xbb, 0xdd,
+	0x53, 0x9b, 0x5f, 0xe0, 0xab, 0xd7, 0xaf, 0xe0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xee, 0xb3, 0x3b, 0xf0, 0x8a, 0x11, 0xd5, 0x5e, 0x37, 0xfd, 0x5a, 0x03,
+	0xaf, 0xaf, 0x0c, 0x99, 0xcc, 0x62, 0x92, 0x12, 0x30, 0x52, 0xac, 0x72,
+	0x7f, 0x51, 0x65, 0x44, 0x19, 0xf9, 0xe4, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x95, 0x4b, 0x50, 0xb3, 0x76, 0xa6, 0xa4, 0xb1, 0x9a, 0x39, 0x1e,
+	0x0d, 0x64, 0xfe, 0xc0, 0xf4, 0x43, 0xef, 0x85, 0x0a, 0xc2, 0xe3, 0xb0,
+	0x58, 0xc3, 0xf0, 0xf8, 0xdb, 0x67, 0xfc, 0x36, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xba, 0x4f, 0xbc, 0x66, 0x32, 0xd4, 0x4e, 0xec, 0x3f, 0x92, 0xfb, 0x0e,
+	0x92, 0x9b, 0x52, 0xe8, 0x27, 0xd9, 0xbb, 0xaa, 0x9c, 0x54, 0x70, 0x82,
+	0x4f, 0xad, 0xca, 0xbc, 0x9e, 0x01, 0x7e, 0x1c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5e, 0xe3, 0x0c, 0xca, 0xa3, 0xaa, 0xd6, 0x3f, 0x90, 0xcc, 0xef, 0xcd,
+	0x74, 0x59, 0xb3, 0xc5, 0xba, 0x35, 0xa8, 0x7e, 0x7e, 0xec, 0x4b, 0x6b,
+	0x00, 0x21, 0xfb, 0xa1, 0x6e, 0x53, 0xc4, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9d, 0xd3, 0xb3, 0xeb, 0xcf, 0xa0, 0x6d, 0xb1, 0x88, 0xab, 0x33, 0xc4,
+	0x0f, 0xd7, 0xb0, 0x76, 0x02, 0x8e, 0x71, 0x61, 0x18, 0x63, 0x07, 0xdc,
+	0x3e, 0x0d, 0xb9, 0xa8, 0x32, 0x75, 0x7a, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0xab, 0xf5, 0x7e, 0x0b, 0x4c, 0x08, 0x30, 0x08, 0x80, 0xc1, 0x9b,
+	0x69, 0x6a, 0x0e, 0xfc, 0x16, 0x81, 0xf1, 0xa9, 0xd4, 0x85, 0x35, 0x94,
+	0x26, 0xc5, 0x23, 0xb4, 0xa8, 0xb1, 0x8a, 0xb8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc5, 0x6d, 0x50, 0x49, 0x27, 0x8d, 0x35, 0x47, 0x0d, 0x73, 0x18, 0xae,
+	0xaf, 0x38, 0xef, 0xfa, 0xdd, 0x70, 0x48, 0x15, 0x39, 0xf0, 0x1c, 0x6e,
+	0x79, 0xd1, 0x13, 0x9f, 0xe4, 0xb3, 0xb2, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x39, 0xeb, 0xfb, 0x14, 0x3f, 0xf0, 0xa0, 0x0b, 0x5e, 0x41, 0x20, 0x0c,
+	0xfe, 0x36, 0x0c, 0x7f, 0xf0, 0xaf, 0xaa, 0xdd, 0x61, 0x66, 0x65, 0x30,
+	0x6b, 0x10, 0x18, 0x28, 0x30, 0xb6, 0x47, 0x3e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf7, 0xa8, 0x12, 0x06, 0x64, 0xfa, 0x90, 0xfa, 0x0c, 0xfb, 0x26, 0xf2,
+	0x2a, 0x1a, 0xc4, 0xf9, 0xae, 0x5c, 0x1b, 0x24, 0xf3, 0xf2, 0x87, 0xa2,
+	0x5c, 0x0a, 0x2a, 0x2b, 0x17, 0xa7, 0x2b, 0x7e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0x6d, 0x30, 0x7d, 0xb2, 0xd1, 0x40, 0xb7, 0x4f, 0x05, 0xac, 0x1a,
+	0xa1, 0x66, 0xa6, 0x19, 0x18, 0xf8, 0xcd, 0xf3, 0x3c, 0xf6, 0x84, 0xc3,
+	0x4d, 0x46, 0x49, 0xf1, 0xf7, 0x28, 0xa6, 0x0c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xf2, 0x0b, 0x90, 0x0d, 0xeb, 0x5c, 0x0b, 0x70, 0x2f, 0x54, 0x26,
+	0x1a, 0x7d, 0x6e, 0x72, 0x67, 0x95, 0x28, 0x03, 0x01, 0x37, 0xfa, 0xc6,
+	0x00, 0x45, 0xa7, 0xda, 0x5b, 0xbf, 0xf0, 0x24, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa9, 0x6c, 0x1d, 0x2b, 0x7e, 0xea, 0x35, 0x8b, 0x92, 0x12, 0x42, 0xf9,
+	0x8f, 0x67, 0x38, 0xf5, 0xf7, 0x1a, 0xe2, 0x8f, 0xb4, 0x40, 0x45, 0x2a,
+	0x47, 0xca, 0x9d, 0xbf, 0xbd, 0x85, 0xc0, 0xd2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+const uint8_t ae_fpm_tbl_ed448[AE_FPM_ED448_LEN] = {
+	0x26, 0x26, 0xa8, 0x2b, 0xc7, 0x0c, 0xc0, 0x5e, 0x43, 0x3b, 0x80, 0xe1,
+	0x8b, 0x00, 0x93, 0x8e, 0x12, 0xae, 0x1a, 0xf7, 0x2a, 0xb6, 0x65, 0x11,
+	0xea, 0x6d, 0xe3, 0x24, 0xa3, 0xd3, 0xa4, 0x64, 0x9e, 0x14, 0x65, 0x70,
+	0x47, 0x0f, 0x17, 0x67, 0x22, 0x1d, 0x15, 0xa6, 0x22, 0xbf, 0x36, 0xda,
+	0x4f, 0x19, 0x70, 0xc6, 0x6b, 0xed, 0x0d, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x98, 0x08, 0x79, 0x5b, 0xf2, 0x30, 0xfa, 0x14,
+	0xfd, 0xbd, 0x13, 0x2c, 0x4e, 0xd7, 0xc8, 0xad, 0x3a, 0xd3, 0xff, 0x1c,
+	0xe6, 0x7c, 0x39, 0xc4, 0x87, 0x78, 0x9c, 0x1e, 0x05, 0xa0, 0xc2, 0xd7,
+	0x4b, 0xea, 0x73, 0x73, 0x6c, 0xa3, 0x98, 0x40, 0x88, 0x76, 0x20, 0x37,
+	0x56, 0xc9, 0xc7, 0x62, 0x69, 0x3f, 0x46, 0x71, 0x6e, 0xb6, 0xbc, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xeb, 0x06, 0x62, 0x4e, 0x82, 0xaf, 0x95, 0xf3, 0xf7, 0x8f, 0xa0, 0x7d,
+	0x85, 0x66, 0x2d, 0x1d, 0xf1, 0x79, 0xde, 0x90, 0xb5, 0xb2, 0x7d, 0xa1,
+	0x60, 0xd7, 0x16, 0x67, 0xe2, 0x35, 0x6d, 0x58, 0xc5, 0x05, 0x6a, 0x18,
+	0x3f, 0x84, 0x51, 0xd2, 0xce, 0xc3, 0x9d, 0x2d, 0x50, 0x8d, 0x91, 0xc9,
+	0xc7, 0x5e, 0xb5, 0x8a, 0xee, 0x22, 0x1c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x12, 0x77, 0x1a, 0x0d, 0x31, 0xc0, 0x77, 0xbf,
+	0xc4, 0x24, 0x04, 0xed, 0x68, 0x36, 0xd7, 0x42, 0x6a, 0x65, 0x11, 0x30,
+	0x9d, 0xd9, 0x3a, 0x78, 0x3d, 0x16, 0x5b, 0x3f, 0x5b, 0x32, 0xdd, 0x27,
+	0x70, 0xf9, 0x81, 0x8f, 0x1b, 0xc6, 0x4d, 0xd1, 0x36, 0xf5, 0xf8, 0x56,
+	0x3e, 0x48, 0x3a, 0xc1, 0x28, 0x41, 0x27, 0x74, 0x35, 0xd1, 0x4b, 0x0f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x69, 0x81, 0x50,
+	0x38, 0xfb, 0x26, 0xe1, 0x68, 0x82, 0xe5, 0x52, 0x90, 0x23, 0xc2, 0x5e,
+	0xb3, 0x5e, 0x42, 0x06, 0x65, 0xea, 0x9f, 0x0c, 0x94, 0x4c, 0x92, 0x1f,
+	0x2d, 0x18, 0x4c, 0x04, 0xbe, 0x79, 0xf0, 0x74, 0x2d, 0x5a, 0x0b, 0x29,
+	0xa7, 0x46, 0xb8, 0x80, 0xdf, 0x83, 0x8f, 0x06, 0xe6, 0xe0, 0x8f, 0x72,
+	0x53, 0xfa, 0x6d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb4, 0x85, 0xa6, 0xed, 0xe6, 0xa8, 0x12, 0xd5, 0x7d, 0x97, 0xf7, 0xc8,
+	0xac, 0x2c, 0x4d, 0x2b, 0xfc, 0x53, 0x3e, 0xd0, 0x9f, 0x45, 0xd1, 0x52,
+	0xac, 0x85, 0x4f, 0xf8, 0x36, 0x7c, 0xcd, 0xa6, 0x6c, 0xb8, 0x0f, 0x8f,
+	0xdc, 0xde, 0x54, 0xc3, 0x23, 0x7b, 0xcc, 0xd9, 0xfe, 0x97, 0x19, 0x86,
+	0xa6, 0x17, 0xcd, 0x9b, 0xfe, 0x08, 0xf6, 0x3f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5c, 0xeb, 0x54, 0x97, 0x02, 0x55, 0xed, 0x8f,
+	0xfe, 0x3f, 0xe6, 0x24, 0x26, 0x1e, 0x3a, 0xc8, 0xdf, 0x28, 0xfc, 0xf9,
+	0xb9, 0x1b, 0x9c, 0xc8, 0x1b, 0x5f, 0xb0, 0x08, 0x2b, 0x19, 0x1e, 0x92,
+	0x29, 0xd9, 0x49, 0xa8, 0xb4, 0x61, 0xcc, 0xf3, 0x18, 0x35, 0x0a, 0x40,
+	0x2a, 0xe3, 0x2c, 0x09, 0x21, 0x81, 0x22, 0x38, 0xaf, 0xc2, 0xf4, 0x20,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x2d, 0x7c, 0xe2,
+	0x41, 0xc3, 0x10, 0x65, 0x01, 0x4a, 0x4f, 0xd5, 0x07, 0x2b, 0xa5, 0xd6,
+	0x7c, 0xc0, 0x57, 0x50, 0xc3, 0xf5, 0x63, 0xa0, 0x03, 0x8b, 0x79, 0xa9,
+	0xb1, 0xdd, 0xc4, 0x2f, 0xbe, 0xfa, 0x48, 0x92, 0xca, 0x8e, 0xd7, 0x0d,
+	0xdf, 0xcf, 0x2d, 0x40, 0xa3, 0xbc, 0x7e, 0xe7, 0x2e, 0xbe, 0xe9, 0x21,
+	0x83, 0xc8, 0x79, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xac, 0xdf, 0x2c, 0x05, 0x92, 0x8e, 0xe1, 0x3b, 0xc0, 0x57, 0xd9, 0xb4,
+	0x16, 0x0c, 0x80, 0x17, 0x03, 0x5a, 0x29, 0x4d, 0xef, 0x36, 0x9b, 0x11,
+	0x3b, 0xe2, 0xef, 0xca, 0x7f, 0xdd, 0xd3, 0xa3, 0xd7, 0x7f, 0x2b, 0x64,
+	0xa9, 0x7f, 0x62, 0x72, 0x71, 0x7d, 0x9e, 0x9f, 0xde, 0x2b, 0xcb, 0xd4,
+	0x3e, 0x95, 0x6f, 0x9d, 0x0c, 0x1f, 0x1a, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x92, 0xef, 0x93, 0x8e, 0xe7, 0x0a, 0x10,
+	0x7b, 0xc3, 0xdc, 0x46, 0xd9, 0x96, 0x27, 0x92, 0x91, 0xa4, 0x98, 0x89,
+	0x2d, 0xf2, 0x17, 0x03, 0x8c, 0xdb, 0x98, 0xed, 0xda, 0xb3, 0x15, 0xd5,
+	0xba, 0x58, 0x01, 0x38, 0x6e, 0x54, 0xd7, 0x46, 0x9c, 0x2b, 0x94, 0x5b,
+	0x60, 0x9e, 0x5b, 0x3b, 0xc3, 0x4c, 0x7e, 0xc3, 0xbc, 0x4d, 0xa9, 0xdd,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xd6, 0x93, 0x46,
+	0x63, 0x4b, 0xb6, 0x15, 0x73, 0x5f, 0xe8, 0x44, 0x1f, 0x89, 0x7c, 0xfe,
+	0x83, 0x79, 0xcb, 0x73, 0x83, 0x58, 0xce, 0x9c, 0x87, 0xad, 0x17, 0xe5,
+	0xfa, 0xdd, 0x04, 0x86, 0x55, 0x71, 0xf7, 0xb8, 0x6b, 0xcd, 0x5d, 0xfc,
+	0x9c, 0x49, 0xe6, 0x3f, 0x3e, 0x87, 0x3b, 0x37, 0x65, 0x32, 0x11, 0x5c,
+	0x6e, 0x65, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x3f, 0x74, 0xbc, 0x23, 0x5e, 0x87, 0xc7, 0x6f, 0xe1, 0x4d, 0x31,
+	0x75, 0x2a, 0x1e, 0xa9, 0x8e, 0xa2, 0x11, 0x3d, 0xfb, 0x62, 0xb8, 0x22,
+	0xdb, 0x4d, 0xb6, 0x29, 0x78, 0x4b, 0xc7, 0xa8, 0xba, 0x9b, 0xd8, 0x39,
+	0x03, 0xb6, 0x66, 0x26, 0xd2, 0xce, 0x26, 0x5d, 0x68, 0x1d, 0xca, 0x51,
+	0x14, 0x75, 0x66, 0xbd, 0xc2, 0xd0, 0xbc, 0xdb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x99, 0x33, 0x2c, 0x81, 0xaa, 0xcd, 0x8e, 0x4a,
+	0x04, 0xdf, 0xf4, 0x24, 0x98, 0x6b, 0x6e, 0x0f, 0xb1, 0xc0, 0x97, 0x61,
+	0x12, 0xbb, 0xa6, 0xd2, 0x67, 0x28, 0x33, 0xbb, 0xe7, 0x56, 0x5f, 0xc1,
+	0xa1, 0x23, 0xad, 0x1f, 0x3c, 0x75, 0x9c, 0x20, 0x92, 0x72, 0xe4, 0xfb,
+	0x60, 0x6c, 0xac, 0x5c, 0x25, 0x89, 0xe9, 0x2c, 0xb0, 0x29, 0x52, 0x1d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x78, 0xf8, 0x9f,
+	0x6b, 0x68, 0x93, 0x3b, 0xd8, 0x27, 0xa4, 0xb3, 0x34, 0x37, 0x63, 0x7b,
+	0x60, 0x22, 0x8b, 0xab, 0x06, 0x92, 0xed, 0x9e, 0x4d, 0xc7, 0x5b, 0xf1,
+	0x23, 0x65, 0x05, 0xc4, 0x6d, 0x7d, 0x04, 0x67, 0xc0, 0x27, 0x29, 0x05,
+	0x23, 0x7f, 0xf8, 0x30, 0xfe, 0x6e, 0xf3, 0x0b, 0x3a, 0x85, 0x47, 0x45,
+	0xa5, 0x1c, 0x9a, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x30, 0x7d, 0x8f, 0x0d, 0xcb, 0xce, 0x3a, 0x48, 0xd3, 0x2f, 0x09, 0xf8,
+	0xdd, 0x49, 0x49, 0x3d, 0x9f, 0x65, 0xb4, 0x4d, 0xcd, 0xa6, 0x93, 0xb2,
+	0x72, 0xe2, 0x98, 0x6e, 0xa7, 0xae, 0x0a, 0x9d, 0xcb, 0xb0, 0xc9, 0x75,
+	0x3b, 0x41, 0x79, 0x71, 0x63, 0xce, 0x55, 0x70, 0xde, 0x2a, 0x0f, 0x07,
+	0x30, 0xe5, 0x7e, 0xb9, 0xf3, 0xdf, 0x50, 0x39, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xce, 0x5b, 0xd0, 0x27, 0x82, 0x18, 0x8e, 0x41,
+	0x4b, 0x43, 0x8a, 0x62, 0x3e, 0x21, 0xce, 0x31, 0x28, 0xe2, 0xc5, 0x53,
+	0xbd, 0x97, 0xec, 0xa0, 0xc8, 0x85, 0xa4, 0x7a, 0x1e, 0xdb, 0x22, 0xc1,
+	0xbc, 0xc8, 0xa3, 0x74, 0xda, 0xd2, 0xd7, 0xa8, 0x96, 0x9e, 0x51, 0xfd,
+	0xa5, 0x74, 0x8f, 0xab, 0x55, 0x4b, 0x95, 0xb6, 0xfc, 0x3d, 0x16, 0x7d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x70, 0x9e, 0xad,
+	0xfb, 0x64, 0xff, 0xc6, 0xe7, 0x78, 0x37, 0x89, 0x04, 0x9f, 0x01, 0x16,
+	0xa1, 0x68, 0x38, 0xf0, 0xf3, 0x01, 0x25, 0xfd, 0xfa, 0xa1, 0xd3, 0x7e,
+	0x6f, 0xb6, 0x33, 0xa7, 0x44, 0x62, 0x83, 0x19, 0xec, 0x5b, 0xfe, 0x17,
+	0xa1, 0x7d, 0xe4, 0xa2, 0x7d, 0x47, 0xa5, 0x1d, 0x1f, 0x31, 0x55, 0x2d,
+	0xe2, 0x3c, 0x9a, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5f, 0xfd, 0xfd, 0x31, 0xc2, 0x6d, 0x22, 0x75, 0x97, 0x37, 0x39, 0x32,
+	0x1a, 0x88, 0x65, 0x16, 0xe9, 0xb8, 0x94, 0x35, 0xd7, 0x1e, 0x32, 0x32,
+	0x29, 0xf8, 0xfd, 0xef, 0x97, 0x26, 0xe9, 0x87, 0x32, 0xf4, 0xc9, 0x2b,
+	0x94, 0x2c, 0x85, 0x28, 0x8e, 0xb5, 0x4c, 0xf8, 0xae, 0xbf, 0xdf, 0x1a,
+	0xe3, 0xff, 0xbf, 0x0d, 0x3a, 0x8f, 0x86, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xb2, 0x45, 0xf4, 0xc9, 0xee, 0x82, 0x26, 0x2e,
+	0xe6, 0xd0, 0x97, 0x07, 0xfb, 0x72, 0xd1, 0x73, 0x98, 0x46, 0x05, 0x88,
+	0x1c, 0xba, 0xa2, 0x06, 0xd0, 0xe5, 0x49, 0xde, 0x1c, 0x6b, 0xa3, 0xe5,
+	0x5b, 0xea, 0x44, 0x4b, 0xe1, 0x5f, 0xa2, 0x77, 0x46, 0xed, 0xe6, 0x8c,
+	0x33, 0x20, 0x8e, 0x54, 0x74, 0x2f, 0x80, 0x95, 0x11, 0x50, 0x6b, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x6f, 0x6f, 0xa4,
+	0xe3, 0x4b, 0x95, 0xa3, 0x98, 0x3f, 0x0a, 0xfa, 0xf3, 0x9d, 0x9b, 0x7d,
+	0x78, 0xf9, 0x3e, 0x56, 0xd2, 0xd9, 0xb4, 0x2e, 0xd8, 0x39, 0xfb, 0x35,
+	0xe3, 0x25, 0xc5, 0xba, 0xfc, 0x18, 0xab, 0x08, 0x2d, 0x38, 0xe9, 0x4e,
+	0x68, 0xd6, 0x98, 0xad, 0x58, 0xfa, 0xd1, 0xe0, 0x55, 0x8f, 0x21, 0x1a,
+	0x11, 0x7e, 0x13, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x33, 0x19, 0x04, 0x18, 0xcf, 0x4b, 0x06, 0xf1, 0x32, 0x0f, 0xb9, 0xcb,
+	0x13, 0x81, 0x9b, 0xaf, 0x4e, 0x55, 0xaa, 0x8b, 0xea, 0x88, 0x95, 0x66,
+	0x9b, 0xf7, 0xd3, 0x58, 0xb5, 0x4b, 0x2c, 0xee, 0x18, 0xca, 0x8a, 0x94,
+	0xc9, 0x82, 0x98, 0x5d, 0x3d, 0xbc, 0xb7, 0x3c, 0x73, 0xab, 0x6c, 0x76,
+	0x7c, 0x25, 0x62, 0xfc, 0x8a, 0xef, 0xd7, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x59, 0x2d, 0xbb, 0xa7, 0xf0, 0x49, 0x6f, 0xc2,
+	0x69, 0xb1, 0xc3, 0x94, 0xf3, 0x8e, 0xf4, 0xac, 0xe3, 0x2c, 0xd9, 0x94,
+	0xfd, 0x15, 0x46, 0x54, 0x49, 0x19, 0xbc, 0x27, 0xb4, 0x8b, 0x85, 0xf5,
+	0x54, 0x81, 0x10, 0x03, 0x99, 0x13, 0x58, 0x6d, 0x0a, 0x2f, 0x6d, 0xbc,
+	0x76, 0x34, 0xd1, 0x12, 0xfe, 0xa6, 0x75, 0xf0, 0x54, 0x39, 0xb4, 0x33,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x52, 0x64, 0x73,
+	0x17, 0xb4, 0xc4, 0xcc, 0x4b, 0x72, 0xf2, 0x4d, 0xf6, 0x31, 0xb3, 0xf8,
+	0x25, 0x64, 0xdb, 0x94, 0xa7, 0x83, 0x86, 0x66, 0xad, 0xc1, 0x9f, 0x9e,
+	0xa7, 0xc9, 0x87, 0x84, 0x9c, 0x80, 0x82, 0x94, 0x36, 0xcd, 0x2a, 0xba,
+	0x04, 0x9f, 0x25, 0x9c, 0x56, 0x1a, 0x3e, 0x09, 0x07, 0xf4, 0x27, 0xae,
+	0xf2, 0x21, 0x0a, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd5, 0xe9, 0x2b, 0xb0, 0x25, 0x50, 0x73, 0x45, 0x24, 0xb4, 0xfe, 0x97,
+	0x6c, 0xaf, 0xb8, 0x72, 0xbf, 0xe2, 0xcf, 0x5d, 0xe8, 0x66, 0x84, 0x74,
+	0xd6, 0xff, 0x14, 0xc9, 0x07, 0x63, 0x58, 0x2e, 0xd2, 0x81, 0x83, 0xc9,
+	0x05, 0x9d, 0x5c, 0x9e, 0x62, 0xd2, 0x90, 0x3a, 0x6c, 0x16, 0x66, 0x7c,
+	0x2d, 0xe1, 0x2b, 0x55, 0x51, 0x2b, 0x25, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xea, 0x86, 0x65, 0xcb, 0x55, 0x08, 0x23, 0x8b,
+	0x3e, 0xd3, 0xa7, 0x88, 0x0f, 0xb1, 0xd3, 0x7f, 0xe7, 0xb8, 0x61, 0xfa,
+	0x58, 0x96, 0x51, 0x4c, 0xea, 0x4d, 0x95, 0xcd, 0x1a, 0x3e, 0x3c, 0x95,
+	0xd3, 0x07, 0xc9, 0x00, 0x66, 0x68, 0x8d, 0x25, 0x9e, 0x1c, 0x82, 0xae,
+	0x5e, 0x48, 0xea, 0xf3, 0x01, 0x27, 0x7b, 0xf2, 0xb2, 0x9b, 0x16, 0xef,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1c, 0x38, 0xc3,
+	0x1f, 0x7b, 0x41, 0x2d, 0x5d, 0xdf, 0xd9, 0xea, 0xbf, 0xad, 0x45, 0xa2,
+	0x25, 0x0b, 0xb6, 0xa3, 0xef, 0xa5, 0xdc, 0xc5, 0xe0, 0xb8, 0x4a, 0xb3,
+	0xfa, 0xb5, 0x36, 0x35, 0x77, 0xdc, 0xf4, 0xa6, 0x88, 0x53, 0xe1, 0xa3,
+	0x1e, 0xf6, 0xa6, 0x8e, 0x7a, 0xc5, 0x0b, 0xc2, 0x16, 0x3e, 0xe2, 0x27,
+	0x0f, 0x9b, 0xc4, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x81, 0x54, 0x75, 0x7f, 0xdb, 0x06, 0xbd, 0xa2, 0x4a, 0x5b, 0xa0, 0x85,
+	0xf8, 0xc5, 0x12, 0x5b, 0xbb, 0x4b, 0xa1, 0x58, 0xa5, 0xd6, 0x1d, 0x98,
+	0x04, 0x21, 0x7a, 0x30, 0x31, 0x00, 0x2c, 0x99, 0x90, 0xcf, 0x80, 0xfe,
+	0xd1, 0x6b, 0x27, 0x93, 0xef, 0x89, 0x06, 0x1b, 0x95, 0x21, 0x8b, 0xbe,
+	0x0b, 0x8d, 0x1b, 0xa0, 0x23, 0x87, 0xf0, 0xe1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x76, 0x74, 0xb2, 0xb2, 0x25, 0x00, 0x07, 0xf9,
+	0x01, 0x30, 0x2b, 0xb8, 0xf2, 0x4e, 0xb2, 0x26, 0x04, 0x11, 0x3c, 0x79,
+	0xeb, 0x4a, 0xdf, 0x53, 0x55, 0xe6, 0x6e, 0x59, 0x60, 0xcd, 0xf2, 0xa4,
+	0xd7, 0xc3, 0x0d, 0x70, 0x9d, 0x6c, 0x64, 0x2a, 0xdd, 0x9d, 0x4d, 0x83,
+	0x95, 0x94, 0xd2, 0x38, 0xd1, 0xcd, 0x6e, 0xdb, 0x33, 0x32, 0x62, 0xd4,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x62, 0x25, 0x5e,
+	0xe0, 0x13, 0x80, 0x39, 0x31, 0x0e, 0x59, 0x15, 0x9c, 0xe8, 0x75, 0xbc,
+	0x60, 0x90, 0x34, 0x3a, 0x5f, 0x7d, 0x7c, 0x0b, 0x6c, 0x3d, 0x02, 0xfd,
+	0xfa, 0xb1, 0xf7, 0xce, 0x1b, 0xec, 0x37, 0x06, 0xaf, 0xc1, 0x9f, 0x93,
+	0x6f, 0x2d, 0x40, 0x9f, 0x22, 0x52, 0xb6, 0x73, 0x8f, 0x91, 0xe1, 0x85,
+	0xfe, 0x57, 0xa6, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x42, 0xde, 0xbe, 0xf5, 0xb7, 0xca, 0x60, 0x2e, 0x10, 0x88, 0xb7, 0xfc,
+	0xbe, 0x7f, 0x06, 0x8a, 0x7d, 0xcd, 0xb1, 0xde, 0x34, 0x43, 0x19, 0x70,
+	0xab, 0xa7, 0x62, 0x0e, 0x37, 0xee, 0x28, 0x2b, 0xd7, 0x5e, 0x4c, 0x5b,
+	0x30, 0x99, 0xc3, 0x3c, 0x47, 0xfb, 0x4d, 0x92, 0xb2, 0x6c, 0xa4, 0xd9,
+	0x9d, 0xe5, 0x74, 0xe2, 0xb2, 0xec, 0x6c, 0xc9, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x60, 0x24, 0xe8, 0xa8, 0xae, 0x35, 0x55, 0x83,
+	0x99, 0xe9, 0x6e, 0xdd, 0xdb, 0x48, 0x26, 0xee, 0x7a, 0x82, 0xdc, 0xa9,
+	0xb5, 0xda, 0xf3, 0xda, 0x21, 0x36, 0x87, 0xc0, 0xc9, 0xa0, 0x0c, 0xb1,
+	0xad, 0xc8, 0x5f, 0x1e, 0x68, 0x40, 0xd9, 0x2c, 0xdb, 0x15, 0x29, 0xfd,
+	0x8f, 0x80, 0xde, 0x8b, 0xad, 0xfa, 0xd4, 0x59, 0x20, 0x94, 0x40, 0x5f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x44, 0x63, 0x52,
+	0x42, 0xef, 0x04, 0x95, 0x0b, 0xbc, 0x2e, 0xc5, 0x6d, 0x67, 0x5a, 0x26,
+	0x24, 0x8e, 0x97, 0x4c, 0x1c, 0x52, 0x85, 0xe2, 0x65, 0x2e, 0xdf, 0xc0,
+	0xe1, 0x38, 0xb2, 0x2d, 0x90, 0xd7, 0x28, 0x31, 0x88, 0xbd, 0xbd, 0x45,
+	0x1e, 0x07, 0x53, 0x0c, 0x31, 0xe3, 0x60, 0x60, 0x96, 0xdd, 0x3f, 0x14,
+	0x3d, 0xb0, 0x03, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x7b, 0x41, 0x1e, 0xcf, 0xd4, 0xa0, 0xf3, 0x55, 0xa5, 0x02, 0x3e,
+	0x43, 0xf3, 0xfe, 0x6c, 0xf5, 0x39, 0x77, 0xfe, 0x5a, 0x9d, 0xa3, 0x43,
+	0xab, 0xa4, 0x11, 0xb7, 0x3c, 0xba, 0x8e, 0xf2, 0x96, 0x22, 0x30, 0x7e,
+	0x3a, 0x89, 0xf4, 0x37, 0xc8, 0x16, 0x4a, 0xcd, 0x29, 0x3f, 0xd0, 0x6c,
+	0x96, 0x68, 0x9d, 0xac, 0x7e, 0x04, 0xee, 0xb3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x50, 0x29, 0x41, 0xcb, 0x86, 0xe0, 0xe6, 0x50,
+	0x09, 0x74, 0xf3, 0xf4, 0x79, 0x40, 0x23, 0xd8, 0xd0, 0xd8, 0xe1, 0xc2,
+	0xe4, 0xe7, 0x87, 0xbf, 0x87, 0x98, 0xff, 0x1e, 0xa1, 0x18, 0xa9, 0x11,
+	0xdd, 0x0d, 0x89, 0xdb, 0x97, 0xb2, 0xd4, 0x93, 0x13, 0x32, 0xd9, 0x48,
+	0x46, 0x4e, 0xe4, 0x7f, 0x1c, 0x3b, 0x6f, 0x60, 0xd0, 0x75, 0x88, 0x6f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xdd, 0xf3, 0xdb,
+	0xc6, 0xc8, 0xca, 0x07, 0x40, 0xe9, 0x72, 0xa3, 0x87, 0xac, 0x4e, 0x08,
+	0xa0, 0x1d, 0xd8, 0xdc, 0x23, 0xf4, 0xe1, 0xcb, 0xca, 0x2a, 0xcd, 0xbb,
+	0x23, 0xf2, 0x52, 0x92, 0x5c, 0x29, 0x62, 0x39, 0x51, 0x66, 0x09, 0x3f,
+	0x96, 0x5c, 0x2e, 0xc7, 0x50, 0xa6, 0x56, 0x07, 0x66, 0x3f, 0x2b, 0x27,
+	0x02, 0x5d, 0x43, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x16, 0x87, 0x89, 0x08, 0x15, 0xbf, 0xb4, 0xbb, 0x04, 0xb9, 0xdf, 0x77,
+	0x4e, 0x6f, 0xde, 0x97, 0x61, 0x3c, 0x6a, 0xa5, 0xef, 0x5b, 0x4e, 0x15,
+	0x26, 0xe9, 0xbc, 0x92, 0xd9, 0xd3, 0xe3, 0xbd, 0x41, 0x3f, 0xb0, 0xe3,
+	0xc6, 0xfc, 0x75, 0xef, 0xb8, 0xb1, 0x31, 0x88, 0x1e, 0x95, 0x6a, 0xa1,
+	0x54, 0x0d, 0x4f, 0xfd, 0xb3, 0xa8, 0xe8, 0x9e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc5, 0xa6, 0xa2, 0xaa, 0x79, 0x6b,
+	0xdc, 0xc8, 0x5b, 0xe6, 0xda, 0xff, 0x69, 0x22, 0x19, 0x5f, 0x5e, 0x32,
+	0x31, 0xc4, 0x83, 0x30, 0xf6, 0xa6, 0xe3, 0x3d, 0xd4, 0xc8, 0xda, 0x4c,
+	0x33, 0xef, 0x38, 0x64, 0x4a, 0x92, 0x8e, 0x83, 0x04, 0xbc, 0x79, 0x12,
+	0x5d, 0x32, 0x59, 0x71, 0xa9, 0xc8, 0x7e, 0x55, 0xc7, 0x5f, 0x98, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x56, 0x48, 0xfa,
+	0x0b, 0x31, 0x1e, 0xdf, 0xfb, 0x40, 0x81, 0xce, 0x2a, 0xf1, 0xf0, 0x85,
+	0x74, 0x0b, 0xd8, 0x5a, 0x63, 0xf0, 0xad, 0x4b, 0xc2, 0x30, 0xf5, 0x1f,
+	0xdb, 0xad, 0x34, 0xb0, 0xe5, 0xac, 0x0f, 0x59, 0xcd, 0x7f, 0x59, 0xcb,
+	0xac, 0xda, 0x7d, 0x3e, 0x2b, 0x77, 0x7c, 0x45, 0x88, 0x66, 0xe4, 0x87,
+	0x77, 0xba, 0x6e, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x38, 0x0e, 0xcd, 0x3e, 0x5c, 0x70, 0xdb, 0xb4, 0xf2, 0x59, 0x37, 0x36,
+	0xc6, 0xf6, 0x78, 0xa8, 0xfa, 0x67, 0xad, 0xad, 0x96, 0x50, 0xf4, 0xe1,
+	0x3c, 0x65, 0xd0, 0x01, 0x59, 0x08, 0x86, 0x96, 0x67, 0x9f, 0x1f, 0x27,
+	0xd4, 0xa5, 0x9d, 0xd7, 0xf2, 0x57, 0xc2, 0x81, 0x3b, 0x1d, 0xe7, 0xaa,
+	0x10, 0xfb, 0x10, 0xa0, 0xe1, 0x25, 0x5a, 0x55, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa9, 0xd1, 0x51, 0x65, 0x95, 0xdd, 0x6f, 0x89,
+	0xad, 0xcc, 0x2a, 0x76, 0xc3, 0x98, 0x26, 0x37, 0x51, 0x07, 0x98, 0x8f,
+	0x85, 0xad, 0x55, 0x38, 0x5e, 0x15, 0x4f, 0x1c, 0xe6, 0x0b, 0xe5, 0x28,
+	0x9c, 0xac, 0xc2, 0x5a, 0x73, 0x23, 0x14, 0x01, 0x71, 0x71, 0x04, 0x47,
+	0xb4, 0xd2, 0x8a, 0x77, 0x2e, 0x22, 0x42, 0xfa, 0xf0, 0x82, 0x86, 0x70,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x1a, 0x11, 0x5a,
+	0x4a, 0xea, 0xae, 0x0a, 0x88, 0x53, 0x09, 0x1a, 0x75, 0xc4, 0x40, 0x1d,
+	0x74, 0x03, 0x44, 0xc8, 0xe3, 0xca, 0x1b, 0xab, 0xee, 0x22, 0xb3, 0xc1,
+	0xef, 0xe6, 0xb8, 0x16, 0x29, 0x07, 0xd8, 0x0b, 0x7e, 0x67, 0xcb, 0xea,
+	0xbd, 0x27, 0x8e, 0x0f, 0x28, 0xac, 0xe6, 0x6d, 0x47, 0x5d, 0x6f, 0x17,
+	0xa2, 0xf8, 0x5d, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x48, 0xea, 0x89, 0x16, 0x74, 0x70, 0x2c, 0x27, 0x93, 0x3a, 0xe7, 0x20,
+	0x03, 0xd8, 0x35, 0x5c, 0xae, 0xaa, 0x2e, 0xc8, 0x45, 0xf3, 0x13, 0xcf,
+	0x65, 0x8d, 0x10, 0x93, 0x53, 0xac, 0x9b, 0x68, 0xf9, 0x03, 0x46, 0x41,
+	0xf4, 0xc5, 0x9e, 0x04, 0x94, 0x79, 0x6e, 0x6f, 0x8c, 0xf5, 0x09, 0x0d,
+	0xfe, 0x92, 0x82, 0x98, 0x01, 0x68, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0x7c, 0x5d, 0xa1, 0x01, 0x26, 0xe6, 0x0a,
+	0x7d, 0x9c, 0xb0, 0xbf, 0x8b, 0xd0, 0x64, 0x3c, 0x38, 0x19, 0x81, 0x43,
+	0x4a, 0x57, 0xfd, 0x7a, 0x93, 0xc7, 0xc8, 0x0a, 0x2e, 0x56, 0x49, 0x07,
+	0x6e, 0x7d, 0x64, 0xed, 0x2b, 0x86, 0x53, 0x9f, 0x95, 0x74, 0xa7, 0x69,
+	0x3d, 0x96, 0x41, 0xb8, 0xca, 0x02, 0xfd, 0xf0, 0xa4, 0xc7, 0x18, 0x49,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x54, 0xe4, 0x81,
+	0xa7, 0xb6, 0x5e, 0x08, 0xe6, 0x8b, 0xc5, 0xb0, 0xad, 0x5a, 0xe3, 0x09,
+	0x31, 0xe5, 0x2b, 0x5d, 0xa1, 0x4f, 0xac, 0x93, 0x49, 0x22, 0xac, 0xfc,
+	0x61, 0x47, 0x51, 0xde, 0xae, 0x8a, 0xd9, 0x9f, 0xcb, 0x9f, 0xcf, 0x78,
+	0xa5, 0x13, 0xf5, 0xcf, 0xd3, 0xc1, 0x49, 0x5a, 0x7b, 0x8e, 0xf0, 0x5e,
+	0xad, 0x9d, 0x6e, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x94, 0x0a, 0x05, 0x03, 0x02, 0x48, 0xa0, 0x7a, 0xd0, 0x3e, 0x53, 0x73,
+	0x6a, 0x9c, 0xee, 0x03, 0x98, 0xe2, 0x60, 0x2a, 0x65, 0x78, 0xbd, 0x89,
+	0x8b, 0x00, 0x67, 0x61, 0x20, 0x81, 0x49, 0xbc, 0xc9, 0x3b, 0x4f, 0x19,
+	0x91, 0x54, 0xba, 0x9d, 0x7c, 0xe1, 0x80, 0xed, 0x74, 0x4f, 0x88, 0x04,
+	0xf5, 0x9b, 0x56, 0xd3, 0x3c, 0x9c, 0xfb, 0xc0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xac, 0x49, 0xa7, 0x7e, 0x71, 0xf8, 0xba, 0x16,
+	0xaa, 0xda, 0x08, 0x92, 0x96, 0xbc, 0xa5, 0x33, 0x3e, 0xbc, 0xff, 0x50,
+	0xe0, 0xba, 0x41, 0x43, 0xeb, 0x2c, 0x10, 0x58, 0x9f, 0x85, 0xa7, 0xd9,
+	0xb1, 0x2d, 0x3a, 0xb4, 0x62, 0x08, 0x91, 0x73, 0xaa, 0x42, 0x1e, 0x96,
+	0x63, 0xf3, 0x1b, 0xaf, 0xcf, 0x76, 0x7b, 0x41, 0x8b, 0x69, 0x26, 0x05,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xa3, 0x1f, 0xb3,
+	0x67, 0xef, 0x7b, 0xfb, 0x4b, 0xfc, 0x59, 0x9e, 0xe7, 0xab, 0xb6, 0x35,
+	0xa2, 0xf1, 0xdf, 0xd6, 0x1d, 0x9e, 0xbb, 0xfd, 0x91, 0x6a, 0x7f, 0x0c,
+	0xc6, 0x2c, 0x07, 0x69, 0x64, 0xd0, 0xda, 0xb3, 0xc6, 0xbf, 0x62, 0x1e,
+	0x4d, 0x48, 0xd5, 0xb4, 0xa4, 0x43, 0xff, 0x91, 0x87, 0xc6, 0x54, 0x10,
+	0xf9, 0xd6, 0xb3, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4f, 0x95, 0x17, 0xe1, 0xf7, 0x38, 0x63, 0x16, 0x3b, 0x02, 0x2f, 0x5a,
+	0x45, 0x64, 0xf1, 0x93, 0xa1, 0xf1, 0xe4, 0x29, 0x62, 0x7c, 0x0c, 0x50,
+	0x3b, 0x49, 0x55, 0x86, 0x9d, 0xc3, 0xe7, 0xf8, 0xc4, 0x65, 0x30, 0x58,
+	0xee, 0x3e, 0x1f, 0x9b, 0x6f, 0x2a, 0xea, 0x23, 0x27, 0x9a, 0x0e, 0xe7,
+	0x6b, 0x96, 0x4b, 0xcb, 0x21, 0xae, 0x1b, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa6, 0x88, 0x80, 0x5b, 0xfb, 0x9f, 0xee, 0x70,
+	0x2b, 0xd4, 0xb4, 0x7d, 0x2c, 0x05, 0x9a, 0xea, 0x0b, 0xa5, 0xeb, 0xc0,
+	0x9f, 0x6c, 0x66, 0x8c, 0xc5, 0x6a, 0x36, 0x87, 0x04, 0xd2, 0x1a, 0x83,
+	0xa5, 0xcf, 0x38, 0xd9, 0x74, 0x52, 0xd3, 0x9c, 0xeb, 0xa4, 0xf9, 0x26,
+	0xf3, 0xc0, 0xdc, 0x94, 0xc0, 0x7f, 0x54, 0x87, 0x62, 0x77, 0x2d, 0x4c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x16, 0x58, 0x49,
+	0xb1, 0x96, 0x15, 0x03, 0x33, 0x7e, 0x44, 0xc4, 0xd6, 0xa6, 0xcb, 0x61,
+	0x57, 0x2b, 0x93, 0x72, 0x8b, 0xad, 0x37, 0xbf, 0x80, 0x3d, 0x79, 0x52,
+	0x0c, 0x18, 0x30, 0x38, 0xc9, 0x69, 0xec, 0x11, 0x45, 0x14, 0x9e, 0xe5,
+	0x47, 0x4d, 0xbb, 0x1b, 0x2c, 0x91, 0x6d, 0x6e, 0x09, 0xf7, 0xbc, 0xc9,
+	0x25, 0x12, 0x98, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc1, 0x16, 0xd7, 0xe8, 0x42, 0x8e, 0xa5, 0x9a, 0xc4, 0x93, 0xc7, 0x86,
+	0x84, 0x45, 0x8e, 0x0f, 0x05, 0x20, 0xfa, 0x16, 0xad, 0xcc, 0x8a, 0x10,
+	0x99, 0x1b, 0x69, 0x56, 0x19, 0xb2, 0x99, 0xc3, 0x2f, 0x4a, 0xf8, 0x11,
+	0x87, 0x99, 0x26, 0x14, 0x81, 0x71, 0xc6, 0x77, 0x84, 0x6b, 0x8d, 0xe2,
+	0xc8, 0xf1, 0x9a, 0x5a, 0x66, 0x67, 0x7d, 0x52, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xbd, 0xd3, 0x7a, 0x37, 0x12, 0x9e, 0xc2, 0x18,
+	0x96, 0x1d, 0x51, 0x31, 0xd9, 0x28, 0xcd, 0x7d, 0xc3, 0x07, 0x9d, 0x98,
+	0xcf, 0x06, 0x82, 0x77, 0xa7, 0xbf, 0xb0, 0xae, 0x7d, 0x8a, 0xc3, 0x0d,
+	0x65, 0xe9, 0x66, 0x91, 0xb6, 0xff, 0x97, 0xb8, 0x67, 0xad, 0x51, 0xd0,
+	0xae, 0x5b, 0x70, 0x7a, 0x25, 0x6e, 0x41, 0x58, 0x62, 0xc3, 0xc8, 0xcb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xb1, 0x7f,
+	0xfd, 0x70, 0x84, 0xba, 0x1e, 0xcf, 0x48, 0x23, 0xcd, 0x84, 0xdf, 0x17,
+	0x06, 0x1e, 0x97, 0x93, 0xad, 0x67, 0x18, 0x97, 0xee, 0xc8, 0xd8, 0x6a,
+	0x20, 0x89, 0x5a, 0x9e, 0x54, 0x9c, 0xd7, 0x22, 0x4b, 0xde, 0x69, 0xfd,
+	0x6b, 0x28, 0xbb, 0x68, 0xfa, 0x05, 0x42, 0xe7, 0x79, 0x65, 0xe5, 0x6d,
+	0x16, 0x71, 0x76, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6c, 0x12, 0x82, 0xb8, 0x7e, 0x03, 0x01, 0x68, 0x5a, 0x51, 0x60, 0xf1,
+	0xe3, 0xd0, 0x45, 0x67, 0x2f, 0x47, 0x4d, 0xb4, 0x97, 0x5c, 0xbd, 0x13,
+	0x50, 0x89, 0xfe, 0x19, 0x4e, 0x4f, 0xad, 0x05, 0x17, 0x3a, 0x84, 0x33,
+	0xaa, 0x15, 0x75, 0xdb, 0x59, 0x34, 0x4c, 0x01, 0xa2, 0x54, 0xc3, 0x21,
+	0x4e, 0xbd, 0x2b, 0xf3, 0x23, 0x19, 0xef, 0xa0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfa, 0x3e, 0x81, 0xb5, 0xd9, 0xe3, 0x5e, 0x50,
+	0xa9, 0x76, 0xc7, 0x31, 0x06, 0x82, 0xf1, 0xc8, 0xc6, 0x6c, 0x9f, 0xa6,
+	0xad, 0x6b, 0x6d, 0x1b, 0x1d, 0x2f, 0xa1, 0x01, 0xd7, 0x72, 0x99, 0x08,
+	0xc1, 0x2f, 0x29, 0xe4, 0x63, 0xc0, 0x32, 0x66, 0x7f, 0x32, 0x55, 0xbd,
+	0x93, 0x0f, 0x10, 0xef, 0x83, 0x29, 0x35, 0x55, 0xba, 0xe0, 0x8c, 0x3f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x71, 0x81, 0x3f,
+	0x62, 0x01, 0xb6, 0x6d, 0xe0, 0x21, 0xac, 0x3a, 0x82, 0x88, 0x77, 0x61,
+	0x3c, 0xea, 0xa0, 0x07, 0x7d, 0x10, 0xd7, 0xaf, 0x17, 0xef, 0x0a, 0x4e,
+	0x44, 0xb4, 0x8b, 0x65, 0x3b, 0x58, 0xc6, 0xb0, 0xec, 0x88, 0x69, 0xb5,
+	0x7a, 0x03, 0xf1, 0xdc, 0x36, 0x05, 0x20, 0xfc, 0xcd, 0xe5, 0x6c, 0x3a,
+	0x19, 0xb3, 0x62, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5c, 0x7c, 0x07, 0xc6, 0xb7, 0x1f, 0x25, 0xdf, 0x7d, 0x8d, 0x81, 0x61,
+	0xeb, 0x3e, 0xbf, 0xe7, 0x10, 0x81, 0xf1, 0x85, 0x40, 0xcb, 0x60, 0xf1,
+	0xae, 0x1a, 0xba, 0xc5, 0xda, 0x60, 0x1c, 0x0f, 0x6d, 0x47, 0xfd, 0xa2,
+	0x56, 0x13, 0x67, 0x02, 0x7c, 0xd9, 0xc5, 0x56, 0x32, 0x69, 0x12, 0xc7,
+	0x8f, 0x2f, 0x31, 0x2c, 0x0f, 0xd2, 0x94, 0x69, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0x20, 0x93, 0x21, 0xb2, 0x35, 0xf1,
+	0x80, 0x14, 0x8e, 0xf1, 0x0c, 0x28, 0x62, 0x8d, 0xb8, 0xcf, 0x6c, 0x9e,
+	0xf6, 0xdb, 0x18, 0x16, 0x0b, 0xbd, 0xe9, 0xb4, 0xa3, 0x75, 0xee, 0xb2,
+	0x55, 0x1e, 0x4c, 0xc7, 0xa7, 0x74, 0xe8, 0x0e, 0x8f, 0xb7, 0xa8, 0x04,
+	0xf3, 0xeb, 0x1c, 0x35, 0xd6, 0x1d, 0x1b, 0x2a, 0x51, 0x10, 0xa2, 0x67,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x1c, 0x40, 0x29,
+	0xfa, 0x43, 0x18, 0x0c, 0x4c, 0xc0, 0xcd, 0x55, 0x99, 0xd0, 0xb9, 0xb4,
+	0x55, 0x69, 0x7d, 0xad, 0x99, 0xb8, 0xec, 0x62, 0x0c, 0x3b, 0x71, 0x11,
+	0xf0, 0xba, 0x59, 0x19, 0x93, 0xef, 0xcd, 0x2c, 0x29, 0x02, 0x8b, 0x76,
+	0x85, 0x21, 0xc1, 0xad, 0x72, 0x67, 0x87, 0xd1, 0x8f, 0xc6, 0x05, 0xe7,
+	0x82, 0x4e, 0x95, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
 const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p192,
@@ -1267,7 +1835,15 @@ const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p256_sm2,
 		.len = sizeof(ae_fpm_tbl_p256_sm2)
-	}
+	},
+	{
+		.data = ae_fpm_tbl_ed25519,
+		.len = sizeof(ae_fpm_tbl_ed25519)
+	},
+	{
+		.data = ae_fpm_tbl_ed448,
+		.len = sizeof(ae_fpm_tbl_ed448)
+	},
 };
 
 int
diff --git a/drivers/crypto/cnxk/cnxk_ae.h b/drivers/crypto/cnxk/cnxk_ae.h
index ef9cb5eb91..431d66c535 100644
--- a/drivers/crypto/cnxk/cnxk_ae.h
+++ b/drivers/crypto/cnxk/cnxk_ae.h
@@ -205,6 +205,12 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_EC_GROUP_SM2:
 		ec->curveid = ROC_AE_EC_ID_SM2;
 		break;
+	case RTE_CRYPTO_EC_GROUP_ED25519:
+		ec->curveid = ROC_AE_EC_ID_ED25519;
+		break;
+	case RTE_CRYPTO_EC_GROUP_ED448:
+		ec->curveid = ROC_AE_EC_ID_ED448;
+		break;
 	default:
 		/* Only NIST curves (FIPS 186-4) and SM2 are supported */
 		return -EINVAL;
@@ -225,6 +231,12 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	if (ec->q.x.length)
 		rte_memcpy(ec->q.x.data, xform->ec.q.x.data, ec->q.x.length);
 
+	/* Use q.x to store compressed public key. q.y is set to 0 */
+	if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_EDDSA) {
+		ec->q.y.length = 0;
+		return 0;
+	}
+
 	ec->q.y.length = xform->ec.q.y.length;
 	if (ec->q.y.length > ROC_AE_EC_DATA_MAX)
 		ec->q.y.length = ROC_AE_EC_DATA_MAX;
@@ -255,6 +267,7 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
 	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
 		ret = cnxk_ae_fill_ec_params(sess, xform);
 		break;
 	default:
@@ -736,6 +749,330 @@ cnxk_ae_enqueue_ecdsa_op(struct rte_crypto_op *op,
 	return 0;
 }
 
+static __rte_always_inline void
+cnxk_ae_eddsa_sign_prep(struct rte_crypto_eddsa_op_param *eddsa,
+			struct roc_ae_buf_ptr *meta_buf,
+			uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
+			struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t pkey_len = sess->ec_ctx.pkey.length;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint16_t ctx_align, k_align;
+	uint16_t prime_bit, iv_len;
+	uint8_t pub = 0, ph = 0;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint8_t ctx_len = 0;
+	uint64_t ctrl = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	if (pubkey_len)
+		pub = 1;
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pkey_len, 8);
+
+	/* Set control word */
+	ctrl |= message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	rte_memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(priv and
+	 * pubkey len), ROUNDUP8(context len) and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) +
+		sizeof(ctrl) + prime_len * 3 + k_align * 2 +
+		ctx_align + iv_len;
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.pkey.data, pkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_SIGN;
+
+	w4.s.param1 = prime_bit |
+					(pub << ROC_AE_ED_PARAM1_KEYGEN_BIT) |
+					(ph << ROC_AE_EC_PARAM1_PH_BIT);
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline void
+cnxk_ae_eddsa_verify_prep(struct rte_crypto_eddsa_op_param *eddsa,
+			  struct roc_ae_buf_ptr *meta_buf,
+			  uint64_t fpm_table_iova,
+			  struct roc_ae_ec_group *ec_grp, struct cnxk_ae_sess *sess,
+			  struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t s_len = eddsa->sign.length / 2;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	uint16_t ctx_align, k_align, s_align;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint16_t prime_bit, iv_len;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint8_t ctx_len = 0;
+	uint64_t ctrl = 0;
+	uint8_t ph = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pubkey_len, 8);
+	s_align = RTE_ALIGN_CEIL(s_len, 8);
+
+	/* Set control word */
+	ctrl |= message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	rte_memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(pub key len),
+	 * ROUNDUP8(s and r len), context and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) +
+		sizeof(ctrl) + prime_len * 3 + k_align + s_align * 2 +
+		ctx_align + iv_len;
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, eddsa->sign.data, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, eddsa->sign.data + s_len, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_VERIFY;
+
+	w4.s.param1 = prime_bit |
+					(ph << ROC_AE_EC_PARAM1_PH_BIT);
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline int __rte_hot
+cnxk_ae_enqueue_eddsa_op(struct rte_crypto_op *op,
+			 struct roc_ae_buf_ptr *meta_buf,
+			 struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
+			 struct roc_ae_ec_group **ec_grp,
+			 struct cpt_inst_s *inst)
+{
+	struct rte_crypto_eddsa_op_param *eddsa = &op->asym->eddsa;
+	uint8_t curveid = sess->ec_ctx.curveid;
+
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+		cnxk_ae_eddsa_sign_prep(eddsa, meta_buf, fpm_iova[curveid],
+					ec_grp[curveid], sess, inst);
+	else if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		cnxk_ae_eddsa_verify_prep(eddsa, meta_buf, fpm_iova[curveid],
+					  ec_grp[curveid], sess, inst);
+	else {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static __rte_always_inline void
 cnxk_ae_sm2_sign_prep(struct rte_crypto_sm2_op_param *sm2,
 			struct roc_ae_buf_ptr *meta_buf,
@@ -1004,6 +1341,88 @@ cnxk_ae_ecfpm_prep(rte_crypto_param *scalar,
 	return 0;
 }
 
+static __rte_always_inline int
+cnxk_ae_edfpm_prep(rte_crypto_param *scalar,
+		   struct roc_ae_buf_ptr *meta_buf, uint64_t *fpm_iova,
+		   struct roc_ae_ec_group *ec_grp, uint8_t curveid,
+		   struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	uint16_t dlen, prime_len, order_len, iv_len;
+	uint16_t scalar_align, p_align, o_offset;
+	uint64_t fpm_table_iova;
+	union cpt_inst_w4 w4;
+	uint16_t prime_bit;
+	uint8_t *dptr;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	fpm_table_iova = (uint64_t)fpm_iova[curveid];
+
+	/* Input buffer */
+	dptr = meta_buf->vaddr;
+	inst->dptr = (uintptr_t)dptr;
+
+	p_align = RTE_ALIGN_CEIL(prime_len, 8);
+	scalar_align = RTE_ALIGN_CEIL(scalar->length, 8);
+
+	/* Set write offset for order and key */
+	o_offset = p_align - order_len;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(prime len, order len, constant,
+	 * private key len and iv len (if ED25519))).
+	 */
+	dlen = sizeof(fpm_table_iova) + 3 * p_align + scalar_align + iv_len;
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += p_align;
+	memcpy(dptr + o_offset, ec_grp->order.data, order_len);
+	dptr += p_align;
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += p_align;
+	memcpy(dptr, scalar->data, scalar->length);
+	dptr += scalar_align;
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, sizeof(iv_sha512));
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_KEYGEN;
+
+	w4.s.param1 = prime_bit;
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+
+	return 0;
+}
+
 static __rte_always_inline int
 cnxk_ae_ecpm_prep(rte_crypto_param *scalar, struct rte_crypto_ec_point *p,
 		  struct roc_ae_buf_ptr *meta_buf,
@@ -1112,8 +1531,12 @@ cnxk_ae_enqueue_ecdh_op(struct rte_crypto_op *op,
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		scalar.data = sess->ec_ctx.pkey.data;
 		scalar.length = sess->ec_ctx.pkey.length;
-		cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
-			curveid, inst);
+		if (curveid == ROC_AE_EC_ID_ED25519 || curveid == ROC_AE_EC_ID_ED448)
+			cnxk_ae_edfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
+		else
+			cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		scalar.data = ec_grp[curveid]->order.data;
@@ -1212,6 +1635,30 @@ cnxk_ae_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa, uint8_t *rptr,
 	ecdsa->s.length = prime_len;
 }
 
+static __rte_always_inline void
+cnxk_ae_dequeue_eddsa_op(struct rte_crypto_eddsa_op_param *eddsa, uint8_t *rptr,
+			 struct roc_ae_ec_ctx *ec,
+			 struct roc_ae_ec_group **ec_grp)
+{
+	RTE_SET_USED(ec);
+	RTE_SET_USED(ec_grp);
+
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519 ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519CTX ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH) {
+		eddsa->sign.length = 64;
+		rte_memcpy(eddsa->sign.data, rptr, eddsa->sign.length);
+	} else {
+		eddsa->sign.length = 114;
+		rte_memcpy(eddsa->sign.data, rptr, 57);
+		rte_memcpy(eddsa->sign.data + 57, rptr + 64, 57);
+	}
+}
+
 static __rte_always_inline void
 cnxk_ae_dequeue_sm2_op(struct rte_crypto_sm2_op_param *sm2, uint8_t *rptr,
 			 struct roc_ae_ec_ctx *ec,
@@ -1245,7 +1692,7 @@ cnxk_ae_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param *ecpm, uint8_t *rptr,
 static __rte_always_inline void
 cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 			struct roc_ae_ec_ctx *ec,
-			struct roc_ae_ec_group **ec_grp)
+			struct roc_ae_ec_group **ec_grp, uint16_t flags)
 {
 	int prime_len = ec_grp[ec->curveid]->prime.length;
 
@@ -1256,9 +1703,12 @@ cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		memcpy(ecdh->pub_key.x.data, rptr, prime_len);
-		memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
 		ecdh->pub_key.x.length = prime_len;
-		ecdh->pub_key.y.length = prime_len;
+		if (!(flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED)) {
+			memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8),
+				prime_len);
+			ecdh->pub_key.y.length = prime_len;
+		}
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		break;
@@ -1328,6 +1778,13 @@ cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		ret = cnxk_ae_enqueue_eddsa_op(op, &meta_buf, sess,
+					       sess->cnxk_fpm_iova,
+					       sess->ec_grp, inst);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		ret = cnxk_ae_enqueue_sm2_op(op, &meta_buf, sess,
 					       sess->cnxk_fpm_iova,
@@ -1390,6 +1847,10 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		cnxk_ae_dequeue_ecdsa_op(&op->ecdsa, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		cnxk_ae_dequeue_eddsa_op(&op->eddsa, rptr, &sess->ec_ctx,
+					 sess->ec_grp);
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		cnxk_ae_dequeue_sm2_op(&op->sm2, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
@@ -1401,7 +1862,7 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_ECDH:
 		cnxk_ae_dequeue_ecdh_op(&op->ecdh, rptr, &sess->ec_ctx,
-					sess->ec_grp);
+					sess->ec_grp, op->flags);
 		break;
 	default:
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index 4000e84a7e..5cec64c2e1 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -11,7 +11,7 @@
 #include "roc_ae.h"
 #include "roc_cpt.h"
 
-#define CNXK_CPT_MAX_CAPS		 55
+#define CNXK_CPT_MAX_CAPS		 56
 #define CNXK_SEC_IPSEC_CRYPTO_MAX_CAPS	 16
 #define CNXK_SEC_TLS_1_3_CRYPTO_MAX_CAPS 3
 #define CNXK_SEC_TLS_1_2_CRYPTO_MAX_CAPS 7
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index 0d5d64b6e7..3897feacb8 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -1201,6 +1201,22 @@ static const struct rte_cryptodev_capabilities caps_sm2[] = {
 	}
 };
 
+static const struct rte_cryptodev_capabilities caps_eddsa[] = {
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					     (1 << RTE_CRYPTO_ASYM_OP_VERIFY))
+			}
+		}
+		}
+	}
+};
+
 static const struct rte_cryptodev_capabilities caps_end[] = {
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1940,6 +1956,9 @@ cn10k_crypto_caps_add(struct rte_cryptodev_capabilities cnxk_caps[],
 
 	if (hw_caps[CPT_ENG_TYPE_AE].sm2)
 		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, sm2);
+
+	if (hw_caps[CPT_ENG_TYPE_AE].eddsa)
+		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, eddsa);
 }
 
 static void
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v3 4/6] test/crypto: add asymmetric EDDSA test cases
  2024-09-20 13:09     ` [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-09-20 13:09       ` [PATCH v3 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
  2024-09-20 13:09       ` [PATCH v3 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
@ 2024-09-20 13:09       ` Gowrishankar Muthukrishnan
  2024-09-20 13:09       ` [PATCH v3 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
                         ` (2 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-20 13:09 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, jerinj, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Gowrishankar Muthukrishnan

Add test cases to validate EDDSA sign and verify ops,
as per RFC 8032.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
v3:
 - minor update in verify test.
---
 app/test/test_cryptodev_asym.c               | 345 +++++++++++-
 app/test/test_cryptodev_ecdh_test_vectors.h  |  94 +++-
 app/test/test_cryptodev_ecdsa_test_vectors.h |   4 +
 app/test/test_cryptodev_eddsa_test_vectors.h | 556 +++++++++++++++++++
 4 files changed, 992 insertions(+), 7 deletions(-)
 create mode 100644 app/test/test_cryptodev_eddsa_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index f0b5d38543..b3a7152c1a 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -20,6 +20,7 @@
 #include "test_cryptodev_ecdh_test_vectors.h"
 #include "test_cryptodev_ecdsa_test_vectors.h"
 #include "test_cryptodev_ecpm_test_vectors.h"
+#include "test_cryptodev_eddsa_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_sm2_test_vectors.h"
@@ -1631,6 +1632,9 @@ test_ecdsa_sign_verify_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
+		if (curve_id == ED25519 || curve_id == ED448)
+			continue;
+
 		status = test_ecdsa_sign_verify(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
@@ -1792,7 +1796,7 @@ test_ecpm_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecpm(curve_id);
@@ -1987,6 +1991,12 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	case SECP521R1:
 		input_params = ecdh_param_secp521r1;
 		break;
+	case ED25519:
+		input_params = ecdh_param_ed25519;
+		break;
+	case ED448:
+		input_params = ecdh_param_ed448;
+		break;
 	default:
 		RTE_LOG(ERR, USER1,
 				"line %u FAILED: %s", __LINE__,
@@ -2031,10 +2041,15 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 
 	/* Populate op with operational details */
 	asym_op->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
 
 	/* Init out buf */
 	asym_op->ecdh.pub_key.x.data = output_buf_x;
-	asym_op->ecdh.pub_key.y.data = output_buf_y;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->ecdh.pub_key.y.data = NULL;
+	else
+		asym_op->ecdh.pub_key.y.data = output_buf_y;
 
 	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
 
@@ -2073,8 +2088,13 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	debug_hexdump(stdout, "qy:",
 		asym_op->ecdh.pub_key.y.data, asym_op->ecdh.pub_key.y.length);
 
-	ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
+	if (curve_id == ED25519 || curve_id == ED448)
+		ret = memcmp(input_params.pubkey_qA_x.data, result_op->asym->ecdh.pub_key.x.data,
+			   result_op->asym->ecdh.pub_key.x.length);
+	else
+		ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
 				input_params.pubkey_qA_y.data, result_op);
+
 	if (ret) {
 		status = TEST_FAILED;
 		RTE_LOG(ERR, USER1,
@@ -2484,7 +2504,7 @@ test_ecdh_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_priv_key_generate(curve_id);
@@ -2514,7 +2534,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_pub_key_verify(curve_id);
@@ -2529,7 +2549,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_shared_secret(curve_id);
@@ -3167,6 +3187,317 @@ test_sm2_dec(void)
 	return status;
 };
 
+static int
+test_eddsa_sign(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct rte_cryptodev_asym_capability_idx idx;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return -ENOTSUP;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.data = input_params->pkey.data;
+	xform.ec.pkey.length = input_params->pkey.length;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	/* Init out buf */
+	asym_op->eddsa.sign.data = output_buf_r;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "sign:",
+			asym_op->eddsa.sign.data, asym_op->eddsa.sign.length);
+
+	/* Verify sign (by comparison). */
+	if (memcmp(input_params->sign.data, asym_op->eddsa.sign.data,
+			   asym_op->eddsa.sign.length) != 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"EDDSA sign failed.\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_verify(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct rte_cryptodev_asym_capability_idx idx;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return -ENOTSUP;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.length = 0;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	asym_op->eddsa.sign.data = input_params->sign.data;
+	asym_op->eddsa.sign.length = input_params->sign.length;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_sign_verify_all_curve(void)
+{
+	struct crypto_testsuite_eddsa_params input_params;
+	int status, overall_status = TEST_SUCCESS;
+	uint8_t i, tc = 0;
+	const char *msg;
+
+	/* Sign tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_sign(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Sign %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Verify tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_verify(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Verify %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Negative tests */
+	memcpy(&input_params, &eddsa_test_params[1],
+			sizeof(input_params));
+	input_params.pubkey.data[0] ^= 0x01;
+
+	status = test_eddsa_sign(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else if (status == TEST_SKIPPED) {
+		msg = "skipped";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Sign %s  %s\n",
+			tc++, input_params.description, msg);
+
+	status = test_eddsa_verify(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else if (status == TEST_SKIPPED) {
+		msg = "skipped";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Verify %s  %s\n",
+			tc++, input_params.description, msg);
+
+	return overall_status;
+}
+
 static int send_one(void)
 {
 	int ticks = 0;
@@ -3543,6 +3874,7 @@ static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 			"Modex Group 18 test",
 			ut_setup_asym, ut_teardown_asym,
 			modular_exponentiation, &modex_group_test_cases[5]),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
@@ -3634,6 +3966,7 @@ static struct unit_test_suite cryptodev_octeontx_asym_testsuite  = {
 				test_ecdh_all_curve),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
 				test_ecpm_all_curve),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_ecdh_test_vectors.h b/app/test/test_cryptodev_ecdh_test_vectors.h
index b577c179c8..4e587a3b01 100644
--- a/app/test/test_cryptodev_ecdh_test_vectors.h
+++ b/app/test/test_cryptodev_ecdh_test_vectors.h
@@ -553,4 +553,96 @@ struct crypto_testsuite_ecdh_params ecdh_param_secp521r1 = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP521R1
 };
 
-#endif /* __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__ */
+/** ED25519 test vector */
+
+static uint8_t dA_ed25519[] = {
+	0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+	0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+	0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+	0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+};
+
+static uint8_t x_qA_ed25519[] = {
+	0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+	0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+	0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+	0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+};
+
+/** ECDH ED25519 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed25519 = {
+	.pubkey_qA_x = {
+		.data = x_qA_ed25519,
+		.length = sizeof(x_qA_ed25519),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = dA_ed25519,
+		.length = sizeof(dA_ed25519),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519
+};
+
+/** ED448 test vector */
+
+static uint8_t dA_ed448[] = {
+	0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+	0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+	0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+	0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+	0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+	0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+	0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+	0x01
+};
+
+static uint8_t x_qA_ed448[] = {
+	0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+	0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+	0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+	0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+	0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+	0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+	0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+	0x00
+};
+
+/** ECDH ED448 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed448 = {
+	.pubkey_qA_x = {
+		.data = x_qA_ed448,
+		.length = sizeof(x_qA_ed448),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = dA_ed448,
+		.length = sizeof(dA_ed448),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448
+};
+
+#endif /* __TEST_CRYPTODEV_ECDH_TEST_VECTORS_H__ */
diff --git a/app/test/test_cryptodev_ecdsa_test_vectors.h b/app/test/test_cryptodev_ecdsa_test_vectors.h
index f1477639ba..636a1ab1b2 100644
--- a/app/test/test_cryptodev_ecdsa_test_vectors.h
+++ b/app/test/test_cryptodev_ecdsa_test_vectors.h
@@ -15,6 +15,8 @@ enum curve {
 	SECP384R1,
 	SECP521R1,
 	SECP521R1_UA,
+	ED25519,
+	ED448,
 	END_OF_CURVE_LIST
 };
 
@@ -24,6 +26,8 @@ const char *curve[] = {"SECP192R1",
 		       "SECP384R1",
 		       "SECP521R1",
 		       "SECP521R1(unaligned)",
+		       "ED25519",
+		       "ED448",
 };
 
 struct crypto_testsuite_ecdsa_params {
diff --git a/app/test/test_cryptodev_eddsa_test_vectors.h b/app/test/test_cryptodev_eddsa_test_vectors.h
new file mode 100644
index 0000000000..47e5355ec7
--- /dev/null
+++ b/app/test/test_cryptodev_eddsa_test_vectors.h
@@ -0,0 +1,556 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifndef __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+#define DATA_SIZE 1024
+
+struct crypto_testsuite_eddsa_params {
+	enum rte_crypto_edward_instance instance;
+	enum rte_crypto_curve_id curve;
+	const char *description;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pubkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} sign;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} message;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} context;
+};
+
+/** EDDSA curve test params (RFC 8032) */
+static const struct
+crypto_testsuite_eddsa_params eddsa_test_params[] = {
+{
+	.description = "EDDSA 25519 (msg=0)",
+	.pkey = {
+		.data = {
+			0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
+			0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4,
+			0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19,
+			0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7,
+			0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a,
+			0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25,
+			0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72,
+			0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a,
+			0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74,
+			0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55,
+			0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
+			0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b,
+			0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
+			0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1)",
+	.pkey = {
+		.data = {
+			0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+			0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+			0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+			0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+			0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+			0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+			0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+			0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+			0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+			0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+			0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+			0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+			0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+			0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x72
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1023)",
+	.pkey = {
+		.data = {
+			0xf5, 0xe5, 0x76, 0x7c, 0xf1, 0x53, 0x31, 0x95,
+			0x17, 0x63, 0x0f, 0x22, 0x68, 0x76, 0xb8, 0x6c,
+			0x81, 0x60, 0xcc, 0x58, 0x3b, 0xc0, 0x13, 0x74,
+			0x4c, 0x6b, 0xf2, 0x55, 0xf5, 0xcc, 0x0e, 0xe5
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x27, 0x81, 0x17, 0xfc, 0x14, 0x4c, 0x72, 0x34,
+			0x0f, 0x67, 0xd0, 0xf2, 0x31, 0x6e, 0x83, 0x86,
+			0xce, 0xff, 0xbf, 0x2b, 0x24, 0x28, 0xc9, 0xc5,
+			0x1f, 0xef, 0x7c, 0x59, 0x7f, 0x1d, 0x42, 0x6e
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x0a, 0xab, 0x4c, 0x90, 0x05, 0x01, 0xb3, 0xe2,
+			0x4d, 0x7c, 0xdf, 0x46, 0x63, 0x32, 0x6a, 0x3a,
+			0x87, 0xdf, 0x5e, 0x48, 0x43, 0xb2, 0xcb, 0xdb,
+			0x67, 0xcb, 0xf6, 0xe4, 0x60, 0xfe, 0xc3, 0x50,
+			0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45,
+			0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b,
+			0x5e, 0x8f, 0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6,
+			0xac, 0x00, 0xa9, 0x70, 0x4a, 0x18, 0x8a, 0x03
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x08, 0xb8, 0xb2, 0xb7, 0x33, 0x42, 0x42, 0x43,
+			0x76, 0x0f, 0xe4, 0x26, 0xa4, 0xb5, 0x49, 0x08,
+			0x63, 0x21, 0x10, 0xa6, 0x6c, 0x2f, 0x65, 0x91,
+			0xea, 0xbd, 0x33, 0x45, 0xe3, 0xe4, 0xeb, 0x98,
+			0xfa, 0x6e, 0x26, 0x4b, 0xf0, 0x9e, 0xfe, 0x12,
+			0xee, 0x50, 0xf8, 0xf5, 0x4e, 0x9f, 0x77, 0xb1,
+			0xe3, 0x55, 0xf6, 0xc5, 0x05, 0x44, 0xe2, 0x3f,
+			0xb1, 0x43, 0x3d, 0xdf, 0x73, 0xbe, 0x84, 0xd8,
+			0x79, 0xde, 0x7c, 0x00, 0x46, 0xdc, 0x49, 0x96,
+			0xd9, 0xe7, 0x73, 0xf4, 0xbc, 0x9e, 0xfe, 0x57,
+			0x38, 0x82, 0x9a, 0xdb, 0x26, 0xc8, 0x1b, 0x37,
+			0xc9, 0x3a, 0x1b, 0x27, 0x0b, 0x20, 0x32, 0x9d,
+			0x65, 0x86, 0x75, 0xfc, 0x6e, 0xa5, 0x34, 0xe0,
+			0x81, 0x0a, 0x44, 0x32, 0x82, 0x6b, 0xf5, 0x8c,
+			0x94, 0x1e, 0xfb, 0x65, 0xd5, 0x7a, 0x33, 0x8b,
+			0xbd, 0x2e, 0x26, 0x64, 0x0f, 0x89, 0xff, 0xbc,
+			0x1a, 0x85, 0x8e, 0xfc, 0xb8, 0x55, 0x0e, 0xe3,
+			0xa5, 0xe1, 0x99, 0x8b, 0xd1, 0x77, 0xe9, 0x3a,
+			0x73, 0x63, 0xc3, 0x44, 0xfe, 0x6b, 0x19, 0x9e,
+			0xe5, 0xd0, 0x2e, 0x82, 0xd5, 0x22, 0xc4, 0xfe,
+			0xba, 0x15, 0x45, 0x2f, 0x80, 0x28, 0x8a, 0x82,
+			0x1a, 0x57, 0x91, 0x16, 0xec, 0x6d, 0xad, 0x2b,
+			0x3b, 0x31, 0x0d, 0xa9, 0x03, 0x40, 0x1a, 0xa6,
+			0x21, 0x00, 0xab, 0x5d, 0x1a, 0x36, 0x55, 0x3e,
+			0x06, 0x20, 0x3b, 0x33, 0x89, 0x0c, 0xc9, 0xb8,
+			0x32, 0xf7, 0x9e, 0xf8, 0x05, 0x60, 0xcc, 0xb9,
+			0xa3, 0x9c, 0xe7, 0x67, 0x96, 0x7e, 0xd6, 0x28,
+			0xc6, 0xad, 0x57, 0x3c, 0xb1, 0x16, 0xdb, 0xef,
+			0xef, 0xd7, 0x54, 0x99, 0xda, 0x96, 0xbd, 0x68,
+			0xa8, 0xa9, 0x7b, 0x92, 0x8a, 0x8b, 0xbc, 0x10,
+			0x3b, 0x66, 0x21, 0xfc, 0xde, 0x2b, 0xec, 0xa1,
+			0x23, 0x1d, 0x20, 0x6b, 0xe6, 0xcd, 0x9e, 0xc7,
+			0xaf, 0xf6, 0xf6, 0xc9, 0x4f, 0xcd, 0x72, 0x04,
+			0xed, 0x34, 0x55, 0xc6, 0x8c, 0x83, 0xf4, 0xa4,
+			0x1d, 0xa4, 0xaf, 0x2b, 0x74, 0xef, 0x5c, 0x53,
+			0xf1, 0xd8, 0xac, 0x70, 0xbd, 0xcb, 0x7e, 0xd1,
+			0x85, 0xce, 0x81, 0xbd, 0x84, 0x35, 0x9d, 0x44,
+			0x25, 0x4d, 0x95, 0x62, 0x9e, 0x98, 0x55, 0xa9,
+			0x4a, 0x7c, 0x19, 0x58, 0xd1, 0xf8, 0xad, 0xa5,
+			0xd0, 0x53, 0x2e, 0xd8, 0xa5, 0xaa, 0x3f, 0xb2,
+			0xd1, 0x7b, 0xa7, 0x0e, 0xb6, 0x24, 0x8e, 0x59,
+			0x4e, 0x1a, 0x22, 0x97, 0xac, 0xbb, 0xb3, 0x9d,
+			0x50, 0x2f, 0x1a, 0x8c, 0x6e, 0xb6, 0xf1, 0xce,
+			0x22, 0xb3, 0xde, 0x1a, 0x1f, 0x40, 0xcc, 0x24,
+			0x55, 0x41, 0x19, 0xa8, 0x31, 0xa9, 0xaa, 0xd6,
+			0x07, 0x9c, 0xad, 0x88, 0x42, 0x5d, 0xe6, 0xbd,
+			0xe1, 0xa9, 0x18, 0x7e, 0xbb, 0x60, 0x92, 0xcf,
+			0x67, 0xbf, 0x2b, 0x13, 0xfd, 0x65, 0xf2, 0x70,
+			0x88, 0xd7, 0x8b, 0x7e, 0x88, 0x3c, 0x87, 0x59,
+			0xd2, 0xc4, 0xf5, 0xc6, 0x5a, 0xdb, 0x75, 0x53,
+			0x87, 0x8a, 0xd5, 0x75, 0xf9, 0xfa, 0xd8, 0x78,
+			0xe8, 0x0a, 0x0c, 0x9b, 0xa6, 0x3b, 0xcb, 0xcc,
+			0x27, 0x32, 0xe6, 0x94, 0x85, 0xbb, 0xc9, 0xc9,
+			0x0b, 0xfb, 0xd6, 0x24, 0x81, 0xd9, 0x08, 0x9b,
+			0xec, 0xcf, 0x80, 0xcf, 0xe2, 0xdf, 0x16, 0xa2,
+			0xcf, 0x65, 0xbd, 0x92, 0xdd, 0x59, 0x7b, 0x07,
+			0x07, 0xe0, 0x91, 0x7a, 0xf4, 0x8b, 0xbb, 0x75,
+			0xfe, 0xd4, 0x13, 0xd2, 0x38, 0xf5, 0x55, 0x5a,
+			0x7a, 0x56, 0x9d, 0x80, 0xc3, 0x41, 0x4a, 0x8d,
+			0x08, 0x59, 0xdc, 0x65, 0xa4, 0x61, 0x28, 0xba,
+			0xb2, 0x7a, 0xf8, 0x7a, 0x71, 0x31, 0x4f, 0x31,
+			0x8c, 0x78, 0x2b, 0x23, 0xeb, 0xfe, 0x80, 0x8b,
+			0x82, 0xb0, 0xce, 0x26, 0x40, 0x1d, 0x2e, 0x22,
+			0xf0, 0x4d, 0x83, 0xd1, 0x25, 0x5d, 0xc5, 0x1a,
+			0xdd, 0xd3, 0xb7, 0x5a, 0x2b, 0x1a, 0xe0, 0x78,
+			0x45, 0x04, 0xdf, 0x54, 0x3a, 0xf8, 0x96, 0x9b,
+			0xe3, 0xea, 0x70, 0x82, 0xff, 0x7f, 0xc9, 0x88,
+			0x8c, 0x14, 0x4d, 0xa2, 0xaf, 0x58, 0x42, 0x9e,
+			0xc9, 0x60, 0x31, 0xdb, 0xca, 0xd3, 0xda, 0xd9,
+			0xaf, 0x0d, 0xcb, 0xaa, 0xaf, 0x26, 0x8c, 0xb8,
+			0xfc, 0xff, 0xea, 0xd9, 0x4f, 0x3c, 0x7c, 0xa4,
+			0x95, 0xe0, 0x56, 0xa9, 0xb4, 0x7a, 0xcd, 0xb7,
+			0x51, 0xfb, 0x73, 0xe6, 0x66, 0xc6, 0xc6, 0x55,
+			0xad, 0xe8, 0x29, 0x72, 0x97, 0xd0, 0x7a, 0xd1,
+			0xba, 0x5e, 0x43, 0xf1, 0xbc, 0xa3, 0x23, 0x01,
+			0x65, 0x13, 0x39, 0xe2, 0x29, 0x04, 0xcc, 0x8c,
+			0x42, 0xf5, 0x8c, 0x30, 0xc0, 0x4a, 0xaf, 0xdb,
+			0x03, 0x8d, 0xda, 0x08, 0x47, 0xdd, 0x98, 0x8d,
+			0xcd, 0xa6, 0xf3, 0xbf, 0xd1, 0x5c, 0x4b, 0x4c,
+			0x45, 0x25, 0x00, 0x4a, 0xa0, 0x6e, 0xef, 0xf8,
+			0xca, 0x61, 0x78, 0x3a, 0xac, 0xec, 0x57, 0xfb,
+			0x3d, 0x1f, 0x92, 0xb0, 0xfe, 0x2f, 0xd1, 0xa8,
+			0x5f, 0x67, 0x24, 0x51, 0x7b, 0x65, 0xe6, 0x14,
+			0xad, 0x68, 0x08, 0xd6, 0xf6, 0xee, 0x34, 0xdf,
+			0xf7, 0x31, 0x0f, 0xdc, 0x82, 0xae, 0xbf, 0xd9,
+			0x04, 0xb0, 0x1e, 0x1d, 0xc5, 0x4b, 0x29, 0x27,
+			0x09, 0x4b, 0x2d, 0xb6, 0x8d, 0x6f, 0x90, 0x3b,
+			0x68, 0x40, 0x1a, 0xde, 0xbf, 0x5a, 0x7e, 0x08,
+			0xd7, 0x8f, 0xf4, 0xef, 0x5d, 0x63, 0x65, 0x3a,
+			0x65, 0x04, 0x0c, 0xf9, 0xbf, 0xd4, 0xac, 0xa7,
+			0x98, 0x4a, 0x74, 0xd3, 0x71, 0x45, 0x98, 0x67,
+			0x80, 0xfc, 0x0b, 0x16, 0xac, 0x45, 0x16, 0x49,
+			0xde, 0x61, 0x88, 0xa7, 0xdb, 0xdf, 0x19, 0x1f,
+			0x64, 0xb5, 0xfc, 0x5e, 0x2a, 0xb4, 0x7b, 0x57,
+			0xf7, 0xf7, 0x27, 0x6c, 0xd4, 0x19, 0xc1, 0x7a,
+			0x3c, 0xa8, 0xe1, 0xb9, 0x39, 0xae, 0x49, 0xe4,
+			0x88, 0xac, 0xba, 0x6b, 0x96, 0x56, 0x10, 0xb5,
+			0x48, 0x01, 0x09, 0xc8, 0xb1, 0x7b, 0x80, 0xe1,
+			0xb7, 0xb7, 0x50, 0xdf, 0xc7, 0x59, 0x8d, 0x5d,
+			0x50, 0x11, 0xfd, 0x2d, 0xcc, 0x56, 0x00, 0xa3,
+			0x2e, 0xf5, 0xb5, 0x2a, 0x1e, 0xcc, 0x82, 0x0e,
+			0x30, 0x8a, 0xa3, 0x42, 0x72, 0x1a, 0xac, 0x09,
+			0x43, 0xbf, 0x66, 0x86, 0xb6, 0x4b, 0x25, 0x79,
+			0x37, 0x65, 0x04, 0xcc, 0xc4, 0x93, 0xd9, 0x7e,
+			0x6a, 0xed, 0x3f, 0xb0, 0xf9, 0xcd, 0x71, 0xa4,
+			0x3d, 0xd4, 0x97, 0xf0, 0x1f, 0x17, 0xc0, 0xe2,
+			0xcb, 0x37, 0x97, 0xaa, 0x2a, 0x2f, 0x25, 0x66,
+			0x56, 0x16, 0x8e, 0x6c, 0x49, 0x6a, 0xfc, 0x5f,
+			0xb9, 0x32, 0x46, 0xf6, 0xb1, 0x11, 0x63, 0x98,
+			0xa3, 0x46, 0xf1, 0xa6, 0x41, 0xf3, 0xb0, 0x41,
+			0xe9, 0x89, 0xf7, 0x91, 0x4f, 0x90, 0xcc, 0x2c,
+			0x7f, 0xff, 0x35, 0x78, 0x76, 0xe5, 0x06, 0xb5,
+			0x0d, 0x33, 0x4b, 0xa7, 0x7c, 0x22, 0x5b, 0xc3,
+			0x07, 0xba, 0x53, 0x71, 0x52, 0xf3, 0xf1, 0x61,
+			0x0e, 0x4e, 0xaf, 0xe5, 0x95, 0xf6, 0xd9, 0xd9,
+			0x0d, 0x11, 0xfa, 0xa9, 0x33, 0xa1, 0x5e, 0xf1,
+			0x36, 0x95, 0x46, 0x86, 0x8a, 0x7f, 0x3a, 0x45,
+			0xa9, 0x67, 0x68, 0xd4, 0x0f, 0xd9, 0xd0, 0x34,
+			0x12, 0xc0, 0x91, 0xc6, 0x31, 0x5c, 0xf4, 0xfd,
+			0xe7, 0xcb, 0x68, 0x60, 0x69, 0x37, 0x38, 0x0d,
+			0xb2, 0xea, 0xaa, 0x70, 0x7b, 0x4c, 0x41, 0x85,
+			0xc3, 0x2e, 0xdd, 0xcd, 0xd3, 0x06, 0x70, 0x5e,
+			0x4d, 0xc1, 0xff, 0xc8, 0x72, 0xee, 0xee, 0x47,
+			0x5a, 0x64, 0xdf, 0xac, 0x86, 0xab, 0xa4, 0x1c,
+			0x06, 0x18, 0x98, 0x3f, 0x87, 0x41, 0xc5, 0xef,
+			0x68, 0xd3, 0xa1, 0x01, 0xe8, 0xa3, 0xb8, 0xca,
+			0xc6, 0x0c, 0x90, 0x5c, 0x15, 0xfc, 0x91, 0x08,
+			0x40, 0xb9, 0x4c, 0x00, 0xa0, 0xb9, 0xd0
+		},
+		.length = 1023,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519CTX (msg=16, ctx=3)",
+	.pkey = {
+		.data = {
+			0x03, 0x05, 0x33, 0x4e, 0x38, 0x1a, 0xf7, 0x8f,
+			0x14, 0x1c, 0xb6, 0x66, 0xf6, 0x19, 0x9f, 0x57,
+			0xbc, 0x34, 0x95, 0x33, 0x5a, 0x25, 0x6a, 0x95,
+			0xbd, 0x2a, 0x55, 0xbf, 0x54, 0x66, 0x63, 0xf6
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xdf, 0xc9, 0x42, 0x5e, 0x4f, 0x96, 0x8f, 0x7f,
+			0x0c, 0x29, 0xf0, 0x25, 0x9c, 0xf5, 0xf9, 0xae,
+			0xd6, 0x85, 0x1c, 0x2b, 0xb4, 0xad, 0x8b, 0xfb,
+			0x86, 0x0c, 0xfe, 0xe0, 0xab, 0x24, 0x82, 0x92
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x55, 0xa4, 0xcc, 0x2f, 0x70, 0xa5, 0x4e, 0x04,
+			0x28, 0x8c, 0x5f, 0x4c, 0xd1, 0xe4, 0x5a, 0x7b,
+			0xb5, 0x20, 0xb3, 0x62, 0x92, 0x91, 0x18, 0x76,
+			0xca, 0xda, 0x73, 0x23, 0x19, 0x8d, 0xd8, 0x7a,
+			0x8b, 0x36, 0x95, 0x0b, 0x95, 0x13, 0x00, 0x22,
+			0x90, 0x7a, 0x7f, 0xb7, 0xc4, 0xe9, 0xb2, 0xd5,
+			0xf6, 0xcc, 0xa6, 0x85, 0xa5, 0x87, 0xb4, 0xb2,
+			0x1f, 0x4b, 0x88, 0x8e, 0x4e, 0x7e, 0xdb, 0x0d
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0xf7, 0x26, 0x93, 0x6d, 0x19, 0xc8, 0x00, 0x49,
+			0x4e, 0x3f, 0xda, 0xff, 0x20, 0xb2, 0x76, 0xa8,
+		},
+		.length = 16,
+	},
+	.context = {
+		.data = {
+			0x66, 0x6f, 0x6f
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519CTX
+},
+{
+	.description = "EDDSA 25519PH (msg=1, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+			0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+			0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+			0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x98, 0xa7, 0x02, 0x22, 0xf0, 0xb8, 0x12, 0x1a,
+			0xa9, 0xd3, 0x0f, 0x81, 0x3d, 0x68, 0x3f, 0x80,
+			0x9e, 0x46, 0x2b, 0x46, 0x9c, 0x7f, 0xf8, 0x76,
+			0x39, 0x49, 0x9b, 0xb9, 0x4e, 0x6d, 0xae, 0x41,
+			0x31, 0xf8, 0x50, 0x42, 0x46, 0x3c, 0x2a, 0x35,
+			0x5a, 0x20, 0x03, 0xd0, 0x62, 0xad, 0xf5, 0xaa,
+			0xa1, 0x0b, 0x8c, 0x61, 0xe6, 0x36, 0x06, 0x2a,
+			0xaa, 0xd1, 0x1c, 0x2a, 0x26, 0x08, 0x34, 0x06
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519PH
+},
+{
+	.description = "EDDSA 448 (msg=0)",
+	.pkey = {
+		.data = {
+			0x6C, 0x82, 0xA5, 0x62, 0xCB, 0x80, 0x8D, 0x10,
+			0xD6, 0x32, 0xBE, 0x89, 0xC8, 0x51, 0x3E, 0xBF,
+			0x6C, 0x92, 0x9F, 0x34, 0xDD, 0xFA, 0x8C, 0x9F,
+			0x63, 0xC9, 0x96, 0x0E, 0xF6, 0xE3, 0x48, 0xA3,
+			0x52, 0x8C, 0x8A, 0x3F, 0xCC, 0x2F, 0x04, 0x4E,
+			0x39, 0xA3, 0xFC, 0x5B, 0x94, 0x49, 0x2F, 0x8F,
+			0x03, 0x2E, 0x75, 0x49, 0xA2, 0x00, 0x98, 0xF9,
+			0x5B,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x5F, 0xD7, 0x44, 0x9B, 0x59, 0xB4, 0x61, 0xFD,
+			0x2C, 0xE7, 0x87, 0xEC, 0x61, 0x6A, 0xD4, 0x6A,
+			0x1D, 0xA1, 0x34, 0x24, 0x85, 0xA7, 0x0E, 0x1F,
+			0x8A, 0x0E, 0xA7, 0x5D, 0x80, 0xE9, 0x67, 0x78,
+			0xED, 0xF1, 0x24, 0x76, 0x9B, 0x46, 0xC7, 0x06,
+			0x1B, 0xD6, 0x78, 0x3D, 0xF1, 0xE5, 0x0F, 0x6C,
+			0xD1, 0xFA, 0x1A, 0xBE, 0xAF, 0xE8, 0x25, 0x61,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25,
+			0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae,
+			0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2,
+			0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f,
+			0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81,
+			0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78,
+			0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39,
+			0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a,
+			0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d,
+			0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41,
+			0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd,
+			0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb,
+			0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26,
+			0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65,
+			0x26, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=1)",
+	.pkey = {
+		.data = {
+			0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6,
+			0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92, 0x4d,
+			0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d,
+			0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c, 0x46, 0x3a,
+			0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c,
+			0x5e, 0x3b, 0xc3, 0x97, 0xa6, 0x59, 0x94, 0x9e,
+			0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27,
+			0x4e,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45,
+			0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd, 0x0a,
+			0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37,
+			0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98, 0xc0, 0x86,
+			0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02,
+			0xb8, 0x43, 0x8e, 0xa4, 0xcb, 0x82, 0x16, 0x9c,
+			0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x26, 0xb8, 0xf9, 0x17, 0x27, 0xbd, 0x62, 0x89,
+			0x7a, 0xf1, 0x5e, 0x41, 0xeb, 0x43, 0xc3, 0x77,
+			0xef, 0xb9, 0xc6, 0x10, 0xd4, 0x8f, 0x23, 0x35,
+			0xcb, 0x0b, 0xd0, 0x08, 0x78, 0x10, 0xf4, 0x35,
+			0x25, 0x41, 0xb1, 0x43, 0xc4, 0xb9, 0x81, 0xb7,
+			0xe1, 0x8f, 0x62, 0xde, 0x8c, 0xcd, 0xf6, 0x33,
+			0xfc, 0x1b, 0xf0, 0x37, 0xab, 0x7c, 0xd7, 0x79,
+			0x80, 0x5e, 0x0d, 0xbc, 0xc0, 0xaa, 0xe1, 0xcb,
+			0xce, 0xe1, 0xaf, 0xb2, 0xe0, 0x27, 0xdf, 0x36,
+			0xbc, 0x04, 0xdc, 0xec, 0xbf, 0x15, 0x43, 0x36,
+			0xc1, 0x9f, 0x0a, 0xf7, 0xe0, 0xa6, 0x47, 0x29,
+			0x05, 0xe7, 0x99, 0xf1, 0x95, 0x3d, 0x2a, 0x0f,
+			0xf3, 0x34, 0x8a, 0xb2, 0x1a, 0xa4, 0xad, 0xaf,
+			0xd1, 0xd2, 0x34, 0x44, 0x1c, 0xf8, 0x07, 0xc0,
+			0x3a, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x03
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=3, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42,
+			0xef, 0x78, 0x22, 0xe0, 0xd5, 0x10, 0x41, 0x27,
+			0xdc, 0x05, 0xd6, 0xdb, 0xef, 0xde, 0x69, 0xe3,
+			0xab, 0x2c, 0xec, 0x7c, 0x86, 0x7c, 0x6e, 0x2c,
+			0x49
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x25, 0x9b, 0x71, 0xc1, 0x9f, 0x83, 0xef, 0x77,
+			0xa7, 0xab, 0xd2, 0x65, 0x24, 0xcb, 0xdb, 0x31,
+			0x61, 0xb5, 0x90, 0xa4, 0x8f, 0x7d, 0x17, 0xde,
+			0x3e, 0xe0, 0xba, 0x9c, 0x52, 0xbe, 0xb7, 0x43,
+			0xc0, 0x94, 0x28, 0xa1, 0x31, 0xd6, 0xb1, 0xb5,
+			0x73, 0x03, 0xd9, 0x0d, 0x81, 0x32, 0xc2, 0x76,
+			0xd5, 0xed, 0x3d, 0x5d, 0x01, 0xc0, 0xf5, 0x38,
+			0x80
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x82, 0x2f, 0x69, 0x01, 0xf7, 0x48, 0x0f, 0x3d,
+			0x5f, 0x56, 0x2c, 0x59, 0x29, 0x94, 0xd9, 0x69,
+			0x36, 0x02, 0x87, 0x56, 0x14, 0x48, 0x32, 0x56,
+			0x50, 0x56, 0x00, 0xbb, 0xc2, 0x81, 0xae, 0x38,
+			0x1f, 0x54, 0xd6, 0xbc, 0xe2, 0xea, 0x91, 0x15,
+			0x74, 0x93, 0x2f, 0x52, 0xa4, 0xe6, 0xca, 0xdd,
+			0x78, 0x76, 0x93, 0x75, 0xec, 0x3f, 0xfd, 0x1b,
+			0x80, 0x1a, 0x0d, 0x9b, 0x3f, 0x40, 0x30, 0xcd,
+			0x43, 0x39, 0x64, 0xb6, 0x45, 0x7e, 0xa3, 0x94,
+			0x76, 0x51, 0x12, 0x14, 0xf9, 0x74, 0x69, 0xb5,
+			0x7d, 0xd3, 0x2d, 0xbc, 0x56, 0x0a, 0x9a, 0x94,
+			0xd0, 0x0b, 0xff, 0x07, 0x62, 0x04, 0x64, 0xa3,
+			0xad, 0x20, 0x3d, 0xf7, 0xdc, 0x7c, 0xe3, 0x60,
+			0xc3, 0xcd, 0x36, 0x96, 0xd9, 0xd9, 0xfa, 0xb9,
+			0x0f, 0x00
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448PH
+},
+};
+
+#endif /* __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__ */
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v3 5/6] examples/fips_validation: support EDDSA
  2024-09-20 13:09     ` [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                         ` (2 preceding siblings ...)
  2024-09-20 13:09       ` [PATCH v3 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
@ 2024-09-20 13:09       ` Gowrishankar Muthukrishnan
  2024-09-20 13:09       ` [PATCH v3 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
  2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-20 13:09 UTC (permalink / raw)
  To: dev, Brian Dooley, Gowrishankar Muthukrishnan
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal

Add EDDSA support in fips_validation app.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 examples/fips_validation/fips_validation.c    |   2 +
 examples/fips_validation/fips_validation.h    |  23 ++
 .../fips_validation/fips_validation_eddsa.c   | 307 +++++++++++++++++
 examples/fips_validation/main.c               | 323 ++++++++++++++++--
 examples/fips_validation/meson.build          |   1 +
 5 files changed, 623 insertions(+), 33 deletions(-)
 create mode 100644 examples/fips_validation/fips_validation_eddsa.c

diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c
index c15178e55b..43d1e55532 100644
--- a/examples/fips_validation/fips_validation.c
+++ b/examples/fips_validation/fips_validation.c
@@ -475,6 +475,8 @@ fips_test_parse_one_json_vector_set(void)
 		info.algo = FIPS_TEST_ALGO_RSA;
 	else if (strstr(algo_str, "ECDSA"))
 		info.algo = FIPS_TEST_ALGO_ECDSA;
+	else if (strstr(algo_str, "EDDSA"))
+		info.algo = FIPS_TEST_ALGO_EDDSA;
 	else
 		return -EINVAL;
 
diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h
index abc1d64742..795cf834e8 100644
--- a/examples/fips_validation/fips_validation.h
+++ b/examples/fips_validation/fips_validation.h
@@ -46,6 +46,7 @@ enum fips_test_algorithms {
 		FIPS_TEST_ALGO_SHA,
 		FIPS_TEST_ALGO_RSA,
 		FIPS_TEST_ALGO_ECDSA,
+		FIPS_TEST_ALGO_EDDSA,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -106,6 +107,12 @@ struct fips_test_vector {
 		struct fips_val s;
 		struct fips_val k;
 	} ecdsa;
+	struct {
+		struct fips_val pkey;
+		struct fips_val q;
+		struct fips_val ctx;
+		struct fips_val sign;
+	} eddsa;
 
 	struct fips_val pt;
 	struct fips_val ct;
@@ -177,6 +184,11 @@ enum fips_ecdsa_test_types {
 	ECDSA_AFT = 0,
 };
 
+enum fips_eddsa_test_types {
+	EDDSA_AFT = 0,
+	EDDSA_BFT
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -241,6 +253,13 @@ struct ecdsa_interim_data {
 	uint8_t pubkey_gen;
 };
 
+struct eddsa_interim_data {
+	enum rte_crypto_curve_id curve_id;
+	uint8_t curve_len;
+	uint8_t pubkey_gen;
+	bool prehash;
+};
+
 #ifdef USE_JANSSON
 /*
  * Maximum length of buffer to hold any json string.
@@ -288,6 +307,7 @@ struct fips_test_interim_info {
 		struct xts_interim_data xts_data;
 		struct rsa_interim_data rsa_data;
 		struct ecdsa_interim_data ecdsa_data;
+		struct eddsa_interim_data eddsa_data;
 	} interim_info;
 
 	enum fips_test_op op;
@@ -374,6 +394,9 @@ parse_test_rsa_json_init(void);
 int
 parse_test_ecdsa_json_init(void);
 
+int
+parse_test_eddsa_json_init(void);
+
 int
 fips_test_randomize_message(struct fips_val *msg, struct fips_val *rand);
 #endif /* USE_JANSSON */
diff --git a/examples/fips_validation/fips_validation_eddsa.c b/examples/fips_validation/fips_validation_eddsa.c
new file mode 100644
index 0000000000..8ccf7501bd
--- /dev/null
+++ b/examples/fips_validation/fips_validation_eddsa.c
@@ -0,0 +1,307 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell.
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef USE_OPENSSL
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#endif /* USE_OPENSSL */
+
+#include <rte_cryptodev.h>
+#include <rte_malloc.h>
+
+#include "fips_validation.h"
+
+#define TESTTYPE_JSON_STR "testType"
+#define CURVE_JSON_STR    "curve"
+#define PH_JSON_STR       "preHash"
+
+#define MSG_JSON_STR "message"
+#define CTX_JSON_STR "context"
+#define Q_JSON_STR	 "q"
+#define SIG_JSON_STR "signature"
+
+#ifdef USE_JANSSON
+struct {
+	uint8_t type;
+	const char *desc;
+} eddsa_test_types[] = {
+	{EDDSA_AFT, "AFT"},
+	{EDDSA_BFT, "BFT"}
+};
+
+struct {
+	enum rte_crypto_curve_id curve_id;
+	const char *desc;
+} eddsa_curve_ids[] = {
+	{RTE_CRYPTO_EC_GROUP_ED25519, "ED-25519"},
+	{RTE_CRYPTO_EC_GROUP_ED448, "ED-448"},
+};
+
+struct {
+	uint8_t curve_len;
+	const char *desc;
+} eddsa_curve_len[] = {
+	{32, "ED-25519"},
+	{64, "ED-448"},
+};
+
+#ifdef USE_OPENSSL
+#define MAX_TRIES 10
+static int
+prepare_vec_eddsa(void)
+{
+	BIGNUM *pkey = NULL, *order = NULL;
+	int ret = -1, j;
+	unsigned long pid;
+
+	/* For EDDSA prime fields, order of base points (RFC 8032 Section 5.1 and 5.2).
+	 */
+	static const char * const orderstr[] = {
+			"7237005577332262213973186563042994240857116359379907606001950938285454250989",
+			"181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779",
+	};
+
+	pid = getpid();
+	RAND_seed(&pid, sizeof(pid));
+
+	if (!RAND_status())
+		return -1;
+
+	order = BN_new();
+	if (!order)
+		goto err;
+
+	j = info.interim_info.eddsa_data.curve_id - RTE_CRYPTO_EC_GROUP_ED25519;
+	if (!BN_hex2bn(&order, orderstr[j]))
+		goto err;
+
+	pkey = BN_new();
+	if (!pkey)
+		goto err;
+
+	for (j = 0; j < MAX_TRIES; j++) {
+		/* pkey should be in [1, order - 1] */
+		if (!BN_rand_range(pkey, order))
+			goto err;
+
+		if (!BN_is_zero(pkey))
+			break;
+	}
+
+	if (j == MAX_TRIES)
+		goto err;
+
+	parse_uint8_hex_str("", BN_bn2hex(pkey), &vec.eddsa.pkey);
+
+	ret = 0;
+err:
+	BN_free(order);
+	BN_free(pkey);
+	return ret;
+}
+#else
+static int
+prepare_vec_eddsa(void)
+{
+	/*
+	 * Generate EDDSA values.
+	 */
+	return -ENOTSUP;
+}
+#endif /* USE_OPENSSL */
+
+static int
+parse_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		/* For siggen tests, EDDSA values can be created soon after
+		 * the test group data are parsed.
+		 */
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+static int
+post_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_group, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_test_eddsa_json_writeback(struct fips_val *val)
+{
+	json_t *tcId;
+
+	RTE_SET_USED(val);
+
+	tcId = json_object_get(json_info.json_test_case, "tcId");
+
+	json_info.json_write_case = json_object();
+	json_object_set(json_info.json_write_case, "tcId", tcId);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.sign);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "signature", obj);
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)
+			json_object_set_new(json_info.json_write_case, "testPassed", json_true());
+		else
+			json_object_set_new(json_info.json_write_case, "testPassed", json_false());
+	} else if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.pkey);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "d", obj);
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_interim_str(const char *key, char *src, struct fips_val *val)
+{
+	uint32_t i;
+
+	RTE_SET_USED(val);
+
+	if (strcmp(key, TESTTYPE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_test_types); i++)
+			if (strstr(src, eddsa_test_types[i].desc)) {
+				info.parse_writeback = parse_test_eddsa_json_writeback;
+				break;
+			}
+
+		if (!info.parse_writeback || i >= RTE_DIM(eddsa_test_types))
+			return -EINVAL;
+
+	} else if (strcmp(key, CURVE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_curve_ids); i++)
+			if (strstr(src, eddsa_curve_ids[i].desc)) {
+				info.interim_info.eddsa_data.curve_id = eddsa_curve_ids[i].curve_id;
+				info.interim_info.eddsa_data.curve_len =
+					eddsa_curve_len[i].curve_len;
+				break;
+			}
+
+		if (i >= RTE_DIM(eddsa_curve_ids))
+			return -EINVAL;
+	} else if (strcmp(key, PH_JSON_STR) == 0) {
+		info.interim_info.eddsa_data.prehash = false;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+parse_keygen_tc_str(const char *key, char *src, struct fips_val *val)
+{
+	RTE_SET_USED(key);
+	RTE_SET_USED(src);
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+struct fips_test_callback eddsa_interim_json_vectors[] = {
+		{TESTTYPE_JSON_STR, parse_interim_str, NULL},
+		{CURVE_JSON_STR, parse_interim_str, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_siggen_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{CTX_JSON_STR, parse_uint8_hex_str, &vec.eddsa.ctx},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_sigver_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{Q_JSON_STR, parse_uint8_hex_str, &vec.eddsa.q},
+		{SIG_JSON_STR, parse_uint8_hex_str, &vec.eddsa.sign},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_keygen_json_vectors[] = {
+		{"tcId", parse_keygen_tc_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+int
+parse_test_eddsa_json_init(void)
+{
+	json_t *mode_obj = json_object_get(json_info.json_vector_set, "mode");
+	const char *mode_str = json_string_value(mode_obj);
+
+	info.callbacks = NULL;
+	info.parse_writeback = NULL;
+
+	info.interim_callbacks = eddsa_interim_json_vectors;
+	info.post_interim_writeback = post_test_eddsa_json_interim_writeback;
+	info.parse_interim_writeback = parse_test_eddsa_json_interim_writeback;
+	if (strcmp(mode_str, "sigGen") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGGEN;
+		info.callbacks = eddsa_siggen_json_vectors;
+	} else if (strcmp(mode_str, "sigVer") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGVER;
+		info.callbacks = eddsa_sigver_json_vectors;
+	} else if (strcmp(mode_str, "keyGen") == 0) {
+		info.op = FIPS_TEST_ASYM_KEYGEN;
+		info.callbacks = eddsa_keygen_json_vectors;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif /* USE_JANSSON */
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index 7ae2c6c007..522373ac1d 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -1041,6 +1041,64 @@ prepare_ecdsa_op(void)
 	return 0;
 }
 
+static int
+prepare_eddsa_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+	struct fips_val msg;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	if (env.digest) {
+		msg.val = env.digest;
+		msg.len = env.digest_len;
+	} else {
+		msg.val = vec.pt.val;
+		msg.len = vec.pt.len;
+	}
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.context.data = vec.eddsa.ctx.val;
+		asym->eddsa.context.length = vec.eddsa.ctx.len;
+
+		rte_free(vec.eddsa.sign.val);
+
+		vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len;
+		vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0);
+
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = 0;
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = vec.eddsa.sign.len;
+	} else {
+		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
+		return -EINVAL;
+	}
+
+	if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH;
+		if (vec.eddsa.ctx.len > 0)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX;
+	} else {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH;
+	}
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_ecfpm_op(void)
 {
@@ -1072,6 +1130,31 @@ prepare_ecfpm_op(void)
 	return 0;
 }
 
+static int
+prepare_edfpm_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	asym->ecpm.scalar.data = vec.eddsa.pkey.val;
+	asym->ecpm.scalar.length = vec.eddsa.pkey.len;
+
+	rte_free(vec.eddsa.q.val);
+
+	vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len;
+	vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0);
+
+	asym->ecpm.r.x.data = vec.eddsa.q.val;
+	asym->ecpm.r.x.length = 0;
+	asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
@@ -1589,6 +1672,56 @@ prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_eddsa_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	switch (info.op) {
+	case FIPS_TEST_ASYM_SIGGEN:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_SIGN)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
+			return -EPERM;
+		}
+
+		xform->ec.pkey.data = vec.eddsa.pkey.val;
+		xform->ec.pkey.length = vec.eddsa.pkey.len;
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	case FIPS_TEST_ASYM_SIGVER:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_VERIFY)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
+			return -EPERM;
+		}
+
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	default:
+		break;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 {
@@ -1610,6 +1743,27 @@ prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_edfpm_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 get_writeback_data(struct fips_val *val)
 {
@@ -1709,7 +1863,9 @@ fips_run_asym_test(void)
 	struct rte_crypto_op *deqd_op;
 	int ret;
 
-	if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != FIPS_TEST_ALGO_ECDSA) {
+	if (info.op == FIPS_TEST_ASYM_KEYGEN &&
+		(info.algo != FIPS_TEST_ALGO_ECDSA &&
+		 info.algo != FIPS_TEST_ALGO_EDDSA)) {
 		RTE_SET_USED(asym);
 		ret = 0;
 		goto exit;
@@ -1758,53 +1914,140 @@ fips_run_test(void)
 {
 	int ret;
 
-	env.op = env.sym.op;
-	if (env.is_asym_test) {
-		if (info.op == FIPS_TEST_ASYM_KEYGEN &&
-			info.algo == FIPS_TEST_ALGO_ECDSA) {
-			env.op = env.asym.op;
+	env.op = NULL;
+	if (!env.is_asym_test) {
+		env.op = env.sym.op;
+		return fips_run_sym_test();
+	}
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (info.algo == FIPS_TEST_ALGO_ECDSA) {
 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
 			test_ops.prepare_asym_op = prepare_ecfpm_op;
-			ret = fips_run_asym_test();
-			if (ret < 0)
-				return ret;
-
 			info.interim_info.ecdsa_data.pubkey_gen = 0;
-			return ret;
+
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA) {
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			info.interim_info.eddsa_data.pubkey_gen = 0;
 		}
 
-		vec.cipher_auth.digest.len = parse_test_sha_hash_size(
-						info.interim_info.rsa_data.auth);
+		env.op = env.asym.op;
+		return fips_run_asym_test();
+	}
+
+	if (info.algo == FIPS_TEST_ALGO_ECDSA) {
+		vec.cipher_auth.digest.len =
+			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
 		test_ops.prepare_sym_xform = prepare_sha_xform;
 		test_ops.prepare_sym_op = prepare_auth_op;
+
+		env.op = env.sym.op;
 		ret = fips_run_sym_test();
 		if (ret < 0)
 			return ret;
-	} else {
-		return fips_run_sym_test();
 	}
 
 	env.op = env.asym.op;
-	if (info.op == FIPS_TEST_ASYM_SIGGEN &&
-		info.algo == FIPS_TEST_ALGO_ECDSA &&
-		info.interim_info.ecdsa_data.pubkey_gen == 1) {
-		fips_prepare_asym_xform_t ecdsa_xform;
-		fips_prepare_op_t ecdsa_op;
-
-		ecdsa_xform = test_ops.prepare_asym_xform;
-		ecdsa_op = test_ops.prepare_asym_op;
-		info.op = FIPS_TEST_ASYM_KEYGEN;
-		test_ops.prepare_asym_xform = prepare_ecfpm_xform;
-		test_ops.prepare_asym_op = prepare_ecfpm_op;
-		ret = fips_run_asym_test();
-		if (ret < 0)
-			return ret;
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		fips_prepare_asym_xform_t old_xform;
+		fips_prepare_op_t old_op;
+
+		old_xform = test_ops.prepare_asym_xform;
+		old_op = test_ops.prepare_asym_op;
+
+		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
+		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
+			test_ops.prepare_asym_op = prepare_ecfpm_op;
 
-		info.post_interim_writeback(NULL);
-		info.interim_info.ecdsa_data.pubkey_gen = 0;
+			ret = fips_run_asym_test();
+			if (ret < 0)
+				return ret;
+
+			info.post_interim_writeback(NULL);
+			info.interim_info.ecdsa_data.pubkey_gen = 0;
 
-		test_ops.prepare_asym_xform = ecdsa_xform;
-		test_ops.prepare_asym_op = ecdsa_op;
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
+				   info.interim_info.eddsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+
+			const struct rte_cryptodev_asymmetric_xform_capability *cap;
+			struct rte_cryptodev_asym_capability_idx cap_idx;
+
+			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+			if (!cap) {
+				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+						env.dev_id);
+				return -EINVAL;
+			}
+
+			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
+				ret = fips_run_asym_test();
+				if (ret < 0)
+					return ret;
+			} else {
+				/* Below is only a workaround by using known keys. */
+				struct rte_crypto_asym_xform xform = {0};
+
+				prepare_edfpm_xform(&xform);
+				prepare_edfpm_op();
+				uint8_t pkey25519[] = {
+					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+				};
+				uint8_t q25519[] = {
+					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+				};
+				uint8_t pkey448[] = {
+					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+					0x01
+				};
+				uint8_t q448[] = {
+					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+					0x00
+				};
+				if (info.interim_info.eddsa_data.curve_id ==
+					RTE_CRYPTO_EC_GROUP_ED25519) {
+					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
+					vec.eddsa.q.len = 32;
+				} else {
+					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
+					vec.eddsa.q.len = 32;
+				}
+			}
+			info.post_interim_writeback(NULL);
+			info.interim_info.eddsa_data.pubkey_gen = 0;
+
+		}
+
+		test_ops.prepare_asym_xform = old_xform;
+		test_ops.prepare_asym_op = old_op;
 		info.op = FIPS_TEST_ASYM_SIGGEN;
 		ret = fips_run_asym_test();
 	} else {
@@ -2536,6 +2779,17 @@ init_test_ops(void)
 			test_ops.test = fips_generic_test;
 		}
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.test = fips_generic_test;
+		} else {
+			test_ops.prepare_asym_op = prepare_eddsa_op;
+			test_ops.prepare_asym_xform = prepare_eddsa_xform;
+			test_ops.test = fips_generic_test;
+		}
+		break;
 	default:
 		if (strstr(info.file_name, "TECB") ||
 				strstr(info.file_name, "TCBC")) {
@@ -2719,6 +2973,9 @@ fips_test_one_test_group(void)
 	case FIPS_TEST_ALGO_ECDSA:
 		ret = parse_test_ecdsa_json_init();
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		ret = parse_test_eddsa_json_init();
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build
index 34d3c7c8ca..7d4e440c6c 100644
--- a/examples/fips_validation/meson.build
+++ b/examples/fips_validation/meson.build
@@ -20,6 +20,7 @@ sources = files(
         'fips_validation_xts.c',
         'fips_validation_rsa.c',
         'fips_validation_ecdsa.c',
+        'fips_validation_eddsa.c',
         'fips_dev_self_test.c',
         'main.c',
 )
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v3 6/6] app/crypto-perf: support EDDSA
  2024-09-20 13:09     ` [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                         ` (3 preceding siblings ...)
  2024-09-20 13:09       ` [PATCH v3 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
@ 2024-09-20 13:09       ` Gowrishankar Muthukrishnan
  2024-10-03  6:42         ` Akhil Goyal
  2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  5 siblings, 1 reply; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-09-20 13:09 UTC (permalink / raw)
  To: dev, Brian Dooley
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Added support for EDDSA 25519 curve SIGN and VERIFY operations.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test-crypto-perf/cperf_ops.c             | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_options.h         |  2 +
 app/test-crypto-perf/cperf_options_parsing.c |  9 +++-
 app/test-crypto-perf/cperf_test_common.c     |  1 +
 app/test-crypto-perf/cperf_test_vectors.c    | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_test_vectors.h    | 10 ++++
 app/test-crypto-perf/main.c                  | 13 +++++
 doc/guides/tools/cryptoperf.rst              |  1 +
 8 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index f139ec5331..220c3acac7 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -67,6 +67,36 @@ cperf_set_ops_asym_ecdsa(struct rte_crypto_op **ops,
 	}
 }
 
+static void
+cperf_set_ops_asym_eddsa(struct rte_crypto_op **ops,
+		   uint32_t src_buf_offset __rte_unused,
+		   uint32_t dst_buf_offset __rte_unused, uint16_t nb_ops,
+		   void *sess,
+		   const struct cperf_options *options,
+		   const struct cperf_test_vector *test_vector __rte_unused,
+		   uint16_t iv_offset __rte_unused,
+		   uint32_t *imix_idx __rte_unused,
+		   uint64_t *tsc_start __rte_unused)
+{
+	uint16_t i;
+
+	for (i = 0; i < nb_ops; i++) {
+		struct rte_crypto_asym_op *asym_op = ops[i]->asym;
+
+		ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		rte_crypto_op_attach_asym_session(ops[i], sess);
+
+		asym_op->eddsa.op_type = options->asym_op_type;
+		asym_op->eddsa.message.data = options->eddsa_data->message.data;
+		asym_op->eddsa.message.length = options->eddsa_data->message.length;
+
+		asym_op->eddsa.instance = options->eddsa_data->instance;
+
+		asym_op->eddsa.sign.data = options->eddsa_data->sign.data;
+		asym_op->eddsa.sign.length = options->eddsa_data->sign.length;
+	}
+}
+
 static void
 cperf_set_ops_asym_sm2(struct rte_crypto_op **ops,
 		   uint32_t src_buf_offset __rte_unused,
@@ -1031,6 +1061,25 @@ cperf_create_session(struct rte_mempool *sess_mp,
 		return asym_sess;
 	}
 
+	if (options->op_type == CPERF_ASYM_ED25519) {
+		xform.next = NULL;
+		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		xform.ec.curve_id = options->eddsa_data->curve;
+		xform.ec.pkey.data = options->eddsa_data->pkey.data;
+		xform.ec.pkey.length = options->eddsa_data->pkey.length;
+		xform.ec.q.x.data = options->eddsa_data->pubkey.data;
+		xform.ec.q.x.length = options->eddsa_data->pubkey.length;
+
+		ret = rte_cryptodev_asym_session_create(dev_id, &xform,
+				sess_mp, &asym_sess);
+		if (ret < 0) {
+			RTE_LOG(ERR, USER1, "EDDSA Asym session create failed\n");
+			return NULL;
+		}
+
+		return asym_sess;
+	}
+
 	if (options->op_type == CPERF_ASYM_SM2) {
 		xform.next = NULL;
 		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
@@ -1354,6 +1403,9 @@ cperf_get_op_functions(const struct cperf_options *options,
 	case CPERF_ASYM_SECP256R1:
 		op_fns->populate_ops = cperf_set_ops_asym_ecdsa;
 		break;
+	case CPERF_ASYM_ED25519:
+		op_fns->populate_ops = cperf_set_ops_asym_eddsa;
+		break;
 	case CPERF_ASYM_SM2:
 		op_fns->populate_ops = cperf_set_ops_asym_sm2;
 		break;
diff --git a/app/test-crypto-perf/cperf_options.h b/app/test-crypto-perf/cperf_options.h
index 131ecfdffb..dbc9f5a97b 100644
--- a/app/test-crypto-perf/cperf_options.h
+++ b/app/test-crypto-perf/cperf_options.h
@@ -89,6 +89,7 @@ enum cperf_op_type {
 	CPERF_IPSEC,
 	CPERF_ASYM_MODEX,
 	CPERF_ASYM_SECP256R1,
+	CPERF_ASYM_ED25519,
 	CPERF_ASYM_SM2,
 	CPERF_TLS,
 };
@@ -169,6 +170,7 @@ struct cperf_options {
 	struct cperf_modex_test_data *modex_data;
 	uint16_t modex_len;
 	struct cperf_ecdsa_test_data *secp256r1_data;
+	struct cperf_eddsa_test_data *eddsa_data;
 	struct cperf_sm2_test_data *sm2_data;
 	enum rte_crypto_asym_op_type asym_op_type;
 	enum rte_crypto_auth_algorithm asym_hash_alg;
diff --git a/app/test-crypto-perf/cperf_options_parsing.c b/app/test-crypto-perf/cperf_options_parsing.c
index c91fcf0479..59ea66c06d 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -38,7 +38,7 @@ usage(char *progname)
 		" --desc-nb N: set number of descriptors for each crypto device\n"
 		" --devtype TYPE: set crypto device type to use\n"
 		" --optype cipher-only / auth-only / cipher-then-auth / auth-then-cipher /\n"
-		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / sm2 / tls-record : set operation type\n"
+		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / eddsa / sm2 / tls-record : set operation type\n"
 		" --sessionless: enable session-less crypto operations\n"
 		" --shared-session: share 1 session across all queue pairs on crypto device\n"
 		" --out-of-place: enable out-of-place crypto operations\n"
@@ -489,6 +489,10 @@ parse_op_type(struct cperf_options *opts, const char *arg)
 			cperf_op_type_strs[CPERF_ASYM_SECP256R1],
 			CPERF_ASYM_SECP256R1
 		},
+		{
+			cperf_op_type_strs[CPERF_ASYM_ED25519],
+			CPERF_ASYM_ED25519
+		},
 		{
 			cperf_op_type_strs[CPERF_ASYM_SM2],
 			CPERF_ASYM_SM2
@@ -1080,6 +1084,7 @@ cperf_options_default(struct cperf_options *opts)
 	opts->modex_data = (struct cperf_modex_test_data *)&modex_perf_data[0];
 
 	opts->secp256r1_data = &secp256r1_perf_data;
+	opts->eddsa_data = &ed25519_perf_data;
 	opts->sm2_data = &sm2_perf_data;
 	opts->asym_op_type = RTE_CRYPTO_ASYM_OP_SIGN;
 }
@@ -1513,7 +1518,7 @@ cperf_options_dump(struct cperf_options *opts)
 	printf("#\n");
 	printf("# number of queue pairs per device: %u\n", opts->nb_qps);
 	printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
-	if (opts->op_type == CPERF_ASYM_SM2 || opts->op_type == CPERF_ASYM_SECP256R1)
+	if (cperf_is_asym_test(opts))
 		printf("# asym operation type: %s\n",
 				rte_crypto_asym_op_strings[opts->asym_op_type]);
 	printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
diff --git a/app/test-crypto-perf/cperf_test_common.c b/app/test-crypto-perf/cperf_test_common.c
index 33bee43c93..ae06ccfc76 100644
--- a/app/test-crypto-perf/cperf_test_common.c
+++ b/app/test-crypto-perf/cperf_test_common.c
@@ -307,6 +307,7 @@ cperf_is_asym_test(const struct cperf_options *options)
 {
 	if (options->op_type == CPERF_ASYM_MODEX ||
 	    options->op_type == CPERF_ASYM_SECP256R1 ||
+		options->op_type == CPERF_ASYM_ED25519 ||
 	    options->op_type == CPERF_ASYM_SM2)
 		return true;
 
diff --git a/app/test-crypto-perf/cperf_test_vectors.c b/app/test-crypto-perf/cperf_test_vectors.c
index 19c56b46bd..64720d50c3 100644
--- a/app/test-crypto-perf/cperf_test_vectors.c
+++ b/app/test-crypto-perf/cperf_test_vectors.c
@@ -853,6 +853,35 @@ static uint8_t secp256r1_message[] = {
 	0xdb, 0xc4, 0xe7, 0xa6, 0xa1, 0x33, 0xec, 0x56
 };
 
+static uint8_t ed25519_pkey[] = {
+	0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+	0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+	0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+	0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+};
+
+static uint8_t ed25519_pubkey[] = {
+	0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+	0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+	0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+	0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+};
+
+static uint8_t ed25519_sign[] = {
+	0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+	0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+	0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+	0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+	0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+	0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+	0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+	0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+};
+
+static uint8_t ed25519_message[] = {
+	0x72
+};
+
 static uint8_t fp256_pkey[] = {
 	0x77, 0x84, 0x35, 0x65, 0x4c, 0x7a, 0x6d, 0xb1,
 	0x1e, 0x63, 0x0b, 0x41, 0x97, 0x36, 0x04, 0xf4,
@@ -1365,6 +1394,29 @@ cperf_ecdsa_test_data secp256r1_perf_data = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP256R1
 };
 
+/** EDDSA 25519 elliptic curve test params */
+struct
+cperf_eddsa_test_data ed25519_perf_data = {
+	.pubkey = {
+		.data = ed25519_pubkey,
+		.length = sizeof(ed25519_pubkey),
+	},
+	.pkey = {
+		.data = ed25519_pkey,
+		.length = sizeof(ed25519_pkey),
+	},
+	.sign = {
+		.data = ed25519_sign,
+		.length = sizeof(ed25519_sign),
+	},
+	.message = {
+		.data = ed25519_message,
+		.length = sizeof(ed25519_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+};
+
 /** SM2 Fp256 elliptic curve test params */
 struct
 cperf_sm2_test_data sm2_perf_data = {
diff --git a/app/test-crypto-perf/cperf_test_vectors.h b/app/test-crypto-perf/cperf_test_vectors.h
index d46cbbc2c8..f83a17c176 100644
--- a/app/test-crypto-perf/cperf_test_vectors.h
+++ b/app/test-crypto-perf/cperf_test_vectors.h
@@ -118,6 +118,15 @@ struct cperf_ecdsa_test_data {
 	int curve;
 };
 
+struct cperf_eddsa_test_data {
+	rte_crypto_param pubkey;
+	rte_crypto_param pkey;
+	rte_crypto_param sign;
+	rte_crypto_param message;
+	int curve;
+	int instance;
+};
+
 struct cperf_sm2_test_data {
 	rte_crypto_param pubkey_qx;
 	rte_crypto_param pubkey_qy;
@@ -147,6 +156,7 @@ extern uint8_t digest[2048];
 
 extern struct cperf_modex_test_data modex_perf_data[10];
 extern struct cperf_ecdsa_test_data secp256r1_perf_data;
+extern struct cperf_eddsa_test_data ed25519_perf_data;
 extern struct cperf_sm2_test_data sm2_perf_data;
 
 #endif
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 75810dbf0b..d93b30bcaa 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -46,6 +46,7 @@ const char *cperf_op_type_strs[] = {
 	[CPERF_IPSEC] = "ipsec",
 	[CPERF_ASYM_MODEX] = "modex",
 	[CPERF_ASYM_SECP256R1] = "ecdsa_p256r1",
+	[CPERF_ASYM_ED25519] = "eddsa_25519",
 	[CPERF_ASYM_SM2] = "sm2",
 	[CPERF_TLS] = "tls-record"
 };
@@ -227,6 +228,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
 
 		switch (opts->op_type) {
 		case CPERF_ASYM_SECP256R1:
+		case CPERF_ASYM_ED25519:
 		case CPERF_ASYM_SM2:
 		case CPERF_ASYM_MODEX:
 			conf.ff_disable |= (RTE_CRYPTODEV_FF_SECURITY |
@@ -382,6 +384,17 @@ cperf_verify_devices_capabilities(struct cperf_options *opts,
 			}
 		}
 
+		if (opts->op_type == CPERF_ASYM_ED25519) {
+			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
+			if (asym_capability == NULL)
+				return -1;
+
+			if (!rte_cryptodev_asym_xform_capability_check_optype(asym_capability,
+						opts->asym_op_type))
+				return -1;
+		}
+
 		if (opts->op_type == CPERF_ASYM_SM2) {
 			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_SM2;
 			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst
index 0510a3bb89..9a20a73f03 100644
--- a/doc/guides/tools/cryptoperf.rst
+++ b/doc/guides/tools/cryptoperf.rst
@@ -176,6 +176,7 @@ The following are the application command-line options:
            docsis
            modex
            ecdsa_p256r1
+           eddsa_25519
            sm2
            ipsec
            tls-record
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v3 2/6] crypto/openssl: support EDDSA
  2024-09-20 13:09       ` [PATCH v3 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
@ 2024-09-20 14:36         ` Akhil Goyal
  0 siblings, 0 replies; 47+ messages in thread
From: Akhil Goyal @ 2024-09-20 14:36 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev, Kai Ji
  Cc: Anoob Joseph, bruce.richardson, Jerin Jacob, fanzhang.oss,
	arkadiuszx.kusztal, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Gowrishankar Muthukrishnan

> Subject: [PATCH v3 2/6] crypto/openssl: support EDDSA
> 
> Support EDDSA crypto algorithm in OpenSSL PMD.
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> ---
>  drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
>  drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
>  drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
>  3 files changed, 367 insertions(+)
Update doc and add release notes.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v3 6/6] app/crypto-perf: support EDDSA
  2024-09-20 13:09       ` [PATCH v3 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
@ 2024-10-03  6:42         ` Akhil Goyal
  0 siblings, 0 replies; 47+ messages in thread
From: Akhil Goyal @ 2024-10-03  6:42 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev, Brian Dooley
  Cc: Anoob Joseph, bruce.richardson, Jerin Jacob, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Gowrishankar Muthukrishnan

Hi Gowri,

Can you fix the CI issues reported.

http://mails.dpdk.org/archives/test-report/2024-September/798079.html

openssl asym autotest is also failing.
http://mails.dpdk.org/archives/test-report/2024-September/798209.html



> Subject: [PATCH v3 6/6] app/crypto-perf: support EDDSA
> 
> Added support for EDDSA 25519 curve SIGN and VERIFY operations.
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> ---
>  app/test-crypto-perf/cperf_ops.c             | 52 ++++++++++++++++++++
>  app/test-crypto-perf/cperf_options.h         |  2 +
>  app/test-crypto-perf/cperf_options_parsing.c |  9 +++-
>  app/test-crypto-perf/cperf_test_common.c     |  1 +
>  app/test-crypto-perf/cperf_test_vectors.c    | 52 ++++++++++++++++++++
>  app/test-crypto-perf/cperf_test_vectors.h    | 10 ++++
>  app/test-crypto-perf/main.c                  | 13 +++++
>  doc/guides/tools/cryptoperf.rst              |  1 +
>  8 files changed, 138 insertions(+), 2 deletions(-)

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-09-20 13:09     ` [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                         ` (4 preceding siblings ...)
  2024-09-20 13:09       ` [PATCH v3 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
@ 2024-10-03 17:56       ` Gowrishankar Muthukrishnan
  2024-10-03 17:56         ` [PATCH v4 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
                           ` (5 more replies)
  5 siblings, 6 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-03 17:56 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, jerinj, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Gowrishankar Muthukrishnan

Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
https://datatracker.ietf.org/doc/html/rfc8032

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
 lib/cryptodev/rte_crypto_asym.h            | 47 ++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index f411d4bab7..3073753911 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -130,6 +130,7 @@ ECDSA                   =
 ECPM                    =
 ECDH                    =
 SM2                     =
+EDDSA                   =
 
 ;
 ; Supported Operating systems of a default crypto driver.
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 2b513bbf82..dd636ba5ef 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -927,7 +927,7 @@ Asymmetric Cryptography
 The cryptodev library currently provides support for the following asymmetric
 Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman and
 Elliptic Curve Diffie-Hellman public and/or private key generation and shared
-secret compute, DSA Signature generation and verification.
+secret compute, DSA and EdDSA Signature generation and verification.
 
 Session and Session Management
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index 39d3da3952..fe4194c184 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -49,6 +49,10 @@ rte_crypto_asym_op_strings[];
  * and if the flag is not set, shared secret will be padded to the left with
  * zeros to the size of the underlying algorithm (default)
  */
+#define RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED		RTE_BIT32(2)
+/**<
+ * Flag to denote public key will be returned in compressed form
+ */
 
 /**
  * List of elliptic curves. This enum aligns with
@@ -65,9 +69,22 @@ enum rte_crypto_curve_id {
 	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
 	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
 	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
+	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
+	RTE_CRYPTO_EC_GROUP_ED448     = 30,
 	RTE_CRYPTO_EC_GROUP_SM2       = 41,
 };
 
+/**
+ * List of Edwards curve instances as per RFC 8032 (Section 5).
+ */
+enum rte_crypto_edward_instance {
+	RTE_CRYPTO_EDCURVE_25519,
+	RTE_CRYPTO_EDCURVE_25519CTX,
+	RTE_CRYPTO_EDCURVE_25519PH,
+	RTE_CRYPTO_EDCURVE_448,
+	RTE_CRYPTO_EDCURVE_448PH
+};
+
 /**
  * Asymmetric crypto transformation types.
  * Each xform type maps to one asymmetric algorithm
@@ -119,6 +136,10 @@ enum rte_crypto_asym_xform_type {
 	 * Performs Encrypt, Decrypt, Sign and Verify.
 	 * Refer to rte_crypto_asym_op_type.
 	 */
+	RTE_CRYPTO_ASYM_XFORM_EDDSA,
+	/**< Edwards Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -585,6 +606,31 @@ struct rte_crypto_ecdsa_op_param {
 	 */
 };
 
+/**
+ * EdDSA operation params
+ */
+struct rte_crypto_eddsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param message;
+	/**< Input message digest to be signed or verified */
+
+	rte_crypto_param context;
+	/**< Context value for the sign op.
+	 *   Must not be empty for Ed25519ctx instance.
+	 */
+
+	enum rte_crypto_edward_instance instance;
+	/**< Type of Edwards curve. */
+
+	rte_crypto_uint sign;
+	/**< Edward curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Structure for EC point multiplication operation param
  */
@@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_ecdsa_op_param ecdsa;
 		struct rte_crypto_ecpm_op_param ecpm;
 		struct rte_crypto_sm2_op_param sm2;
+		struct rte_crypto_eddsa_op_param eddsa;
 	};
 	uint16_t flags;
 	/**<
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v4 2/6] crypto/openssl: support EDDSA
  2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
@ 2024-10-03 17:56         ` Gowrishankar Muthukrishnan
  2024-10-03 17:56         ` [PATCH v4 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
                           ` (4 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-03 17:56 UTC (permalink / raw)
  To: dev, Kai Ji
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in OpenSSL PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
v4:
 - Restrict eddsa session creation only for openssl 3.3.0 and above.
   Lower v3.x may support pure instances, but not context and prehash
   instances.
   
---
 doc/guides/cryptodevs/features/openssl.ini   |   1 +
 drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
 drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
 4 files changed, 368 insertions(+)

diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index b64c8ec4a5..0540c075dc 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -66,6 +66,7 @@ Modular Exponentiation = Y
 Modular Inversion = Y
 Diffie-hellman = Y
 SM2 = Y
+EDDSA = Y
 
 ;
 ; Supported Operating systems of the 'openssl' crypto driver.
diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index a50e4d4918..a613988dbe 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -231,10 +231,23 @@ struct __rte_cache_aligned openssl_asym_session {
 #endif
 		} s;
 		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			EC_GROUP * group;
+			BIGNUM *priv_key;
+#endif
+		} ec;
+		struct {
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 			OSSL_PARAM * params;
 #endif
 		} sm2;
+		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			OSSL_PARAM * params;
+#endif
+		} eddsa;
 	} u;
 };
 /** Set and validate OPENSSL crypto session parameters */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 101111e85b..cbc10b27d4 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2849,6 +2849,45 @@ process_openssl_rsa_op_evp(struct rte_crypto_op *cop,
 
 }
 
+static int
+process_openssl_ecfpm_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	const EC_GROUP *ecgrp = sess->u.ec.group;
+	EC_POINT *ecpt = NULL;
+	BN_CTX *ctx = NULL;
+	BIGNUM *n = NULL;
+	int ret = -1;
+
+	n = BN_bin2bn((const unsigned char *)
+			cop->asym->ecpm.scalar.data,
+			cop->asym->ecpm.scalar.length,
+			BN_new());
+
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto err_ecfpm;
+
+	if (!EC_POINT_mul(ecgrp, ecpt, n, NULL, NULL, ctx))
+		goto err_ecfpm;
+
+	if (cop->asym->flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED) {
+		unsigned char *buf = cop->asym->ecpm.r.x.data;
+		size_t sz;
+
+		sz = EC_POINT_point2oct(ecgrp, ecpt, POINT_CONVERSION_COMPRESSED, buf, 0, ctx);
+		if (!sz)
+			goto err_ecfpm;
+
+		cop->asym->ecpm.r.x.length = sz;
+	}
+
+err_ecfpm:
+	BN_CTX_free(ctx);
+	BN_free(n);
+	return ret;
+}
+
 static int
 process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3074,6 +3113,158 @@ process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 	return ret;
 }
 
+static int
+process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	static const char * const instance[] = {"Ed25519", "Ed25519ctx", "Ed25519ph",
+						"Ed448", "Ed448ph"};
+	EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
+	const uint8_t curve_id = sess->u.eddsa.curve_id;
+	struct rte_crypto_asym_op *op = cop->asym;
+	OSSL_PARAM *params = sess->u.eddsa.params;
+	OSSL_PARAM_BLD *iparam_bld = NULL;
+	OSSL_PARAM *iparams = NULL;
+	uint8_t signbuf[128] = {0};
+	EVP_MD_CTX *md_ctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	size_t signlen;
+	int ret = -1;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	iparam_bld = OSSL_PARAM_BLD_new();
+	if (!iparam_bld)
+		goto err_eddsa;
+
+	if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519CTX) {
+		OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-string",
+			op->eddsa.context.data, op->eddsa.context.length);
+
+	}
+
+	OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
+		instance[op->eddsa.instance], strlen(instance[op->eddsa.instance]));
+
+	iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
+	if (!iparams)
+		goto err_eddsa;
+
+	switch (op->eddsa.op_type) {
+	case RTE_CRYPTO_ASYM_OP_SIGN:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			if (!EVP_DigestSign(md_ctx, NULL, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			if (signlen > RTE_DIM(signbuf))
+				goto err_eddsa;
+
+			if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
+			op->eddsa.sign.length = signlen;
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_VERIFY:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			signlen = op->eddsa.sign.length;
+			memcpy(&signbuf[0], op->eddsa.sign.data, op->eddsa.sign.length);
+
+			ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op->eddsa.message.data,
+					op->eddsa.message.length);
+			if (ret == 0)
+				goto err_eddsa;
+		}
+		break;
+	default:
+		/* allow ops with invalid args to be pushed to
+		 * completion queue
+		 */
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		goto err_eddsa;
+	}
+
+	ret = 0;
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+err_eddsa:
+	OSSL_PARAM_BLD_free(iparam_bld);
+
+	if (sctx)
+		EVP_PKEY_CTX_free(sctx);
+
+	if (cctx)
+		EVP_PKEY_CTX_free(cctx);
+
+	if (pkey)
+		EVP_PKEY_free(pkey);
+
+	return ret;
+}
 #else
 static int
 process_openssl_rsa_op(struct rte_crypto_op *cop,
@@ -3174,6 +3365,15 @@ process_openssl_rsa_op(struct rte_crypto_op *cop,
 	return 0;
 }
 
+static int
+process_openssl_ecfpm_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
+
 static int
 process_openssl_sm2_op(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3182,6 +3382,15 @@ process_openssl_sm2_op(struct rte_crypto_op *cop,
 	RTE_SET_USED(sess);
 	return -ENOTSUP;
 }
+
+static int
+process_openssl_eddsa_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
 #endif
 
 static int
@@ -3230,6 +3439,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 				process_openssl_dsa_verify_op(op, sess);
 		else
 			op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_ecfpm_op_evp(op, sess);
+#else
+		retval = process_openssl_ecfpm_op(op, sess);
 #endif
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
@@ -3237,6 +3453,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 		retval = process_openssl_sm2_op_evp(op, sess);
 #else
 		retval = process_openssl_sm2_op(op, sess);
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_eddsa_op_evp(op, sess);
+#else
+		retval = process_openssl_eddsa_op(op, sess);
 #endif
 		break;
 	default:
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index 1bbb855a59..5e95828211 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -593,6 +593,16 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		},
 		}
 	},
+	{	/* ECFPM */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM,
+				.op_types = 0
+				}
+			}
+		}
+	},
 	{	/* SM2 */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
@@ -610,6 +620,20 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		}
 		}
 	},
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types =
+				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
+				 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+			}
+		}
+		}
+	},
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1356,6 +1380,47 @@ static int openssl_set_asym_session_parameters(
 		BN_free(pub_key);
 		return -1;
 	}
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		EC_GROUP *ecgrp = NULL;
+
+		asym_session->xfrm_type = xform->xform_type;
+
+		switch (xform->ec.curve_id) {
+		case RTE_CRYPTO_EC_GROUP_SECP192R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp192k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP224R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp224r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP256R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP384R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp384r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP521R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp521r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED25519:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED25519);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED448:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED448);
+			break;
+		default:
+			break;
+		}
+
+		asym_session->u.ec.curve_id = xform->ec.curve_id;
+		asym_session->u.ec.group = ecgrp;
+		break;
+#else
+		OPENSSL_LOG(WARNING, "ECFPM unsupported for OpenSSL Version < 3.0");
+		return -ENOTSUP;
+#endif
+	}
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 	{
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
@@ -1440,6 +1505,66 @@ static int openssl_set_asym_session_parameters(
 #else
 		OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL Version < 3.0");
 		return -ENOTSUP;
+#endif
+	}
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+		OSSL_PARAM_BLD *param_bld = NULL;
+		OSSL_PARAM *params = NULL;
+		int ret = -1;
+
+		asym_session->u.eddsa.curve_id = xform->ec.curve_id;
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+			  OSSL_PKEY_PARAM_GROUP_NAME, "ED25519", sizeof("ED25519"));
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PRIV_KEY,
+				xform->ec.pkey.data, xform->ec.pkey.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
+				xform->ec.q.x.data, xform->ec.q.x.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		params = OSSL_PARAM_BLD_to_param(param_bld);
+		if (!params) {
+			OPENSSL_LOG(ERR, "failed to push params\n");
+			goto err_eddsa;
+		}
+
+		asym_session->u.eddsa.params = params;
+		OSSL_PARAM_BLD_free(param_bld);
+
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		break;
+err_eddsa:
+		if (param_bld)
+			OSSL_PARAM_BLD_free(param_bld);
+
+		if (asym_session->u.eddsa.params)
+			OSSL_PARAM_free(asym_session->u.eddsa.params);
+
+		return -1;
+#else
+		OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL Version < 3.3");
+		return -ENOTSUP;
 #endif
 	}
 	default:
@@ -1538,6 +1663,12 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 		OSSL_PARAM_free(sess->u.sm2.params);
 #endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+		OSSL_PARAM_free(sess->u.eddsa.params);
+#endif
+		break;
 	default:
 		break;
 	}
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v4 3/6] crypto/cnxk: support EDDSA
  2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-10-03 17:56         ` [PATCH v4 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
@ 2024-10-03 17:56         ` Gowrishankar Muthukrishnan
  2024-10-03 17:56         ` [PATCH v4 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
                           ` (3 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-03 17:56 UTC (permalink / raw)
  To: dev, Ankur Dwivedi, Anoob Joseph, Tejasree Kondoj,
	Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
	Harman Kalra
  Cc: bruce.richardson, jerinj, fanzhang.oss, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Akhil Goyal, Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in CNXK PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/cn10k.ini      |   1 +
 drivers/common/cnxk/hw/cpt.h                  |   3 +-
 drivers/common/cnxk/roc_ae.c                  |  52 +-
 drivers/common/cnxk/roc_ae.h                  |  10 +
 drivers/common/cnxk/roc_ae_fpm_tables.c       | 580 +++++++++++++++++-
 drivers/crypto/cnxk/cnxk_ae.h                 | 455 +++++++++++++-
 drivers/crypto/cnxk/cnxk_cryptodev.h          |   2 +-
 .../crypto/cnxk/cnxk_cryptodev_capabilities.c |  19 +
 drivers/crypto/cnxk/cnxk_cryptodev_ops.c      |   2 +-
 drivers/crypto/cnxk/cnxk_cryptodev_ops.h      |   2 +
 10 files changed, 1112 insertions(+), 14 deletions(-)

diff --git a/doc/guides/cryptodevs/features/cn10k.ini b/doc/guides/cryptodevs/features/cn10k.ini
index 39f4b56b9f..bb7d265005 100644
--- a/doc/guides/cryptodevs/features/cn10k.ini
+++ b/doc/guides/cryptodevs/features/cn10k.ini
@@ -107,6 +107,7 @@ ECDH                    = Y
 ECDSA                   = Y
 ECPM                    = Y
 SM2                     = Y
+EDDSA                   = Y
 
 ;
 ; Supported Operating systems of the 'cn10k' crypto driver.
diff --git a/drivers/common/cnxk/hw/cpt.h b/drivers/common/cnxk/hw/cpt.h
index 2620965606..47df3fbf9f 100644
--- a/drivers/common/cnxk/hw/cpt.h
+++ b/drivers/common/cnxk/hw/cpt.h
@@ -81,7 +81,8 @@ union cpt_eng_caps {
 		uint64_t __io sm2 : 1;
 		uint64_t __io pdcp_chain_zuc256 : 1;
 		uint64_t __io tls : 1;
-		uint64_t __io reserved_39_63 : 25;
+		uint64_t __io eddsa : 1;
+		uint64_t __io reserved_40_63 : 24;
 	};
 };
 
diff --git a/drivers/common/cnxk/roc_ae.c b/drivers/common/cnxk/roc_ae.c
index 7ef0efe2b3..2c563c30de 100644
--- a/drivers/common/cnxk/roc_ae.c
+++ b/drivers/common/cnxk/roc_ae.c
@@ -179,7 +179,57 @@ const struct roc_ae_ec_group ae_ec_grp[ROC_AE_EC_ID_PMAX] = {
 				    0xAB, 0x8F, 0x92, 0xDD, 0xBC, 0xBD, 0x41,
 				    0x4D, 0x94, 0x0E, 0x93},
 			   .length = 32},
-	}};
+	},
+	{
+		.prime = {.data = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0x7F},
+			  .length = 32},
+		.order = {.data = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12,
+				   0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9,
+				   0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x10},
+			  .length = 32},
+		.consta = {.data = {0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb,
+				    0x75, 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a,
+				    0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79,
+				    0x40, 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b,
+				    0xee, 0x6c, 0x03, 0x52},
+			   .length = 32},
+	},
+	{
+		.prime = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			  .length = 56},
+		.order = {.data = {0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78,
+				   0x23, 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2,
+				   0x6c, 0x21, 0x90, 0x36, 0xd6, 0xae, 0x49,
+				   0xdb, 0x4e, 0xc4, 0xe9, 0x23, 0xca, 0x7c,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f},
+			  .length = 56},
+		.consta = {.data = {0x56, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			   .length = 56},
+	},
+};
 
 int
 roc_ae_ec_grp_get(struct roc_ae_ec_group **tbl)
diff --git a/drivers/common/cnxk/roc_ae.h b/drivers/common/cnxk/roc_ae.h
index 7886b9d107..6595f22754 100644
--- a/drivers/common/cnxk/roc_ae.h
+++ b/drivers/common/cnxk/roc_ae.h
@@ -12,6 +12,7 @@
 #define ROC_AE_MAJOR_OP_MODEX	     0x03
 #define ROC_AE_MAJOR_OP_EC	     0x04
 #define ROC_AE_MAJOR_OP_ECC	     0x05
+#define ROC_AE_MAJOR_OP_EDDSA	     0x0A
 #define ROC_AE_MINOR_OP_RANDOM	     0x00
 #define ROC_AE_MINOR_OP_MODEX	     0x01
 #define ROC_AE_MINOR_OP_PKCS_ENC     0x02
@@ -23,6 +24,9 @@
 #define ROC_AE_MINOR_OP_EC_VERIFY    0x02
 #define ROC_AE_MINOR_OP_ECC_UMP	     0x03
 #define ROC_AE_MINOR_OP_ECC_FPM	     0x04
+#define ROC_AE_MINOR_OP_ED_SIGN      0x00
+#define ROC_AE_MINOR_OP_ED_VERIFY    0x01
+#define ROC_AE_MINOR_OP_ED_KEYGEN    0x02
 
 /**
  * Enumeration roc_ae_ec_id
@@ -39,6 +43,8 @@ typedef enum {
 	ROC_AE_EC_ID_P320 = 6,
 	ROC_AE_EC_ID_P512 = 7,
 	ROC_AE_EC_ID_SM2  = 8,
+	ROC_AE_EC_ID_ED25519 = 9,
+	ROC_AE_EC_ID_ED448 = 10,
 	ROC_AE_EC_ID_PMAX
 } roc_ae_ec_id;
 
@@ -47,6 +53,10 @@ typedef enum {
 #define ROC_AE_EC_PARAM1_SM2       (1 << 7)
 #define ROC_AE_EC_PARAM1_NIST      (0 << 6)
 #define ROC_AE_EC_PARAM1_NONNIST   (1 << 6)
+#define ROC_AE_ED_PARAM1_25519     (1 << 1)
+#define ROC_AE_ED_PARAM1_448       (1 << 3)
+#define ROC_AE_ED_PARAM1_KEYGEN_BIT      4
+#define ROC_AE_EC_PARAM1_PH_BIT          5
 
 typedef enum {
 	ROC_AE_ERR_ECC_PAI = 0x0b,
diff --git a/drivers/common/cnxk/roc_ae_fpm_tables.c b/drivers/common/cnxk/roc_ae_fpm_tables.c
index 942657b56a..9dcf60ef03 100644
--- a/drivers/common/cnxk/roc_ae_fpm_tables.c
+++ b/drivers/common/cnxk/roc_ae_fpm_tables.c
@@ -21,7 +21,9 @@ typedef enum {
 	AE_FPM_P224_LEN = 2160,
 	AE_FPM_P256_LEN = 2160,
 	AE_FPM_P384_LEN = 2520,
-	AE_FPM_P521_LEN = 3240
+	AE_FPM_P521_LEN = 3240,
+	AE_FPM_ED25519_LEN = 2880,
+	AE_FPM_ED448_LEN = 3840,
 } ae_fpm_len;
 
 /* FPM table address and length */
@@ -1240,6 +1242,572 @@ const uint8_t ae_fpm_tbl_p256_sm2[AE_FPM_P256_LEN] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+const uint8_t ae_fpm_tbl_ed25519[AE_FPM_ED25519_LEN] = {
+	0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a, 0x69, 0x2c, 0xc7, 0x60,
+	0x95, 0x25, 0xa7, 0xb2, 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c,
+	0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6d, 0xde, 0x8a, 0xb3, 0xa5, 0xb7, 0xdd, 0xa3, 0x20, 0xf0, 0x9f, 0x80,
+	0x77, 0x51, 0x52, 0xf5, 0x66, 0xea, 0x4e, 0x8e, 0x64, 0xab, 0xe3, 0x7d,
+	0x67, 0x87, 0x5f, 0x0f, 0xd7, 0x8b, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x18, 0xc0, 0x0c, 0x55, 0x07, 0xed, 0xf1, 0x0d, 0x69, 0xbe, 0x61, 0x3a,
+	0x4f, 0x82, 0xd2, 0xc4, 0x3e, 0xf0, 0xa1, 0x4e, 0xf1, 0xba, 0xd8, 0xb1,
+	0x5a, 0x8a, 0x5a, 0x58, 0xbe, 0xf1, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x63, 0xce, 0x54, 0x79, 0x0e, 0x45, 0x3f, 0x73, 0xe9, 0x33, 0xff, 0xc7,
+	0xec, 0xab, 0xc7, 0x4b, 0x6b, 0x43, 0x64, 0x02, 0x45, 0xcf, 0x64, 0xfa,
+	0x1a, 0xd2, 0xdd, 0x57, 0x64, 0x55, 0xf6, 0x78, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x8c, 0x9d, 0x04, 0xac, 0x84, 0x05, 0xe0, 0xe7, 0xa5, 0x17, 0x56,
+	0x92, 0x2e, 0xbd, 0x07, 0x96, 0x72, 0x74, 0xa7, 0xd8, 0x1d, 0x8d, 0x30,
+	0x42, 0x4d, 0xa3, 0xd2, 0x15, 0xae, 0xf3, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x19, 0xcf, 0x23, 0xc1, 0x1f, 0x40, 0x15, 0x86, 0x4d, 0xd5, 0x99, 0x64,
+	0x9b, 0x94, 0x9e, 0x8e, 0x22, 0x68, 0xc6, 0xcf, 0xf4, 0xe4, 0xf9, 0xd9,
+	0x75, 0xe4, 0xce, 0xc7, 0xf1, 0xc8, 0x41, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x98, 0x8c, 0x87, 0x10, 0xcd, 0x87, 0x55, 0x95, 0x52, 0x83, 0xad, 0xc1,
+	0x83, 0x92, 0xcf, 0xa4, 0x28, 0x4a, 0x93, 0xe5, 0x21, 0x53, 0xaa, 0x3d,
+	0x33, 0x97, 0x60, 0xe6, 0xcb, 0xdc, 0xf5, 0xd4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe6, 0xf2, 0x50, 0x1e, 0x50, 0x14, 0x12, 0xd8, 0x45, 0xcc, 0xd0, 0xd4,
+	0x75, 0x78, 0xec, 0xae, 0x42, 0x10, 0x45, 0x12, 0x74, 0x2b, 0x26, 0xde,
+	0x41, 0xea, 0x80, 0x41, 0x7f, 0xb3, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x75, 0x61, 0x33, 0xad, 0x0c, 0x22, 0xe4, 0x7f, 0xd7, 0x18, 0xb3,
+	0xf9, 0xd3, 0x55, 0x9e, 0x96, 0x2d, 0xa3, 0xfa, 0x7d, 0xfb, 0x1e, 0xb6,
+	0x4e, 0xd0, 0xb6, 0x26, 0xa7, 0x32, 0x09, 0x87, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaf, 0x7f, 0xd1, 0x3e, 0xfe, 0xa5, 0xa5, 0x96, 0x3c, 0x42, 0xec, 0x0e,
+	0xef, 0x69, 0x4e, 0x62, 0xf5, 0xb9, 0xc2, 0xad, 0x65, 0x7b, 0x91, 0x6f,
+	0x25, 0x55, 0x0a, 0xc3, 0x9c, 0xfb, 0x1a, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2a, 0xf9, 0xfb, 0x16, 0x90, 0xe8, 0x72, 0x7e, 0x98, 0x92, 0x1f, 0xc5,
+	0x97, 0x96, 0xc5, 0x0c, 0x8a, 0x12, 0x0b, 0xf3, 0x98, 0xc0, 0x5f, 0x4d,
+	0x38, 0x56, 0x94, 0x41, 0xa1, 0xf5, 0xcd, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0x39, 0xdb, 0x96, 0xf7, 0x8d, 0x2e, 0x7c, 0xb1, 0xc0, 0x51, 0x3b,
+	0xa4, 0xc4, 0x55, 0x12, 0x75, 0x29, 0xd9, 0x29, 0x65, 0x02, 0x36, 0x8d,
+	0x0a, 0x97, 0xdf, 0xad, 0x58, 0xfa, 0x26, 0x19, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0x4b, 0xb5, 0xe5, 0x13, 0xa5, 0x45, 0x40, 0x2c, 0xba, 0x4d, 0x3b,
+	0x1e, 0x5f, 0x55, 0xb8, 0x04, 0xa2, 0xce, 0x24, 0x52, 0x7e, 0xb7, 0x3c,
+	0x78, 0xd9, 0x8e, 0xba, 0xc3, 0x3b, 0xd9, 0x46, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb2, 0x1d, 0x1e, 0x95, 0xfb, 0x8d, 0x9a, 0xdd, 0xdb, 0xfc, 0xa8, 0xca,
+	0x0f, 0x51, 0x54, 0x75, 0x72, 0x53, 0xc9, 0xca, 0xe4, 0x6b, 0x0a, 0x2f,
+	0x3d, 0xc4, 0xd8, 0x0a, 0x0c, 0x80, 0x9a, 0xb6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0xc6, 0x8e, 0xea, 0x63, 0xb3, 0x17, 0x45, 0x1b, 0xc9, 0x4f, 0xf2,
+	0xb9, 0xce, 0xab, 0x28, 0x84, 0x84, 0x27, 0x82, 0x6e, 0x59, 0x5d, 0x0d,
+	0x57, 0x1c, 0xd9, 0x4b, 0x55, 0xf8, 0xa2, 0xd1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x76, 0xd4, 0x7d, 0xa8, 0x8a, 0xfd, 0x34, 0xf3, 0x5e, 0xa7, 0x1b, 0x7c,
+	0x94, 0x84, 0x05, 0x81, 0x7f, 0x9d, 0x55, 0x08, 0x06, 0x03, 0x5e, 0x42,
+	0x42, 0xe8, 0x55, 0x9a, 0xac, 0x90, 0x41, 0xf2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x74, 0xd2, 0x01, 0x61, 0xc0, 0x1f, 0x88, 0x8b, 0xcb, 0xca, 0xf5, 0xd3,
+	0x63, 0x58, 0x4b, 0xbb, 0x66, 0xc6, 0x4e, 0xab, 0x8c, 0x6c, 0x68, 0x22,
+	0x66, 0xca, 0x84, 0x72, 0x7e, 0x3c, 0x0b, 0xa2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0x0b, 0xdb, 0xf8, 0x8a, 0x48, 0x29, 0x71, 0x03, 0xf7, 0xcf, 0x4d,
+	0xb1, 0x85, 0x7a, 0x22, 0x97, 0xbe, 0x2e, 0xd9, 0xa1, 0xee, 0x20, 0x13,
+	0x2f, 0x5e, 0x07, 0xda, 0x24, 0x97, 0xb3, 0x43, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xec, 0x5e, 0x68, 0xad, 0xfe, 0x26, 0x70, 0x65, 0xfa, 0x03, 0x3f, 0x24,
+	0x56, 0xa2, 0x51, 0xc9, 0x79, 0x88, 0x89, 0x08, 0x86, 0x02, 0x18, 0x39,
+	0x59, 0x77, 0x53, 0x1b, 0xf7, 0x2c, 0x65, 0x3c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x23, 0xb1, 0xc4, 0x4d, 0xad, 0xf1, 0xae, 0x7a, 0x52, 0xba, 0x48,
+	0xd0, 0x0a, 0xc1, 0x94, 0x34, 0x41, 0x1b, 0x3d, 0x93, 0x49, 0xf0, 0x8d,
+	0x25, 0xf2, 0x72, 0x56, 0xd7, 0xb7, 0x05, 0x81, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0x05, 0x2c, 0x85, 0xc5, 0x52, 0xad, 0x02, 0xbd, 0xb7, 0x5d, 0x21,
+	0xcd, 0xbd, 0xce, 0x01, 0xd3, 0xd9, 0x12, 0xba, 0xc6, 0x7f, 0x45, 0x31,
+	0x00, 0x33, 0x8c, 0x20, 0x63, 0x4d, 0xf5, 0x22, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1a, 0x38, 0xa7, 0xf1, 0x5b, 0xd0, 0xb8, 0x54, 0x3c, 0x33, 0x27, 0x32,
+	0xca, 0x04, 0x38, 0x5e, 0xa0, 0xf8, 0x81, 0x06, 0xa0, 0xe7, 0x47, 0x1d,
+	0x16, 0xcb, 0xaa, 0x68, 0xb5, 0x6a, 0xd2, 0xaa, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3e, 0x69, 0x14, 0xef, 0xc0, 0x82, 0x94, 0x72, 0x09, 0x07, 0xb5, 0xa6,
+	0x98, 0x1d, 0xb2, 0xd7, 0xcb, 0xe4, 0x6c, 0xb7, 0x88, 0x78, 0x8b, 0xd9,
+	0x34, 0x5a, 0xdb, 0xae, 0x55, 0x6a, 0x6b, 0x1f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf1, 0x20, 0x49, 0xc6, 0xda, 0x47, 0x7a, 0x25, 0x9e, 0xce, 0xf6, 0x2e,
+	0xd4, 0x76, 0xb6, 0x0f, 0x41, 0x54, 0x08, 0xb8, 0x29, 0x08, 0x96, 0xd0,
+	0x01, 0x23, 0x34, 0xb6, 0x1e, 0xfe, 0xb0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd1, 0x6c, 0x52, 0xd3, 0x5f, 0x6a, 0x74, 0x18, 0x9b, 0xfe, 0xf3, 0x73,
+	0x74, 0xb8, 0x05, 0xa2, 0x29, 0x9d, 0x41, 0x53, 0x72, 0xa2, 0x93, 0x7c,
+	0x0a, 0xa8, 0xe8, 0x48, 0x89, 0x8f, 0x6f, 0x60, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x21, 0x4a, 0xd6, 0xa6, 0x0b, 0x51, 0xf6, 0x1d, 0xa2, 0x5c, 0xa5, 0x23,
+	0x6a, 0x1e, 0x34, 0x7d, 0xc5, 0xfe, 0xba, 0x77, 0x9d, 0xe5, 0x40, 0x9c,
+	0x38, 0x4e, 0xab, 0x29, 0x0d, 0x17, 0x7e, 0x48, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1e, 0x04, 0x03, 0xaf, 0xbd, 0x77, 0xba, 0x7d, 0x53, 0xe9, 0x14, 0x63,
+	0x40, 0xa7, 0xba, 0x26, 0x00, 0x55, 0x42, 0xff, 0x7c, 0x0d, 0xde, 0xd1,
+	0x59, 0xa2, 0x72, 0x6d, 0x1a, 0x92, 0x7e, 0x56, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x6d, 0x5c, 0x1d, 0x19, 0xf5, 0x09, 0x6d, 0x18, 0xa1, 0x69, 0x87,
+	0xad, 0x52, 0x19, 0x1e, 0xf1, 0x83, 0x14, 0xea, 0x85, 0x1c, 0xeb, 0xe0,
+	0x09, 0x34, 0x4b, 0x8a, 0xd2, 0x98, 0x25, 0x20, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4c, 0x5a, 0xf1, 0x8b, 0x60, 0xa3, 0xef, 0xfb, 0xe6, 0x9a, 0x9e, 0x2a,
+	0x7c, 0x79, 0x13, 0x18, 0x9b, 0x68, 0xed, 0x3d, 0x9c, 0x96, 0x87, 0x75,
+	0x7d, 0x03, 0x00, 0x62, 0x8a, 0x38, 0x69, 0x58, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8e, 0x21, 0xc4, 0x17, 0x0e, 0x2d, 0x4e, 0x01, 0xb5, 0xfb, 0x2e, 0x65,
+	0x3f, 0x32, 0xd7, 0x18, 0x50, 0x70, 0x81, 0x6b, 0xf7, 0xab, 0xc2, 0xfc,
+	0x4b, 0xa9, 0x21, 0x10, 0x37, 0x21, 0xbf, 0xbb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xda, 0x5a, 0x33, 0xeb, 0x21, 0x36, 0x7c, 0x40, 0x16, 0x1d, 0xd5, 0x6e,
+	0xe1, 0xe4, 0x79, 0x2b, 0x9f, 0x9f, 0x06, 0x89, 0x80, 0x93, 0xc6, 0x0f,
+	0x61, 0xbe, 0x0b, 0x75, 0xdb, 0x7c, 0x78, 0x50, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8b, 0xdc, 0x45, 0xa9, 0x5e, 0xbc, 0xf3, 0xb4, 0xcc, 0x3c, 0xba, 0xbd,
+	0x65, 0x2f, 0x2f, 0xd7, 0xd5, 0x15, 0x7f, 0x7e, 0x03, 0x0b, 0xc6, 0xc7,
+	0x6b, 0x6b, 0x6e, 0x77, 0x30, 0xcb, 0xc0, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2e, 0xf0, 0x16, 0xcd, 0xf9, 0x23, 0xf9, 0x10, 0xe0, 0x5d, 0xa7, 0x26,
+	0xbb, 0xf1, 0x53, 0x06, 0xea, 0x81, 0x2f, 0x38, 0x9e, 0x53, 0x67, 0x40,
+	0x74, 0x2a, 0xd5, 0x6e, 0xec, 0xc8, 0xa5, 0xcb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe2, 0x1f, 0xc1, 0xee, 0x82, 0xd5, 0x6e, 0x58, 0x81, 0x97, 0x4c, 0xf3,
+	0x0b, 0x90, 0x1e, 0x1f, 0xf8, 0xdc, 0x2b, 0xc0, 0x58, 0x3b, 0x2a, 0x28,
+	0x56, 0xc1, 0xe7, 0xb4, 0x40, 0x44, 0x5b, 0x54, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x85, 0x49, 0x08, 0xe7, 0xfa, 0x5d, 0x0c, 0xf9, 0xa3, 0x6e, 0xe5,
+	0x34, 0x8e, 0x83, 0xf2, 0xd0, 0xf1, 0xa4, 0x13, 0x32, 0x52, 0x86, 0x50,
+	0x75, 0xcd, 0xb5, 0xfc, 0xe9, 0x7b, 0x7c, 0xf6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2c, 0x85, 0x09, 0xe3, 0xd9, 0x4a, 0x91, 0xa2, 0x10, 0xf7, 0x7f, 0x5b,
+	0xde, 0x9a, 0xb7, 0x87, 0x32, 0x7d, 0x63, 0xf6, 0x7e, 0x0c, 0x3e, 0xcc,
+	0x4a, 0xa4, 0x9e, 0x35, 0x6b, 0x55, 0x50, 0x2e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xde, 0x9c, 0x80, 0x75, 0xc0, 0x21, 0x92, 0xf7, 0x30, 0x72, 0x1c, 0x15,
+	0xb2, 0x00, 0x0e, 0xc4, 0xa1, 0xa6, 0x1a, 0x6d, 0xd1, 0x63, 0x6b, 0xa8,
+	0x4b, 0x01, 0x10, 0x6f, 0x61, 0xe7, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7f, 0xdd, 0x3e, 0x2e, 0x6d, 0x7e, 0xed, 0x72, 0x65, 0xf7, 0x8d, 0x29,
+	0xba, 0x75, 0xa3, 0x07, 0x93, 0x86, 0xb4, 0xee, 0xcd, 0xd8, 0x5d, 0x19,
+	0x22, 0x02, 0x39, 0xba, 0xc5, 0x05, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa2, 0x01, 0xed, 0x74, 0x47, 0xd9, 0x0b, 0x18, 0x73, 0x4d, 0xcd, 0x41,
+	0x9a, 0xe4, 0xf1, 0xee, 0x33, 0x8a, 0x74, 0x8b, 0x26, 0xfd, 0x6e, 0x02,
+	0x2e, 0x5c, 0xc7, 0xf5, 0xa1, 0xeb, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3a, 0x3c, 0x00, 0x91, 0x80, 0xf2, 0x0f, 0x07, 0xf5, 0x02, 0xdc, 0xfa,
+	0xb7, 0x6e, 0x74, 0xdc, 0x3a, 0x78, 0xc5, 0x28, 0x8e, 0x17, 0x4f, 0xf1,
+	0x54, 0x40, 0x61, 0xfa, 0x46, 0x6c, 0x6d, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0x5f, 0xf2, 0x5a, 0x62, 0xbc, 0x77, 0xc1, 0xea, 0xbb, 0x38, 0xc2,
+	0x7e, 0x63, 0xac, 0x59, 0xc9, 0xd1, 0x37, 0xea, 0xeb, 0x09, 0x77, 0xa1,
+	0x6b, 0x49, 0x7e, 0x17, 0xc3, 0xab, 0x03, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xce, 0x14, 0xe5, 0x45, 0x4b, 0x16, 0x3e, 0x4a, 0xec, 0x3d, 0x52, 0x21,
+	0x35, 0xff, 0xe5, 0x33, 0x06, 0x46, 0x11, 0x32, 0x96, 0xc0, 0x34, 0x06,
+	0x04, 0x31, 0x37, 0x31, 0x25, 0xde, 0xde, 0xd8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x11, 0xbe, 0x6b, 0x47, 0xcd, 0x4a, 0xfd, 0xc3, 0x0d, 0x90, 0x1c, 0xc0,
+	0xd4, 0x70, 0x96, 0x72, 0xec, 0x42, 0xd6, 0x1d, 0x25, 0x5a, 0x9c, 0xd2,
+	0x23, 0xd6, 0x8e, 0xaf, 0x95, 0x7e, 0xfb, 0xd3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xdf, 0x28, 0x49, 0xeb, 0xa9, 0x5a, 0x0b, 0xf6, 0xf0, 0x9f, 0x4a,
+	0x47, 0x70, 0xf3, 0x49, 0x5f, 0x6f, 0xac, 0x86, 0x40, 0xfb, 0x0d, 0xf7,
+	0x72, 0xab, 0x23, 0x3d, 0x91, 0x08, 0x8c, 0x32, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0xb9, 0xe2, 0xb7, 0x4e, 0x62, 0xde, 0xcc, 0xd7, 0x68, 0xbd, 0x60,
+	0x83, 0x7d, 0x9c, 0x61, 0xfd, 0xd8, 0x5e, 0xb7, 0x64, 0x9b, 0xce, 0xa5,
+	0x23, 0x81, 0x2c, 0xcd, 0x9b, 0x5a, 0xaa, 0xd6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1d, 0x4a, 0x45, 0xf9, 0x1b, 0x9f, 0xa9, 0xfd, 0x38, 0x86, 0x31, 0x53,
+	0x9a, 0x2f, 0xb5, 0x5d, 0x2d, 0xed, 0x31, 0x75, 0x30, 0xd6, 0xbb, 0xdd,
+	0x53, 0x9b, 0x5f, 0xe0, 0xab, 0xd7, 0xaf, 0xe0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xee, 0xb3, 0x3b, 0xf0, 0x8a, 0x11, 0xd5, 0x5e, 0x37, 0xfd, 0x5a, 0x03,
+	0xaf, 0xaf, 0x0c, 0x99, 0xcc, 0x62, 0x92, 0x12, 0x30, 0x52, 0xac, 0x72,
+	0x7f, 0x51, 0x65, 0x44, 0x19, 0xf9, 0xe4, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x95, 0x4b, 0x50, 0xb3, 0x76, 0xa6, 0xa4, 0xb1, 0x9a, 0x39, 0x1e,
+	0x0d, 0x64, 0xfe, 0xc0, 0xf4, 0x43, 0xef, 0x85, 0x0a, 0xc2, 0xe3, 0xb0,
+	0x58, 0xc3, 0xf0, 0xf8, 0xdb, 0x67, 0xfc, 0x36, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xba, 0x4f, 0xbc, 0x66, 0x32, 0xd4, 0x4e, 0xec, 0x3f, 0x92, 0xfb, 0x0e,
+	0x92, 0x9b, 0x52, 0xe8, 0x27, 0xd9, 0xbb, 0xaa, 0x9c, 0x54, 0x70, 0x82,
+	0x4f, 0xad, 0xca, 0xbc, 0x9e, 0x01, 0x7e, 0x1c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5e, 0xe3, 0x0c, 0xca, 0xa3, 0xaa, 0xd6, 0x3f, 0x90, 0xcc, 0xef, 0xcd,
+	0x74, 0x59, 0xb3, 0xc5, 0xba, 0x35, 0xa8, 0x7e, 0x7e, 0xec, 0x4b, 0x6b,
+	0x00, 0x21, 0xfb, 0xa1, 0x6e, 0x53, 0xc4, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9d, 0xd3, 0xb3, 0xeb, 0xcf, 0xa0, 0x6d, 0xb1, 0x88, 0xab, 0x33, 0xc4,
+	0x0f, 0xd7, 0xb0, 0x76, 0x02, 0x8e, 0x71, 0x61, 0x18, 0x63, 0x07, 0xdc,
+	0x3e, 0x0d, 0xb9, 0xa8, 0x32, 0x75, 0x7a, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0xab, 0xf5, 0x7e, 0x0b, 0x4c, 0x08, 0x30, 0x08, 0x80, 0xc1, 0x9b,
+	0x69, 0x6a, 0x0e, 0xfc, 0x16, 0x81, 0xf1, 0xa9, 0xd4, 0x85, 0x35, 0x94,
+	0x26, 0xc5, 0x23, 0xb4, 0xa8, 0xb1, 0x8a, 0xb8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc5, 0x6d, 0x50, 0x49, 0x27, 0x8d, 0x35, 0x47, 0x0d, 0x73, 0x18, 0xae,
+	0xaf, 0x38, 0xef, 0xfa, 0xdd, 0x70, 0x48, 0x15, 0x39, 0xf0, 0x1c, 0x6e,
+	0x79, 0xd1, 0x13, 0x9f, 0xe4, 0xb3, 0xb2, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x39, 0xeb, 0xfb, 0x14, 0x3f, 0xf0, 0xa0, 0x0b, 0x5e, 0x41, 0x20, 0x0c,
+	0xfe, 0x36, 0x0c, 0x7f, 0xf0, 0xaf, 0xaa, 0xdd, 0x61, 0x66, 0x65, 0x30,
+	0x6b, 0x10, 0x18, 0x28, 0x30, 0xb6, 0x47, 0x3e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf7, 0xa8, 0x12, 0x06, 0x64, 0xfa, 0x90, 0xfa, 0x0c, 0xfb, 0x26, 0xf2,
+	0x2a, 0x1a, 0xc4, 0xf9, 0xae, 0x5c, 0x1b, 0x24, 0xf3, 0xf2, 0x87, 0xa2,
+	0x5c, 0x0a, 0x2a, 0x2b, 0x17, 0xa7, 0x2b, 0x7e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0x6d, 0x30, 0x7d, 0xb2, 0xd1, 0x40, 0xb7, 0x4f, 0x05, 0xac, 0x1a,
+	0xa1, 0x66, 0xa6, 0x19, 0x18, 0xf8, 0xcd, 0xf3, 0x3c, 0xf6, 0x84, 0xc3,
+	0x4d, 0x46, 0x49, 0xf1, 0xf7, 0x28, 0xa6, 0x0c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xf2, 0x0b, 0x90, 0x0d, 0xeb, 0x5c, 0x0b, 0x70, 0x2f, 0x54, 0x26,
+	0x1a, 0x7d, 0x6e, 0x72, 0x67, 0x95, 0x28, 0x03, 0x01, 0x37, 0xfa, 0xc6,
+	0x00, 0x45, 0xa7, 0xda, 0x5b, 0xbf, 0xf0, 0x24, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa9, 0x6c, 0x1d, 0x2b, 0x7e, 0xea, 0x35, 0x8b, 0x92, 0x12, 0x42, 0xf9,
+	0x8f, 0x67, 0x38, 0xf5, 0xf7, 0x1a, 0xe2, 0x8f, 0xb4, 0x40, 0x45, 0x2a,
+	0x47, 0xca, 0x9d, 0xbf, 0xbd, 0x85, 0xc0, 0xd2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+const uint8_t ae_fpm_tbl_ed448[AE_FPM_ED448_LEN] = {
+	0x26, 0x26, 0xa8, 0x2b, 0xc7, 0x0c, 0xc0, 0x5e, 0x43, 0x3b, 0x80, 0xe1,
+	0x8b, 0x00, 0x93, 0x8e, 0x12, 0xae, 0x1a, 0xf7, 0x2a, 0xb6, 0x65, 0x11,
+	0xea, 0x6d, 0xe3, 0x24, 0xa3, 0xd3, 0xa4, 0x64, 0x9e, 0x14, 0x65, 0x70,
+	0x47, 0x0f, 0x17, 0x67, 0x22, 0x1d, 0x15, 0xa6, 0x22, 0xbf, 0x36, 0xda,
+	0x4f, 0x19, 0x70, 0xc6, 0x6b, 0xed, 0x0d, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x98, 0x08, 0x79, 0x5b, 0xf2, 0x30, 0xfa, 0x14,
+	0xfd, 0xbd, 0x13, 0x2c, 0x4e, 0xd7, 0xc8, 0xad, 0x3a, 0xd3, 0xff, 0x1c,
+	0xe6, 0x7c, 0x39, 0xc4, 0x87, 0x78, 0x9c, 0x1e, 0x05, 0xa0, 0xc2, 0xd7,
+	0x4b, 0xea, 0x73, 0x73, 0x6c, 0xa3, 0x98, 0x40, 0x88, 0x76, 0x20, 0x37,
+	0x56, 0xc9, 0xc7, 0x62, 0x69, 0x3f, 0x46, 0x71, 0x6e, 0xb6, 0xbc, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xeb, 0x06, 0x62, 0x4e, 0x82, 0xaf, 0x95, 0xf3, 0xf7, 0x8f, 0xa0, 0x7d,
+	0x85, 0x66, 0x2d, 0x1d, 0xf1, 0x79, 0xde, 0x90, 0xb5, 0xb2, 0x7d, 0xa1,
+	0x60, 0xd7, 0x16, 0x67, 0xe2, 0x35, 0x6d, 0x58, 0xc5, 0x05, 0x6a, 0x18,
+	0x3f, 0x84, 0x51, 0xd2, 0xce, 0xc3, 0x9d, 0x2d, 0x50, 0x8d, 0x91, 0xc9,
+	0xc7, 0x5e, 0xb5, 0x8a, 0xee, 0x22, 0x1c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x12, 0x77, 0x1a, 0x0d, 0x31, 0xc0, 0x77, 0xbf,
+	0xc4, 0x24, 0x04, 0xed, 0x68, 0x36, 0xd7, 0x42, 0x6a, 0x65, 0x11, 0x30,
+	0x9d, 0xd9, 0x3a, 0x78, 0x3d, 0x16, 0x5b, 0x3f, 0x5b, 0x32, 0xdd, 0x27,
+	0x70, 0xf9, 0x81, 0x8f, 0x1b, 0xc6, 0x4d, 0xd1, 0x36, 0xf5, 0xf8, 0x56,
+	0x3e, 0x48, 0x3a, 0xc1, 0x28, 0x41, 0x27, 0x74, 0x35, 0xd1, 0x4b, 0x0f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x69, 0x81, 0x50,
+	0x38, 0xfb, 0x26, 0xe1, 0x68, 0x82, 0xe5, 0x52, 0x90, 0x23, 0xc2, 0x5e,
+	0xb3, 0x5e, 0x42, 0x06, 0x65, 0xea, 0x9f, 0x0c, 0x94, 0x4c, 0x92, 0x1f,
+	0x2d, 0x18, 0x4c, 0x04, 0xbe, 0x79, 0xf0, 0x74, 0x2d, 0x5a, 0x0b, 0x29,
+	0xa7, 0x46, 0xb8, 0x80, 0xdf, 0x83, 0x8f, 0x06, 0xe6, 0xe0, 0x8f, 0x72,
+	0x53, 0xfa, 0x6d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb4, 0x85, 0xa6, 0xed, 0xe6, 0xa8, 0x12, 0xd5, 0x7d, 0x97, 0xf7, 0xc8,
+	0xac, 0x2c, 0x4d, 0x2b, 0xfc, 0x53, 0x3e, 0xd0, 0x9f, 0x45, 0xd1, 0x52,
+	0xac, 0x85, 0x4f, 0xf8, 0x36, 0x7c, 0xcd, 0xa6, 0x6c, 0xb8, 0x0f, 0x8f,
+	0xdc, 0xde, 0x54, 0xc3, 0x23, 0x7b, 0xcc, 0xd9, 0xfe, 0x97, 0x19, 0x86,
+	0xa6, 0x17, 0xcd, 0x9b, 0xfe, 0x08, 0xf6, 0x3f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5c, 0xeb, 0x54, 0x97, 0x02, 0x55, 0xed, 0x8f,
+	0xfe, 0x3f, 0xe6, 0x24, 0x26, 0x1e, 0x3a, 0xc8, 0xdf, 0x28, 0xfc, 0xf9,
+	0xb9, 0x1b, 0x9c, 0xc8, 0x1b, 0x5f, 0xb0, 0x08, 0x2b, 0x19, 0x1e, 0x92,
+	0x29, 0xd9, 0x49, 0xa8, 0xb4, 0x61, 0xcc, 0xf3, 0x18, 0x35, 0x0a, 0x40,
+	0x2a, 0xe3, 0x2c, 0x09, 0x21, 0x81, 0x22, 0x38, 0xaf, 0xc2, 0xf4, 0x20,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x2d, 0x7c, 0xe2,
+	0x41, 0xc3, 0x10, 0x65, 0x01, 0x4a, 0x4f, 0xd5, 0x07, 0x2b, 0xa5, 0xd6,
+	0x7c, 0xc0, 0x57, 0x50, 0xc3, 0xf5, 0x63, 0xa0, 0x03, 0x8b, 0x79, 0xa9,
+	0xb1, 0xdd, 0xc4, 0x2f, 0xbe, 0xfa, 0x48, 0x92, 0xca, 0x8e, 0xd7, 0x0d,
+	0xdf, 0xcf, 0x2d, 0x40, 0xa3, 0xbc, 0x7e, 0xe7, 0x2e, 0xbe, 0xe9, 0x21,
+	0x83, 0xc8, 0x79, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xac, 0xdf, 0x2c, 0x05, 0x92, 0x8e, 0xe1, 0x3b, 0xc0, 0x57, 0xd9, 0xb4,
+	0x16, 0x0c, 0x80, 0x17, 0x03, 0x5a, 0x29, 0x4d, 0xef, 0x36, 0x9b, 0x11,
+	0x3b, 0xe2, 0xef, 0xca, 0x7f, 0xdd, 0xd3, 0xa3, 0xd7, 0x7f, 0x2b, 0x64,
+	0xa9, 0x7f, 0x62, 0x72, 0x71, 0x7d, 0x9e, 0x9f, 0xde, 0x2b, 0xcb, 0xd4,
+	0x3e, 0x95, 0x6f, 0x9d, 0x0c, 0x1f, 0x1a, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x92, 0xef, 0x93, 0x8e, 0xe7, 0x0a, 0x10,
+	0x7b, 0xc3, 0xdc, 0x46, 0xd9, 0x96, 0x27, 0x92, 0x91, 0xa4, 0x98, 0x89,
+	0x2d, 0xf2, 0x17, 0x03, 0x8c, 0xdb, 0x98, 0xed, 0xda, 0xb3, 0x15, 0xd5,
+	0xba, 0x58, 0x01, 0x38, 0x6e, 0x54, 0xd7, 0x46, 0x9c, 0x2b, 0x94, 0x5b,
+	0x60, 0x9e, 0x5b, 0x3b, 0xc3, 0x4c, 0x7e, 0xc3, 0xbc, 0x4d, 0xa9, 0xdd,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xd6, 0x93, 0x46,
+	0x63, 0x4b, 0xb6, 0x15, 0x73, 0x5f, 0xe8, 0x44, 0x1f, 0x89, 0x7c, 0xfe,
+	0x83, 0x79, 0xcb, 0x73, 0x83, 0x58, 0xce, 0x9c, 0x87, 0xad, 0x17, 0xe5,
+	0xfa, 0xdd, 0x04, 0x86, 0x55, 0x71, 0xf7, 0xb8, 0x6b, 0xcd, 0x5d, 0xfc,
+	0x9c, 0x49, 0xe6, 0x3f, 0x3e, 0x87, 0x3b, 0x37, 0x65, 0x32, 0x11, 0x5c,
+	0x6e, 0x65, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x3f, 0x74, 0xbc, 0x23, 0x5e, 0x87, 0xc7, 0x6f, 0xe1, 0x4d, 0x31,
+	0x75, 0x2a, 0x1e, 0xa9, 0x8e, 0xa2, 0x11, 0x3d, 0xfb, 0x62, 0xb8, 0x22,
+	0xdb, 0x4d, 0xb6, 0x29, 0x78, 0x4b, 0xc7, 0xa8, 0xba, 0x9b, 0xd8, 0x39,
+	0x03, 0xb6, 0x66, 0x26, 0xd2, 0xce, 0x26, 0x5d, 0x68, 0x1d, 0xca, 0x51,
+	0x14, 0x75, 0x66, 0xbd, 0xc2, 0xd0, 0xbc, 0xdb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x99, 0x33, 0x2c, 0x81, 0xaa, 0xcd, 0x8e, 0x4a,
+	0x04, 0xdf, 0xf4, 0x24, 0x98, 0x6b, 0x6e, 0x0f, 0xb1, 0xc0, 0x97, 0x61,
+	0x12, 0xbb, 0xa6, 0xd2, 0x67, 0x28, 0x33, 0xbb, 0xe7, 0x56, 0x5f, 0xc1,
+	0xa1, 0x23, 0xad, 0x1f, 0x3c, 0x75, 0x9c, 0x20, 0x92, 0x72, 0xe4, 0xfb,
+	0x60, 0x6c, 0xac, 0x5c, 0x25, 0x89, 0xe9, 0x2c, 0xb0, 0x29, 0x52, 0x1d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x78, 0xf8, 0x9f,
+	0x6b, 0x68, 0x93, 0x3b, 0xd8, 0x27, 0xa4, 0xb3, 0x34, 0x37, 0x63, 0x7b,
+	0x60, 0x22, 0x8b, 0xab, 0x06, 0x92, 0xed, 0x9e, 0x4d, 0xc7, 0x5b, 0xf1,
+	0x23, 0x65, 0x05, 0xc4, 0x6d, 0x7d, 0x04, 0x67, 0xc0, 0x27, 0x29, 0x05,
+	0x23, 0x7f, 0xf8, 0x30, 0xfe, 0x6e, 0xf3, 0x0b, 0x3a, 0x85, 0x47, 0x45,
+	0xa5, 0x1c, 0x9a, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x30, 0x7d, 0x8f, 0x0d, 0xcb, 0xce, 0x3a, 0x48, 0xd3, 0x2f, 0x09, 0xf8,
+	0xdd, 0x49, 0x49, 0x3d, 0x9f, 0x65, 0xb4, 0x4d, 0xcd, 0xa6, 0x93, 0xb2,
+	0x72, 0xe2, 0x98, 0x6e, 0xa7, 0xae, 0x0a, 0x9d, 0xcb, 0xb0, 0xc9, 0x75,
+	0x3b, 0x41, 0x79, 0x71, 0x63, 0xce, 0x55, 0x70, 0xde, 0x2a, 0x0f, 0x07,
+	0x30, 0xe5, 0x7e, 0xb9, 0xf3, 0xdf, 0x50, 0x39, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xce, 0x5b, 0xd0, 0x27, 0x82, 0x18, 0x8e, 0x41,
+	0x4b, 0x43, 0x8a, 0x62, 0x3e, 0x21, 0xce, 0x31, 0x28, 0xe2, 0xc5, 0x53,
+	0xbd, 0x97, 0xec, 0xa0, 0xc8, 0x85, 0xa4, 0x7a, 0x1e, 0xdb, 0x22, 0xc1,
+	0xbc, 0xc8, 0xa3, 0x74, 0xda, 0xd2, 0xd7, 0xa8, 0x96, 0x9e, 0x51, 0xfd,
+	0xa5, 0x74, 0x8f, 0xab, 0x55, 0x4b, 0x95, 0xb6, 0xfc, 0x3d, 0x16, 0x7d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x70, 0x9e, 0xad,
+	0xfb, 0x64, 0xff, 0xc6, 0xe7, 0x78, 0x37, 0x89, 0x04, 0x9f, 0x01, 0x16,
+	0xa1, 0x68, 0x38, 0xf0, 0xf3, 0x01, 0x25, 0xfd, 0xfa, 0xa1, 0xd3, 0x7e,
+	0x6f, 0xb6, 0x33, 0xa7, 0x44, 0x62, 0x83, 0x19, 0xec, 0x5b, 0xfe, 0x17,
+	0xa1, 0x7d, 0xe4, 0xa2, 0x7d, 0x47, 0xa5, 0x1d, 0x1f, 0x31, 0x55, 0x2d,
+	0xe2, 0x3c, 0x9a, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5f, 0xfd, 0xfd, 0x31, 0xc2, 0x6d, 0x22, 0x75, 0x97, 0x37, 0x39, 0x32,
+	0x1a, 0x88, 0x65, 0x16, 0xe9, 0xb8, 0x94, 0x35, 0xd7, 0x1e, 0x32, 0x32,
+	0x29, 0xf8, 0xfd, 0xef, 0x97, 0x26, 0xe9, 0x87, 0x32, 0xf4, 0xc9, 0x2b,
+	0x94, 0x2c, 0x85, 0x28, 0x8e, 0xb5, 0x4c, 0xf8, 0xae, 0xbf, 0xdf, 0x1a,
+	0xe3, 0xff, 0xbf, 0x0d, 0x3a, 0x8f, 0x86, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xb2, 0x45, 0xf4, 0xc9, 0xee, 0x82, 0x26, 0x2e,
+	0xe6, 0xd0, 0x97, 0x07, 0xfb, 0x72, 0xd1, 0x73, 0x98, 0x46, 0x05, 0x88,
+	0x1c, 0xba, 0xa2, 0x06, 0xd0, 0xe5, 0x49, 0xde, 0x1c, 0x6b, 0xa3, 0xe5,
+	0x5b, 0xea, 0x44, 0x4b, 0xe1, 0x5f, 0xa2, 0x77, 0x46, 0xed, 0xe6, 0x8c,
+	0x33, 0x20, 0x8e, 0x54, 0x74, 0x2f, 0x80, 0x95, 0x11, 0x50, 0x6b, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x6f, 0x6f, 0xa4,
+	0xe3, 0x4b, 0x95, 0xa3, 0x98, 0x3f, 0x0a, 0xfa, 0xf3, 0x9d, 0x9b, 0x7d,
+	0x78, 0xf9, 0x3e, 0x56, 0xd2, 0xd9, 0xb4, 0x2e, 0xd8, 0x39, 0xfb, 0x35,
+	0xe3, 0x25, 0xc5, 0xba, 0xfc, 0x18, 0xab, 0x08, 0x2d, 0x38, 0xe9, 0x4e,
+	0x68, 0xd6, 0x98, 0xad, 0x58, 0xfa, 0xd1, 0xe0, 0x55, 0x8f, 0x21, 0x1a,
+	0x11, 0x7e, 0x13, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x33, 0x19, 0x04, 0x18, 0xcf, 0x4b, 0x06, 0xf1, 0x32, 0x0f, 0xb9, 0xcb,
+	0x13, 0x81, 0x9b, 0xaf, 0x4e, 0x55, 0xaa, 0x8b, 0xea, 0x88, 0x95, 0x66,
+	0x9b, 0xf7, 0xd3, 0x58, 0xb5, 0x4b, 0x2c, 0xee, 0x18, 0xca, 0x8a, 0x94,
+	0xc9, 0x82, 0x98, 0x5d, 0x3d, 0xbc, 0xb7, 0x3c, 0x73, 0xab, 0x6c, 0x76,
+	0x7c, 0x25, 0x62, 0xfc, 0x8a, 0xef, 0xd7, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x59, 0x2d, 0xbb, 0xa7, 0xf0, 0x49, 0x6f, 0xc2,
+	0x69, 0xb1, 0xc3, 0x94, 0xf3, 0x8e, 0xf4, 0xac, 0xe3, 0x2c, 0xd9, 0x94,
+	0xfd, 0x15, 0x46, 0x54, 0x49, 0x19, 0xbc, 0x27, 0xb4, 0x8b, 0x85, 0xf5,
+	0x54, 0x81, 0x10, 0x03, 0x99, 0x13, 0x58, 0x6d, 0x0a, 0x2f, 0x6d, 0xbc,
+	0x76, 0x34, 0xd1, 0x12, 0xfe, 0xa6, 0x75, 0xf0, 0x54, 0x39, 0xb4, 0x33,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x52, 0x64, 0x73,
+	0x17, 0xb4, 0xc4, 0xcc, 0x4b, 0x72, 0xf2, 0x4d, 0xf6, 0x31, 0xb3, 0xf8,
+	0x25, 0x64, 0xdb, 0x94, 0xa7, 0x83, 0x86, 0x66, 0xad, 0xc1, 0x9f, 0x9e,
+	0xa7, 0xc9, 0x87, 0x84, 0x9c, 0x80, 0x82, 0x94, 0x36, 0xcd, 0x2a, 0xba,
+	0x04, 0x9f, 0x25, 0x9c, 0x56, 0x1a, 0x3e, 0x09, 0x07, 0xf4, 0x27, 0xae,
+	0xf2, 0x21, 0x0a, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd5, 0xe9, 0x2b, 0xb0, 0x25, 0x50, 0x73, 0x45, 0x24, 0xb4, 0xfe, 0x97,
+	0x6c, 0xaf, 0xb8, 0x72, 0xbf, 0xe2, 0xcf, 0x5d, 0xe8, 0x66, 0x84, 0x74,
+	0xd6, 0xff, 0x14, 0xc9, 0x07, 0x63, 0x58, 0x2e, 0xd2, 0x81, 0x83, 0xc9,
+	0x05, 0x9d, 0x5c, 0x9e, 0x62, 0xd2, 0x90, 0x3a, 0x6c, 0x16, 0x66, 0x7c,
+	0x2d, 0xe1, 0x2b, 0x55, 0x51, 0x2b, 0x25, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xea, 0x86, 0x65, 0xcb, 0x55, 0x08, 0x23, 0x8b,
+	0x3e, 0xd3, 0xa7, 0x88, 0x0f, 0xb1, 0xd3, 0x7f, 0xe7, 0xb8, 0x61, 0xfa,
+	0x58, 0x96, 0x51, 0x4c, 0xea, 0x4d, 0x95, 0xcd, 0x1a, 0x3e, 0x3c, 0x95,
+	0xd3, 0x07, 0xc9, 0x00, 0x66, 0x68, 0x8d, 0x25, 0x9e, 0x1c, 0x82, 0xae,
+	0x5e, 0x48, 0xea, 0xf3, 0x01, 0x27, 0x7b, 0xf2, 0xb2, 0x9b, 0x16, 0xef,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1c, 0x38, 0xc3,
+	0x1f, 0x7b, 0x41, 0x2d, 0x5d, 0xdf, 0xd9, 0xea, 0xbf, 0xad, 0x45, 0xa2,
+	0x25, 0x0b, 0xb6, 0xa3, 0xef, 0xa5, 0xdc, 0xc5, 0xe0, 0xb8, 0x4a, 0xb3,
+	0xfa, 0xb5, 0x36, 0x35, 0x77, 0xdc, 0xf4, 0xa6, 0x88, 0x53, 0xe1, 0xa3,
+	0x1e, 0xf6, 0xa6, 0x8e, 0x7a, 0xc5, 0x0b, 0xc2, 0x16, 0x3e, 0xe2, 0x27,
+	0x0f, 0x9b, 0xc4, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x81, 0x54, 0x75, 0x7f, 0xdb, 0x06, 0xbd, 0xa2, 0x4a, 0x5b, 0xa0, 0x85,
+	0xf8, 0xc5, 0x12, 0x5b, 0xbb, 0x4b, 0xa1, 0x58, 0xa5, 0xd6, 0x1d, 0x98,
+	0x04, 0x21, 0x7a, 0x30, 0x31, 0x00, 0x2c, 0x99, 0x90, 0xcf, 0x80, 0xfe,
+	0xd1, 0x6b, 0x27, 0x93, 0xef, 0x89, 0x06, 0x1b, 0x95, 0x21, 0x8b, 0xbe,
+	0x0b, 0x8d, 0x1b, 0xa0, 0x23, 0x87, 0xf0, 0xe1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x76, 0x74, 0xb2, 0xb2, 0x25, 0x00, 0x07, 0xf9,
+	0x01, 0x30, 0x2b, 0xb8, 0xf2, 0x4e, 0xb2, 0x26, 0x04, 0x11, 0x3c, 0x79,
+	0xeb, 0x4a, 0xdf, 0x53, 0x55, 0xe6, 0x6e, 0x59, 0x60, 0xcd, 0xf2, 0xa4,
+	0xd7, 0xc3, 0x0d, 0x70, 0x9d, 0x6c, 0x64, 0x2a, 0xdd, 0x9d, 0x4d, 0x83,
+	0x95, 0x94, 0xd2, 0x38, 0xd1, 0xcd, 0x6e, 0xdb, 0x33, 0x32, 0x62, 0xd4,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x62, 0x25, 0x5e,
+	0xe0, 0x13, 0x80, 0x39, 0x31, 0x0e, 0x59, 0x15, 0x9c, 0xe8, 0x75, 0xbc,
+	0x60, 0x90, 0x34, 0x3a, 0x5f, 0x7d, 0x7c, 0x0b, 0x6c, 0x3d, 0x02, 0xfd,
+	0xfa, 0xb1, 0xf7, 0xce, 0x1b, 0xec, 0x37, 0x06, 0xaf, 0xc1, 0x9f, 0x93,
+	0x6f, 0x2d, 0x40, 0x9f, 0x22, 0x52, 0xb6, 0x73, 0x8f, 0x91, 0xe1, 0x85,
+	0xfe, 0x57, 0xa6, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x42, 0xde, 0xbe, 0xf5, 0xb7, 0xca, 0x60, 0x2e, 0x10, 0x88, 0xb7, 0xfc,
+	0xbe, 0x7f, 0x06, 0x8a, 0x7d, 0xcd, 0xb1, 0xde, 0x34, 0x43, 0x19, 0x70,
+	0xab, 0xa7, 0x62, 0x0e, 0x37, 0xee, 0x28, 0x2b, 0xd7, 0x5e, 0x4c, 0x5b,
+	0x30, 0x99, 0xc3, 0x3c, 0x47, 0xfb, 0x4d, 0x92, 0xb2, 0x6c, 0xa4, 0xd9,
+	0x9d, 0xe5, 0x74, 0xe2, 0xb2, 0xec, 0x6c, 0xc9, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x60, 0x24, 0xe8, 0xa8, 0xae, 0x35, 0x55, 0x83,
+	0x99, 0xe9, 0x6e, 0xdd, 0xdb, 0x48, 0x26, 0xee, 0x7a, 0x82, 0xdc, 0xa9,
+	0xb5, 0xda, 0xf3, 0xda, 0x21, 0x36, 0x87, 0xc0, 0xc9, 0xa0, 0x0c, 0xb1,
+	0xad, 0xc8, 0x5f, 0x1e, 0x68, 0x40, 0xd9, 0x2c, 0xdb, 0x15, 0x29, 0xfd,
+	0x8f, 0x80, 0xde, 0x8b, 0xad, 0xfa, 0xd4, 0x59, 0x20, 0x94, 0x40, 0x5f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x44, 0x63, 0x52,
+	0x42, 0xef, 0x04, 0x95, 0x0b, 0xbc, 0x2e, 0xc5, 0x6d, 0x67, 0x5a, 0x26,
+	0x24, 0x8e, 0x97, 0x4c, 0x1c, 0x52, 0x85, 0xe2, 0x65, 0x2e, 0xdf, 0xc0,
+	0xe1, 0x38, 0xb2, 0x2d, 0x90, 0xd7, 0x28, 0x31, 0x88, 0xbd, 0xbd, 0x45,
+	0x1e, 0x07, 0x53, 0x0c, 0x31, 0xe3, 0x60, 0x60, 0x96, 0xdd, 0x3f, 0x14,
+	0x3d, 0xb0, 0x03, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x7b, 0x41, 0x1e, 0xcf, 0xd4, 0xa0, 0xf3, 0x55, 0xa5, 0x02, 0x3e,
+	0x43, 0xf3, 0xfe, 0x6c, 0xf5, 0x39, 0x77, 0xfe, 0x5a, 0x9d, 0xa3, 0x43,
+	0xab, 0xa4, 0x11, 0xb7, 0x3c, 0xba, 0x8e, 0xf2, 0x96, 0x22, 0x30, 0x7e,
+	0x3a, 0x89, 0xf4, 0x37, 0xc8, 0x16, 0x4a, 0xcd, 0x29, 0x3f, 0xd0, 0x6c,
+	0x96, 0x68, 0x9d, 0xac, 0x7e, 0x04, 0xee, 0xb3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x50, 0x29, 0x41, 0xcb, 0x86, 0xe0, 0xe6, 0x50,
+	0x09, 0x74, 0xf3, 0xf4, 0x79, 0x40, 0x23, 0xd8, 0xd0, 0xd8, 0xe1, 0xc2,
+	0xe4, 0xe7, 0x87, 0xbf, 0x87, 0x98, 0xff, 0x1e, 0xa1, 0x18, 0xa9, 0x11,
+	0xdd, 0x0d, 0x89, 0xdb, 0x97, 0xb2, 0xd4, 0x93, 0x13, 0x32, 0xd9, 0x48,
+	0x46, 0x4e, 0xe4, 0x7f, 0x1c, 0x3b, 0x6f, 0x60, 0xd0, 0x75, 0x88, 0x6f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xdd, 0xf3, 0xdb,
+	0xc6, 0xc8, 0xca, 0x07, 0x40, 0xe9, 0x72, 0xa3, 0x87, 0xac, 0x4e, 0x08,
+	0xa0, 0x1d, 0xd8, 0xdc, 0x23, 0xf4, 0xe1, 0xcb, 0xca, 0x2a, 0xcd, 0xbb,
+	0x23, 0xf2, 0x52, 0x92, 0x5c, 0x29, 0x62, 0x39, 0x51, 0x66, 0x09, 0x3f,
+	0x96, 0x5c, 0x2e, 0xc7, 0x50, 0xa6, 0x56, 0x07, 0x66, 0x3f, 0x2b, 0x27,
+	0x02, 0x5d, 0x43, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x16, 0x87, 0x89, 0x08, 0x15, 0xbf, 0xb4, 0xbb, 0x04, 0xb9, 0xdf, 0x77,
+	0x4e, 0x6f, 0xde, 0x97, 0x61, 0x3c, 0x6a, 0xa5, 0xef, 0x5b, 0x4e, 0x15,
+	0x26, 0xe9, 0xbc, 0x92, 0xd9, 0xd3, 0xe3, 0xbd, 0x41, 0x3f, 0xb0, 0xe3,
+	0xc6, 0xfc, 0x75, 0xef, 0xb8, 0xb1, 0x31, 0x88, 0x1e, 0x95, 0x6a, 0xa1,
+	0x54, 0x0d, 0x4f, 0xfd, 0xb3, 0xa8, 0xe8, 0x9e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc5, 0xa6, 0xa2, 0xaa, 0x79, 0x6b,
+	0xdc, 0xc8, 0x5b, 0xe6, 0xda, 0xff, 0x69, 0x22, 0x19, 0x5f, 0x5e, 0x32,
+	0x31, 0xc4, 0x83, 0x30, 0xf6, 0xa6, 0xe3, 0x3d, 0xd4, 0xc8, 0xda, 0x4c,
+	0x33, 0xef, 0x38, 0x64, 0x4a, 0x92, 0x8e, 0x83, 0x04, 0xbc, 0x79, 0x12,
+	0x5d, 0x32, 0x59, 0x71, 0xa9, 0xc8, 0x7e, 0x55, 0xc7, 0x5f, 0x98, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x56, 0x48, 0xfa,
+	0x0b, 0x31, 0x1e, 0xdf, 0xfb, 0x40, 0x81, 0xce, 0x2a, 0xf1, 0xf0, 0x85,
+	0x74, 0x0b, 0xd8, 0x5a, 0x63, 0xf0, 0xad, 0x4b, 0xc2, 0x30, 0xf5, 0x1f,
+	0xdb, 0xad, 0x34, 0xb0, 0xe5, 0xac, 0x0f, 0x59, 0xcd, 0x7f, 0x59, 0xcb,
+	0xac, 0xda, 0x7d, 0x3e, 0x2b, 0x77, 0x7c, 0x45, 0x88, 0x66, 0xe4, 0x87,
+	0x77, 0xba, 0x6e, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x38, 0x0e, 0xcd, 0x3e, 0x5c, 0x70, 0xdb, 0xb4, 0xf2, 0x59, 0x37, 0x36,
+	0xc6, 0xf6, 0x78, 0xa8, 0xfa, 0x67, 0xad, 0xad, 0x96, 0x50, 0xf4, 0xe1,
+	0x3c, 0x65, 0xd0, 0x01, 0x59, 0x08, 0x86, 0x96, 0x67, 0x9f, 0x1f, 0x27,
+	0xd4, 0xa5, 0x9d, 0xd7, 0xf2, 0x57, 0xc2, 0x81, 0x3b, 0x1d, 0xe7, 0xaa,
+	0x10, 0xfb, 0x10, 0xa0, 0xe1, 0x25, 0x5a, 0x55, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa9, 0xd1, 0x51, 0x65, 0x95, 0xdd, 0x6f, 0x89,
+	0xad, 0xcc, 0x2a, 0x76, 0xc3, 0x98, 0x26, 0x37, 0x51, 0x07, 0x98, 0x8f,
+	0x85, 0xad, 0x55, 0x38, 0x5e, 0x15, 0x4f, 0x1c, 0xe6, 0x0b, 0xe5, 0x28,
+	0x9c, 0xac, 0xc2, 0x5a, 0x73, 0x23, 0x14, 0x01, 0x71, 0x71, 0x04, 0x47,
+	0xb4, 0xd2, 0x8a, 0x77, 0x2e, 0x22, 0x42, 0xfa, 0xf0, 0x82, 0x86, 0x70,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x1a, 0x11, 0x5a,
+	0x4a, 0xea, 0xae, 0x0a, 0x88, 0x53, 0x09, 0x1a, 0x75, 0xc4, 0x40, 0x1d,
+	0x74, 0x03, 0x44, 0xc8, 0xe3, 0xca, 0x1b, 0xab, 0xee, 0x22, 0xb3, 0xc1,
+	0xef, 0xe6, 0xb8, 0x16, 0x29, 0x07, 0xd8, 0x0b, 0x7e, 0x67, 0xcb, 0xea,
+	0xbd, 0x27, 0x8e, 0x0f, 0x28, 0xac, 0xe6, 0x6d, 0x47, 0x5d, 0x6f, 0x17,
+	0xa2, 0xf8, 0x5d, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x48, 0xea, 0x89, 0x16, 0x74, 0x70, 0x2c, 0x27, 0x93, 0x3a, 0xe7, 0x20,
+	0x03, 0xd8, 0x35, 0x5c, 0xae, 0xaa, 0x2e, 0xc8, 0x45, 0xf3, 0x13, 0xcf,
+	0x65, 0x8d, 0x10, 0x93, 0x53, 0xac, 0x9b, 0x68, 0xf9, 0x03, 0x46, 0x41,
+	0xf4, 0xc5, 0x9e, 0x04, 0x94, 0x79, 0x6e, 0x6f, 0x8c, 0xf5, 0x09, 0x0d,
+	0xfe, 0x92, 0x82, 0x98, 0x01, 0x68, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0x7c, 0x5d, 0xa1, 0x01, 0x26, 0xe6, 0x0a,
+	0x7d, 0x9c, 0xb0, 0xbf, 0x8b, 0xd0, 0x64, 0x3c, 0x38, 0x19, 0x81, 0x43,
+	0x4a, 0x57, 0xfd, 0x7a, 0x93, 0xc7, 0xc8, 0x0a, 0x2e, 0x56, 0x49, 0x07,
+	0x6e, 0x7d, 0x64, 0xed, 0x2b, 0x86, 0x53, 0x9f, 0x95, 0x74, 0xa7, 0x69,
+	0x3d, 0x96, 0x41, 0xb8, 0xca, 0x02, 0xfd, 0xf0, 0xa4, 0xc7, 0x18, 0x49,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x54, 0xe4, 0x81,
+	0xa7, 0xb6, 0x5e, 0x08, 0xe6, 0x8b, 0xc5, 0xb0, 0xad, 0x5a, 0xe3, 0x09,
+	0x31, 0xe5, 0x2b, 0x5d, 0xa1, 0x4f, 0xac, 0x93, 0x49, 0x22, 0xac, 0xfc,
+	0x61, 0x47, 0x51, 0xde, 0xae, 0x8a, 0xd9, 0x9f, 0xcb, 0x9f, 0xcf, 0x78,
+	0xa5, 0x13, 0xf5, 0xcf, 0xd3, 0xc1, 0x49, 0x5a, 0x7b, 0x8e, 0xf0, 0x5e,
+	0xad, 0x9d, 0x6e, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x94, 0x0a, 0x05, 0x03, 0x02, 0x48, 0xa0, 0x7a, 0xd0, 0x3e, 0x53, 0x73,
+	0x6a, 0x9c, 0xee, 0x03, 0x98, 0xe2, 0x60, 0x2a, 0x65, 0x78, 0xbd, 0x89,
+	0x8b, 0x00, 0x67, 0x61, 0x20, 0x81, 0x49, 0xbc, 0xc9, 0x3b, 0x4f, 0x19,
+	0x91, 0x54, 0xba, 0x9d, 0x7c, 0xe1, 0x80, 0xed, 0x74, 0x4f, 0x88, 0x04,
+	0xf5, 0x9b, 0x56, 0xd3, 0x3c, 0x9c, 0xfb, 0xc0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xac, 0x49, 0xa7, 0x7e, 0x71, 0xf8, 0xba, 0x16,
+	0xaa, 0xda, 0x08, 0x92, 0x96, 0xbc, 0xa5, 0x33, 0x3e, 0xbc, 0xff, 0x50,
+	0xe0, 0xba, 0x41, 0x43, 0xeb, 0x2c, 0x10, 0x58, 0x9f, 0x85, 0xa7, 0xd9,
+	0xb1, 0x2d, 0x3a, 0xb4, 0x62, 0x08, 0x91, 0x73, 0xaa, 0x42, 0x1e, 0x96,
+	0x63, 0xf3, 0x1b, 0xaf, 0xcf, 0x76, 0x7b, 0x41, 0x8b, 0x69, 0x26, 0x05,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xa3, 0x1f, 0xb3,
+	0x67, 0xef, 0x7b, 0xfb, 0x4b, 0xfc, 0x59, 0x9e, 0xe7, 0xab, 0xb6, 0x35,
+	0xa2, 0xf1, 0xdf, 0xd6, 0x1d, 0x9e, 0xbb, 0xfd, 0x91, 0x6a, 0x7f, 0x0c,
+	0xc6, 0x2c, 0x07, 0x69, 0x64, 0xd0, 0xda, 0xb3, 0xc6, 0xbf, 0x62, 0x1e,
+	0x4d, 0x48, 0xd5, 0xb4, 0xa4, 0x43, 0xff, 0x91, 0x87, 0xc6, 0x54, 0x10,
+	0xf9, 0xd6, 0xb3, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4f, 0x95, 0x17, 0xe1, 0xf7, 0x38, 0x63, 0x16, 0x3b, 0x02, 0x2f, 0x5a,
+	0x45, 0x64, 0xf1, 0x93, 0xa1, 0xf1, 0xe4, 0x29, 0x62, 0x7c, 0x0c, 0x50,
+	0x3b, 0x49, 0x55, 0x86, 0x9d, 0xc3, 0xe7, 0xf8, 0xc4, 0x65, 0x30, 0x58,
+	0xee, 0x3e, 0x1f, 0x9b, 0x6f, 0x2a, 0xea, 0x23, 0x27, 0x9a, 0x0e, 0xe7,
+	0x6b, 0x96, 0x4b, 0xcb, 0x21, 0xae, 0x1b, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa6, 0x88, 0x80, 0x5b, 0xfb, 0x9f, 0xee, 0x70,
+	0x2b, 0xd4, 0xb4, 0x7d, 0x2c, 0x05, 0x9a, 0xea, 0x0b, 0xa5, 0xeb, 0xc0,
+	0x9f, 0x6c, 0x66, 0x8c, 0xc5, 0x6a, 0x36, 0x87, 0x04, 0xd2, 0x1a, 0x83,
+	0xa5, 0xcf, 0x38, 0xd9, 0x74, 0x52, 0xd3, 0x9c, 0xeb, 0xa4, 0xf9, 0x26,
+	0xf3, 0xc0, 0xdc, 0x94, 0xc0, 0x7f, 0x54, 0x87, 0x62, 0x77, 0x2d, 0x4c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x16, 0x58, 0x49,
+	0xb1, 0x96, 0x15, 0x03, 0x33, 0x7e, 0x44, 0xc4, 0xd6, 0xa6, 0xcb, 0x61,
+	0x57, 0x2b, 0x93, 0x72, 0x8b, 0xad, 0x37, 0xbf, 0x80, 0x3d, 0x79, 0x52,
+	0x0c, 0x18, 0x30, 0x38, 0xc9, 0x69, 0xec, 0x11, 0x45, 0x14, 0x9e, 0xe5,
+	0x47, 0x4d, 0xbb, 0x1b, 0x2c, 0x91, 0x6d, 0x6e, 0x09, 0xf7, 0xbc, 0xc9,
+	0x25, 0x12, 0x98, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc1, 0x16, 0xd7, 0xe8, 0x42, 0x8e, 0xa5, 0x9a, 0xc4, 0x93, 0xc7, 0x86,
+	0x84, 0x45, 0x8e, 0x0f, 0x05, 0x20, 0xfa, 0x16, 0xad, 0xcc, 0x8a, 0x10,
+	0x99, 0x1b, 0x69, 0x56, 0x19, 0xb2, 0x99, 0xc3, 0x2f, 0x4a, 0xf8, 0x11,
+	0x87, 0x99, 0x26, 0x14, 0x81, 0x71, 0xc6, 0x77, 0x84, 0x6b, 0x8d, 0xe2,
+	0xc8, 0xf1, 0x9a, 0x5a, 0x66, 0x67, 0x7d, 0x52, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xbd, 0xd3, 0x7a, 0x37, 0x12, 0x9e, 0xc2, 0x18,
+	0x96, 0x1d, 0x51, 0x31, 0xd9, 0x28, 0xcd, 0x7d, 0xc3, 0x07, 0x9d, 0x98,
+	0xcf, 0x06, 0x82, 0x77, 0xa7, 0xbf, 0xb0, 0xae, 0x7d, 0x8a, 0xc3, 0x0d,
+	0x65, 0xe9, 0x66, 0x91, 0xb6, 0xff, 0x97, 0xb8, 0x67, 0xad, 0x51, 0xd0,
+	0xae, 0x5b, 0x70, 0x7a, 0x25, 0x6e, 0x41, 0x58, 0x62, 0xc3, 0xc8, 0xcb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xb1, 0x7f,
+	0xfd, 0x70, 0x84, 0xba, 0x1e, 0xcf, 0x48, 0x23, 0xcd, 0x84, 0xdf, 0x17,
+	0x06, 0x1e, 0x97, 0x93, 0xad, 0x67, 0x18, 0x97, 0xee, 0xc8, 0xd8, 0x6a,
+	0x20, 0x89, 0x5a, 0x9e, 0x54, 0x9c, 0xd7, 0x22, 0x4b, 0xde, 0x69, 0xfd,
+	0x6b, 0x28, 0xbb, 0x68, 0xfa, 0x05, 0x42, 0xe7, 0x79, 0x65, 0xe5, 0x6d,
+	0x16, 0x71, 0x76, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6c, 0x12, 0x82, 0xb8, 0x7e, 0x03, 0x01, 0x68, 0x5a, 0x51, 0x60, 0xf1,
+	0xe3, 0xd0, 0x45, 0x67, 0x2f, 0x47, 0x4d, 0xb4, 0x97, 0x5c, 0xbd, 0x13,
+	0x50, 0x89, 0xfe, 0x19, 0x4e, 0x4f, 0xad, 0x05, 0x17, 0x3a, 0x84, 0x33,
+	0xaa, 0x15, 0x75, 0xdb, 0x59, 0x34, 0x4c, 0x01, 0xa2, 0x54, 0xc3, 0x21,
+	0x4e, 0xbd, 0x2b, 0xf3, 0x23, 0x19, 0xef, 0xa0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfa, 0x3e, 0x81, 0xb5, 0xd9, 0xe3, 0x5e, 0x50,
+	0xa9, 0x76, 0xc7, 0x31, 0x06, 0x82, 0xf1, 0xc8, 0xc6, 0x6c, 0x9f, 0xa6,
+	0xad, 0x6b, 0x6d, 0x1b, 0x1d, 0x2f, 0xa1, 0x01, 0xd7, 0x72, 0x99, 0x08,
+	0xc1, 0x2f, 0x29, 0xe4, 0x63, 0xc0, 0x32, 0x66, 0x7f, 0x32, 0x55, 0xbd,
+	0x93, 0x0f, 0x10, 0xef, 0x83, 0x29, 0x35, 0x55, 0xba, 0xe0, 0x8c, 0x3f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x71, 0x81, 0x3f,
+	0x62, 0x01, 0xb6, 0x6d, 0xe0, 0x21, 0xac, 0x3a, 0x82, 0x88, 0x77, 0x61,
+	0x3c, 0xea, 0xa0, 0x07, 0x7d, 0x10, 0xd7, 0xaf, 0x17, 0xef, 0x0a, 0x4e,
+	0x44, 0xb4, 0x8b, 0x65, 0x3b, 0x58, 0xc6, 0xb0, 0xec, 0x88, 0x69, 0xb5,
+	0x7a, 0x03, 0xf1, 0xdc, 0x36, 0x05, 0x20, 0xfc, 0xcd, 0xe5, 0x6c, 0x3a,
+	0x19, 0xb3, 0x62, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5c, 0x7c, 0x07, 0xc6, 0xb7, 0x1f, 0x25, 0xdf, 0x7d, 0x8d, 0x81, 0x61,
+	0xeb, 0x3e, 0xbf, 0xe7, 0x10, 0x81, 0xf1, 0x85, 0x40, 0xcb, 0x60, 0xf1,
+	0xae, 0x1a, 0xba, 0xc5, 0xda, 0x60, 0x1c, 0x0f, 0x6d, 0x47, 0xfd, 0xa2,
+	0x56, 0x13, 0x67, 0x02, 0x7c, 0xd9, 0xc5, 0x56, 0x32, 0x69, 0x12, 0xc7,
+	0x8f, 0x2f, 0x31, 0x2c, 0x0f, 0xd2, 0x94, 0x69, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0x20, 0x93, 0x21, 0xb2, 0x35, 0xf1,
+	0x80, 0x14, 0x8e, 0xf1, 0x0c, 0x28, 0x62, 0x8d, 0xb8, 0xcf, 0x6c, 0x9e,
+	0xf6, 0xdb, 0x18, 0x16, 0x0b, 0xbd, 0xe9, 0xb4, 0xa3, 0x75, 0xee, 0xb2,
+	0x55, 0x1e, 0x4c, 0xc7, 0xa7, 0x74, 0xe8, 0x0e, 0x8f, 0xb7, 0xa8, 0x04,
+	0xf3, 0xeb, 0x1c, 0x35, 0xd6, 0x1d, 0x1b, 0x2a, 0x51, 0x10, 0xa2, 0x67,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x1c, 0x40, 0x29,
+	0xfa, 0x43, 0x18, 0x0c, 0x4c, 0xc0, 0xcd, 0x55, 0x99, 0xd0, 0xb9, 0xb4,
+	0x55, 0x69, 0x7d, 0xad, 0x99, 0xb8, 0xec, 0x62, 0x0c, 0x3b, 0x71, 0x11,
+	0xf0, 0xba, 0x59, 0x19, 0x93, 0xef, 0xcd, 0x2c, 0x29, 0x02, 0x8b, 0x76,
+	0x85, 0x21, 0xc1, 0xad, 0x72, 0x67, 0x87, 0xd1, 0x8f, 0xc6, 0x05, 0xe7,
+	0x82, 0x4e, 0x95, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
 const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p192,
@@ -1267,7 +1835,15 @@ const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p256_sm2,
 		.len = sizeof(ae_fpm_tbl_p256_sm2)
-	}
+	},
+	{
+		.data = ae_fpm_tbl_ed25519,
+		.len = sizeof(ae_fpm_tbl_ed25519)
+	},
+	{
+		.data = ae_fpm_tbl_ed448,
+		.len = sizeof(ae_fpm_tbl_ed448)
+	},
 };
 
 int
diff --git a/drivers/crypto/cnxk/cnxk_ae.h b/drivers/crypto/cnxk/cnxk_ae.h
index ef9cb5eb91..c75ff615ec 100644
--- a/drivers/crypto/cnxk/cnxk_ae.h
+++ b/drivers/crypto/cnxk/cnxk_ae.h
@@ -15,6 +15,8 @@
 
 #define ASYM_SESS_SIZE sizeof(struct rte_cryptodev_asym_session)
 
+#define CNXK_AE_EDDSA_MAX_PARAM_LEN 1024
+
 struct cnxk_ae_sess {
 	uint8_t rte_sess[ASYM_SESS_SIZE];
 	enum rte_crypto_asym_xform_type xfrm_type;
@@ -25,10 +27,12 @@ struct cnxk_ae_sess {
 	};
 	uint64_t *cnxk_fpm_iova;
 	struct roc_ae_ec_group **ec_grp;
+	uint64_t cpt_inst_w4;
 	uint64_t cpt_inst_w7;
 	uint64_t cpt_inst_w2;
 	struct cnxk_cpt_qp *qp;
 	struct roc_cpt_lf *lf;
+	uint64_t msg_max_sz;
 	struct hw_ctx_s {
 		union {
 			struct {
@@ -181,10 +185,10 @@ cnxk_ae_fill_rsa_params(struct cnxk_ae_sess *sess,
 }
 
 static __rte_always_inline int
-cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
-		       struct rte_crypto_asym_xform *xform)
+cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess, struct rte_crypto_asym_xform *xform)
 {
 	struct roc_ae_ec_ctx *ec = &sess->ec_ctx;
+	union cpt_inst_w4 w4;
 
 	switch (xform->ec.curve_id) {
 	case RTE_CRYPTO_EC_GROUP_SECP192R1:
@@ -205,6 +209,14 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_EC_GROUP_SM2:
 		ec->curveid = ROC_AE_EC_ID_SM2;
 		break;
+	case RTE_CRYPTO_EC_GROUP_ED25519:
+		ec->curveid = ROC_AE_EC_ID_ED25519;
+		w4.s.param1 = ROC_AE_ED_PARAM1_25519;
+		break;
+	case RTE_CRYPTO_EC_GROUP_ED448:
+		ec->curveid = ROC_AE_EC_ID_ED448;
+		w4.s.param1 = ROC_AE_ED_PARAM1_448;
+		break;
 	default:
 		/* Only NIST curves (FIPS 186-4) and SM2 are supported */
 		return -EINVAL;
@@ -225,12 +237,22 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	if (ec->q.x.length)
 		rte_memcpy(ec->q.x.data, xform->ec.q.x.data, ec->q.x.length);
 
+	if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_EDDSA) {
+		w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+
+		/* Use q.x to store compressed public key. q.y is set to 0 */
+		ec->q.y.length = 0;
+		goto _exit;
+	}
+
 	ec->q.y.length = xform->ec.q.y.length;
 	if (ec->q.y.length > ROC_AE_EC_DATA_MAX)
 		ec->q.y.length = ROC_AE_EC_DATA_MAX;
 	if (xform->ec.q.y.length)
 		rte_memcpy(ec->q.y.data, xform->ec.q.y.data, ec->q.y.length);
 
+_exit:
+	sess->cpt_inst_w4 = w4.u64;
 	return 0;
 }
 
@@ -241,6 +263,7 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
 	int ret;
 
 	sess->xfrm_type = xform->xform_type;
+	sess->msg_max_sz = cnxk_cpt_asym_get_mlen();
 
 	switch (xform->xform_type) {
 	case RTE_CRYPTO_ASYM_XFORM_RSA:
@@ -255,6 +278,7 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
 	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
 		ret = cnxk_ae_fill_ec_params(sess, xform);
 		break;
 	default:
@@ -736,6 +760,310 @@ cnxk_ae_enqueue_ecdsa_op(struct rte_crypto_op *op,
 	return 0;
 }
 
+static __rte_always_inline void
+cnxk_ae_eddsa_sign_prep(struct rte_crypto_eddsa_op_param *eddsa, struct roc_ae_buf_ptr *meta_buf,
+			uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
+			struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t pkey_len = sess->ec_ctx.pkey.length;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint16_t ctx_align, k_align;
+	uint8_t pub = 0, ph = 0;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint8_t ctx_len = 0;
+	uint16_t iv_len = 0;
+	uint64_t ctrl = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+	    eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519)
+		iv_len = sizeof(iv_sha512);
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	if (pubkey_len)
+		pub = 1;
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pkey_len, 8);
+
+	/* Set control word */
+	ctrl = message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(priv and
+	 * pubkey len), ROUNDUP8(context len) and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) + sizeof(ctrl) + prime_len * 3 +
+		k_align * 2 + ctx_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.pkey.data, pkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.u64 = sess->cpt_inst_w4;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_SIGN;
+	w4.s.param1 |= ((pub << ROC_AE_ED_PARAM1_KEYGEN_BIT) | (ph << ROC_AE_EC_PARAM1_PH_BIT));
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline void
+cnxk_ae_eddsa_verify_prep(struct rte_crypto_eddsa_op_param *eddsa, struct roc_ae_buf_ptr *meta_buf,
+			  uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
+			  struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t s_len = eddsa->sign.length / 2;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	uint16_t ctx_align, k_align, s_align;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint16_t iv_len = 0;
+	uint8_t ctx_len = 0;
+	uint64_t ctrl = 0;
+	uint8_t ph = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+	    eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519)
+		iv_len = sizeof(iv_sha512);
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pubkey_len, 8);
+	s_align = RTE_ALIGN_CEIL(s_len, 8);
+
+	/* Set control word */
+	ctrl = message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(pub key len),
+	 * ROUNDUP8(s and r len), context and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) + sizeof(ctrl) + prime_len * 3 +
+		k_align + s_align * 2 +	ctx_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, eddsa->sign.data, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, eddsa->sign.data + s_len, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.u64 = sess->cpt_inst_w4;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_VERIFY;
+
+	w4.s.param1 |= (ph << ROC_AE_EC_PARAM1_PH_BIT);
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline int __rte_hot
+cnxk_ae_enqueue_eddsa_op(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
+			 struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
+			 struct roc_ae_ec_group **ec_grp, struct cpt_inst_s *inst)
+{
+	struct rte_crypto_eddsa_op_param *eddsa = &op->asym->eddsa;
+	uint8_t curveid = sess->ec_ctx.curveid;
+
+	if (eddsa->message.length > (sess->msg_max_sz - CNXK_AE_EDDSA_MAX_PARAM_LEN)) {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+		cnxk_ae_eddsa_sign_prep(eddsa, meta_buf, fpm_iova[curveid],	ec_grp[curveid], sess,
+					  inst);
+	else if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		cnxk_ae_eddsa_verify_prep(eddsa, meta_buf, fpm_iova[curveid], ec_grp[curveid], sess,
+					  inst);
+	else {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static __rte_always_inline void
 cnxk_ae_sm2_sign_prep(struct rte_crypto_sm2_op_param *sm2,
 			struct roc_ae_buf_ptr *meta_buf,
@@ -1004,6 +1332,81 @@ cnxk_ae_ecfpm_prep(rte_crypto_param *scalar,
 	return 0;
 }
 
+static __rte_always_inline int
+cnxk_ae_edfpm_prep(rte_crypto_param *scalar, struct roc_ae_buf_ptr *meta_buf, uint64_t *fpm_iova,
+		   struct roc_ae_ec_group *ec_grp, uint8_t curveid, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	uint16_t dlen, prime_len, order_len, iv_len;
+	uint64_t fpm_table_iova;
+	uint16_t scalar_align;
+	union cpt_inst_w4 w4;
+	uint16_t prime_bit;
+	uint8_t *dptr;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	fpm_table_iova = (uint64_t)fpm_iova[curveid];
+
+	/* Input buffer */
+	dptr = meta_buf->vaddr;
+	inst->dptr = (uintptr_t)dptr;
+
+	scalar_align = RTE_ALIGN_CEIL(scalar->length, 8);
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(prime len, order len, constant,
+	 * private key len and iv len (if ED25519))).
+	 */
+	dlen = sizeof(fpm_table_iova) + 3 * prime_len + scalar_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, scalar->data, scalar->length);
+	dptr += scalar_align;
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, sizeof(iv_sha512));
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_KEYGEN;
+
+	w4.s.param1 = prime_bit;
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+
+	return 0;
+}
+
 static __rte_always_inline int
 cnxk_ae_ecpm_prep(rte_crypto_param *scalar, struct rte_crypto_ec_point *p,
 		  struct roc_ae_buf_ptr *meta_buf,
@@ -1112,8 +1515,12 @@ cnxk_ae_enqueue_ecdh_op(struct rte_crypto_op *op,
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		scalar.data = sess->ec_ctx.pkey.data;
 		scalar.length = sess->ec_ctx.pkey.length;
-		cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
-			curveid, inst);
+		if (curveid == ROC_AE_EC_ID_ED25519 || curveid == ROC_AE_EC_ID_ED448)
+			cnxk_ae_edfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
+		else
+			cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		scalar.data = ec_grp[curveid]->order.data;
@@ -1212,6 +1619,25 @@ cnxk_ae_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa, uint8_t *rptr,
 	ecdsa->s.length = prime_len;
 }
 
+static __rte_always_inline void
+cnxk_ae_dequeue_eddsa_op(struct rte_crypto_eddsa_op_param *eddsa, uint8_t *rptr)
+{
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519 ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519CTX ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH) {
+		eddsa->sign.length = 64;
+		memcpy(eddsa->sign.data, rptr, eddsa->sign.length);
+	} else {
+		eddsa->sign.length = 114;
+		memcpy(eddsa->sign.data, rptr, 57);
+		memcpy(eddsa->sign.data + 57, rptr + 64, 57);
+	}
+}
+
 static __rte_always_inline void
 cnxk_ae_dequeue_sm2_op(struct rte_crypto_sm2_op_param *sm2, uint8_t *rptr,
 			 struct roc_ae_ec_ctx *ec,
@@ -1245,7 +1671,7 @@ cnxk_ae_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param *ecpm, uint8_t *rptr,
 static __rte_always_inline void
 cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 			struct roc_ae_ec_ctx *ec,
-			struct roc_ae_ec_group **ec_grp)
+			struct roc_ae_ec_group **ec_grp, uint16_t flags)
 {
 	int prime_len = ec_grp[ec->curveid]->prime.length;
 
@@ -1256,9 +1682,12 @@ cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		memcpy(ecdh->pub_key.x.data, rptr, prime_len);
-		memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
 		ecdh->pub_key.x.length = prime_len;
-		ecdh->pub_key.y.length = prime_len;
+		if (!(flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED)) {
+			memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8),
+				prime_len);
+			ecdh->pub_key.y.length = prime_len;
+		}
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		break;
@@ -1328,6 +1757,13 @@ cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		ret = cnxk_ae_enqueue_eddsa_op(op, &meta_buf, sess,
+					       sess->cnxk_fpm_iova,
+					       sess->ec_grp, inst);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		ret = cnxk_ae_enqueue_sm2_op(op, &meta_buf, sess,
 					       sess->cnxk_fpm_iova,
@@ -1390,6 +1826,9 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		cnxk_ae_dequeue_ecdsa_op(&op->ecdsa, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		cnxk_ae_dequeue_eddsa_op(&op->eddsa, rptr);
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		cnxk_ae_dequeue_sm2_op(&op->sm2, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
@@ -1401,7 +1840,7 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_ECDH:
 		cnxk_ae_dequeue_ecdh_op(&op->ecdh, rptr, &sess->ec_ctx,
-					sess->ec_grp);
+					sess->ec_grp, op->flags);
 		break;
 	default:
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index 4000e84a7e..5cec64c2e1 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -11,7 +11,7 @@
 #include "roc_ae.h"
 #include "roc_cpt.h"
 
-#define CNXK_CPT_MAX_CAPS		 55
+#define CNXK_CPT_MAX_CAPS		 56
 #define CNXK_SEC_IPSEC_CRYPTO_MAX_CAPS	 16
 #define CNXK_SEC_TLS_1_3_CRYPTO_MAX_CAPS 3
 #define CNXK_SEC_TLS_1_2_CRYPTO_MAX_CAPS 7
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index 0d5d64b6e7..3897feacb8 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -1201,6 +1201,22 @@ static const struct rte_cryptodev_capabilities caps_sm2[] = {
 	}
 };
 
+static const struct rte_cryptodev_capabilities caps_eddsa[] = {
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					     (1 << RTE_CRYPTO_ASYM_OP_VERIFY))
+			}
+		}
+		}
+	}
+};
+
 static const struct rte_cryptodev_capabilities caps_end[] = {
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1940,6 +1956,9 @@ cn10k_crypto_caps_add(struct rte_cryptodev_capabilities cnxk_caps[],
 
 	if (hw_caps[CPT_ENG_TYPE_AE].sm2)
 		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, sm2);
+
+	if (hw_caps[CPT_ENG_TYPE_AE].eddsa)
+		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, eddsa);
 }
 
 static void
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index cfcfa79fdf..3bb4101946 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -65,7 +65,7 @@ cnxk_cpt_sec_get_mlen(void)
 	return len;
 }
 
-static int
+int
 cnxk_cpt_asym_get_mlen(void)
 {
 	uint32_t len;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
index caf6ac35e5..bc05266552 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
@@ -104,6 +104,8 @@ struct cnxk_cpt_qp {
 	/**< Session mempool */
 };
 
+int cnxk_cpt_asym_get_mlen(void);
+
 int cnxk_cpt_dev_config(struct rte_cryptodev *dev,
 			struct rte_cryptodev_config *conf);
 
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v4 4/6] test/crypto: add asymmetric EDDSA test cases
  2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-10-03 17:56         ` [PATCH v4 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
  2024-10-03 17:56         ` [PATCH v4 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
@ 2024-10-03 17:56         ` Gowrishankar Muthukrishnan
  2024-10-03 17:56         ` [PATCH v4 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
                           ` (2 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-03 17:56 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, jerinj, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Gowrishankar Muthukrishnan

Add test cases to validate EDDSA sign and verify ops,
as per RFC 8032.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test/test_cryptodev_asym.c               | 345 +++++++++++-
 app/test/test_cryptodev_ecdh_test_vectors.h  |  94 +++-
 app/test/test_cryptodev_ecdsa_test_vectors.h |   4 +
 app/test/test_cryptodev_eddsa_test_vectors.h | 556 +++++++++++++++++++
 4 files changed, 990 insertions(+), 9 deletions(-)
 create mode 100644 app/test/test_cryptodev_eddsa_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index f0b5d38543..893cc81770 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -20,6 +20,7 @@
 #include "test_cryptodev_ecdh_test_vectors.h"
 #include "test_cryptodev_ecdsa_test_vectors.h"
 #include "test_cryptodev_ecpm_test_vectors.h"
+#include "test_cryptodev_eddsa_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_sm2_test_vectors.h"
@@ -1631,6 +1632,9 @@ test_ecdsa_sign_verify_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
+		if (curve_id == ED25519 || curve_id == ED448)
+			continue;
+
 		status = test_ecdsa_sign_verify(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
@@ -1792,7 +1796,7 @@ test_ecpm_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecpm(curve_id);
@@ -1966,10 +1970,18 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	idx.type = RTE_CRYPTO_ASYM_XFORM_ECDH;
 	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
 	if (capa == NULL)
-		return -ENOTSUP;
+		return TEST_SKIPPED;
 
 	if (!(capa->op_types & (1 <<  RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)))
-		return -ENOTSUP;
+		return TEST_SKIPPED;
+
+	if (curve_id == ED25519 || curve_id == ED448) {
+		/* Check EDDSA capability */
+		idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+		if (capa == NULL)
+			return TEST_SKIPPED;
+	}
 
 	switch (curve_id) {
 	case SECP192R1:
@@ -1987,6 +1999,12 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	case SECP521R1:
 		input_params = ecdh_param_secp521r1;
 		break;
+	case ED25519:
+		input_params = ecdh_param_ed25519;
+		break;
+	case ED448:
+		input_params = ecdh_param_ed448;
+		break;
 	default:
 		RTE_LOG(ERR, USER1,
 				"line %u FAILED: %s", __LINE__,
@@ -2031,10 +2049,15 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 
 	/* Populate op with operational details */
 	asym_op->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
 
 	/* Init out buf */
 	asym_op->ecdh.pub_key.x.data = output_buf_x;
-	asym_op->ecdh.pub_key.y.data = output_buf_y;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->ecdh.pub_key.y.data = NULL;
+	else
+		asym_op->ecdh.pub_key.y.data = output_buf_y;
 
 	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
 
@@ -2073,8 +2096,13 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	debug_hexdump(stdout, "qy:",
 		asym_op->ecdh.pub_key.y.data, asym_op->ecdh.pub_key.y.length);
 
-	ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
+	if (curve_id == ED25519 || curve_id == ED448)
+		ret = memcmp(input_params.pubkey_qA_x.data, result_op->asym->ecdh.pub_key.x.data,
+			   result_op->asym->ecdh.pub_key.x.length);
+	else
+		ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
 				input_params.pubkey_qA_y.data, result_op);
+
 	if (ret) {
 		status = TEST_FAILED;
 		RTE_LOG(ERR, USER1,
@@ -2484,7 +2512,7 @@ test_ecdh_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_priv_key_generate(curve_id);
@@ -2505,6 +2533,8 @@ test_ecdh_all_curve(void)
 		status = test_ecdh_pub_key_generate(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
 		} else {
 			msg = "failed";
 			overall_status = status;
@@ -2514,7 +2544,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_pub_key_verify(curve_id);
@@ -2529,7 +2559,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_shared_secret(curve_id);
@@ -3167,6 +3197,303 @@ test_sm2_dec(void)
 	return status;
 };
 
+static int
+test_eddsa_sign(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.data = input_params->pkey.data;
+	xform.ec.pkey.length = input_params->pkey.length;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	/* Init out buf */
+	asym_op->eddsa.sign.data = output_buf_r;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "sign:",
+			asym_op->eddsa.sign.data, asym_op->eddsa.sign.length);
+
+	/* Verify sign (by comparison). */
+	if (memcmp(input_params->sign.data, asym_op->eddsa.sign.data,
+			   asym_op->eddsa.sign.length) != 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"EDDSA sign failed.\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_verify(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.length = 0;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	asym_op->eddsa.sign.data = input_params->sign.data;
+	asym_op->eddsa.sign.length = input_params->sign.length;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_sign_verify_all_curve(void)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct crypto_testsuite_eddsa_params input_params;
+	struct rte_cryptodev_asym_capability_idx idx;
+	int status, overall_status = TEST_SUCCESS;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	uint8_t i, tc = 0;
+	const char *msg;
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return TEST_SKIPPED;
+
+	/* Sign tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_sign(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Sign %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Verify tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_verify(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Verify %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Negative tests */
+	memcpy(&input_params, &eddsa_test_params[1],
+			sizeof(input_params));
+	input_params.pubkey.data[0] ^= 0x01;
+
+	status = test_eddsa_sign(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Sign %s  %s\n",
+			tc++, input_params.description, msg);
+
+	status = test_eddsa_verify(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Verify %s  %s\n",
+			tc++, input_params.description, msg);
+
+	return overall_status;
+}
+
 static int send_one(void)
 {
 	int ticks = 0;
@@ -3543,6 +3870,7 @@ static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 			"Modex Group 18 test",
 			ut_setup_asym, ut_teardown_asym,
 			modular_exponentiation, &modex_group_test_cases[5]),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
@@ -3634,6 +3962,7 @@ static struct unit_test_suite cryptodev_octeontx_asym_testsuite  = {
 				test_ecdh_all_curve),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
 				test_ecpm_all_curve),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_ecdh_test_vectors.h b/app/test/test_cryptodev_ecdh_test_vectors.h
index b577c179c8..36f92b223f 100644
--- a/app/test/test_cryptodev_ecdh_test_vectors.h
+++ b/app/test/test_cryptodev_ecdh_test_vectors.h
@@ -553,4 +553,96 @@ struct crypto_testsuite_ecdh_params ecdh_param_secp521r1 = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP521R1
 };
 
-#endif /* __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__ */
+/** ED25519 test vector */
+
+static uint8_t privkey_ed25519[] = {
+	0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+	0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+	0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+	0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+};
+
+static uint8_t pubkey_ed25519[] = {
+	0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+	0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+	0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+	0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+};
+
+/** ECDH ED25519 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed25519 = {
+	.pubkey_qA_x = {
+		.data = pubkey_ed25519,
+		.length = sizeof(pubkey_ed25519),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = privkey_ed25519,
+		.length = sizeof(privkey_ed25519),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519
+};
+
+/** ED448 test vector */
+
+static uint8_t privkey_ed448[] = {
+	0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+	0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+	0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+	0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+	0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+	0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+	0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+	0x01
+};
+
+static uint8_t pubkey_ed448[] = {
+	0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+	0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+	0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+	0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+	0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+	0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+	0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+	0x00
+};
+
+/** ECDH ED448 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed448 = {
+	.pubkey_qA_x = {
+		.data = pubkey_ed448,
+		.length = sizeof(pubkey_ed448),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = privkey_ed448,
+		.length = sizeof(privkey_ed448),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448
+};
+
+#endif /* __TEST_CRYPTODEV_ECDH_TEST_VECTORS_H__ */
diff --git a/app/test/test_cryptodev_ecdsa_test_vectors.h b/app/test/test_cryptodev_ecdsa_test_vectors.h
index f1477639ba..636a1ab1b2 100644
--- a/app/test/test_cryptodev_ecdsa_test_vectors.h
+++ b/app/test/test_cryptodev_ecdsa_test_vectors.h
@@ -15,6 +15,8 @@ enum curve {
 	SECP384R1,
 	SECP521R1,
 	SECP521R1_UA,
+	ED25519,
+	ED448,
 	END_OF_CURVE_LIST
 };
 
@@ -24,6 +26,8 @@ const char *curve[] = {"SECP192R1",
 		       "SECP384R1",
 		       "SECP521R1",
 		       "SECP521R1(unaligned)",
+		       "ED25519",
+		       "ED448",
 };
 
 struct crypto_testsuite_ecdsa_params {
diff --git a/app/test/test_cryptodev_eddsa_test_vectors.h b/app/test/test_cryptodev_eddsa_test_vectors.h
new file mode 100644
index 0000000000..47e5355ec7
--- /dev/null
+++ b/app/test/test_cryptodev_eddsa_test_vectors.h
@@ -0,0 +1,556 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifndef __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+#define DATA_SIZE 1024
+
+struct crypto_testsuite_eddsa_params {
+	enum rte_crypto_edward_instance instance;
+	enum rte_crypto_curve_id curve;
+	const char *description;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pubkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} sign;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} message;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} context;
+};
+
+/** EDDSA curve test params (RFC 8032) */
+static const struct
+crypto_testsuite_eddsa_params eddsa_test_params[] = {
+{
+	.description = "EDDSA 25519 (msg=0)",
+	.pkey = {
+		.data = {
+			0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
+			0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4,
+			0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19,
+			0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7,
+			0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a,
+			0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25,
+			0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72,
+			0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a,
+			0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74,
+			0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55,
+			0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
+			0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b,
+			0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
+			0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1)",
+	.pkey = {
+		.data = {
+			0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+			0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+			0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+			0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+			0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+			0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+			0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+			0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+			0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+			0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+			0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+			0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+			0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+			0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x72
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1023)",
+	.pkey = {
+		.data = {
+			0xf5, 0xe5, 0x76, 0x7c, 0xf1, 0x53, 0x31, 0x95,
+			0x17, 0x63, 0x0f, 0x22, 0x68, 0x76, 0xb8, 0x6c,
+			0x81, 0x60, 0xcc, 0x58, 0x3b, 0xc0, 0x13, 0x74,
+			0x4c, 0x6b, 0xf2, 0x55, 0xf5, 0xcc, 0x0e, 0xe5
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x27, 0x81, 0x17, 0xfc, 0x14, 0x4c, 0x72, 0x34,
+			0x0f, 0x67, 0xd0, 0xf2, 0x31, 0x6e, 0x83, 0x86,
+			0xce, 0xff, 0xbf, 0x2b, 0x24, 0x28, 0xc9, 0xc5,
+			0x1f, 0xef, 0x7c, 0x59, 0x7f, 0x1d, 0x42, 0x6e
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x0a, 0xab, 0x4c, 0x90, 0x05, 0x01, 0xb3, 0xe2,
+			0x4d, 0x7c, 0xdf, 0x46, 0x63, 0x32, 0x6a, 0x3a,
+			0x87, 0xdf, 0x5e, 0x48, 0x43, 0xb2, 0xcb, 0xdb,
+			0x67, 0xcb, 0xf6, 0xe4, 0x60, 0xfe, 0xc3, 0x50,
+			0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45,
+			0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b,
+			0x5e, 0x8f, 0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6,
+			0xac, 0x00, 0xa9, 0x70, 0x4a, 0x18, 0x8a, 0x03
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x08, 0xb8, 0xb2, 0xb7, 0x33, 0x42, 0x42, 0x43,
+			0x76, 0x0f, 0xe4, 0x26, 0xa4, 0xb5, 0x49, 0x08,
+			0x63, 0x21, 0x10, 0xa6, 0x6c, 0x2f, 0x65, 0x91,
+			0xea, 0xbd, 0x33, 0x45, 0xe3, 0xe4, 0xeb, 0x98,
+			0xfa, 0x6e, 0x26, 0x4b, 0xf0, 0x9e, 0xfe, 0x12,
+			0xee, 0x50, 0xf8, 0xf5, 0x4e, 0x9f, 0x77, 0xb1,
+			0xe3, 0x55, 0xf6, 0xc5, 0x05, 0x44, 0xe2, 0x3f,
+			0xb1, 0x43, 0x3d, 0xdf, 0x73, 0xbe, 0x84, 0xd8,
+			0x79, 0xde, 0x7c, 0x00, 0x46, 0xdc, 0x49, 0x96,
+			0xd9, 0xe7, 0x73, 0xf4, 0xbc, 0x9e, 0xfe, 0x57,
+			0x38, 0x82, 0x9a, 0xdb, 0x26, 0xc8, 0x1b, 0x37,
+			0xc9, 0x3a, 0x1b, 0x27, 0x0b, 0x20, 0x32, 0x9d,
+			0x65, 0x86, 0x75, 0xfc, 0x6e, 0xa5, 0x34, 0xe0,
+			0x81, 0x0a, 0x44, 0x32, 0x82, 0x6b, 0xf5, 0x8c,
+			0x94, 0x1e, 0xfb, 0x65, 0xd5, 0x7a, 0x33, 0x8b,
+			0xbd, 0x2e, 0x26, 0x64, 0x0f, 0x89, 0xff, 0xbc,
+			0x1a, 0x85, 0x8e, 0xfc, 0xb8, 0x55, 0x0e, 0xe3,
+			0xa5, 0xe1, 0x99, 0x8b, 0xd1, 0x77, 0xe9, 0x3a,
+			0x73, 0x63, 0xc3, 0x44, 0xfe, 0x6b, 0x19, 0x9e,
+			0xe5, 0xd0, 0x2e, 0x82, 0xd5, 0x22, 0xc4, 0xfe,
+			0xba, 0x15, 0x45, 0x2f, 0x80, 0x28, 0x8a, 0x82,
+			0x1a, 0x57, 0x91, 0x16, 0xec, 0x6d, 0xad, 0x2b,
+			0x3b, 0x31, 0x0d, 0xa9, 0x03, 0x40, 0x1a, 0xa6,
+			0x21, 0x00, 0xab, 0x5d, 0x1a, 0x36, 0x55, 0x3e,
+			0x06, 0x20, 0x3b, 0x33, 0x89, 0x0c, 0xc9, 0xb8,
+			0x32, 0xf7, 0x9e, 0xf8, 0x05, 0x60, 0xcc, 0xb9,
+			0xa3, 0x9c, 0xe7, 0x67, 0x96, 0x7e, 0xd6, 0x28,
+			0xc6, 0xad, 0x57, 0x3c, 0xb1, 0x16, 0xdb, 0xef,
+			0xef, 0xd7, 0x54, 0x99, 0xda, 0x96, 0xbd, 0x68,
+			0xa8, 0xa9, 0x7b, 0x92, 0x8a, 0x8b, 0xbc, 0x10,
+			0x3b, 0x66, 0x21, 0xfc, 0xde, 0x2b, 0xec, 0xa1,
+			0x23, 0x1d, 0x20, 0x6b, 0xe6, 0xcd, 0x9e, 0xc7,
+			0xaf, 0xf6, 0xf6, 0xc9, 0x4f, 0xcd, 0x72, 0x04,
+			0xed, 0x34, 0x55, 0xc6, 0x8c, 0x83, 0xf4, 0xa4,
+			0x1d, 0xa4, 0xaf, 0x2b, 0x74, 0xef, 0x5c, 0x53,
+			0xf1, 0xd8, 0xac, 0x70, 0xbd, 0xcb, 0x7e, 0xd1,
+			0x85, 0xce, 0x81, 0xbd, 0x84, 0x35, 0x9d, 0x44,
+			0x25, 0x4d, 0x95, 0x62, 0x9e, 0x98, 0x55, 0xa9,
+			0x4a, 0x7c, 0x19, 0x58, 0xd1, 0xf8, 0xad, 0xa5,
+			0xd0, 0x53, 0x2e, 0xd8, 0xa5, 0xaa, 0x3f, 0xb2,
+			0xd1, 0x7b, 0xa7, 0x0e, 0xb6, 0x24, 0x8e, 0x59,
+			0x4e, 0x1a, 0x22, 0x97, 0xac, 0xbb, 0xb3, 0x9d,
+			0x50, 0x2f, 0x1a, 0x8c, 0x6e, 0xb6, 0xf1, 0xce,
+			0x22, 0xb3, 0xde, 0x1a, 0x1f, 0x40, 0xcc, 0x24,
+			0x55, 0x41, 0x19, 0xa8, 0x31, 0xa9, 0xaa, 0xd6,
+			0x07, 0x9c, 0xad, 0x88, 0x42, 0x5d, 0xe6, 0xbd,
+			0xe1, 0xa9, 0x18, 0x7e, 0xbb, 0x60, 0x92, 0xcf,
+			0x67, 0xbf, 0x2b, 0x13, 0xfd, 0x65, 0xf2, 0x70,
+			0x88, 0xd7, 0x8b, 0x7e, 0x88, 0x3c, 0x87, 0x59,
+			0xd2, 0xc4, 0xf5, 0xc6, 0x5a, 0xdb, 0x75, 0x53,
+			0x87, 0x8a, 0xd5, 0x75, 0xf9, 0xfa, 0xd8, 0x78,
+			0xe8, 0x0a, 0x0c, 0x9b, 0xa6, 0x3b, 0xcb, 0xcc,
+			0x27, 0x32, 0xe6, 0x94, 0x85, 0xbb, 0xc9, 0xc9,
+			0x0b, 0xfb, 0xd6, 0x24, 0x81, 0xd9, 0x08, 0x9b,
+			0xec, 0xcf, 0x80, 0xcf, 0xe2, 0xdf, 0x16, 0xa2,
+			0xcf, 0x65, 0xbd, 0x92, 0xdd, 0x59, 0x7b, 0x07,
+			0x07, 0xe0, 0x91, 0x7a, 0xf4, 0x8b, 0xbb, 0x75,
+			0xfe, 0xd4, 0x13, 0xd2, 0x38, 0xf5, 0x55, 0x5a,
+			0x7a, 0x56, 0x9d, 0x80, 0xc3, 0x41, 0x4a, 0x8d,
+			0x08, 0x59, 0xdc, 0x65, 0xa4, 0x61, 0x28, 0xba,
+			0xb2, 0x7a, 0xf8, 0x7a, 0x71, 0x31, 0x4f, 0x31,
+			0x8c, 0x78, 0x2b, 0x23, 0xeb, 0xfe, 0x80, 0x8b,
+			0x82, 0xb0, 0xce, 0x26, 0x40, 0x1d, 0x2e, 0x22,
+			0xf0, 0x4d, 0x83, 0xd1, 0x25, 0x5d, 0xc5, 0x1a,
+			0xdd, 0xd3, 0xb7, 0x5a, 0x2b, 0x1a, 0xe0, 0x78,
+			0x45, 0x04, 0xdf, 0x54, 0x3a, 0xf8, 0x96, 0x9b,
+			0xe3, 0xea, 0x70, 0x82, 0xff, 0x7f, 0xc9, 0x88,
+			0x8c, 0x14, 0x4d, 0xa2, 0xaf, 0x58, 0x42, 0x9e,
+			0xc9, 0x60, 0x31, 0xdb, 0xca, 0xd3, 0xda, 0xd9,
+			0xaf, 0x0d, 0xcb, 0xaa, 0xaf, 0x26, 0x8c, 0xb8,
+			0xfc, 0xff, 0xea, 0xd9, 0x4f, 0x3c, 0x7c, 0xa4,
+			0x95, 0xe0, 0x56, 0xa9, 0xb4, 0x7a, 0xcd, 0xb7,
+			0x51, 0xfb, 0x73, 0xe6, 0x66, 0xc6, 0xc6, 0x55,
+			0xad, 0xe8, 0x29, 0x72, 0x97, 0xd0, 0x7a, 0xd1,
+			0xba, 0x5e, 0x43, 0xf1, 0xbc, 0xa3, 0x23, 0x01,
+			0x65, 0x13, 0x39, 0xe2, 0x29, 0x04, 0xcc, 0x8c,
+			0x42, 0xf5, 0x8c, 0x30, 0xc0, 0x4a, 0xaf, 0xdb,
+			0x03, 0x8d, 0xda, 0x08, 0x47, 0xdd, 0x98, 0x8d,
+			0xcd, 0xa6, 0xf3, 0xbf, 0xd1, 0x5c, 0x4b, 0x4c,
+			0x45, 0x25, 0x00, 0x4a, 0xa0, 0x6e, 0xef, 0xf8,
+			0xca, 0x61, 0x78, 0x3a, 0xac, 0xec, 0x57, 0xfb,
+			0x3d, 0x1f, 0x92, 0xb0, 0xfe, 0x2f, 0xd1, 0xa8,
+			0x5f, 0x67, 0x24, 0x51, 0x7b, 0x65, 0xe6, 0x14,
+			0xad, 0x68, 0x08, 0xd6, 0xf6, 0xee, 0x34, 0xdf,
+			0xf7, 0x31, 0x0f, 0xdc, 0x82, 0xae, 0xbf, 0xd9,
+			0x04, 0xb0, 0x1e, 0x1d, 0xc5, 0x4b, 0x29, 0x27,
+			0x09, 0x4b, 0x2d, 0xb6, 0x8d, 0x6f, 0x90, 0x3b,
+			0x68, 0x40, 0x1a, 0xde, 0xbf, 0x5a, 0x7e, 0x08,
+			0xd7, 0x8f, 0xf4, 0xef, 0x5d, 0x63, 0x65, 0x3a,
+			0x65, 0x04, 0x0c, 0xf9, 0xbf, 0xd4, 0xac, 0xa7,
+			0x98, 0x4a, 0x74, 0xd3, 0x71, 0x45, 0x98, 0x67,
+			0x80, 0xfc, 0x0b, 0x16, 0xac, 0x45, 0x16, 0x49,
+			0xde, 0x61, 0x88, 0xa7, 0xdb, 0xdf, 0x19, 0x1f,
+			0x64, 0xb5, 0xfc, 0x5e, 0x2a, 0xb4, 0x7b, 0x57,
+			0xf7, 0xf7, 0x27, 0x6c, 0xd4, 0x19, 0xc1, 0x7a,
+			0x3c, 0xa8, 0xe1, 0xb9, 0x39, 0xae, 0x49, 0xe4,
+			0x88, 0xac, 0xba, 0x6b, 0x96, 0x56, 0x10, 0xb5,
+			0x48, 0x01, 0x09, 0xc8, 0xb1, 0x7b, 0x80, 0xe1,
+			0xb7, 0xb7, 0x50, 0xdf, 0xc7, 0x59, 0x8d, 0x5d,
+			0x50, 0x11, 0xfd, 0x2d, 0xcc, 0x56, 0x00, 0xa3,
+			0x2e, 0xf5, 0xb5, 0x2a, 0x1e, 0xcc, 0x82, 0x0e,
+			0x30, 0x8a, 0xa3, 0x42, 0x72, 0x1a, 0xac, 0x09,
+			0x43, 0xbf, 0x66, 0x86, 0xb6, 0x4b, 0x25, 0x79,
+			0x37, 0x65, 0x04, 0xcc, 0xc4, 0x93, 0xd9, 0x7e,
+			0x6a, 0xed, 0x3f, 0xb0, 0xf9, 0xcd, 0x71, 0xa4,
+			0x3d, 0xd4, 0x97, 0xf0, 0x1f, 0x17, 0xc0, 0xe2,
+			0xcb, 0x37, 0x97, 0xaa, 0x2a, 0x2f, 0x25, 0x66,
+			0x56, 0x16, 0x8e, 0x6c, 0x49, 0x6a, 0xfc, 0x5f,
+			0xb9, 0x32, 0x46, 0xf6, 0xb1, 0x11, 0x63, 0x98,
+			0xa3, 0x46, 0xf1, 0xa6, 0x41, 0xf3, 0xb0, 0x41,
+			0xe9, 0x89, 0xf7, 0x91, 0x4f, 0x90, 0xcc, 0x2c,
+			0x7f, 0xff, 0x35, 0x78, 0x76, 0xe5, 0x06, 0xb5,
+			0x0d, 0x33, 0x4b, 0xa7, 0x7c, 0x22, 0x5b, 0xc3,
+			0x07, 0xba, 0x53, 0x71, 0x52, 0xf3, 0xf1, 0x61,
+			0x0e, 0x4e, 0xaf, 0xe5, 0x95, 0xf6, 0xd9, 0xd9,
+			0x0d, 0x11, 0xfa, 0xa9, 0x33, 0xa1, 0x5e, 0xf1,
+			0x36, 0x95, 0x46, 0x86, 0x8a, 0x7f, 0x3a, 0x45,
+			0xa9, 0x67, 0x68, 0xd4, 0x0f, 0xd9, 0xd0, 0x34,
+			0x12, 0xc0, 0x91, 0xc6, 0x31, 0x5c, 0xf4, 0xfd,
+			0xe7, 0xcb, 0x68, 0x60, 0x69, 0x37, 0x38, 0x0d,
+			0xb2, 0xea, 0xaa, 0x70, 0x7b, 0x4c, 0x41, 0x85,
+			0xc3, 0x2e, 0xdd, 0xcd, 0xd3, 0x06, 0x70, 0x5e,
+			0x4d, 0xc1, 0xff, 0xc8, 0x72, 0xee, 0xee, 0x47,
+			0x5a, 0x64, 0xdf, 0xac, 0x86, 0xab, 0xa4, 0x1c,
+			0x06, 0x18, 0x98, 0x3f, 0x87, 0x41, 0xc5, 0xef,
+			0x68, 0xd3, 0xa1, 0x01, 0xe8, 0xa3, 0xb8, 0xca,
+			0xc6, 0x0c, 0x90, 0x5c, 0x15, 0xfc, 0x91, 0x08,
+			0x40, 0xb9, 0x4c, 0x00, 0xa0, 0xb9, 0xd0
+		},
+		.length = 1023,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519CTX (msg=16, ctx=3)",
+	.pkey = {
+		.data = {
+			0x03, 0x05, 0x33, 0x4e, 0x38, 0x1a, 0xf7, 0x8f,
+			0x14, 0x1c, 0xb6, 0x66, 0xf6, 0x19, 0x9f, 0x57,
+			0xbc, 0x34, 0x95, 0x33, 0x5a, 0x25, 0x6a, 0x95,
+			0xbd, 0x2a, 0x55, 0xbf, 0x54, 0x66, 0x63, 0xf6
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xdf, 0xc9, 0x42, 0x5e, 0x4f, 0x96, 0x8f, 0x7f,
+			0x0c, 0x29, 0xf0, 0x25, 0x9c, 0xf5, 0xf9, 0xae,
+			0xd6, 0x85, 0x1c, 0x2b, 0xb4, 0xad, 0x8b, 0xfb,
+			0x86, 0x0c, 0xfe, 0xe0, 0xab, 0x24, 0x82, 0x92
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x55, 0xa4, 0xcc, 0x2f, 0x70, 0xa5, 0x4e, 0x04,
+			0x28, 0x8c, 0x5f, 0x4c, 0xd1, 0xe4, 0x5a, 0x7b,
+			0xb5, 0x20, 0xb3, 0x62, 0x92, 0x91, 0x18, 0x76,
+			0xca, 0xda, 0x73, 0x23, 0x19, 0x8d, 0xd8, 0x7a,
+			0x8b, 0x36, 0x95, 0x0b, 0x95, 0x13, 0x00, 0x22,
+			0x90, 0x7a, 0x7f, 0xb7, 0xc4, 0xe9, 0xb2, 0xd5,
+			0xf6, 0xcc, 0xa6, 0x85, 0xa5, 0x87, 0xb4, 0xb2,
+			0x1f, 0x4b, 0x88, 0x8e, 0x4e, 0x7e, 0xdb, 0x0d
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0xf7, 0x26, 0x93, 0x6d, 0x19, 0xc8, 0x00, 0x49,
+			0x4e, 0x3f, 0xda, 0xff, 0x20, 0xb2, 0x76, 0xa8,
+		},
+		.length = 16,
+	},
+	.context = {
+		.data = {
+			0x66, 0x6f, 0x6f
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519CTX
+},
+{
+	.description = "EDDSA 25519PH (msg=1, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+			0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+			0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+			0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x98, 0xa7, 0x02, 0x22, 0xf0, 0xb8, 0x12, 0x1a,
+			0xa9, 0xd3, 0x0f, 0x81, 0x3d, 0x68, 0x3f, 0x80,
+			0x9e, 0x46, 0x2b, 0x46, 0x9c, 0x7f, 0xf8, 0x76,
+			0x39, 0x49, 0x9b, 0xb9, 0x4e, 0x6d, 0xae, 0x41,
+			0x31, 0xf8, 0x50, 0x42, 0x46, 0x3c, 0x2a, 0x35,
+			0x5a, 0x20, 0x03, 0xd0, 0x62, 0xad, 0xf5, 0xaa,
+			0xa1, 0x0b, 0x8c, 0x61, 0xe6, 0x36, 0x06, 0x2a,
+			0xaa, 0xd1, 0x1c, 0x2a, 0x26, 0x08, 0x34, 0x06
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519PH
+},
+{
+	.description = "EDDSA 448 (msg=0)",
+	.pkey = {
+		.data = {
+			0x6C, 0x82, 0xA5, 0x62, 0xCB, 0x80, 0x8D, 0x10,
+			0xD6, 0x32, 0xBE, 0x89, 0xC8, 0x51, 0x3E, 0xBF,
+			0x6C, 0x92, 0x9F, 0x34, 0xDD, 0xFA, 0x8C, 0x9F,
+			0x63, 0xC9, 0x96, 0x0E, 0xF6, 0xE3, 0x48, 0xA3,
+			0x52, 0x8C, 0x8A, 0x3F, 0xCC, 0x2F, 0x04, 0x4E,
+			0x39, 0xA3, 0xFC, 0x5B, 0x94, 0x49, 0x2F, 0x8F,
+			0x03, 0x2E, 0x75, 0x49, 0xA2, 0x00, 0x98, 0xF9,
+			0x5B,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x5F, 0xD7, 0x44, 0x9B, 0x59, 0xB4, 0x61, 0xFD,
+			0x2C, 0xE7, 0x87, 0xEC, 0x61, 0x6A, 0xD4, 0x6A,
+			0x1D, 0xA1, 0x34, 0x24, 0x85, 0xA7, 0x0E, 0x1F,
+			0x8A, 0x0E, 0xA7, 0x5D, 0x80, 0xE9, 0x67, 0x78,
+			0xED, 0xF1, 0x24, 0x76, 0x9B, 0x46, 0xC7, 0x06,
+			0x1B, 0xD6, 0x78, 0x3D, 0xF1, 0xE5, 0x0F, 0x6C,
+			0xD1, 0xFA, 0x1A, 0xBE, 0xAF, 0xE8, 0x25, 0x61,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25,
+			0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae,
+			0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2,
+			0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f,
+			0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81,
+			0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78,
+			0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39,
+			0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a,
+			0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d,
+			0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41,
+			0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd,
+			0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb,
+			0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26,
+			0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65,
+			0x26, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=1)",
+	.pkey = {
+		.data = {
+			0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6,
+			0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92, 0x4d,
+			0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d,
+			0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c, 0x46, 0x3a,
+			0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c,
+			0x5e, 0x3b, 0xc3, 0x97, 0xa6, 0x59, 0x94, 0x9e,
+			0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27,
+			0x4e,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45,
+			0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd, 0x0a,
+			0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37,
+			0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98, 0xc0, 0x86,
+			0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02,
+			0xb8, 0x43, 0x8e, 0xa4, 0xcb, 0x82, 0x16, 0x9c,
+			0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x26, 0xb8, 0xf9, 0x17, 0x27, 0xbd, 0x62, 0x89,
+			0x7a, 0xf1, 0x5e, 0x41, 0xeb, 0x43, 0xc3, 0x77,
+			0xef, 0xb9, 0xc6, 0x10, 0xd4, 0x8f, 0x23, 0x35,
+			0xcb, 0x0b, 0xd0, 0x08, 0x78, 0x10, 0xf4, 0x35,
+			0x25, 0x41, 0xb1, 0x43, 0xc4, 0xb9, 0x81, 0xb7,
+			0xe1, 0x8f, 0x62, 0xde, 0x8c, 0xcd, 0xf6, 0x33,
+			0xfc, 0x1b, 0xf0, 0x37, 0xab, 0x7c, 0xd7, 0x79,
+			0x80, 0x5e, 0x0d, 0xbc, 0xc0, 0xaa, 0xe1, 0xcb,
+			0xce, 0xe1, 0xaf, 0xb2, 0xe0, 0x27, 0xdf, 0x36,
+			0xbc, 0x04, 0xdc, 0xec, 0xbf, 0x15, 0x43, 0x36,
+			0xc1, 0x9f, 0x0a, 0xf7, 0xe0, 0xa6, 0x47, 0x29,
+			0x05, 0xe7, 0x99, 0xf1, 0x95, 0x3d, 0x2a, 0x0f,
+			0xf3, 0x34, 0x8a, 0xb2, 0x1a, 0xa4, 0xad, 0xaf,
+			0xd1, 0xd2, 0x34, 0x44, 0x1c, 0xf8, 0x07, 0xc0,
+			0x3a, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x03
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=3, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42,
+			0xef, 0x78, 0x22, 0xe0, 0xd5, 0x10, 0x41, 0x27,
+			0xdc, 0x05, 0xd6, 0xdb, 0xef, 0xde, 0x69, 0xe3,
+			0xab, 0x2c, 0xec, 0x7c, 0x86, 0x7c, 0x6e, 0x2c,
+			0x49
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x25, 0x9b, 0x71, 0xc1, 0x9f, 0x83, 0xef, 0x77,
+			0xa7, 0xab, 0xd2, 0x65, 0x24, 0xcb, 0xdb, 0x31,
+			0x61, 0xb5, 0x90, 0xa4, 0x8f, 0x7d, 0x17, 0xde,
+			0x3e, 0xe0, 0xba, 0x9c, 0x52, 0xbe, 0xb7, 0x43,
+			0xc0, 0x94, 0x28, 0xa1, 0x31, 0xd6, 0xb1, 0xb5,
+			0x73, 0x03, 0xd9, 0x0d, 0x81, 0x32, 0xc2, 0x76,
+			0xd5, 0xed, 0x3d, 0x5d, 0x01, 0xc0, 0xf5, 0x38,
+			0x80
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x82, 0x2f, 0x69, 0x01, 0xf7, 0x48, 0x0f, 0x3d,
+			0x5f, 0x56, 0x2c, 0x59, 0x29, 0x94, 0xd9, 0x69,
+			0x36, 0x02, 0x87, 0x56, 0x14, 0x48, 0x32, 0x56,
+			0x50, 0x56, 0x00, 0xbb, 0xc2, 0x81, 0xae, 0x38,
+			0x1f, 0x54, 0xd6, 0xbc, 0xe2, 0xea, 0x91, 0x15,
+			0x74, 0x93, 0x2f, 0x52, 0xa4, 0xe6, 0xca, 0xdd,
+			0x78, 0x76, 0x93, 0x75, 0xec, 0x3f, 0xfd, 0x1b,
+			0x80, 0x1a, 0x0d, 0x9b, 0x3f, 0x40, 0x30, 0xcd,
+			0x43, 0x39, 0x64, 0xb6, 0x45, 0x7e, 0xa3, 0x94,
+			0x76, 0x51, 0x12, 0x14, 0xf9, 0x74, 0x69, 0xb5,
+			0x7d, 0xd3, 0x2d, 0xbc, 0x56, 0x0a, 0x9a, 0x94,
+			0xd0, 0x0b, 0xff, 0x07, 0x62, 0x04, 0x64, 0xa3,
+			0xad, 0x20, 0x3d, 0xf7, 0xdc, 0x7c, 0xe3, 0x60,
+			0xc3, 0xcd, 0x36, 0x96, 0xd9, 0xd9, 0xfa, 0xb9,
+			0x0f, 0x00
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448PH
+},
+};
+
+#endif /* __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__ */
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v4 5/6] examples/fips_validation: support EDDSA
  2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                           ` (2 preceding siblings ...)
  2024-10-03 17:56         ` [PATCH v4 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
@ 2024-10-03 17:56         ` Gowrishankar Muthukrishnan
  2024-10-03 17:56         ` [PATCH v4 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
  2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-03 17:56 UTC (permalink / raw)
  To: dev, Brian Dooley, Gowrishankar Muthukrishnan
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal

Add EDDSA support in fips_validation app.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 examples/fips_validation/fips_validation.c    |   2 +
 examples/fips_validation/fips_validation.h    |  23 ++
 .../fips_validation/fips_validation_eddsa.c   | 307 +++++++++++++++++
 examples/fips_validation/main.c               | 323 ++++++++++++++++--
 examples/fips_validation/meson.build          |   1 +
 5 files changed, 623 insertions(+), 33 deletions(-)
 create mode 100644 examples/fips_validation/fips_validation_eddsa.c

diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c
index c15178e55b..43d1e55532 100644
--- a/examples/fips_validation/fips_validation.c
+++ b/examples/fips_validation/fips_validation.c
@@ -475,6 +475,8 @@ fips_test_parse_one_json_vector_set(void)
 		info.algo = FIPS_TEST_ALGO_RSA;
 	else if (strstr(algo_str, "ECDSA"))
 		info.algo = FIPS_TEST_ALGO_ECDSA;
+	else if (strstr(algo_str, "EDDSA"))
+		info.algo = FIPS_TEST_ALGO_EDDSA;
 	else
 		return -EINVAL;
 
diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h
index abc1d64742..795cf834e8 100644
--- a/examples/fips_validation/fips_validation.h
+++ b/examples/fips_validation/fips_validation.h
@@ -46,6 +46,7 @@ enum fips_test_algorithms {
 		FIPS_TEST_ALGO_SHA,
 		FIPS_TEST_ALGO_RSA,
 		FIPS_TEST_ALGO_ECDSA,
+		FIPS_TEST_ALGO_EDDSA,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -106,6 +107,12 @@ struct fips_test_vector {
 		struct fips_val s;
 		struct fips_val k;
 	} ecdsa;
+	struct {
+		struct fips_val pkey;
+		struct fips_val q;
+		struct fips_val ctx;
+		struct fips_val sign;
+	} eddsa;
 
 	struct fips_val pt;
 	struct fips_val ct;
@@ -177,6 +184,11 @@ enum fips_ecdsa_test_types {
 	ECDSA_AFT = 0,
 };
 
+enum fips_eddsa_test_types {
+	EDDSA_AFT = 0,
+	EDDSA_BFT
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -241,6 +253,13 @@ struct ecdsa_interim_data {
 	uint8_t pubkey_gen;
 };
 
+struct eddsa_interim_data {
+	enum rte_crypto_curve_id curve_id;
+	uint8_t curve_len;
+	uint8_t pubkey_gen;
+	bool prehash;
+};
+
 #ifdef USE_JANSSON
 /*
  * Maximum length of buffer to hold any json string.
@@ -288,6 +307,7 @@ struct fips_test_interim_info {
 		struct xts_interim_data xts_data;
 		struct rsa_interim_data rsa_data;
 		struct ecdsa_interim_data ecdsa_data;
+		struct eddsa_interim_data eddsa_data;
 	} interim_info;
 
 	enum fips_test_op op;
@@ -374,6 +394,9 @@ parse_test_rsa_json_init(void);
 int
 parse_test_ecdsa_json_init(void);
 
+int
+parse_test_eddsa_json_init(void);
+
 int
 fips_test_randomize_message(struct fips_val *msg, struct fips_val *rand);
 #endif /* USE_JANSSON */
diff --git a/examples/fips_validation/fips_validation_eddsa.c b/examples/fips_validation/fips_validation_eddsa.c
new file mode 100644
index 0000000000..8ccf7501bd
--- /dev/null
+++ b/examples/fips_validation/fips_validation_eddsa.c
@@ -0,0 +1,307 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell.
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef USE_OPENSSL
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#endif /* USE_OPENSSL */
+
+#include <rte_cryptodev.h>
+#include <rte_malloc.h>
+
+#include "fips_validation.h"
+
+#define TESTTYPE_JSON_STR "testType"
+#define CURVE_JSON_STR    "curve"
+#define PH_JSON_STR       "preHash"
+
+#define MSG_JSON_STR "message"
+#define CTX_JSON_STR "context"
+#define Q_JSON_STR	 "q"
+#define SIG_JSON_STR "signature"
+
+#ifdef USE_JANSSON
+struct {
+	uint8_t type;
+	const char *desc;
+} eddsa_test_types[] = {
+	{EDDSA_AFT, "AFT"},
+	{EDDSA_BFT, "BFT"}
+};
+
+struct {
+	enum rte_crypto_curve_id curve_id;
+	const char *desc;
+} eddsa_curve_ids[] = {
+	{RTE_CRYPTO_EC_GROUP_ED25519, "ED-25519"},
+	{RTE_CRYPTO_EC_GROUP_ED448, "ED-448"},
+};
+
+struct {
+	uint8_t curve_len;
+	const char *desc;
+} eddsa_curve_len[] = {
+	{32, "ED-25519"},
+	{64, "ED-448"},
+};
+
+#ifdef USE_OPENSSL
+#define MAX_TRIES 10
+static int
+prepare_vec_eddsa(void)
+{
+	BIGNUM *pkey = NULL, *order = NULL;
+	int ret = -1, j;
+	unsigned long pid;
+
+	/* For EDDSA prime fields, order of base points (RFC 8032 Section 5.1 and 5.2).
+	 */
+	static const char * const orderstr[] = {
+			"7237005577332262213973186563042994240857116359379907606001950938285454250989",
+			"181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779",
+	};
+
+	pid = getpid();
+	RAND_seed(&pid, sizeof(pid));
+
+	if (!RAND_status())
+		return -1;
+
+	order = BN_new();
+	if (!order)
+		goto err;
+
+	j = info.interim_info.eddsa_data.curve_id - RTE_CRYPTO_EC_GROUP_ED25519;
+	if (!BN_hex2bn(&order, orderstr[j]))
+		goto err;
+
+	pkey = BN_new();
+	if (!pkey)
+		goto err;
+
+	for (j = 0; j < MAX_TRIES; j++) {
+		/* pkey should be in [1, order - 1] */
+		if (!BN_rand_range(pkey, order))
+			goto err;
+
+		if (!BN_is_zero(pkey))
+			break;
+	}
+
+	if (j == MAX_TRIES)
+		goto err;
+
+	parse_uint8_hex_str("", BN_bn2hex(pkey), &vec.eddsa.pkey);
+
+	ret = 0;
+err:
+	BN_free(order);
+	BN_free(pkey);
+	return ret;
+}
+#else
+static int
+prepare_vec_eddsa(void)
+{
+	/*
+	 * Generate EDDSA values.
+	 */
+	return -ENOTSUP;
+}
+#endif /* USE_OPENSSL */
+
+static int
+parse_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		/* For siggen tests, EDDSA values can be created soon after
+		 * the test group data are parsed.
+		 */
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+static int
+post_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_group, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_test_eddsa_json_writeback(struct fips_val *val)
+{
+	json_t *tcId;
+
+	RTE_SET_USED(val);
+
+	tcId = json_object_get(json_info.json_test_case, "tcId");
+
+	json_info.json_write_case = json_object();
+	json_object_set(json_info.json_write_case, "tcId", tcId);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.sign);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "signature", obj);
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)
+			json_object_set_new(json_info.json_write_case, "testPassed", json_true());
+		else
+			json_object_set_new(json_info.json_write_case, "testPassed", json_false());
+	} else if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.pkey);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "d", obj);
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_interim_str(const char *key, char *src, struct fips_val *val)
+{
+	uint32_t i;
+
+	RTE_SET_USED(val);
+
+	if (strcmp(key, TESTTYPE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_test_types); i++)
+			if (strstr(src, eddsa_test_types[i].desc)) {
+				info.parse_writeback = parse_test_eddsa_json_writeback;
+				break;
+			}
+
+		if (!info.parse_writeback || i >= RTE_DIM(eddsa_test_types))
+			return -EINVAL;
+
+	} else if (strcmp(key, CURVE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_curve_ids); i++)
+			if (strstr(src, eddsa_curve_ids[i].desc)) {
+				info.interim_info.eddsa_data.curve_id = eddsa_curve_ids[i].curve_id;
+				info.interim_info.eddsa_data.curve_len =
+					eddsa_curve_len[i].curve_len;
+				break;
+			}
+
+		if (i >= RTE_DIM(eddsa_curve_ids))
+			return -EINVAL;
+	} else if (strcmp(key, PH_JSON_STR) == 0) {
+		info.interim_info.eddsa_data.prehash = false;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+parse_keygen_tc_str(const char *key, char *src, struct fips_val *val)
+{
+	RTE_SET_USED(key);
+	RTE_SET_USED(src);
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+struct fips_test_callback eddsa_interim_json_vectors[] = {
+		{TESTTYPE_JSON_STR, parse_interim_str, NULL},
+		{CURVE_JSON_STR, parse_interim_str, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_siggen_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{CTX_JSON_STR, parse_uint8_hex_str, &vec.eddsa.ctx},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_sigver_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{Q_JSON_STR, parse_uint8_hex_str, &vec.eddsa.q},
+		{SIG_JSON_STR, parse_uint8_hex_str, &vec.eddsa.sign},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_keygen_json_vectors[] = {
+		{"tcId", parse_keygen_tc_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+int
+parse_test_eddsa_json_init(void)
+{
+	json_t *mode_obj = json_object_get(json_info.json_vector_set, "mode");
+	const char *mode_str = json_string_value(mode_obj);
+
+	info.callbacks = NULL;
+	info.parse_writeback = NULL;
+
+	info.interim_callbacks = eddsa_interim_json_vectors;
+	info.post_interim_writeback = post_test_eddsa_json_interim_writeback;
+	info.parse_interim_writeback = parse_test_eddsa_json_interim_writeback;
+	if (strcmp(mode_str, "sigGen") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGGEN;
+		info.callbacks = eddsa_siggen_json_vectors;
+	} else if (strcmp(mode_str, "sigVer") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGVER;
+		info.callbacks = eddsa_sigver_json_vectors;
+	} else if (strcmp(mode_str, "keyGen") == 0) {
+		info.op = FIPS_TEST_ASYM_KEYGEN;
+		info.callbacks = eddsa_keygen_json_vectors;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif /* USE_JANSSON */
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index 7ae2c6c007..522373ac1d 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -1041,6 +1041,64 @@ prepare_ecdsa_op(void)
 	return 0;
 }
 
+static int
+prepare_eddsa_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+	struct fips_val msg;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	if (env.digest) {
+		msg.val = env.digest;
+		msg.len = env.digest_len;
+	} else {
+		msg.val = vec.pt.val;
+		msg.len = vec.pt.len;
+	}
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.context.data = vec.eddsa.ctx.val;
+		asym->eddsa.context.length = vec.eddsa.ctx.len;
+
+		rte_free(vec.eddsa.sign.val);
+
+		vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len;
+		vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0);
+
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = 0;
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = vec.eddsa.sign.len;
+	} else {
+		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
+		return -EINVAL;
+	}
+
+	if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH;
+		if (vec.eddsa.ctx.len > 0)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX;
+	} else {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH;
+	}
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_ecfpm_op(void)
 {
@@ -1072,6 +1130,31 @@ prepare_ecfpm_op(void)
 	return 0;
 }
 
+static int
+prepare_edfpm_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	asym->ecpm.scalar.data = vec.eddsa.pkey.val;
+	asym->ecpm.scalar.length = vec.eddsa.pkey.len;
+
+	rte_free(vec.eddsa.q.val);
+
+	vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len;
+	vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0);
+
+	asym->ecpm.r.x.data = vec.eddsa.q.val;
+	asym->ecpm.r.x.length = 0;
+	asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
@@ -1589,6 +1672,56 @@ prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_eddsa_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	switch (info.op) {
+	case FIPS_TEST_ASYM_SIGGEN:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_SIGN)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
+			return -EPERM;
+		}
+
+		xform->ec.pkey.data = vec.eddsa.pkey.val;
+		xform->ec.pkey.length = vec.eddsa.pkey.len;
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	case FIPS_TEST_ASYM_SIGVER:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_VERIFY)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
+			return -EPERM;
+		}
+
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	default:
+		break;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 {
@@ -1610,6 +1743,27 @@ prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_edfpm_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 get_writeback_data(struct fips_val *val)
 {
@@ -1709,7 +1863,9 @@ fips_run_asym_test(void)
 	struct rte_crypto_op *deqd_op;
 	int ret;
 
-	if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != FIPS_TEST_ALGO_ECDSA) {
+	if (info.op == FIPS_TEST_ASYM_KEYGEN &&
+		(info.algo != FIPS_TEST_ALGO_ECDSA &&
+		 info.algo != FIPS_TEST_ALGO_EDDSA)) {
 		RTE_SET_USED(asym);
 		ret = 0;
 		goto exit;
@@ -1758,53 +1914,140 @@ fips_run_test(void)
 {
 	int ret;
 
-	env.op = env.sym.op;
-	if (env.is_asym_test) {
-		if (info.op == FIPS_TEST_ASYM_KEYGEN &&
-			info.algo == FIPS_TEST_ALGO_ECDSA) {
-			env.op = env.asym.op;
+	env.op = NULL;
+	if (!env.is_asym_test) {
+		env.op = env.sym.op;
+		return fips_run_sym_test();
+	}
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (info.algo == FIPS_TEST_ALGO_ECDSA) {
 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
 			test_ops.prepare_asym_op = prepare_ecfpm_op;
-			ret = fips_run_asym_test();
-			if (ret < 0)
-				return ret;
-
 			info.interim_info.ecdsa_data.pubkey_gen = 0;
-			return ret;
+
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA) {
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			info.interim_info.eddsa_data.pubkey_gen = 0;
 		}
 
-		vec.cipher_auth.digest.len = parse_test_sha_hash_size(
-						info.interim_info.rsa_data.auth);
+		env.op = env.asym.op;
+		return fips_run_asym_test();
+	}
+
+	if (info.algo == FIPS_TEST_ALGO_ECDSA) {
+		vec.cipher_auth.digest.len =
+			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
 		test_ops.prepare_sym_xform = prepare_sha_xform;
 		test_ops.prepare_sym_op = prepare_auth_op;
+
+		env.op = env.sym.op;
 		ret = fips_run_sym_test();
 		if (ret < 0)
 			return ret;
-	} else {
-		return fips_run_sym_test();
 	}
 
 	env.op = env.asym.op;
-	if (info.op == FIPS_TEST_ASYM_SIGGEN &&
-		info.algo == FIPS_TEST_ALGO_ECDSA &&
-		info.interim_info.ecdsa_data.pubkey_gen == 1) {
-		fips_prepare_asym_xform_t ecdsa_xform;
-		fips_prepare_op_t ecdsa_op;
-
-		ecdsa_xform = test_ops.prepare_asym_xform;
-		ecdsa_op = test_ops.prepare_asym_op;
-		info.op = FIPS_TEST_ASYM_KEYGEN;
-		test_ops.prepare_asym_xform = prepare_ecfpm_xform;
-		test_ops.prepare_asym_op = prepare_ecfpm_op;
-		ret = fips_run_asym_test();
-		if (ret < 0)
-			return ret;
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		fips_prepare_asym_xform_t old_xform;
+		fips_prepare_op_t old_op;
+
+		old_xform = test_ops.prepare_asym_xform;
+		old_op = test_ops.prepare_asym_op;
+
+		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
+		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
+			test_ops.prepare_asym_op = prepare_ecfpm_op;
 
-		info.post_interim_writeback(NULL);
-		info.interim_info.ecdsa_data.pubkey_gen = 0;
+			ret = fips_run_asym_test();
+			if (ret < 0)
+				return ret;
+
+			info.post_interim_writeback(NULL);
+			info.interim_info.ecdsa_data.pubkey_gen = 0;
 
-		test_ops.prepare_asym_xform = ecdsa_xform;
-		test_ops.prepare_asym_op = ecdsa_op;
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
+				   info.interim_info.eddsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+
+			const struct rte_cryptodev_asymmetric_xform_capability *cap;
+			struct rte_cryptodev_asym_capability_idx cap_idx;
+
+			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+			if (!cap) {
+				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+						env.dev_id);
+				return -EINVAL;
+			}
+
+			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
+				ret = fips_run_asym_test();
+				if (ret < 0)
+					return ret;
+			} else {
+				/* Below is only a workaround by using known keys. */
+				struct rte_crypto_asym_xform xform = {0};
+
+				prepare_edfpm_xform(&xform);
+				prepare_edfpm_op();
+				uint8_t pkey25519[] = {
+					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+				};
+				uint8_t q25519[] = {
+					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+				};
+				uint8_t pkey448[] = {
+					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+					0x01
+				};
+				uint8_t q448[] = {
+					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+					0x00
+				};
+				if (info.interim_info.eddsa_data.curve_id ==
+					RTE_CRYPTO_EC_GROUP_ED25519) {
+					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
+					vec.eddsa.q.len = 32;
+				} else {
+					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
+					vec.eddsa.q.len = 32;
+				}
+			}
+			info.post_interim_writeback(NULL);
+			info.interim_info.eddsa_data.pubkey_gen = 0;
+
+		}
+
+		test_ops.prepare_asym_xform = old_xform;
+		test_ops.prepare_asym_op = old_op;
 		info.op = FIPS_TEST_ASYM_SIGGEN;
 		ret = fips_run_asym_test();
 	} else {
@@ -2536,6 +2779,17 @@ init_test_ops(void)
 			test_ops.test = fips_generic_test;
 		}
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.test = fips_generic_test;
+		} else {
+			test_ops.prepare_asym_op = prepare_eddsa_op;
+			test_ops.prepare_asym_xform = prepare_eddsa_xform;
+			test_ops.test = fips_generic_test;
+		}
+		break;
 	default:
 		if (strstr(info.file_name, "TECB") ||
 				strstr(info.file_name, "TCBC")) {
@@ -2719,6 +2973,9 @@ fips_test_one_test_group(void)
 	case FIPS_TEST_ALGO_ECDSA:
 		ret = parse_test_ecdsa_json_init();
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		ret = parse_test_eddsa_json_init();
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build
index 34d3c7c8ca..7d4e440c6c 100644
--- a/examples/fips_validation/meson.build
+++ b/examples/fips_validation/meson.build
@@ -20,6 +20,7 @@ sources = files(
         'fips_validation_xts.c',
         'fips_validation_rsa.c',
         'fips_validation_ecdsa.c',
+        'fips_validation_eddsa.c',
         'fips_dev_self_test.c',
         'main.c',
 )
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v4 6/6] app/crypto-perf: support EDDSA
  2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                           ` (3 preceding siblings ...)
  2024-10-03 17:56         ` [PATCH v4 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
@ 2024-10-03 17:56         ` Gowrishankar Muthukrishnan
  2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-03 17:56 UTC (permalink / raw)
  To: dev, Brian Dooley
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Added support for EDDSA 25519 curve SIGN and VERIFY operations.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test-crypto-perf/cperf_ops.c             | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_options.h         |  2 +
 app/test-crypto-perf/cperf_options_parsing.c |  9 +++-
 app/test-crypto-perf/cperf_test_common.c     |  1 +
 app/test-crypto-perf/cperf_test_vectors.c    | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_test_vectors.h    | 10 ++++
 app/test-crypto-perf/main.c                  | 13 +++++
 doc/guides/tools/cryptoperf.rst              |  1 +
 8 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index f139ec5331..220c3acac7 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -67,6 +67,36 @@ cperf_set_ops_asym_ecdsa(struct rte_crypto_op **ops,
 	}
 }
 
+static void
+cperf_set_ops_asym_eddsa(struct rte_crypto_op **ops,
+		   uint32_t src_buf_offset __rte_unused,
+		   uint32_t dst_buf_offset __rte_unused, uint16_t nb_ops,
+		   void *sess,
+		   const struct cperf_options *options,
+		   const struct cperf_test_vector *test_vector __rte_unused,
+		   uint16_t iv_offset __rte_unused,
+		   uint32_t *imix_idx __rte_unused,
+		   uint64_t *tsc_start __rte_unused)
+{
+	uint16_t i;
+
+	for (i = 0; i < nb_ops; i++) {
+		struct rte_crypto_asym_op *asym_op = ops[i]->asym;
+
+		ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		rte_crypto_op_attach_asym_session(ops[i], sess);
+
+		asym_op->eddsa.op_type = options->asym_op_type;
+		asym_op->eddsa.message.data = options->eddsa_data->message.data;
+		asym_op->eddsa.message.length = options->eddsa_data->message.length;
+
+		asym_op->eddsa.instance = options->eddsa_data->instance;
+
+		asym_op->eddsa.sign.data = options->eddsa_data->sign.data;
+		asym_op->eddsa.sign.length = options->eddsa_data->sign.length;
+	}
+}
+
 static void
 cperf_set_ops_asym_sm2(struct rte_crypto_op **ops,
 		   uint32_t src_buf_offset __rte_unused,
@@ -1031,6 +1061,25 @@ cperf_create_session(struct rte_mempool *sess_mp,
 		return asym_sess;
 	}
 
+	if (options->op_type == CPERF_ASYM_ED25519) {
+		xform.next = NULL;
+		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		xform.ec.curve_id = options->eddsa_data->curve;
+		xform.ec.pkey.data = options->eddsa_data->pkey.data;
+		xform.ec.pkey.length = options->eddsa_data->pkey.length;
+		xform.ec.q.x.data = options->eddsa_data->pubkey.data;
+		xform.ec.q.x.length = options->eddsa_data->pubkey.length;
+
+		ret = rte_cryptodev_asym_session_create(dev_id, &xform,
+				sess_mp, &asym_sess);
+		if (ret < 0) {
+			RTE_LOG(ERR, USER1, "EDDSA Asym session create failed\n");
+			return NULL;
+		}
+
+		return asym_sess;
+	}
+
 	if (options->op_type == CPERF_ASYM_SM2) {
 		xform.next = NULL;
 		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
@@ -1354,6 +1403,9 @@ cperf_get_op_functions(const struct cperf_options *options,
 	case CPERF_ASYM_SECP256R1:
 		op_fns->populate_ops = cperf_set_ops_asym_ecdsa;
 		break;
+	case CPERF_ASYM_ED25519:
+		op_fns->populate_ops = cperf_set_ops_asym_eddsa;
+		break;
 	case CPERF_ASYM_SM2:
 		op_fns->populate_ops = cperf_set_ops_asym_sm2;
 		break;
diff --git a/app/test-crypto-perf/cperf_options.h b/app/test-crypto-perf/cperf_options.h
index 131ecfdffb..dbc9f5a97b 100644
--- a/app/test-crypto-perf/cperf_options.h
+++ b/app/test-crypto-perf/cperf_options.h
@@ -89,6 +89,7 @@ enum cperf_op_type {
 	CPERF_IPSEC,
 	CPERF_ASYM_MODEX,
 	CPERF_ASYM_SECP256R1,
+	CPERF_ASYM_ED25519,
 	CPERF_ASYM_SM2,
 	CPERF_TLS,
 };
@@ -169,6 +170,7 @@ struct cperf_options {
 	struct cperf_modex_test_data *modex_data;
 	uint16_t modex_len;
 	struct cperf_ecdsa_test_data *secp256r1_data;
+	struct cperf_eddsa_test_data *eddsa_data;
 	struct cperf_sm2_test_data *sm2_data;
 	enum rte_crypto_asym_op_type asym_op_type;
 	enum rte_crypto_auth_algorithm asym_hash_alg;
diff --git a/app/test-crypto-perf/cperf_options_parsing.c b/app/test-crypto-perf/cperf_options_parsing.c
index c91fcf0479..59ea66c06d 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -38,7 +38,7 @@ usage(char *progname)
 		" --desc-nb N: set number of descriptors for each crypto device\n"
 		" --devtype TYPE: set crypto device type to use\n"
 		" --optype cipher-only / auth-only / cipher-then-auth / auth-then-cipher /\n"
-		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / sm2 / tls-record : set operation type\n"
+		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / eddsa / sm2 / tls-record : set operation type\n"
 		" --sessionless: enable session-less crypto operations\n"
 		" --shared-session: share 1 session across all queue pairs on crypto device\n"
 		" --out-of-place: enable out-of-place crypto operations\n"
@@ -489,6 +489,10 @@ parse_op_type(struct cperf_options *opts, const char *arg)
 			cperf_op_type_strs[CPERF_ASYM_SECP256R1],
 			CPERF_ASYM_SECP256R1
 		},
+		{
+			cperf_op_type_strs[CPERF_ASYM_ED25519],
+			CPERF_ASYM_ED25519
+		},
 		{
 			cperf_op_type_strs[CPERF_ASYM_SM2],
 			CPERF_ASYM_SM2
@@ -1080,6 +1084,7 @@ cperf_options_default(struct cperf_options *opts)
 	opts->modex_data = (struct cperf_modex_test_data *)&modex_perf_data[0];
 
 	opts->secp256r1_data = &secp256r1_perf_data;
+	opts->eddsa_data = &ed25519_perf_data;
 	opts->sm2_data = &sm2_perf_data;
 	opts->asym_op_type = RTE_CRYPTO_ASYM_OP_SIGN;
 }
@@ -1513,7 +1518,7 @@ cperf_options_dump(struct cperf_options *opts)
 	printf("#\n");
 	printf("# number of queue pairs per device: %u\n", opts->nb_qps);
 	printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
-	if (opts->op_type == CPERF_ASYM_SM2 || opts->op_type == CPERF_ASYM_SECP256R1)
+	if (cperf_is_asym_test(opts))
 		printf("# asym operation type: %s\n",
 				rte_crypto_asym_op_strings[opts->asym_op_type]);
 	printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
diff --git a/app/test-crypto-perf/cperf_test_common.c b/app/test-crypto-perf/cperf_test_common.c
index 33bee43c93..9c287665a4 100644
--- a/app/test-crypto-perf/cperf_test_common.c
+++ b/app/test-crypto-perf/cperf_test_common.c
@@ -307,6 +307,7 @@ cperf_is_asym_test(const struct cperf_options *options)
 {
 	if (options->op_type == CPERF_ASYM_MODEX ||
 	    options->op_type == CPERF_ASYM_SECP256R1 ||
+	    options->op_type == CPERF_ASYM_ED25519 ||
 	    options->op_type == CPERF_ASYM_SM2)
 		return true;
 
diff --git a/app/test-crypto-perf/cperf_test_vectors.c b/app/test-crypto-perf/cperf_test_vectors.c
index 19c56b46bd..64720d50c3 100644
--- a/app/test-crypto-perf/cperf_test_vectors.c
+++ b/app/test-crypto-perf/cperf_test_vectors.c
@@ -853,6 +853,35 @@ static uint8_t secp256r1_message[] = {
 	0xdb, 0xc4, 0xe7, 0xa6, 0xa1, 0x33, 0xec, 0x56
 };
 
+static uint8_t ed25519_pkey[] = {
+	0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+	0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+	0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+	0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+};
+
+static uint8_t ed25519_pubkey[] = {
+	0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+	0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+	0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+	0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+};
+
+static uint8_t ed25519_sign[] = {
+	0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+	0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+	0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+	0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+	0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+	0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+	0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+	0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+};
+
+static uint8_t ed25519_message[] = {
+	0x72
+};
+
 static uint8_t fp256_pkey[] = {
 	0x77, 0x84, 0x35, 0x65, 0x4c, 0x7a, 0x6d, 0xb1,
 	0x1e, 0x63, 0x0b, 0x41, 0x97, 0x36, 0x04, 0xf4,
@@ -1365,6 +1394,29 @@ cperf_ecdsa_test_data secp256r1_perf_data = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP256R1
 };
 
+/** EDDSA 25519 elliptic curve test params */
+struct
+cperf_eddsa_test_data ed25519_perf_data = {
+	.pubkey = {
+		.data = ed25519_pubkey,
+		.length = sizeof(ed25519_pubkey),
+	},
+	.pkey = {
+		.data = ed25519_pkey,
+		.length = sizeof(ed25519_pkey),
+	},
+	.sign = {
+		.data = ed25519_sign,
+		.length = sizeof(ed25519_sign),
+	},
+	.message = {
+		.data = ed25519_message,
+		.length = sizeof(ed25519_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+};
+
 /** SM2 Fp256 elliptic curve test params */
 struct
 cperf_sm2_test_data sm2_perf_data = {
diff --git a/app/test-crypto-perf/cperf_test_vectors.h b/app/test-crypto-perf/cperf_test_vectors.h
index d46cbbc2c8..f83a17c176 100644
--- a/app/test-crypto-perf/cperf_test_vectors.h
+++ b/app/test-crypto-perf/cperf_test_vectors.h
@@ -118,6 +118,15 @@ struct cperf_ecdsa_test_data {
 	int curve;
 };
 
+struct cperf_eddsa_test_data {
+	rte_crypto_param pubkey;
+	rte_crypto_param pkey;
+	rte_crypto_param sign;
+	rte_crypto_param message;
+	int curve;
+	int instance;
+};
+
 struct cperf_sm2_test_data {
 	rte_crypto_param pubkey_qx;
 	rte_crypto_param pubkey_qy;
@@ -147,6 +156,7 @@ extern uint8_t digest[2048];
 
 extern struct cperf_modex_test_data modex_perf_data[10];
 extern struct cperf_ecdsa_test_data secp256r1_perf_data;
+extern struct cperf_eddsa_test_data ed25519_perf_data;
 extern struct cperf_sm2_test_data sm2_perf_data;
 
 #endif
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 75810dbf0b..d93b30bcaa 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -46,6 +46,7 @@ const char *cperf_op_type_strs[] = {
 	[CPERF_IPSEC] = "ipsec",
 	[CPERF_ASYM_MODEX] = "modex",
 	[CPERF_ASYM_SECP256R1] = "ecdsa_p256r1",
+	[CPERF_ASYM_ED25519] = "eddsa_25519",
 	[CPERF_ASYM_SM2] = "sm2",
 	[CPERF_TLS] = "tls-record"
 };
@@ -227,6 +228,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
 
 		switch (opts->op_type) {
 		case CPERF_ASYM_SECP256R1:
+		case CPERF_ASYM_ED25519:
 		case CPERF_ASYM_SM2:
 		case CPERF_ASYM_MODEX:
 			conf.ff_disable |= (RTE_CRYPTODEV_FF_SECURITY |
@@ -382,6 +384,17 @@ cperf_verify_devices_capabilities(struct cperf_options *opts,
 			}
 		}
 
+		if (opts->op_type == CPERF_ASYM_ED25519) {
+			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
+			if (asym_capability == NULL)
+				return -1;
+
+			if (!rte_cryptodev_asym_xform_capability_check_optype(asym_capability,
+						opts->asym_op_type))
+				return -1;
+		}
+
 		if (opts->op_type == CPERF_ASYM_SM2) {
 			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_SM2;
 			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst
index 0510a3bb89..9a20a73f03 100644
--- a/doc/guides/tools/cryptoperf.rst
+++ b/doc/guides/tools/cryptoperf.rst
@@ -176,6 +176,7 @@ The following are the application command-line options:
            docsis
            modex
            ecdsa_p256r1
+           eddsa_25519
            sm2
            ipsec
            tls-record
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                           ` (4 preceding siblings ...)
  2024-10-03 17:56         ` [PATCH v4 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
@ 2024-10-04  5:30         ` Gowrishankar Muthukrishnan
  2024-10-04  5:30           ` [PATCH v5 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
                             ` (5 more replies)
  5 siblings, 6 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  5:30 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, jerinj, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Gowrishankar Muthukrishnan

Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
https://datatracker.ietf.org/doc/html/rfc8032

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
 lib/cryptodev/rte_crypto_asym.h            | 47 ++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index f411d4bab7..3073753911 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -130,6 +130,7 @@ ECDSA                   =
 ECPM                    =
 ECDH                    =
 SM2                     =
+EDDSA                   =
 
 ;
 ; Supported Operating systems of a default crypto driver.
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 2b513bbf82..dd636ba5ef 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -927,7 +927,7 @@ Asymmetric Cryptography
 The cryptodev library currently provides support for the following asymmetric
 Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman and
 Elliptic Curve Diffie-Hellman public and/or private key generation and shared
-secret compute, DSA Signature generation and verification.
+secret compute, DSA and EdDSA Signature generation and verification.
 
 Session and Session Management
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index 39d3da3952..fe4194c184 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -49,6 +49,10 @@ rte_crypto_asym_op_strings[];
  * and if the flag is not set, shared secret will be padded to the left with
  * zeros to the size of the underlying algorithm (default)
  */
+#define RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED		RTE_BIT32(2)
+/**<
+ * Flag to denote public key will be returned in compressed form
+ */
 
 /**
  * List of elliptic curves. This enum aligns with
@@ -65,9 +69,22 @@ enum rte_crypto_curve_id {
 	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
 	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
 	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
+	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
+	RTE_CRYPTO_EC_GROUP_ED448     = 30,
 	RTE_CRYPTO_EC_GROUP_SM2       = 41,
 };
 
+/**
+ * List of Edwards curve instances as per RFC 8032 (Section 5).
+ */
+enum rte_crypto_edward_instance {
+	RTE_CRYPTO_EDCURVE_25519,
+	RTE_CRYPTO_EDCURVE_25519CTX,
+	RTE_CRYPTO_EDCURVE_25519PH,
+	RTE_CRYPTO_EDCURVE_448,
+	RTE_CRYPTO_EDCURVE_448PH
+};
+
 /**
  * Asymmetric crypto transformation types.
  * Each xform type maps to one asymmetric algorithm
@@ -119,6 +136,10 @@ enum rte_crypto_asym_xform_type {
 	 * Performs Encrypt, Decrypt, Sign and Verify.
 	 * Refer to rte_crypto_asym_op_type.
 	 */
+	RTE_CRYPTO_ASYM_XFORM_EDDSA,
+	/**< Edwards Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -585,6 +606,31 @@ struct rte_crypto_ecdsa_op_param {
 	 */
 };
 
+/**
+ * EdDSA operation params
+ */
+struct rte_crypto_eddsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param message;
+	/**< Input message digest to be signed or verified */
+
+	rte_crypto_param context;
+	/**< Context value for the sign op.
+	 *   Must not be empty for Ed25519ctx instance.
+	 */
+
+	enum rte_crypto_edward_instance instance;
+	/**< Type of Edwards curve. */
+
+	rte_crypto_uint sign;
+	/**< Edward curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Structure for EC point multiplication operation param
  */
@@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_ecdsa_op_param ecdsa;
 		struct rte_crypto_ecpm_op_param ecpm;
 		struct rte_crypto_sm2_op_param sm2;
+		struct rte_crypto_eddsa_op_param eddsa;
 	};
 	uint16_t flags;
 	/**<
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v5 2/6] crypto/openssl: support EDDSA
  2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
@ 2024-10-04  5:30           ` Gowrishankar Muthukrishnan
  2024-10-04  5:30           ` [PATCH v5 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
                             ` (4 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  5:30 UTC (permalink / raw)
  To: dev, Kai Ji
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in OpenSSL PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
v5:
 - fixed compilation error due to RTE_LOG_CHECK_NO_NEWLINE.
---
 doc/guides/cryptodevs/features/openssl.ini   |   1 +
 drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
 drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
 4 files changed, 368 insertions(+)

diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index b64c8ec4a5..0540c075dc 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -66,6 +66,7 @@ Modular Exponentiation = Y
 Modular Inversion = Y
 Diffie-hellman = Y
 SM2 = Y
+EDDSA = Y
 
 ;
 ; Supported Operating systems of the 'openssl' crypto driver.
diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index 0282b3d829..7dd97f1c72 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -231,10 +231,23 @@ struct __rte_cache_aligned openssl_asym_session {
 #endif
 		} s;
 		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			EC_GROUP * group;
+			BIGNUM *priv_key;
+#endif
+		} ec;
+		struct {
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 			OSSL_PARAM * params;
 #endif
 		} sm2;
+		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			OSSL_PARAM * params;
+#endif
+		} eddsa;
 	} u;
 };
 /** Set and validate OPENSSL crypto session parameters */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index e10a172f46..4e4d06403b 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2849,6 +2849,45 @@ process_openssl_rsa_op_evp(struct rte_crypto_op *cop,
 
 }
 
+static int
+process_openssl_ecfpm_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	const EC_GROUP *ecgrp = sess->u.ec.group;
+	EC_POINT *ecpt = NULL;
+	BN_CTX *ctx = NULL;
+	BIGNUM *n = NULL;
+	int ret = -1;
+
+	n = BN_bin2bn((const unsigned char *)
+			cop->asym->ecpm.scalar.data,
+			cop->asym->ecpm.scalar.length,
+			BN_new());
+
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto err_ecfpm;
+
+	if (!EC_POINT_mul(ecgrp, ecpt, n, NULL, NULL, ctx))
+		goto err_ecfpm;
+
+	if (cop->asym->flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED) {
+		unsigned char *buf = cop->asym->ecpm.r.x.data;
+		size_t sz;
+
+		sz = EC_POINT_point2oct(ecgrp, ecpt, POINT_CONVERSION_COMPRESSED, buf, 0, ctx);
+		if (!sz)
+			goto err_ecfpm;
+
+		cop->asym->ecpm.r.x.length = sz;
+	}
+
+err_ecfpm:
+	BN_CTX_free(ctx);
+	BN_free(n);
+	return ret;
+}
+
 static int
 process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3074,6 +3113,158 @@ process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 	return ret;
 }
 
+static int
+process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	static const char * const instance[] = {"Ed25519", "Ed25519ctx", "Ed25519ph",
+						"Ed448", "Ed448ph"};
+	EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
+	const uint8_t curve_id = sess->u.eddsa.curve_id;
+	struct rte_crypto_asym_op *op = cop->asym;
+	OSSL_PARAM *params = sess->u.eddsa.params;
+	OSSL_PARAM_BLD *iparam_bld = NULL;
+	OSSL_PARAM *iparams = NULL;
+	uint8_t signbuf[128] = {0};
+	EVP_MD_CTX *md_ctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	size_t signlen;
+	int ret = -1;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	iparam_bld = OSSL_PARAM_BLD_new();
+	if (!iparam_bld)
+		goto err_eddsa;
+
+	if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519CTX) {
+		OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-string",
+			op->eddsa.context.data, op->eddsa.context.length);
+
+	}
+
+	OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
+		instance[op->eddsa.instance], strlen(instance[op->eddsa.instance]));
+
+	iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
+	if (!iparams)
+		goto err_eddsa;
+
+	switch (op->eddsa.op_type) {
+	case RTE_CRYPTO_ASYM_OP_SIGN:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			if (!EVP_DigestSign(md_ctx, NULL, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			if (signlen > RTE_DIM(signbuf))
+				goto err_eddsa;
+
+			if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
+			op->eddsa.sign.length = signlen;
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_VERIFY:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			signlen = op->eddsa.sign.length;
+			memcpy(&signbuf[0], op->eddsa.sign.data, op->eddsa.sign.length);
+
+			ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op->eddsa.message.data,
+					op->eddsa.message.length);
+			if (ret == 0)
+				goto err_eddsa;
+		}
+		break;
+	default:
+		/* allow ops with invalid args to be pushed to
+		 * completion queue
+		 */
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		goto err_eddsa;
+	}
+
+	ret = 0;
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+err_eddsa:
+	OSSL_PARAM_BLD_free(iparam_bld);
+
+	if (sctx)
+		EVP_PKEY_CTX_free(sctx);
+
+	if (cctx)
+		EVP_PKEY_CTX_free(cctx);
+
+	if (pkey)
+		EVP_PKEY_free(pkey);
+
+	return ret;
+}
 #else
 static int
 process_openssl_rsa_op(struct rte_crypto_op *cop,
@@ -3174,6 +3365,15 @@ process_openssl_rsa_op(struct rte_crypto_op *cop,
 	return 0;
 }
 
+static int
+process_openssl_ecfpm_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
+
 static int
 process_openssl_sm2_op(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3182,6 +3382,15 @@ process_openssl_sm2_op(struct rte_crypto_op *cop,
 	RTE_SET_USED(sess);
 	return -ENOTSUP;
 }
+
+static int
+process_openssl_eddsa_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
 #endif
 
 static int
@@ -3230,6 +3439,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 				process_openssl_dsa_verify_op(op, sess);
 		else
 			op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_ecfpm_op_evp(op, sess);
+#else
+		retval = process_openssl_ecfpm_op(op, sess);
 #endif
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
@@ -3237,6 +3453,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 		retval = process_openssl_sm2_op_evp(op, sess);
 #else
 		retval = process_openssl_sm2_op(op, sess);
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_eddsa_op_evp(op, sess);
+#else
+		retval = process_openssl_eddsa_op(op, sess);
 #endif
 		break;
 	default:
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index b7b612fc57..0725184653 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -593,6 +593,16 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		},
 		}
 	},
+	{	/* ECFPM */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM,
+				.op_types = 0
+				}
+			}
+		}
+	},
 	{	/* SM2 */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
@@ -610,6 +620,20 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		}
 		}
 	},
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types =
+				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
+				 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+			}
+		}
+		}
+	},
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1356,6 +1380,47 @@ static int openssl_set_asym_session_parameters(
 		BN_free(pub_key);
 		return -1;
 	}
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		EC_GROUP *ecgrp = NULL;
+
+		asym_session->xfrm_type = xform->xform_type;
+
+		switch (xform->ec.curve_id) {
+		case RTE_CRYPTO_EC_GROUP_SECP192R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp192k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP224R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp224r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP256R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP384R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp384r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP521R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp521r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED25519:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED25519);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED448:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED448);
+			break;
+		default:
+			break;
+		}
+
+		asym_session->u.ec.curve_id = xform->ec.curve_id;
+		asym_session->u.ec.group = ecgrp;
+		break;
+#else
+		OPENSSL_LOG(WARNING, "ECFPM unsupported for OpenSSL Version < 3.0");
+		return -ENOTSUP;
+#endif
+	}
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 	{
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
@@ -1440,6 +1505,66 @@ static int openssl_set_asym_session_parameters(
 #else
 		OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL Version < 3.0");
 		return -ENOTSUP;
+#endif
+	}
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+		OSSL_PARAM_BLD *param_bld = NULL;
+		OSSL_PARAM *params = NULL;
+		int ret = -1;
+
+		asym_session->u.eddsa.curve_id = xform->ec.curve_id;
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate params");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+			  OSSL_PKEY_PARAM_GROUP_NAME, "ED25519", sizeof("ED25519"));
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PRIV_KEY,
+				xform->ec.pkey.data, xform->ec.pkey.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
+				xform->ec.q.x.data, xform->ec.q.x.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params");
+			goto err_eddsa;
+		}
+
+		params = OSSL_PARAM_BLD_to_param(param_bld);
+		if (!params) {
+			OPENSSL_LOG(ERR, "failed to push params");
+			goto err_eddsa;
+		}
+
+		asym_session->u.eddsa.params = params;
+		OSSL_PARAM_BLD_free(param_bld);
+
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		break;
+err_eddsa:
+		if (param_bld)
+			OSSL_PARAM_BLD_free(param_bld);
+
+		if (asym_session->u.eddsa.params)
+			OSSL_PARAM_free(asym_session->u.eddsa.params);
+
+		return -1;
+#else
+		OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL Version < 3.3");
+		return -ENOTSUP;
 #endif
 	}
 	default:
@@ -1538,6 +1663,12 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 		OSSL_PARAM_free(sess->u.sm2.params);
 #endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+		OSSL_PARAM_free(sess->u.eddsa.params);
+#endif
+		break;
 	default:
 		break;
 	}
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v5 3/6] crypto/cnxk: support EDDSA
  2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-10-04  5:30           ` [PATCH v5 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
@ 2024-10-04  5:30           ` Gowrishankar Muthukrishnan
  2024-10-04  5:30           ` [PATCH v5 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
                             ` (3 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  5:30 UTC (permalink / raw)
  To: dev, Ankur Dwivedi, Anoob Joseph, Tejasree Kondoj,
	Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
	Harman Kalra
  Cc: bruce.richardson, jerinj, fanzhang.oss, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Akhil Goyal, Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in CNXK PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
v5:
 - long line fixed.
---
 doc/guides/cryptodevs/features/cn10k.ini      |   1 +
 drivers/common/cnxk/hw/cpt.h                  |   3 +-
 drivers/common/cnxk/roc_ae.c                  |  52 +-
 drivers/common/cnxk/roc_ae.h                  |  10 +
 drivers/common/cnxk/roc_ae_fpm_tables.c       | 580 +++++++++++++++++-
 drivers/crypto/cnxk/cnxk_ae.h                 | 455 +++++++++++++-
 drivers/crypto/cnxk/cnxk_cryptodev.h          |   2 +-
 .../crypto/cnxk/cnxk_cryptodev_capabilities.c |  19 +
 drivers/crypto/cnxk/cnxk_cryptodev_ops.c      |   2 +-
 drivers/crypto/cnxk/cnxk_cryptodev_ops.h      |   2 +
 10 files changed, 1112 insertions(+), 14 deletions(-)

diff --git a/doc/guides/cryptodevs/features/cn10k.ini b/doc/guides/cryptodevs/features/cn10k.ini
index 39f4b56b9f..bb7d265005 100644
--- a/doc/guides/cryptodevs/features/cn10k.ini
+++ b/doc/guides/cryptodevs/features/cn10k.ini
@@ -107,6 +107,7 @@ ECDH                    = Y
 ECDSA                   = Y
 ECPM                    = Y
 SM2                     = Y
+EDDSA                   = Y
 
 ;
 ; Supported Operating systems of the 'cn10k' crypto driver.
diff --git a/drivers/common/cnxk/hw/cpt.h b/drivers/common/cnxk/hw/cpt.h
index 2620965606..47df3fbf9f 100644
--- a/drivers/common/cnxk/hw/cpt.h
+++ b/drivers/common/cnxk/hw/cpt.h
@@ -81,7 +81,8 @@ union cpt_eng_caps {
 		uint64_t __io sm2 : 1;
 		uint64_t __io pdcp_chain_zuc256 : 1;
 		uint64_t __io tls : 1;
-		uint64_t __io reserved_39_63 : 25;
+		uint64_t __io eddsa : 1;
+		uint64_t __io reserved_40_63 : 24;
 	};
 };
 
diff --git a/drivers/common/cnxk/roc_ae.c b/drivers/common/cnxk/roc_ae.c
index 7ef0efe2b3..2c563c30de 100644
--- a/drivers/common/cnxk/roc_ae.c
+++ b/drivers/common/cnxk/roc_ae.c
@@ -179,7 +179,57 @@ const struct roc_ae_ec_group ae_ec_grp[ROC_AE_EC_ID_PMAX] = {
 				    0xAB, 0x8F, 0x92, 0xDD, 0xBC, 0xBD, 0x41,
 				    0x4D, 0x94, 0x0E, 0x93},
 			   .length = 32},
-	}};
+	},
+	{
+		.prime = {.data = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0x7F},
+			  .length = 32},
+		.order = {.data = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12,
+				   0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9,
+				   0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x10},
+			  .length = 32},
+		.consta = {.data = {0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb,
+				    0x75, 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a,
+				    0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79,
+				    0x40, 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b,
+				    0xee, 0x6c, 0x03, 0x52},
+			   .length = 32},
+	},
+	{
+		.prime = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			  .length = 56},
+		.order = {.data = {0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78,
+				   0x23, 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2,
+				   0x6c, 0x21, 0x90, 0x36, 0xd6, 0xae, 0x49,
+				   0xdb, 0x4e, 0xc4, 0xe9, 0x23, 0xca, 0x7c,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f},
+			  .length = 56},
+		.consta = {.data = {0x56, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			   .length = 56},
+	},
+};
 
 int
 roc_ae_ec_grp_get(struct roc_ae_ec_group **tbl)
diff --git a/drivers/common/cnxk/roc_ae.h b/drivers/common/cnxk/roc_ae.h
index 7886b9d107..6595f22754 100644
--- a/drivers/common/cnxk/roc_ae.h
+++ b/drivers/common/cnxk/roc_ae.h
@@ -12,6 +12,7 @@
 #define ROC_AE_MAJOR_OP_MODEX	     0x03
 #define ROC_AE_MAJOR_OP_EC	     0x04
 #define ROC_AE_MAJOR_OP_ECC	     0x05
+#define ROC_AE_MAJOR_OP_EDDSA	     0x0A
 #define ROC_AE_MINOR_OP_RANDOM	     0x00
 #define ROC_AE_MINOR_OP_MODEX	     0x01
 #define ROC_AE_MINOR_OP_PKCS_ENC     0x02
@@ -23,6 +24,9 @@
 #define ROC_AE_MINOR_OP_EC_VERIFY    0x02
 #define ROC_AE_MINOR_OP_ECC_UMP	     0x03
 #define ROC_AE_MINOR_OP_ECC_FPM	     0x04
+#define ROC_AE_MINOR_OP_ED_SIGN      0x00
+#define ROC_AE_MINOR_OP_ED_VERIFY    0x01
+#define ROC_AE_MINOR_OP_ED_KEYGEN    0x02
 
 /**
  * Enumeration roc_ae_ec_id
@@ -39,6 +43,8 @@ typedef enum {
 	ROC_AE_EC_ID_P320 = 6,
 	ROC_AE_EC_ID_P512 = 7,
 	ROC_AE_EC_ID_SM2  = 8,
+	ROC_AE_EC_ID_ED25519 = 9,
+	ROC_AE_EC_ID_ED448 = 10,
 	ROC_AE_EC_ID_PMAX
 } roc_ae_ec_id;
 
@@ -47,6 +53,10 @@ typedef enum {
 #define ROC_AE_EC_PARAM1_SM2       (1 << 7)
 #define ROC_AE_EC_PARAM1_NIST      (0 << 6)
 #define ROC_AE_EC_PARAM1_NONNIST   (1 << 6)
+#define ROC_AE_ED_PARAM1_25519     (1 << 1)
+#define ROC_AE_ED_PARAM1_448       (1 << 3)
+#define ROC_AE_ED_PARAM1_KEYGEN_BIT      4
+#define ROC_AE_EC_PARAM1_PH_BIT          5
 
 typedef enum {
 	ROC_AE_ERR_ECC_PAI = 0x0b,
diff --git a/drivers/common/cnxk/roc_ae_fpm_tables.c b/drivers/common/cnxk/roc_ae_fpm_tables.c
index 942657b56a..9dcf60ef03 100644
--- a/drivers/common/cnxk/roc_ae_fpm_tables.c
+++ b/drivers/common/cnxk/roc_ae_fpm_tables.c
@@ -21,7 +21,9 @@ typedef enum {
 	AE_FPM_P224_LEN = 2160,
 	AE_FPM_P256_LEN = 2160,
 	AE_FPM_P384_LEN = 2520,
-	AE_FPM_P521_LEN = 3240
+	AE_FPM_P521_LEN = 3240,
+	AE_FPM_ED25519_LEN = 2880,
+	AE_FPM_ED448_LEN = 3840,
 } ae_fpm_len;
 
 /* FPM table address and length */
@@ -1240,6 +1242,572 @@ const uint8_t ae_fpm_tbl_p256_sm2[AE_FPM_P256_LEN] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+const uint8_t ae_fpm_tbl_ed25519[AE_FPM_ED25519_LEN] = {
+	0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a, 0x69, 0x2c, 0xc7, 0x60,
+	0x95, 0x25, 0xa7, 0xb2, 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c,
+	0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6d, 0xde, 0x8a, 0xb3, 0xa5, 0xb7, 0xdd, 0xa3, 0x20, 0xf0, 0x9f, 0x80,
+	0x77, 0x51, 0x52, 0xf5, 0x66, 0xea, 0x4e, 0x8e, 0x64, 0xab, 0xe3, 0x7d,
+	0x67, 0x87, 0x5f, 0x0f, 0xd7, 0x8b, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x18, 0xc0, 0x0c, 0x55, 0x07, 0xed, 0xf1, 0x0d, 0x69, 0xbe, 0x61, 0x3a,
+	0x4f, 0x82, 0xd2, 0xc4, 0x3e, 0xf0, 0xa1, 0x4e, 0xf1, 0xba, 0xd8, 0xb1,
+	0x5a, 0x8a, 0x5a, 0x58, 0xbe, 0xf1, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x63, 0xce, 0x54, 0x79, 0x0e, 0x45, 0x3f, 0x73, 0xe9, 0x33, 0xff, 0xc7,
+	0xec, 0xab, 0xc7, 0x4b, 0x6b, 0x43, 0x64, 0x02, 0x45, 0xcf, 0x64, 0xfa,
+	0x1a, 0xd2, 0xdd, 0x57, 0x64, 0x55, 0xf6, 0x78, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x8c, 0x9d, 0x04, 0xac, 0x84, 0x05, 0xe0, 0xe7, 0xa5, 0x17, 0x56,
+	0x92, 0x2e, 0xbd, 0x07, 0x96, 0x72, 0x74, 0xa7, 0xd8, 0x1d, 0x8d, 0x30,
+	0x42, 0x4d, 0xa3, 0xd2, 0x15, 0xae, 0xf3, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x19, 0xcf, 0x23, 0xc1, 0x1f, 0x40, 0x15, 0x86, 0x4d, 0xd5, 0x99, 0x64,
+	0x9b, 0x94, 0x9e, 0x8e, 0x22, 0x68, 0xc6, 0xcf, 0xf4, 0xe4, 0xf9, 0xd9,
+	0x75, 0xe4, 0xce, 0xc7, 0xf1, 0xc8, 0x41, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x98, 0x8c, 0x87, 0x10, 0xcd, 0x87, 0x55, 0x95, 0x52, 0x83, 0xad, 0xc1,
+	0x83, 0x92, 0xcf, 0xa4, 0x28, 0x4a, 0x93, 0xe5, 0x21, 0x53, 0xaa, 0x3d,
+	0x33, 0x97, 0x60, 0xe6, 0xcb, 0xdc, 0xf5, 0xd4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe6, 0xf2, 0x50, 0x1e, 0x50, 0x14, 0x12, 0xd8, 0x45, 0xcc, 0xd0, 0xd4,
+	0x75, 0x78, 0xec, 0xae, 0x42, 0x10, 0x45, 0x12, 0x74, 0x2b, 0x26, 0xde,
+	0x41, 0xea, 0x80, 0x41, 0x7f, 0xb3, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x75, 0x61, 0x33, 0xad, 0x0c, 0x22, 0xe4, 0x7f, 0xd7, 0x18, 0xb3,
+	0xf9, 0xd3, 0x55, 0x9e, 0x96, 0x2d, 0xa3, 0xfa, 0x7d, 0xfb, 0x1e, 0xb6,
+	0x4e, 0xd0, 0xb6, 0x26, 0xa7, 0x32, 0x09, 0x87, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaf, 0x7f, 0xd1, 0x3e, 0xfe, 0xa5, 0xa5, 0x96, 0x3c, 0x42, 0xec, 0x0e,
+	0xef, 0x69, 0x4e, 0x62, 0xf5, 0xb9, 0xc2, 0xad, 0x65, 0x7b, 0x91, 0x6f,
+	0x25, 0x55, 0x0a, 0xc3, 0x9c, 0xfb, 0x1a, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2a, 0xf9, 0xfb, 0x16, 0x90, 0xe8, 0x72, 0x7e, 0x98, 0x92, 0x1f, 0xc5,
+	0x97, 0x96, 0xc5, 0x0c, 0x8a, 0x12, 0x0b, 0xf3, 0x98, 0xc0, 0x5f, 0x4d,
+	0x38, 0x56, 0x94, 0x41, 0xa1, 0xf5, 0xcd, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0x39, 0xdb, 0x96, 0xf7, 0x8d, 0x2e, 0x7c, 0xb1, 0xc0, 0x51, 0x3b,
+	0xa4, 0xc4, 0x55, 0x12, 0x75, 0x29, 0xd9, 0x29, 0x65, 0x02, 0x36, 0x8d,
+	0x0a, 0x97, 0xdf, 0xad, 0x58, 0xfa, 0x26, 0x19, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0x4b, 0xb5, 0xe5, 0x13, 0xa5, 0x45, 0x40, 0x2c, 0xba, 0x4d, 0x3b,
+	0x1e, 0x5f, 0x55, 0xb8, 0x04, 0xa2, 0xce, 0x24, 0x52, 0x7e, 0xb7, 0x3c,
+	0x78, 0xd9, 0x8e, 0xba, 0xc3, 0x3b, 0xd9, 0x46, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb2, 0x1d, 0x1e, 0x95, 0xfb, 0x8d, 0x9a, 0xdd, 0xdb, 0xfc, 0xa8, 0xca,
+	0x0f, 0x51, 0x54, 0x75, 0x72, 0x53, 0xc9, 0xca, 0xe4, 0x6b, 0x0a, 0x2f,
+	0x3d, 0xc4, 0xd8, 0x0a, 0x0c, 0x80, 0x9a, 0xb6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0xc6, 0x8e, 0xea, 0x63, 0xb3, 0x17, 0x45, 0x1b, 0xc9, 0x4f, 0xf2,
+	0xb9, 0xce, 0xab, 0x28, 0x84, 0x84, 0x27, 0x82, 0x6e, 0x59, 0x5d, 0x0d,
+	0x57, 0x1c, 0xd9, 0x4b, 0x55, 0xf8, 0xa2, 0xd1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x76, 0xd4, 0x7d, 0xa8, 0x8a, 0xfd, 0x34, 0xf3, 0x5e, 0xa7, 0x1b, 0x7c,
+	0x94, 0x84, 0x05, 0x81, 0x7f, 0x9d, 0x55, 0x08, 0x06, 0x03, 0x5e, 0x42,
+	0x42, 0xe8, 0x55, 0x9a, 0xac, 0x90, 0x41, 0xf2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x74, 0xd2, 0x01, 0x61, 0xc0, 0x1f, 0x88, 0x8b, 0xcb, 0xca, 0xf5, 0xd3,
+	0x63, 0x58, 0x4b, 0xbb, 0x66, 0xc6, 0x4e, 0xab, 0x8c, 0x6c, 0x68, 0x22,
+	0x66, 0xca, 0x84, 0x72, 0x7e, 0x3c, 0x0b, 0xa2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0x0b, 0xdb, 0xf8, 0x8a, 0x48, 0x29, 0x71, 0x03, 0xf7, 0xcf, 0x4d,
+	0xb1, 0x85, 0x7a, 0x22, 0x97, 0xbe, 0x2e, 0xd9, 0xa1, 0xee, 0x20, 0x13,
+	0x2f, 0x5e, 0x07, 0xda, 0x24, 0x97, 0xb3, 0x43, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xec, 0x5e, 0x68, 0xad, 0xfe, 0x26, 0x70, 0x65, 0xfa, 0x03, 0x3f, 0x24,
+	0x56, 0xa2, 0x51, 0xc9, 0x79, 0x88, 0x89, 0x08, 0x86, 0x02, 0x18, 0x39,
+	0x59, 0x77, 0x53, 0x1b, 0xf7, 0x2c, 0x65, 0x3c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x23, 0xb1, 0xc4, 0x4d, 0xad, 0xf1, 0xae, 0x7a, 0x52, 0xba, 0x48,
+	0xd0, 0x0a, 0xc1, 0x94, 0x34, 0x41, 0x1b, 0x3d, 0x93, 0x49, 0xf0, 0x8d,
+	0x25, 0xf2, 0x72, 0x56, 0xd7, 0xb7, 0x05, 0x81, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0x05, 0x2c, 0x85, 0xc5, 0x52, 0xad, 0x02, 0xbd, 0xb7, 0x5d, 0x21,
+	0xcd, 0xbd, 0xce, 0x01, 0xd3, 0xd9, 0x12, 0xba, 0xc6, 0x7f, 0x45, 0x31,
+	0x00, 0x33, 0x8c, 0x20, 0x63, 0x4d, 0xf5, 0x22, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1a, 0x38, 0xa7, 0xf1, 0x5b, 0xd0, 0xb8, 0x54, 0x3c, 0x33, 0x27, 0x32,
+	0xca, 0x04, 0x38, 0x5e, 0xa0, 0xf8, 0x81, 0x06, 0xa0, 0xe7, 0x47, 0x1d,
+	0x16, 0xcb, 0xaa, 0x68, 0xb5, 0x6a, 0xd2, 0xaa, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3e, 0x69, 0x14, 0xef, 0xc0, 0x82, 0x94, 0x72, 0x09, 0x07, 0xb5, 0xa6,
+	0x98, 0x1d, 0xb2, 0xd7, 0xcb, 0xe4, 0x6c, 0xb7, 0x88, 0x78, 0x8b, 0xd9,
+	0x34, 0x5a, 0xdb, 0xae, 0x55, 0x6a, 0x6b, 0x1f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf1, 0x20, 0x49, 0xc6, 0xda, 0x47, 0x7a, 0x25, 0x9e, 0xce, 0xf6, 0x2e,
+	0xd4, 0x76, 0xb6, 0x0f, 0x41, 0x54, 0x08, 0xb8, 0x29, 0x08, 0x96, 0xd0,
+	0x01, 0x23, 0x34, 0xb6, 0x1e, 0xfe, 0xb0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd1, 0x6c, 0x52, 0xd3, 0x5f, 0x6a, 0x74, 0x18, 0x9b, 0xfe, 0xf3, 0x73,
+	0x74, 0xb8, 0x05, 0xa2, 0x29, 0x9d, 0x41, 0x53, 0x72, 0xa2, 0x93, 0x7c,
+	0x0a, 0xa8, 0xe8, 0x48, 0x89, 0x8f, 0x6f, 0x60, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x21, 0x4a, 0xd6, 0xa6, 0x0b, 0x51, 0xf6, 0x1d, 0xa2, 0x5c, 0xa5, 0x23,
+	0x6a, 0x1e, 0x34, 0x7d, 0xc5, 0xfe, 0xba, 0x77, 0x9d, 0xe5, 0x40, 0x9c,
+	0x38, 0x4e, 0xab, 0x29, 0x0d, 0x17, 0x7e, 0x48, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1e, 0x04, 0x03, 0xaf, 0xbd, 0x77, 0xba, 0x7d, 0x53, 0xe9, 0x14, 0x63,
+	0x40, 0xa7, 0xba, 0x26, 0x00, 0x55, 0x42, 0xff, 0x7c, 0x0d, 0xde, 0xd1,
+	0x59, 0xa2, 0x72, 0x6d, 0x1a, 0x92, 0x7e, 0x56, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x6d, 0x5c, 0x1d, 0x19, 0xf5, 0x09, 0x6d, 0x18, 0xa1, 0x69, 0x87,
+	0xad, 0x52, 0x19, 0x1e, 0xf1, 0x83, 0x14, 0xea, 0x85, 0x1c, 0xeb, 0xe0,
+	0x09, 0x34, 0x4b, 0x8a, 0xd2, 0x98, 0x25, 0x20, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4c, 0x5a, 0xf1, 0x8b, 0x60, 0xa3, 0xef, 0xfb, 0xe6, 0x9a, 0x9e, 0x2a,
+	0x7c, 0x79, 0x13, 0x18, 0x9b, 0x68, 0xed, 0x3d, 0x9c, 0x96, 0x87, 0x75,
+	0x7d, 0x03, 0x00, 0x62, 0x8a, 0x38, 0x69, 0x58, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8e, 0x21, 0xc4, 0x17, 0x0e, 0x2d, 0x4e, 0x01, 0xb5, 0xfb, 0x2e, 0x65,
+	0x3f, 0x32, 0xd7, 0x18, 0x50, 0x70, 0x81, 0x6b, 0xf7, 0xab, 0xc2, 0xfc,
+	0x4b, 0xa9, 0x21, 0x10, 0x37, 0x21, 0xbf, 0xbb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xda, 0x5a, 0x33, 0xeb, 0x21, 0x36, 0x7c, 0x40, 0x16, 0x1d, 0xd5, 0x6e,
+	0xe1, 0xe4, 0x79, 0x2b, 0x9f, 0x9f, 0x06, 0x89, 0x80, 0x93, 0xc6, 0x0f,
+	0x61, 0xbe, 0x0b, 0x75, 0xdb, 0x7c, 0x78, 0x50, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8b, 0xdc, 0x45, 0xa9, 0x5e, 0xbc, 0xf3, 0xb4, 0xcc, 0x3c, 0xba, 0xbd,
+	0x65, 0x2f, 0x2f, 0xd7, 0xd5, 0x15, 0x7f, 0x7e, 0x03, 0x0b, 0xc6, 0xc7,
+	0x6b, 0x6b, 0x6e, 0x77, 0x30, 0xcb, 0xc0, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2e, 0xf0, 0x16, 0xcd, 0xf9, 0x23, 0xf9, 0x10, 0xe0, 0x5d, 0xa7, 0x26,
+	0xbb, 0xf1, 0x53, 0x06, 0xea, 0x81, 0x2f, 0x38, 0x9e, 0x53, 0x67, 0x40,
+	0x74, 0x2a, 0xd5, 0x6e, 0xec, 0xc8, 0xa5, 0xcb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe2, 0x1f, 0xc1, 0xee, 0x82, 0xd5, 0x6e, 0x58, 0x81, 0x97, 0x4c, 0xf3,
+	0x0b, 0x90, 0x1e, 0x1f, 0xf8, 0xdc, 0x2b, 0xc0, 0x58, 0x3b, 0x2a, 0x28,
+	0x56, 0xc1, 0xe7, 0xb4, 0x40, 0x44, 0x5b, 0x54, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x85, 0x49, 0x08, 0xe7, 0xfa, 0x5d, 0x0c, 0xf9, 0xa3, 0x6e, 0xe5,
+	0x34, 0x8e, 0x83, 0xf2, 0xd0, 0xf1, 0xa4, 0x13, 0x32, 0x52, 0x86, 0x50,
+	0x75, 0xcd, 0xb5, 0xfc, 0xe9, 0x7b, 0x7c, 0xf6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2c, 0x85, 0x09, 0xe3, 0xd9, 0x4a, 0x91, 0xa2, 0x10, 0xf7, 0x7f, 0x5b,
+	0xde, 0x9a, 0xb7, 0x87, 0x32, 0x7d, 0x63, 0xf6, 0x7e, 0x0c, 0x3e, 0xcc,
+	0x4a, 0xa4, 0x9e, 0x35, 0x6b, 0x55, 0x50, 0x2e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xde, 0x9c, 0x80, 0x75, 0xc0, 0x21, 0x92, 0xf7, 0x30, 0x72, 0x1c, 0x15,
+	0xb2, 0x00, 0x0e, 0xc4, 0xa1, 0xa6, 0x1a, 0x6d, 0xd1, 0x63, 0x6b, 0xa8,
+	0x4b, 0x01, 0x10, 0x6f, 0x61, 0xe7, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7f, 0xdd, 0x3e, 0x2e, 0x6d, 0x7e, 0xed, 0x72, 0x65, 0xf7, 0x8d, 0x29,
+	0xba, 0x75, 0xa3, 0x07, 0x93, 0x86, 0xb4, 0xee, 0xcd, 0xd8, 0x5d, 0x19,
+	0x22, 0x02, 0x39, 0xba, 0xc5, 0x05, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa2, 0x01, 0xed, 0x74, 0x47, 0xd9, 0x0b, 0x18, 0x73, 0x4d, 0xcd, 0x41,
+	0x9a, 0xe4, 0xf1, 0xee, 0x33, 0x8a, 0x74, 0x8b, 0x26, 0xfd, 0x6e, 0x02,
+	0x2e, 0x5c, 0xc7, 0xf5, 0xa1, 0xeb, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3a, 0x3c, 0x00, 0x91, 0x80, 0xf2, 0x0f, 0x07, 0xf5, 0x02, 0xdc, 0xfa,
+	0xb7, 0x6e, 0x74, 0xdc, 0x3a, 0x78, 0xc5, 0x28, 0x8e, 0x17, 0x4f, 0xf1,
+	0x54, 0x40, 0x61, 0xfa, 0x46, 0x6c, 0x6d, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0x5f, 0xf2, 0x5a, 0x62, 0xbc, 0x77, 0xc1, 0xea, 0xbb, 0x38, 0xc2,
+	0x7e, 0x63, 0xac, 0x59, 0xc9, 0xd1, 0x37, 0xea, 0xeb, 0x09, 0x77, 0xa1,
+	0x6b, 0x49, 0x7e, 0x17, 0xc3, 0xab, 0x03, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xce, 0x14, 0xe5, 0x45, 0x4b, 0x16, 0x3e, 0x4a, 0xec, 0x3d, 0x52, 0x21,
+	0x35, 0xff, 0xe5, 0x33, 0x06, 0x46, 0x11, 0x32, 0x96, 0xc0, 0x34, 0x06,
+	0x04, 0x31, 0x37, 0x31, 0x25, 0xde, 0xde, 0xd8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x11, 0xbe, 0x6b, 0x47, 0xcd, 0x4a, 0xfd, 0xc3, 0x0d, 0x90, 0x1c, 0xc0,
+	0xd4, 0x70, 0x96, 0x72, 0xec, 0x42, 0xd6, 0x1d, 0x25, 0x5a, 0x9c, 0xd2,
+	0x23, 0xd6, 0x8e, 0xaf, 0x95, 0x7e, 0xfb, 0xd3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xdf, 0x28, 0x49, 0xeb, 0xa9, 0x5a, 0x0b, 0xf6, 0xf0, 0x9f, 0x4a,
+	0x47, 0x70, 0xf3, 0x49, 0x5f, 0x6f, 0xac, 0x86, 0x40, 0xfb, 0x0d, 0xf7,
+	0x72, 0xab, 0x23, 0x3d, 0x91, 0x08, 0x8c, 0x32, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0xb9, 0xe2, 0xb7, 0x4e, 0x62, 0xde, 0xcc, 0xd7, 0x68, 0xbd, 0x60,
+	0x83, 0x7d, 0x9c, 0x61, 0xfd, 0xd8, 0x5e, 0xb7, 0x64, 0x9b, 0xce, 0xa5,
+	0x23, 0x81, 0x2c, 0xcd, 0x9b, 0x5a, 0xaa, 0xd6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1d, 0x4a, 0x45, 0xf9, 0x1b, 0x9f, 0xa9, 0xfd, 0x38, 0x86, 0x31, 0x53,
+	0x9a, 0x2f, 0xb5, 0x5d, 0x2d, 0xed, 0x31, 0x75, 0x30, 0xd6, 0xbb, 0xdd,
+	0x53, 0x9b, 0x5f, 0xe0, 0xab, 0xd7, 0xaf, 0xe0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xee, 0xb3, 0x3b, 0xf0, 0x8a, 0x11, 0xd5, 0x5e, 0x37, 0xfd, 0x5a, 0x03,
+	0xaf, 0xaf, 0x0c, 0x99, 0xcc, 0x62, 0x92, 0x12, 0x30, 0x52, 0xac, 0x72,
+	0x7f, 0x51, 0x65, 0x44, 0x19, 0xf9, 0xe4, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x95, 0x4b, 0x50, 0xb3, 0x76, 0xa6, 0xa4, 0xb1, 0x9a, 0x39, 0x1e,
+	0x0d, 0x64, 0xfe, 0xc0, 0xf4, 0x43, 0xef, 0x85, 0x0a, 0xc2, 0xe3, 0xb0,
+	0x58, 0xc3, 0xf0, 0xf8, 0xdb, 0x67, 0xfc, 0x36, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xba, 0x4f, 0xbc, 0x66, 0x32, 0xd4, 0x4e, 0xec, 0x3f, 0x92, 0xfb, 0x0e,
+	0x92, 0x9b, 0x52, 0xe8, 0x27, 0xd9, 0xbb, 0xaa, 0x9c, 0x54, 0x70, 0x82,
+	0x4f, 0xad, 0xca, 0xbc, 0x9e, 0x01, 0x7e, 0x1c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5e, 0xe3, 0x0c, 0xca, 0xa3, 0xaa, 0xd6, 0x3f, 0x90, 0xcc, 0xef, 0xcd,
+	0x74, 0x59, 0xb3, 0xc5, 0xba, 0x35, 0xa8, 0x7e, 0x7e, 0xec, 0x4b, 0x6b,
+	0x00, 0x21, 0xfb, 0xa1, 0x6e, 0x53, 0xc4, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9d, 0xd3, 0xb3, 0xeb, 0xcf, 0xa0, 0x6d, 0xb1, 0x88, 0xab, 0x33, 0xc4,
+	0x0f, 0xd7, 0xb0, 0x76, 0x02, 0x8e, 0x71, 0x61, 0x18, 0x63, 0x07, 0xdc,
+	0x3e, 0x0d, 0xb9, 0xa8, 0x32, 0x75, 0x7a, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0xab, 0xf5, 0x7e, 0x0b, 0x4c, 0x08, 0x30, 0x08, 0x80, 0xc1, 0x9b,
+	0x69, 0x6a, 0x0e, 0xfc, 0x16, 0x81, 0xf1, 0xa9, 0xd4, 0x85, 0x35, 0x94,
+	0x26, 0xc5, 0x23, 0xb4, 0xa8, 0xb1, 0x8a, 0xb8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc5, 0x6d, 0x50, 0x49, 0x27, 0x8d, 0x35, 0x47, 0x0d, 0x73, 0x18, 0xae,
+	0xaf, 0x38, 0xef, 0xfa, 0xdd, 0x70, 0x48, 0x15, 0x39, 0xf0, 0x1c, 0x6e,
+	0x79, 0xd1, 0x13, 0x9f, 0xe4, 0xb3, 0xb2, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x39, 0xeb, 0xfb, 0x14, 0x3f, 0xf0, 0xa0, 0x0b, 0x5e, 0x41, 0x20, 0x0c,
+	0xfe, 0x36, 0x0c, 0x7f, 0xf0, 0xaf, 0xaa, 0xdd, 0x61, 0x66, 0x65, 0x30,
+	0x6b, 0x10, 0x18, 0x28, 0x30, 0xb6, 0x47, 0x3e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf7, 0xa8, 0x12, 0x06, 0x64, 0xfa, 0x90, 0xfa, 0x0c, 0xfb, 0x26, 0xf2,
+	0x2a, 0x1a, 0xc4, 0xf9, 0xae, 0x5c, 0x1b, 0x24, 0xf3, 0xf2, 0x87, 0xa2,
+	0x5c, 0x0a, 0x2a, 0x2b, 0x17, 0xa7, 0x2b, 0x7e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0x6d, 0x30, 0x7d, 0xb2, 0xd1, 0x40, 0xb7, 0x4f, 0x05, 0xac, 0x1a,
+	0xa1, 0x66, 0xa6, 0x19, 0x18, 0xf8, 0xcd, 0xf3, 0x3c, 0xf6, 0x84, 0xc3,
+	0x4d, 0x46, 0x49, 0xf1, 0xf7, 0x28, 0xa6, 0x0c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xf2, 0x0b, 0x90, 0x0d, 0xeb, 0x5c, 0x0b, 0x70, 0x2f, 0x54, 0x26,
+	0x1a, 0x7d, 0x6e, 0x72, 0x67, 0x95, 0x28, 0x03, 0x01, 0x37, 0xfa, 0xc6,
+	0x00, 0x45, 0xa7, 0xda, 0x5b, 0xbf, 0xf0, 0x24, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa9, 0x6c, 0x1d, 0x2b, 0x7e, 0xea, 0x35, 0x8b, 0x92, 0x12, 0x42, 0xf9,
+	0x8f, 0x67, 0x38, 0xf5, 0xf7, 0x1a, 0xe2, 0x8f, 0xb4, 0x40, 0x45, 0x2a,
+	0x47, 0xca, 0x9d, 0xbf, 0xbd, 0x85, 0xc0, 0xd2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+const uint8_t ae_fpm_tbl_ed448[AE_FPM_ED448_LEN] = {
+	0x26, 0x26, 0xa8, 0x2b, 0xc7, 0x0c, 0xc0, 0x5e, 0x43, 0x3b, 0x80, 0xe1,
+	0x8b, 0x00, 0x93, 0x8e, 0x12, 0xae, 0x1a, 0xf7, 0x2a, 0xb6, 0x65, 0x11,
+	0xea, 0x6d, 0xe3, 0x24, 0xa3, 0xd3, 0xa4, 0x64, 0x9e, 0x14, 0x65, 0x70,
+	0x47, 0x0f, 0x17, 0x67, 0x22, 0x1d, 0x15, 0xa6, 0x22, 0xbf, 0x36, 0xda,
+	0x4f, 0x19, 0x70, 0xc6, 0x6b, 0xed, 0x0d, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x98, 0x08, 0x79, 0x5b, 0xf2, 0x30, 0xfa, 0x14,
+	0xfd, 0xbd, 0x13, 0x2c, 0x4e, 0xd7, 0xc8, 0xad, 0x3a, 0xd3, 0xff, 0x1c,
+	0xe6, 0x7c, 0x39, 0xc4, 0x87, 0x78, 0x9c, 0x1e, 0x05, 0xa0, 0xc2, 0xd7,
+	0x4b, 0xea, 0x73, 0x73, 0x6c, 0xa3, 0x98, 0x40, 0x88, 0x76, 0x20, 0x37,
+	0x56, 0xc9, 0xc7, 0x62, 0x69, 0x3f, 0x46, 0x71, 0x6e, 0xb6, 0xbc, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xeb, 0x06, 0x62, 0x4e, 0x82, 0xaf, 0x95, 0xf3, 0xf7, 0x8f, 0xa0, 0x7d,
+	0x85, 0x66, 0x2d, 0x1d, 0xf1, 0x79, 0xde, 0x90, 0xb5, 0xb2, 0x7d, 0xa1,
+	0x60, 0xd7, 0x16, 0x67, 0xe2, 0x35, 0x6d, 0x58, 0xc5, 0x05, 0x6a, 0x18,
+	0x3f, 0x84, 0x51, 0xd2, 0xce, 0xc3, 0x9d, 0x2d, 0x50, 0x8d, 0x91, 0xc9,
+	0xc7, 0x5e, 0xb5, 0x8a, 0xee, 0x22, 0x1c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x12, 0x77, 0x1a, 0x0d, 0x31, 0xc0, 0x77, 0xbf,
+	0xc4, 0x24, 0x04, 0xed, 0x68, 0x36, 0xd7, 0x42, 0x6a, 0x65, 0x11, 0x30,
+	0x9d, 0xd9, 0x3a, 0x78, 0x3d, 0x16, 0x5b, 0x3f, 0x5b, 0x32, 0xdd, 0x27,
+	0x70, 0xf9, 0x81, 0x8f, 0x1b, 0xc6, 0x4d, 0xd1, 0x36, 0xf5, 0xf8, 0x56,
+	0x3e, 0x48, 0x3a, 0xc1, 0x28, 0x41, 0x27, 0x74, 0x35, 0xd1, 0x4b, 0x0f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x69, 0x81, 0x50,
+	0x38, 0xfb, 0x26, 0xe1, 0x68, 0x82, 0xe5, 0x52, 0x90, 0x23, 0xc2, 0x5e,
+	0xb3, 0x5e, 0x42, 0x06, 0x65, 0xea, 0x9f, 0x0c, 0x94, 0x4c, 0x92, 0x1f,
+	0x2d, 0x18, 0x4c, 0x04, 0xbe, 0x79, 0xf0, 0x74, 0x2d, 0x5a, 0x0b, 0x29,
+	0xa7, 0x46, 0xb8, 0x80, 0xdf, 0x83, 0x8f, 0x06, 0xe6, 0xe0, 0x8f, 0x72,
+	0x53, 0xfa, 0x6d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb4, 0x85, 0xa6, 0xed, 0xe6, 0xa8, 0x12, 0xd5, 0x7d, 0x97, 0xf7, 0xc8,
+	0xac, 0x2c, 0x4d, 0x2b, 0xfc, 0x53, 0x3e, 0xd0, 0x9f, 0x45, 0xd1, 0x52,
+	0xac, 0x85, 0x4f, 0xf8, 0x36, 0x7c, 0xcd, 0xa6, 0x6c, 0xb8, 0x0f, 0x8f,
+	0xdc, 0xde, 0x54, 0xc3, 0x23, 0x7b, 0xcc, 0xd9, 0xfe, 0x97, 0x19, 0x86,
+	0xa6, 0x17, 0xcd, 0x9b, 0xfe, 0x08, 0xf6, 0x3f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5c, 0xeb, 0x54, 0x97, 0x02, 0x55, 0xed, 0x8f,
+	0xfe, 0x3f, 0xe6, 0x24, 0x26, 0x1e, 0x3a, 0xc8, 0xdf, 0x28, 0xfc, 0xf9,
+	0xb9, 0x1b, 0x9c, 0xc8, 0x1b, 0x5f, 0xb0, 0x08, 0x2b, 0x19, 0x1e, 0x92,
+	0x29, 0xd9, 0x49, 0xa8, 0xb4, 0x61, 0xcc, 0xf3, 0x18, 0x35, 0x0a, 0x40,
+	0x2a, 0xe3, 0x2c, 0x09, 0x21, 0x81, 0x22, 0x38, 0xaf, 0xc2, 0xf4, 0x20,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x2d, 0x7c, 0xe2,
+	0x41, 0xc3, 0x10, 0x65, 0x01, 0x4a, 0x4f, 0xd5, 0x07, 0x2b, 0xa5, 0xd6,
+	0x7c, 0xc0, 0x57, 0x50, 0xc3, 0xf5, 0x63, 0xa0, 0x03, 0x8b, 0x79, 0xa9,
+	0xb1, 0xdd, 0xc4, 0x2f, 0xbe, 0xfa, 0x48, 0x92, 0xca, 0x8e, 0xd7, 0x0d,
+	0xdf, 0xcf, 0x2d, 0x40, 0xa3, 0xbc, 0x7e, 0xe7, 0x2e, 0xbe, 0xe9, 0x21,
+	0x83, 0xc8, 0x79, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xac, 0xdf, 0x2c, 0x05, 0x92, 0x8e, 0xe1, 0x3b, 0xc0, 0x57, 0xd9, 0xb4,
+	0x16, 0x0c, 0x80, 0x17, 0x03, 0x5a, 0x29, 0x4d, 0xef, 0x36, 0x9b, 0x11,
+	0x3b, 0xe2, 0xef, 0xca, 0x7f, 0xdd, 0xd3, 0xa3, 0xd7, 0x7f, 0x2b, 0x64,
+	0xa9, 0x7f, 0x62, 0x72, 0x71, 0x7d, 0x9e, 0x9f, 0xde, 0x2b, 0xcb, 0xd4,
+	0x3e, 0x95, 0x6f, 0x9d, 0x0c, 0x1f, 0x1a, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x92, 0xef, 0x93, 0x8e, 0xe7, 0x0a, 0x10,
+	0x7b, 0xc3, 0xdc, 0x46, 0xd9, 0x96, 0x27, 0x92, 0x91, 0xa4, 0x98, 0x89,
+	0x2d, 0xf2, 0x17, 0x03, 0x8c, 0xdb, 0x98, 0xed, 0xda, 0xb3, 0x15, 0xd5,
+	0xba, 0x58, 0x01, 0x38, 0x6e, 0x54, 0xd7, 0x46, 0x9c, 0x2b, 0x94, 0x5b,
+	0x60, 0x9e, 0x5b, 0x3b, 0xc3, 0x4c, 0x7e, 0xc3, 0xbc, 0x4d, 0xa9, 0xdd,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xd6, 0x93, 0x46,
+	0x63, 0x4b, 0xb6, 0x15, 0x73, 0x5f, 0xe8, 0x44, 0x1f, 0x89, 0x7c, 0xfe,
+	0x83, 0x79, 0xcb, 0x73, 0x83, 0x58, 0xce, 0x9c, 0x87, 0xad, 0x17, 0xe5,
+	0xfa, 0xdd, 0x04, 0x86, 0x55, 0x71, 0xf7, 0xb8, 0x6b, 0xcd, 0x5d, 0xfc,
+	0x9c, 0x49, 0xe6, 0x3f, 0x3e, 0x87, 0x3b, 0x37, 0x65, 0x32, 0x11, 0x5c,
+	0x6e, 0x65, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x3f, 0x74, 0xbc, 0x23, 0x5e, 0x87, 0xc7, 0x6f, 0xe1, 0x4d, 0x31,
+	0x75, 0x2a, 0x1e, 0xa9, 0x8e, 0xa2, 0x11, 0x3d, 0xfb, 0x62, 0xb8, 0x22,
+	0xdb, 0x4d, 0xb6, 0x29, 0x78, 0x4b, 0xc7, 0xa8, 0xba, 0x9b, 0xd8, 0x39,
+	0x03, 0xb6, 0x66, 0x26, 0xd2, 0xce, 0x26, 0x5d, 0x68, 0x1d, 0xca, 0x51,
+	0x14, 0x75, 0x66, 0xbd, 0xc2, 0xd0, 0xbc, 0xdb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x99, 0x33, 0x2c, 0x81, 0xaa, 0xcd, 0x8e, 0x4a,
+	0x04, 0xdf, 0xf4, 0x24, 0x98, 0x6b, 0x6e, 0x0f, 0xb1, 0xc0, 0x97, 0x61,
+	0x12, 0xbb, 0xa6, 0xd2, 0x67, 0x28, 0x33, 0xbb, 0xe7, 0x56, 0x5f, 0xc1,
+	0xa1, 0x23, 0xad, 0x1f, 0x3c, 0x75, 0x9c, 0x20, 0x92, 0x72, 0xe4, 0xfb,
+	0x60, 0x6c, 0xac, 0x5c, 0x25, 0x89, 0xe9, 0x2c, 0xb0, 0x29, 0x52, 0x1d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x78, 0xf8, 0x9f,
+	0x6b, 0x68, 0x93, 0x3b, 0xd8, 0x27, 0xa4, 0xb3, 0x34, 0x37, 0x63, 0x7b,
+	0x60, 0x22, 0x8b, 0xab, 0x06, 0x92, 0xed, 0x9e, 0x4d, 0xc7, 0x5b, 0xf1,
+	0x23, 0x65, 0x05, 0xc4, 0x6d, 0x7d, 0x04, 0x67, 0xc0, 0x27, 0x29, 0x05,
+	0x23, 0x7f, 0xf8, 0x30, 0xfe, 0x6e, 0xf3, 0x0b, 0x3a, 0x85, 0x47, 0x45,
+	0xa5, 0x1c, 0x9a, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x30, 0x7d, 0x8f, 0x0d, 0xcb, 0xce, 0x3a, 0x48, 0xd3, 0x2f, 0x09, 0xf8,
+	0xdd, 0x49, 0x49, 0x3d, 0x9f, 0x65, 0xb4, 0x4d, 0xcd, 0xa6, 0x93, 0xb2,
+	0x72, 0xe2, 0x98, 0x6e, 0xa7, 0xae, 0x0a, 0x9d, 0xcb, 0xb0, 0xc9, 0x75,
+	0x3b, 0x41, 0x79, 0x71, 0x63, 0xce, 0x55, 0x70, 0xde, 0x2a, 0x0f, 0x07,
+	0x30, 0xe5, 0x7e, 0xb9, 0xf3, 0xdf, 0x50, 0x39, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xce, 0x5b, 0xd0, 0x27, 0x82, 0x18, 0x8e, 0x41,
+	0x4b, 0x43, 0x8a, 0x62, 0x3e, 0x21, 0xce, 0x31, 0x28, 0xe2, 0xc5, 0x53,
+	0xbd, 0x97, 0xec, 0xa0, 0xc8, 0x85, 0xa4, 0x7a, 0x1e, 0xdb, 0x22, 0xc1,
+	0xbc, 0xc8, 0xa3, 0x74, 0xda, 0xd2, 0xd7, 0xa8, 0x96, 0x9e, 0x51, 0xfd,
+	0xa5, 0x74, 0x8f, 0xab, 0x55, 0x4b, 0x95, 0xb6, 0xfc, 0x3d, 0x16, 0x7d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x70, 0x9e, 0xad,
+	0xfb, 0x64, 0xff, 0xc6, 0xe7, 0x78, 0x37, 0x89, 0x04, 0x9f, 0x01, 0x16,
+	0xa1, 0x68, 0x38, 0xf0, 0xf3, 0x01, 0x25, 0xfd, 0xfa, 0xa1, 0xd3, 0x7e,
+	0x6f, 0xb6, 0x33, 0xa7, 0x44, 0x62, 0x83, 0x19, 0xec, 0x5b, 0xfe, 0x17,
+	0xa1, 0x7d, 0xe4, 0xa2, 0x7d, 0x47, 0xa5, 0x1d, 0x1f, 0x31, 0x55, 0x2d,
+	0xe2, 0x3c, 0x9a, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5f, 0xfd, 0xfd, 0x31, 0xc2, 0x6d, 0x22, 0x75, 0x97, 0x37, 0x39, 0x32,
+	0x1a, 0x88, 0x65, 0x16, 0xe9, 0xb8, 0x94, 0x35, 0xd7, 0x1e, 0x32, 0x32,
+	0x29, 0xf8, 0xfd, 0xef, 0x97, 0x26, 0xe9, 0x87, 0x32, 0xf4, 0xc9, 0x2b,
+	0x94, 0x2c, 0x85, 0x28, 0x8e, 0xb5, 0x4c, 0xf8, 0xae, 0xbf, 0xdf, 0x1a,
+	0xe3, 0xff, 0xbf, 0x0d, 0x3a, 0x8f, 0x86, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xb2, 0x45, 0xf4, 0xc9, 0xee, 0x82, 0x26, 0x2e,
+	0xe6, 0xd0, 0x97, 0x07, 0xfb, 0x72, 0xd1, 0x73, 0x98, 0x46, 0x05, 0x88,
+	0x1c, 0xba, 0xa2, 0x06, 0xd0, 0xe5, 0x49, 0xde, 0x1c, 0x6b, 0xa3, 0xe5,
+	0x5b, 0xea, 0x44, 0x4b, 0xe1, 0x5f, 0xa2, 0x77, 0x46, 0xed, 0xe6, 0x8c,
+	0x33, 0x20, 0x8e, 0x54, 0x74, 0x2f, 0x80, 0x95, 0x11, 0x50, 0x6b, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x6f, 0x6f, 0xa4,
+	0xe3, 0x4b, 0x95, 0xa3, 0x98, 0x3f, 0x0a, 0xfa, 0xf3, 0x9d, 0x9b, 0x7d,
+	0x78, 0xf9, 0x3e, 0x56, 0xd2, 0xd9, 0xb4, 0x2e, 0xd8, 0x39, 0xfb, 0x35,
+	0xe3, 0x25, 0xc5, 0xba, 0xfc, 0x18, 0xab, 0x08, 0x2d, 0x38, 0xe9, 0x4e,
+	0x68, 0xd6, 0x98, 0xad, 0x58, 0xfa, 0xd1, 0xe0, 0x55, 0x8f, 0x21, 0x1a,
+	0x11, 0x7e, 0x13, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x33, 0x19, 0x04, 0x18, 0xcf, 0x4b, 0x06, 0xf1, 0x32, 0x0f, 0xb9, 0xcb,
+	0x13, 0x81, 0x9b, 0xaf, 0x4e, 0x55, 0xaa, 0x8b, 0xea, 0x88, 0x95, 0x66,
+	0x9b, 0xf7, 0xd3, 0x58, 0xb5, 0x4b, 0x2c, 0xee, 0x18, 0xca, 0x8a, 0x94,
+	0xc9, 0x82, 0x98, 0x5d, 0x3d, 0xbc, 0xb7, 0x3c, 0x73, 0xab, 0x6c, 0x76,
+	0x7c, 0x25, 0x62, 0xfc, 0x8a, 0xef, 0xd7, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x59, 0x2d, 0xbb, 0xa7, 0xf0, 0x49, 0x6f, 0xc2,
+	0x69, 0xb1, 0xc3, 0x94, 0xf3, 0x8e, 0xf4, 0xac, 0xe3, 0x2c, 0xd9, 0x94,
+	0xfd, 0x15, 0x46, 0x54, 0x49, 0x19, 0xbc, 0x27, 0xb4, 0x8b, 0x85, 0xf5,
+	0x54, 0x81, 0x10, 0x03, 0x99, 0x13, 0x58, 0x6d, 0x0a, 0x2f, 0x6d, 0xbc,
+	0x76, 0x34, 0xd1, 0x12, 0xfe, 0xa6, 0x75, 0xf0, 0x54, 0x39, 0xb4, 0x33,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x52, 0x64, 0x73,
+	0x17, 0xb4, 0xc4, 0xcc, 0x4b, 0x72, 0xf2, 0x4d, 0xf6, 0x31, 0xb3, 0xf8,
+	0x25, 0x64, 0xdb, 0x94, 0xa7, 0x83, 0x86, 0x66, 0xad, 0xc1, 0x9f, 0x9e,
+	0xa7, 0xc9, 0x87, 0x84, 0x9c, 0x80, 0x82, 0x94, 0x36, 0xcd, 0x2a, 0xba,
+	0x04, 0x9f, 0x25, 0x9c, 0x56, 0x1a, 0x3e, 0x09, 0x07, 0xf4, 0x27, 0xae,
+	0xf2, 0x21, 0x0a, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd5, 0xe9, 0x2b, 0xb0, 0x25, 0x50, 0x73, 0x45, 0x24, 0xb4, 0xfe, 0x97,
+	0x6c, 0xaf, 0xb8, 0x72, 0xbf, 0xe2, 0xcf, 0x5d, 0xe8, 0x66, 0x84, 0x74,
+	0xd6, 0xff, 0x14, 0xc9, 0x07, 0x63, 0x58, 0x2e, 0xd2, 0x81, 0x83, 0xc9,
+	0x05, 0x9d, 0x5c, 0x9e, 0x62, 0xd2, 0x90, 0x3a, 0x6c, 0x16, 0x66, 0x7c,
+	0x2d, 0xe1, 0x2b, 0x55, 0x51, 0x2b, 0x25, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xea, 0x86, 0x65, 0xcb, 0x55, 0x08, 0x23, 0x8b,
+	0x3e, 0xd3, 0xa7, 0x88, 0x0f, 0xb1, 0xd3, 0x7f, 0xe7, 0xb8, 0x61, 0xfa,
+	0x58, 0x96, 0x51, 0x4c, 0xea, 0x4d, 0x95, 0xcd, 0x1a, 0x3e, 0x3c, 0x95,
+	0xd3, 0x07, 0xc9, 0x00, 0x66, 0x68, 0x8d, 0x25, 0x9e, 0x1c, 0x82, 0xae,
+	0x5e, 0x48, 0xea, 0xf3, 0x01, 0x27, 0x7b, 0xf2, 0xb2, 0x9b, 0x16, 0xef,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1c, 0x38, 0xc3,
+	0x1f, 0x7b, 0x41, 0x2d, 0x5d, 0xdf, 0xd9, 0xea, 0xbf, 0xad, 0x45, 0xa2,
+	0x25, 0x0b, 0xb6, 0xa3, 0xef, 0xa5, 0xdc, 0xc5, 0xe0, 0xb8, 0x4a, 0xb3,
+	0xfa, 0xb5, 0x36, 0x35, 0x77, 0xdc, 0xf4, 0xa6, 0x88, 0x53, 0xe1, 0xa3,
+	0x1e, 0xf6, 0xa6, 0x8e, 0x7a, 0xc5, 0x0b, 0xc2, 0x16, 0x3e, 0xe2, 0x27,
+	0x0f, 0x9b, 0xc4, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x81, 0x54, 0x75, 0x7f, 0xdb, 0x06, 0xbd, 0xa2, 0x4a, 0x5b, 0xa0, 0x85,
+	0xf8, 0xc5, 0x12, 0x5b, 0xbb, 0x4b, 0xa1, 0x58, 0xa5, 0xd6, 0x1d, 0x98,
+	0x04, 0x21, 0x7a, 0x30, 0x31, 0x00, 0x2c, 0x99, 0x90, 0xcf, 0x80, 0xfe,
+	0xd1, 0x6b, 0x27, 0x93, 0xef, 0x89, 0x06, 0x1b, 0x95, 0x21, 0x8b, 0xbe,
+	0x0b, 0x8d, 0x1b, 0xa0, 0x23, 0x87, 0xf0, 0xe1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x76, 0x74, 0xb2, 0xb2, 0x25, 0x00, 0x07, 0xf9,
+	0x01, 0x30, 0x2b, 0xb8, 0xf2, 0x4e, 0xb2, 0x26, 0x04, 0x11, 0x3c, 0x79,
+	0xeb, 0x4a, 0xdf, 0x53, 0x55, 0xe6, 0x6e, 0x59, 0x60, 0xcd, 0xf2, 0xa4,
+	0xd7, 0xc3, 0x0d, 0x70, 0x9d, 0x6c, 0x64, 0x2a, 0xdd, 0x9d, 0x4d, 0x83,
+	0x95, 0x94, 0xd2, 0x38, 0xd1, 0xcd, 0x6e, 0xdb, 0x33, 0x32, 0x62, 0xd4,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x62, 0x25, 0x5e,
+	0xe0, 0x13, 0x80, 0x39, 0x31, 0x0e, 0x59, 0x15, 0x9c, 0xe8, 0x75, 0xbc,
+	0x60, 0x90, 0x34, 0x3a, 0x5f, 0x7d, 0x7c, 0x0b, 0x6c, 0x3d, 0x02, 0xfd,
+	0xfa, 0xb1, 0xf7, 0xce, 0x1b, 0xec, 0x37, 0x06, 0xaf, 0xc1, 0x9f, 0x93,
+	0x6f, 0x2d, 0x40, 0x9f, 0x22, 0x52, 0xb6, 0x73, 0x8f, 0x91, 0xe1, 0x85,
+	0xfe, 0x57, 0xa6, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x42, 0xde, 0xbe, 0xf5, 0xb7, 0xca, 0x60, 0x2e, 0x10, 0x88, 0xb7, 0xfc,
+	0xbe, 0x7f, 0x06, 0x8a, 0x7d, 0xcd, 0xb1, 0xde, 0x34, 0x43, 0x19, 0x70,
+	0xab, 0xa7, 0x62, 0x0e, 0x37, 0xee, 0x28, 0x2b, 0xd7, 0x5e, 0x4c, 0x5b,
+	0x30, 0x99, 0xc3, 0x3c, 0x47, 0xfb, 0x4d, 0x92, 0xb2, 0x6c, 0xa4, 0xd9,
+	0x9d, 0xe5, 0x74, 0xe2, 0xb2, 0xec, 0x6c, 0xc9, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x60, 0x24, 0xe8, 0xa8, 0xae, 0x35, 0x55, 0x83,
+	0x99, 0xe9, 0x6e, 0xdd, 0xdb, 0x48, 0x26, 0xee, 0x7a, 0x82, 0xdc, 0xa9,
+	0xb5, 0xda, 0xf3, 0xda, 0x21, 0x36, 0x87, 0xc0, 0xc9, 0xa0, 0x0c, 0xb1,
+	0xad, 0xc8, 0x5f, 0x1e, 0x68, 0x40, 0xd9, 0x2c, 0xdb, 0x15, 0x29, 0xfd,
+	0x8f, 0x80, 0xde, 0x8b, 0xad, 0xfa, 0xd4, 0x59, 0x20, 0x94, 0x40, 0x5f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x44, 0x63, 0x52,
+	0x42, 0xef, 0x04, 0x95, 0x0b, 0xbc, 0x2e, 0xc5, 0x6d, 0x67, 0x5a, 0x26,
+	0x24, 0x8e, 0x97, 0x4c, 0x1c, 0x52, 0x85, 0xe2, 0x65, 0x2e, 0xdf, 0xc0,
+	0xe1, 0x38, 0xb2, 0x2d, 0x90, 0xd7, 0x28, 0x31, 0x88, 0xbd, 0xbd, 0x45,
+	0x1e, 0x07, 0x53, 0x0c, 0x31, 0xe3, 0x60, 0x60, 0x96, 0xdd, 0x3f, 0x14,
+	0x3d, 0xb0, 0x03, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x7b, 0x41, 0x1e, 0xcf, 0xd4, 0xa0, 0xf3, 0x55, 0xa5, 0x02, 0x3e,
+	0x43, 0xf3, 0xfe, 0x6c, 0xf5, 0x39, 0x77, 0xfe, 0x5a, 0x9d, 0xa3, 0x43,
+	0xab, 0xa4, 0x11, 0xb7, 0x3c, 0xba, 0x8e, 0xf2, 0x96, 0x22, 0x30, 0x7e,
+	0x3a, 0x89, 0xf4, 0x37, 0xc8, 0x16, 0x4a, 0xcd, 0x29, 0x3f, 0xd0, 0x6c,
+	0x96, 0x68, 0x9d, 0xac, 0x7e, 0x04, 0xee, 0xb3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x50, 0x29, 0x41, 0xcb, 0x86, 0xe0, 0xe6, 0x50,
+	0x09, 0x74, 0xf3, 0xf4, 0x79, 0x40, 0x23, 0xd8, 0xd0, 0xd8, 0xe1, 0xc2,
+	0xe4, 0xe7, 0x87, 0xbf, 0x87, 0x98, 0xff, 0x1e, 0xa1, 0x18, 0xa9, 0x11,
+	0xdd, 0x0d, 0x89, 0xdb, 0x97, 0xb2, 0xd4, 0x93, 0x13, 0x32, 0xd9, 0x48,
+	0x46, 0x4e, 0xe4, 0x7f, 0x1c, 0x3b, 0x6f, 0x60, 0xd0, 0x75, 0x88, 0x6f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xdd, 0xf3, 0xdb,
+	0xc6, 0xc8, 0xca, 0x07, 0x40, 0xe9, 0x72, 0xa3, 0x87, 0xac, 0x4e, 0x08,
+	0xa0, 0x1d, 0xd8, 0xdc, 0x23, 0xf4, 0xe1, 0xcb, 0xca, 0x2a, 0xcd, 0xbb,
+	0x23, 0xf2, 0x52, 0x92, 0x5c, 0x29, 0x62, 0x39, 0x51, 0x66, 0x09, 0x3f,
+	0x96, 0x5c, 0x2e, 0xc7, 0x50, 0xa6, 0x56, 0x07, 0x66, 0x3f, 0x2b, 0x27,
+	0x02, 0x5d, 0x43, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x16, 0x87, 0x89, 0x08, 0x15, 0xbf, 0xb4, 0xbb, 0x04, 0xb9, 0xdf, 0x77,
+	0x4e, 0x6f, 0xde, 0x97, 0x61, 0x3c, 0x6a, 0xa5, 0xef, 0x5b, 0x4e, 0x15,
+	0x26, 0xe9, 0xbc, 0x92, 0xd9, 0xd3, 0xe3, 0xbd, 0x41, 0x3f, 0xb0, 0xe3,
+	0xc6, 0xfc, 0x75, 0xef, 0xb8, 0xb1, 0x31, 0x88, 0x1e, 0x95, 0x6a, 0xa1,
+	0x54, 0x0d, 0x4f, 0xfd, 0xb3, 0xa8, 0xe8, 0x9e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc5, 0xa6, 0xa2, 0xaa, 0x79, 0x6b,
+	0xdc, 0xc8, 0x5b, 0xe6, 0xda, 0xff, 0x69, 0x22, 0x19, 0x5f, 0x5e, 0x32,
+	0x31, 0xc4, 0x83, 0x30, 0xf6, 0xa6, 0xe3, 0x3d, 0xd4, 0xc8, 0xda, 0x4c,
+	0x33, 0xef, 0x38, 0x64, 0x4a, 0x92, 0x8e, 0x83, 0x04, 0xbc, 0x79, 0x12,
+	0x5d, 0x32, 0x59, 0x71, 0xa9, 0xc8, 0x7e, 0x55, 0xc7, 0x5f, 0x98, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x56, 0x48, 0xfa,
+	0x0b, 0x31, 0x1e, 0xdf, 0xfb, 0x40, 0x81, 0xce, 0x2a, 0xf1, 0xf0, 0x85,
+	0x74, 0x0b, 0xd8, 0x5a, 0x63, 0xf0, 0xad, 0x4b, 0xc2, 0x30, 0xf5, 0x1f,
+	0xdb, 0xad, 0x34, 0xb0, 0xe5, 0xac, 0x0f, 0x59, 0xcd, 0x7f, 0x59, 0xcb,
+	0xac, 0xda, 0x7d, 0x3e, 0x2b, 0x77, 0x7c, 0x45, 0x88, 0x66, 0xe4, 0x87,
+	0x77, 0xba, 0x6e, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x38, 0x0e, 0xcd, 0x3e, 0x5c, 0x70, 0xdb, 0xb4, 0xf2, 0x59, 0x37, 0x36,
+	0xc6, 0xf6, 0x78, 0xa8, 0xfa, 0x67, 0xad, 0xad, 0x96, 0x50, 0xf4, 0xe1,
+	0x3c, 0x65, 0xd0, 0x01, 0x59, 0x08, 0x86, 0x96, 0x67, 0x9f, 0x1f, 0x27,
+	0xd4, 0xa5, 0x9d, 0xd7, 0xf2, 0x57, 0xc2, 0x81, 0x3b, 0x1d, 0xe7, 0xaa,
+	0x10, 0xfb, 0x10, 0xa0, 0xe1, 0x25, 0x5a, 0x55, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa9, 0xd1, 0x51, 0x65, 0x95, 0xdd, 0x6f, 0x89,
+	0xad, 0xcc, 0x2a, 0x76, 0xc3, 0x98, 0x26, 0x37, 0x51, 0x07, 0x98, 0x8f,
+	0x85, 0xad, 0x55, 0x38, 0x5e, 0x15, 0x4f, 0x1c, 0xe6, 0x0b, 0xe5, 0x28,
+	0x9c, 0xac, 0xc2, 0x5a, 0x73, 0x23, 0x14, 0x01, 0x71, 0x71, 0x04, 0x47,
+	0xb4, 0xd2, 0x8a, 0x77, 0x2e, 0x22, 0x42, 0xfa, 0xf0, 0x82, 0x86, 0x70,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x1a, 0x11, 0x5a,
+	0x4a, 0xea, 0xae, 0x0a, 0x88, 0x53, 0x09, 0x1a, 0x75, 0xc4, 0x40, 0x1d,
+	0x74, 0x03, 0x44, 0xc8, 0xe3, 0xca, 0x1b, 0xab, 0xee, 0x22, 0xb3, 0xc1,
+	0xef, 0xe6, 0xb8, 0x16, 0x29, 0x07, 0xd8, 0x0b, 0x7e, 0x67, 0xcb, 0xea,
+	0xbd, 0x27, 0x8e, 0x0f, 0x28, 0xac, 0xe6, 0x6d, 0x47, 0x5d, 0x6f, 0x17,
+	0xa2, 0xf8, 0x5d, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x48, 0xea, 0x89, 0x16, 0x74, 0x70, 0x2c, 0x27, 0x93, 0x3a, 0xe7, 0x20,
+	0x03, 0xd8, 0x35, 0x5c, 0xae, 0xaa, 0x2e, 0xc8, 0x45, 0xf3, 0x13, 0xcf,
+	0x65, 0x8d, 0x10, 0x93, 0x53, 0xac, 0x9b, 0x68, 0xf9, 0x03, 0x46, 0x41,
+	0xf4, 0xc5, 0x9e, 0x04, 0x94, 0x79, 0x6e, 0x6f, 0x8c, 0xf5, 0x09, 0x0d,
+	0xfe, 0x92, 0x82, 0x98, 0x01, 0x68, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0x7c, 0x5d, 0xa1, 0x01, 0x26, 0xe6, 0x0a,
+	0x7d, 0x9c, 0xb0, 0xbf, 0x8b, 0xd0, 0x64, 0x3c, 0x38, 0x19, 0x81, 0x43,
+	0x4a, 0x57, 0xfd, 0x7a, 0x93, 0xc7, 0xc8, 0x0a, 0x2e, 0x56, 0x49, 0x07,
+	0x6e, 0x7d, 0x64, 0xed, 0x2b, 0x86, 0x53, 0x9f, 0x95, 0x74, 0xa7, 0x69,
+	0x3d, 0x96, 0x41, 0xb8, 0xca, 0x02, 0xfd, 0xf0, 0xa4, 0xc7, 0x18, 0x49,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x54, 0xe4, 0x81,
+	0xa7, 0xb6, 0x5e, 0x08, 0xe6, 0x8b, 0xc5, 0xb0, 0xad, 0x5a, 0xe3, 0x09,
+	0x31, 0xe5, 0x2b, 0x5d, 0xa1, 0x4f, 0xac, 0x93, 0x49, 0x22, 0xac, 0xfc,
+	0x61, 0x47, 0x51, 0xde, 0xae, 0x8a, 0xd9, 0x9f, 0xcb, 0x9f, 0xcf, 0x78,
+	0xa5, 0x13, 0xf5, 0xcf, 0xd3, 0xc1, 0x49, 0x5a, 0x7b, 0x8e, 0xf0, 0x5e,
+	0xad, 0x9d, 0x6e, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x94, 0x0a, 0x05, 0x03, 0x02, 0x48, 0xa0, 0x7a, 0xd0, 0x3e, 0x53, 0x73,
+	0x6a, 0x9c, 0xee, 0x03, 0x98, 0xe2, 0x60, 0x2a, 0x65, 0x78, 0xbd, 0x89,
+	0x8b, 0x00, 0x67, 0x61, 0x20, 0x81, 0x49, 0xbc, 0xc9, 0x3b, 0x4f, 0x19,
+	0x91, 0x54, 0xba, 0x9d, 0x7c, 0xe1, 0x80, 0xed, 0x74, 0x4f, 0x88, 0x04,
+	0xf5, 0x9b, 0x56, 0xd3, 0x3c, 0x9c, 0xfb, 0xc0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xac, 0x49, 0xa7, 0x7e, 0x71, 0xf8, 0xba, 0x16,
+	0xaa, 0xda, 0x08, 0x92, 0x96, 0xbc, 0xa5, 0x33, 0x3e, 0xbc, 0xff, 0x50,
+	0xe0, 0xba, 0x41, 0x43, 0xeb, 0x2c, 0x10, 0x58, 0x9f, 0x85, 0xa7, 0xd9,
+	0xb1, 0x2d, 0x3a, 0xb4, 0x62, 0x08, 0x91, 0x73, 0xaa, 0x42, 0x1e, 0x96,
+	0x63, 0xf3, 0x1b, 0xaf, 0xcf, 0x76, 0x7b, 0x41, 0x8b, 0x69, 0x26, 0x05,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xa3, 0x1f, 0xb3,
+	0x67, 0xef, 0x7b, 0xfb, 0x4b, 0xfc, 0x59, 0x9e, 0xe7, 0xab, 0xb6, 0x35,
+	0xa2, 0xf1, 0xdf, 0xd6, 0x1d, 0x9e, 0xbb, 0xfd, 0x91, 0x6a, 0x7f, 0x0c,
+	0xc6, 0x2c, 0x07, 0x69, 0x64, 0xd0, 0xda, 0xb3, 0xc6, 0xbf, 0x62, 0x1e,
+	0x4d, 0x48, 0xd5, 0xb4, 0xa4, 0x43, 0xff, 0x91, 0x87, 0xc6, 0x54, 0x10,
+	0xf9, 0xd6, 0xb3, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4f, 0x95, 0x17, 0xe1, 0xf7, 0x38, 0x63, 0x16, 0x3b, 0x02, 0x2f, 0x5a,
+	0x45, 0x64, 0xf1, 0x93, 0xa1, 0xf1, 0xe4, 0x29, 0x62, 0x7c, 0x0c, 0x50,
+	0x3b, 0x49, 0x55, 0x86, 0x9d, 0xc3, 0xe7, 0xf8, 0xc4, 0x65, 0x30, 0x58,
+	0xee, 0x3e, 0x1f, 0x9b, 0x6f, 0x2a, 0xea, 0x23, 0x27, 0x9a, 0x0e, 0xe7,
+	0x6b, 0x96, 0x4b, 0xcb, 0x21, 0xae, 0x1b, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa6, 0x88, 0x80, 0x5b, 0xfb, 0x9f, 0xee, 0x70,
+	0x2b, 0xd4, 0xb4, 0x7d, 0x2c, 0x05, 0x9a, 0xea, 0x0b, 0xa5, 0xeb, 0xc0,
+	0x9f, 0x6c, 0x66, 0x8c, 0xc5, 0x6a, 0x36, 0x87, 0x04, 0xd2, 0x1a, 0x83,
+	0xa5, 0xcf, 0x38, 0xd9, 0x74, 0x52, 0xd3, 0x9c, 0xeb, 0xa4, 0xf9, 0x26,
+	0xf3, 0xc0, 0xdc, 0x94, 0xc0, 0x7f, 0x54, 0x87, 0x62, 0x77, 0x2d, 0x4c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x16, 0x58, 0x49,
+	0xb1, 0x96, 0x15, 0x03, 0x33, 0x7e, 0x44, 0xc4, 0xd6, 0xa6, 0xcb, 0x61,
+	0x57, 0x2b, 0x93, 0x72, 0x8b, 0xad, 0x37, 0xbf, 0x80, 0x3d, 0x79, 0x52,
+	0x0c, 0x18, 0x30, 0x38, 0xc9, 0x69, 0xec, 0x11, 0x45, 0x14, 0x9e, 0xe5,
+	0x47, 0x4d, 0xbb, 0x1b, 0x2c, 0x91, 0x6d, 0x6e, 0x09, 0xf7, 0xbc, 0xc9,
+	0x25, 0x12, 0x98, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc1, 0x16, 0xd7, 0xe8, 0x42, 0x8e, 0xa5, 0x9a, 0xc4, 0x93, 0xc7, 0x86,
+	0x84, 0x45, 0x8e, 0x0f, 0x05, 0x20, 0xfa, 0x16, 0xad, 0xcc, 0x8a, 0x10,
+	0x99, 0x1b, 0x69, 0x56, 0x19, 0xb2, 0x99, 0xc3, 0x2f, 0x4a, 0xf8, 0x11,
+	0x87, 0x99, 0x26, 0x14, 0x81, 0x71, 0xc6, 0x77, 0x84, 0x6b, 0x8d, 0xe2,
+	0xc8, 0xf1, 0x9a, 0x5a, 0x66, 0x67, 0x7d, 0x52, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xbd, 0xd3, 0x7a, 0x37, 0x12, 0x9e, 0xc2, 0x18,
+	0x96, 0x1d, 0x51, 0x31, 0xd9, 0x28, 0xcd, 0x7d, 0xc3, 0x07, 0x9d, 0x98,
+	0xcf, 0x06, 0x82, 0x77, 0xa7, 0xbf, 0xb0, 0xae, 0x7d, 0x8a, 0xc3, 0x0d,
+	0x65, 0xe9, 0x66, 0x91, 0xb6, 0xff, 0x97, 0xb8, 0x67, 0xad, 0x51, 0xd0,
+	0xae, 0x5b, 0x70, 0x7a, 0x25, 0x6e, 0x41, 0x58, 0x62, 0xc3, 0xc8, 0xcb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xb1, 0x7f,
+	0xfd, 0x70, 0x84, 0xba, 0x1e, 0xcf, 0x48, 0x23, 0xcd, 0x84, 0xdf, 0x17,
+	0x06, 0x1e, 0x97, 0x93, 0xad, 0x67, 0x18, 0x97, 0xee, 0xc8, 0xd8, 0x6a,
+	0x20, 0x89, 0x5a, 0x9e, 0x54, 0x9c, 0xd7, 0x22, 0x4b, 0xde, 0x69, 0xfd,
+	0x6b, 0x28, 0xbb, 0x68, 0xfa, 0x05, 0x42, 0xe7, 0x79, 0x65, 0xe5, 0x6d,
+	0x16, 0x71, 0x76, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6c, 0x12, 0x82, 0xb8, 0x7e, 0x03, 0x01, 0x68, 0x5a, 0x51, 0x60, 0xf1,
+	0xe3, 0xd0, 0x45, 0x67, 0x2f, 0x47, 0x4d, 0xb4, 0x97, 0x5c, 0xbd, 0x13,
+	0x50, 0x89, 0xfe, 0x19, 0x4e, 0x4f, 0xad, 0x05, 0x17, 0x3a, 0x84, 0x33,
+	0xaa, 0x15, 0x75, 0xdb, 0x59, 0x34, 0x4c, 0x01, 0xa2, 0x54, 0xc3, 0x21,
+	0x4e, 0xbd, 0x2b, 0xf3, 0x23, 0x19, 0xef, 0xa0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfa, 0x3e, 0x81, 0xb5, 0xd9, 0xe3, 0x5e, 0x50,
+	0xa9, 0x76, 0xc7, 0x31, 0x06, 0x82, 0xf1, 0xc8, 0xc6, 0x6c, 0x9f, 0xa6,
+	0xad, 0x6b, 0x6d, 0x1b, 0x1d, 0x2f, 0xa1, 0x01, 0xd7, 0x72, 0x99, 0x08,
+	0xc1, 0x2f, 0x29, 0xe4, 0x63, 0xc0, 0x32, 0x66, 0x7f, 0x32, 0x55, 0xbd,
+	0x93, 0x0f, 0x10, 0xef, 0x83, 0x29, 0x35, 0x55, 0xba, 0xe0, 0x8c, 0x3f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x71, 0x81, 0x3f,
+	0x62, 0x01, 0xb6, 0x6d, 0xe0, 0x21, 0xac, 0x3a, 0x82, 0x88, 0x77, 0x61,
+	0x3c, 0xea, 0xa0, 0x07, 0x7d, 0x10, 0xd7, 0xaf, 0x17, 0xef, 0x0a, 0x4e,
+	0x44, 0xb4, 0x8b, 0x65, 0x3b, 0x58, 0xc6, 0xb0, 0xec, 0x88, 0x69, 0xb5,
+	0x7a, 0x03, 0xf1, 0xdc, 0x36, 0x05, 0x20, 0xfc, 0xcd, 0xe5, 0x6c, 0x3a,
+	0x19, 0xb3, 0x62, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5c, 0x7c, 0x07, 0xc6, 0xb7, 0x1f, 0x25, 0xdf, 0x7d, 0x8d, 0x81, 0x61,
+	0xeb, 0x3e, 0xbf, 0xe7, 0x10, 0x81, 0xf1, 0x85, 0x40, 0xcb, 0x60, 0xf1,
+	0xae, 0x1a, 0xba, 0xc5, 0xda, 0x60, 0x1c, 0x0f, 0x6d, 0x47, 0xfd, 0xa2,
+	0x56, 0x13, 0x67, 0x02, 0x7c, 0xd9, 0xc5, 0x56, 0x32, 0x69, 0x12, 0xc7,
+	0x8f, 0x2f, 0x31, 0x2c, 0x0f, 0xd2, 0x94, 0x69, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0x20, 0x93, 0x21, 0xb2, 0x35, 0xf1,
+	0x80, 0x14, 0x8e, 0xf1, 0x0c, 0x28, 0x62, 0x8d, 0xb8, 0xcf, 0x6c, 0x9e,
+	0xf6, 0xdb, 0x18, 0x16, 0x0b, 0xbd, 0xe9, 0xb4, 0xa3, 0x75, 0xee, 0xb2,
+	0x55, 0x1e, 0x4c, 0xc7, 0xa7, 0x74, 0xe8, 0x0e, 0x8f, 0xb7, 0xa8, 0x04,
+	0xf3, 0xeb, 0x1c, 0x35, 0xd6, 0x1d, 0x1b, 0x2a, 0x51, 0x10, 0xa2, 0x67,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x1c, 0x40, 0x29,
+	0xfa, 0x43, 0x18, 0x0c, 0x4c, 0xc0, 0xcd, 0x55, 0x99, 0xd0, 0xb9, 0xb4,
+	0x55, 0x69, 0x7d, 0xad, 0x99, 0xb8, 0xec, 0x62, 0x0c, 0x3b, 0x71, 0x11,
+	0xf0, 0xba, 0x59, 0x19, 0x93, 0xef, 0xcd, 0x2c, 0x29, 0x02, 0x8b, 0x76,
+	0x85, 0x21, 0xc1, 0xad, 0x72, 0x67, 0x87, 0xd1, 0x8f, 0xc6, 0x05, 0xe7,
+	0x82, 0x4e, 0x95, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
 const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p192,
@@ -1267,7 +1835,15 @@ const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p256_sm2,
 		.len = sizeof(ae_fpm_tbl_p256_sm2)
-	}
+	},
+	{
+		.data = ae_fpm_tbl_ed25519,
+		.len = sizeof(ae_fpm_tbl_ed25519)
+	},
+	{
+		.data = ae_fpm_tbl_ed448,
+		.len = sizeof(ae_fpm_tbl_ed448)
+	},
 };
 
 int
diff --git a/drivers/crypto/cnxk/cnxk_ae.h b/drivers/crypto/cnxk/cnxk_ae.h
index ef9cb5eb91..efb3ace7c0 100644
--- a/drivers/crypto/cnxk/cnxk_ae.h
+++ b/drivers/crypto/cnxk/cnxk_ae.h
@@ -15,6 +15,8 @@
 
 #define ASYM_SESS_SIZE sizeof(struct rte_cryptodev_asym_session)
 
+#define CNXK_AE_EDDSA_MAX_PARAM_LEN 1024
+
 struct cnxk_ae_sess {
 	uint8_t rte_sess[ASYM_SESS_SIZE];
 	enum rte_crypto_asym_xform_type xfrm_type;
@@ -25,10 +27,12 @@ struct cnxk_ae_sess {
 	};
 	uint64_t *cnxk_fpm_iova;
 	struct roc_ae_ec_group **ec_grp;
+	uint64_t cpt_inst_w4;
 	uint64_t cpt_inst_w7;
 	uint64_t cpt_inst_w2;
 	struct cnxk_cpt_qp *qp;
 	struct roc_cpt_lf *lf;
+	uint64_t msg_max_sz;
 	struct hw_ctx_s {
 		union {
 			struct {
@@ -181,10 +185,10 @@ cnxk_ae_fill_rsa_params(struct cnxk_ae_sess *sess,
 }
 
 static __rte_always_inline int
-cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
-		       struct rte_crypto_asym_xform *xform)
+cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess, struct rte_crypto_asym_xform *xform)
 {
 	struct roc_ae_ec_ctx *ec = &sess->ec_ctx;
+	union cpt_inst_w4 w4;
 
 	switch (xform->ec.curve_id) {
 	case RTE_CRYPTO_EC_GROUP_SECP192R1:
@@ -205,6 +209,14 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_EC_GROUP_SM2:
 		ec->curveid = ROC_AE_EC_ID_SM2;
 		break;
+	case RTE_CRYPTO_EC_GROUP_ED25519:
+		ec->curveid = ROC_AE_EC_ID_ED25519;
+		w4.s.param1 = ROC_AE_ED_PARAM1_25519;
+		break;
+	case RTE_CRYPTO_EC_GROUP_ED448:
+		ec->curveid = ROC_AE_EC_ID_ED448;
+		w4.s.param1 = ROC_AE_ED_PARAM1_448;
+		break;
 	default:
 		/* Only NIST curves (FIPS 186-4) and SM2 are supported */
 		return -EINVAL;
@@ -225,12 +237,22 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	if (ec->q.x.length)
 		rte_memcpy(ec->q.x.data, xform->ec.q.x.data, ec->q.x.length);
 
+	if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_EDDSA) {
+		w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+
+		/* Use q.x to store compressed public key. q.y is set to 0 */
+		ec->q.y.length = 0;
+		goto _exit;
+	}
+
 	ec->q.y.length = xform->ec.q.y.length;
 	if (ec->q.y.length > ROC_AE_EC_DATA_MAX)
 		ec->q.y.length = ROC_AE_EC_DATA_MAX;
 	if (xform->ec.q.y.length)
 		rte_memcpy(ec->q.y.data, xform->ec.q.y.data, ec->q.y.length);
 
+_exit:
+	sess->cpt_inst_w4 = w4.u64;
 	return 0;
 }
 
@@ -241,6 +263,7 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
 	int ret;
 
 	sess->xfrm_type = xform->xform_type;
+	sess->msg_max_sz = cnxk_cpt_asym_get_mlen();
 
 	switch (xform->xform_type) {
 	case RTE_CRYPTO_ASYM_XFORM_RSA:
@@ -255,6 +278,7 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
 	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
 		ret = cnxk_ae_fill_ec_params(sess, xform);
 		break;
 	default:
@@ -736,6 +760,310 @@ cnxk_ae_enqueue_ecdsa_op(struct rte_crypto_op *op,
 	return 0;
 }
 
+static __rte_always_inline void
+cnxk_ae_eddsa_sign_prep(struct rte_crypto_eddsa_op_param *eddsa, struct roc_ae_buf_ptr *meta_buf,
+			uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
+			struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t pkey_len = sess->ec_ctx.pkey.length;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint16_t ctx_align, k_align;
+	uint8_t pub = 0, ph = 0;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint8_t ctx_len = 0;
+	uint16_t iv_len = 0;
+	uint64_t ctrl = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+	    eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519)
+		iv_len = sizeof(iv_sha512);
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	if (pubkey_len)
+		pub = 1;
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pkey_len, 8);
+
+	/* Set control word */
+	ctrl = message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(priv and
+	 * pubkey len), ROUNDUP8(context len) and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) + sizeof(ctrl) + prime_len * 3 +
+		k_align * 2 + ctx_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.pkey.data, pkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.u64 = sess->cpt_inst_w4;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_SIGN;
+	w4.s.param1 |= ((pub << ROC_AE_ED_PARAM1_KEYGEN_BIT) | (ph << ROC_AE_EC_PARAM1_PH_BIT));
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline void
+cnxk_ae_eddsa_verify_prep(struct rte_crypto_eddsa_op_param *eddsa, struct roc_ae_buf_ptr *meta_buf,
+			  uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
+			  struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t s_len = eddsa->sign.length / 2;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	uint16_t ctx_align, k_align, s_align;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint16_t iv_len = 0;
+	uint8_t ctx_len = 0;
+	uint64_t ctrl = 0;
+	uint8_t ph = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+	    eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519)
+		iv_len = sizeof(iv_sha512);
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pubkey_len, 8);
+	s_align = RTE_ALIGN_CEIL(s_len, 8);
+
+	/* Set control word */
+	ctrl = message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(pub key len),
+	 * ROUNDUP8(s and r len), context and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) + sizeof(ctrl) + prime_len * 3 +
+		k_align + s_align * 2 +	ctx_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, eddsa->sign.data, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, eddsa->sign.data + s_len, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.u64 = sess->cpt_inst_w4;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_VERIFY;
+
+	w4.s.param1 |= (ph << ROC_AE_EC_PARAM1_PH_BIT);
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline int __rte_hot
+cnxk_ae_enqueue_eddsa_op(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
+			 struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
+			 struct roc_ae_ec_group **ec_grp, struct cpt_inst_s *inst)
+{
+	struct rte_crypto_eddsa_op_param *eddsa = &op->asym->eddsa;
+	uint8_t curveid = sess->ec_ctx.curveid;
+
+	if (eddsa->message.length > (sess->msg_max_sz - CNXK_AE_EDDSA_MAX_PARAM_LEN)) {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+		cnxk_ae_eddsa_sign_prep(eddsa, meta_buf, fpm_iova[curveid], ec_grp[curveid], sess,
+					  inst);
+	else if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		cnxk_ae_eddsa_verify_prep(eddsa, meta_buf, fpm_iova[curveid], ec_grp[curveid], sess,
+					  inst);
+	else {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static __rte_always_inline void
 cnxk_ae_sm2_sign_prep(struct rte_crypto_sm2_op_param *sm2,
 			struct roc_ae_buf_ptr *meta_buf,
@@ -1004,6 +1332,81 @@ cnxk_ae_ecfpm_prep(rte_crypto_param *scalar,
 	return 0;
 }
 
+static __rte_always_inline int
+cnxk_ae_edfpm_prep(rte_crypto_param *scalar, struct roc_ae_buf_ptr *meta_buf, uint64_t *fpm_iova,
+		   struct roc_ae_ec_group *ec_grp, uint8_t curveid, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	uint16_t dlen, prime_len, order_len, iv_len;
+	uint64_t fpm_table_iova;
+	uint16_t scalar_align;
+	union cpt_inst_w4 w4;
+	uint16_t prime_bit;
+	uint8_t *dptr;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	fpm_table_iova = (uint64_t)fpm_iova[curveid];
+
+	/* Input buffer */
+	dptr = meta_buf->vaddr;
+	inst->dptr = (uintptr_t)dptr;
+
+	scalar_align = RTE_ALIGN_CEIL(scalar->length, 8);
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(prime len, order len, constant,
+	 * private key len and iv len (if ED25519))).
+	 */
+	dlen = sizeof(fpm_table_iova) + 3 * prime_len + scalar_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, scalar->data, scalar->length);
+	dptr += scalar_align;
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, sizeof(iv_sha512));
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_KEYGEN;
+
+	w4.s.param1 = prime_bit;
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+
+	return 0;
+}
+
 static __rte_always_inline int
 cnxk_ae_ecpm_prep(rte_crypto_param *scalar, struct rte_crypto_ec_point *p,
 		  struct roc_ae_buf_ptr *meta_buf,
@@ -1112,8 +1515,12 @@ cnxk_ae_enqueue_ecdh_op(struct rte_crypto_op *op,
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		scalar.data = sess->ec_ctx.pkey.data;
 		scalar.length = sess->ec_ctx.pkey.length;
-		cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
-			curveid, inst);
+		if (curveid == ROC_AE_EC_ID_ED25519 || curveid == ROC_AE_EC_ID_ED448)
+			cnxk_ae_edfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
+		else
+			cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		scalar.data = ec_grp[curveid]->order.data;
@@ -1212,6 +1619,25 @@ cnxk_ae_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa, uint8_t *rptr,
 	ecdsa->s.length = prime_len;
 }
 
+static __rte_always_inline void
+cnxk_ae_dequeue_eddsa_op(struct rte_crypto_eddsa_op_param *eddsa, uint8_t *rptr)
+{
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519 ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519CTX ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH) {
+		eddsa->sign.length = 64;
+		memcpy(eddsa->sign.data, rptr, eddsa->sign.length);
+	} else {
+		eddsa->sign.length = 114;
+		memcpy(eddsa->sign.data, rptr, 57);
+		memcpy(eddsa->sign.data + 57, rptr + 64, 57);
+	}
+}
+
 static __rte_always_inline void
 cnxk_ae_dequeue_sm2_op(struct rte_crypto_sm2_op_param *sm2, uint8_t *rptr,
 			 struct roc_ae_ec_ctx *ec,
@@ -1245,7 +1671,7 @@ cnxk_ae_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param *ecpm, uint8_t *rptr,
 static __rte_always_inline void
 cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 			struct roc_ae_ec_ctx *ec,
-			struct roc_ae_ec_group **ec_grp)
+			struct roc_ae_ec_group **ec_grp, uint16_t flags)
 {
 	int prime_len = ec_grp[ec->curveid]->prime.length;
 
@@ -1256,9 +1682,12 @@ cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		memcpy(ecdh->pub_key.x.data, rptr, prime_len);
-		memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
 		ecdh->pub_key.x.length = prime_len;
-		ecdh->pub_key.y.length = prime_len;
+		if (!(flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED)) {
+			memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8),
+				prime_len);
+			ecdh->pub_key.y.length = prime_len;
+		}
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		break;
@@ -1328,6 +1757,13 @@ cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		ret = cnxk_ae_enqueue_eddsa_op(op, &meta_buf, sess,
+					       sess->cnxk_fpm_iova,
+					       sess->ec_grp, inst);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		ret = cnxk_ae_enqueue_sm2_op(op, &meta_buf, sess,
 					       sess->cnxk_fpm_iova,
@@ -1390,6 +1826,9 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		cnxk_ae_dequeue_ecdsa_op(&op->ecdsa, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		cnxk_ae_dequeue_eddsa_op(&op->eddsa, rptr);
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		cnxk_ae_dequeue_sm2_op(&op->sm2, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
@@ -1401,7 +1840,7 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_ECDH:
 		cnxk_ae_dequeue_ecdh_op(&op->ecdh, rptr, &sess->ec_ctx,
-					sess->ec_grp);
+					sess->ec_grp, op->flags);
 		break;
 	default:
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index 4000e84a7e..5cec64c2e1 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -11,7 +11,7 @@
 #include "roc_ae.h"
 #include "roc_cpt.h"
 
-#define CNXK_CPT_MAX_CAPS		 55
+#define CNXK_CPT_MAX_CAPS		 56
 #define CNXK_SEC_IPSEC_CRYPTO_MAX_CAPS	 16
 #define CNXK_SEC_TLS_1_3_CRYPTO_MAX_CAPS 3
 #define CNXK_SEC_TLS_1_2_CRYPTO_MAX_CAPS 7
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index 0d5d64b6e7..3897feacb8 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -1201,6 +1201,22 @@ static const struct rte_cryptodev_capabilities caps_sm2[] = {
 	}
 };
 
+static const struct rte_cryptodev_capabilities caps_eddsa[] = {
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					     (1 << RTE_CRYPTO_ASYM_OP_VERIFY))
+			}
+		}
+		}
+	}
+};
+
 static const struct rte_cryptodev_capabilities caps_end[] = {
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1940,6 +1956,9 @@ cn10k_crypto_caps_add(struct rte_cryptodev_capabilities cnxk_caps[],
 
 	if (hw_caps[CPT_ENG_TYPE_AE].sm2)
 		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, sm2);
+
+	if (hw_caps[CPT_ENG_TYPE_AE].eddsa)
+		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, eddsa);
 }
 
 static void
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index cfcfa79fdf..3bb4101946 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -65,7 +65,7 @@ cnxk_cpt_sec_get_mlen(void)
 	return len;
 }
 
-static int
+int
 cnxk_cpt_asym_get_mlen(void)
 {
 	uint32_t len;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
index caf6ac35e5..bc05266552 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
@@ -104,6 +104,8 @@ struct cnxk_cpt_qp {
 	/**< Session mempool */
 };
 
+int cnxk_cpt_asym_get_mlen(void);
+
 int cnxk_cpt_dev_config(struct rte_cryptodev *dev,
 			struct rte_cryptodev_config *conf);
 
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v5 4/6] test/crypto: add asymmetric EDDSA test cases
  2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-10-04  5:30           ` [PATCH v5 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
  2024-10-04  5:30           ` [PATCH v5 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
@ 2024-10-04  5:30           ` Gowrishankar Muthukrishnan
  2024-10-04  5:30           ` [PATCH v5 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
                             ` (2 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  5:30 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, jerinj, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Gowrishankar Muthukrishnan

Add test cases to validate EDDSA sign and verify ops,
as per RFC 8032.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test/test_cryptodev_asym.c               | 345 +++++++++++-
 app/test/test_cryptodev_ecdh_test_vectors.h  |  94 +++-
 app/test/test_cryptodev_ecdsa_test_vectors.h |   4 +
 app/test/test_cryptodev_eddsa_test_vectors.h | 556 +++++++++++++++++++
 4 files changed, 990 insertions(+), 9 deletions(-)
 create mode 100644 app/test/test_cryptodev_eddsa_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index f0b5d38543..893cc81770 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -20,6 +20,7 @@
 #include "test_cryptodev_ecdh_test_vectors.h"
 #include "test_cryptodev_ecdsa_test_vectors.h"
 #include "test_cryptodev_ecpm_test_vectors.h"
+#include "test_cryptodev_eddsa_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_sm2_test_vectors.h"
@@ -1631,6 +1632,9 @@ test_ecdsa_sign_verify_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
+		if (curve_id == ED25519 || curve_id == ED448)
+			continue;
+
 		status = test_ecdsa_sign_verify(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
@@ -1792,7 +1796,7 @@ test_ecpm_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecpm(curve_id);
@@ -1966,10 +1970,18 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	idx.type = RTE_CRYPTO_ASYM_XFORM_ECDH;
 	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
 	if (capa == NULL)
-		return -ENOTSUP;
+		return TEST_SKIPPED;
 
 	if (!(capa->op_types & (1 <<  RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)))
-		return -ENOTSUP;
+		return TEST_SKIPPED;
+
+	if (curve_id == ED25519 || curve_id == ED448) {
+		/* Check EDDSA capability */
+		idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+		if (capa == NULL)
+			return TEST_SKIPPED;
+	}
 
 	switch (curve_id) {
 	case SECP192R1:
@@ -1987,6 +1999,12 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	case SECP521R1:
 		input_params = ecdh_param_secp521r1;
 		break;
+	case ED25519:
+		input_params = ecdh_param_ed25519;
+		break;
+	case ED448:
+		input_params = ecdh_param_ed448;
+		break;
 	default:
 		RTE_LOG(ERR, USER1,
 				"line %u FAILED: %s", __LINE__,
@@ -2031,10 +2049,15 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 
 	/* Populate op with operational details */
 	asym_op->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
 
 	/* Init out buf */
 	asym_op->ecdh.pub_key.x.data = output_buf_x;
-	asym_op->ecdh.pub_key.y.data = output_buf_y;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->ecdh.pub_key.y.data = NULL;
+	else
+		asym_op->ecdh.pub_key.y.data = output_buf_y;
 
 	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
 
@@ -2073,8 +2096,13 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	debug_hexdump(stdout, "qy:",
 		asym_op->ecdh.pub_key.y.data, asym_op->ecdh.pub_key.y.length);
 
-	ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
+	if (curve_id == ED25519 || curve_id == ED448)
+		ret = memcmp(input_params.pubkey_qA_x.data, result_op->asym->ecdh.pub_key.x.data,
+			   result_op->asym->ecdh.pub_key.x.length);
+	else
+		ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
 				input_params.pubkey_qA_y.data, result_op);
+
 	if (ret) {
 		status = TEST_FAILED;
 		RTE_LOG(ERR, USER1,
@@ -2484,7 +2512,7 @@ test_ecdh_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_priv_key_generate(curve_id);
@@ -2505,6 +2533,8 @@ test_ecdh_all_curve(void)
 		status = test_ecdh_pub_key_generate(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
 		} else {
 			msg = "failed";
 			overall_status = status;
@@ -2514,7 +2544,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_pub_key_verify(curve_id);
@@ -2529,7 +2559,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_shared_secret(curve_id);
@@ -3167,6 +3197,303 @@ test_sm2_dec(void)
 	return status;
 };
 
+static int
+test_eddsa_sign(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.data = input_params->pkey.data;
+	xform.ec.pkey.length = input_params->pkey.length;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	/* Init out buf */
+	asym_op->eddsa.sign.data = output_buf_r;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "sign:",
+			asym_op->eddsa.sign.data, asym_op->eddsa.sign.length);
+
+	/* Verify sign (by comparison). */
+	if (memcmp(input_params->sign.data, asym_op->eddsa.sign.data,
+			   asym_op->eddsa.sign.length) != 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"EDDSA sign failed.\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_verify(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.length = 0;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	asym_op->eddsa.sign.data = input_params->sign.data;
+	asym_op->eddsa.sign.length = input_params->sign.length;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_sign_verify_all_curve(void)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct crypto_testsuite_eddsa_params input_params;
+	struct rte_cryptodev_asym_capability_idx idx;
+	int status, overall_status = TEST_SUCCESS;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	uint8_t i, tc = 0;
+	const char *msg;
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return TEST_SKIPPED;
+
+	/* Sign tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_sign(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Sign %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Verify tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_verify(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Verify %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Negative tests */
+	memcpy(&input_params, &eddsa_test_params[1],
+			sizeof(input_params));
+	input_params.pubkey.data[0] ^= 0x01;
+
+	status = test_eddsa_sign(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Sign %s  %s\n",
+			tc++, input_params.description, msg);
+
+	status = test_eddsa_verify(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Verify %s  %s\n",
+			tc++, input_params.description, msg);
+
+	return overall_status;
+}
+
 static int send_one(void)
 {
 	int ticks = 0;
@@ -3543,6 +3870,7 @@ static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 			"Modex Group 18 test",
 			ut_setup_asym, ut_teardown_asym,
 			modular_exponentiation, &modex_group_test_cases[5]),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
@@ -3634,6 +3962,7 @@ static struct unit_test_suite cryptodev_octeontx_asym_testsuite  = {
 				test_ecdh_all_curve),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
 				test_ecpm_all_curve),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_ecdh_test_vectors.h b/app/test/test_cryptodev_ecdh_test_vectors.h
index b577c179c8..36f92b223f 100644
--- a/app/test/test_cryptodev_ecdh_test_vectors.h
+++ b/app/test/test_cryptodev_ecdh_test_vectors.h
@@ -553,4 +553,96 @@ struct crypto_testsuite_ecdh_params ecdh_param_secp521r1 = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP521R1
 };
 
-#endif /* __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__ */
+/** ED25519 test vector */
+
+static uint8_t privkey_ed25519[] = {
+	0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+	0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+	0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+	0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+};
+
+static uint8_t pubkey_ed25519[] = {
+	0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+	0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+	0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+	0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+};
+
+/** ECDH ED25519 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed25519 = {
+	.pubkey_qA_x = {
+		.data = pubkey_ed25519,
+		.length = sizeof(pubkey_ed25519),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = privkey_ed25519,
+		.length = sizeof(privkey_ed25519),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519
+};
+
+/** ED448 test vector */
+
+static uint8_t privkey_ed448[] = {
+	0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+	0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+	0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+	0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+	0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+	0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+	0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+	0x01
+};
+
+static uint8_t pubkey_ed448[] = {
+	0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+	0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+	0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+	0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+	0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+	0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+	0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+	0x00
+};
+
+/** ECDH ED448 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed448 = {
+	.pubkey_qA_x = {
+		.data = pubkey_ed448,
+		.length = sizeof(pubkey_ed448),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = privkey_ed448,
+		.length = sizeof(privkey_ed448),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448
+};
+
+#endif /* __TEST_CRYPTODEV_ECDH_TEST_VECTORS_H__ */
diff --git a/app/test/test_cryptodev_ecdsa_test_vectors.h b/app/test/test_cryptodev_ecdsa_test_vectors.h
index f1477639ba..636a1ab1b2 100644
--- a/app/test/test_cryptodev_ecdsa_test_vectors.h
+++ b/app/test/test_cryptodev_ecdsa_test_vectors.h
@@ -15,6 +15,8 @@ enum curve {
 	SECP384R1,
 	SECP521R1,
 	SECP521R1_UA,
+	ED25519,
+	ED448,
 	END_OF_CURVE_LIST
 };
 
@@ -24,6 +26,8 @@ const char *curve[] = {"SECP192R1",
 		       "SECP384R1",
 		       "SECP521R1",
 		       "SECP521R1(unaligned)",
+		       "ED25519",
+		       "ED448",
 };
 
 struct crypto_testsuite_ecdsa_params {
diff --git a/app/test/test_cryptodev_eddsa_test_vectors.h b/app/test/test_cryptodev_eddsa_test_vectors.h
new file mode 100644
index 0000000000..47e5355ec7
--- /dev/null
+++ b/app/test/test_cryptodev_eddsa_test_vectors.h
@@ -0,0 +1,556 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifndef __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+#define DATA_SIZE 1024
+
+struct crypto_testsuite_eddsa_params {
+	enum rte_crypto_edward_instance instance;
+	enum rte_crypto_curve_id curve;
+	const char *description;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pubkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} sign;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} message;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} context;
+};
+
+/** EDDSA curve test params (RFC 8032) */
+static const struct
+crypto_testsuite_eddsa_params eddsa_test_params[] = {
+{
+	.description = "EDDSA 25519 (msg=0)",
+	.pkey = {
+		.data = {
+			0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
+			0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4,
+			0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19,
+			0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7,
+			0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a,
+			0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25,
+			0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72,
+			0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a,
+			0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74,
+			0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55,
+			0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
+			0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b,
+			0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
+			0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1)",
+	.pkey = {
+		.data = {
+			0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+			0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+			0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+			0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+			0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+			0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+			0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+			0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+			0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+			0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+			0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+			0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+			0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+			0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x72
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1023)",
+	.pkey = {
+		.data = {
+			0xf5, 0xe5, 0x76, 0x7c, 0xf1, 0x53, 0x31, 0x95,
+			0x17, 0x63, 0x0f, 0x22, 0x68, 0x76, 0xb8, 0x6c,
+			0x81, 0x60, 0xcc, 0x58, 0x3b, 0xc0, 0x13, 0x74,
+			0x4c, 0x6b, 0xf2, 0x55, 0xf5, 0xcc, 0x0e, 0xe5
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x27, 0x81, 0x17, 0xfc, 0x14, 0x4c, 0x72, 0x34,
+			0x0f, 0x67, 0xd0, 0xf2, 0x31, 0x6e, 0x83, 0x86,
+			0xce, 0xff, 0xbf, 0x2b, 0x24, 0x28, 0xc9, 0xc5,
+			0x1f, 0xef, 0x7c, 0x59, 0x7f, 0x1d, 0x42, 0x6e
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x0a, 0xab, 0x4c, 0x90, 0x05, 0x01, 0xb3, 0xe2,
+			0x4d, 0x7c, 0xdf, 0x46, 0x63, 0x32, 0x6a, 0x3a,
+			0x87, 0xdf, 0x5e, 0x48, 0x43, 0xb2, 0xcb, 0xdb,
+			0x67, 0xcb, 0xf6, 0xe4, 0x60, 0xfe, 0xc3, 0x50,
+			0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45,
+			0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b,
+			0x5e, 0x8f, 0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6,
+			0xac, 0x00, 0xa9, 0x70, 0x4a, 0x18, 0x8a, 0x03
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x08, 0xb8, 0xb2, 0xb7, 0x33, 0x42, 0x42, 0x43,
+			0x76, 0x0f, 0xe4, 0x26, 0xa4, 0xb5, 0x49, 0x08,
+			0x63, 0x21, 0x10, 0xa6, 0x6c, 0x2f, 0x65, 0x91,
+			0xea, 0xbd, 0x33, 0x45, 0xe3, 0xe4, 0xeb, 0x98,
+			0xfa, 0x6e, 0x26, 0x4b, 0xf0, 0x9e, 0xfe, 0x12,
+			0xee, 0x50, 0xf8, 0xf5, 0x4e, 0x9f, 0x77, 0xb1,
+			0xe3, 0x55, 0xf6, 0xc5, 0x05, 0x44, 0xe2, 0x3f,
+			0xb1, 0x43, 0x3d, 0xdf, 0x73, 0xbe, 0x84, 0xd8,
+			0x79, 0xde, 0x7c, 0x00, 0x46, 0xdc, 0x49, 0x96,
+			0xd9, 0xe7, 0x73, 0xf4, 0xbc, 0x9e, 0xfe, 0x57,
+			0x38, 0x82, 0x9a, 0xdb, 0x26, 0xc8, 0x1b, 0x37,
+			0xc9, 0x3a, 0x1b, 0x27, 0x0b, 0x20, 0x32, 0x9d,
+			0x65, 0x86, 0x75, 0xfc, 0x6e, 0xa5, 0x34, 0xe0,
+			0x81, 0x0a, 0x44, 0x32, 0x82, 0x6b, 0xf5, 0x8c,
+			0x94, 0x1e, 0xfb, 0x65, 0xd5, 0x7a, 0x33, 0x8b,
+			0xbd, 0x2e, 0x26, 0x64, 0x0f, 0x89, 0xff, 0xbc,
+			0x1a, 0x85, 0x8e, 0xfc, 0xb8, 0x55, 0x0e, 0xe3,
+			0xa5, 0xe1, 0x99, 0x8b, 0xd1, 0x77, 0xe9, 0x3a,
+			0x73, 0x63, 0xc3, 0x44, 0xfe, 0x6b, 0x19, 0x9e,
+			0xe5, 0xd0, 0x2e, 0x82, 0xd5, 0x22, 0xc4, 0xfe,
+			0xba, 0x15, 0x45, 0x2f, 0x80, 0x28, 0x8a, 0x82,
+			0x1a, 0x57, 0x91, 0x16, 0xec, 0x6d, 0xad, 0x2b,
+			0x3b, 0x31, 0x0d, 0xa9, 0x03, 0x40, 0x1a, 0xa6,
+			0x21, 0x00, 0xab, 0x5d, 0x1a, 0x36, 0x55, 0x3e,
+			0x06, 0x20, 0x3b, 0x33, 0x89, 0x0c, 0xc9, 0xb8,
+			0x32, 0xf7, 0x9e, 0xf8, 0x05, 0x60, 0xcc, 0xb9,
+			0xa3, 0x9c, 0xe7, 0x67, 0x96, 0x7e, 0xd6, 0x28,
+			0xc6, 0xad, 0x57, 0x3c, 0xb1, 0x16, 0xdb, 0xef,
+			0xef, 0xd7, 0x54, 0x99, 0xda, 0x96, 0xbd, 0x68,
+			0xa8, 0xa9, 0x7b, 0x92, 0x8a, 0x8b, 0xbc, 0x10,
+			0x3b, 0x66, 0x21, 0xfc, 0xde, 0x2b, 0xec, 0xa1,
+			0x23, 0x1d, 0x20, 0x6b, 0xe6, 0xcd, 0x9e, 0xc7,
+			0xaf, 0xf6, 0xf6, 0xc9, 0x4f, 0xcd, 0x72, 0x04,
+			0xed, 0x34, 0x55, 0xc6, 0x8c, 0x83, 0xf4, 0xa4,
+			0x1d, 0xa4, 0xaf, 0x2b, 0x74, 0xef, 0x5c, 0x53,
+			0xf1, 0xd8, 0xac, 0x70, 0xbd, 0xcb, 0x7e, 0xd1,
+			0x85, 0xce, 0x81, 0xbd, 0x84, 0x35, 0x9d, 0x44,
+			0x25, 0x4d, 0x95, 0x62, 0x9e, 0x98, 0x55, 0xa9,
+			0x4a, 0x7c, 0x19, 0x58, 0xd1, 0xf8, 0xad, 0xa5,
+			0xd0, 0x53, 0x2e, 0xd8, 0xa5, 0xaa, 0x3f, 0xb2,
+			0xd1, 0x7b, 0xa7, 0x0e, 0xb6, 0x24, 0x8e, 0x59,
+			0x4e, 0x1a, 0x22, 0x97, 0xac, 0xbb, 0xb3, 0x9d,
+			0x50, 0x2f, 0x1a, 0x8c, 0x6e, 0xb6, 0xf1, 0xce,
+			0x22, 0xb3, 0xde, 0x1a, 0x1f, 0x40, 0xcc, 0x24,
+			0x55, 0x41, 0x19, 0xa8, 0x31, 0xa9, 0xaa, 0xd6,
+			0x07, 0x9c, 0xad, 0x88, 0x42, 0x5d, 0xe6, 0xbd,
+			0xe1, 0xa9, 0x18, 0x7e, 0xbb, 0x60, 0x92, 0xcf,
+			0x67, 0xbf, 0x2b, 0x13, 0xfd, 0x65, 0xf2, 0x70,
+			0x88, 0xd7, 0x8b, 0x7e, 0x88, 0x3c, 0x87, 0x59,
+			0xd2, 0xc4, 0xf5, 0xc6, 0x5a, 0xdb, 0x75, 0x53,
+			0x87, 0x8a, 0xd5, 0x75, 0xf9, 0xfa, 0xd8, 0x78,
+			0xe8, 0x0a, 0x0c, 0x9b, 0xa6, 0x3b, 0xcb, 0xcc,
+			0x27, 0x32, 0xe6, 0x94, 0x85, 0xbb, 0xc9, 0xc9,
+			0x0b, 0xfb, 0xd6, 0x24, 0x81, 0xd9, 0x08, 0x9b,
+			0xec, 0xcf, 0x80, 0xcf, 0xe2, 0xdf, 0x16, 0xa2,
+			0xcf, 0x65, 0xbd, 0x92, 0xdd, 0x59, 0x7b, 0x07,
+			0x07, 0xe0, 0x91, 0x7a, 0xf4, 0x8b, 0xbb, 0x75,
+			0xfe, 0xd4, 0x13, 0xd2, 0x38, 0xf5, 0x55, 0x5a,
+			0x7a, 0x56, 0x9d, 0x80, 0xc3, 0x41, 0x4a, 0x8d,
+			0x08, 0x59, 0xdc, 0x65, 0xa4, 0x61, 0x28, 0xba,
+			0xb2, 0x7a, 0xf8, 0x7a, 0x71, 0x31, 0x4f, 0x31,
+			0x8c, 0x78, 0x2b, 0x23, 0xeb, 0xfe, 0x80, 0x8b,
+			0x82, 0xb0, 0xce, 0x26, 0x40, 0x1d, 0x2e, 0x22,
+			0xf0, 0x4d, 0x83, 0xd1, 0x25, 0x5d, 0xc5, 0x1a,
+			0xdd, 0xd3, 0xb7, 0x5a, 0x2b, 0x1a, 0xe0, 0x78,
+			0x45, 0x04, 0xdf, 0x54, 0x3a, 0xf8, 0x96, 0x9b,
+			0xe3, 0xea, 0x70, 0x82, 0xff, 0x7f, 0xc9, 0x88,
+			0x8c, 0x14, 0x4d, 0xa2, 0xaf, 0x58, 0x42, 0x9e,
+			0xc9, 0x60, 0x31, 0xdb, 0xca, 0xd3, 0xda, 0xd9,
+			0xaf, 0x0d, 0xcb, 0xaa, 0xaf, 0x26, 0x8c, 0xb8,
+			0xfc, 0xff, 0xea, 0xd9, 0x4f, 0x3c, 0x7c, 0xa4,
+			0x95, 0xe0, 0x56, 0xa9, 0xb4, 0x7a, 0xcd, 0xb7,
+			0x51, 0xfb, 0x73, 0xe6, 0x66, 0xc6, 0xc6, 0x55,
+			0xad, 0xe8, 0x29, 0x72, 0x97, 0xd0, 0x7a, 0xd1,
+			0xba, 0x5e, 0x43, 0xf1, 0xbc, 0xa3, 0x23, 0x01,
+			0x65, 0x13, 0x39, 0xe2, 0x29, 0x04, 0xcc, 0x8c,
+			0x42, 0xf5, 0x8c, 0x30, 0xc0, 0x4a, 0xaf, 0xdb,
+			0x03, 0x8d, 0xda, 0x08, 0x47, 0xdd, 0x98, 0x8d,
+			0xcd, 0xa6, 0xf3, 0xbf, 0xd1, 0x5c, 0x4b, 0x4c,
+			0x45, 0x25, 0x00, 0x4a, 0xa0, 0x6e, 0xef, 0xf8,
+			0xca, 0x61, 0x78, 0x3a, 0xac, 0xec, 0x57, 0xfb,
+			0x3d, 0x1f, 0x92, 0xb0, 0xfe, 0x2f, 0xd1, 0xa8,
+			0x5f, 0x67, 0x24, 0x51, 0x7b, 0x65, 0xe6, 0x14,
+			0xad, 0x68, 0x08, 0xd6, 0xf6, 0xee, 0x34, 0xdf,
+			0xf7, 0x31, 0x0f, 0xdc, 0x82, 0xae, 0xbf, 0xd9,
+			0x04, 0xb0, 0x1e, 0x1d, 0xc5, 0x4b, 0x29, 0x27,
+			0x09, 0x4b, 0x2d, 0xb6, 0x8d, 0x6f, 0x90, 0x3b,
+			0x68, 0x40, 0x1a, 0xde, 0xbf, 0x5a, 0x7e, 0x08,
+			0xd7, 0x8f, 0xf4, 0xef, 0x5d, 0x63, 0x65, 0x3a,
+			0x65, 0x04, 0x0c, 0xf9, 0xbf, 0xd4, 0xac, 0xa7,
+			0x98, 0x4a, 0x74, 0xd3, 0x71, 0x45, 0x98, 0x67,
+			0x80, 0xfc, 0x0b, 0x16, 0xac, 0x45, 0x16, 0x49,
+			0xde, 0x61, 0x88, 0xa7, 0xdb, 0xdf, 0x19, 0x1f,
+			0x64, 0xb5, 0xfc, 0x5e, 0x2a, 0xb4, 0x7b, 0x57,
+			0xf7, 0xf7, 0x27, 0x6c, 0xd4, 0x19, 0xc1, 0x7a,
+			0x3c, 0xa8, 0xe1, 0xb9, 0x39, 0xae, 0x49, 0xe4,
+			0x88, 0xac, 0xba, 0x6b, 0x96, 0x56, 0x10, 0xb5,
+			0x48, 0x01, 0x09, 0xc8, 0xb1, 0x7b, 0x80, 0xe1,
+			0xb7, 0xb7, 0x50, 0xdf, 0xc7, 0x59, 0x8d, 0x5d,
+			0x50, 0x11, 0xfd, 0x2d, 0xcc, 0x56, 0x00, 0xa3,
+			0x2e, 0xf5, 0xb5, 0x2a, 0x1e, 0xcc, 0x82, 0x0e,
+			0x30, 0x8a, 0xa3, 0x42, 0x72, 0x1a, 0xac, 0x09,
+			0x43, 0xbf, 0x66, 0x86, 0xb6, 0x4b, 0x25, 0x79,
+			0x37, 0x65, 0x04, 0xcc, 0xc4, 0x93, 0xd9, 0x7e,
+			0x6a, 0xed, 0x3f, 0xb0, 0xf9, 0xcd, 0x71, 0xa4,
+			0x3d, 0xd4, 0x97, 0xf0, 0x1f, 0x17, 0xc0, 0xe2,
+			0xcb, 0x37, 0x97, 0xaa, 0x2a, 0x2f, 0x25, 0x66,
+			0x56, 0x16, 0x8e, 0x6c, 0x49, 0x6a, 0xfc, 0x5f,
+			0xb9, 0x32, 0x46, 0xf6, 0xb1, 0x11, 0x63, 0x98,
+			0xa3, 0x46, 0xf1, 0xa6, 0x41, 0xf3, 0xb0, 0x41,
+			0xe9, 0x89, 0xf7, 0x91, 0x4f, 0x90, 0xcc, 0x2c,
+			0x7f, 0xff, 0x35, 0x78, 0x76, 0xe5, 0x06, 0xb5,
+			0x0d, 0x33, 0x4b, 0xa7, 0x7c, 0x22, 0x5b, 0xc3,
+			0x07, 0xba, 0x53, 0x71, 0x52, 0xf3, 0xf1, 0x61,
+			0x0e, 0x4e, 0xaf, 0xe5, 0x95, 0xf6, 0xd9, 0xd9,
+			0x0d, 0x11, 0xfa, 0xa9, 0x33, 0xa1, 0x5e, 0xf1,
+			0x36, 0x95, 0x46, 0x86, 0x8a, 0x7f, 0x3a, 0x45,
+			0xa9, 0x67, 0x68, 0xd4, 0x0f, 0xd9, 0xd0, 0x34,
+			0x12, 0xc0, 0x91, 0xc6, 0x31, 0x5c, 0xf4, 0xfd,
+			0xe7, 0xcb, 0x68, 0x60, 0x69, 0x37, 0x38, 0x0d,
+			0xb2, 0xea, 0xaa, 0x70, 0x7b, 0x4c, 0x41, 0x85,
+			0xc3, 0x2e, 0xdd, 0xcd, 0xd3, 0x06, 0x70, 0x5e,
+			0x4d, 0xc1, 0xff, 0xc8, 0x72, 0xee, 0xee, 0x47,
+			0x5a, 0x64, 0xdf, 0xac, 0x86, 0xab, 0xa4, 0x1c,
+			0x06, 0x18, 0x98, 0x3f, 0x87, 0x41, 0xc5, 0xef,
+			0x68, 0xd3, 0xa1, 0x01, 0xe8, 0xa3, 0xb8, 0xca,
+			0xc6, 0x0c, 0x90, 0x5c, 0x15, 0xfc, 0x91, 0x08,
+			0x40, 0xb9, 0x4c, 0x00, 0xa0, 0xb9, 0xd0
+		},
+		.length = 1023,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519CTX (msg=16, ctx=3)",
+	.pkey = {
+		.data = {
+			0x03, 0x05, 0x33, 0x4e, 0x38, 0x1a, 0xf7, 0x8f,
+			0x14, 0x1c, 0xb6, 0x66, 0xf6, 0x19, 0x9f, 0x57,
+			0xbc, 0x34, 0x95, 0x33, 0x5a, 0x25, 0x6a, 0x95,
+			0xbd, 0x2a, 0x55, 0xbf, 0x54, 0x66, 0x63, 0xf6
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xdf, 0xc9, 0x42, 0x5e, 0x4f, 0x96, 0x8f, 0x7f,
+			0x0c, 0x29, 0xf0, 0x25, 0x9c, 0xf5, 0xf9, 0xae,
+			0xd6, 0x85, 0x1c, 0x2b, 0xb4, 0xad, 0x8b, 0xfb,
+			0x86, 0x0c, 0xfe, 0xe0, 0xab, 0x24, 0x82, 0x92
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x55, 0xa4, 0xcc, 0x2f, 0x70, 0xa5, 0x4e, 0x04,
+			0x28, 0x8c, 0x5f, 0x4c, 0xd1, 0xe4, 0x5a, 0x7b,
+			0xb5, 0x20, 0xb3, 0x62, 0x92, 0x91, 0x18, 0x76,
+			0xca, 0xda, 0x73, 0x23, 0x19, 0x8d, 0xd8, 0x7a,
+			0x8b, 0x36, 0x95, 0x0b, 0x95, 0x13, 0x00, 0x22,
+			0x90, 0x7a, 0x7f, 0xb7, 0xc4, 0xe9, 0xb2, 0xd5,
+			0xf6, 0xcc, 0xa6, 0x85, 0xa5, 0x87, 0xb4, 0xb2,
+			0x1f, 0x4b, 0x88, 0x8e, 0x4e, 0x7e, 0xdb, 0x0d
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0xf7, 0x26, 0x93, 0x6d, 0x19, 0xc8, 0x00, 0x49,
+			0x4e, 0x3f, 0xda, 0xff, 0x20, 0xb2, 0x76, 0xa8,
+		},
+		.length = 16,
+	},
+	.context = {
+		.data = {
+			0x66, 0x6f, 0x6f
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519CTX
+},
+{
+	.description = "EDDSA 25519PH (msg=1, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+			0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+			0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+			0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x98, 0xa7, 0x02, 0x22, 0xf0, 0xb8, 0x12, 0x1a,
+			0xa9, 0xd3, 0x0f, 0x81, 0x3d, 0x68, 0x3f, 0x80,
+			0x9e, 0x46, 0x2b, 0x46, 0x9c, 0x7f, 0xf8, 0x76,
+			0x39, 0x49, 0x9b, 0xb9, 0x4e, 0x6d, 0xae, 0x41,
+			0x31, 0xf8, 0x50, 0x42, 0x46, 0x3c, 0x2a, 0x35,
+			0x5a, 0x20, 0x03, 0xd0, 0x62, 0xad, 0xf5, 0xaa,
+			0xa1, 0x0b, 0x8c, 0x61, 0xe6, 0x36, 0x06, 0x2a,
+			0xaa, 0xd1, 0x1c, 0x2a, 0x26, 0x08, 0x34, 0x06
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519PH
+},
+{
+	.description = "EDDSA 448 (msg=0)",
+	.pkey = {
+		.data = {
+			0x6C, 0x82, 0xA5, 0x62, 0xCB, 0x80, 0x8D, 0x10,
+			0xD6, 0x32, 0xBE, 0x89, 0xC8, 0x51, 0x3E, 0xBF,
+			0x6C, 0x92, 0x9F, 0x34, 0xDD, 0xFA, 0x8C, 0x9F,
+			0x63, 0xC9, 0x96, 0x0E, 0xF6, 0xE3, 0x48, 0xA3,
+			0x52, 0x8C, 0x8A, 0x3F, 0xCC, 0x2F, 0x04, 0x4E,
+			0x39, 0xA3, 0xFC, 0x5B, 0x94, 0x49, 0x2F, 0x8F,
+			0x03, 0x2E, 0x75, 0x49, 0xA2, 0x00, 0x98, 0xF9,
+			0x5B,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x5F, 0xD7, 0x44, 0x9B, 0x59, 0xB4, 0x61, 0xFD,
+			0x2C, 0xE7, 0x87, 0xEC, 0x61, 0x6A, 0xD4, 0x6A,
+			0x1D, 0xA1, 0x34, 0x24, 0x85, 0xA7, 0x0E, 0x1F,
+			0x8A, 0x0E, 0xA7, 0x5D, 0x80, 0xE9, 0x67, 0x78,
+			0xED, 0xF1, 0x24, 0x76, 0x9B, 0x46, 0xC7, 0x06,
+			0x1B, 0xD6, 0x78, 0x3D, 0xF1, 0xE5, 0x0F, 0x6C,
+			0xD1, 0xFA, 0x1A, 0xBE, 0xAF, 0xE8, 0x25, 0x61,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25,
+			0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae,
+			0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2,
+			0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f,
+			0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81,
+			0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78,
+			0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39,
+			0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a,
+			0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d,
+			0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41,
+			0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd,
+			0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb,
+			0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26,
+			0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65,
+			0x26, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=1)",
+	.pkey = {
+		.data = {
+			0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6,
+			0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92, 0x4d,
+			0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d,
+			0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c, 0x46, 0x3a,
+			0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c,
+			0x5e, 0x3b, 0xc3, 0x97, 0xa6, 0x59, 0x94, 0x9e,
+			0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27,
+			0x4e,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45,
+			0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd, 0x0a,
+			0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37,
+			0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98, 0xc0, 0x86,
+			0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02,
+			0xb8, 0x43, 0x8e, 0xa4, 0xcb, 0x82, 0x16, 0x9c,
+			0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x26, 0xb8, 0xf9, 0x17, 0x27, 0xbd, 0x62, 0x89,
+			0x7a, 0xf1, 0x5e, 0x41, 0xeb, 0x43, 0xc3, 0x77,
+			0xef, 0xb9, 0xc6, 0x10, 0xd4, 0x8f, 0x23, 0x35,
+			0xcb, 0x0b, 0xd0, 0x08, 0x78, 0x10, 0xf4, 0x35,
+			0x25, 0x41, 0xb1, 0x43, 0xc4, 0xb9, 0x81, 0xb7,
+			0xe1, 0x8f, 0x62, 0xde, 0x8c, 0xcd, 0xf6, 0x33,
+			0xfc, 0x1b, 0xf0, 0x37, 0xab, 0x7c, 0xd7, 0x79,
+			0x80, 0x5e, 0x0d, 0xbc, 0xc0, 0xaa, 0xe1, 0xcb,
+			0xce, 0xe1, 0xaf, 0xb2, 0xe0, 0x27, 0xdf, 0x36,
+			0xbc, 0x04, 0xdc, 0xec, 0xbf, 0x15, 0x43, 0x36,
+			0xc1, 0x9f, 0x0a, 0xf7, 0xe0, 0xa6, 0x47, 0x29,
+			0x05, 0xe7, 0x99, 0xf1, 0x95, 0x3d, 0x2a, 0x0f,
+			0xf3, 0x34, 0x8a, 0xb2, 0x1a, 0xa4, 0xad, 0xaf,
+			0xd1, 0xd2, 0x34, 0x44, 0x1c, 0xf8, 0x07, 0xc0,
+			0x3a, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x03
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=3, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42,
+			0xef, 0x78, 0x22, 0xe0, 0xd5, 0x10, 0x41, 0x27,
+			0xdc, 0x05, 0xd6, 0xdb, 0xef, 0xde, 0x69, 0xe3,
+			0xab, 0x2c, 0xec, 0x7c, 0x86, 0x7c, 0x6e, 0x2c,
+			0x49
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x25, 0x9b, 0x71, 0xc1, 0x9f, 0x83, 0xef, 0x77,
+			0xa7, 0xab, 0xd2, 0x65, 0x24, 0xcb, 0xdb, 0x31,
+			0x61, 0xb5, 0x90, 0xa4, 0x8f, 0x7d, 0x17, 0xde,
+			0x3e, 0xe0, 0xba, 0x9c, 0x52, 0xbe, 0xb7, 0x43,
+			0xc0, 0x94, 0x28, 0xa1, 0x31, 0xd6, 0xb1, 0xb5,
+			0x73, 0x03, 0xd9, 0x0d, 0x81, 0x32, 0xc2, 0x76,
+			0xd5, 0xed, 0x3d, 0x5d, 0x01, 0xc0, 0xf5, 0x38,
+			0x80
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x82, 0x2f, 0x69, 0x01, 0xf7, 0x48, 0x0f, 0x3d,
+			0x5f, 0x56, 0x2c, 0x59, 0x29, 0x94, 0xd9, 0x69,
+			0x36, 0x02, 0x87, 0x56, 0x14, 0x48, 0x32, 0x56,
+			0x50, 0x56, 0x00, 0xbb, 0xc2, 0x81, 0xae, 0x38,
+			0x1f, 0x54, 0xd6, 0xbc, 0xe2, 0xea, 0x91, 0x15,
+			0x74, 0x93, 0x2f, 0x52, 0xa4, 0xe6, 0xca, 0xdd,
+			0x78, 0x76, 0x93, 0x75, 0xec, 0x3f, 0xfd, 0x1b,
+			0x80, 0x1a, 0x0d, 0x9b, 0x3f, 0x40, 0x30, 0xcd,
+			0x43, 0x39, 0x64, 0xb6, 0x45, 0x7e, 0xa3, 0x94,
+			0x76, 0x51, 0x12, 0x14, 0xf9, 0x74, 0x69, 0xb5,
+			0x7d, 0xd3, 0x2d, 0xbc, 0x56, 0x0a, 0x9a, 0x94,
+			0xd0, 0x0b, 0xff, 0x07, 0x62, 0x04, 0x64, 0xa3,
+			0xad, 0x20, 0x3d, 0xf7, 0xdc, 0x7c, 0xe3, 0x60,
+			0xc3, 0xcd, 0x36, 0x96, 0xd9, 0xd9, 0xfa, 0xb9,
+			0x0f, 0x00
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448PH
+},
+};
+
+#endif /* __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__ */
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v5 5/6] examples/fips_validation: support EDDSA
  2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                             ` (2 preceding siblings ...)
  2024-10-04  5:30           ` [PATCH v5 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
@ 2024-10-04  5:30           ` Gowrishankar Muthukrishnan
  2024-10-04  5:30           ` [PATCH v5 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
  2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  5:30 UTC (permalink / raw)
  To: dev, Brian Dooley, Gowrishankar Muthukrishnan
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal

Add EDDSA support in fips_validation app.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 examples/fips_validation/fips_validation.c    |   2 +
 examples/fips_validation/fips_validation.h    |  23 ++
 .../fips_validation/fips_validation_eddsa.c   | 307 +++++++++++++++++
 examples/fips_validation/main.c               | 323 ++++++++++++++++--
 examples/fips_validation/meson.build          |   1 +
 5 files changed, 623 insertions(+), 33 deletions(-)
 create mode 100644 examples/fips_validation/fips_validation_eddsa.c

diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c
index c15178e55b..43d1e55532 100644
--- a/examples/fips_validation/fips_validation.c
+++ b/examples/fips_validation/fips_validation.c
@@ -475,6 +475,8 @@ fips_test_parse_one_json_vector_set(void)
 		info.algo = FIPS_TEST_ALGO_RSA;
 	else if (strstr(algo_str, "ECDSA"))
 		info.algo = FIPS_TEST_ALGO_ECDSA;
+	else if (strstr(algo_str, "EDDSA"))
+		info.algo = FIPS_TEST_ALGO_EDDSA;
 	else
 		return -EINVAL;
 
diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h
index abc1d64742..795cf834e8 100644
--- a/examples/fips_validation/fips_validation.h
+++ b/examples/fips_validation/fips_validation.h
@@ -46,6 +46,7 @@ enum fips_test_algorithms {
 		FIPS_TEST_ALGO_SHA,
 		FIPS_TEST_ALGO_RSA,
 		FIPS_TEST_ALGO_ECDSA,
+		FIPS_TEST_ALGO_EDDSA,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -106,6 +107,12 @@ struct fips_test_vector {
 		struct fips_val s;
 		struct fips_val k;
 	} ecdsa;
+	struct {
+		struct fips_val pkey;
+		struct fips_val q;
+		struct fips_val ctx;
+		struct fips_val sign;
+	} eddsa;
 
 	struct fips_val pt;
 	struct fips_val ct;
@@ -177,6 +184,11 @@ enum fips_ecdsa_test_types {
 	ECDSA_AFT = 0,
 };
 
+enum fips_eddsa_test_types {
+	EDDSA_AFT = 0,
+	EDDSA_BFT
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -241,6 +253,13 @@ struct ecdsa_interim_data {
 	uint8_t pubkey_gen;
 };
 
+struct eddsa_interim_data {
+	enum rte_crypto_curve_id curve_id;
+	uint8_t curve_len;
+	uint8_t pubkey_gen;
+	bool prehash;
+};
+
 #ifdef USE_JANSSON
 /*
  * Maximum length of buffer to hold any json string.
@@ -288,6 +307,7 @@ struct fips_test_interim_info {
 		struct xts_interim_data xts_data;
 		struct rsa_interim_data rsa_data;
 		struct ecdsa_interim_data ecdsa_data;
+		struct eddsa_interim_data eddsa_data;
 	} interim_info;
 
 	enum fips_test_op op;
@@ -374,6 +394,9 @@ parse_test_rsa_json_init(void);
 int
 parse_test_ecdsa_json_init(void);
 
+int
+parse_test_eddsa_json_init(void);
+
 int
 fips_test_randomize_message(struct fips_val *msg, struct fips_val *rand);
 #endif /* USE_JANSSON */
diff --git a/examples/fips_validation/fips_validation_eddsa.c b/examples/fips_validation/fips_validation_eddsa.c
new file mode 100644
index 0000000000..8ccf7501bd
--- /dev/null
+++ b/examples/fips_validation/fips_validation_eddsa.c
@@ -0,0 +1,307 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell.
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef USE_OPENSSL
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#endif /* USE_OPENSSL */
+
+#include <rte_cryptodev.h>
+#include <rte_malloc.h>
+
+#include "fips_validation.h"
+
+#define TESTTYPE_JSON_STR "testType"
+#define CURVE_JSON_STR    "curve"
+#define PH_JSON_STR       "preHash"
+
+#define MSG_JSON_STR "message"
+#define CTX_JSON_STR "context"
+#define Q_JSON_STR	 "q"
+#define SIG_JSON_STR "signature"
+
+#ifdef USE_JANSSON
+struct {
+	uint8_t type;
+	const char *desc;
+} eddsa_test_types[] = {
+	{EDDSA_AFT, "AFT"},
+	{EDDSA_BFT, "BFT"}
+};
+
+struct {
+	enum rte_crypto_curve_id curve_id;
+	const char *desc;
+} eddsa_curve_ids[] = {
+	{RTE_CRYPTO_EC_GROUP_ED25519, "ED-25519"},
+	{RTE_CRYPTO_EC_GROUP_ED448, "ED-448"},
+};
+
+struct {
+	uint8_t curve_len;
+	const char *desc;
+} eddsa_curve_len[] = {
+	{32, "ED-25519"},
+	{64, "ED-448"},
+};
+
+#ifdef USE_OPENSSL
+#define MAX_TRIES 10
+static int
+prepare_vec_eddsa(void)
+{
+	BIGNUM *pkey = NULL, *order = NULL;
+	int ret = -1, j;
+	unsigned long pid;
+
+	/* For EDDSA prime fields, order of base points (RFC 8032 Section 5.1 and 5.2).
+	 */
+	static const char * const orderstr[] = {
+			"7237005577332262213973186563042994240857116359379907606001950938285454250989",
+			"181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779",
+	};
+
+	pid = getpid();
+	RAND_seed(&pid, sizeof(pid));
+
+	if (!RAND_status())
+		return -1;
+
+	order = BN_new();
+	if (!order)
+		goto err;
+
+	j = info.interim_info.eddsa_data.curve_id - RTE_CRYPTO_EC_GROUP_ED25519;
+	if (!BN_hex2bn(&order, orderstr[j]))
+		goto err;
+
+	pkey = BN_new();
+	if (!pkey)
+		goto err;
+
+	for (j = 0; j < MAX_TRIES; j++) {
+		/* pkey should be in [1, order - 1] */
+		if (!BN_rand_range(pkey, order))
+			goto err;
+
+		if (!BN_is_zero(pkey))
+			break;
+	}
+
+	if (j == MAX_TRIES)
+		goto err;
+
+	parse_uint8_hex_str("", BN_bn2hex(pkey), &vec.eddsa.pkey);
+
+	ret = 0;
+err:
+	BN_free(order);
+	BN_free(pkey);
+	return ret;
+}
+#else
+static int
+prepare_vec_eddsa(void)
+{
+	/*
+	 * Generate EDDSA values.
+	 */
+	return -ENOTSUP;
+}
+#endif /* USE_OPENSSL */
+
+static int
+parse_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		/* For siggen tests, EDDSA values can be created soon after
+		 * the test group data are parsed.
+		 */
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+static int
+post_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_group, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_test_eddsa_json_writeback(struct fips_val *val)
+{
+	json_t *tcId;
+
+	RTE_SET_USED(val);
+
+	tcId = json_object_get(json_info.json_test_case, "tcId");
+
+	json_info.json_write_case = json_object();
+	json_object_set(json_info.json_write_case, "tcId", tcId);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.sign);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "signature", obj);
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)
+			json_object_set_new(json_info.json_write_case, "testPassed", json_true());
+		else
+			json_object_set_new(json_info.json_write_case, "testPassed", json_false());
+	} else if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.pkey);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "d", obj);
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_interim_str(const char *key, char *src, struct fips_val *val)
+{
+	uint32_t i;
+
+	RTE_SET_USED(val);
+
+	if (strcmp(key, TESTTYPE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_test_types); i++)
+			if (strstr(src, eddsa_test_types[i].desc)) {
+				info.parse_writeback = parse_test_eddsa_json_writeback;
+				break;
+			}
+
+		if (!info.parse_writeback || i >= RTE_DIM(eddsa_test_types))
+			return -EINVAL;
+
+	} else if (strcmp(key, CURVE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_curve_ids); i++)
+			if (strstr(src, eddsa_curve_ids[i].desc)) {
+				info.interim_info.eddsa_data.curve_id = eddsa_curve_ids[i].curve_id;
+				info.interim_info.eddsa_data.curve_len =
+					eddsa_curve_len[i].curve_len;
+				break;
+			}
+
+		if (i >= RTE_DIM(eddsa_curve_ids))
+			return -EINVAL;
+	} else if (strcmp(key, PH_JSON_STR) == 0) {
+		info.interim_info.eddsa_data.prehash = false;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+parse_keygen_tc_str(const char *key, char *src, struct fips_val *val)
+{
+	RTE_SET_USED(key);
+	RTE_SET_USED(src);
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+struct fips_test_callback eddsa_interim_json_vectors[] = {
+		{TESTTYPE_JSON_STR, parse_interim_str, NULL},
+		{CURVE_JSON_STR, parse_interim_str, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_siggen_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{CTX_JSON_STR, parse_uint8_hex_str, &vec.eddsa.ctx},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_sigver_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{Q_JSON_STR, parse_uint8_hex_str, &vec.eddsa.q},
+		{SIG_JSON_STR, parse_uint8_hex_str, &vec.eddsa.sign},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_keygen_json_vectors[] = {
+		{"tcId", parse_keygen_tc_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+int
+parse_test_eddsa_json_init(void)
+{
+	json_t *mode_obj = json_object_get(json_info.json_vector_set, "mode");
+	const char *mode_str = json_string_value(mode_obj);
+
+	info.callbacks = NULL;
+	info.parse_writeback = NULL;
+
+	info.interim_callbacks = eddsa_interim_json_vectors;
+	info.post_interim_writeback = post_test_eddsa_json_interim_writeback;
+	info.parse_interim_writeback = parse_test_eddsa_json_interim_writeback;
+	if (strcmp(mode_str, "sigGen") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGGEN;
+		info.callbacks = eddsa_siggen_json_vectors;
+	} else if (strcmp(mode_str, "sigVer") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGVER;
+		info.callbacks = eddsa_sigver_json_vectors;
+	} else if (strcmp(mode_str, "keyGen") == 0) {
+		info.op = FIPS_TEST_ASYM_KEYGEN;
+		info.callbacks = eddsa_keygen_json_vectors;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif /* USE_JANSSON */
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index 7ae2c6c007..522373ac1d 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -1041,6 +1041,64 @@ prepare_ecdsa_op(void)
 	return 0;
 }
 
+static int
+prepare_eddsa_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+	struct fips_val msg;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	if (env.digest) {
+		msg.val = env.digest;
+		msg.len = env.digest_len;
+	} else {
+		msg.val = vec.pt.val;
+		msg.len = vec.pt.len;
+	}
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.context.data = vec.eddsa.ctx.val;
+		asym->eddsa.context.length = vec.eddsa.ctx.len;
+
+		rte_free(vec.eddsa.sign.val);
+
+		vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len;
+		vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0);
+
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = 0;
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = vec.eddsa.sign.len;
+	} else {
+		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
+		return -EINVAL;
+	}
+
+	if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH;
+		if (vec.eddsa.ctx.len > 0)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX;
+	} else {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH;
+	}
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_ecfpm_op(void)
 {
@@ -1072,6 +1130,31 @@ prepare_ecfpm_op(void)
 	return 0;
 }
 
+static int
+prepare_edfpm_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	asym->ecpm.scalar.data = vec.eddsa.pkey.val;
+	asym->ecpm.scalar.length = vec.eddsa.pkey.len;
+
+	rte_free(vec.eddsa.q.val);
+
+	vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len;
+	vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0);
+
+	asym->ecpm.r.x.data = vec.eddsa.q.val;
+	asym->ecpm.r.x.length = 0;
+	asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
@@ -1589,6 +1672,56 @@ prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_eddsa_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	switch (info.op) {
+	case FIPS_TEST_ASYM_SIGGEN:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_SIGN)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
+			return -EPERM;
+		}
+
+		xform->ec.pkey.data = vec.eddsa.pkey.val;
+		xform->ec.pkey.length = vec.eddsa.pkey.len;
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	case FIPS_TEST_ASYM_SIGVER:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_VERIFY)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
+			return -EPERM;
+		}
+
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	default:
+		break;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 {
@@ -1610,6 +1743,27 @@ prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_edfpm_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 get_writeback_data(struct fips_val *val)
 {
@@ -1709,7 +1863,9 @@ fips_run_asym_test(void)
 	struct rte_crypto_op *deqd_op;
 	int ret;
 
-	if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != FIPS_TEST_ALGO_ECDSA) {
+	if (info.op == FIPS_TEST_ASYM_KEYGEN &&
+		(info.algo != FIPS_TEST_ALGO_ECDSA &&
+		 info.algo != FIPS_TEST_ALGO_EDDSA)) {
 		RTE_SET_USED(asym);
 		ret = 0;
 		goto exit;
@@ -1758,53 +1914,140 @@ fips_run_test(void)
 {
 	int ret;
 
-	env.op = env.sym.op;
-	if (env.is_asym_test) {
-		if (info.op == FIPS_TEST_ASYM_KEYGEN &&
-			info.algo == FIPS_TEST_ALGO_ECDSA) {
-			env.op = env.asym.op;
+	env.op = NULL;
+	if (!env.is_asym_test) {
+		env.op = env.sym.op;
+		return fips_run_sym_test();
+	}
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (info.algo == FIPS_TEST_ALGO_ECDSA) {
 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
 			test_ops.prepare_asym_op = prepare_ecfpm_op;
-			ret = fips_run_asym_test();
-			if (ret < 0)
-				return ret;
-
 			info.interim_info.ecdsa_data.pubkey_gen = 0;
-			return ret;
+
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA) {
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			info.interim_info.eddsa_data.pubkey_gen = 0;
 		}
 
-		vec.cipher_auth.digest.len = parse_test_sha_hash_size(
-						info.interim_info.rsa_data.auth);
+		env.op = env.asym.op;
+		return fips_run_asym_test();
+	}
+
+	if (info.algo == FIPS_TEST_ALGO_ECDSA) {
+		vec.cipher_auth.digest.len =
+			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
 		test_ops.prepare_sym_xform = prepare_sha_xform;
 		test_ops.prepare_sym_op = prepare_auth_op;
+
+		env.op = env.sym.op;
 		ret = fips_run_sym_test();
 		if (ret < 0)
 			return ret;
-	} else {
-		return fips_run_sym_test();
 	}
 
 	env.op = env.asym.op;
-	if (info.op == FIPS_TEST_ASYM_SIGGEN &&
-		info.algo == FIPS_TEST_ALGO_ECDSA &&
-		info.interim_info.ecdsa_data.pubkey_gen == 1) {
-		fips_prepare_asym_xform_t ecdsa_xform;
-		fips_prepare_op_t ecdsa_op;
-
-		ecdsa_xform = test_ops.prepare_asym_xform;
-		ecdsa_op = test_ops.prepare_asym_op;
-		info.op = FIPS_TEST_ASYM_KEYGEN;
-		test_ops.prepare_asym_xform = prepare_ecfpm_xform;
-		test_ops.prepare_asym_op = prepare_ecfpm_op;
-		ret = fips_run_asym_test();
-		if (ret < 0)
-			return ret;
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		fips_prepare_asym_xform_t old_xform;
+		fips_prepare_op_t old_op;
+
+		old_xform = test_ops.prepare_asym_xform;
+		old_op = test_ops.prepare_asym_op;
+
+		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
+		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
+			test_ops.prepare_asym_op = prepare_ecfpm_op;
 
-		info.post_interim_writeback(NULL);
-		info.interim_info.ecdsa_data.pubkey_gen = 0;
+			ret = fips_run_asym_test();
+			if (ret < 0)
+				return ret;
+
+			info.post_interim_writeback(NULL);
+			info.interim_info.ecdsa_data.pubkey_gen = 0;
 
-		test_ops.prepare_asym_xform = ecdsa_xform;
-		test_ops.prepare_asym_op = ecdsa_op;
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
+				   info.interim_info.eddsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+
+			const struct rte_cryptodev_asymmetric_xform_capability *cap;
+			struct rte_cryptodev_asym_capability_idx cap_idx;
+
+			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+			if (!cap) {
+				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+						env.dev_id);
+				return -EINVAL;
+			}
+
+			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
+				ret = fips_run_asym_test();
+				if (ret < 0)
+					return ret;
+			} else {
+				/* Below is only a workaround by using known keys. */
+				struct rte_crypto_asym_xform xform = {0};
+
+				prepare_edfpm_xform(&xform);
+				prepare_edfpm_op();
+				uint8_t pkey25519[] = {
+					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+				};
+				uint8_t q25519[] = {
+					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+				};
+				uint8_t pkey448[] = {
+					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+					0x01
+				};
+				uint8_t q448[] = {
+					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+					0x00
+				};
+				if (info.interim_info.eddsa_data.curve_id ==
+					RTE_CRYPTO_EC_GROUP_ED25519) {
+					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
+					vec.eddsa.q.len = 32;
+				} else {
+					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
+					vec.eddsa.q.len = 32;
+				}
+			}
+			info.post_interim_writeback(NULL);
+			info.interim_info.eddsa_data.pubkey_gen = 0;
+
+		}
+
+		test_ops.prepare_asym_xform = old_xform;
+		test_ops.prepare_asym_op = old_op;
 		info.op = FIPS_TEST_ASYM_SIGGEN;
 		ret = fips_run_asym_test();
 	} else {
@@ -2536,6 +2779,17 @@ init_test_ops(void)
 			test_ops.test = fips_generic_test;
 		}
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.test = fips_generic_test;
+		} else {
+			test_ops.prepare_asym_op = prepare_eddsa_op;
+			test_ops.prepare_asym_xform = prepare_eddsa_xform;
+			test_ops.test = fips_generic_test;
+		}
+		break;
 	default:
 		if (strstr(info.file_name, "TECB") ||
 				strstr(info.file_name, "TCBC")) {
@@ -2719,6 +2973,9 @@ fips_test_one_test_group(void)
 	case FIPS_TEST_ALGO_ECDSA:
 		ret = parse_test_ecdsa_json_init();
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		ret = parse_test_eddsa_json_init();
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build
index 34d3c7c8ca..7d4e440c6c 100644
--- a/examples/fips_validation/meson.build
+++ b/examples/fips_validation/meson.build
@@ -20,6 +20,7 @@ sources = files(
         'fips_validation_xts.c',
         'fips_validation_rsa.c',
         'fips_validation_ecdsa.c',
+        'fips_validation_eddsa.c',
         'fips_dev_self_test.c',
         'main.c',
 )
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v5 6/6] app/crypto-perf: support EDDSA
  2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                             ` (3 preceding siblings ...)
  2024-10-04  5:30           ` [PATCH v5 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
@ 2024-10-04  5:30           ` Gowrishankar Muthukrishnan
  2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  5:30 UTC (permalink / raw)
  To: dev, Brian Dooley
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Added support for EDDSA 25519 curve SIGN and VERIFY operations.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test-crypto-perf/cperf_ops.c             | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_options.h         |  2 +
 app/test-crypto-perf/cperf_options_parsing.c |  9 +++-
 app/test-crypto-perf/cperf_test_common.c     |  1 +
 app/test-crypto-perf/cperf_test_vectors.c    | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_test_vectors.h    | 10 ++++
 app/test-crypto-perf/main.c                  | 13 +++++
 doc/guides/tools/cryptoperf.rst              |  1 +
 8 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index f139ec5331..220c3acac7 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -67,6 +67,36 @@ cperf_set_ops_asym_ecdsa(struct rte_crypto_op **ops,
 	}
 }
 
+static void
+cperf_set_ops_asym_eddsa(struct rte_crypto_op **ops,
+		   uint32_t src_buf_offset __rte_unused,
+		   uint32_t dst_buf_offset __rte_unused, uint16_t nb_ops,
+		   void *sess,
+		   const struct cperf_options *options,
+		   const struct cperf_test_vector *test_vector __rte_unused,
+		   uint16_t iv_offset __rte_unused,
+		   uint32_t *imix_idx __rte_unused,
+		   uint64_t *tsc_start __rte_unused)
+{
+	uint16_t i;
+
+	for (i = 0; i < nb_ops; i++) {
+		struct rte_crypto_asym_op *asym_op = ops[i]->asym;
+
+		ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		rte_crypto_op_attach_asym_session(ops[i], sess);
+
+		asym_op->eddsa.op_type = options->asym_op_type;
+		asym_op->eddsa.message.data = options->eddsa_data->message.data;
+		asym_op->eddsa.message.length = options->eddsa_data->message.length;
+
+		asym_op->eddsa.instance = options->eddsa_data->instance;
+
+		asym_op->eddsa.sign.data = options->eddsa_data->sign.data;
+		asym_op->eddsa.sign.length = options->eddsa_data->sign.length;
+	}
+}
+
 static void
 cperf_set_ops_asym_sm2(struct rte_crypto_op **ops,
 		   uint32_t src_buf_offset __rte_unused,
@@ -1031,6 +1061,25 @@ cperf_create_session(struct rte_mempool *sess_mp,
 		return asym_sess;
 	}
 
+	if (options->op_type == CPERF_ASYM_ED25519) {
+		xform.next = NULL;
+		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		xform.ec.curve_id = options->eddsa_data->curve;
+		xform.ec.pkey.data = options->eddsa_data->pkey.data;
+		xform.ec.pkey.length = options->eddsa_data->pkey.length;
+		xform.ec.q.x.data = options->eddsa_data->pubkey.data;
+		xform.ec.q.x.length = options->eddsa_data->pubkey.length;
+
+		ret = rte_cryptodev_asym_session_create(dev_id, &xform,
+				sess_mp, &asym_sess);
+		if (ret < 0) {
+			RTE_LOG(ERR, USER1, "EDDSA Asym session create failed\n");
+			return NULL;
+		}
+
+		return asym_sess;
+	}
+
 	if (options->op_type == CPERF_ASYM_SM2) {
 		xform.next = NULL;
 		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
@@ -1354,6 +1403,9 @@ cperf_get_op_functions(const struct cperf_options *options,
 	case CPERF_ASYM_SECP256R1:
 		op_fns->populate_ops = cperf_set_ops_asym_ecdsa;
 		break;
+	case CPERF_ASYM_ED25519:
+		op_fns->populate_ops = cperf_set_ops_asym_eddsa;
+		break;
 	case CPERF_ASYM_SM2:
 		op_fns->populate_ops = cperf_set_ops_asym_sm2;
 		break;
diff --git a/app/test-crypto-perf/cperf_options.h b/app/test-crypto-perf/cperf_options.h
index 131ecfdffb..dbc9f5a97b 100644
--- a/app/test-crypto-perf/cperf_options.h
+++ b/app/test-crypto-perf/cperf_options.h
@@ -89,6 +89,7 @@ enum cperf_op_type {
 	CPERF_IPSEC,
 	CPERF_ASYM_MODEX,
 	CPERF_ASYM_SECP256R1,
+	CPERF_ASYM_ED25519,
 	CPERF_ASYM_SM2,
 	CPERF_TLS,
 };
@@ -169,6 +170,7 @@ struct cperf_options {
 	struct cperf_modex_test_data *modex_data;
 	uint16_t modex_len;
 	struct cperf_ecdsa_test_data *secp256r1_data;
+	struct cperf_eddsa_test_data *eddsa_data;
 	struct cperf_sm2_test_data *sm2_data;
 	enum rte_crypto_asym_op_type asym_op_type;
 	enum rte_crypto_auth_algorithm asym_hash_alg;
diff --git a/app/test-crypto-perf/cperf_options_parsing.c b/app/test-crypto-perf/cperf_options_parsing.c
index c91fcf0479..59ea66c06d 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -38,7 +38,7 @@ usage(char *progname)
 		" --desc-nb N: set number of descriptors for each crypto device\n"
 		" --devtype TYPE: set crypto device type to use\n"
 		" --optype cipher-only / auth-only / cipher-then-auth / auth-then-cipher /\n"
-		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / sm2 / tls-record : set operation type\n"
+		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / eddsa / sm2 / tls-record : set operation type\n"
 		" --sessionless: enable session-less crypto operations\n"
 		" --shared-session: share 1 session across all queue pairs on crypto device\n"
 		" --out-of-place: enable out-of-place crypto operations\n"
@@ -489,6 +489,10 @@ parse_op_type(struct cperf_options *opts, const char *arg)
 			cperf_op_type_strs[CPERF_ASYM_SECP256R1],
 			CPERF_ASYM_SECP256R1
 		},
+		{
+			cperf_op_type_strs[CPERF_ASYM_ED25519],
+			CPERF_ASYM_ED25519
+		},
 		{
 			cperf_op_type_strs[CPERF_ASYM_SM2],
 			CPERF_ASYM_SM2
@@ -1080,6 +1084,7 @@ cperf_options_default(struct cperf_options *opts)
 	opts->modex_data = (struct cperf_modex_test_data *)&modex_perf_data[0];
 
 	opts->secp256r1_data = &secp256r1_perf_data;
+	opts->eddsa_data = &ed25519_perf_data;
 	opts->sm2_data = &sm2_perf_data;
 	opts->asym_op_type = RTE_CRYPTO_ASYM_OP_SIGN;
 }
@@ -1513,7 +1518,7 @@ cperf_options_dump(struct cperf_options *opts)
 	printf("#\n");
 	printf("# number of queue pairs per device: %u\n", opts->nb_qps);
 	printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
-	if (opts->op_type == CPERF_ASYM_SM2 || opts->op_type == CPERF_ASYM_SECP256R1)
+	if (cperf_is_asym_test(opts))
 		printf("# asym operation type: %s\n",
 				rte_crypto_asym_op_strings[opts->asym_op_type]);
 	printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
diff --git a/app/test-crypto-perf/cperf_test_common.c b/app/test-crypto-perf/cperf_test_common.c
index 33bee43c93..9c287665a4 100644
--- a/app/test-crypto-perf/cperf_test_common.c
+++ b/app/test-crypto-perf/cperf_test_common.c
@@ -307,6 +307,7 @@ cperf_is_asym_test(const struct cperf_options *options)
 {
 	if (options->op_type == CPERF_ASYM_MODEX ||
 	    options->op_type == CPERF_ASYM_SECP256R1 ||
+	    options->op_type == CPERF_ASYM_ED25519 ||
 	    options->op_type == CPERF_ASYM_SM2)
 		return true;
 
diff --git a/app/test-crypto-perf/cperf_test_vectors.c b/app/test-crypto-perf/cperf_test_vectors.c
index 19c56b46bd..64720d50c3 100644
--- a/app/test-crypto-perf/cperf_test_vectors.c
+++ b/app/test-crypto-perf/cperf_test_vectors.c
@@ -853,6 +853,35 @@ static uint8_t secp256r1_message[] = {
 	0xdb, 0xc4, 0xe7, 0xa6, 0xa1, 0x33, 0xec, 0x56
 };
 
+static uint8_t ed25519_pkey[] = {
+	0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+	0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+	0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+	0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+};
+
+static uint8_t ed25519_pubkey[] = {
+	0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+	0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+	0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+	0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+};
+
+static uint8_t ed25519_sign[] = {
+	0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+	0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+	0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+	0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+	0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+	0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+	0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+	0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+};
+
+static uint8_t ed25519_message[] = {
+	0x72
+};
+
 static uint8_t fp256_pkey[] = {
 	0x77, 0x84, 0x35, 0x65, 0x4c, 0x7a, 0x6d, 0xb1,
 	0x1e, 0x63, 0x0b, 0x41, 0x97, 0x36, 0x04, 0xf4,
@@ -1365,6 +1394,29 @@ cperf_ecdsa_test_data secp256r1_perf_data = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP256R1
 };
 
+/** EDDSA 25519 elliptic curve test params */
+struct
+cperf_eddsa_test_data ed25519_perf_data = {
+	.pubkey = {
+		.data = ed25519_pubkey,
+		.length = sizeof(ed25519_pubkey),
+	},
+	.pkey = {
+		.data = ed25519_pkey,
+		.length = sizeof(ed25519_pkey),
+	},
+	.sign = {
+		.data = ed25519_sign,
+		.length = sizeof(ed25519_sign),
+	},
+	.message = {
+		.data = ed25519_message,
+		.length = sizeof(ed25519_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+};
+
 /** SM2 Fp256 elliptic curve test params */
 struct
 cperf_sm2_test_data sm2_perf_data = {
diff --git a/app/test-crypto-perf/cperf_test_vectors.h b/app/test-crypto-perf/cperf_test_vectors.h
index d46cbbc2c8..f83a17c176 100644
--- a/app/test-crypto-perf/cperf_test_vectors.h
+++ b/app/test-crypto-perf/cperf_test_vectors.h
@@ -118,6 +118,15 @@ struct cperf_ecdsa_test_data {
 	int curve;
 };
 
+struct cperf_eddsa_test_data {
+	rte_crypto_param pubkey;
+	rte_crypto_param pkey;
+	rte_crypto_param sign;
+	rte_crypto_param message;
+	int curve;
+	int instance;
+};
+
 struct cperf_sm2_test_data {
 	rte_crypto_param pubkey_qx;
 	rte_crypto_param pubkey_qy;
@@ -147,6 +156,7 @@ extern uint8_t digest[2048];
 
 extern struct cperf_modex_test_data modex_perf_data[10];
 extern struct cperf_ecdsa_test_data secp256r1_perf_data;
+extern struct cperf_eddsa_test_data ed25519_perf_data;
 extern struct cperf_sm2_test_data sm2_perf_data;
 
 #endif
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 75810dbf0b..d93b30bcaa 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -46,6 +46,7 @@ const char *cperf_op_type_strs[] = {
 	[CPERF_IPSEC] = "ipsec",
 	[CPERF_ASYM_MODEX] = "modex",
 	[CPERF_ASYM_SECP256R1] = "ecdsa_p256r1",
+	[CPERF_ASYM_ED25519] = "eddsa_25519",
 	[CPERF_ASYM_SM2] = "sm2",
 	[CPERF_TLS] = "tls-record"
 };
@@ -227,6 +228,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
 
 		switch (opts->op_type) {
 		case CPERF_ASYM_SECP256R1:
+		case CPERF_ASYM_ED25519:
 		case CPERF_ASYM_SM2:
 		case CPERF_ASYM_MODEX:
 			conf.ff_disable |= (RTE_CRYPTODEV_FF_SECURITY |
@@ -382,6 +384,17 @@ cperf_verify_devices_capabilities(struct cperf_options *opts,
 			}
 		}
 
+		if (opts->op_type == CPERF_ASYM_ED25519) {
+			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
+			if (asym_capability == NULL)
+				return -1;
+
+			if (!rte_cryptodev_asym_xform_capability_check_optype(asym_capability,
+						opts->asym_op_type))
+				return -1;
+		}
+
 		if (opts->op_type == CPERF_ASYM_SM2) {
 			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_SM2;
 			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst
index 0510a3bb89..9a20a73f03 100644
--- a/doc/guides/tools/cryptoperf.rst
+++ b/doc/guides/tools/cryptoperf.rst
@@ -176,6 +176,7 @@ The following are the application command-line options:
            docsis
            modex
            ecdsa_p256r1
+           eddsa_25519
            sm2
            ipsec
            tls-record
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                             ` (4 preceding siblings ...)
  2024-10-04  5:30           ` [PATCH v5 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
@ 2024-10-04  8:26           ` Gowrishankar Muthukrishnan
  2024-10-04  8:26             ` [PATCH v6 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
                               ` (5 more replies)
  5 siblings, 6 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  8:26 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, jerinj, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Gowrishankar Muthukrishnan

Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
https://datatracker.ietf.org/doc/html/rfc8032

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
 lib/cryptodev/rte_crypto_asym.h            | 47 ++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index f411d4bab7..3073753911 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -130,6 +130,7 @@ ECDSA                   =
 ECPM                    =
 ECDH                    =
 SM2                     =
+EDDSA                   =
 
 ;
 ; Supported Operating systems of a default crypto driver.
diff --git a/doc/guides/prog_guide/cryptodev_lib.rst b/doc/guides/prog_guide/cryptodev_lib.rst
index 2b513bbf82..dd636ba5ef 100644
--- a/doc/guides/prog_guide/cryptodev_lib.rst
+++ b/doc/guides/prog_guide/cryptodev_lib.rst
@@ -927,7 +927,7 @@ Asymmetric Cryptography
 The cryptodev library currently provides support for the following asymmetric
 Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman and
 Elliptic Curve Diffie-Hellman public and/or private key generation and shared
-secret compute, DSA Signature generation and verification.
+secret compute, DSA and EdDSA Signature generation and verification.
 
 Session and Session Management
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
index 39d3da3952..fe4194c184 100644
--- a/lib/cryptodev/rte_crypto_asym.h
+++ b/lib/cryptodev/rte_crypto_asym.h
@@ -49,6 +49,10 @@ rte_crypto_asym_op_strings[];
  * and if the flag is not set, shared secret will be padded to the left with
  * zeros to the size of the underlying algorithm (default)
  */
+#define RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED		RTE_BIT32(2)
+/**<
+ * Flag to denote public key will be returned in compressed form
+ */
 
 /**
  * List of elliptic curves. This enum aligns with
@@ -65,9 +69,22 @@ enum rte_crypto_curve_id {
 	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
 	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
 	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
+	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
+	RTE_CRYPTO_EC_GROUP_ED448     = 30,
 	RTE_CRYPTO_EC_GROUP_SM2       = 41,
 };
 
+/**
+ * List of Edwards curve instances as per RFC 8032 (Section 5).
+ */
+enum rte_crypto_edward_instance {
+	RTE_CRYPTO_EDCURVE_25519,
+	RTE_CRYPTO_EDCURVE_25519CTX,
+	RTE_CRYPTO_EDCURVE_25519PH,
+	RTE_CRYPTO_EDCURVE_448,
+	RTE_CRYPTO_EDCURVE_448PH
+};
+
 /**
  * Asymmetric crypto transformation types.
  * Each xform type maps to one asymmetric algorithm
@@ -119,6 +136,10 @@ enum rte_crypto_asym_xform_type {
 	 * Performs Encrypt, Decrypt, Sign and Verify.
 	 * Refer to rte_crypto_asym_op_type.
 	 */
+	RTE_CRYPTO_ASYM_XFORM_EDDSA,
+	/**< Edwards Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -585,6 +606,31 @@ struct rte_crypto_ecdsa_op_param {
 	 */
 };
 
+/**
+ * EdDSA operation params
+ */
+struct rte_crypto_eddsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param message;
+	/**< Input message digest to be signed or verified */
+
+	rte_crypto_param context;
+	/**< Context value for the sign op.
+	 *   Must not be empty for Ed25519ctx instance.
+	 */
+
+	enum rte_crypto_edward_instance instance;
+	/**< Type of Edwards curve. */
+
+	rte_crypto_uint sign;
+	/**< Edward curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
 /**
  * Structure for EC point multiplication operation param
  */
@@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_ecdsa_op_param ecdsa;
 		struct rte_crypto_ecpm_op_param ecpm;
 		struct rte_crypto_sm2_op_param sm2;
+		struct rte_crypto_eddsa_op_param eddsa;
 	};
 	uint16_t flags;
 	/**<
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v6 2/6] crypto/openssl: support EDDSA
  2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
@ 2024-10-04  8:26             ` Gowrishankar Muthukrishnan
  2024-10-07  9:50               ` Ji, Kai
  2024-10-07 16:27               ` Kusztal, ArkadiuszX
  2024-10-04  8:26             ` [PATCH v6 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
                               ` (4 subsequent siblings)
  5 siblings, 2 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  8:26 UTC (permalink / raw)
  To: dev, Kai Ji
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in OpenSSL PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/openssl.ini   |   1 +
 drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
 drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
 4 files changed, 368 insertions(+)

diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index b64c8ec4a5..0540c075dc 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -66,6 +66,7 @@ Modular Exponentiation = Y
 Modular Inversion = Y
 Diffie-hellman = Y
 SM2 = Y
+EDDSA = Y
 
 ;
 ; Supported Operating systems of the 'openssl' crypto driver.
diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index 0282b3d829..7dd97f1c72 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -231,10 +231,23 @@ struct __rte_cache_aligned openssl_asym_session {
 #endif
 		} s;
 		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			EC_GROUP * group;
+			BIGNUM *priv_key;
+#endif
+		} ec;
+		struct {
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 			OSSL_PARAM * params;
 #endif
 		} sm2;
+		struct {
+			uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+			OSSL_PARAM * params;
+#endif
+		} eddsa;
 	} u;
 };
 /** Set and validate OPENSSL crypto session parameters */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index e10a172f46..4e4d06403b 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2849,6 +2849,45 @@ process_openssl_rsa_op_evp(struct rte_crypto_op *cop,
 
 }
 
+static int
+process_openssl_ecfpm_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	const EC_GROUP *ecgrp = sess->u.ec.group;
+	EC_POINT *ecpt = NULL;
+	BN_CTX *ctx = NULL;
+	BIGNUM *n = NULL;
+	int ret = -1;
+
+	n = BN_bin2bn((const unsigned char *)
+			cop->asym->ecpm.scalar.data,
+			cop->asym->ecpm.scalar.length,
+			BN_new());
+
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto err_ecfpm;
+
+	if (!EC_POINT_mul(ecgrp, ecpt, n, NULL, NULL, ctx))
+		goto err_ecfpm;
+
+	if (cop->asym->flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED) {
+		unsigned char *buf = cop->asym->ecpm.r.x.data;
+		size_t sz;
+
+		sz = EC_POINT_point2oct(ecgrp, ecpt, POINT_CONVERSION_COMPRESSED, buf, 0, ctx);
+		if (!sz)
+			goto err_ecfpm;
+
+		cop->asym->ecpm.r.x.length = sz;
+	}
+
+err_ecfpm:
+	BN_CTX_free(ctx);
+	BN_free(n);
+	return ret;
+}
+
 static int
 process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3074,6 +3113,158 @@ process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
 	return ret;
 }
 
+static int
+process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	static const char * const instance[] = {"Ed25519", "Ed25519ctx", "Ed25519ph",
+						"Ed448", "Ed448ph"};
+	EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
+	const uint8_t curve_id = sess->u.eddsa.curve_id;
+	struct rte_crypto_asym_op *op = cop->asym;
+	OSSL_PARAM *params = sess->u.eddsa.params;
+	OSSL_PARAM_BLD *iparam_bld = NULL;
+	OSSL_PARAM *iparams = NULL;
+	uint8_t signbuf[128] = {0};
+	EVP_MD_CTX *md_ctx = NULL;
+	EVP_PKEY *pkey = NULL;
+	size_t signlen;
+	int ret = -1;
+
+	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	iparam_bld = OSSL_PARAM_BLD_new();
+	if (!iparam_bld)
+		goto err_eddsa;
+
+	if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519CTX) {
+		OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-string",
+			op->eddsa.context.data, op->eddsa.context.length);
+
+	}
+
+	OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
+		instance[op->eddsa.instance], strlen(instance[op->eddsa.instance]));
+
+	iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
+	if (!iparams)
+		goto err_eddsa;
+
+	switch (op->eddsa.op_type) {
+	case RTE_CRYPTO_ASYM_OP_SIGN:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			if (!EVP_DigestSign(md_ctx, NULL, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			if (signlen > RTE_DIM(signbuf))
+				goto err_eddsa;
+
+			if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op->eddsa.message.data,
+					op->eddsa.message.length))
+				goto err_eddsa;
+
+			memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
+			op->eddsa.sign.length = signlen;
+		}
+		break;
+	case RTE_CRYPTO_ASYM_OP_VERIFY:
+		{
+			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+			else
+				kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+				EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+				goto err_eddsa;
+
+			md_ctx = EVP_MD_CTX_new();
+			if (!md_ctx)
+				goto err_eddsa;
+
+			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+			if (!sctx)
+				goto err_eddsa;
+
+			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+			if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+				goto err_eddsa;
+#else
+			if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+				op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+				if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey))
+					goto err_eddsa;
+			} else
+				goto err_eddsa;
+#endif
+
+			signlen = op->eddsa.sign.length;
+			memcpy(&signbuf[0], op->eddsa.sign.data, op->eddsa.sign.length);
+
+			ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op->eddsa.message.data,
+					op->eddsa.message.length);
+			if (ret == 0)
+				goto err_eddsa;
+		}
+		break;
+	default:
+		/* allow ops with invalid args to be pushed to
+		 * completion queue
+		 */
+		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		goto err_eddsa;
+	}
+
+	ret = 0;
+	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+err_eddsa:
+	OSSL_PARAM_BLD_free(iparam_bld);
+
+	if (sctx)
+		EVP_PKEY_CTX_free(sctx);
+
+	if (cctx)
+		EVP_PKEY_CTX_free(cctx);
+
+	if (pkey)
+		EVP_PKEY_free(pkey);
+
+	return ret;
+}
 #else
 static int
 process_openssl_rsa_op(struct rte_crypto_op *cop,
@@ -3174,6 +3365,15 @@ process_openssl_rsa_op(struct rte_crypto_op *cop,
 	return 0;
 }
 
+static int
+process_openssl_ecfpm_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
+
 static int
 process_openssl_sm2_op(struct rte_crypto_op *cop,
 		struct openssl_asym_session *sess)
@@ -3182,6 +3382,15 @@ process_openssl_sm2_op(struct rte_crypto_op *cop,
 	RTE_SET_USED(sess);
 	return -ENOTSUP;
 }
+
+static int
+process_openssl_eddsa_op(struct rte_crypto_op *cop,
+		struct openssl_asym_session *sess)
+{
+	RTE_SET_USED(cop);
+	RTE_SET_USED(sess);
+	return -ENOTSUP;
+}
 #endif
 
 static int
@@ -3230,6 +3439,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 				process_openssl_dsa_verify_op(op, sess);
 		else
 			op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_ecfpm_op_evp(op, sess);
+#else
+		retval = process_openssl_ecfpm_op(op, sess);
 #endif
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
@@ -3237,6 +3453,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
 		retval = process_openssl_sm2_op_evp(op, sess);
 #else
 		retval = process_openssl_sm2_op(op, sess);
+#endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		retval = process_openssl_eddsa_op_evp(op, sess);
+#else
+		retval = process_openssl_eddsa_op(op, sess);
 #endif
 		break;
 	default:
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index b7b612fc57..0725184653 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -593,6 +593,16 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		},
 		}
 	},
+	{	/* ECFPM */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM,
+				.op_types = 0
+				}
+			}
+		}
+	},
 	{	/* SM2 */
 		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
 		{.asym = {
@@ -610,6 +620,20 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
 		}
 		}
 	},
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types =
+				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
+				 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+			}
+		}
+		}
+	},
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1356,6 +1380,47 @@ static int openssl_set_asym_session_parameters(
 		BN_free(pub_key);
 		return -1;
 	}
+	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+		EC_GROUP *ecgrp = NULL;
+
+		asym_session->xfrm_type = xform->xform_type;
+
+		switch (xform->ec.curve_id) {
+		case RTE_CRYPTO_EC_GROUP_SECP192R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp192k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP224R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp224r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP256R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP384R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp384r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_SECP521R1:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_secp521r1);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED25519:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED25519);
+			break;
+		case RTE_CRYPTO_EC_GROUP_ED448:
+			ecgrp = EC_GROUP_new_by_curve_name(NID_ED448);
+			break;
+		default:
+			break;
+		}
+
+		asym_session->u.ec.curve_id = xform->ec.curve_id;
+		asym_session->u.ec.group = ecgrp;
+		break;
+#else
+		OPENSSL_LOG(WARNING, "ECFPM unsupported for OpenSSL Version < 3.0");
+		return -ENOTSUP;
+#endif
+	}
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 	{
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
@@ -1440,6 +1505,66 @@ static int openssl_set_asym_session_parameters(
 #else
 		OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL Version < 3.0");
 		return -ENOTSUP;
+#endif
+	}
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+	{
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+		OSSL_PARAM_BLD *param_bld = NULL;
+		OSSL_PARAM *params = NULL;
+		int ret = -1;
+
+		asym_session->u.eddsa.curve_id = xform->ec.curve_id;
+
+		param_bld = OSSL_PARAM_BLD_new();
+		if (!param_bld) {
+			OPENSSL_LOG(ERR, "failed to allocate params");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+			  OSSL_PKEY_PARAM_GROUP_NAME, "ED25519", sizeof("ED25519"));
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PRIV_KEY,
+				xform->ec.pkey.data, xform->ec.pkey.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params");
+			goto err_eddsa;
+		}
+
+		ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
+				xform->ec.q.x.data, xform->ec.q.x.length);
+		if (!ret) {
+			OPENSSL_LOG(ERR, "failed to push params");
+			goto err_eddsa;
+		}
+
+		params = OSSL_PARAM_BLD_to_param(param_bld);
+		if (!params) {
+			OPENSSL_LOG(ERR, "failed to push params");
+			goto err_eddsa;
+		}
+
+		asym_session->u.eddsa.params = params;
+		OSSL_PARAM_BLD_free(param_bld);
+
+		asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		break;
+err_eddsa:
+		if (param_bld)
+			OSSL_PARAM_BLD_free(param_bld);
+
+		if (asym_session->u.eddsa.params)
+			OSSL_PARAM_free(asym_session->u.eddsa.params);
+
+		return -1;
+#else
+		OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL Version < 3.3");
+		return -ENOTSUP;
 #endif
 	}
 	default:
@@ -1538,6 +1663,12 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
 		OSSL_PARAM_free(sess->u.sm2.params);
 #endif
+		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+		OSSL_PARAM_free(sess->u.eddsa.params);
+#endif
+		break;
 	default:
 		break;
 	}
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v6 3/6] crypto/cnxk: support EDDSA
  2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-10-04  8:26             ` [PATCH v6 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
@ 2024-10-04  8:26             ` Gowrishankar Muthukrishnan
  2024-10-04  8:26             ` [PATCH v6 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
                               ` (3 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  8:26 UTC (permalink / raw)
  To: dev, Ankur Dwivedi, Anoob Joseph, Tejasree Kondoj,
	Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori, Satha Rao,
	Harman Kalra
  Cc: bruce.richardson, jerinj, fanzhang.oss, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Akhil Goyal, Gowrishankar Muthukrishnan

Support EDDSA crypto algorithm in CNXK PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/cn10k.ini      |   1 +
 drivers/common/cnxk/hw/cpt.h                  |   3 +-
 drivers/common/cnxk/roc_ae.c                  |  52 +-
 drivers/common/cnxk/roc_ae.h                  |  10 +
 drivers/common/cnxk/roc_ae_fpm_tables.c       | 580 +++++++++++++++++-
 drivers/crypto/cnxk/cnxk_ae.h                 | 455 +++++++++++++-
 drivers/crypto/cnxk/cnxk_cryptodev.h          |   2 +-
 .../crypto/cnxk/cnxk_cryptodev_capabilities.c |  19 +
 drivers/crypto/cnxk/cnxk_cryptodev_ops.c      |   2 +-
 drivers/crypto/cnxk/cnxk_cryptodev_ops.h      |   2 +
 10 files changed, 1112 insertions(+), 14 deletions(-)

diff --git a/doc/guides/cryptodevs/features/cn10k.ini b/doc/guides/cryptodevs/features/cn10k.ini
index 39f4b56b9f..bb7d265005 100644
--- a/doc/guides/cryptodevs/features/cn10k.ini
+++ b/doc/guides/cryptodevs/features/cn10k.ini
@@ -107,6 +107,7 @@ ECDH                    = Y
 ECDSA                   = Y
 ECPM                    = Y
 SM2                     = Y
+EDDSA                   = Y
 
 ;
 ; Supported Operating systems of the 'cn10k' crypto driver.
diff --git a/drivers/common/cnxk/hw/cpt.h b/drivers/common/cnxk/hw/cpt.h
index 2620965606..47df3fbf9f 100644
--- a/drivers/common/cnxk/hw/cpt.h
+++ b/drivers/common/cnxk/hw/cpt.h
@@ -81,7 +81,8 @@ union cpt_eng_caps {
 		uint64_t __io sm2 : 1;
 		uint64_t __io pdcp_chain_zuc256 : 1;
 		uint64_t __io tls : 1;
-		uint64_t __io reserved_39_63 : 25;
+		uint64_t __io eddsa : 1;
+		uint64_t __io reserved_40_63 : 24;
 	};
 };
 
diff --git a/drivers/common/cnxk/roc_ae.c b/drivers/common/cnxk/roc_ae.c
index 7ef0efe2b3..2c563c30de 100644
--- a/drivers/common/cnxk/roc_ae.c
+++ b/drivers/common/cnxk/roc_ae.c
@@ -179,7 +179,57 @@ const struct roc_ae_ec_group ae_ec_grp[ROC_AE_EC_ID_PMAX] = {
 				    0xAB, 0x8F, 0x92, 0xDD, 0xBC, 0xBD, 0x41,
 				    0x4D, 0x94, 0x0E, 0x93},
 			   .length = 32},
-	}};
+	},
+	{
+		.prime = {.data = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0x7F},
+			  .length = 32},
+		.order = {.data = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12,
+				   0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9,
+				   0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				   0x00, 0x00, 0x00, 0x10},
+			  .length = 32},
+		.consta = {.data = {0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb,
+				    0x75, 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a,
+				    0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79,
+				    0x40, 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b,
+				    0xee, 0x6c, 0x03, 0x52},
+			   .length = 32},
+	},
+	{
+		.prime = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			  .length = 56},
+		.order = {.data = {0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78,
+				   0x23, 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2,
+				   0x6c, 0x21, 0x90, 0x36, 0xd6, 0xae, 0x49,
+				   0xdb, 0x4e, 0xc4, 0xe9, 0x23, 0xca, 0x7c,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f},
+			  .length = 56},
+		.consta = {.data = {0x56, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+			   .length = 56},
+	},
+};
 
 int
 roc_ae_ec_grp_get(struct roc_ae_ec_group **tbl)
diff --git a/drivers/common/cnxk/roc_ae.h b/drivers/common/cnxk/roc_ae.h
index 7886b9d107..6595f22754 100644
--- a/drivers/common/cnxk/roc_ae.h
+++ b/drivers/common/cnxk/roc_ae.h
@@ -12,6 +12,7 @@
 #define ROC_AE_MAJOR_OP_MODEX	     0x03
 #define ROC_AE_MAJOR_OP_EC	     0x04
 #define ROC_AE_MAJOR_OP_ECC	     0x05
+#define ROC_AE_MAJOR_OP_EDDSA	     0x0A
 #define ROC_AE_MINOR_OP_RANDOM	     0x00
 #define ROC_AE_MINOR_OP_MODEX	     0x01
 #define ROC_AE_MINOR_OP_PKCS_ENC     0x02
@@ -23,6 +24,9 @@
 #define ROC_AE_MINOR_OP_EC_VERIFY    0x02
 #define ROC_AE_MINOR_OP_ECC_UMP	     0x03
 #define ROC_AE_MINOR_OP_ECC_FPM	     0x04
+#define ROC_AE_MINOR_OP_ED_SIGN      0x00
+#define ROC_AE_MINOR_OP_ED_VERIFY    0x01
+#define ROC_AE_MINOR_OP_ED_KEYGEN    0x02
 
 /**
  * Enumeration roc_ae_ec_id
@@ -39,6 +43,8 @@ typedef enum {
 	ROC_AE_EC_ID_P320 = 6,
 	ROC_AE_EC_ID_P512 = 7,
 	ROC_AE_EC_ID_SM2  = 8,
+	ROC_AE_EC_ID_ED25519 = 9,
+	ROC_AE_EC_ID_ED448 = 10,
 	ROC_AE_EC_ID_PMAX
 } roc_ae_ec_id;
 
@@ -47,6 +53,10 @@ typedef enum {
 #define ROC_AE_EC_PARAM1_SM2       (1 << 7)
 #define ROC_AE_EC_PARAM1_NIST      (0 << 6)
 #define ROC_AE_EC_PARAM1_NONNIST   (1 << 6)
+#define ROC_AE_ED_PARAM1_25519     (1 << 1)
+#define ROC_AE_ED_PARAM1_448       (1 << 3)
+#define ROC_AE_ED_PARAM1_KEYGEN_BIT      4
+#define ROC_AE_EC_PARAM1_PH_BIT          5
 
 typedef enum {
 	ROC_AE_ERR_ECC_PAI = 0x0b,
diff --git a/drivers/common/cnxk/roc_ae_fpm_tables.c b/drivers/common/cnxk/roc_ae_fpm_tables.c
index 942657b56a..9dcf60ef03 100644
--- a/drivers/common/cnxk/roc_ae_fpm_tables.c
+++ b/drivers/common/cnxk/roc_ae_fpm_tables.c
@@ -21,7 +21,9 @@ typedef enum {
 	AE_FPM_P224_LEN = 2160,
 	AE_FPM_P256_LEN = 2160,
 	AE_FPM_P384_LEN = 2520,
-	AE_FPM_P521_LEN = 3240
+	AE_FPM_P521_LEN = 3240,
+	AE_FPM_ED25519_LEN = 2880,
+	AE_FPM_ED448_LEN = 3840,
 } ae_fpm_len;
 
 /* FPM table address and length */
@@ -1240,6 +1242,572 @@ const uint8_t ae_fpm_tbl_p256_sm2[AE_FPM_P256_LEN] = {
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
+const uint8_t ae_fpm_tbl_ed25519[AE_FPM_ED25519_LEN] = {
+	0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a, 0x69, 0x2c, 0xc7, 0x60,
+	0x95, 0x25, 0xa7, 0xb2, 0xc0, 0xa4, 0xe2, 0x31, 0xfd, 0xd6, 0xdc, 0x5c,
+	0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6d, 0xde, 0x8a, 0xb3, 0xa5, 0xb7, 0xdd, 0xa3, 0x20, 0xf0, 0x9f, 0x80,
+	0x77, 0x51, 0x52, 0xf5, 0x66, 0xea, 0x4e, 0x8e, 0x64, 0xab, 0xe3, 0x7d,
+	0x67, 0x87, 0x5f, 0x0f, 0xd7, 0x8b, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x18, 0xc0, 0x0c, 0x55, 0x07, 0xed, 0xf1, 0x0d, 0x69, 0xbe, 0x61, 0x3a,
+	0x4f, 0x82, 0xd2, 0xc4, 0x3e, 0xf0, 0xa1, 0x4e, 0xf1, 0xba, 0xd8, 0xb1,
+	0x5a, 0x8a, 0x5a, 0x58, 0xbe, 0xf1, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x63, 0xce, 0x54, 0x79, 0x0e, 0x45, 0x3f, 0x73, 0xe9, 0x33, 0xff, 0xc7,
+	0xec, 0xab, 0xc7, 0x4b, 0x6b, 0x43, 0x64, 0x02, 0x45, 0xcf, 0x64, 0xfa,
+	0x1a, 0xd2, 0xdd, 0x57, 0x64, 0x55, 0xf6, 0x78, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x8c, 0x9d, 0x04, 0xac, 0x84, 0x05, 0xe0, 0xe7, 0xa5, 0x17, 0x56,
+	0x92, 0x2e, 0xbd, 0x07, 0x96, 0x72, 0x74, 0xa7, 0xd8, 0x1d, 0x8d, 0x30,
+	0x42, 0x4d, 0xa3, 0xd2, 0x15, 0xae, 0xf3, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x19, 0xcf, 0x23, 0xc1, 0x1f, 0x40, 0x15, 0x86, 0x4d, 0xd5, 0x99, 0x64,
+	0x9b, 0x94, 0x9e, 0x8e, 0x22, 0x68, 0xc6, 0xcf, 0xf4, 0xe4, 0xf9, 0xd9,
+	0x75, 0xe4, 0xce, 0xc7, 0xf1, 0xc8, 0x41, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x98, 0x8c, 0x87, 0x10, 0xcd, 0x87, 0x55, 0x95, 0x52, 0x83, 0xad, 0xc1,
+	0x83, 0x92, 0xcf, 0xa4, 0x28, 0x4a, 0x93, 0xe5, 0x21, 0x53, 0xaa, 0x3d,
+	0x33, 0x97, 0x60, 0xe6, 0xcb, 0xdc, 0xf5, 0xd4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe6, 0xf2, 0x50, 0x1e, 0x50, 0x14, 0x12, 0xd8, 0x45, 0xcc, 0xd0, 0xd4,
+	0x75, 0x78, 0xec, 0xae, 0x42, 0x10, 0x45, 0x12, 0x74, 0x2b, 0x26, 0xde,
+	0x41, 0xea, 0x80, 0x41, 0x7f, 0xb3, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x75, 0x61, 0x33, 0xad, 0x0c, 0x22, 0xe4, 0x7f, 0xd7, 0x18, 0xb3,
+	0xf9, 0xd3, 0x55, 0x9e, 0x96, 0x2d, 0xa3, 0xfa, 0x7d, 0xfb, 0x1e, 0xb6,
+	0x4e, 0xd0, 0xb6, 0x26, 0xa7, 0x32, 0x09, 0x87, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaf, 0x7f, 0xd1, 0x3e, 0xfe, 0xa5, 0xa5, 0x96, 0x3c, 0x42, 0xec, 0x0e,
+	0xef, 0x69, 0x4e, 0x62, 0xf5, 0xb9, 0xc2, 0xad, 0x65, 0x7b, 0x91, 0x6f,
+	0x25, 0x55, 0x0a, 0xc3, 0x9c, 0xfb, 0x1a, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2a, 0xf9, 0xfb, 0x16, 0x90, 0xe8, 0x72, 0x7e, 0x98, 0x92, 0x1f, 0xc5,
+	0x97, 0x96, 0xc5, 0x0c, 0x8a, 0x12, 0x0b, 0xf3, 0x98, 0xc0, 0x5f, 0x4d,
+	0x38, 0x56, 0x94, 0x41, 0xa1, 0xf5, 0xcd, 0x40, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0x39, 0xdb, 0x96, 0xf7, 0x8d, 0x2e, 0x7c, 0xb1, 0xc0, 0x51, 0x3b,
+	0xa4, 0xc4, 0x55, 0x12, 0x75, 0x29, 0xd9, 0x29, 0x65, 0x02, 0x36, 0x8d,
+	0x0a, 0x97, 0xdf, 0xad, 0x58, 0xfa, 0x26, 0x19, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0x4b, 0xb5, 0xe5, 0x13, 0xa5, 0x45, 0x40, 0x2c, 0xba, 0x4d, 0x3b,
+	0x1e, 0x5f, 0x55, 0xb8, 0x04, 0xa2, 0xce, 0x24, 0x52, 0x7e, 0xb7, 0x3c,
+	0x78, 0xd9, 0x8e, 0xba, 0xc3, 0x3b, 0xd9, 0x46, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb2, 0x1d, 0x1e, 0x95, 0xfb, 0x8d, 0x9a, 0xdd, 0xdb, 0xfc, 0xa8, 0xca,
+	0x0f, 0x51, 0x54, 0x75, 0x72, 0x53, 0xc9, 0xca, 0xe4, 0x6b, 0x0a, 0x2f,
+	0x3d, 0xc4, 0xd8, 0x0a, 0x0c, 0x80, 0x9a, 0xb6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0xc6, 0x8e, 0xea, 0x63, 0xb3, 0x17, 0x45, 0x1b, 0xc9, 0x4f, 0xf2,
+	0xb9, 0xce, 0xab, 0x28, 0x84, 0x84, 0x27, 0x82, 0x6e, 0x59, 0x5d, 0x0d,
+	0x57, 0x1c, 0xd9, 0x4b, 0x55, 0xf8, 0xa2, 0xd1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x76, 0xd4, 0x7d, 0xa8, 0x8a, 0xfd, 0x34, 0xf3, 0x5e, 0xa7, 0x1b, 0x7c,
+	0x94, 0x84, 0x05, 0x81, 0x7f, 0x9d, 0x55, 0x08, 0x06, 0x03, 0x5e, 0x42,
+	0x42, 0xe8, 0x55, 0x9a, 0xac, 0x90, 0x41, 0xf2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x74, 0xd2, 0x01, 0x61, 0xc0, 0x1f, 0x88, 0x8b, 0xcb, 0xca, 0xf5, 0xd3,
+	0x63, 0x58, 0x4b, 0xbb, 0x66, 0xc6, 0x4e, 0xab, 0x8c, 0x6c, 0x68, 0x22,
+	0x66, 0xca, 0x84, 0x72, 0x7e, 0x3c, 0x0b, 0xa2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0x0b, 0xdb, 0xf8, 0x8a, 0x48, 0x29, 0x71, 0x03, 0xf7, 0xcf, 0x4d,
+	0xb1, 0x85, 0x7a, 0x22, 0x97, 0xbe, 0x2e, 0xd9, 0xa1, 0xee, 0x20, 0x13,
+	0x2f, 0x5e, 0x07, 0xda, 0x24, 0x97, 0xb3, 0x43, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xec, 0x5e, 0x68, 0xad, 0xfe, 0x26, 0x70, 0x65, 0xfa, 0x03, 0x3f, 0x24,
+	0x56, 0xa2, 0x51, 0xc9, 0x79, 0x88, 0x89, 0x08, 0x86, 0x02, 0x18, 0x39,
+	0x59, 0x77, 0x53, 0x1b, 0xf7, 0x2c, 0x65, 0x3c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x23, 0xb1, 0xc4, 0x4d, 0xad, 0xf1, 0xae, 0x7a, 0x52, 0xba, 0x48,
+	0xd0, 0x0a, 0xc1, 0x94, 0x34, 0x41, 0x1b, 0x3d, 0x93, 0x49, 0xf0, 0x8d,
+	0x25, 0xf2, 0x72, 0x56, 0xd7, 0xb7, 0x05, 0x81, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf8, 0x05, 0x2c, 0x85, 0xc5, 0x52, 0xad, 0x02, 0xbd, 0xb7, 0x5d, 0x21,
+	0xcd, 0xbd, 0xce, 0x01, 0xd3, 0xd9, 0x12, 0xba, 0xc6, 0x7f, 0x45, 0x31,
+	0x00, 0x33, 0x8c, 0x20, 0x63, 0x4d, 0xf5, 0x22, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1a, 0x38, 0xa7, 0xf1, 0x5b, 0xd0, 0xb8, 0x54, 0x3c, 0x33, 0x27, 0x32,
+	0xca, 0x04, 0x38, 0x5e, 0xa0, 0xf8, 0x81, 0x06, 0xa0, 0xe7, 0x47, 0x1d,
+	0x16, 0xcb, 0xaa, 0x68, 0xb5, 0x6a, 0xd2, 0xaa, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3e, 0x69, 0x14, 0xef, 0xc0, 0x82, 0x94, 0x72, 0x09, 0x07, 0xb5, 0xa6,
+	0x98, 0x1d, 0xb2, 0xd7, 0xcb, 0xe4, 0x6c, 0xb7, 0x88, 0x78, 0x8b, 0xd9,
+	0x34, 0x5a, 0xdb, 0xae, 0x55, 0x6a, 0x6b, 0x1f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf1, 0x20, 0x49, 0xc6, 0xda, 0x47, 0x7a, 0x25, 0x9e, 0xce, 0xf6, 0x2e,
+	0xd4, 0x76, 0xb6, 0x0f, 0x41, 0x54, 0x08, 0xb8, 0x29, 0x08, 0x96, 0xd0,
+	0x01, 0x23, 0x34, 0xb6, 0x1e, 0xfe, 0xb0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd1, 0x6c, 0x52, 0xd3, 0x5f, 0x6a, 0x74, 0x18, 0x9b, 0xfe, 0xf3, 0x73,
+	0x74, 0xb8, 0x05, 0xa2, 0x29, 0x9d, 0x41, 0x53, 0x72, 0xa2, 0x93, 0x7c,
+	0x0a, 0xa8, 0xe8, 0x48, 0x89, 0x8f, 0x6f, 0x60, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x21, 0x4a, 0xd6, 0xa6, 0x0b, 0x51, 0xf6, 0x1d, 0xa2, 0x5c, 0xa5, 0x23,
+	0x6a, 0x1e, 0x34, 0x7d, 0xc5, 0xfe, 0xba, 0x77, 0x9d, 0xe5, 0x40, 0x9c,
+	0x38, 0x4e, 0xab, 0x29, 0x0d, 0x17, 0x7e, 0x48, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1e, 0x04, 0x03, 0xaf, 0xbd, 0x77, 0xba, 0x7d, 0x53, 0xe9, 0x14, 0x63,
+	0x40, 0xa7, 0xba, 0x26, 0x00, 0x55, 0x42, 0xff, 0x7c, 0x0d, 0xde, 0xd1,
+	0x59, 0xa2, 0x72, 0x6d, 0x1a, 0x92, 0x7e, 0x56, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0x6d, 0x5c, 0x1d, 0x19, 0xf5, 0x09, 0x6d, 0x18, 0xa1, 0x69, 0x87,
+	0xad, 0x52, 0x19, 0x1e, 0xf1, 0x83, 0x14, 0xea, 0x85, 0x1c, 0xeb, 0xe0,
+	0x09, 0x34, 0x4b, 0x8a, 0xd2, 0x98, 0x25, 0x20, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4c, 0x5a, 0xf1, 0x8b, 0x60, 0xa3, 0xef, 0xfb, 0xe6, 0x9a, 0x9e, 0x2a,
+	0x7c, 0x79, 0x13, 0x18, 0x9b, 0x68, 0xed, 0x3d, 0x9c, 0x96, 0x87, 0x75,
+	0x7d, 0x03, 0x00, 0x62, 0x8a, 0x38, 0x69, 0x58, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8e, 0x21, 0xc4, 0x17, 0x0e, 0x2d, 0x4e, 0x01, 0xb5, 0xfb, 0x2e, 0x65,
+	0x3f, 0x32, 0xd7, 0x18, 0x50, 0x70, 0x81, 0x6b, 0xf7, 0xab, 0xc2, 0xfc,
+	0x4b, 0xa9, 0x21, 0x10, 0x37, 0x21, 0xbf, 0xbb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xda, 0x5a, 0x33, 0xeb, 0x21, 0x36, 0x7c, 0x40, 0x16, 0x1d, 0xd5, 0x6e,
+	0xe1, 0xe4, 0x79, 0x2b, 0x9f, 0x9f, 0x06, 0x89, 0x80, 0x93, 0xc6, 0x0f,
+	0x61, 0xbe, 0x0b, 0x75, 0xdb, 0x7c, 0x78, 0x50, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8b, 0xdc, 0x45, 0xa9, 0x5e, 0xbc, 0xf3, 0xb4, 0xcc, 0x3c, 0xba, 0xbd,
+	0x65, 0x2f, 0x2f, 0xd7, 0xd5, 0x15, 0x7f, 0x7e, 0x03, 0x0b, 0xc6, 0xc7,
+	0x6b, 0x6b, 0x6e, 0x77, 0x30, 0xcb, 0xc0, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2e, 0xf0, 0x16, 0xcd, 0xf9, 0x23, 0xf9, 0x10, 0xe0, 0x5d, 0xa7, 0x26,
+	0xbb, 0xf1, 0x53, 0x06, 0xea, 0x81, 0x2f, 0x38, 0x9e, 0x53, 0x67, 0x40,
+	0x74, 0x2a, 0xd5, 0x6e, 0xec, 0xc8, 0xa5, 0xcb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe2, 0x1f, 0xc1, 0xee, 0x82, 0xd5, 0x6e, 0x58, 0x81, 0x97, 0x4c, 0xf3,
+	0x0b, 0x90, 0x1e, 0x1f, 0xf8, 0xdc, 0x2b, 0xc0, 0x58, 0x3b, 0x2a, 0x28,
+	0x56, 0xc1, 0xe7, 0xb4, 0x40, 0x44, 0x5b, 0x54, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x25, 0x85, 0x49, 0x08, 0xe7, 0xfa, 0x5d, 0x0c, 0xf9, 0xa3, 0x6e, 0xe5,
+	0x34, 0x8e, 0x83, 0xf2, 0xd0, 0xf1, 0xa4, 0x13, 0x32, 0x52, 0x86, 0x50,
+	0x75, 0xcd, 0xb5, 0xfc, 0xe9, 0x7b, 0x7c, 0xf6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x2c, 0x85, 0x09, 0xe3, 0xd9, 0x4a, 0x91, 0xa2, 0x10, 0xf7, 0x7f, 0x5b,
+	0xde, 0x9a, 0xb7, 0x87, 0x32, 0x7d, 0x63, 0xf6, 0x7e, 0x0c, 0x3e, 0xcc,
+	0x4a, 0xa4, 0x9e, 0x35, 0x6b, 0x55, 0x50, 0x2e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xde, 0x9c, 0x80, 0x75, 0xc0, 0x21, 0x92, 0xf7, 0x30, 0x72, 0x1c, 0x15,
+	0xb2, 0x00, 0x0e, 0xc4, 0xa1, 0xa6, 0x1a, 0x6d, 0xd1, 0x63, 0x6b, 0xa8,
+	0x4b, 0x01, 0x10, 0x6f, 0x61, 0xe7, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7f, 0xdd, 0x3e, 0x2e, 0x6d, 0x7e, 0xed, 0x72, 0x65, 0xf7, 0x8d, 0x29,
+	0xba, 0x75, 0xa3, 0x07, 0x93, 0x86, 0xb4, 0xee, 0xcd, 0xd8, 0x5d, 0x19,
+	0x22, 0x02, 0x39, 0xba, 0xc5, 0x05, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa2, 0x01, 0xed, 0x74, 0x47, 0xd9, 0x0b, 0x18, 0x73, 0x4d, 0xcd, 0x41,
+	0x9a, 0xe4, 0xf1, 0xee, 0x33, 0x8a, 0x74, 0x8b, 0x26, 0xfd, 0x6e, 0x02,
+	0x2e, 0x5c, 0xc7, 0xf5, 0xa1, 0xeb, 0x41, 0xa7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3a, 0x3c, 0x00, 0x91, 0x80, 0xf2, 0x0f, 0x07, 0xf5, 0x02, 0xdc, 0xfa,
+	0xb7, 0x6e, 0x74, 0xdc, 0x3a, 0x78, 0xc5, 0x28, 0x8e, 0x17, 0x4f, 0xf1,
+	0x54, 0x40, 0x61, 0xfa, 0x46, 0x6c, 0x6d, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0x5f, 0xf2, 0x5a, 0x62, 0xbc, 0x77, 0xc1, 0xea, 0xbb, 0x38, 0xc2,
+	0x7e, 0x63, 0xac, 0x59, 0xc9, 0xd1, 0x37, 0xea, 0xeb, 0x09, 0x77, 0xa1,
+	0x6b, 0x49, 0x7e, 0x17, 0xc3, 0xab, 0x03, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xce, 0x14, 0xe5, 0x45, 0x4b, 0x16, 0x3e, 0x4a, 0xec, 0x3d, 0x52, 0x21,
+	0x35, 0xff, 0xe5, 0x33, 0x06, 0x46, 0x11, 0x32, 0x96, 0xc0, 0x34, 0x06,
+	0x04, 0x31, 0x37, 0x31, 0x25, 0xde, 0xde, 0xd8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x11, 0xbe, 0x6b, 0x47, 0xcd, 0x4a, 0xfd, 0xc3, 0x0d, 0x90, 0x1c, 0xc0,
+	0xd4, 0x70, 0x96, 0x72, 0xec, 0x42, 0xd6, 0x1d, 0x25, 0x5a, 0x9c, 0xd2,
+	0x23, 0xd6, 0x8e, 0xaf, 0x95, 0x7e, 0xfb, 0xd3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xdf, 0x28, 0x49, 0xeb, 0xa9, 0x5a, 0x0b, 0xf6, 0xf0, 0x9f, 0x4a,
+	0x47, 0x70, 0xf3, 0x49, 0x5f, 0x6f, 0xac, 0x86, 0x40, 0xfb, 0x0d, 0xf7,
+	0x72, 0xab, 0x23, 0x3d, 0x91, 0x08, 0x8c, 0x32, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0xb9, 0xe2, 0xb7, 0x4e, 0x62, 0xde, 0xcc, 0xd7, 0x68, 0xbd, 0x60,
+	0x83, 0x7d, 0x9c, 0x61, 0xfd, 0xd8, 0x5e, 0xb7, 0x64, 0x9b, 0xce, 0xa5,
+	0x23, 0x81, 0x2c, 0xcd, 0x9b, 0x5a, 0xaa, 0xd6, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1d, 0x4a, 0x45, 0xf9, 0x1b, 0x9f, 0xa9, 0xfd, 0x38, 0x86, 0x31, 0x53,
+	0x9a, 0x2f, 0xb5, 0x5d, 0x2d, 0xed, 0x31, 0x75, 0x30, 0xd6, 0xbb, 0xdd,
+	0x53, 0x9b, 0x5f, 0xe0, 0xab, 0xd7, 0xaf, 0xe0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xee, 0xb3, 0x3b, 0xf0, 0x8a, 0x11, 0xd5, 0x5e, 0x37, 0xfd, 0x5a, 0x03,
+	0xaf, 0xaf, 0x0c, 0x99, 0xcc, 0x62, 0x92, 0x12, 0x30, 0x52, 0xac, 0x72,
+	0x7f, 0x51, 0x65, 0x44, 0x19, 0xf9, 0xe4, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x95, 0x4b, 0x50, 0xb3, 0x76, 0xa6, 0xa4, 0xb1, 0x9a, 0x39, 0x1e,
+	0x0d, 0x64, 0xfe, 0xc0, 0xf4, 0x43, 0xef, 0x85, 0x0a, 0xc2, 0xe3, 0xb0,
+	0x58, 0xc3, 0xf0, 0xf8, 0xdb, 0x67, 0xfc, 0x36, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xba, 0x4f, 0xbc, 0x66, 0x32, 0xd4, 0x4e, 0xec, 0x3f, 0x92, 0xfb, 0x0e,
+	0x92, 0x9b, 0x52, 0xe8, 0x27, 0xd9, 0xbb, 0xaa, 0x9c, 0x54, 0x70, 0x82,
+	0x4f, 0xad, 0xca, 0xbc, 0x9e, 0x01, 0x7e, 0x1c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5e, 0xe3, 0x0c, 0xca, 0xa3, 0xaa, 0xd6, 0x3f, 0x90, 0xcc, 0xef, 0xcd,
+	0x74, 0x59, 0xb3, 0xc5, 0xba, 0x35, 0xa8, 0x7e, 0x7e, 0xec, 0x4b, 0x6b,
+	0x00, 0x21, 0xfb, 0xa1, 0x6e, 0x53, 0xc4, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9d, 0xd3, 0xb3, 0xeb, 0xcf, 0xa0, 0x6d, 0xb1, 0x88, 0xab, 0x33, 0xc4,
+	0x0f, 0xd7, 0xb0, 0x76, 0x02, 0x8e, 0x71, 0x61, 0x18, 0x63, 0x07, 0xdc,
+	0x3e, 0x0d, 0xb9, 0xa8, 0x32, 0x75, 0x7a, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0xab, 0xf5, 0x7e, 0x0b, 0x4c, 0x08, 0x30, 0x08, 0x80, 0xc1, 0x9b,
+	0x69, 0x6a, 0x0e, 0xfc, 0x16, 0x81, 0xf1, 0xa9, 0xd4, 0x85, 0x35, 0x94,
+	0x26, 0xc5, 0x23, 0xb4, 0xa8, 0xb1, 0x8a, 0xb8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc5, 0x6d, 0x50, 0x49, 0x27, 0x8d, 0x35, 0x47, 0x0d, 0x73, 0x18, 0xae,
+	0xaf, 0x38, 0xef, 0xfa, 0xdd, 0x70, 0x48, 0x15, 0x39, 0xf0, 0x1c, 0x6e,
+	0x79, 0xd1, 0x13, 0x9f, 0xe4, 0xb3, 0xb2, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x39, 0xeb, 0xfb, 0x14, 0x3f, 0xf0, 0xa0, 0x0b, 0x5e, 0x41, 0x20, 0x0c,
+	0xfe, 0x36, 0x0c, 0x7f, 0xf0, 0xaf, 0xaa, 0xdd, 0x61, 0x66, 0x65, 0x30,
+	0x6b, 0x10, 0x18, 0x28, 0x30, 0xb6, 0x47, 0x3e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf7, 0xa8, 0x12, 0x06, 0x64, 0xfa, 0x90, 0xfa, 0x0c, 0xfb, 0x26, 0xf2,
+	0x2a, 0x1a, 0xc4, 0xf9, 0xae, 0x5c, 0x1b, 0x24, 0xf3, 0xf2, 0x87, 0xa2,
+	0x5c, 0x0a, 0x2a, 0x2b, 0x17, 0xa7, 0x2b, 0x7e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x99, 0x6d, 0x30, 0x7d, 0xb2, 0xd1, 0x40, 0xb7, 0x4f, 0x05, 0xac, 0x1a,
+	0xa1, 0x66, 0xa6, 0x19, 0x18, 0xf8, 0xcd, 0xf3, 0x3c, 0xf6, 0x84, 0xc3,
+	0x4d, 0x46, 0x49, 0xf1, 0xf7, 0x28, 0xa6, 0x0c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0xf2, 0x0b, 0x90, 0x0d, 0xeb, 0x5c, 0x0b, 0x70, 0x2f, 0x54, 0x26,
+	0x1a, 0x7d, 0x6e, 0x72, 0x67, 0x95, 0x28, 0x03, 0x01, 0x37, 0xfa, 0xc6,
+	0x00, 0x45, 0xa7, 0xda, 0x5b, 0xbf, 0xf0, 0x24, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa9, 0x6c, 0x1d, 0x2b, 0x7e, 0xea, 0x35, 0x8b, 0x92, 0x12, 0x42, 0xf9,
+	0x8f, 0x67, 0x38, 0xf5, 0xf7, 0x1a, 0xe2, 0x8f, 0xb4, 0x40, 0x45, 0x2a,
+	0x47, 0xca, 0x9d, 0xbf, 0xbd, 0x85, 0xc0, 0xd2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+const uint8_t ae_fpm_tbl_ed448[AE_FPM_ED448_LEN] = {
+	0x26, 0x26, 0xa8, 0x2b, 0xc7, 0x0c, 0xc0, 0x5e, 0x43, 0x3b, 0x80, 0xe1,
+	0x8b, 0x00, 0x93, 0x8e, 0x12, 0xae, 0x1a, 0xf7, 0x2a, 0xb6, 0x65, 0x11,
+	0xea, 0x6d, 0xe3, 0x24, 0xa3, 0xd3, 0xa4, 0x64, 0x9e, 0x14, 0x65, 0x70,
+	0x47, 0x0f, 0x17, 0x67, 0x22, 0x1d, 0x15, 0xa6, 0x22, 0xbf, 0x36, 0xda,
+	0x4f, 0x19, 0x70, 0xc6, 0x6b, 0xed, 0x0d, 0xed, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x98, 0x08, 0x79, 0x5b, 0xf2, 0x30, 0xfa, 0x14,
+	0xfd, 0xbd, 0x13, 0x2c, 0x4e, 0xd7, 0xc8, 0xad, 0x3a, 0xd3, 0xff, 0x1c,
+	0xe6, 0x7c, 0x39, 0xc4, 0x87, 0x78, 0x9c, 0x1e, 0x05, 0xa0, 0xc2, 0xd7,
+	0x4b, 0xea, 0x73, 0x73, 0x6c, 0xa3, 0x98, 0x40, 0x88, 0x76, 0x20, 0x37,
+	0x56, 0xc9, 0xc7, 0x62, 0x69, 0x3f, 0x46, 0x71, 0x6e, 0xb6, 0xbc, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xeb, 0x06, 0x62, 0x4e, 0x82, 0xaf, 0x95, 0xf3, 0xf7, 0x8f, 0xa0, 0x7d,
+	0x85, 0x66, 0x2d, 0x1d, 0xf1, 0x79, 0xde, 0x90, 0xb5, 0xb2, 0x7d, 0xa1,
+	0x60, 0xd7, 0x16, 0x67, 0xe2, 0x35, 0x6d, 0x58, 0xc5, 0x05, 0x6a, 0x18,
+	0x3f, 0x84, 0x51, 0xd2, 0xce, 0xc3, 0x9d, 0x2d, 0x50, 0x8d, 0x91, 0xc9,
+	0xc7, 0x5e, 0xb5, 0x8a, 0xee, 0x22, 0x1c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x12, 0x77, 0x1a, 0x0d, 0x31, 0xc0, 0x77, 0xbf,
+	0xc4, 0x24, 0x04, 0xed, 0x68, 0x36, 0xd7, 0x42, 0x6a, 0x65, 0x11, 0x30,
+	0x9d, 0xd9, 0x3a, 0x78, 0x3d, 0x16, 0x5b, 0x3f, 0x5b, 0x32, 0xdd, 0x27,
+	0x70, 0xf9, 0x81, 0x8f, 0x1b, 0xc6, 0x4d, 0xd1, 0x36, 0xf5, 0xf8, 0x56,
+	0x3e, 0x48, 0x3a, 0xc1, 0x28, 0x41, 0x27, 0x74, 0x35, 0xd1, 0x4b, 0x0f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x69, 0x81, 0x50,
+	0x38, 0xfb, 0x26, 0xe1, 0x68, 0x82, 0xe5, 0x52, 0x90, 0x23, 0xc2, 0x5e,
+	0xb3, 0x5e, 0x42, 0x06, 0x65, 0xea, 0x9f, 0x0c, 0x94, 0x4c, 0x92, 0x1f,
+	0x2d, 0x18, 0x4c, 0x04, 0xbe, 0x79, 0xf0, 0x74, 0x2d, 0x5a, 0x0b, 0x29,
+	0xa7, 0x46, 0xb8, 0x80, 0xdf, 0x83, 0x8f, 0x06, 0xe6, 0xe0, 0x8f, 0x72,
+	0x53, 0xfa, 0x6d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb4, 0x85, 0xa6, 0xed, 0xe6, 0xa8, 0x12, 0xd5, 0x7d, 0x97, 0xf7, 0xc8,
+	0xac, 0x2c, 0x4d, 0x2b, 0xfc, 0x53, 0x3e, 0xd0, 0x9f, 0x45, 0xd1, 0x52,
+	0xac, 0x85, 0x4f, 0xf8, 0x36, 0x7c, 0xcd, 0xa6, 0x6c, 0xb8, 0x0f, 0x8f,
+	0xdc, 0xde, 0x54, 0xc3, 0x23, 0x7b, 0xcc, 0xd9, 0xfe, 0x97, 0x19, 0x86,
+	0xa6, 0x17, 0xcd, 0x9b, 0xfe, 0x08, 0xf6, 0x3f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5c, 0xeb, 0x54, 0x97, 0x02, 0x55, 0xed, 0x8f,
+	0xfe, 0x3f, 0xe6, 0x24, 0x26, 0x1e, 0x3a, 0xc8, 0xdf, 0x28, 0xfc, 0xf9,
+	0xb9, 0x1b, 0x9c, 0xc8, 0x1b, 0x5f, 0xb0, 0x08, 0x2b, 0x19, 0x1e, 0x92,
+	0x29, 0xd9, 0x49, 0xa8, 0xb4, 0x61, 0xcc, 0xf3, 0x18, 0x35, 0x0a, 0x40,
+	0x2a, 0xe3, 0x2c, 0x09, 0x21, 0x81, 0x22, 0x38, 0xaf, 0xc2, 0xf4, 0x20,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x2d, 0x7c, 0xe2,
+	0x41, 0xc3, 0x10, 0x65, 0x01, 0x4a, 0x4f, 0xd5, 0x07, 0x2b, 0xa5, 0xd6,
+	0x7c, 0xc0, 0x57, 0x50, 0xc3, 0xf5, 0x63, 0xa0, 0x03, 0x8b, 0x79, 0xa9,
+	0xb1, 0xdd, 0xc4, 0x2f, 0xbe, 0xfa, 0x48, 0x92, 0xca, 0x8e, 0xd7, 0x0d,
+	0xdf, 0xcf, 0x2d, 0x40, 0xa3, 0xbc, 0x7e, 0xe7, 0x2e, 0xbe, 0xe9, 0x21,
+	0x83, 0xc8, 0x79, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xac, 0xdf, 0x2c, 0x05, 0x92, 0x8e, 0xe1, 0x3b, 0xc0, 0x57, 0xd9, 0xb4,
+	0x16, 0x0c, 0x80, 0x17, 0x03, 0x5a, 0x29, 0x4d, 0xef, 0x36, 0x9b, 0x11,
+	0x3b, 0xe2, 0xef, 0xca, 0x7f, 0xdd, 0xd3, 0xa3, 0xd7, 0x7f, 0x2b, 0x64,
+	0xa9, 0x7f, 0x62, 0x72, 0x71, 0x7d, 0x9e, 0x9f, 0xde, 0x2b, 0xcb, 0xd4,
+	0x3e, 0x95, 0x6f, 0x9d, 0x0c, 0x1f, 0x1a, 0xb4, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x92, 0xef, 0x93, 0x8e, 0xe7, 0x0a, 0x10,
+	0x7b, 0xc3, 0xdc, 0x46, 0xd9, 0x96, 0x27, 0x92, 0x91, 0xa4, 0x98, 0x89,
+	0x2d, 0xf2, 0x17, 0x03, 0x8c, 0xdb, 0x98, 0xed, 0xda, 0xb3, 0x15, 0xd5,
+	0xba, 0x58, 0x01, 0x38, 0x6e, 0x54, 0xd7, 0x46, 0x9c, 0x2b, 0x94, 0x5b,
+	0x60, 0x9e, 0x5b, 0x3b, 0xc3, 0x4c, 0x7e, 0xc3, 0xbc, 0x4d, 0xa9, 0xdd,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xd6, 0x93, 0x46,
+	0x63, 0x4b, 0xb6, 0x15, 0x73, 0x5f, 0xe8, 0x44, 0x1f, 0x89, 0x7c, 0xfe,
+	0x83, 0x79, 0xcb, 0x73, 0x83, 0x58, 0xce, 0x9c, 0x87, 0xad, 0x17, 0xe5,
+	0xfa, 0xdd, 0x04, 0x86, 0x55, 0x71, 0xf7, 0xb8, 0x6b, 0xcd, 0x5d, 0xfc,
+	0x9c, 0x49, 0xe6, 0x3f, 0x3e, 0x87, 0x3b, 0x37, 0x65, 0x32, 0x11, 0x5c,
+	0x6e, 0x65, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0x3f, 0x74, 0xbc, 0x23, 0x5e, 0x87, 0xc7, 0x6f, 0xe1, 0x4d, 0x31,
+	0x75, 0x2a, 0x1e, 0xa9, 0x8e, 0xa2, 0x11, 0x3d, 0xfb, 0x62, 0xb8, 0x22,
+	0xdb, 0x4d, 0xb6, 0x29, 0x78, 0x4b, 0xc7, 0xa8, 0xba, 0x9b, 0xd8, 0x39,
+	0x03, 0xb6, 0x66, 0x26, 0xd2, 0xce, 0x26, 0x5d, 0x68, 0x1d, 0xca, 0x51,
+	0x14, 0x75, 0x66, 0xbd, 0xc2, 0xd0, 0xbc, 0xdb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x99, 0x33, 0x2c, 0x81, 0xaa, 0xcd, 0x8e, 0x4a,
+	0x04, 0xdf, 0xf4, 0x24, 0x98, 0x6b, 0x6e, 0x0f, 0xb1, 0xc0, 0x97, 0x61,
+	0x12, 0xbb, 0xa6, 0xd2, 0x67, 0x28, 0x33, 0xbb, 0xe7, 0x56, 0x5f, 0xc1,
+	0xa1, 0x23, 0xad, 0x1f, 0x3c, 0x75, 0x9c, 0x20, 0x92, 0x72, 0xe4, 0xfb,
+	0x60, 0x6c, 0xac, 0x5c, 0x25, 0x89, 0xe9, 0x2c, 0xb0, 0x29, 0x52, 0x1d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x78, 0xf8, 0x9f,
+	0x6b, 0x68, 0x93, 0x3b, 0xd8, 0x27, 0xa4, 0xb3, 0x34, 0x37, 0x63, 0x7b,
+	0x60, 0x22, 0x8b, 0xab, 0x06, 0x92, 0xed, 0x9e, 0x4d, 0xc7, 0x5b, 0xf1,
+	0x23, 0x65, 0x05, 0xc4, 0x6d, 0x7d, 0x04, 0x67, 0xc0, 0x27, 0x29, 0x05,
+	0x23, 0x7f, 0xf8, 0x30, 0xfe, 0x6e, 0xf3, 0x0b, 0x3a, 0x85, 0x47, 0x45,
+	0xa5, 0x1c, 0x9a, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x30, 0x7d, 0x8f, 0x0d, 0xcb, 0xce, 0x3a, 0x48, 0xd3, 0x2f, 0x09, 0xf8,
+	0xdd, 0x49, 0x49, 0x3d, 0x9f, 0x65, 0xb4, 0x4d, 0xcd, 0xa6, 0x93, 0xb2,
+	0x72, 0xe2, 0x98, 0x6e, 0xa7, 0xae, 0x0a, 0x9d, 0xcb, 0xb0, 0xc9, 0x75,
+	0x3b, 0x41, 0x79, 0x71, 0x63, 0xce, 0x55, 0x70, 0xde, 0x2a, 0x0f, 0x07,
+	0x30, 0xe5, 0x7e, 0xb9, 0xf3, 0xdf, 0x50, 0x39, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xce, 0x5b, 0xd0, 0x27, 0x82, 0x18, 0x8e, 0x41,
+	0x4b, 0x43, 0x8a, 0x62, 0x3e, 0x21, 0xce, 0x31, 0x28, 0xe2, 0xc5, 0x53,
+	0xbd, 0x97, 0xec, 0xa0, 0xc8, 0x85, 0xa4, 0x7a, 0x1e, 0xdb, 0x22, 0xc1,
+	0xbc, 0xc8, 0xa3, 0x74, 0xda, 0xd2, 0xd7, 0xa8, 0x96, 0x9e, 0x51, 0xfd,
+	0xa5, 0x74, 0x8f, 0xab, 0x55, 0x4b, 0x95, 0xb6, 0xfc, 0x3d, 0x16, 0x7d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x70, 0x9e, 0xad,
+	0xfb, 0x64, 0xff, 0xc6, 0xe7, 0x78, 0x37, 0x89, 0x04, 0x9f, 0x01, 0x16,
+	0xa1, 0x68, 0x38, 0xf0, 0xf3, 0x01, 0x25, 0xfd, 0xfa, 0xa1, 0xd3, 0x7e,
+	0x6f, 0xb6, 0x33, 0xa7, 0x44, 0x62, 0x83, 0x19, 0xec, 0x5b, 0xfe, 0x17,
+	0xa1, 0x7d, 0xe4, 0xa2, 0x7d, 0x47, 0xa5, 0x1d, 0x1f, 0x31, 0x55, 0x2d,
+	0xe2, 0x3c, 0x9a, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5f, 0xfd, 0xfd, 0x31, 0xc2, 0x6d, 0x22, 0x75, 0x97, 0x37, 0x39, 0x32,
+	0x1a, 0x88, 0x65, 0x16, 0xe9, 0xb8, 0x94, 0x35, 0xd7, 0x1e, 0x32, 0x32,
+	0x29, 0xf8, 0xfd, 0xef, 0x97, 0x26, 0xe9, 0x87, 0x32, 0xf4, 0xc9, 0x2b,
+	0x94, 0x2c, 0x85, 0x28, 0x8e, 0xb5, 0x4c, 0xf8, 0xae, 0xbf, 0xdf, 0x1a,
+	0xe3, 0xff, 0xbf, 0x0d, 0x3a, 0x8f, 0x86, 0xdf, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xb2, 0x45, 0xf4, 0xc9, 0xee, 0x82, 0x26, 0x2e,
+	0xe6, 0xd0, 0x97, 0x07, 0xfb, 0x72, 0xd1, 0x73, 0x98, 0x46, 0x05, 0x88,
+	0x1c, 0xba, 0xa2, 0x06, 0xd0, 0xe5, 0x49, 0xde, 0x1c, 0x6b, 0xa3, 0xe5,
+	0x5b, 0xea, 0x44, 0x4b, 0xe1, 0x5f, 0xa2, 0x77, 0x46, 0xed, 0xe6, 0x8c,
+	0x33, 0x20, 0x8e, 0x54, 0x74, 0x2f, 0x80, 0x95, 0x11, 0x50, 0x6b, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x6f, 0x6f, 0xa4,
+	0xe3, 0x4b, 0x95, 0xa3, 0x98, 0x3f, 0x0a, 0xfa, 0xf3, 0x9d, 0x9b, 0x7d,
+	0x78, 0xf9, 0x3e, 0x56, 0xd2, 0xd9, 0xb4, 0x2e, 0xd8, 0x39, 0xfb, 0x35,
+	0xe3, 0x25, 0xc5, 0xba, 0xfc, 0x18, 0xab, 0x08, 0x2d, 0x38, 0xe9, 0x4e,
+	0x68, 0xd6, 0x98, 0xad, 0x58, 0xfa, 0xd1, 0xe0, 0x55, 0x8f, 0x21, 0x1a,
+	0x11, 0x7e, 0x13, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x33, 0x19, 0x04, 0x18, 0xcf, 0x4b, 0x06, 0xf1, 0x32, 0x0f, 0xb9, 0xcb,
+	0x13, 0x81, 0x9b, 0xaf, 0x4e, 0x55, 0xaa, 0x8b, 0xea, 0x88, 0x95, 0x66,
+	0x9b, 0xf7, 0xd3, 0x58, 0xb5, 0x4b, 0x2c, 0xee, 0x18, 0xca, 0x8a, 0x94,
+	0xc9, 0x82, 0x98, 0x5d, 0x3d, 0xbc, 0xb7, 0x3c, 0x73, 0xab, 0x6c, 0x76,
+	0x7c, 0x25, 0x62, 0xfc, 0x8a, 0xef, 0xd7, 0xf5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x59, 0x2d, 0xbb, 0xa7, 0xf0, 0x49, 0x6f, 0xc2,
+	0x69, 0xb1, 0xc3, 0x94, 0xf3, 0x8e, 0xf4, 0xac, 0xe3, 0x2c, 0xd9, 0x94,
+	0xfd, 0x15, 0x46, 0x54, 0x49, 0x19, 0xbc, 0x27, 0xb4, 0x8b, 0x85, 0xf5,
+	0x54, 0x81, 0x10, 0x03, 0x99, 0x13, 0x58, 0x6d, 0x0a, 0x2f, 0x6d, 0xbc,
+	0x76, 0x34, 0xd1, 0x12, 0xfe, 0xa6, 0x75, 0xf0, 0x54, 0x39, 0xb4, 0x33,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x52, 0x64, 0x73,
+	0x17, 0xb4, 0xc4, 0xcc, 0x4b, 0x72, 0xf2, 0x4d, 0xf6, 0x31, 0xb3, 0xf8,
+	0x25, 0x64, 0xdb, 0x94, 0xa7, 0x83, 0x86, 0x66, 0xad, 0xc1, 0x9f, 0x9e,
+	0xa7, 0xc9, 0x87, 0x84, 0x9c, 0x80, 0x82, 0x94, 0x36, 0xcd, 0x2a, 0xba,
+	0x04, 0x9f, 0x25, 0x9c, 0x56, 0x1a, 0x3e, 0x09, 0x07, 0xf4, 0x27, 0xae,
+	0xf2, 0x21, 0x0a, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xd5, 0xe9, 0x2b, 0xb0, 0x25, 0x50, 0x73, 0x45, 0x24, 0xb4, 0xfe, 0x97,
+	0x6c, 0xaf, 0xb8, 0x72, 0xbf, 0xe2, 0xcf, 0x5d, 0xe8, 0x66, 0x84, 0x74,
+	0xd6, 0xff, 0x14, 0xc9, 0x07, 0x63, 0x58, 0x2e, 0xd2, 0x81, 0x83, 0xc9,
+	0x05, 0x9d, 0x5c, 0x9e, 0x62, 0xd2, 0x90, 0x3a, 0x6c, 0x16, 0x66, 0x7c,
+	0x2d, 0xe1, 0x2b, 0x55, 0x51, 0x2b, 0x25, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xea, 0x86, 0x65, 0xcb, 0x55, 0x08, 0x23, 0x8b,
+	0x3e, 0xd3, 0xa7, 0x88, 0x0f, 0xb1, 0xd3, 0x7f, 0xe7, 0xb8, 0x61, 0xfa,
+	0x58, 0x96, 0x51, 0x4c, 0xea, 0x4d, 0x95, 0xcd, 0x1a, 0x3e, 0x3c, 0x95,
+	0xd3, 0x07, 0xc9, 0x00, 0x66, 0x68, 0x8d, 0x25, 0x9e, 0x1c, 0x82, 0xae,
+	0x5e, 0x48, 0xea, 0xf3, 0x01, 0x27, 0x7b, 0xf2, 0xb2, 0x9b, 0x16, 0xef,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1c, 0x38, 0xc3,
+	0x1f, 0x7b, 0x41, 0x2d, 0x5d, 0xdf, 0xd9, 0xea, 0xbf, 0xad, 0x45, 0xa2,
+	0x25, 0x0b, 0xb6, 0xa3, 0xef, 0xa5, 0xdc, 0xc5, 0xe0, 0xb8, 0x4a, 0xb3,
+	0xfa, 0xb5, 0x36, 0x35, 0x77, 0xdc, 0xf4, 0xa6, 0x88, 0x53, 0xe1, 0xa3,
+	0x1e, 0xf6, 0xa6, 0x8e, 0x7a, 0xc5, 0x0b, 0xc2, 0x16, 0x3e, 0xe2, 0x27,
+	0x0f, 0x9b, 0xc4, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x81, 0x54, 0x75, 0x7f, 0xdb, 0x06, 0xbd, 0xa2, 0x4a, 0x5b, 0xa0, 0x85,
+	0xf8, 0xc5, 0x12, 0x5b, 0xbb, 0x4b, 0xa1, 0x58, 0xa5, 0xd6, 0x1d, 0x98,
+	0x04, 0x21, 0x7a, 0x30, 0x31, 0x00, 0x2c, 0x99, 0x90, 0xcf, 0x80, 0xfe,
+	0xd1, 0x6b, 0x27, 0x93, 0xef, 0x89, 0x06, 0x1b, 0x95, 0x21, 0x8b, 0xbe,
+	0x0b, 0x8d, 0x1b, 0xa0, 0x23, 0x87, 0xf0, 0xe1, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x76, 0x74, 0xb2, 0xb2, 0x25, 0x00, 0x07, 0xf9,
+	0x01, 0x30, 0x2b, 0xb8, 0xf2, 0x4e, 0xb2, 0x26, 0x04, 0x11, 0x3c, 0x79,
+	0xeb, 0x4a, 0xdf, 0x53, 0x55, 0xe6, 0x6e, 0x59, 0x60, 0xcd, 0xf2, 0xa4,
+	0xd7, 0xc3, 0x0d, 0x70, 0x9d, 0x6c, 0x64, 0x2a, 0xdd, 0x9d, 0x4d, 0x83,
+	0x95, 0x94, 0xd2, 0x38, 0xd1, 0xcd, 0x6e, 0xdb, 0x33, 0x32, 0x62, 0xd4,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x62, 0x25, 0x5e,
+	0xe0, 0x13, 0x80, 0x39, 0x31, 0x0e, 0x59, 0x15, 0x9c, 0xe8, 0x75, 0xbc,
+	0x60, 0x90, 0x34, 0x3a, 0x5f, 0x7d, 0x7c, 0x0b, 0x6c, 0x3d, 0x02, 0xfd,
+	0xfa, 0xb1, 0xf7, 0xce, 0x1b, 0xec, 0x37, 0x06, 0xaf, 0xc1, 0x9f, 0x93,
+	0x6f, 0x2d, 0x40, 0x9f, 0x22, 0x52, 0xb6, 0x73, 0x8f, 0x91, 0xe1, 0x85,
+	0xfe, 0x57, 0xa6, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x42, 0xde, 0xbe, 0xf5, 0xb7, 0xca, 0x60, 0x2e, 0x10, 0x88, 0xb7, 0xfc,
+	0xbe, 0x7f, 0x06, 0x8a, 0x7d, 0xcd, 0xb1, 0xde, 0x34, 0x43, 0x19, 0x70,
+	0xab, 0xa7, 0x62, 0x0e, 0x37, 0xee, 0x28, 0x2b, 0xd7, 0x5e, 0x4c, 0x5b,
+	0x30, 0x99, 0xc3, 0x3c, 0x47, 0xfb, 0x4d, 0x92, 0xb2, 0x6c, 0xa4, 0xd9,
+	0x9d, 0xe5, 0x74, 0xe2, 0xb2, 0xec, 0x6c, 0xc9, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x60, 0x24, 0xe8, 0xa8, 0xae, 0x35, 0x55, 0x83,
+	0x99, 0xe9, 0x6e, 0xdd, 0xdb, 0x48, 0x26, 0xee, 0x7a, 0x82, 0xdc, 0xa9,
+	0xb5, 0xda, 0xf3, 0xda, 0x21, 0x36, 0x87, 0xc0, 0xc9, 0xa0, 0x0c, 0xb1,
+	0xad, 0xc8, 0x5f, 0x1e, 0x68, 0x40, 0xd9, 0x2c, 0xdb, 0x15, 0x29, 0xfd,
+	0x8f, 0x80, 0xde, 0x8b, 0xad, 0xfa, 0xd4, 0x59, 0x20, 0x94, 0x40, 0x5f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x44, 0x63, 0x52,
+	0x42, 0xef, 0x04, 0x95, 0x0b, 0xbc, 0x2e, 0xc5, 0x6d, 0x67, 0x5a, 0x26,
+	0x24, 0x8e, 0x97, 0x4c, 0x1c, 0x52, 0x85, 0xe2, 0x65, 0x2e, 0xdf, 0xc0,
+	0xe1, 0x38, 0xb2, 0x2d, 0x90, 0xd7, 0x28, 0x31, 0x88, 0xbd, 0xbd, 0x45,
+	0x1e, 0x07, 0x53, 0x0c, 0x31, 0xe3, 0x60, 0x60, 0x96, 0xdd, 0x3f, 0x14,
+	0x3d, 0xb0, 0x03, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x7b, 0x41, 0x1e, 0xcf, 0xd4, 0xa0, 0xf3, 0x55, 0xa5, 0x02, 0x3e,
+	0x43, 0xf3, 0xfe, 0x6c, 0xf5, 0x39, 0x77, 0xfe, 0x5a, 0x9d, 0xa3, 0x43,
+	0xab, 0xa4, 0x11, 0xb7, 0x3c, 0xba, 0x8e, 0xf2, 0x96, 0x22, 0x30, 0x7e,
+	0x3a, 0x89, 0xf4, 0x37, 0xc8, 0x16, 0x4a, 0xcd, 0x29, 0x3f, 0xd0, 0x6c,
+	0x96, 0x68, 0x9d, 0xac, 0x7e, 0x04, 0xee, 0xb3, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x50, 0x29, 0x41, 0xcb, 0x86, 0xe0, 0xe6, 0x50,
+	0x09, 0x74, 0xf3, 0xf4, 0x79, 0x40, 0x23, 0xd8, 0xd0, 0xd8, 0xe1, 0xc2,
+	0xe4, 0xe7, 0x87, 0xbf, 0x87, 0x98, 0xff, 0x1e, 0xa1, 0x18, 0xa9, 0x11,
+	0xdd, 0x0d, 0x89, 0xdb, 0x97, 0xb2, 0xd4, 0x93, 0x13, 0x32, 0xd9, 0x48,
+	0x46, 0x4e, 0xe4, 0x7f, 0x1c, 0x3b, 0x6f, 0x60, 0xd0, 0x75, 0x88, 0x6f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xdd, 0xf3, 0xdb,
+	0xc6, 0xc8, 0xca, 0x07, 0x40, 0xe9, 0x72, 0xa3, 0x87, 0xac, 0x4e, 0x08,
+	0xa0, 0x1d, 0xd8, 0xdc, 0x23, 0xf4, 0xe1, 0xcb, 0xca, 0x2a, 0xcd, 0xbb,
+	0x23, 0xf2, 0x52, 0x92, 0x5c, 0x29, 0x62, 0x39, 0x51, 0x66, 0x09, 0x3f,
+	0x96, 0x5c, 0x2e, 0xc7, 0x50, 0xa6, 0x56, 0x07, 0x66, 0x3f, 0x2b, 0x27,
+	0x02, 0x5d, 0x43, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x16, 0x87, 0x89, 0x08, 0x15, 0xbf, 0xb4, 0xbb, 0x04, 0xb9, 0xdf, 0x77,
+	0x4e, 0x6f, 0xde, 0x97, 0x61, 0x3c, 0x6a, 0xa5, 0xef, 0x5b, 0x4e, 0x15,
+	0x26, 0xe9, 0xbc, 0x92, 0xd9, 0xd3, 0xe3, 0xbd, 0x41, 0x3f, 0xb0, 0xe3,
+	0xc6, 0xfc, 0x75, 0xef, 0xb8, 0xb1, 0x31, 0x88, 0x1e, 0x95, 0x6a, 0xa1,
+	0x54, 0x0d, 0x4f, 0xfd, 0xb3, 0xa8, 0xe8, 0x9e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc5, 0xa6, 0xa2, 0xaa, 0x79, 0x6b,
+	0xdc, 0xc8, 0x5b, 0xe6, 0xda, 0xff, 0x69, 0x22, 0x19, 0x5f, 0x5e, 0x32,
+	0x31, 0xc4, 0x83, 0x30, 0xf6, 0xa6, 0xe3, 0x3d, 0xd4, 0xc8, 0xda, 0x4c,
+	0x33, 0xef, 0x38, 0x64, 0x4a, 0x92, 0x8e, 0x83, 0x04, 0xbc, 0x79, 0x12,
+	0x5d, 0x32, 0x59, 0x71, 0xa9, 0xc8, 0x7e, 0x55, 0xc7, 0x5f, 0x98, 0x10,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x56, 0x48, 0xfa,
+	0x0b, 0x31, 0x1e, 0xdf, 0xfb, 0x40, 0x81, 0xce, 0x2a, 0xf1, 0xf0, 0x85,
+	0x74, 0x0b, 0xd8, 0x5a, 0x63, 0xf0, 0xad, 0x4b, 0xc2, 0x30, 0xf5, 0x1f,
+	0xdb, 0xad, 0x34, 0xb0, 0xe5, 0xac, 0x0f, 0x59, 0xcd, 0x7f, 0x59, 0xcb,
+	0xac, 0xda, 0x7d, 0x3e, 0x2b, 0x77, 0x7c, 0x45, 0x88, 0x66, 0xe4, 0x87,
+	0x77, 0xba, 0x6e, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x38, 0x0e, 0xcd, 0x3e, 0x5c, 0x70, 0xdb, 0xb4, 0xf2, 0x59, 0x37, 0x36,
+	0xc6, 0xf6, 0x78, 0xa8, 0xfa, 0x67, 0xad, 0xad, 0x96, 0x50, 0xf4, 0xe1,
+	0x3c, 0x65, 0xd0, 0x01, 0x59, 0x08, 0x86, 0x96, 0x67, 0x9f, 0x1f, 0x27,
+	0xd4, 0xa5, 0x9d, 0xd7, 0xf2, 0x57, 0xc2, 0x81, 0x3b, 0x1d, 0xe7, 0xaa,
+	0x10, 0xfb, 0x10, 0xa0, 0xe1, 0x25, 0x5a, 0x55, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa9, 0xd1, 0x51, 0x65, 0x95, 0xdd, 0x6f, 0x89,
+	0xad, 0xcc, 0x2a, 0x76, 0xc3, 0x98, 0x26, 0x37, 0x51, 0x07, 0x98, 0x8f,
+	0x85, 0xad, 0x55, 0x38, 0x5e, 0x15, 0x4f, 0x1c, 0xe6, 0x0b, 0xe5, 0x28,
+	0x9c, 0xac, 0xc2, 0x5a, 0x73, 0x23, 0x14, 0x01, 0x71, 0x71, 0x04, 0x47,
+	0xb4, 0xd2, 0x8a, 0x77, 0x2e, 0x22, 0x42, 0xfa, 0xf0, 0x82, 0x86, 0x70,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x1a, 0x11, 0x5a,
+	0x4a, 0xea, 0xae, 0x0a, 0x88, 0x53, 0x09, 0x1a, 0x75, 0xc4, 0x40, 0x1d,
+	0x74, 0x03, 0x44, 0xc8, 0xe3, 0xca, 0x1b, 0xab, 0xee, 0x22, 0xb3, 0xc1,
+	0xef, 0xe6, 0xb8, 0x16, 0x29, 0x07, 0xd8, 0x0b, 0x7e, 0x67, 0xcb, 0xea,
+	0xbd, 0x27, 0x8e, 0x0f, 0x28, 0xac, 0xe6, 0x6d, 0x47, 0x5d, 0x6f, 0x17,
+	0xa2, 0xf8, 0x5d, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x48, 0xea, 0x89, 0x16, 0x74, 0x70, 0x2c, 0x27, 0x93, 0x3a, 0xe7, 0x20,
+	0x03, 0xd8, 0x35, 0x5c, 0xae, 0xaa, 0x2e, 0xc8, 0x45, 0xf3, 0x13, 0xcf,
+	0x65, 0x8d, 0x10, 0x93, 0x53, 0xac, 0x9b, 0x68, 0xf9, 0x03, 0x46, 0x41,
+	0xf4, 0xc5, 0x9e, 0x04, 0x94, 0x79, 0x6e, 0x6f, 0x8c, 0xf5, 0x09, 0x0d,
+	0xfe, 0x92, 0x82, 0x98, 0x01, 0x68, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0x7c, 0x5d, 0xa1, 0x01, 0x26, 0xe6, 0x0a,
+	0x7d, 0x9c, 0xb0, 0xbf, 0x8b, 0xd0, 0x64, 0x3c, 0x38, 0x19, 0x81, 0x43,
+	0x4a, 0x57, 0xfd, 0x7a, 0x93, 0xc7, 0xc8, 0x0a, 0x2e, 0x56, 0x49, 0x07,
+	0x6e, 0x7d, 0x64, 0xed, 0x2b, 0x86, 0x53, 0x9f, 0x95, 0x74, 0xa7, 0x69,
+	0x3d, 0x96, 0x41, 0xb8, 0xca, 0x02, 0xfd, 0xf0, 0xa4, 0xc7, 0x18, 0x49,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x54, 0xe4, 0x81,
+	0xa7, 0xb6, 0x5e, 0x08, 0xe6, 0x8b, 0xc5, 0xb0, 0xad, 0x5a, 0xe3, 0x09,
+	0x31, 0xe5, 0x2b, 0x5d, 0xa1, 0x4f, 0xac, 0x93, 0x49, 0x22, 0xac, 0xfc,
+	0x61, 0x47, 0x51, 0xde, 0xae, 0x8a, 0xd9, 0x9f, 0xcb, 0x9f, 0xcf, 0x78,
+	0xa5, 0x13, 0xf5, 0xcf, 0xd3, 0xc1, 0x49, 0x5a, 0x7b, 0x8e, 0xf0, 0x5e,
+	0xad, 0x9d, 0x6e, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x94, 0x0a, 0x05, 0x03, 0x02, 0x48, 0xa0, 0x7a, 0xd0, 0x3e, 0x53, 0x73,
+	0x6a, 0x9c, 0xee, 0x03, 0x98, 0xe2, 0x60, 0x2a, 0x65, 0x78, 0xbd, 0x89,
+	0x8b, 0x00, 0x67, 0x61, 0x20, 0x81, 0x49, 0xbc, 0xc9, 0x3b, 0x4f, 0x19,
+	0x91, 0x54, 0xba, 0x9d, 0x7c, 0xe1, 0x80, 0xed, 0x74, 0x4f, 0x88, 0x04,
+	0xf5, 0x9b, 0x56, 0xd3, 0x3c, 0x9c, 0xfb, 0xc0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xac, 0x49, 0xa7, 0x7e, 0x71, 0xf8, 0xba, 0x16,
+	0xaa, 0xda, 0x08, 0x92, 0x96, 0xbc, 0xa5, 0x33, 0x3e, 0xbc, 0xff, 0x50,
+	0xe0, 0xba, 0x41, 0x43, 0xeb, 0x2c, 0x10, 0x58, 0x9f, 0x85, 0xa7, 0xd9,
+	0xb1, 0x2d, 0x3a, 0xb4, 0x62, 0x08, 0x91, 0x73, 0xaa, 0x42, 0x1e, 0x96,
+	0x63, 0xf3, 0x1b, 0xaf, 0xcf, 0x76, 0x7b, 0x41, 0x8b, 0x69, 0x26, 0x05,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xa3, 0x1f, 0xb3,
+	0x67, 0xef, 0x7b, 0xfb, 0x4b, 0xfc, 0x59, 0x9e, 0xe7, 0xab, 0xb6, 0x35,
+	0xa2, 0xf1, 0xdf, 0xd6, 0x1d, 0x9e, 0xbb, 0xfd, 0x91, 0x6a, 0x7f, 0x0c,
+	0xc6, 0x2c, 0x07, 0x69, 0x64, 0xd0, 0xda, 0xb3, 0xc6, 0xbf, 0x62, 0x1e,
+	0x4d, 0x48, 0xd5, 0xb4, 0xa4, 0x43, 0xff, 0x91, 0x87, 0xc6, 0x54, 0x10,
+	0xf9, 0xd6, 0xb3, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x4f, 0x95, 0x17, 0xe1, 0xf7, 0x38, 0x63, 0x16, 0x3b, 0x02, 0x2f, 0x5a,
+	0x45, 0x64, 0xf1, 0x93, 0xa1, 0xf1, 0xe4, 0x29, 0x62, 0x7c, 0x0c, 0x50,
+	0x3b, 0x49, 0x55, 0x86, 0x9d, 0xc3, 0xe7, 0xf8, 0xc4, 0x65, 0x30, 0x58,
+	0xee, 0x3e, 0x1f, 0x9b, 0x6f, 0x2a, 0xea, 0x23, 0x27, 0x9a, 0x0e, 0xe7,
+	0x6b, 0x96, 0x4b, 0xcb, 0x21, 0xae, 0x1b, 0x3a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xa6, 0x88, 0x80, 0x5b, 0xfb, 0x9f, 0xee, 0x70,
+	0x2b, 0xd4, 0xb4, 0x7d, 0x2c, 0x05, 0x9a, 0xea, 0x0b, 0xa5, 0xeb, 0xc0,
+	0x9f, 0x6c, 0x66, 0x8c, 0xc5, 0x6a, 0x36, 0x87, 0x04, 0xd2, 0x1a, 0x83,
+	0xa5, 0xcf, 0x38, 0xd9, 0x74, 0x52, 0xd3, 0x9c, 0xeb, 0xa4, 0xf9, 0x26,
+	0xf3, 0xc0, 0xdc, 0x94, 0xc0, 0x7f, 0x54, 0x87, 0x62, 0x77, 0x2d, 0x4c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x16, 0x58, 0x49,
+	0xb1, 0x96, 0x15, 0x03, 0x33, 0x7e, 0x44, 0xc4, 0xd6, 0xa6, 0xcb, 0x61,
+	0x57, 0x2b, 0x93, 0x72, 0x8b, 0xad, 0x37, 0xbf, 0x80, 0x3d, 0x79, 0x52,
+	0x0c, 0x18, 0x30, 0x38, 0xc9, 0x69, 0xec, 0x11, 0x45, 0x14, 0x9e, 0xe5,
+	0x47, 0x4d, 0xbb, 0x1b, 0x2c, 0x91, 0x6d, 0x6e, 0x09, 0xf7, 0xbc, 0xc9,
+	0x25, 0x12, 0x98, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc1, 0x16, 0xd7, 0xe8, 0x42, 0x8e, 0xa5, 0x9a, 0xc4, 0x93, 0xc7, 0x86,
+	0x84, 0x45, 0x8e, 0x0f, 0x05, 0x20, 0xfa, 0x16, 0xad, 0xcc, 0x8a, 0x10,
+	0x99, 0x1b, 0x69, 0x56, 0x19, 0xb2, 0x99, 0xc3, 0x2f, 0x4a, 0xf8, 0x11,
+	0x87, 0x99, 0x26, 0x14, 0x81, 0x71, 0xc6, 0x77, 0x84, 0x6b, 0x8d, 0xe2,
+	0xc8, 0xf1, 0x9a, 0x5a, 0x66, 0x67, 0x7d, 0x52, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xbd, 0xd3, 0x7a, 0x37, 0x12, 0x9e, 0xc2, 0x18,
+	0x96, 0x1d, 0x51, 0x31, 0xd9, 0x28, 0xcd, 0x7d, 0xc3, 0x07, 0x9d, 0x98,
+	0xcf, 0x06, 0x82, 0x77, 0xa7, 0xbf, 0xb0, 0xae, 0x7d, 0x8a, 0xc3, 0x0d,
+	0x65, 0xe9, 0x66, 0x91, 0xb6, 0xff, 0x97, 0xb8, 0x67, 0xad, 0x51, 0xd0,
+	0xae, 0x5b, 0x70, 0x7a, 0x25, 0x6e, 0x41, 0x58, 0x62, 0xc3, 0xc8, 0xcb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xb1, 0x7f,
+	0xfd, 0x70, 0x84, 0xba, 0x1e, 0xcf, 0x48, 0x23, 0xcd, 0x84, 0xdf, 0x17,
+	0x06, 0x1e, 0x97, 0x93, 0xad, 0x67, 0x18, 0x97, 0xee, 0xc8, 0xd8, 0x6a,
+	0x20, 0x89, 0x5a, 0x9e, 0x54, 0x9c, 0xd7, 0x22, 0x4b, 0xde, 0x69, 0xfd,
+	0x6b, 0x28, 0xbb, 0x68, 0xfa, 0x05, 0x42, 0xe7, 0x79, 0x65, 0xe5, 0x6d,
+	0x16, 0x71, 0x76, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x6c, 0x12, 0x82, 0xb8, 0x7e, 0x03, 0x01, 0x68, 0x5a, 0x51, 0x60, 0xf1,
+	0xe3, 0xd0, 0x45, 0x67, 0x2f, 0x47, 0x4d, 0xb4, 0x97, 0x5c, 0xbd, 0x13,
+	0x50, 0x89, 0xfe, 0x19, 0x4e, 0x4f, 0xad, 0x05, 0x17, 0x3a, 0x84, 0x33,
+	0xaa, 0x15, 0x75, 0xdb, 0x59, 0x34, 0x4c, 0x01, 0xa2, 0x54, 0xc3, 0x21,
+	0x4e, 0xbd, 0x2b, 0xf3, 0x23, 0x19, 0xef, 0xa0, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfa, 0x3e, 0x81, 0xb5, 0xd9, 0xe3, 0x5e, 0x50,
+	0xa9, 0x76, 0xc7, 0x31, 0x06, 0x82, 0xf1, 0xc8, 0xc6, 0x6c, 0x9f, 0xa6,
+	0xad, 0x6b, 0x6d, 0x1b, 0x1d, 0x2f, 0xa1, 0x01, 0xd7, 0x72, 0x99, 0x08,
+	0xc1, 0x2f, 0x29, 0xe4, 0x63, 0xc0, 0x32, 0x66, 0x7f, 0x32, 0x55, 0xbd,
+	0x93, 0x0f, 0x10, 0xef, 0x83, 0x29, 0x35, 0x55, 0xba, 0xe0, 0x8c, 0x3f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x71, 0x81, 0x3f,
+	0x62, 0x01, 0xb6, 0x6d, 0xe0, 0x21, 0xac, 0x3a, 0x82, 0x88, 0x77, 0x61,
+	0x3c, 0xea, 0xa0, 0x07, 0x7d, 0x10, 0xd7, 0xaf, 0x17, 0xef, 0x0a, 0x4e,
+	0x44, 0xb4, 0x8b, 0x65, 0x3b, 0x58, 0xc6, 0xb0, 0xec, 0x88, 0x69, 0xb5,
+	0x7a, 0x03, 0xf1, 0xdc, 0x36, 0x05, 0x20, 0xfc, 0xcd, 0xe5, 0x6c, 0x3a,
+	0x19, 0xb3, 0x62, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5c, 0x7c, 0x07, 0xc6, 0xb7, 0x1f, 0x25, 0xdf, 0x7d, 0x8d, 0x81, 0x61,
+	0xeb, 0x3e, 0xbf, 0xe7, 0x10, 0x81, 0xf1, 0x85, 0x40, 0xcb, 0x60, 0xf1,
+	0xae, 0x1a, 0xba, 0xc5, 0xda, 0x60, 0x1c, 0x0f, 0x6d, 0x47, 0xfd, 0xa2,
+	0x56, 0x13, 0x67, 0x02, 0x7c, 0xd9, 0xc5, 0x56, 0x32, 0x69, 0x12, 0xc7,
+	0x8f, 0x2f, 0x31, 0x2c, 0x0f, 0xd2, 0x94, 0x69, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0x20, 0x93, 0x21, 0xb2, 0x35, 0xf1,
+	0x80, 0x14, 0x8e, 0xf1, 0x0c, 0x28, 0x62, 0x8d, 0xb8, 0xcf, 0x6c, 0x9e,
+	0xf6, 0xdb, 0x18, 0x16, 0x0b, 0xbd, 0xe9, 0xb4, 0xa3, 0x75, 0xee, 0xb2,
+	0x55, 0x1e, 0x4c, 0xc7, 0xa7, 0x74, 0xe8, 0x0e, 0x8f, 0xb7, 0xa8, 0x04,
+	0xf3, 0xeb, 0x1c, 0x35, 0xd6, 0x1d, 0x1b, 0x2a, 0x51, 0x10, 0xa2, 0x67,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x1c, 0x40, 0x29,
+	0xfa, 0x43, 0x18, 0x0c, 0x4c, 0xc0, 0xcd, 0x55, 0x99, 0xd0, 0xb9, 0xb4,
+	0x55, 0x69, 0x7d, 0xad, 0x99, 0xb8, 0xec, 0x62, 0x0c, 0x3b, 0x71, 0x11,
+	0xf0, 0xba, 0x59, 0x19, 0x93, 0xef, 0xcd, 0x2c, 0x29, 0x02, 0x8b, 0x76,
+	0x85, 0x21, 0xc1, 0xad, 0x72, 0x67, 0x87, 0xd1, 0x8f, 0xc6, 0x05, 0xe7,
+	0x82, 0x4e, 0x95, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
 const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p192,
@@ -1267,7 +1835,15 @@ const struct ae_fpm_entry ae_fpm_tbl_scalar[ROC_AE_EC_ID_PMAX] = {
 	{
 		.data = ae_fpm_tbl_p256_sm2,
 		.len = sizeof(ae_fpm_tbl_p256_sm2)
-	}
+	},
+	{
+		.data = ae_fpm_tbl_ed25519,
+		.len = sizeof(ae_fpm_tbl_ed25519)
+	},
+	{
+		.data = ae_fpm_tbl_ed448,
+		.len = sizeof(ae_fpm_tbl_ed448)
+	},
 };
 
 int
diff --git a/drivers/crypto/cnxk/cnxk_ae.h b/drivers/crypto/cnxk/cnxk_ae.h
index ef9cb5eb91..efb3ace7c0 100644
--- a/drivers/crypto/cnxk/cnxk_ae.h
+++ b/drivers/crypto/cnxk/cnxk_ae.h
@@ -15,6 +15,8 @@
 
 #define ASYM_SESS_SIZE sizeof(struct rte_cryptodev_asym_session)
 
+#define CNXK_AE_EDDSA_MAX_PARAM_LEN 1024
+
 struct cnxk_ae_sess {
 	uint8_t rte_sess[ASYM_SESS_SIZE];
 	enum rte_crypto_asym_xform_type xfrm_type;
@@ -25,10 +27,12 @@ struct cnxk_ae_sess {
 	};
 	uint64_t *cnxk_fpm_iova;
 	struct roc_ae_ec_group **ec_grp;
+	uint64_t cpt_inst_w4;
 	uint64_t cpt_inst_w7;
 	uint64_t cpt_inst_w2;
 	struct cnxk_cpt_qp *qp;
 	struct roc_cpt_lf *lf;
+	uint64_t msg_max_sz;
 	struct hw_ctx_s {
 		union {
 			struct {
@@ -181,10 +185,10 @@ cnxk_ae_fill_rsa_params(struct cnxk_ae_sess *sess,
 }
 
 static __rte_always_inline int
-cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
-		       struct rte_crypto_asym_xform *xform)
+cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess, struct rte_crypto_asym_xform *xform)
 {
 	struct roc_ae_ec_ctx *ec = &sess->ec_ctx;
+	union cpt_inst_w4 w4;
 
 	switch (xform->ec.curve_id) {
 	case RTE_CRYPTO_EC_GROUP_SECP192R1:
@@ -205,6 +209,14 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_EC_GROUP_SM2:
 		ec->curveid = ROC_AE_EC_ID_SM2;
 		break;
+	case RTE_CRYPTO_EC_GROUP_ED25519:
+		ec->curveid = ROC_AE_EC_ID_ED25519;
+		w4.s.param1 = ROC_AE_ED_PARAM1_25519;
+		break;
+	case RTE_CRYPTO_EC_GROUP_ED448:
+		ec->curveid = ROC_AE_EC_ID_ED448;
+		w4.s.param1 = ROC_AE_ED_PARAM1_448;
+		break;
 	default:
 		/* Only NIST curves (FIPS 186-4) and SM2 are supported */
 		return -EINVAL;
@@ -225,12 +237,22 @@ cnxk_ae_fill_ec_params(struct cnxk_ae_sess *sess,
 	if (ec->q.x.length)
 		rte_memcpy(ec->q.x.data, xform->ec.q.x.data, ec->q.x.length);
 
+	if (xform->xform_type == RTE_CRYPTO_ASYM_XFORM_EDDSA) {
+		w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+
+		/* Use q.x to store compressed public key. q.y is set to 0 */
+		ec->q.y.length = 0;
+		goto _exit;
+	}
+
 	ec->q.y.length = xform->ec.q.y.length;
 	if (ec->q.y.length > ROC_AE_EC_DATA_MAX)
 		ec->q.y.length = ROC_AE_EC_DATA_MAX;
 	if (xform->ec.q.y.length)
 		rte_memcpy(ec->q.y.data, xform->ec.q.y.data, ec->q.y.length);
 
+_exit:
+	sess->cpt_inst_w4 = w4.u64;
 	return 0;
 }
 
@@ -241,6 +263,7 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
 	int ret;
 
 	sess->xfrm_type = xform->xform_type;
+	sess->msg_max_sz = cnxk_cpt_asym_get_mlen();
 
 	switch (xform->xform_type) {
 	case RTE_CRYPTO_ASYM_XFORM_RSA:
@@ -255,6 +278,7 @@ cnxk_ae_fill_session_parameters(struct cnxk_ae_sess *sess,
 	case RTE_CRYPTO_ASYM_XFORM_ECPM:
 	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
 		ret = cnxk_ae_fill_ec_params(sess, xform);
 		break;
 	default:
@@ -736,6 +760,310 @@ cnxk_ae_enqueue_ecdsa_op(struct rte_crypto_op *op,
 	return 0;
 }
 
+static __rte_always_inline void
+cnxk_ae_eddsa_sign_prep(struct rte_crypto_eddsa_op_param *eddsa, struct roc_ae_buf_ptr *meta_buf,
+			uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
+			struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t pkey_len = sess->ec_ctx.pkey.length;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint16_t ctx_align, k_align;
+	uint8_t pub = 0, ph = 0;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint8_t ctx_len = 0;
+	uint16_t iv_len = 0;
+	uint64_t ctrl = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+	    eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519)
+		iv_len = sizeof(iv_sha512);
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	if (pubkey_len)
+		pub = 1;
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pkey_len, 8);
+
+	/* Set control word */
+	ctrl = message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(priv and
+	 * pubkey len), ROUNDUP8(context len) and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) + sizeof(ctrl) + prime_len * 3 +
+		k_align * 2 + ctx_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.pkey.data, pkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.u64 = sess->cpt_inst_w4;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_SIGN;
+	w4.s.param1 |= ((pub << ROC_AE_ED_PARAM1_KEYGEN_BIT) | (ph << ROC_AE_EC_PARAM1_PH_BIT));
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline void
+cnxk_ae_eddsa_verify_prep(struct rte_crypto_eddsa_op_param *eddsa, struct roc_ae_buf_ptr *meta_buf,
+			  uint64_t fpm_table_iova, struct roc_ae_ec_group *ec_grp,
+			  struct cnxk_ae_sess *sess, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	const uint8_t domx_ed25519[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35,
+		0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
+		0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
+		0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
+		0x00, 0x00};
+	const uint8_t domx_ed448[] = {
+		0x53, 0x69, 0x67, 0x45, 0x64, 0x34, 0x34, 0x38,
+		0x00, 0x00};
+
+	uint16_t pubkey_len = sess->ec_ctx.q.x.length;
+	uint16_t message_len = eddsa->message.length;
+	uint16_t s_len = eddsa->sign.length / 2;
+	uint8_t curveid = sess->ec_ctx.curveid;
+	uint16_t ctx_align, k_align, s_align;
+	const uint8_t *domx_ptr = NULL;
+	uint16_t order_len, prime_len;
+	uint64_t message_handle;
+	union cpt_inst_w4 w4;
+	uint8_t domx_len = 0;
+	uint16_t iv_len = 0;
+	uint8_t ctx_len = 0;
+	uint64_t ctrl = 0;
+	uint8_t ph = 0;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH ||
+	    eddsa->instance == RTE_CRYPTO_EDCURVE_448PH)
+		ph = 1;
+
+	if (curveid == ROC_AE_EC_ID_ED25519)
+		iv_len = sizeof(iv_sha512);
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	ctx_len = eddsa->context.length;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		if (ph || ctx_len) {
+			domx_ptr = domx_ed25519;
+			domx_len = sizeof(domx_ed25519);
+		}
+	} else {
+		domx_ptr = domx_ed448;
+		domx_len = sizeof(domx_ed448);
+	}
+
+	ctx_align = RTE_ALIGN_CEIL(ctx_len + domx_len, 8);
+	k_align = RTE_ALIGN_CEIL(pubkey_len, 8);
+	s_align = RTE_ALIGN_CEIL(s_len, 8);
+
+	/* Set control word */
+	ctrl = message_len;
+	ctrl |= (ctx_len + domx_len) << 16;
+
+	/* Copy message and set message handle in metabuf */
+	dptr = meta_buf->vaddr;
+	memcpy(dptr, eddsa->message.data, message_len);
+	message_handle = (uint64_t)dptr;
+	dptr += RTE_ALIGN_CEIL(message_len, 8);
+
+	/* Input buffer */
+	inst->dptr = (uintptr_t)dptr;
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), input handle, ctrl,
+	 * ROUNDUP8(prime len, order len, constant), ROUNDUP8(pub key len),
+	 * ROUNDUP8(s and r len), context and iv len (if ED25519)).
+	 */
+	dlen = sizeof(fpm_table_iova) + sizeof(message_handle) + sizeof(ctrl) + prime_len * 3 +
+		k_align + s_align * 2 +	ctx_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(message_handle);
+	dptr += sizeof(message_handle);
+
+	*(uint64_t *)dptr = rte_cpu_to_be_64(ctrl);
+	dptr += sizeof(ctrl);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, sess->ec_ctx.q.x.data, pubkey_len);
+	dptr += k_align;
+
+	memcpy(dptr, eddsa->sign.data, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, eddsa->sign.data + s_len, s_len);
+	dptr += s_align;
+
+	memcpy(dptr, domx_ptr, domx_len);
+	if (eddsa->instance != RTE_CRYPTO_EDCURVE_25519) {
+		memset(dptr + (domx_len - 1), ctx_len, 1);
+		memset(dptr + (domx_len - 2), ph, 1);
+	}
+
+	memcpy(dptr + domx_len, eddsa->context.data, ctx_len);
+	dptr += ctx_align;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, iv_len);
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.u64 = sess->cpt_inst_w4;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_VERIFY;
+
+	w4.s.param1 |= (ph << ROC_AE_EC_PARAM1_PH_BIT);
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+}
+
+static __rte_always_inline int __rte_hot
+cnxk_ae_enqueue_eddsa_op(struct rte_crypto_op *op, struct roc_ae_buf_ptr *meta_buf,
+			 struct cnxk_ae_sess *sess, uint64_t *fpm_iova,
+			 struct roc_ae_ec_group **ec_grp, struct cpt_inst_s *inst)
+{
+	struct rte_crypto_eddsa_op_param *eddsa = &op->asym->eddsa;
+	uint8_t curveid = sess->ec_ctx.curveid;
+
+	if (eddsa->message.length > (sess->msg_max_sz - CNXK_AE_EDDSA_MAX_PARAM_LEN)) {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+		cnxk_ae_eddsa_sign_prep(eddsa, meta_buf, fpm_iova[curveid], ec_grp[curveid], sess,
+					  inst);
+	else if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		cnxk_ae_eddsa_verify_prep(eddsa, meta_buf, fpm_iova[curveid], ec_grp[curveid], sess,
+					  inst);
+	else {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static __rte_always_inline void
 cnxk_ae_sm2_sign_prep(struct rte_crypto_sm2_op_param *sm2,
 			struct roc_ae_buf_ptr *meta_buf,
@@ -1004,6 +1332,81 @@ cnxk_ae_ecfpm_prep(rte_crypto_param *scalar,
 	return 0;
 }
 
+static __rte_always_inline int
+cnxk_ae_edfpm_prep(rte_crypto_param *scalar, struct roc_ae_buf_ptr *meta_buf, uint64_t *fpm_iova,
+		   struct roc_ae_ec_group *ec_grp, uint8_t curveid, struct cpt_inst_s *inst)
+{
+	const uint8_t iv_sha512[] = {
+		0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
+		0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
+		0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+		0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
+		0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
+		0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+		0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
+		0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79};
+	uint16_t dlen, prime_len, order_len, iv_len;
+	uint64_t fpm_table_iova;
+	uint16_t scalar_align;
+	union cpt_inst_w4 w4;
+	uint16_t prime_bit;
+	uint8_t *dptr;
+
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		prime_bit = ROC_AE_ED_PARAM1_25519;
+		iv_len = sizeof(iv_sha512);
+	} else {
+		prime_bit = ROC_AE_ED_PARAM1_448;
+		iv_len = 0;
+	}
+
+	prime_len = ec_grp->prime.length;
+	order_len = ec_grp->order.length;
+	fpm_table_iova = (uint64_t)fpm_iova[curveid];
+
+	/* Input buffer */
+	dptr = meta_buf->vaddr;
+	inst->dptr = (uintptr_t)dptr;
+
+	scalar_align = RTE_ALIGN_CEIL(scalar->length, 8);
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(prime len, order len, constant,
+	 * private key len and iv len (if ED25519))).
+	 */
+	dlen = sizeof(fpm_table_iova) + 3 * prime_len + scalar_align + iv_len;
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr, ec_grp->prime.data, prime_len);
+	dptr += prime_len;
+	memcpy(dptr, ec_grp->order.data, order_len);
+	dptr += prime_len;
+	memcpy(dptr, ec_grp->consta.data, prime_len);
+	dptr += prime_len;
+
+	memcpy(dptr, scalar->data, scalar->length);
+	dptr += scalar_align;
+	if (curveid == ROC_AE_EC_ID_ED25519) {
+		memcpy(dptr, iv_sha512, sizeof(iv_sha512));
+		dptr += iv_len;
+	}
+
+	/* Setup opcodes */
+	w4.s.opcode_major = ROC_AE_MAJOR_OP_EDDSA;
+	w4.s.opcode_minor = ROC_AE_MINOR_OP_ED_KEYGEN;
+
+	w4.s.param1 = prime_bit;
+	w4.s.param2 = 0;
+	w4.s.dlen = dlen;
+
+	inst->w4.u64 = w4.u64;
+	inst->rptr = (uintptr_t)dptr;
+
+	return 0;
+}
+
 static __rte_always_inline int
 cnxk_ae_ecpm_prep(rte_crypto_param *scalar, struct rte_crypto_ec_point *p,
 		  struct roc_ae_buf_ptr *meta_buf,
@@ -1112,8 +1515,12 @@ cnxk_ae_enqueue_ecdh_op(struct rte_crypto_op *op,
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		scalar.data = sess->ec_ctx.pkey.data;
 		scalar.length = sess->ec_ctx.pkey.length;
-		cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
-			curveid, inst);
+		if (curveid == ROC_AE_EC_ID_ED25519 || curveid == ROC_AE_EC_ID_ED448)
+			cnxk_ae_edfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
+		else
+			cnxk_ae_ecfpm_prep(&scalar, meta_buf, fpm_iova, ec_grp[curveid],
+				curveid, inst);
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		scalar.data = ec_grp[curveid]->order.data;
@@ -1212,6 +1619,25 @@ cnxk_ae_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa, uint8_t *rptr,
 	ecdsa->s.length = prime_len;
 }
 
+static __rte_always_inline void
+cnxk_ae_dequeue_eddsa_op(struct rte_crypto_eddsa_op_param *eddsa, uint8_t *rptr)
+{
+	if (eddsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	if (eddsa->instance == RTE_CRYPTO_EDCURVE_25519 ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519CTX ||
+		eddsa->instance == RTE_CRYPTO_EDCURVE_25519PH) {
+		eddsa->sign.length = 64;
+		memcpy(eddsa->sign.data, rptr, eddsa->sign.length);
+	} else {
+		eddsa->sign.length = 114;
+		memcpy(eddsa->sign.data, rptr, 57);
+		memcpy(eddsa->sign.data + 57, rptr + 64, 57);
+	}
+}
+
 static __rte_always_inline void
 cnxk_ae_dequeue_sm2_op(struct rte_crypto_sm2_op_param *sm2, uint8_t *rptr,
 			 struct roc_ae_ec_ctx *ec,
@@ -1245,7 +1671,7 @@ cnxk_ae_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param *ecpm, uint8_t *rptr,
 static __rte_always_inline void
 cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 			struct roc_ae_ec_ctx *ec,
-			struct roc_ae_ec_group **ec_grp)
+			struct roc_ae_ec_group **ec_grp, uint16_t flags)
 {
 	int prime_len = ec_grp[ec->curveid]->prime.length;
 
@@ -1256,9 +1682,12 @@ cnxk_ae_dequeue_ecdh_op(struct rte_crypto_ecdh_op_param *ecdh, uint8_t *rptr,
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE:
 		memcpy(ecdh->pub_key.x.data, rptr, prime_len);
-		memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8), prime_len);
 		ecdh->pub_key.x.length = prime_len;
-		ecdh->pub_key.y.length = prime_len;
+		if (!(flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED)) {
+			memcpy(ecdh->pub_key.y.data, rptr + RTE_ALIGN_CEIL(prime_len, 8),
+				prime_len);
+			ecdh->pub_key.y.length = prime_len;
+		}
 		break;
 	case RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY:
 		break;
@@ -1328,6 +1757,13 @@ cnxk_ae_enqueue(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		ret = cnxk_ae_enqueue_eddsa_op(op, &meta_buf, sess,
+					       sess->cnxk_fpm_iova,
+					       sess->ec_grp, inst);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		ret = cnxk_ae_enqueue_sm2_op(op, &meta_buf, sess,
 					       sess->cnxk_fpm_iova,
@@ -1390,6 +1826,9 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		cnxk_ae_dequeue_ecdsa_op(&op->ecdsa, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+		cnxk_ae_dequeue_eddsa_op(&op->eddsa, rptr);
+		break;
 	case RTE_CRYPTO_ASYM_XFORM_SM2:
 		cnxk_ae_dequeue_sm2_op(&op->sm2, rptr, &sess->ec_ctx,
 					 sess->ec_grp);
@@ -1401,7 +1840,7 @@ cnxk_ae_post_process(struct rte_crypto_op *cop, struct cnxk_ae_sess *sess,
 		break;
 	case RTE_CRYPTO_ASYM_XFORM_ECDH:
 		cnxk_ae_dequeue_ecdh_op(&op->ecdh, rptr, &sess->ec_ctx,
-					sess->ec_grp);
+					sess->ec_grp, op->flags);
 		break;
 	default:
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev.h b/drivers/crypto/cnxk/cnxk_cryptodev.h
index 4000e84a7e..5cec64c2e1 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev.h
@@ -11,7 +11,7 @@
 #include "roc_ae.h"
 #include "roc_cpt.h"
 
-#define CNXK_CPT_MAX_CAPS		 55
+#define CNXK_CPT_MAX_CAPS		 56
 #define CNXK_SEC_IPSEC_CRYPTO_MAX_CAPS	 16
 #define CNXK_SEC_TLS_1_3_CRYPTO_MAX_CAPS 3
 #define CNXK_SEC_TLS_1_2_CRYPTO_MAX_CAPS 7
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
index 0d5d64b6e7..3897feacb8 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_capabilities.c
@@ -1201,6 +1201,22 @@ static const struct rte_cryptodev_capabilities caps_sm2[] = {
 	}
 };
 
+static const struct rte_cryptodev_capabilities caps_eddsa[] = {
+	{	/* EDDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+				.hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+					       1 << RTE_CRYPTO_AUTH_SHAKE_256),
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					     (1 << RTE_CRYPTO_ASYM_OP_VERIFY))
+			}
+		}
+		}
+	}
+};
+
 static const struct rte_cryptodev_capabilities caps_end[] = {
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1940,6 +1956,9 @@ cn10k_crypto_caps_add(struct rte_cryptodev_capabilities cnxk_caps[],
 
 	if (hw_caps[CPT_ENG_TYPE_AE].sm2)
 		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, sm2);
+
+	if (hw_caps[CPT_ENG_TYPE_AE].eddsa)
+		CPT_CAPS_ADD(cnxk_caps, cur_pos, hw_caps, eddsa);
 }
 
 static void
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
index cfcfa79fdf..3bb4101946 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c
@@ -65,7 +65,7 @@ cnxk_cpt_sec_get_mlen(void)
 	return len;
 }
 
-static int
+int
 cnxk_cpt_asym_get_mlen(void)
 {
 	uint32_t len;
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
index caf6ac35e5..bc05266552 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
@@ -104,6 +104,8 @@ struct cnxk_cpt_qp {
 	/**< Session mempool */
 };
 
+int cnxk_cpt_asym_get_mlen(void);
+
 int cnxk_cpt_dev_config(struct rte_cryptodev *dev,
 			struct rte_cryptodev_config *conf);
 
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v6 4/6] test/crypto: add asymmetric EDDSA test cases
  2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
  2024-10-04  8:26             ` [PATCH v6 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
  2024-10-04  8:26             ` [PATCH v6 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
@ 2024-10-04  8:26             ` Gowrishankar Muthukrishnan
  2024-10-04  8:26             ` [PATCH v6 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
                               ` (2 subsequent siblings)
  5 siblings, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  8:26 UTC (permalink / raw)
  To: dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, bruce.richardson, jerinj, arkadiuszx.kusztal,
	kai.ji, jack.bond-preston, david.marchand, hemant.agrawal,
	pablo.de.lara.guarch, fiona.trahe, declan.doherty, matan,
	ruifeng.wang, Gowrishankar Muthukrishnan

Add test cases to validate EDDSA sign and verify ops,
as per RFC 8032.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test/test_cryptodev_asym.c               | 345 +++++++++++-
 app/test/test_cryptodev_ecdh_test_vectors.h  |  94 +++-
 app/test/test_cryptodev_ecdsa_test_vectors.h |   4 +
 app/test/test_cryptodev_eddsa_test_vectors.h | 556 +++++++++++++++++++
 4 files changed, 990 insertions(+), 9 deletions(-)
 create mode 100644 app/test/test_cryptodev_eddsa_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index f0b5d38543..893cc81770 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -20,6 +20,7 @@
 #include "test_cryptodev_ecdh_test_vectors.h"
 #include "test_cryptodev_ecdsa_test_vectors.h"
 #include "test_cryptodev_ecpm_test_vectors.h"
+#include "test_cryptodev_eddsa_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_sm2_test_vectors.h"
@@ -1631,6 +1632,9 @@ test_ecdsa_sign_verify_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
+		if (curve_id == ED25519 || curve_id == ED448)
+			continue;
+
 		status = test_ecdsa_sign_verify(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
@@ -1792,7 +1796,7 @@ test_ecpm_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecpm(curve_id);
@@ -1966,10 +1970,18 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	idx.type = RTE_CRYPTO_ASYM_XFORM_ECDH;
 	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
 	if (capa == NULL)
-		return -ENOTSUP;
+		return TEST_SKIPPED;
 
 	if (!(capa->op_types & (1 <<  RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)))
-		return -ENOTSUP;
+		return TEST_SKIPPED;
+
+	if (curve_id == ED25519 || curve_id == ED448) {
+		/* Check EDDSA capability */
+		idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+		if (capa == NULL)
+			return TEST_SKIPPED;
+	}
 
 	switch (curve_id) {
 	case SECP192R1:
@@ -1987,6 +1999,12 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	case SECP521R1:
 		input_params = ecdh_param_secp521r1;
 		break;
+	case ED25519:
+		input_params = ecdh_param_ed25519;
+		break;
+	case ED448:
+		input_params = ecdh_param_ed448;
+		break;
 	default:
 		RTE_LOG(ERR, USER1,
 				"line %u FAILED: %s", __LINE__,
@@ -2031,10 +2049,15 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 
 	/* Populate op with operational details */
 	asym_op->ecdh.ke_type = RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
 
 	/* Init out buf */
 	asym_op->ecdh.pub_key.x.data = output_buf_x;
-	asym_op->ecdh.pub_key.y.data = output_buf_y;
+	if (curve_id == ED25519 || curve_id == ED448)
+		asym_op->ecdh.pub_key.y.data = NULL;
+	else
+		asym_op->ecdh.pub_key.y.data = output_buf_y;
 
 	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
 
@@ -2073,8 +2096,13 @@ test_ecdh_pub_key_generate(enum curve curve_id)
 	debug_hexdump(stdout, "qy:",
 		asym_op->ecdh.pub_key.y.data, asym_op->ecdh.pub_key.y.length);
 
-	ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
+	if (curve_id == ED25519 || curve_id == ED448)
+		ret = memcmp(input_params.pubkey_qA_x.data, result_op->asym->ecdh.pub_key.x.data,
+			   result_op->asym->ecdh.pub_key.x.length);
+	else
+		ret = verify_ecdh_secret(input_params.pubkey_qA_x.data,
 				input_params.pubkey_qA_y.data, result_op);
+
 	if (ret) {
 		status = TEST_FAILED;
 		RTE_LOG(ERR, USER1,
@@ -2484,7 +2512,7 @@ test_ecdh_all_curve(void)
 	const char *msg;
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_priv_key_generate(curve_id);
@@ -2505,6 +2533,8 @@ test_ecdh_all_curve(void)
 		status = test_ecdh_pub_key_generate(curve_id);
 		if (status == TEST_SUCCESS) {
 			msg = "succeeded";
+		} else if (status == TEST_SKIPPED) {
+			msg = "skipped";
 		} else {
 			msg = "failed";
 			overall_status = status;
@@ -2514,7 +2544,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_pub_key_verify(curve_id);
@@ -2529,7 +2559,7 @@ test_ecdh_all_curve(void)
 	}
 
 	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
-		if (curve_id == SECP521R1_UA)
+		if (curve_id == SECP521R1_UA || curve_id == ED25519 || curve_id == ED448)
 			continue;
 
 		status = test_ecdh_shared_secret(curve_id);
@@ -3167,6 +3197,303 @@ test_sm2_dec(void)
 	return status;
 };
 
+static int
+test_eddsa_sign(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.data = input_params->pkey.data;
+	xform.ec.pkey.length = input_params->pkey.length;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	/* Init out buf */
+	asym_op->eddsa.sign.data = output_buf_r;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "sign:",
+			asym_op->eddsa.sign.data, asym_op->eddsa.sign.length);
+
+	/* Verify sign (by comparison). */
+	if (memcmp(input_params->sign.data, asym_op->eddsa.sign.data,
+			   asym_op->eddsa.sign.length) != 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"EDDSA sign failed.\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_verify(struct crypto_testsuite_eddsa_params *input_params)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	enum rte_crypto_edward_instance instance = input_params->instance;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_crypto_op *op = NULL;
+	int ret, status = TEST_FAILED;
+	void *sess = NULL;
+	bool ctx = false;
+
+	if (instance == RTE_CRYPTO_EDCURVE_25519CTX)
+		ctx = true;
+
+	/* Setup crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to allocate asymmetric crypto "
+				"operation struct\n");
+		goto exit;
+	}
+
+	asym_op = op->asym;
+
+	/* Setup asym xform */
+	xform.next = NULL;
+	xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform.ec.curve_id = input_params->curve;
+	xform.ec.pkey.length = 0;
+	xform.ec.q.x.data = input_params->pubkey.data;
+	xform.ec.q.x.length = input_params->pubkey.length;
+
+	ret = rte_cryptodev_asym_session_create(dev_id, &xform, sess_mpool, &sess);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = (ret == -ENOTSUP) ? TEST_SKIPPED : TEST_FAILED;
+		goto exit;
+	}
+
+	/* Attach asymmetric crypto session to crypto operations */
+	rte_crypto_op_attach_asym_session(op, sess);
+
+	/* Compute sign */
+
+	/* Populate op with operational details */
+	asym_op->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	asym_op->eddsa.instance = input_params->instance;
+	asym_op->eddsa.message.data = input_params->message.data;
+	asym_op->eddsa.message.length = input_params->message.length;
+	asym_op->eddsa.context.length = 0;
+	if (ctx) {
+		asym_op->eddsa.context.data = input_params->context.data;
+		asym_op->eddsa.context.length = input_params->context.length;
+	}
+
+	asym_op->eddsa.sign.data = input_params->sign.data;
+	asym_op->eddsa.sign.length = input_params->sign.length;
+
+	RTE_LOG(DEBUG, USER1, "Process ASYM operation\n");
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Error sending packet for operation\n");
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &result_op, 1) == 0)
+		rte_pause();
+
+	if (result_op == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Failed to process asym crypto op\n");
+		goto exit;
+	}
+
+	status = TEST_SUCCESS;
+exit:
+	if (sess != NULL)
+		rte_cryptodev_asym_session_free(dev_id, sess);
+	rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_eddsa_sign_verify_all_curve(void)
+{
+	struct crypto_testsuite_params_asym *ts_params = &testsuite_params;
+	const struct rte_cryptodev_asymmetric_xform_capability *capa;
+	struct crypto_testsuite_eddsa_params input_params;
+	struct rte_cryptodev_asym_capability_idx idx;
+	int status, overall_status = TEST_SUCCESS;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	uint8_t i, tc = 0;
+	const char *msg;
+
+	/* Check EDDSA capability */
+	idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	capa = rte_cryptodev_asym_capability_get(dev_id, &idx);
+	if (capa == NULL)
+		return TEST_SKIPPED;
+
+	/* Sign tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_sign(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Sign %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Verify tests */
+	for (i = 0; i < RTE_DIM(eddsa_test_params); i++) {
+		memcpy(&input_params, &eddsa_test_params[i],
+				sizeof(input_params));
+		status = test_eddsa_verify(&input_params);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Verify %s  %s\n",
+		       tc++, input_params.description, msg);
+	}
+
+	/* Negative tests */
+	memcpy(&input_params, &eddsa_test_params[1],
+			sizeof(input_params));
+	input_params.pubkey.data[0] ^= 0x01;
+
+	status = test_eddsa_sign(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Sign %s  %s\n",
+			tc++, input_params.description, msg);
+
+	status = test_eddsa_verify(&input_params);
+	if (status == TEST_FAILED) {
+		msg = "succeeded";
+	} else {
+		msg = "failed";
+		overall_status = status;
+	}
+	printf("  %u) TestCase Negative Verify %s  %s\n",
+			tc++, input_params.description, msg);
+
+	return overall_status;
+}
+
 static int send_one(void)
 {
 	int ticks = 0;
@@ -3543,6 +3870,7 @@ static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 			"Modex Group 18 test",
 			ut_setup_asym, ut_teardown_asym,
 			modular_exponentiation, &modex_group_test_cases[5]),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
@@ -3634,6 +3962,7 @@ static struct unit_test_suite cryptodev_octeontx_asym_testsuite  = {
 				test_ecdh_all_curve),
 		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym,
 				test_ecpm_all_curve),
+		TEST_CASE_ST(ut_setup_asym, ut_teardown_asym, test_eddsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_ecdh_test_vectors.h b/app/test/test_cryptodev_ecdh_test_vectors.h
index b577c179c8..36f92b223f 100644
--- a/app/test/test_cryptodev_ecdh_test_vectors.h
+++ b/app/test/test_cryptodev_ecdh_test_vectors.h
@@ -553,4 +553,96 @@ struct crypto_testsuite_ecdh_params ecdh_param_secp521r1 = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP521R1
 };
 
-#endif /* __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__ */
+/** ED25519 test vector */
+
+static uint8_t privkey_ed25519[] = {
+	0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+	0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+	0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+	0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+};
+
+static uint8_t pubkey_ed25519[] = {
+	0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+	0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+	0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+	0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+};
+
+/** ECDH ED25519 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed25519 = {
+	.pubkey_qA_x = {
+		.data = pubkey_ed25519,
+		.length = sizeof(pubkey_ed25519),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = privkey_ed25519,
+		.length = sizeof(privkey_ed25519),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519
+};
+
+/** ED448 test vector */
+
+static uint8_t privkey_ed448[] = {
+	0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+	0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+	0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+	0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+	0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+	0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+	0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+	0x01
+};
+
+static uint8_t pubkey_ed448[] = {
+	0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+	0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+	0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+	0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+	0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+	0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+	0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+	0x00
+};
+
+/** ECDH ED448 elliptic curve param */
+
+struct crypto_testsuite_ecdh_params ecdh_param_ed448 = {
+	.pubkey_qA_x = {
+		.data = pubkey_ed448,
+		.length = sizeof(pubkey_ed448),
+	},
+	.pubkey_qA_y = {
+	},
+	.pubkey_qB_x = {
+	},
+	.pubkey_qB_y = {
+	},
+	.pkey_A = {
+		.data = privkey_ed448,
+		.length = sizeof(privkey_ed448),
+	},
+	.pkey_B = {
+	},
+	.secret_x = {
+	},
+	.secret_y = {
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448
+};
+
+#endif /* __TEST_CRYPTODEV_ECDH_TEST_VECTORS_H__ */
diff --git a/app/test/test_cryptodev_ecdsa_test_vectors.h b/app/test/test_cryptodev_ecdsa_test_vectors.h
index f1477639ba..636a1ab1b2 100644
--- a/app/test/test_cryptodev_ecdsa_test_vectors.h
+++ b/app/test/test_cryptodev_ecdsa_test_vectors.h
@@ -15,6 +15,8 @@ enum curve {
 	SECP384R1,
 	SECP521R1,
 	SECP521R1_UA,
+	ED25519,
+	ED448,
 	END_OF_CURVE_LIST
 };
 
@@ -24,6 +26,8 @@ const char *curve[] = {"SECP192R1",
 		       "SECP384R1",
 		       "SECP521R1",
 		       "SECP521R1(unaligned)",
+		       "ED25519",
+		       "ED448",
 };
 
 struct crypto_testsuite_ecdsa_params {
diff --git a/app/test/test_cryptodev_eddsa_test_vectors.h b/app/test/test_cryptodev_eddsa_test_vectors.h
new file mode 100644
index 0000000000..47e5355ec7
--- /dev/null
+++ b/app/test/test_cryptodev_eddsa_test_vectors.h
@@ -0,0 +1,556 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifndef __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+#define DATA_SIZE 1024
+
+struct crypto_testsuite_eddsa_params {
+	enum rte_crypto_edward_instance instance;
+	enum rte_crypto_curve_id curve;
+	const char *description;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pubkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} pkey;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} sign;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} message;
+	struct {
+		uint8_t data[DATA_SIZE];
+		uint16_t length;
+	} context;
+};
+
+/** EDDSA curve test params (RFC 8032) */
+static const struct
+crypto_testsuite_eddsa_params eddsa_test_params[] = {
+{
+	.description = "EDDSA 25519 (msg=0)",
+	.pkey = {
+		.data = {
+			0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
+			0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4,
+			0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19,
+			0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7,
+			0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a,
+			0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25,
+			0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72,
+			0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a,
+			0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74,
+			0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55,
+			0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
+			0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b,
+			0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
+			0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1)",
+	.pkey = {
+		.data = {
+			0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+			0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+			0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+			0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+			0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+			0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+			0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+			0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+			0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+			0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+			0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+			0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+			0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+			0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x72
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519 (msg=1023)",
+	.pkey = {
+		.data = {
+			0xf5, 0xe5, 0x76, 0x7c, 0xf1, 0x53, 0x31, 0x95,
+			0x17, 0x63, 0x0f, 0x22, 0x68, 0x76, 0xb8, 0x6c,
+			0x81, 0x60, 0xcc, 0x58, 0x3b, 0xc0, 0x13, 0x74,
+			0x4c, 0x6b, 0xf2, 0x55, 0xf5, 0xcc, 0x0e, 0xe5
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0x27, 0x81, 0x17, 0xfc, 0x14, 0x4c, 0x72, 0x34,
+			0x0f, 0x67, 0xd0, 0xf2, 0x31, 0x6e, 0x83, 0x86,
+			0xce, 0xff, 0xbf, 0x2b, 0x24, 0x28, 0xc9, 0xc5,
+			0x1f, 0xef, 0x7c, 0x59, 0x7f, 0x1d, 0x42, 0x6e
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x0a, 0xab, 0x4c, 0x90, 0x05, 0x01, 0xb3, 0xe2,
+			0x4d, 0x7c, 0xdf, 0x46, 0x63, 0x32, 0x6a, 0x3a,
+			0x87, 0xdf, 0x5e, 0x48, 0x43, 0xb2, 0xcb, 0xdb,
+			0x67, 0xcb, 0xf6, 0xe4, 0x60, 0xfe, 0xc3, 0x50,
+			0xaa, 0x53, 0x71, 0xb1, 0x50, 0x8f, 0x9f, 0x45,
+			0x28, 0xec, 0xea, 0x23, 0xc4, 0x36, 0xd9, 0x4b,
+			0x5e, 0x8f, 0xcd, 0x4f, 0x68, 0x1e, 0x30, 0xa6,
+			0xac, 0x00, 0xa9, 0x70, 0x4a, 0x18, 0x8a, 0x03
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x08, 0xb8, 0xb2, 0xb7, 0x33, 0x42, 0x42, 0x43,
+			0x76, 0x0f, 0xe4, 0x26, 0xa4, 0xb5, 0x49, 0x08,
+			0x63, 0x21, 0x10, 0xa6, 0x6c, 0x2f, 0x65, 0x91,
+			0xea, 0xbd, 0x33, 0x45, 0xe3, 0xe4, 0xeb, 0x98,
+			0xfa, 0x6e, 0x26, 0x4b, 0xf0, 0x9e, 0xfe, 0x12,
+			0xee, 0x50, 0xf8, 0xf5, 0x4e, 0x9f, 0x77, 0xb1,
+			0xe3, 0x55, 0xf6, 0xc5, 0x05, 0x44, 0xe2, 0x3f,
+			0xb1, 0x43, 0x3d, 0xdf, 0x73, 0xbe, 0x84, 0xd8,
+			0x79, 0xde, 0x7c, 0x00, 0x46, 0xdc, 0x49, 0x96,
+			0xd9, 0xe7, 0x73, 0xf4, 0xbc, 0x9e, 0xfe, 0x57,
+			0x38, 0x82, 0x9a, 0xdb, 0x26, 0xc8, 0x1b, 0x37,
+			0xc9, 0x3a, 0x1b, 0x27, 0x0b, 0x20, 0x32, 0x9d,
+			0x65, 0x86, 0x75, 0xfc, 0x6e, 0xa5, 0x34, 0xe0,
+			0x81, 0x0a, 0x44, 0x32, 0x82, 0x6b, 0xf5, 0x8c,
+			0x94, 0x1e, 0xfb, 0x65, 0xd5, 0x7a, 0x33, 0x8b,
+			0xbd, 0x2e, 0x26, 0x64, 0x0f, 0x89, 0xff, 0xbc,
+			0x1a, 0x85, 0x8e, 0xfc, 0xb8, 0x55, 0x0e, 0xe3,
+			0xa5, 0xe1, 0x99, 0x8b, 0xd1, 0x77, 0xe9, 0x3a,
+			0x73, 0x63, 0xc3, 0x44, 0xfe, 0x6b, 0x19, 0x9e,
+			0xe5, 0xd0, 0x2e, 0x82, 0xd5, 0x22, 0xc4, 0xfe,
+			0xba, 0x15, 0x45, 0x2f, 0x80, 0x28, 0x8a, 0x82,
+			0x1a, 0x57, 0x91, 0x16, 0xec, 0x6d, 0xad, 0x2b,
+			0x3b, 0x31, 0x0d, 0xa9, 0x03, 0x40, 0x1a, 0xa6,
+			0x21, 0x00, 0xab, 0x5d, 0x1a, 0x36, 0x55, 0x3e,
+			0x06, 0x20, 0x3b, 0x33, 0x89, 0x0c, 0xc9, 0xb8,
+			0x32, 0xf7, 0x9e, 0xf8, 0x05, 0x60, 0xcc, 0xb9,
+			0xa3, 0x9c, 0xe7, 0x67, 0x96, 0x7e, 0xd6, 0x28,
+			0xc6, 0xad, 0x57, 0x3c, 0xb1, 0x16, 0xdb, 0xef,
+			0xef, 0xd7, 0x54, 0x99, 0xda, 0x96, 0xbd, 0x68,
+			0xa8, 0xa9, 0x7b, 0x92, 0x8a, 0x8b, 0xbc, 0x10,
+			0x3b, 0x66, 0x21, 0xfc, 0xde, 0x2b, 0xec, 0xa1,
+			0x23, 0x1d, 0x20, 0x6b, 0xe6, 0xcd, 0x9e, 0xc7,
+			0xaf, 0xf6, 0xf6, 0xc9, 0x4f, 0xcd, 0x72, 0x04,
+			0xed, 0x34, 0x55, 0xc6, 0x8c, 0x83, 0xf4, 0xa4,
+			0x1d, 0xa4, 0xaf, 0x2b, 0x74, 0xef, 0x5c, 0x53,
+			0xf1, 0xd8, 0xac, 0x70, 0xbd, 0xcb, 0x7e, 0xd1,
+			0x85, 0xce, 0x81, 0xbd, 0x84, 0x35, 0x9d, 0x44,
+			0x25, 0x4d, 0x95, 0x62, 0x9e, 0x98, 0x55, 0xa9,
+			0x4a, 0x7c, 0x19, 0x58, 0xd1, 0xf8, 0xad, 0xa5,
+			0xd0, 0x53, 0x2e, 0xd8, 0xa5, 0xaa, 0x3f, 0xb2,
+			0xd1, 0x7b, 0xa7, 0x0e, 0xb6, 0x24, 0x8e, 0x59,
+			0x4e, 0x1a, 0x22, 0x97, 0xac, 0xbb, 0xb3, 0x9d,
+			0x50, 0x2f, 0x1a, 0x8c, 0x6e, 0xb6, 0xf1, 0xce,
+			0x22, 0xb3, 0xde, 0x1a, 0x1f, 0x40, 0xcc, 0x24,
+			0x55, 0x41, 0x19, 0xa8, 0x31, 0xa9, 0xaa, 0xd6,
+			0x07, 0x9c, 0xad, 0x88, 0x42, 0x5d, 0xe6, 0xbd,
+			0xe1, 0xa9, 0x18, 0x7e, 0xbb, 0x60, 0x92, 0xcf,
+			0x67, 0xbf, 0x2b, 0x13, 0xfd, 0x65, 0xf2, 0x70,
+			0x88, 0xd7, 0x8b, 0x7e, 0x88, 0x3c, 0x87, 0x59,
+			0xd2, 0xc4, 0xf5, 0xc6, 0x5a, 0xdb, 0x75, 0x53,
+			0x87, 0x8a, 0xd5, 0x75, 0xf9, 0xfa, 0xd8, 0x78,
+			0xe8, 0x0a, 0x0c, 0x9b, 0xa6, 0x3b, 0xcb, 0xcc,
+			0x27, 0x32, 0xe6, 0x94, 0x85, 0xbb, 0xc9, 0xc9,
+			0x0b, 0xfb, 0xd6, 0x24, 0x81, 0xd9, 0x08, 0x9b,
+			0xec, 0xcf, 0x80, 0xcf, 0xe2, 0xdf, 0x16, 0xa2,
+			0xcf, 0x65, 0xbd, 0x92, 0xdd, 0x59, 0x7b, 0x07,
+			0x07, 0xe0, 0x91, 0x7a, 0xf4, 0x8b, 0xbb, 0x75,
+			0xfe, 0xd4, 0x13, 0xd2, 0x38, 0xf5, 0x55, 0x5a,
+			0x7a, 0x56, 0x9d, 0x80, 0xc3, 0x41, 0x4a, 0x8d,
+			0x08, 0x59, 0xdc, 0x65, 0xa4, 0x61, 0x28, 0xba,
+			0xb2, 0x7a, 0xf8, 0x7a, 0x71, 0x31, 0x4f, 0x31,
+			0x8c, 0x78, 0x2b, 0x23, 0xeb, 0xfe, 0x80, 0x8b,
+			0x82, 0xb0, 0xce, 0x26, 0x40, 0x1d, 0x2e, 0x22,
+			0xf0, 0x4d, 0x83, 0xd1, 0x25, 0x5d, 0xc5, 0x1a,
+			0xdd, 0xd3, 0xb7, 0x5a, 0x2b, 0x1a, 0xe0, 0x78,
+			0x45, 0x04, 0xdf, 0x54, 0x3a, 0xf8, 0x96, 0x9b,
+			0xe3, 0xea, 0x70, 0x82, 0xff, 0x7f, 0xc9, 0x88,
+			0x8c, 0x14, 0x4d, 0xa2, 0xaf, 0x58, 0x42, 0x9e,
+			0xc9, 0x60, 0x31, 0xdb, 0xca, 0xd3, 0xda, 0xd9,
+			0xaf, 0x0d, 0xcb, 0xaa, 0xaf, 0x26, 0x8c, 0xb8,
+			0xfc, 0xff, 0xea, 0xd9, 0x4f, 0x3c, 0x7c, 0xa4,
+			0x95, 0xe0, 0x56, 0xa9, 0xb4, 0x7a, 0xcd, 0xb7,
+			0x51, 0xfb, 0x73, 0xe6, 0x66, 0xc6, 0xc6, 0x55,
+			0xad, 0xe8, 0x29, 0x72, 0x97, 0xd0, 0x7a, 0xd1,
+			0xba, 0x5e, 0x43, 0xf1, 0xbc, 0xa3, 0x23, 0x01,
+			0x65, 0x13, 0x39, 0xe2, 0x29, 0x04, 0xcc, 0x8c,
+			0x42, 0xf5, 0x8c, 0x30, 0xc0, 0x4a, 0xaf, 0xdb,
+			0x03, 0x8d, 0xda, 0x08, 0x47, 0xdd, 0x98, 0x8d,
+			0xcd, 0xa6, 0xf3, 0xbf, 0xd1, 0x5c, 0x4b, 0x4c,
+			0x45, 0x25, 0x00, 0x4a, 0xa0, 0x6e, 0xef, 0xf8,
+			0xca, 0x61, 0x78, 0x3a, 0xac, 0xec, 0x57, 0xfb,
+			0x3d, 0x1f, 0x92, 0xb0, 0xfe, 0x2f, 0xd1, 0xa8,
+			0x5f, 0x67, 0x24, 0x51, 0x7b, 0x65, 0xe6, 0x14,
+			0xad, 0x68, 0x08, 0xd6, 0xf6, 0xee, 0x34, 0xdf,
+			0xf7, 0x31, 0x0f, 0xdc, 0x82, 0xae, 0xbf, 0xd9,
+			0x04, 0xb0, 0x1e, 0x1d, 0xc5, 0x4b, 0x29, 0x27,
+			0x09, 0x4b, 0x2d, 0xb6, 0x8d, 0x6f, 0x90, 0x3b,
+			0x68, 0x40, 0x1a, 0xde, 0xbf, 0x5a, 0x7e, 0x08,
+			0xd7, 0x8f, 0xf4, 0xef, 0x5d, 0x63, 0x65, 0x3a,
+			0x65, 0x04, 0x0c, 0xf9, 0xbf, 0xd4, 0xac, 0xa7,
+			0x98, 0x4a, 0x74, 0xd3, 0x71, 0x45, 0x98, 0x67,
+			0x80, 0xfc, 0x0b, 0x16, 0xac, 0x45, 0x16, 0x49,
+			0xde, 0x61, 0x88, 0xa7, 0xdb, 0xdf, 0x19, 0x1f,
+			0x64, 0xb5, 0xfc, 0x5e, 0x2a, 0xb4, 0x7b, 0x57,
+			0xf7, 0xf7, 0x27, 0x6c, 0xd4, 0x19, 0xc1, 0x7a,
+			0x3c, 0xa8, 0xe1, 0xb9, 0x39, 0xae, 0x49, 0xe4,
+			0x88, 0xac, 0xba, 0x6b, 0x96, 0x56, 0x10, 0xb5,
+			0x48, 0x01, 0x09, 0xc8, 0xb1, 0x7b, 0x80, 0xe1,
+			0xb7, 0xb7, 0x50, 0xdf, 0xc7, 0x59, 0x8d, 0x5d,
+			0x50, 0x11, 0xfd, 0x2d, 0xcc, 0x56, 0x00, 0xa3,
+			0x2e, 0xf5, 0xb5, 0x2a, 0x1e, 0xcc, 0x82, 0x0e,
+			0x30, 0x8a, 0xa3, 0x42, 0x72, 0x1a, 0xac, 0x09,
+			0x43, 0xbf, 0x66, 0x86, 0xb6, 0x4b, 0x25, 0x79,
+			0x37, 0x65, 0x04, 0xcc, 0xc4, 0x93, 0xd9, 0x7e,
+			0x6a, 0xed, 0x3f, 0xb0, 0xf9, 0xcd, 0x71, 0xa4,
+			0x3d, 0xd4, 0x97, 0xf0, 0x1f, 0x17, 0xc0, 0xe2,
+			0xcb, 0x37, 0x97, 0xaa, 0x2a, 0x2f, 0x25, 0x66,
+			0x56, 0x16, 0x8e, 0x6c, 0x49, 0x6a, 0xfc, 0x5f,
+			0xb9, 0x32, 0x46, 0xf6, 0xb1, 0x11, 0x63, 0x98,
+			0xa3, 0x46, 0xf1, 0xa6, 0x41, 0xf3, 0xb0, 0x41,
+			0xe9, 0x89, 0xf7, 0x91, 0x4f, 0x90, 0xcc, 0x2c,
+			0x7f, 0xff, 0x35, 0x78, 0x76, 0xe5, 0x06, 0xb5,
+			0x0d, 0x33, 0x4b, 0xa7, 0x7c, 0x22, 0x5b, 0xc3,
+			0x07, 0xba, 0x53, 0x71, 0x52, 0xf3, 0xf1, 0x61,
+			0x0e, 0x4e, 0xaf, 0xe5, 0x95, 0xf6, 0xd9, 0xd9,
+			0x0d, 0x11, 0xfa, 0xa9, 0x33, 0xa1, 0x5e, 0xf1,
+			0x36, 0x95, 0x46, 0x86, 0x8a, 0x7f, 0x3a, 0x45,
+			0xa9, 0x67, 0x68, 0xd4, 0x0f, 0xd9, 0xd0, 0x34,
+			0x12, 0xc0, 0x91, 0xc6, 0x31, 0x5c, 0xf4, 0xfd,
+			0xe7, 0xcb, 0x68, 0x60, 0x69, 0x37, 0x38, 0x0d,
+			0xb2, 0xea, 0xaa, 0x70, 0x7b, 0x4c, 0x41, 0x85,
+			0xc3, 0x2e, 0xdd, 0xcd, 0xd3, 0x06, 0x70, 0x5e,
+			0x4d, 0xc1, 0xff, 0xc8, 0x72, 0xee, 0xee, 0x47,
+			0x5a, 0x64, 0xdf, 0xac, 0x86, 0xab, 0xa4, 0x1c,
+			0x06, 0x18, 0x98, 0x3f, 0x87, 0x41, 0xc5, 0xef,
+			0x68, 0xd3, 0xa1, 0x01, 0xe8, 0xa3, 0xb8, 0xca,
+			0xc6, 0x0c, 0x90, 0x5c, 0x15, 0xfc, 0x91, 0x08,
+			0x40, 0xb9, 0x4c, 0x00, 0xa0, 0xb9, 0xd0
+		},
+		.length = 1023,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+},
+{
+	.description = "EDDSA 25519CTX (msg=16, ctx=3)",
+	.pkey = {
+		.data = {
+			0x03, 0x05, 0x33, 0x4e, 0x38, 0x1a, 0xf7, 0x8f,
+			0x14, 0x1c, 0xb6, 0x66, 0xf6, 0x19, 0x9f, 0x57,
+			0xbc, 0x34, 0x95, 0x33, 0x5a, 0x25, 0x6a, 0x95,
+			0xbd, 0x2a, 0x55, 0xbf, 0x54, 0x66, 0x63, 0xf6
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xdf, 0xc9, 0x42, 0x5e, 0x4f, 0x96, 0x8f, 0x7f,
+			0x0c, 0x29, 0xf0, 0x25, 0x9c, 0xf5, 0xf9, 0xae,
+			0xd6, 0x85, 0x1c, 0x2b, 0xb4, 0xad, 0x8b, 0xfb,
+			0x86, 0x0c, 0xfe, 0xe0, 0xab, 0x24, 0x82, 0x92
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x55, 0xa4, 0xcc, 0x2f, 0x70, 0xa5, 0x4e, 0x04,
+			0x28, 0x8c, 0x5f, 0x4c, 0xd1, 0xe4, 0x5a, 0x7b,
+			0xb5, 0x20, 0xb3, 0x62, 0x92, 0x91, 0x18, 0x76,
+			0xca, 0xda, 0x73, 0x23, 0x19, 0x8d, 0xd8, 0x7a,
+			0x8b, 0x36, 0x95, 0x0b, 0x95, 0x13, 0x00, 0x22,
+			0x90, 0x7a, 0x7f, 0xb7, 0xc4, 0xe9, 0xb2, 0xd5,
+			0xf6, 0xcc, 0xa6, 0x85, 0xa5, 0x87, 0xb4, 0xb2,
+			0x1f, 0x4b, 0x88, 0x8e, 0x4e, 0x7e, 0xdb, 0x0d
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0xf7, 0x26, 0x93, 0x6d, 0x19, 0xc8, 0x00, 0x49,
+			0x4e, 0x3f, 0xda, 0xff, 0x20, 0xb2, 0x76, 0xa8,
+		},
+		.length = 16,
+	},
+	.context = {
+		.data = {
+			0x66, 0x6f, 0x6f
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519CTX
+},
+{
+	.description = "EDDSA 25519PH (msg=1, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+		},
+		.length = 32,
+	},
+	.pubkey = {
+		.data = {
+			0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+			0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+			0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+			0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+		},
+		.length = 32,
+	},
+	.sign = {
+		.data = {
+			0x98, 0xa7, 0x02, 0x22, 0xf0, 0xb8, 0x12, 0x1a,
+			0xa9, 0xd3, 0x0f, 0x81, 0x3d, 0x68, 0x3f, 0x80,
+			0x9e, 0x46, 0x2b, 0x46, 0x9c, 0x7f, 0xf8, 0x76,
+			0x39, 0x49, 0x9b, 0xb9, 0x4e, 0x6d, 0xae, 0x41,
+			0x31, 0xf8, 0x50, 0x42, 0x46, 0x3c, 0x2a, 0x35,
+			0x5a, 0x20, 0x03, 0xd0, 0x62, 0xad, 0xf5, 0xaa,
+			0xa1, 0x0b, 0x8c, 0x61, 0xe6, 0x36, 0x06, 0x2a,
+			0xaa, 0xd1, 0x1c, 0x2a, 0x26, 0x08, 0x34, 0x06
+		},
+		.length = 64,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519PH
+},
+{
+	.description = "EDDSA 448 (msg=0)",
+	.pkey = {
+		.data = {
+			0x6C, 0x82, 0xA5, 0x62, 0xCB, 0x80, 0x8D, 0x10,
+			0xD6, 0x32, 0xBE, 0x89, 0xC8, 0x51, 0x3E, 0xBF,
+			0x6C, 0x92, 0x9F, 0x34, 0xDD, 0xFA, 0x8C, 0x9F,
+			0x63, 0xC9, 0x96, 0x0E, 0xF6, 0xE3, 0x48, 0xA3,
+			0x52, 0x8C, 0x8A, 0x3F, 0xCC, 0x2F, 0x04, 0x4E,
+			0x39, 0xA3, 0xFC, 0x5B, 0x94, 0x49, 0x2F, 0x8F,
+			0x03, 0x2E, 0x75, 0x49, 0xA2, 0x00, 0x98, 0xF9,
+			0x5B,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x5F, 0xD7, 0x44, 0x9B, 0x59, 0xB4, 0x61, 0xFD,
+			0x2C, 0xE7, 0x87, 0xEC, 0x61, 0x6A, 0xD4, 0x6A,
+			0x1D, 0xA1, 0x34, 0x24, 0x85, 0xA7, 0x0E, 0x1F,
+			0x8A, 0x0E, 0xA7, 0x5D, 0x80, 0xE9, 0x67, 0x78,
+			0xED, 0xF1, 0x24, 0x76, 0x9B, 0x46, 0xC7, 0x06,
+			0x1B, 0xD6, 0x78, 0x3D, 0xF1, 0xE5, 0x0F, 0x6C,
+			0xD1, 0xFA, 0x1A, 0xBE, 0xAF, 0xE8, 0x25, 0x61,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25,
+			0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae,
+			0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2,
+			0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f,
+			0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81,
+			0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78,
+			0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39,
+			0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a,
+			0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d,
+			0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41,
+			0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd,
+			0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb,
+			0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26,
+			0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65,
+			0x26, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+		},
+		.length = 0,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=1)",
+	.pkey = {
+		.data = {
+			0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6,
+			0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92, 0x4d,
+			0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d,
+			0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c, 0x46, 0x3a,
+			0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c,
+			0x5e, 0x3b, 0xc3, 0x97, 0xa6, 0x59, 0x94, 0x9e,
+			0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27,
+			0x4e,
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45,
+			0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd, 0x0a,
+			0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37,
+			0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98, 0xc0, 0x86,
+			0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02,
+			0xb8, 0x43, 0x8e, 0xa4, 0xcb, 0x82, 0x16, 0x9c,
+			0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94,
+			0x80,
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x26, 0xb8, 0xf9, 0x17, 0x27, 0xbd, 0x62, 0x89,
+			0x7a, 0xf1, 0x5e, 0x41, 0xeb, 0x43, 0xc3, 0x77,
+			0xef, 0xb9, 0xc6, 0x10, 0xd4, 0x8f, 0x23, 0x35,
+			0xcb, 0x0b, 0xd0, 0x08, 0x78, 0x10, 0xf4, 0x35,
+			0x25, 0x41, 0xb1, 0x43, 0xc4, 0xb9, 0x81, 0xb7,
+			0xe1, 0x8f, 0x62, 0xde, 0x8c, 0xcd, 0xf6, 0x33,
+			0xfc, 0x1b, 0xf0, 0x37, 0xab, 0x7c, 0xd7, 0x79,
+			0x80, 0x5e, 0x0d, 0xbc, 0xc0, 0xaa, 0xe1, 0xcb,
+			0xce, 0xe1, 0xaf, 0xb2, 0xe0, 0x27, 0xdf, 0x36,
+			0xbc, 0x04, 0xdc, 0xec, 0xbf, 0x15, 0x43, 0x36,
+			0xc1, 0x9f, 0x0a, 0xf7, 0xe0, 0xa6, 0x47, 0x29,
+			0x05, 0xe7, 0x99, 0xf1, 0x95, 0x3d, 0x2a, 0x0f,
+			0xf3, 0x34, 0x8a, 0xb2, 0x1a, 0xa4, 0xad, 0xaf,
+			0xd1, 0xd2, 0x34, 0x44, 0x1c, 0xf8, 0x07, 0xc0,
+			0x3a, 0x00,
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x03
+		},
+		.length = 1,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448
+},
+{
+	.description = "EDDSA 448 (msg=3, ph=1)",
+	.pkey = {
+		.data = {
+			0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+			0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+			0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+			0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42,
+			0xef, 0x78, 0x22, 0xe0, 0xd5, 0x10, 0x41, 0x27,
+			0xdc, 0x05, 0xd6, 0xdb, 0xef, 0xde, 0x69, 0xe3,
+			0xab, 0x2c, 0xec, 0x7c, 0x86, 0x7c, 0x6e, 0x2c,
+			0x49
+		},
+		.length = 57,
+	},
+	.pubkey = {
+		.data = {
+			0x25, 0x9b, 0x71, 0xc1, 0x9f, 0x83, 0xef, 0x77,
+			0xa7, 0xab, 0xd2, 0x65, 0x24, 0xcb, 0xdb, 0x31,
+			0x61, 0xb5, 0x90, 0xa4, 0x8f, 0x7d, 0x17, 0xde,
+			0x3e, 0xe0, 0xba, 0x9c, 0x52, 0xbe, 0xb7, 0x43,
+			0xc0, 0x94, 0x28, 0xa1, 0x31, 0xd6, 0xb1, 0xb5,
+			0x73, 0x03, 0xd9, 0x0d, 0x81, 0x32, 0xc2, 0x76,
+			0xd5, 0xed, 0x3d, 0x5d, 0x01, 0xc0, 0xf5, 0x38,
+			0x80
+		},
+		.length = 57,
+	},
+	.sign = {
+		.data = {
+			0x82, 0x2f, 0x69, 0x01, 0xf7, 0x48, 0x0f, 0x3d,
+			0x5f, 0x56, 0x2c, 0x59, 0x29, 0x94, 0xd9, 0x69,
+			0x36, 0x02, 0x87, 0x56, 0x14, 0x48, 0x32, 0x56,
+			0x50, 0x56, 0x00, 0xbb, 0xc2, 0x81, 0xae, 0x38,
+			0x1f, 0x54, 0xd6, 0xbc, 0xe2, 0xea, 0x91, 0x15,
+			0x74, 0x93, 0x2f, 0x52, 0xa4, 0xe6, 0xca, 0xdd,
+			0x78, 0x76, 0x93, 0x75, 0xec, 0x3f, 0xfd, 0x1b,
+			0x80, 0x1a, 0x0d, 0x9b, 0x3f, 0x40, 0x30, 0xcd,
+			0x43, 0x39, 0x64, 0xb6, 0x45, 0x7e, 0xa3, 0x94,
+			0x76, 0x51, 0x12, 0x14, 0xf9, 0x74, 0x69, 0xb5,
+			0x7d, 0xd3, 0x2d, 0xbc, 0x56, 0x0a, 0x9a, 0x94,
+			0xd0, 0x0b, 0xff, 0x07, 0x62, 0x04, 0x64, 0xa3,
+			0xad, 0x20, 0x3d, 0xf7, 0xdc, 0x7c, 0xe3, 0x60,
+			0xc3, 0xcd, 0x36, 0x96, 0xd9, 0xd9, 0xfa, 0xb9,
+			0x0f, 0x00
+		},
+		.length = 114,
+	},
+	.message = {
+		.data = {
+			0x61, 0x62, 0x63
+		},
+		.length = 3,
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED448,
+	.instance = RTE_CRYPTO_EDCURVE_448PH
+},
+};
+
+#endif /* __TEST_CRYPTODEV_EDDSA_TEST_VECTORS_H__ */
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v6 5/6] examples/fips_validation: support EDDSA
  2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                               ` (2 preceding siblings ...)
  2024-10-04  8:26             ` [PATCH v6 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
@ 2024-10-04  8:26             ` Gowrishankar Muthukrishnan
  2024-10-04 16:19               ` Dooley, Brian
  2024-10-04  8:26             ` [PATCH v6 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
  2024-10-07 16:03             ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Kusztal, ArkadiuszX
  5 siblings, 1 reply; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  8:26 UTC (permalink / raw)
  To: dev, Brian Dooley, Gowrishankar Muthukrishnan
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal

Add EDDSA support in fips_validation app.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
v6:
 - fixed Makefile.
---
 examples/fips_validation/Makefile             |   1 +
 examples/fips_validation/fips_validation.c    |   2 +
 examples/fips_validation/fips_validation.h    |  23 ++
 .../fips_validation/fips_validation_eddsa.c   | 307 +++++++++++++++++
 examples/fips_validation/main.c               | 323 ++++++++++++++++--
 examples/fips_validation/meson.build          |   1 +
 6 files changed, 624 insertions(+), 33 deletions(-)
 create mode 100644 examples/fips_validation/fips_validation_eddsa.c

diff --git a/examples/fips_validation/Makefile b/examples/fips_validation/Makefile
index fbb778d57a..8ab85688c9 100644
--- a/examples/fips_validation/Makefile
+++ b/examples/fips_validation/Makefile
@@ -17,6 +17,7 @@ SRCS-y += fips_dev_self_test.c
 SRCS-y += fips_validation_xts.c
 SRCS-y += fips_validation_rsa.c
 SRCS-y += fips_validation_ecdsa.c
+SRCS-y += fips_validation_eddsa.c
 SRCS-y += main.c
 
 PKGCONF ?= pkg-config
diff --git a/examples/fips_validation/fips_validation.c b/examples/fips_validation/fips_validation.c
index c15178e55b..43d1e55532 100644
--- a/examples/fips_validation/fips_validation.c
+++ b/examples/fips_validation/fips_validation.c
@@ -475,6 +475,8 @@ fips_test_parse_one_json_vector_set(void)
 		info.algo = FIPS_TEST_ALGO_RSA;
 	else if (strstr(algo_str, "ECDSA"))
 		info.algo = FIPS_TEST_ALGO_ECDSA;
+	else if (strstr(algo_str, "EDDSA"))
+		info.algo = FIPS_TEST_ALGO_EDDSA;
 	else
 		return -EINVAL;
 
diff --git a/examples/fips_validation/fips_validation.h b/examples/fips_validation/fips_validation.h
index abc1d64742..795cf834e8 100644
--- a/examples/fips_validation/fips_validation.h
+++ b/examples/fips_validation/fips_validation.h
@@ -46,6 +46,7 @@ enum fips_test_algorithms {
 		FIPS_TEST_ALGO_SHA,
 		FIPS_TEST_ALGO_RSA,
 		FIPS_TEST_ALGO_ECDSA,
+		FIPS_TEST_ALGO_EDDSA,
 		FIPS_TEST_ALGO_MAX
 };
 
@@ -106,6 +107,12 @@ struct fips_test_vector {
 		struct fips_val s;
 		struct fips_val k;
 	} ecdsa;
+	struct {
+		struct fips_val pkey;
+		struct fips_val q;
+		struct fips_val ctx;
+		struct fips_val sign;
+	} eddsa;
 
 	struct fips_val pt;
 	struct fips_val ct;
@@ -177,6 +184,11 @@ enum fips_ecdsa_test_types {
 	ECDSA_AFT = 0,
 };
 
+enum fips_eddsa_test_types {
+	EDDSA_AFT = 0,
+	EDDSA_BFT
+};
+
 struct aesavs_interim_data {
 	enum fips_aesavs_test_types test_type;
 	uint32_t cipher_algo;
@@ -241,6 +253,13 @@ struct ecdsa_interim_data {
 	uint8_t pubkey_gen;
 };
 
+struct eddsa_interim_data {
+	enum rte_crypto_curve_id curve_id;
+	uint8_t curve_len;
+	uint8_t pubkey_gen;
+	bool prehash;
+};
+
 #ifdef USE_JANSSON
 /*
  * Maximum length of buffer to hold any json string.
@@ -288,6 +307,7 @@ struct fips_test_interim_info {
 		struct xts_interim_data xts_data;
 		struct rsa_interim_data rsa_data;
 		struct ecdsa_interim_data ecdsa_data;
+		struct eddsa_interim_data eddsa_data;
 	} interim_info;
 
 	enum fips_test_op op;
@@ -374,6 +394,9 @@ parse_test_rsa_json_init(void);
 int
 parse_test_ecdsa_json_init(void);
 
+int
+parse_test_eddsa_json_init(void);
+
 int
 fips_test_randomize_message(struct fips_val *msg, struct fips_val *rand);
 #endif /* USE_JANSSON */
diff --git a/examples/fips_validation/fips_validation_eddsa.c b/examples/fips_validation/fips_validation_eddsa.c
new file mode 100644
index 0000000000..8ccf7501bd
--- /dev/null
+++ b/examples/fips_validation/fips_validation_eddsa.c
@@ -0,0 +1,307 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2023 Marvell.
+ */
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef USE_OPENSSL
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#endif /* USE_OPENSSL */
+
+#include <rte_cryptodev.h>
+#include <rte_malloc.h>
+
+#include "fips_validation.h"
+
+#define TESTTYPE_JSON_STR "testType"
+#define CURVE_JSON_STR    "curve"
+#define PH_JSON_STR       "preHash"
+
+#define MSG_JSON_STR "message"
+#define CTX_JSON_STR "context"
+#define Q_JSON_STR	 "q"
+#define SIG_JSON_STR "signature"
+
+#ifdef USE_JANSSON
+struct {
+	uint8_t type;
+	const char *desc;
+} eddsa_test_types[] = {
+	{EDDSA_AFT, "AFT"},
+	{EDDSA_BFT, "BFT"}
+};
+
+struct {
+	enum rte_crypto_curve_id curve_id;
+	const char *desc;
+} eddsa_curve_ids[] = {
+	{RTE_CRYPTO_EC_GROUP_ED25519, "ED-25519"},
+	{RTE_CRYPTO_EC_GROUP_ED448, "ED-448"},
+};
+
+struct {
+	uint8_t curve_len;
+	const char *desc;
+} eddsa_curve_len[] = {
+	{32, "ED-25519"},
+	{64, "ED-448"},
+};
+
+#ifdef USE_OPENSSL
+#define MAX_TRIES 10
+static int
+prepare_vec_eddsa(void)
+{
+	BIGNUM *pkey = NULL, *order = NULL;
+	int ret = -1, j;
+	unsigned long pid;
+
+	/* For EDDSA prime fields, order of base points (RFC 8032 Section 5.1 and 5.2).
+	 */
+	static const char * const orderstr[] = {
+			"7237005577332262213973186563042994240857116359379907606001950938285454250989",
+			"181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779",
+	};
+
+	pid = getpid();
+	RAND_seed(&pid, sizeof(pid));
+
+	if (!RAND_status())
+		return -1;
+
+	order = BN_new();
+	if (!order)
+		goto err;
+
+	j = info.interim_info.eddsa_data.curve_id - RTE_CRYPTO_EC_GROUP_ED25519;
+	if (!BN_hex2bn(&order, orderstr[j]))
+		goto err;
+
+	pkey = BN_new();
+	if (!pkey)
+		goto err;
+
+	for (j = 0; j < MAX_TRIES; j++) {
+		/* pkey should be in [1, order - 1] */
+		if (!BN_rand_range(pkey, order))
+			goto err;
+
+		if (!BN_is_zero(pkey))
+			break;
+	}
+
+	if (j == MAX_TRIES)
+		goto err;
+
+	parse_uint8_hex_str("", BN_bn2hex(pkey), &vec.eddsa.pkey);
+
+	ret = 0;
+err:
+	BN_free(order);
+	BN_free(pkey);
+	return ret;
+}
+#else
+static int
+prepare_vec_eddsa(void)
+{
+	/*
+	 * Generate EDDSA values.
+	 */
+	return -ENOTSUP;
+}
+#endif /* USE_OPENSSL */
+
+static int
+parse_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		/* For siggen tests, EDDSA values can be created soon after
+		 * the test group data are parsed.
+		 */
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+static int
+post_test_eddsa_json_interim_writeback(struct fips_val *val)
+{
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_group, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_test_eddsa_json_writeback(struct fips_val *val)
+{
+	json_t *tcId;
+
+	RTE_SET_USED(val);
+
+	tcId = json_object_get(json_info.json_test_case, "tcId");
+
+	json_info.json_write_case = json_object();
+	json_object_set(json_info.json_write_case, "tcId", tcId);
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.sign);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "signature", obj);
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)
+			json_object_set_new(json_info.json_write_case, "testPassed", json_true());
+		else
+			json_object_set_new(json_info.json_write_case, "testPassed", json_false());
+	} else if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		json_t *obj;
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.pkey);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "d", obj);
+
+		writeback_hex_str("", info.one_line_text, &vec.eddsa.q);
+		obj = json_string(info.one_line_text);
+		json_object_set_new(json_info.json_write_case, "q", obj);
+	}
+
+	return 0;
+}
+
+static int
+parse_interim_str(const char *key, char *src, struct fips_val *val)
+{
+	uint32_t i;
+
+	RTE_SET_USED(val);
+
+	if (strcmp(key, TESTTYPE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_test_types); i++)
+			if (strstr(src, eddsa_test_types[i].desc)) {
+				info.parse_writeback = parse_test_eddsa_json_writeback;
+				break;
+			}
+
+		if (!info.parse_writeback || i >= RTE_DIM(eddsa_test_types))
+			return -EINVAL;
+
+	} else if (strcmp(key, CURVE_JSON_STR) == 0) {
+		for (i = 0; i < RTE_DIM(eddsa_curve_ids); i++)
+			if (strstr(src, eddsa_curve_ids[i].desc)) {
+				info.interim_info.eddsa_data.curve_id = eddsa_curve_ids[i].curve_id;
+				info.interim_info.eddsa_data.curve_len =
+					eddsa_curve_len[i].curve_len;
+				break;
+			}
+
+		if (i >= RTE_DIM(eddsa_curve_ids))
+			return -EINVAL;
+	} else if (strcmp(key, PH_JSON_STR) == 0) {
+		info.interim_info.eddsa_data.prehash = false;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+parse_keygen_tc_str(const char *key, char *src, struct fips_val *val)
+{
+	RTE_SET_USED(key);
+	RTE_SET_USED(src);
+	RTE_SET_USED(val);
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (vec.eddsa.pkey.val) {
+			rte_free(vec.eddsa.pkey.val);
+			vec.eddsa.pkey.val = NULL;
+		}
+
+		if (prepare_vec_eddsa() < 0)
+			return -1;
+
+		info.interim_info.eddsa_data.pubkey_gen = 1;
+	}
+
+	return 0;
+}
+
+struct fips_test_callback eddsa_interim_json_vectors[] = {
+		{TESTTYPE_JSON_STR, parse_interim_str, NULL},
+		{CURVE_JSON_STR, parse_interim_str, NULL},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_siggen_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{CTX_JSON_STR, parse_uint8_hex_str, &vec.eddsa.ctx},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_sigver_json_vectors[] = {
+		{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
+		{Q_JSON_STR, parse_uint8_hex_str, &vec.eddsa.q},
+		{SIG_JSON_STR, parse_uint8_hex_str, &vec.eddsa.sign},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+struct fips_test_callback eddsa_keygen_json_vectors[] = {
+		{"tcId", parse_keygen_tc_str, &vec.pt},
+		{NULL, NULL, NULL} /**< end pointer */
+};
+
+int
+parse_test_eddsa_json_init(void)
+{
+	json_t *mode_obj = json_object_get(json_info.json_vector_set, "mode");
+	const char *mode_str = json_string_value(mode_obj);
+
+	info.callbacks = NULL;
+	info.parse_writeback = NULL;
+
+	info.interim_callbacks = eddsa_interim_json_vectors;
+	info.post_interim_writeback = post_test_eddsa_json_interim_writeback;
+	info.parse_interim_writeback = parse_test_eddsa_json_interim_writeback;
+	if (strcmp(mode_str, "sigGen") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGGEN;
+		info.callbacks = eddsa_siggen_json_vectors;
+	} else if (strcmp(mode_str, "sigVer") == 0) {
+		info.op = FIPS_TEST_ASYM_SIGVER;
+		info.callbacks = eddsa_sigver_json_vectors;
+	} else if (strcmp(mode_str, "keyGen") == 0) {
+		info.op = FIPS_TEST_ASYM_KEYGEN;
+		info.callbacks = eddsa_keygen_json_vectors;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#endif /* USE_JANSSON */
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index 7ae2c6c007..522373ac1d 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -1041,6 +1041,64 @@ prepare_ecdsa_op(void)
 	return 0;
 }
 
+static int
+prepare_eddsa_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+	struct fips_val msg;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	if (env.digest) {
+		msg.val = env.digest;
+		msg.len = env.digest_len;
+	} else {
+		msg.val = vec.pt.val;
+		msg.len = vec.pt.len;
+	}
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.context.data = vec.eddsa.ctx.val;
+		asym->eddsa.context.length = vec.eddsa.ctx.len;
+
+		rte_free(vec.eddsa.sign.val);
+
+		vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len;
+		vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0);
+
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = 0;
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = vec.eddsa.sign.len;
+	} else {
+		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
+		return -EINVAL;
+	}
+
+	if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH;
+		if (vec.eddsa.ctx.len > 0)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX;
+	} else {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH;
+	}
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_ecfpm_op(void)
 {
@@ -1072,6 +1130,31 @@ prepare_ecfpm_op(void)
 	return 0;
 }
 
+static int
+prepare_edfpm_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	asym->ecpm.scalar.data = vec.eddsa.pkey.val;
+	asym->ecpm.scalar.length = vec.eddsa.pkey.len;
+
+	rte_free(vec.eddsa.q.val);
+
+	vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len;
+	vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0);
+
+	asym->ecpm.r.x.data = vec.eddsa.q.val;
+	asym->ecpm.r.x.length = 0;
+	asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
 static int
 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
 {
@@ -1589,6 +1672,56 @@ prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_eddsa_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	switch (info.op) {
+	case FIPS_TEST_ASYM_SIGGEN:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_SIGN)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
+			return -EPERM;
+		}
+
+		xform->ec.pkey.data = vec.eddsa.pkey.val;
+		xform->ec.pkey.length = vec.eddsa.pkey.len;
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	case FIPS_TEST_ASYM_SIGVER:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_VERIFY)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
+			return -EPERM;
+		}
+
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	default:
+		break;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 {
@@ -1610,6 +1743,27 @@ prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
 	return 0;
 }
 
+static int
+prepare_edfpm_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
 static int
 get_writeback_data(struct fips_val *val)
 {
@@ -1709,7 +1863,9 @@ fips_run_asym_test(void)
 	struct rte_crypto_op *deqd_op;
 	int ret;
 
-	if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != FIPS_TEST_ALGO_ECDSA) {
+	if (info.op == FIPS_TEST_ASYM_KEYGEN &&
+		(info.algo != FIPS_TEST_ALGO_ECDSA &&
+		 info.algo != FIPS_TEST_ALGO_EDDSA)) {
 		RTE_SET_USED(asym);
 		ret = 0;
 		goto exit;
@@ -1758,53 +1914,140 @@ fips_run_test(void)
 {
 	int ret;
 
-	env.op = env.sym.op;
-	if (env.is_asym_test) {
-		if (info.op == FIPS_TEST_ASYM_KEYGEN &&
-			info.algo == FIPS_TEST_ALGO_ECDSA) {
-			env.op = env.asym.op;
+	env.op = NULL;
+	if (!env.is_asym_test) {
+		env.op = env.sym.op;
+		return fips_run_sym_test();
+	}
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (info.algo == FIPS_TEST_ALGO_ECDSA) {
 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
 			test_ops.prepare_asym_op = prepare_ecfpm_op;
-			ret = fips_run_asym_test();
-			if (ret < 0)
-				return ret;
-
 			info.interim_info.ecdsa_data.pubkey_gen = 0;
-			return ret;
+
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA) {
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			info.interim_info.eddsa_data.pubkey_gen = 0;
 		}
 
-		vec.cipher_auth.digest.len = parse_test_sha_hash_size(
-						info.interim_info.rsa_data.auth);
+		env.op = env.asym.op;
+		return fips_run_asym_test();
+	}
+
+	if (info.algo == FIPS_TEST_ALGO_ECDSA) {
+		vec.cipher_auth.digest.len =
+			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
 		test_ops.prepare_sym_xform = prepare_sha_xform;
 		test_ops.prepare_sym_op = prepare_auth_op;
+
+		env.op = env.sym.op;
 		ret = fips_run_sym_test();
 		if (ret < 0)
 			return ret;
-	} else {
-		return fips_run_sym_test();
 	}
 
 	env.op = env.asym.op;
-	if (info.op == FIPS_TEST_ASYM_SIGGEN &&
-		info.algo == FIPS_TEST_ALGO_ECDSA &&
-		info.interim_info.ecdsa_data.pubkey_gen == 1) {
-		fips_prepare_asym_xform_t ecdsa_xform;
-		fips_prepare_op_t ecdsa_op;
-
-		ecdsa_xform = test_ops.prepare_asym_xform;
-		ecdsa_op = test_ops.prepare_asym_op;
-		info.op = FIPS_TEST_ASYM_KEYGEN;
-		test_ops.prepare_asym_xform = prepare_ecfpm_xform;
-		test_ops.prepare_asym_op = prepare_ecfpm_op;
-		ret = fips_run_asym_test();
-		if (ret < 0)
-			return ret;
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		fips_prepare_asym_xform_t old_xform;
+		fips_prepare_op_t old_op;
+
+		old_xform = test_ops.prepare_asym_xform;
+		old_op = test_ops.prepare_asym_op;
+
+		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
+		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
+			test_ops.prepare_asym_op = prepare_ecfpm_op;
 
-		info.post_interim_writeback(NULL);
-		info.interim_info.ecdsa_data.pubkey_gen = 0;
+			ret = fips_run_asym_test();
+			if (ret < 0)
+				return ret;
+
+			info.post_interim_writeback(NULL);
+			info.interim_info.ecdsa_data.pubkey_gen = 0;
 
-		test_ops.prepare_asym_xform = ecdsa_xform;
-		test_ops.prepare_asym_op = ecdsa_op;
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
+				   info.interim_info.eddsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+
+			const struct rte_cryptodev_asymmetric_xform_capability *cap;
+			struct rte_cryptodev_asym_capability_idx cap_idx;
+
+			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+			if (!cap) {
+				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+						env.dev_id);
+				return -EINVAL;
+			}
+
+			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
+				ret = fips_run_asym_test();
+				if (ret < 0)
+					return ret;
+			} else {
+				/* Below is only a workaround by using known keys. */
+				struct rte_crypto_asym_xform xform = {0};
+
+				prepare_edfpm_xform(&xform);
+				prepare_edfpm_op();
+				uint8_t pkey25519[] = {
+					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+				};
+				uint8_t q25519[] = {
+					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+				};
+				uint8_t pkey448[] = {
+					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+					0x01
+				};
+				uint8_t q448[] = {
+					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+					0x00
+				};
+				if (info.interim_info.eddsa_data.curve_id ==
+					RTE_CRYPTO_EC_GROUP_ED25519) {
+					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
+					vec.eddsa.q.len = 32;
+				} else {
+					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
+					vec.eddsa.q.len = 32;
+				}
+			}
+			info.post_interim_writeback(NULL);
+			info.interim_info.eddsa_data.pubkey_gen = 0;
+
+		}
+
+		test_ops.prepare_asym_xform = old_xform;
+		test_ops.prepare_asym_op = old_op;
 		info.op = FIPS_TEST_ASYM_SIGGEN;
 		ret = fips_run_asym_test();
 	} else {
@@ -2536,6 +2779,17 @@ init_test_ops(void)
 			test_ops.test = fips_generic_test;
 		}
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.test = fips_generic_test;
+		} else {
+			test_ops.prepare_asym_op = prepare_eddsa_op;
+			test_ops.prepare_asym_xform = prepare_eddsa_xform;
+			test_ops.test = fips_generic_test;
+		}
+		break;
 	default:
 		if (strstr(info.file_name, "TECB") ||
 				strstr(info.file_name, "TCBC")) {
@@ -2719,6 +2973,9 @@ fips_test_one_test_group(void)
 	case FIPS_TEST_ALGO_ECDSA:
 		ret = parse_test_ecdsa_json_init();
 		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		ret = parse_test_eddsa_json_init();
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/examples/fips_validation/meson.build b/examples/fips_validation/meson.build
index 34d3c7c8ca..7d4e440c6c 100644
--- a/examples/fips_validation/meson.build
+++ b/examples/fips_validation/meson.build
@@ -20,6 +20,7 @@ sources = files(
         'fips_validation_xts.c',
         'fips_validation_rsa.c',
         'fips_validation_ecdsa.c',
+        'fips_validation_eddsa.c',
         'fips_dev_self_test.c',
         'main.c',
 )
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH v6 6/6] app/crypto-perf: support EDDSA
  2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                               ` (3 preceding siblings ...)
  2024-10-04  8:26             ` [PATCH v6 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
@ 2024-10-04  8:26             ` Gowrishankar Muthukrishnan
  2024-10-04 16:20               ` Dooley, Brian
  2024-10-07 16:03             ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Kusztal, ArkadiuszX
  5 siblings, 1 reply; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-04  8:26 UTC (permalink / raw)
  To: dev, Brian Dooley
  Cc: Anoob Joseph, bruce.richardson, jerinj, fanzhang.oss,
	arkadiuszx.kusztal, kai.ji, jack.bond-preston, david.marchand,
	hemant.agrawal, pablo.de.lara.guarch, fiona.trahe,
	declan.doherty, matan, ruifeng.wang, Akhil Goyal,
	Gowrishankar Muthukrishnan

Added support for EDDSA 25519 curve SIGN and VERIFY operations.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 app/test-crypto-perf/cperf_ops.c             | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_options.h         |  2 +
 app/test-crypto-perf/cperf_options_parsing.c |  9 +++-
 app/test-crypto-perf/cperf_test_common.c     |  1 +
 app/test-crypto-perf/cperf_test_vectors.c    | 52 ++++++++++++++++++++
 app/test-crypto-perf/cperf_test_vectors.h    | 10 ++++
 app/test-crypto-perf/main.c                  | 13 +++++
 doc/guides/tools/cryptoperf.rst              |  1 +
 8 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/app/test-crypto-perf/cperf_ops.c b/app/test-crypto-perf/cperf_ops.c
index f139ec5331..220c3acac7 100644
--- a/app/test-crypto-perf/cperf_ops.c
+++ b/app/test-crypto-perf/cperf_ops.c
@@ -67,6 +67,36 @@ cperf_set_ops_asym_ecdsa(struct rte_crypto_op **ops,
 	}
 }
 
+static void
+cperf_set_ops_asym_eddsa(struct rte_crypto_op **ops,
+		   uint32_t src_buf_offset __rte_unused,
+		   uint32_t dst_buf_offset __rte_unused, uint16_t nb_ops,
+		   void *sess,
+		   const struct cperf_options *options,
+		   const struct cperf_test_vector *test_vector __rte_unused,
+		   uint16_t iv_offset __rte_unused,
+		   uint32_t *imix_idx __rte_unused,
+		   uint64_t *tsc_start __rte_unused)
+{
+	uint16_t i;
+
+	for (i = 0; i < nb_ops; i++) {
+		struct rte_crypto_asym_op *asym_op = ops[i]->asym;
+
+		ops[i]->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+		rte_crypto_op_attach_asym_session(ops[i], sess);
+
+		asym_op->eddsa.op_type = options->asym_op_type;
+		asym_op->eddsa.message.data = options->eddsa_data->message.data;
+		asym_op->eddsa.message.length = options->eddsa_data->message.length;
+
+		asym_op->eddsa.instance = options->eddsa_data->instance;
+
+		asym_op->eddsa.sign.data = options->eddsa_data->sign.data;
+		asym_op->eddsa.sign.length = options->eddsa_data->sign.length;
+	}
+}
+
 static void
 cperf_set_ops_asym_sm2(struct rte_crypto_op **ops,
 		   uint32_t src_buf_offset __rte_unused,
@@ -1031,6 +1061,25 @@ cperf_create_session(struct rte_mempool *sess_mp,
 		return asym_sess;
 	}
 
+	if (options->op_type == CPERF_ASYM_ED25519) {
+		xform.next = NULL;
+		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+		xform.ec.curve_id = options->eddsa_data->curve;
+		xform.ec.pkey.data = options->eddsa_data->pkey.data;
+		xform.ec.pkey.length = options->eddsa_data->pkey.length;
+		xform.ec.q.x.data = options->eddsa_data->pubkey.data;
+		xform.ec.q.x.length = options->eddsa_data->pubkey.length;
+
+		ret = rte_cryptodev_asym_session_create(dev_id, &xform,
+				sess_mp, &asym_sess);
+		if (ret < 0) {
+			RTE_LOG(ERR, USER1, "EDDSA Asym session create failed\n");
+			return NULL;
+		}
+
+		return asym_sess;
+	}
+
 	if (options->op_type == CPERF_ASYM_SM2) {
 		xform.next = NULL;
 		xform.xform_type = RTE_CRYPTO_ASYM_XFORM_SM2;
@@ -1354,6 +1403,9 @@ cperf_get_op_functions(const struct cperf_options *options,
 	case CPERF_ASYM_SECP256R1:
 		op_fns->populate_ops = cperf_set_ops_asym_ecdsa;
 		break;
+	case CPERF_ASYM_ED25519:
+		op_fns->populate_ops = cperf_set_ops_asym_eddsa;
+		break;
 	case CPERF_ASYM_SM2:
 		op_fns->populate_ops = cperf_set_ops_asym_sm2;
 		break;
diff --git a/app/test-crypto-perf/cperf_options.h b/app/test-crypto-perf/cperf_options.h
index 131ecfdffb..dbc9f5a97b 100644
--- a/app/test-crypto-perf/cperf_options.h
+++ b/app/test-crypto-perf/cperf_options.h
@@ -89,6 +89,7 @@ enum cperf_op_type {
 	CPERF_IPSEC,
 	CPERF_ASYM_MODEX,
 	CPERF_ASYM_SECP256R1,
+	CPERF_ASYM_ED25519,
 	CPERF_ASYM_SM2,
 	CPERF_TLS,
 };
@@ -169,6 +170,7 @@ struct cperf_options {
 	struct cperf_modex_test_data *modex_data;
 	uint16_t modex_len;
 	struct cperf_ecdsa_test_data *secp256r1_data;
+	struct cperf_eddsa_test_data *eddsa_data;
 	struct cperf_sm2_test_data *sm2_data;
 	enum rte_crypto_asym_op_type asym_op_type;
 	enum rte_crypto_auth_algorithm asym_hash_alg;
diff --git a/app/test-crypto-perf/cperf_options_parsing.c b/app/test-crypto-perf/cperf_options_parsing.c
index c91fcf0479..59ea66c06d 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -38,7 +38,7 @@ usage(char *progname)
 		" --desc-nb N: set number of descriptors for each crypto device\n"
 		" --devtype TYPE: set crypto device type to use\n"
 		" --optype cipher-only / auth-only / cipher-then-auth / auth-then-cipher /\n"
-		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / sm2 / tls-record : set operation type\n"
+		"        aead / pdcp / docsis / ipsec / modex / secp256r1 / eddsa / sm2 / tls-record : set operation type\n"
 		" --sessionless: enable session-less crypto operations\n"
 		" --shared-session: share 1 session across all queue pairs on crypto device\n"
 		" --out-of-place: enable out-of-place crypto operations\n"
@@ -489,6 +489,10 @@ parse_op_type(struct cperf_options *opts, const char *arg)
 			cperf_op_type_strs[CPERF_ASYM_SECP256R1],
 			CPERF_ASYM_SECP256R1
 		},
+		{
+			cperf_op_type_strs[CPERF_ASYM_ED25519],
+			CPERF_ASYM_ED25519
+		},
 		{
 			cperf_op_type_strs[CPERF_ASYM_SM2],
 			CPERF_ASYM_SM2
@@ -1080,6 +1084,7 @@ cperf_options_default(struct cperf_options *opts)
 	opts->modex_data = (struct cperf_modex_test_data *)&modex_perf_data[0];
 
 	opts->secp256r1_data = &secp256r1_perf_data;
+	opts->eddsa_data = &ed25519_perf_data;
 	opts->sm2_data = &sm2_perf_data;
 	opts->asym_op_type = RTE_CRYPTO_ASYM_OP_SIGN;
 }
@@ -1513,7 +1518,7 @@ cperf_options_dump(struct cperf_options *opts)
 	printf("#\n");
 	printf("# number of queue pairs per device: %u\n", opts->nb_qps);
 	printf("# crypto operation: %s\n", cperf_op_type_strs[opts->op_type]);
-	if (opts->op_type == CPERF_ASYM_SM2 || opts->op_type == CPERF_ASYM_SECP256R1)
+	if (cperf_is_asym_test(opts))
 		printf("# asym operation type: %s\n",
 				rte_crypto_asym_op_strings[opts->asym_op_type]);
 	printf("# sessionless: %s\n", opts->sessionless ? "yes" : "no");
diff --git a/app/test-crypto-perf/cperf_test_common.c b/app/test-crypto-perf/cperf_test_common.c
index 33bee43c93..9c287665a4 100644
--- a/app/test-crypto-perf/cperf_test_common.c
+++ b/app/test-crypto-perf/cperf_test_common.c
@@ -307,6 +307,7 @@ cperf_is_asym_test(const struct cperf_options *options)
 {
 	if (options->op_type == CPERF_ASYM_MODEX ||
 	    options->op_type == CPERF_ASYM_SECP256R1 ||
+	    options->op_type == CPERF_ASYM_ED25519 ||
 	    options->op_type == CPERF_ASYM_SM2)
 		return true;
 
diff --git a/app/test-crypto-perf/cperf_test_vectors.c b/app/test-crypto-perf/cperf_test_vectors.c
index 19c56b46bd..64720d50c3 100644
--- a/app/test-crypto-perf/cperf_test_vectors.c
+++ b/app/test-crypto-perf/cperf_test_vectors.c
@@ -853,6 +853,35 @@ static uint8_t secp256r1_message[] = {
 	0xdb, 0xc4, 0xe7, 0xa6, 0xa1, 0x33, 0xec, 0x56
 };
 
+static uint8_t ed25519_pkey[] = {
+	0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
+	0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
+	0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
+	0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb,
+};
+
+static uint8_t ed25519_pubkey[] = {
+	0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
+	0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
+	0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
+	0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c,
+};
+
+static uint8_t ed25519_sign[] = {
+	0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
+	0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
+	0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
+	0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
+	0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
+	0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
+	0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
+	0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00,
+};
+
+static uint8_t ed25519_message[] = {
+	0x72
+};
+
 static uint8_t fp256_pkey[] = {
 	0x77, 0x84, 0x35, 0x65, 0x4c, 0x7a, 0x6d, 0xb1,
 	0x1e, 0x63, 0x0b, 0x41, 0x97, 0x36, 0x04, 0xf4,
@@ -1365,6 +1394,29 @@ cperf_ecdsa_test_data secp256r1_perf_data = {
 	.curve = RTE_CRYPTO_EC_GROUP_SECP256R1
 };
 
+/** EDDSA 25519 elliptic curve test params */
+struct
+cperf_eddsa_test_data ed25519_perf_data = {
+	.pubkey = {
+		.data = ed25519_pubkey,
+		.length = sizeof(ed25519_pubkey),
+	},
+	.pkey = {
+		.data = ed25519_pkey,
+		.length = sizeof(ed25519_pkey),
+	},
+	.sign = {
+		.data = ed25519_sign,
+		.length = sizeof(ed25519_sign),
+	},
+	.message = {
+		.data = ed25519_message,
+		.length = sizeof(ed25519_message),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_ED25519,
+	.instance = RTE_CRYPTO_EDCURVE_25519
+};
+
 /** SM2 Fp256 elliptic curve test params */
 struct
 cperf_sm2_test_data sm2_perf_data = {
diff --git a/app/test-crypto-perf/cperf_test_vectors.h b/app/test-crypto-perf/cperf_test_vectors.h
index d46cbbc2c8..f83a17c176 100644
--- a/app/test-crypto-perf/cperf_test_vectors.h
+++ b/app/test-crypto-perf/cperf_test_vectors.h
@@ -118,6 +118,15 @@ struct cperf_ecdsa_test_data {
 	int curve;
 };
 
+struct cperf_eddsa_test_data {
+	rte_crypto_param pubkey;
+	rte_crypto_param pkey;
+	rte_crypto_param sign;
+	rte_crypto_param message;
+	int curve;
+	int instance;
+};
+
 struct cperf_sm2_test_data {
 	rte_crypto_param pubkey_qx;
 	rte_crypto_param pubkey_qy;
@@ -147,6 +156,7 @@ extern uint8_t digest[2048];
 
 extern struct cperf_modex_test_data modex_perf_data[10];
 extern struct cperf_ecdsa_test_data secp256r1_perf_data;
+extern struct cperf_eddsa_test_data ed25519_perf_data;
 extern struct cperf_sm2_test_data sm2_perf_data;
 
 #endif
diff --git a/app/test-crypto-perf/main.c b/app/test-crypto-perf/main.c
index 75810dbf0b..d93b30bcaa 100644
--- a/app/test-crypto-perf/main.c
+++ b/app/test-crypto-perf/main.c
@@ -46,6 +46,7 @@ const char *cperf_op_type_strs[] = {
 	[CPERF_IPSEC] = "ipsec",
 	[CPERF_ASYM_MODEX] = "modex",
 	[CPERF_ASYM_SECP256R1] = "ecdsa_p256r1",
+	[CPERF_ASYM_ED25519] = "eddsa_25519",
 	[CPERF_ASYM_SM2] = "sm2",
 	[CPERF_TLS] = "tls-record"
 };
@@ -227,6 +228,7 @@ cperf_initialize_cryptodev(struct cperf_options *opts, uint8_t *enabled_cdevs)
 
 		switch (opts->op_type) {
 		case CPERF_ASYM_SECP256R1:
+		case CPERF_ASYM_ED25519:
 		case CPERF_ASYM_SM2:
 		case CPERF_ASYM_MODEX:
 			conf.ff_disable |= (RTE_CRYPTODEV_FF_SECURITY |
@@ -382,6 +384,17 @@ cperf_verify_devices_capabilities(struct cperf_options *opts,
 			}
 		}
 
+		if (opts->op_type == CPERF_ASYM_ED25519) {
+			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
+			if (asym_capability == NULL)
+				return -1;
+
+			if (!rte_cryptodev_asym_xform_capability_check_optype(asym_capability,
+						opts->asym_op_type))
+				return -1;
+		}
+
 		if (opts->op_type == CPERF_ASYM_SM2) {
 			asym_cap_idx.type = RTE_CRYPTO_ASYM_XFORM_SM2;
 			asym_capability = rte_cryptodev_asym_capability_get(cdev_id, &asym_cap_idx);
diff --git a/doc/guides/tools/cryptoperf.rst b/doc/guides/tools/cryptoperf.rst
index 0510a3bb89..9a20a73f03 100644
--- a/doc/guides/tools/cryptoperf.rst
+++ b/doc/guides/tools/cryptoperf.rst
@@ -176,6 +176,7 @@ The following are the application command-line options:
            docsis
            modex
            ecdsa_p256r1
+           eddsa_25519
            sm2
            ipsec
            tls-record
-- 
2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 5/6] examples/fips_validation: support EDDSA
  2024-10-04  8:26             ` [PATCH v6 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
@ 2024-10-04 16:19               ` Dooley, Brian
  0 siblings, 0 replies; 47+ messages in thread
From: Dooley, Brian @ 2024-10-04 16:19 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev
  Cc: Anoob Joseph, Richardson, Bruce, jerinj, fanzhang.oss, Kusztal,
	ArkadiuszX, Ji, Kai, jack.bond-preston, Marchand,  David,
	hemant.agrawal, De Lara Guarch, Pablo, Trahe, Fiona, Doherty,
	Declan, matan, ruifeng.wang, Akhil Goyal

Hi Gowrishankar,

> -----Original Message-----
> From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> Sent: Friday, October 4, 2024 9:26 AM
> To: dev@dpdk.org; Dooley, Brian <brian.dooley@intel.com>; Gowrishankar
> Muthukrishnan <gmuthukrishn@marvell.com>
> Cc: Anoob Joseph <anoobj@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; jerinj@marvell.com;
> fanzhang.oss@gmail.com; Kusztal, ArkadiuszX
> <arkadiuszx.kusztal@intel.com>; Ji, Kai <kai.ji@intel.com>; jack.bond-
> preston@foss.arm.com; Marchand, David <david.marchand@redhat.com>;
> hemant.agrawal@nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
> Doherty, Declan <declan.doherty@intel.com>; matan@nvidia.com;
> ruifeng.wang@arm.com; Akhil Goyal <gakhil@marvell.com>
> Subject: [PATCH v6 5/6] examples/fips_validation: support EDDSA
> 
> Add EDDSA support in fips_validation app.
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>

Acked-by: Brian Dooley <brian.dooley@intel.com>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 6/6] app/crypto-perf: support EDDSA
  2024-10-04  8:26             ` [PATCH v6 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
@ 2024-10-04 16:20               ` Dooley, Brian
  0 siblings, 0 replies; 47+ messages in thread
From: Dooley, Brian @ 2024-10-04 16:20 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev
  Cc: Anoob Joseph, Richardson, Bruce, jerinj, fanzhang.oss, Kusztal,
	ArkadiuszX, Ji, Kai, jack.bond-preston, Marchand,  David,
	hemant.agrawal, De Lara Guarch, Pablo, Trahe, Fiona, Doherty,
	Declan, matan, ruifeng.wang, Akhil Goyal

Hi Gowrishankar,

> -----Original Message-----
> From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> Sent: Friday, October 4, 2024 9:26 AM
> To: dev@dpdk.org; Dooley, Brian <brian.dooley@intel.com>
> Cc: Anoob Joseph <anoobj@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; jerinj@marvell.com;
> fanzhang.oss@gmail.com; Kusztal, ArkadiuszX
> <arkadiuszx.kusztal@intel.com>; Ji, Kai <kai.ji@intel.com>; jack.bond-
> preston@foss.arm.com; Marchand, David <david.marchand@redhat.com>;
> hemant.agrawal@nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
> Doherty, Declan <declan.doherty@intel.com>; matan@nvidia.com;
> ruifeng.wang@arm.com; Akhil Goyal <gakhil@marvell.com>; Gowrishankar
> Muthukrishnan <gmuthukrishn@marvell.com>
> Subject: [PATCH v6 6/6] app/crypto-perf: support EDDSA
> 
> Added support for EDDSA 25519 curve SIGN and VERIFY operations.
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>

Acked-by: Brian Dooley <brian.dooley@intel.com>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH v6 2/6] crypto/openssl: support EDDSA
  2024-10-04  8:26             ` [PATCH v6 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
@ 2024-10-07  9:50               ` Ji, Kai
  2024-10-07 16:27               ` Kusztal, ArkadiuszX
  1 sibling, 0 replies; 47+ messages in thread
From: Ji, Kai @ 2024-10-07  9:50 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev
  Cc: Anoob Joseph, Richardson, Bruce, jerinj, fanzhang.oss, Kusztal,
	ArkadiuszX, jack.bond-preston, Marchand, David, hemant.agrawal,
	De Lara Guarch, Pablo, Trahe, Fiona, Doherty, Declan, matan,
	ruifeng.wang, Akhil Goyal

[-- Attachment #1: Type: text/plain, Size: 19631 bytes --]

Acked-by: Kai Ji <kai.ji@intel.com>

________________________________
From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Sent: 04 October 2024 09:26
To: dev@dpdk.org <dev@dpdk.org>; Ji, Kai <kai.ji@intel.com>
Cc: Anoob Joseph <anoobj@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>; jerinj@marvell.com <jerinj@marvell.com>; fanzhang.oss@gmail.com <fanzhang.oss@gmail.com>; Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; jack.bond-preston@foss.arm.com <jack.bond-preston@foss.arm.com>; Marchand, David <david.marchand@redhat.com>; hemant.agrawal@nxp.com <hemant.agrawal@nxp.com>; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>; Doherty, Declan <declan.doherty@intel.com>; matan@nvidia.com <matan@nvidia.com>; ruifeng.wang@arm.com <ruifeng.wang@arm.com>; Akhil Goyal <gakhil@marvell.com>; Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Subject: [PATCH v6 2/6] crypto/openssl: support EDDSA

Support EDDSA crypto algorithm in OpenSSL PMD.

Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
 doc/guides/cryptodevs/features/openssl.ini   |   1 +
 drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
 drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
 drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
 4 files changed, 368 insertions(+)

diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index b64c8ec4a5..0540c075dc 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -66,6 +66,7 @@ Modular Exponentiation = Y
 Modular Inversion = Y
 Diffie-hellman = Y
 SM2 = Y
+EDDSA = Y

 ;
 ; Supported Operating systems of the 'openssl' crypto driver.
diff --git a/drivers/crypto/openssl/openssl_pmd_private.h b/drivers/crypto/openssl/openssl_pmd_private.h
index 0282b3d829..7dd97f1c72 100644
--- a/drivers/crypto/openssl/openssl_pmd_private.h
+++ b/drivers/crypto/openssl/openssl_pmd_private.h
@@ -231,10 +231,23 @@ struct __rte_cache_aligned openssl_asym_session {
 #endif
                 } s;
                 struct {
+                       uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+                       EC_GROUP * group;
+                       BIGNUM *priv_key;
+#endif
+               } ec;
+               struct {
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
                         OSSL_PARAM * params;
 #endif
                 } sm2;
+               struct {
+                       uint8_t curve_id;
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+                       OSSL_PARAM * params;
+#endif
+               } eddsa;
         } u;
 };
 /** Set and validate OPENSSL crypto session parameters */
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index e10a172f46..4e4d06403b 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -2849,6 +2849,45 @@ process_openssl_rsa_op_evp(struct rte_crypto_op *cop,

 }

+static int
+process_openssl_ecfpm_op_evp(struct rte_crypto_op *cop,
+               struct openssl_asym_session *sess)
+{
+       const EC_GROUP *ecgrp = sess->u.ec.group;
+       EC_POINT *ecpt = NULL;
+       BN_CTX *ctx = NULL;
+       BIGNUM *n = NULL;
+       int ret = -1;
+
+       n = BN_bin2bn((const unsigned char *)
+                       cop->asym->ecpm.scalar.data,
+                       cop->asym->ecpm.scalar.length,
+                       BN_new());
+
+       ctx = BN_CTX_new();
+       if (!ctx)
+               goto err_ecfpm;
+
+       if (!EC_POINT_mul(ecgrp, ecpt, n, NULL, NULL, ctx))
+               goto err_ecfpm;
+
+       if (cop->asym->flags & RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED) {
+               unsigned char *buf = cop->asym->ecpm.r.x.data;
+               size_t sz;
+
+               sz = EC_POINT_point2oct(ecgrp, ecpt, POINT_CONVERSION_COMPRESSED, buf, 0, ctx);
+               if (!sz)
+                       goto err_ecfpm;
+
+               cop->asym->ecpm.r.x.length = sz;
+       }
+
+err_ecfpm:
+       BN_CTX_free(ctx);
+       BN_free(n);
+       return ret;
+}
+
 static int
 process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
                 struct openssl_asym_session *sess)
@@ -3074,6 +3113,158 @@ process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
         return ret;
 }

+static int
+process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
+               struct openssl_asym_session *sess)
+{
+       static const char * const instance[] = {"Ed25519", "Ed25519ctx", "Ed25519ph",
+                                               "Ed448", "Ed448ph"};
+       EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
+       const uint8_t curve_id = sess->u.eddsa.curve_id;
+       struct rte_crypto_asym_op *op = cop->asym;
+       OSSL_PARAM *params = sess->u.eddsa.params;
+       OSSL_PARAM_BLD *iparam_bld = NULL;
+       OSSL_PARAM *iparams = NULL;
+       uint8_t signbuf[128] = {0};
+       EVP_MD_CTX *md_ctx = NULL;
+       EVP_PKEY *pkey = NULL;
+       size_t signlen;
+       int ret = -1;
+
+       cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+       iparam_bld = OSSL_PARAM_BLD_new();
+       if (!iparam_bld)
+               goto err_eddsa;
+
+       if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519CTX) {
+               OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-string",
+                       op->eddsa.context.data, op->eddsa.context.length);
+
+       }
+
+       OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
+               instance[op->eddsa.instance], strlen(instance[op->eddsa.instance]));
+
+       iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
+       if (!iparams)
+               goto err_eddsa;
+
+       switch (op->eddsa.op_type) {
+       case RTE_CRYPTO_ASYM_OP_SIGN:
+               {
+                       if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+                               kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+                       else
+                               kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+                       if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+                               EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+                               goto err_eddsa;
+
+                       md_ctx = EVP_MD_CTX_new();
+                       if (!md_ctx)
+                               goto err_eddsa;
+
+                       sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+                       if (!sctx)
+                               goto err_eddsa;
+
+                       EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+                       if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+                               goto err_eddsa;
+#else
+                       if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+                               op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+                               if (!EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, pkey))
+                                       goto err_eddsa;
+                       } else
+                               goto err_eddsa;
+#endif
+
+                       if (!EVP_DigestSign(md_ctx, NULL, &signlen, op->eddsa.message.data,
+                                       op->eddsa.message.length))
+                               goto err_eddsa;
+
+                       if (signlen > RTE_DIM(signbuf))
+                               goto err_eddsa;
+
+                       if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op->eddsa.message.data,
+                                       op->eddsa.message.length))
+                               goto err_eddsa;
+
+                       memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
+                       op->eddsa.sign.length = signlen;
+               }
+               break;
+       case RTE_CRYPTO_ASYM_OP_VERIFY:
+               {
+                       if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
+                               kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED25519", NULL);
+                       else
+                               kctx = EVP_PKEY_CTX_new_from_name(NULL, "ED448", NULL);
+
+                       if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0 ||
+                               EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+                               goto err_eddsa;
+
+                       md_ctx = EVP_MD_CTX_new();
+                       if (!md_ctx)
+                               goto err_eddsa;
+
+                       sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+                       if (!sctx)
+                               goto err_eddsa;
+
+                       EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+                       if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL, NULL, NULL, pkey, iparams))
+                               goto err_eddsa;
+#else
+                       if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519 ||
+                               op->eddsa.instance == RTE_CRYPTO_EDCURVE_448) {
+                               if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey))
+                                       goto err_eddsa;
+                       } else
+                               goto err_eddsa;
+#endif
+
+                       signlen = op->eddsa.sign.length;
+                       memcpy(&signbuf[0], op->eddsa.sign.data, op->eddsa.sign.length);
+
+                       ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op->eddsa.message.data,
+                                       op->eddsa.message.length);
+                       if (ret == 0)
+                               goto err_eddsa;
+               }
+               break;
+       default:
+               /* allow ops with invalid args to be pushed to
+                * completion queue
+                */
+               cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+               goto err_eddsa;
+       }
+
+       ret = 0;
+       cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+err_eddsa:
+       OSSL_PARAM_BLD_free(iparam_bld);
+
+       if (sctx)
+               EVP_PKEY_CTX_free(sctx);
+
+       if (cctx)
+               EVP_PKEY_CTX_free(cctx);
+
+       if (pkey)
+               EVP_PKEY_free(pkey);
+
+       return ret;
+}
 #else
 static int
 process_openssl_rsa_op(struct rte_crypto_op *cop,
@@ -3174,6 +3365,15 @@ process_openssl_rsa_op(struct rte_crypto_op *cop,
         return 0;
 }

+static int
+process_openssl_ecfpm_op(struct rte_crypto_op *cop,
+               struct openssl_asym_session *sess)
+{
+       RTE_SET_USED(cop);
+       RTE_SET_USED(sess);
+       return -ENOTSUP;
+}
+
 static int
 process_openssl_sm2_op(struct rte_crypto_op *cop,
                 struct openssl_asym_session *sess)
@@ -3182,6 +3382,15 @@ process_openssl_sm2_op(struct rte_crypto_op *cop,
         RTE_SET_USED(sess);
         return -ENOTSUP;
 }
+
+static int
+process_openssl_eddsa_op(struct rte_crypto_op *cop,
+               struct openssl_asym_session *sess)
+{
+       RTE_SET_USED(cop);
+       RTE_SET_USED(sess);
+       return -ENOTSUP;
+}
 #endif

 static int
@@ -3230,6 +3439,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
                                 process_openssl_dsa_verify_op(op, sess);
                 else
                         op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+#endif
+               break;
+       case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+               retval = process_openssl_ecfpm_op_evp(op, sess);
+#else
+               retval = process_openssl_ecfpm_op(op, sess);
 #endif
                 break;
         case RTE_CRYPTO_ASYM_XFORM_SM2:
@@ -3237,6 +3453,13 @@ process_asym_op(struct openssl_qp *qp, struct rte_crypto_op *op,
                 retval = process_openssl_sm2_op_evp(op, sess);
 #else
                 retval = process_openssl_sm2_op(op, sess);
+#endif
+               break;
+       case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+               retval = process_openssl_eddsa_op_evp(op, sess);
+#else
+               retval = process_openssl_eddsa_op(op, sess);
 #endif
                 break;
         default:
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index b7b612fc57..0725184653 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -593,6 +593,16 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
                 },
                 }
         },
+       {       /* ECFPM */
+               .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+               {.asym = {
+                       .xform_capa = {
+                               .xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM,
+                               .op_types = 0
+                               }
+                       }
+               }
+       },
         {       /* SM2 */
                 .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
                 {.asym = {
@@ -610,6 +620,20 @@ static const struct rte_cryptodev_capabilities openssl_pmd_capabilities[] = {
                 }
                 }
         },
+       {       /* EDDSA */
+               .op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+               {.asym = {
+                       .xform_capa = {
+                               .xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA,
+                               .hash_algos = (1 << RTE_CRYPTO_AUTH_SHA512 |
+                                              1 << RTE_CRYPTO_AUTH_SHAKE_256),
+                               .op_types =
+                               ((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
+                                (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+                       }
+               }
+               }
+       },

         RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
@@ -1356,6 +1380,47 @@ static int openssl_set_asym_session_parameters(
                 BN_free(pub_key);
                 return -1;
         }
+       case RTE_CRYPTO_ASYM_XFORM_ECFPM:
+       {
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+               EC_GROUP *ecgrp = NULL;
+
+               asym_session->xfrm_type = xform->xform_type;
+
+               switch (xform->ec.curve_id) {
+               case RTE_CRYPTO_EC_GROUP_SECP192R1:
+                       ecgrp = EC_GROUP_new_by_curve_name(NID_secp192k1);
+                       break;
+               case RTE_CRYPTO_EC_GROUP_SECP224R1:
+                       ecgrp = EC_GROUP_new_by_curve_name(NID_secp224r1);
+                       break;
+               case RTE_CRYPTO_EC_GROUP_SECP256R1:
+                       ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
+                       break;
+               case RTE_CRYPTO_EC_GROUP_SECP384R1:
+                       ecgrp = EC_GROUP_new_by_curve_name(NID_secp384r1);
+                       break;
+               case RTE_CRYPTO_EC_GROUP_SECP521R1:
+                       ecgrp = EC_GROUP_new_by_curve_name(NID_secp521r1);
+                       break;
+               case RTE_CRYPTO_EC_GROUP_ED25519:
+                       ecgrp = EC_GROUP_new_by_curve_name(NID_ED25519);
+                       break;
+               case RTE_CRYPTO_EC_GROUP_ED448:
+                       ecgrp = EC_GROUP_new_by_curve_name(NID_ED448);
+                       break;
+               default:
+                       break;
+               }
+
+               asym_session->u.ec.curve_id = xform->ec.curve_id;
+               asym_session->u.ec.group = ecgrp;
+               break;
+#else
+               OPENSSL_LOG(WARNING, "ECFPM unsupported for OpenSSL Version < 3.0");
+               return -ENOTSUP;
+#endif
+       }
         case RTE_CRYPTO_ASYM_XFORM_SM2:
         {
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
@@ -1440,6 +1505,66 @@ static int openssl_set_asym_session_parameters(
 #else
                 OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL Version < 3.0");
                 return -ENOTSUP;
+#endif
+       }
+       case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+       {
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+               OSSL_PARAM_BLD *param_bld = NULL;
+               OSSL_PARAM *params = NULL;
+               int ret = -1;
+
+               asym_session->u.eddsa.curve_id = xform->ec.curve_id;
+
+               param_bld = OSSL_PARAM_BLD_new();
+               if (!param_bld) {
+                       OPENSSL_LOG(ERR, "failed to allocate params");
+                       goto err_eddsa;
+               }
+
+               ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
+                         OSSL_PKEY_PARAM_GROUP_NAME, "ED25519", sizeof("ED25519"));
+               if (!ret) {
+                       OPENSSL_LOG(ERR, "failed to push params");
+                       goto err_eddsa;
+               }
+
+               ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PRIV_KEY,
+                               xform->ec.pkey.data, xform->ec.pkey.length);
+               if (!ret) {
+                       OPENSSL_LOG(ERR, "failed to push params");
+                       goto err_eddsa;
+               }
+
+               ret = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_PKEY_PARAM_PUB_KEY,
+                               xform->ec.q.x.data, xform->ec.q.x.length);
+               if (!ret) {
+                       OPENSSL_LOG(ERR, "failed to push params");
+                       goto err_eddsa;
+               }
+
+               params = OSSL_PARAM_BLD_to_param(param_bld);
+               if (!params) {
+                       OPENSSL_LOG(ERR, "failed to push params");
+                       goto err_eddsa;
+               }
+
+               asym_session->u.eddsa.params = params;
+               OSSL_PARAM_BLD_free(param_bld);
+
+               asym_session->xfrm_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+               break;
+err_eddsa:
+               if (param_bld)
+                       OSSL_PARAM_BLD_free(param_bld);
+
+               if (asym_session->u.eddsa.params)
+                       OSSL_PARAM_free(asym_session->u.eddsa.params);
+
+               return -1;
+#else
+               OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL Version < 3.3");
+               return -ENOTSUP;
 #endif
         }
         default:
@@ -1538,6 +1663,12 @@ static void openssl_reset_asym_session(struct openssl_asym_session *sess)
 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
                 OSSL_PARAM_free(sess->u.sm2.params);
 #endif
+               break;
+       case RTE_CRYPTO_ASYM_XFORM_EDDSA:
+#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
+               OSSL_PARAM_free(sess->u.eddsa.params);
+#endif
+               break;
         default:
                 break;
         }
--
2.21.0


[-- Attachment #2: Type: text/html, Size: 49393 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
                               ` (4 preceding siblings ...)
  2024-10-04  8:26             ` [PATCH v6 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
@ 2024-10-07 16:03             ` Kusztal, ArkadiuszX
  2024-10-08  7:40               ` Kusztal, ArkadiuszX
  5 siblings, 1 reply; 47+ messages in thread
From: Kusztal, ArkadiuszX @ 2024-10-07 16:03 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, Richardson, Bruce, jerinj, Ji,  Kai,
	jack.bond-preston, Marchand, David, hemant.agrawal,
	De Lara Guarch, Pablo, Trahe, Fiona, Doherty, Declan, matan,
	ruifeng.wang

Hi Gowrishankar,

I like the idea of adding EdDSA, but I have several comments.

> -----Original Message-----
> From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> Sent: Friday, October 4, 2024 10:26 AM
> To: dev@dpdk.org; Akhil Goyal <gakhil@marvell.com>; Fan Zhang
> <fanzhang.oss@gmail.com>
> Cc: Anoob Joseph <anoobj@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; jerinj@marvell.com; Kusztal, ArkadiuszX
> <arkadiuszx.kusztal@intel.com>; Ji, Kai <kai.ji@intel.com>; jack.bond-
> preston@foss.arm.com; Marchand, David <david.marchand@redhat.com>;
> hemant.agrawal@nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
> Doherty, Declan <declan.doherty@intel.com>; matan@nvidia.com;
> ruifeng.wang@arm.com; Gowrishankar Muthukrishnan
> <gmuthukrishn@marvell.com>
> Subject: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
> 
> Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
> https://datatracker.ietf.org/doc/html/rfc8032
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> ---
>  doc/guides/cryptodevs/features/default.ini |  1 +
>  doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
>  lib/cryptodev/rte_crypto_asym.h            | 47 ++++++++++++++++++++++
>  3 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/guides/cryptodevs/features/default.ini
> b/doc/guides/cryptodevs/features/default.ini
> index f411d4bab7..3073753911 100644
> --- a/doc/guides/cryptodevs/features/default.ini
> +++ b/doc/guides/cryptodevs/features/default.ini
> @@ -130,6 +130,7 @@ ECDSA                   =
>  ECPM                    =
>  ECDH                    =
>  SM2                     =
> +EDDSA                   =
> 
>  ;
>  ; Supported Operating systems of a default crypto driver.
> diff --git a/doc/guides/prog_guide/cryptodev_lib.rst
> b/doc/guides/prog_guide/cryptodev_lib.rst
> index 2b513bbf82..dd636ba5ef 100644
> --- a/doc/guides/prog_guide/cryptodev_lib.rst
> +++ b/doc/guides/prog_guide/cryptodev_lib.rst
> @@ -927,7 +927,7 @@ Asymmetric Cryptography  The cryptodev library
> currently provides support for the following asymmetric  Crypto operations;
> RSA, Modular exponentiation and inversion, Diffie-Hellman and  Elliptic Curve
> Diffie-Hellman public and/or private key generation and shared -secret compute,
> DSA Signature generation and verification.
> +secret compute, DSA and EdDSA Signature generation and verification.
> 
>  Session and Session Management
>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> diff --git a/lib/cryptodev/rte_crypto_asym.h b/lib/cryptodev/rte_crypto_asym.h
> index 39d3da3952..fe4194c184 100644
> --- a/lib/cryptodev/rte_crypto_asym.h
> +++ b/lib/cryptodev/rte_crypto_asym.h
> @@ -49,6 +49,10 @@ rte_crypto_asym_op_strings[];
>   * and if the flag is not set, shared secret will be padded to the left with
>   * zeros to the size of the underlying algorithm (default)
>   */
> +#define RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED
> 	RTE_BIT32(2)
> +/**<
> + * Flag to denote public key will be returned in compressed form  */
> 
>  /**
>   * List of elliptic curves. This enum aligns with @@ -65,9 +69,22 @@ enum
> rte_crypto_curve_id {
>  	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
>  	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
>  	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
> +	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
> +	RTE_CRYPTO_EC_GROUP_ED448     = 30,
>  	RTE_CRYPTO_EC_GROUP_SM2       = 41,
>  };
> 
> +/**
> + * List of Edwards curve instances as per RFC 8032 (Section 5).
> + */
> +enum rte_crypto_edward_instance {
> +	RTE_CRYPTO_EDCURVE_25519,
> +	RTE_CRYPTO_EDCURVE_25519CTX,
> +	RTE_CRYPTO_EDCURVE_25519PH,
> +	RTE_CRYPTO_EDCURVE_448,
> +	RTE_CRYPTO_EDCURVE_448PH
> +};
> +
>  /**
>   * Asymmetric crypto transformation types.
>   * Each xform type maps to one asymmetric algorithm @@ -119,6 +136,10 @@
> enum rte_crypto_asym_xform_type {
>  	 * Performs Encrypt, Decrypt, Sign and Verify.
>  	 * Refer to rte_crypto_asym_op_type.
>  	 */
> +	RTE_CRYPTO_ASYM_XFORM_EDDSA,
> +	/**< Edwards Curve Digital Signature Algorithm
> +	 * Perform Signature Generation and Verification.
> +	 */
>  	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
>  	/**< End of list */
>  };
> @@ -585,6 +606,31 @@ struct rte_crypto_ecdsa_op_param {
>  	 */
>  };
> 
> +/**
> + * EdDSA operation params
> + */
> +struct rte_crypto_eddsa_op_param {
> +	enum rte_crypto_asym_op_type op_type;
> +	/**< Signature generation or verification */
> +
> +	rte_crypto_param message;
> +	/**< Input message digest to be signed or verified */
HashEdDSA will require a message digest; pure EdDSA will require the message itself. For HW it will be more complicated.
> +
> +	rte_crypto_param context;
> +	/**< Context value for the sign op.
> +	 *   Must not be empty for Ed25519ctx instance.
> +	 */
> +
> +	enum rte_crypto_edward_instance instance;
> +	/**< Type of Edwards curve. */
All instances are using the same curve, where they differ is the way of handling input message.
And I think this should be a session variable -> new xform for the EdDSA.
> +
> +	rte_crypto_uint sign;
> +	/**< Edward curve signature
> +	 *     output : for signature generation
> +	 *     input  : for signature verification
> +	 */
> +};
> +
>  /**
>   * Structure for EC point multiplication operation param
>   */
> @@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
>  		struct rte_crypto_ecdsa_op_param ecdsa;
>  		struct rte_crypto_ecpm_op_param ecpm;
>  		struct rte_crypto_sm2_op_param sm2;
> +		struct rte_crypto_eddsa_op_param eddsa;
>  	};
>  	uint16_t flags;
>  	/**<
> --
> 2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 2/6] crypto/openssl: support EDDSA
  2024-10-04  8:26             ` [PATCH v6 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
  2024-10-07  9:50               ` Ji, Kai
@ 2024-10-07 16:27               ` Kusztal, ArkadiuszX
  1 sibling, 0 replies; 47+ messages in thread
From: Kusztal, ArkadiuszX @ 2024-10-07 16:27 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev, Ji, Kai
  Cc: Anoob Joseph, Richardson, Bruce, jerinj, fanzhang.oss,
	jack.bond-preston, Marchand,  David, hemant.agrawal,
	De Lara Guarch, Pablo, Trahe, Fiona, Doherty, Declan, matan,
	ruifeng.wang, Akhil Goyal

Hi Gowrishankar,

> -----Original Message-----
> From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> Sent: Friday, October 4, 2024 10:26 AM
> To: dev@dpdk.org; Ji, Kai <kai.ji@intel.com>
> Cc: Anoob Joseph <anoobj@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; jerinj@marvell.com; fanzhang.oss@gmail.com;
> Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; jack.bond-
> preston@foss.arm.com; Marchand, David <david.marchand@redhat.com>;
> hemant.agrawal@nxp.com; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
> Doherty, Declan <declan.doherty@intel.com>; matan@nvidia.com;
> ruifeng.wang@arm.com; Akhil Goyal <gakhil@marvell.com>; Gowrishankar
> Muthukrishnan <gmuthukrishn@marvell.com>
> Subject: [PATCH v6 2/6] crypto/openssl: support EDDSA
> 
> Support EDDSA crypto algorithm in OpenSSL PMD.
> 
> Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> ---
>  doc/guides/cryptodevs/features/openssl.ini   |   1 +
>  drivers/crypto/openssl/openssl_pmd_private.h |  13 ++
>  drivers/crypto/openssl/rte_openssl_pmd.c     | 223 +++++++++++++++++++
>  drivers/crypto/openssl/rte_openssl_pmd_ops.c | 131 +++++++++++
>  4 files changed, 368 insertions(+)
> 
> diff --git a/doc/guides/cryptodevs/features/openssl.ini
> b/doc/guides/cryptodevs/features/openssl.ini
> index b64c8ec4a5..0540c075dc 100644
> --- a/doc/guides/cryptodevs/features/openssl.ini
> +++ b/doc/guides/cryptodevs/features/openssl.ini
> @@ -66,6 +66,7 @@ Modular Exponentiation = Y  Modular Inversion = Y  Diffie-
> hellman = Y
>  SM2 = Y
> +EDDSA = Y
> 
>  ;
>  ; Supported Operating systems of the 'openssl' crypto driver.
> diff --git a/drivers/crypto/openssl/openssl_pmd_private.h
> b/drivers/crypto/openssl/openssl_pmd_private.h
> index 0282b3d829..7dd97f1c72 100644
> --- a/drivers/crypto/openssl/openssl_pmd_private.h
> +++ b/drivers/crypto/openssl/openssl_pmd_private.h
> @@ -231,10 +231,23 @@ struct __rte_cache_aligned openssl_asym_session {
> #endif
>  		} s;
>  		struct {
> +			uint8_t curve_id;
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> +			EC_GROUP * group;
> +			BIGNUM *priv_key;
> +#endif
> +		} ec;
> +		struct {
>  #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
>  			OSSL_PARAM * params;
>  #endif
>  		} sm2;
> +		struct {
> +			uint8_t curve_id;
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> +			OSSL_PARAM * params;
> +#endif
> +		} eddsa;
>  	} u;
>  };
>  /** Set and validate OPENSSL crypto session parameters */ diff --git
> a/drivers/crypto/openssl/rte_openssl_pmd.c
> b/drivers/crypto/openssl/rte_openssl_pmd.c
> index e10a172f46..4e4d06403b 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd.c
> @@ -2849,6 +2849,45 @@ process_openssl_rsa_op_evp(struct rte_crypto_op
> *cop,
> 
>  }
> 
> +static int
> +process_openssl_ecfpm_op_evp(struct rte_crypto_op *cop,
> +		struct openssl_asym_session *sess)
> +{
> +	const EC_GROUP *ecgrp = sess->u.ec.group;
> +	EC_POINT *ecpt = NULL;
> +	BN_CTX *ctx = NULL;
> +	BIGNUM *n = NULL;
> +	int ret = -1;
> +
> +	n = BN_bin2bn((const unsigned char *)
> +			cop->asym->ecpm.scalar.data,
> +			cop->asym->ecpm.scalar.length,
> +			BN_new());
> +
> +	ctx = BN_CTX_new();
> +	if (!ctx)
> +		goto err_ecfpm;
> +
> +	if (!EC_POINT_mul(ecgrp, ecpt, n, NULL, NULL, ctx))
> +		goto err_ecfpm;
> +
> +	if (cop->asym->flags &
> RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED) {
> +		unsigned char *buf = cop->asym->ecpm.r.x.data;
> +		size_t sz;
> +
> +		sz = EC_POINT_point2oct(ecgrp, ecpt,
> POINT_CONVERSION_COMPRESSED, buf, 0, ctx);
> +		if (!sz)
> +			goto err_ecfpm;
> +
> +		cop->asym->ecpm.r.x.length = sz;
> +	}
> +
> +err_ecfpm:
> +	BN_CTX_free(ctx);
> +	BN_free(n);
> +	return ret;
> +}
> +
>  static int
>  process_openssl_sm2_op_evp(struct rte_crypto_op *cop,
>  		struct openssl_asym_session *sess)
> @@ -3074,6 +3113,158 @@ process_openssl_sm2_op_evp(struct
> rte_crypto_op *cop,
>  	return ret;
>  }
> 
> +static int
> +process_openssl_eddsa_op_evp(struct rte_crypto_op *cop,
> +		struct openssl_asym_session *sess)
> +{
> +	static const char * const instance[] = {"Ed25519", "Ed25519ctx",
> "Ed25519ph",
> +						"Ed448", "Ed448ph"};
> +	EVP_PKEY_CTX *kctx = NULL, *sctx = NULL, *cctx = NULL;
> +	const uint8_t curve_id = sess->u.eddsa.curve_id;
> +	struct rte_crypto_asym_op *op = cop->asym;
> +	OSSL_PARAM *params = sess->u.eddsa.params;
> +	OSSL_PARAM_BLD *iparam_bld = NULL;
> +	OSSL_PARAM *iparams = NULL;
> +	uint8_t signbuf[128] = {0};
> +	EVP_MD_CTX *md_ctx = NULL;
> +	EVP_PKEY *pkey = NULL;
> +	size_t signlen;
> +	int ret = -1;
> +
> +	cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
> +
> +	iparam_bld = OSSL_PARAM_BLD_new();
> +	if (!iparam_bld)
> +		goto err_eddsa;
> +
> +	if (op->eddsa.instance == RTE_CRYPTO_EDCURVE_25519CTX) {
> +		OSSL_PARAM_BLD_push_octet_string(iparam_bld, "context-
> string",
> +			op->eddsa.context.data, op->eddsa.context.length);
> +
> +	}
> +
> +	OSSL_PARAM_BLD_push_utf8_string(iparam_bld, "instance",
> +		instance[op->eddsa.instance], strlen(instance[op-
> >eddsa.instance]));
> +
> +	iparams = OSSL_PARAM_BLD_to_param(iparam_bld);
> +	if (!iparams)
> +		goto err_eddsa;
> +
> +	switch (op->eddsa.op_type) {
> +	case RTE_CRYPTO_ASYM_OP_SIGN:
> +		{
> +			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
> +				kctx = EVP_PKEY_CTX_new_from_name(NULL,
> "ED25519", NULL);

I see this is a pattern in this PMD, but there are plenty of operations that should be done in session instead on the datapath.
EVP_PKEY_CTX_new_from_name
EVP_PKEY_fromdata
EVP_MD_CTX_new
EVP_MD_CTX_set_pkey_ctx
Should rather be done once per session than per every operation in with-session case.

> +			else
> +				kctx = EVP_PKEY_CTX_new_from_name(NULL,
> "ED448", NULL);
> +
> +			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0
> ||
> +				EVP_PKEY_fromdata(kctx, &pkey,
> EVP_PKEY_KEYPAIR, params) <= 0)
> +				goto err_eddsa;
> +
> +			md_ctx = EVP_MD_CTX_new();
> +			if (!md_ctx)
> +				goto err_eddsa;
> +
> +			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey,
> NULL);
> +			if (!sctx)
> +				goto err_eddsa;
> +
> +			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
> +
> +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
> +			if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, NULL,
> NULL, pkey, iparams))
> +				goto err_eddsa;
> +#else
> +			if (op->eddsa.instance ==
> RTE_CRYPTO_EDCURVE_25519 ||
> +				op->eddsa.instance ==
> RTE_CRYPTO_EDCURVE_448) {
> +				if (!EVP_DigestSignInit(md_ctx, NULL, NULL,
> NULL, pkey))
> +					goto err_eddsa;
> +			} else
> +				goto err_eddsa;
> +#endif
> +
> +			if (!EVP_DigestSign(md_ctx, NULL, &signlen, op-
> >eddsa.message.data,
> +					op->eddsa.message.length))
> +				goto err_eddsa;
> +
> +			if (signlen > RTE_DIM(signbuf))
> +				goto err_eddsa;
> +
> +			if (!EVP_DigestSign(md_ctx, signbuf, &signlen, op-
> >eddsa.message.data,
> +					op->eddsa.message.length))
> +				goto err_eddsa;
> +
> +			memcpy(op->eddsa.sign.data, &signbuf[0], signlen);
> +			op->eddsa.sign.length = signlen;
> +		}
> +		break;
> +	case RTE_CRYPTO_ASYM_OP_VERIFY:
> +		{
> +			if (curve_id == RTE_CRYPTO_EC_GROUP_ED25519)
> +				kctx = EVP_PKEY_CTX_new_from_name(NULL,
> "ED25519", NULL);
> +			else
> +				kctx = EVP_PKEY_CTX_new_from_name(NULL,
> "ED448", NULL);
> +
> +			if (kctx == NULL || EVP_PKEY_fromdata_init(kctx) <= 0
> ||
> +				EVP_PKEY_fromdata(kctx, &pkey,
> EVP_PKEY_PUBLIC_KEY, params) <= 0)
> +				goto err_eddsa;
> +
> +			md_ctx = EVP_MD_CTX_new();
> +			if (!md_ctx)
> +				goto err_eddsa;
> +
> +			sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey,
> NULL);
> +			if (!sctx)
> +				goto err_eddsa;
> +
> +			EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
> +
> +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
> +			if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL,
> NULL, NULL, pkey, iparams))
> +				goto err_eddsa;
> +#else
> +			if (op->eddsa.instance ==
> RTE_CRYPTO_EDCURVE_25519 ||
> +				op->eddsa.instance ==
> RTE_CRYPTO_EDCURVE_448) {
> +				if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL,
> NULL, pkey))
> +					goto err_eddsa;
> +			} else
> +				goto err_eddsa;
> +#endif
> +
> +			signlen = op->eddsa.sign.length;
> +			memcpy(&signbuf[0], op->eddsa.sign.data, op-
> >eddsa.sign.length);
> +
> +			ret = EVP_DigestVerify(md_ctx, signbuf, signlen, op-
> >eddsa.message.data,
> +					op->eddsa.message.length);
> +			if (ret == 0)
> +				goto err_eddsa;
> +		}
> +		break;
> +	default:
> +		/* allow ops with invalid args to be pushed to
> +		 * completion queue
> +		 */
> +		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> +		goto err_eddsa;
> +	}
> +
> +	ret = 0;
> +	cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
> +err_eddsa:
> +	OSSL_PARAM_BLD_free(iparam_bld);
> +
> +	if (sctx)
> +		EVP_PKEY_CTX_free(sctx);
> +
> +	if (cctx)
> +		EVP_PKEY_CTX_free(cctx);
> +
> +	if (pkey)
> +		EVP_PKEY_free(pkey);
> +
> +	return ret;
> +}
>  #else
>  static int
>  process_openssl_rsa_op(struct rte_crypto_op *cop, @@ -3174,6 +3365,15 @@
> process_openssl_rsa_op(struct rte_crypto_op *cop,
>  	return 0;
>  }
> 
> +static int
> +process_openssl_ecfpm_op(struct rte_crypto_op *cop,
> +		struct openssl_asym_session *sess)
> +{
> +	RTE_SET_USED(cop);
> +	RTE_SET_USED(sess);
> +	return -ENOTSUP;
> +}
> +
>  static int
>  process_openssl_sm2_op(struct rte_crypto_op *cop,
>  		struct openssl_asym_session *sess)
> @@ -3182,6 +3382,15 @@ process_openssl_sm2_op(struct rte_crypto_op
> *cop,
>  	RTE_SET_USED(sess);
>  	return -ENOTSUP;
>  }
> +
> +static int
> +process_openssl_eddsa_op(struct rte_crypto_op *cop,
> +		struct openssl_asym_session *sess)
> +{
> +	RTE_SET_USED(cop);
> +	RTE_SET_USED(sess);
> +	return -ENOTSUP;
> +}
>  #endif
> 
>  static int
> @@ -3230,6 +3439,13 @@ process_asym_op(struct openssl_qp *qp, struct
> rte_crypto_op *op,
>  				process_openssl_dsa_verify_op(op, sess);
>  		else
>  			op->status =
> RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> +#endif
> +		break;
> +	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> +		retval = process_openssl_ecfpm_op_evp(op, sess); #else
> +		retval = process_openssl_ecfpm_op(op, sess);
>  #endif
>  		break;
>  	case RTE_CRYPTO_ASYM_XFORM_SM2:
> @@ -3237,6 +3453,13 @@ process_asym_op(struct openssl_qp *qp, struct
> rte_crypto_op *op,
>  		retval = process_openssl_sm2_op_evp(op, sess);  #else
>  		retval = process_openssl_sm2_op(op, sess);
> +#endif
> +		break;
> +	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> +		retval = process_openssl_eddsa_op_evp(op, sess); #else
> +		retval = process_openssl_eddsa_op(op, sess);
>  #endif
>  		break;
>  	default:
> diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> index b7b612fc57..0725184653 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
> @@ -593,6 +593,16 @@ static const struct rte_cryptodev_capabilities
> openssl_pmd_capabilities[] = {
>  		},
>  		}
>  	},
> +	{	/* ECFPM */
> +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> +		{.asym = {
> +			.xform_capa = {
> +				.xform_type =
> RTE_CRYPTO_ASYM_XFORM_ECFPM,
> +				.op_types = 0
> +				}
> +			}
> +		}
> +	},
>  	{	/* SM2 */
>  		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
>  		{.asym = {
> @@ -610,6 +620,20 @@ static const struct rte_cryptodev_capabilities
> openssl_pmd_capabilities[] = {
>  		}
>  		}
>  	},
> +	{	/* EDDSA */
> +		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
> +		{.asym = {
> +			.xform_capa = {
> +				.xform_type =
> RTE_CRYPTO_ASYM_XFORM_EDDSA,
> +				.hash_algos = (1 <<
> RTE_CRYPTO_AUTH_SHA512 |
> +					       1 <<
> RTE_CRYPTO_AUTH_SHAKE_256),
> +				.op_types =
> +				((1<<RTE_CRYPTO_ASYM_OP_SIGN) |
> +				 (1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
> +			}
> +		}
> +		}
> +	},
> 
>  	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
>  };
> @@ -1356,6 +1380,47 @@ static int openssl_set_asym_session_parameters(
>  		BN_free(pub_key);
>  		return -1;
>  	}
> +	case RTE_CRYPTO_ASYM_XFORM_ECFPM:
> +	{
> +#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
> +		EC_GROUP *ecgrp = NULL;
> +
> +		asym_session->xfrm_type = xform->xform_type;
> +
> +		switch (xform->ec.curve_id) {
> +		case RTE_CRYPTO_EC_GROUP_SECP192R1:
> +			ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp192k1);
> +			break;
> +		case RTE_CRYPTO_EC_GROUP_SECP224R1:
> +			ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp224r1);
> +			break;
> +		case RTE_CRYPTO_EC_GROUP_SECP256R1:
> +			ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp256k1);
> +			break;
> +		case RTE_CRYPTO_EC_GROUP_SECP384R1:
> +			ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp384r1);
> +			break;
> +		case RTE_CRYPTO_EC_GROUP_SECP521R1:
> +			ecgrp =
> EC_GROUP_new_by_curve_name(NID_secp521r1);
> +			break;
> +		case RTE_CRYPTO_EC_GROUP_ED25519:
> +			ecgrp =
> EC_GROUP_new_by_curve_name(NID_ED25519);
> +			break;
> +		case RTE_CRYPTO_EC_GROUP_ED448:
> +			ecgrp = EC_GROUP_new_by_curve_name(NID_ED448);
> +			break;
> +		default:
> +			break;
> +		}
> +
> +		asym_session->u.ec.curve_id = xform->ec.curve_id;
> +		asym_session->u.ec.group = ecgrp;
> +		break;
> +#else
> +		OPENSSL_LOG(WARNING, "ECFPM unsupported for OpenSSL
> Version < 3.0");
> +		return -ENOTSUP;
> +#endif
> +	}
>  	case RTE_CRYPTO_ASYM_XFORM_SM2:
>  	{
>  #if (OPENSSL_VERSION_NUMBER >= 0x30000000L) @@ -1440,6 +1505,66 @@
> static int openssl_set_asym_session_parameters(
>  #else
>  		OPENSSL_LOG(WARNING, "SM2 unsupported for OpenSSL
> Version < 3.0");
>  		return -ENOTSUP;
> +#endif
> +	}
> +	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
> +	{
> +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
> +		OSSL_PARAM_BLD *param_bld = NULL;
> +		OSSL_PARAM *params = NULL;
> +		int ret = -1;
> +
> +		asym_session->u.eddsa.curve_id = xform->ec.curve_id;
> +
> +		param_bld = OSSL_PARAM_BLD_new();
> +		if (!param_bld) {
> +			OPENSSL_LOG(ERR, "failed to allocate params");
> +			goto err_eddsa;
> +		}
> +
> +		ret = OSSL_PARAM_BLD_push_utf8_string(param_bld,
> +			  OSSL_PKEY_PARAM_GROUP_NAME, "ED25519",
> sizeof("ED25519"));
> +		if (!ret) {
> +			OPENSSL_LOG(ERR, "failed to push params");
> +			goto err_eddsa;
> +		}
> +
> +		ret = OSSL_PARAM_BLD_push_octet_string(param_bld,
> OSSL_PKEY_PARAM_PRIV_KEY,
> +				xform->ec.pkey.data, xform->ec.pkey.length);
> +		if (!ret) {
> +			OPENSSL_LOG(ERR, "failed to push params");
> +			goto err_eddsa;
> +		}
> +
> +		ret = OSSL_PARAM_BLD_push_octet_string(param_bld,
> OSSL_PKEY_PARAM_PUB_KEY,
> +				xform->ec.q.x.data, xform->ec.q.x.length);
> +		if (!ret) {
> +			OPENSSL_LOG(ERR, "failed to push params");
> +			goto err_eddsa;
> +		}
> +
> +		params = OSSL_PARAM_BLD_to_param(param_bld);
> +		if (!params) {
> +			OPENSSL_LOG(ERR, "failed to push params");
> +			goto err_eddsa;
> +		}
> +
> +		asym_session->u.eddsa.params = params;
> +		OSSL_PARAM_BLD_free(param_bld);
> +
> +		asym_session->xfrm_type =
> RTE_CRYPTO_ASYM_XFORM_EDDSA;
> +		break;
> +err_eddsa:
> +		if (param_bld)
> +			OSSL_PARAM_BLD_free(param_bld);
> +
> +		if (asym_session->u.eddsa.params)
> +			OSSL_PARAM_free(asym_session->u.eddsa.params);
> +
> +		return -1;
> +#else
> +		OPENSSL_LOG(WARNING, "EDDSA unsupported for OpenSSL
> Version < 3.3");
> +		return -ENOTSUP;
>  #endif
>  	}
>  	default:
> @@ -1538,6 +1663,12 @@ static void openssl_reset_asym_session(struct
> openssl_asym_session *sess)  #if (OPENSSL_VERSION_NUMBER >=
> 0x30000000L)
>  		OSSL_PARAM_free(sess->u.sm2.params);
>  #endif
> +		break;
> +	case RTE_CRYPTO_ASYM_XFORM_EDDSA:
> +#if (OPENSSL_VERSION_NUMBER >= 0x30300000L)
> +		OSSL_PARAM_free(sess->u.eddsa.params);
> +#endif
> +		break;
>  	default:
>  		break;
>  	}
> --
> 2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-10-07 16:03             ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Kusztal, ArkadiuszX
@ 2024-10-08  7:40               ` Kusztal, ArkadiuszX
  2024-10-08  9:31                 ` Gowrishankar Muthukrishnan
  0 siblings, 1 reply; 47+ messages in thread
From: Kusztal, ArkadiuszX @ 2024-10-08  7:40 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, Gowrishankar Muthukrishnan, dev,
	Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, Richardson, Bruce, jerinj, Ji,  Kai,
	jack.bond-preston, Marchand, David, hemant.agrawal,
	De Lara Guarch, Pablo, Trahe, Fiona, Doherty, Declan, matan,
	ruifeng.wang

Acked-by: Arkadiusz Kusztal <arkadiuszx.kusztal@intel.com>

> -----Original Message-----
> From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> Sent: Monday, October 7, 2024 6:04 PM
> To: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>;
> dev@dpdk.org; Akhil Goyal <gakhil@marvell.com>; Fan Zhang
> <fanzhang.oss@gmail.com>
> Cc: Anoob Joseph <anoobj@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; jerinj@marvell.com; Ji, Kai <kai.ji@intel.com>;
> jack.bond-preston@foss.arm.com; Marchand, David
> <david.marchand@redhat.com>; hemant.agrawal@nxp.com; De Lara Guarch,
> Pablo <pablo.de.lara.guarch@intel.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; Doherty, Declan <declan.doherty@intel.com>;
> matan@nvidia.com; ruifeng.wang@arm.com
> Subject: RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
> 
> Hi Gowrishankar,
> 
> I like the idea of adding EdDSA, but I have several comments.
> 
> > -----Original Message-----
> > From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> > Sent: Friday, October 4, 2024 10:26 AM
> > To: dev@dpdk.org; Akhil Goyal <gakhil@marvell.com>; Fan Zhang
> > <fanzhang.oss@gmail.com>
> > Cc: Anoob Joseph <anoobj@marvell.com>; Richardson, Bruce
> > <bruce.richardson@intel.com>; jerinj@marvell.com; Kusztal, ArkadiuszX
> > <arkadiuszx.kusztal@intel.com>; Ji, Kai <kai.ji@intel.com>; jack.bond-
> > preston@foss.arm.com; Marchand, David <david.marchand@redhat.com>;
> > hemant.agrawal@nxp.com; De Lara Guarch, Pablo
> > <pablo.de.lara.guarch@intel.com>; Trahe, Fiona
> > <fiona.trahe@intel.com>; Doherty, Declan <declan.doherty@intel.com>;
> > matan@nvidia.com; ruifeng.wang@arm.com; Gowrishankar Muthukrishnan
> > <gmuthukrishn@marvell.com>
> > Subject: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto
> > algorithm
> >
> > Add support for asymmetric EDDSA in cryptodev, as referenced in RFC:
> > https://datatracker.ietf.org/doc/html/rfc8032
> >
> > Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> > ---
> >  doc/guides/cryptodevs/features/default.ini |  1 +
> >  doc/guides/prog_guide/cryptodev_lib.rst    |  2 +-
> >  lib/cryptodev/rte_crypto_asym.h            | 47 ++++++++++++++++++++++
> >  3 files changed, 49 insertions(+), 1 deletion(-)
> >
> > diff --git a/doc/guides/cryptodevs/features/default.ini
> > b/doc/guides/cryptodevs/features/default.ini
> > index f411d4bab7..3073753911 100644
> > --- a/doc/guides/cryptodevs/features/default.ini
> > +++ b/doc/guides/cryptodevs/features/default.ini
> > @@ -130,6 +130,7 @@ ECDSA                   =
> >  ECPM                    =
> >  ECDH                    =
> >  SM2                     =
> > +EDDSA                   =
> >
> >  ;
> >  ; Supported Operating systems of a default crypto driver.
> > diff --git a/doc/guides/prog_guide/cryptodev_lib.rst
> > b/doc/guides/prog_guide/cryptodev_lib.rst
> > index 2b513bbf82..dd636ba5ef 100644
> > --- a/doc/guides/prog_guide/cryptodev_lib.rst
> > +++ b/doc/guides/prog_guide/cryptodev_lib.rst
> > @@ -927,7 +927,7 @@ Asymmetric Cryptography  The cryptodev library
> > currently provides support for the following asymmetric  Crypto
> > operations; RSA, Modular exponentiation and inversion, Diffie-Hellman
> > and  Elliptic Curve Diffie-Hellman public and/or private key
> > generation and shared -secret compute, DSA Signature generation and
> verification.
> > +secret compute, DSA and EdDSA Signature generation and verification.
> >
> >  Session and Session Management
> >  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > diff --git a/lib/cryptodev/rte_crypto_asym.h
> > b/lib/cryptodev/rte_crypto_asym.h index 39d3da3952..fe4194c184 100644
> > --- a/lib/cryptodev/rte_crypto_asym.h
> > +++ b/lib/cryptodev/rte_crypto_asym.h
> > @@ -49,6 +49,10 @@ rte_crypto_asym_op_strings[];
> >   * and if the flag is not set, shared secret will be padded to the left with
> >   * zeros to the size of the underlying algorithm (default)
> >   */
> > +#define RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED
> > 	RTE_BIT32(2)
> > +/**<
> > + * Flag to denote public key will be returned in compressed form  */
> >
> >  /**
> >   * List of elliptic curves. This enum aligns with @@ -65,9 +69,22 @@
> > enum rte_crypto_curve_id {
> >  	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
> >  	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
> >  	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
> > +	RTE_CRYPTO_EC_GROUP_ED25519   = 29,
> > +	RTE_CRYPTO_EC_GROUP_ED448     = 30,
> >  	RTE_CRYPTO_EC_GROUP_SM2       = 41,
> >  };
> >
> > +/**
> > + * List of Edwards curve instances as per RFC 8032 (Section 5).
> > + */
> > +enum rte_crypto_edward_instance {
> > +	RTE_CRYPTO_EDCURVE_25519,
> > +	RTE_CRYPTO_EDCURVE_25519CTX,
> > +	RTE_CRYPTO_EDCURVE_25519PH,
> > +	RTE_CRYPTO_EDCURVE_448,
> > +	RTE_CRYPTO_EDCURVE_448PH
> > +};
> > +
> >  /**
> >   * Asymmetric crypto transformation types.
> >   * Each xform type maps to one asymmetric algorithm @@ -119,6 +136,10
> > @@ enum rte_crypto_asym_xform_type {
> >  	 * Performs Encrypt, Decrypt, Sign and Verify.
> >  	 * Refer to rte_crypto_asym_op_type.
> >  	 */
> > +	RTE_CRYPTO_ASYM_XFORM_EDDSA,
> > +	/**< Edwards Curve Digital Signature Algorithm
> > +	 * Perform Signature Generation and Verification.
> > +	 */
> >  	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
> >  	/**< End of list */
> >  };
> > @@ -585,6 +606,31 @@ struct rte_crypto_ecdsa_op_param {
> >  	 */
> >  };
> >
> > +/**
> > + * EdDSA operation params
> > + */
> > +struct rte_crypto_eddsa_op_param {
> > +	enum rte_crypto_asym_op_type op_type;
> > +	/**< Signature generation or verification */
> > +
> > +	rte_crypto_param message;
> > +	/**< Input message digest to be signed or verified */
> HashEdDSA will require a message digest; pure EdDSA will require the message
> itself. For HW it will be more complicated.
> > +
> > +	rte_crypto_param context;
> > +	/**< Context value for the sign op.
> > +	 *   Must not be empty for Ed25519ctx instance.
> > +	 */
> > +
> > +	enum rte_crypto_edward_instance instance;
> > +	/**< Type of Edwards curve. */
> All instances are using the same curve, where they differ is the way of handling
> input message.
> And I think this should be a session variable -> new xform for the EdDSA.
> > +
> > +	rte_crypto_uint sign;
> > +	/**< Edward curve signature
> > +	 *     output : for signature generation
> > +	 *     input  : for signature verification
> > +	 */
> > +};
> > +
> >  /**
> >   * Structure for EC point multiplication operation param
> >   */
> > @@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
> >  		struct rte_crypto_ecdsa_op_param ecdsa;
> >  		struct rte_crypto_ecpm_op_param ecpm;
> >  		struct rte_crypto_sm2_op_param sm2;
> > +		struct rte_crypto_eddsa_op_param eddsa;
> >  	};
> >  	uint16_t flags;
> >  	/**<
> > --
> > 2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-10-08  7:40               ` Kusztal, ArkadiuszX
@ 2024-10-08  9:31                 ` Gowrishankar Muthukrishnan
  2024-10-08 11:37                   ` Kusztal, ArkadiuszX
  0 siblings, 1 reply; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-08  9:31 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, Richardson, Bruce, Jerin Jacob, Ji, Kai,
	jack.bond-preston, Marchand, David, hemant.agrawal,
	De Lara Guarch, Pablo, Trahe, Fiona, Doherty, Declan, matan,
	ruifeng.wang

> Acked-by: Arkadiusz Kusztal <arkadiuszx. kusztal@ intel. com

Thanks Arkadiusz.

> > Hi Gowrishankar,
> >
> > I like the idea of adding EdDSA, but I have several comments.
> >
<cut>
> > > +/**
> > > + * EdDSA operation params
> > > + */
> > > +struct rte_crypto_eddsa_op_param {
> > > +	enum rte_crypto_asym_op_type op_type;
> > > +	/**< Signature generation or verification */
> > > +
> > > +	rte_crypto_param message;
> > > +	/**< Input message digest to be signed or verified */
> > HashEdDSA will require a message digest; pure EdDSA will require the
> > message itself. For HW it will be more complicated.

Do you mean some hardware may not have HashEdDSA support ?
If so, I think it can be addressed as an operation capability in EdDSA xform itself as proposed in another patch:
https://patches.dpdk.org/project/dpdk/patch/20241004181255.916-1-gmuthukrishn@marvell.com/

> > > +
> > > +	rte_crypto_param context;
> > > +	/**< Context value for the sign op.
> > > +	 *   Must not be empty for Ed25519ctx instance.
> > > +	 */
> > > +
> > > +	enum rte_crypto_edward_instance instance;
> > > +	/**< Type of Edwards curve. */
> > All instances are using the same curve, where they differ is the way
> > of handling input message.
> > And I think this should be a session variable -> new xform for the EdDSA.

Based on prehash and context string, these instances are listed in RFC.
A context string per operation helps ensure each signature is uniquely tied to its specific context, thereby preventing reuse of signatures across different contexts or operations.
Prehashing adds additional security by ensuring new prehash is computed from the message.
Therefor it is more appropriate to treat both of these as operational variables.

Thanks,
Gowrishankar
> > > +
> > > +	rte_crypto_uint sign;
> > > +	/**< Edward curve signature
> > > +	 *     output : for signature generation
> > > +	 *     input  : for signature verification
> > > +	 */
> > > +};
> > > +
> > >  /**
> > >   * Structure for EC point multiplication operation param
> > >   */
> > > @@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
> > >  		struct rte_crypto_ecdsa_op_param ecdsa;
> > >  		struct rte_crypto_ecpm_op_param ecpm;
> > >  		struct rte_crypto_sm2_op_param sm2;
> > > +		struct rte_crypto_eddsa_op_param eddsa;
> > >  	};
> > >  	uint16_t flags;
> > >  	/**<
> > > --
> > > 2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-10-08  9:31                 ` Gowrishankar Muthukrishnan
@ 2024-10-08 11:37                   ` Kusztal, ArkadiuszX
  2024-10-09  3:43                     ` Gowrishankar Muthukrishnan
  2024-10-09 19:43                     ` Akhil Goyal
  0 siblings, 2 replies; 47+ messages in thread
From: Kusztal, ArkadiuszX @ 2024-10-08 11:37 UTC (permalink / raw)
  To: Gowrishankar Muthukrishnan, dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, Richardson, Bruce, Jerin Jacob, Ji, Kai,
	jack.bond-preston, Marchand, David, hemant.agrawal,
	De Lara Guarch, Pablo, Trahe, Fiona, Doherty, Declan, matan,
	ruifeng.wang



> -----Original Message-----
> From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> Sent: Tuesday, October 8, 2024 11:32 AM
> To: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; dev@dpdk.org; Akhil
> Goyal <gakhil@marvell.com>; Fan Zhang <fanzhang.oss@gmail.com>
> Cc: Anoob Joseph <anoobj@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Jerin Jacob <jerinj@marvell.com>; Ji, Kai
> <kai.ji@intel.com>; jack.bond-preston@foss.arm.com; Marchand, David
> <david.marchand@redhat.com>; hemant.agrawal@nxp.com; De Lara Guarch,
> Pablo <pablo.de.lara.guarch@intel.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; Doherty, Declan <declan.doherty@intel.com>;
> matan@nvidia.com; ruifeng.wang@arm.com
> Subject: RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
> 
> > Acked-by: Arkadiusz Kusztal <arkadiuszx. kusztal@ intel. com
> 
> Thanks Arkadiusz.
> 
> > > Hi Gowrishankar,
> > >
> > > I like the idea of adding EdDSA, but I have several comments.
> > >
> <cut>
> > > > +/**
> > > > + * EdDSA operation params
> > > > + */
> > > > +struct rte_crypto_eddsa_op_param {
> > > > +	enum rte_crypto_asym_op_type op_type;
> > > > +	/**< Signature generation or verification */
> > > > +
> > > > +	rte_crypto_param message;
> > > > +	/**< Input message digest to be signed or verified */
> > > HashEdDSA will require a message digest; pure EdDSA will require the
> > > message itself. For HW it will be more complicated.
> 
> Do you mean some hardware may not have HashEdDSA support ?
Not in full. For example: ECDSA in QAT and Octeon accepts a digest, not a message. So it does not support the full process, but EdDSA is more complicated than that because of the two hash rounds, similar to the SM2.

For now we have only OpenSSL PMD that supports it, and it accepts a message not a digest, so this should be changed to "message to be signed".

> If so, I think it can be addressed as an operation capability in EdDSA xform itself
> as proposed in another patch:
> https://patches.dpdk.org/project/dpdk/patch/20241004181255.916-1-
> gmuthukrishn@marvell.com/
I have not yet reviewed this patch, but it looks that possibly yes.
> 
> > > > +
> > > > +	rte_crypto_param context;
> > > > +	/**< Context value for the sign op.
> > > > +	 *   Must not be empty for Ed25519ctx instance.
> > > > +	 */
> > > > +
> > > > +	enum rte_crypto_edward_instance instance;
> > > > +	/**< Type of Edwards curve. */
> > > All instances are using the same curve, where they differ is the way
> > > of handling input message.
> > > And I think this should be a session variable -> new xform for the EdDSA.
> 
> Based on prehash and context string, these instances are listed in RFC.
> A context string per operation helps ensure each signature is uniquely tied to its
> specific context, thereby preventing reuse of signatures across different
> contexts or operations.
> Prehashing adds additional security by ensuring new prehash is computed from
> the message.
> Therefor it is more appropriate to treat both of these as operational variables.

Different 'instance' are basically different algorithms.

About the 'context' I am not sure, as not any major protocol specifies its usage (TLS and IKEv2 forbids PH though),
But from RFC8032, it looks like it was defined to be used per protocol basis, or some subprotocol routine. But about this I am not sure.

Yet, EdDSA should not be delayed really; it is basically a network standard for quite a time.
These changes may be discussed later.

> 
> Thanks,
> Gowrishankar
> > > > +
> > > > +	rte_crypto_uint sign;
> > > > +	/**< Edward curve signature
> > > > +	 *     output : for signature generation
> > > > +	 *     input  : for signature verification
> > > > +	 */
> > > > +};
> > > > +
> > > >  /**
> > > >   * Structure for EC point multiplication operation param
> > > >   */
> > > > @@ -720,6 +766,7 @@ struct rte_crypto_asym_op {
> > > >  		struct rte_crypto_ecdsa_op_param ecdsa;
> > > >  		struct rte_crypto_ecpm_op_param ecpm;
> > > >  		struct rte_crypto_sm2_op_param sm2;
> > > > +		struct rte_crypto_eddsa_op_param eddsa;
> > > >  	};
> > > >  	uint16_t flags;
> > > >  	/**<
> > > > --
> > > > 2.21.0


^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-10-08 11:37                   ` Kusztal, ArkadiuszX
@ 2024-10-09  3:43                     ` Gowrishankar Muthukrishnan
  2024-10-09 19:43                     ` Akhil Goyal
  1 sibling, 0 replies; 47+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-10-09  3:43 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, dev, Akhil Goyal, Fan Zhang
  Cc: Anoob Joseph, Richardson, Bruce, Jerin Jacob, Ji, Kai,
	jack.bond-preston, Marchand, David, hemant.agrawal,
	De Lara Guarch, Pablo, Trahe, Fiona, Doherty, Declan, matan,
	ruifeng.wang

> > > > > +/**
> > > > > + * EdDSA operation params
> > > > > + */
> > > > > +struct rte_crypto_eddsa_op_param {
> > > > > +	enum rte_crypto_asym_op_type op_type;
> > > > > +	/**< Signature generation or verification */
> > > > > +
> > > > > +	rte_crypto_param message;
> > > > > +	/**< Input message digest to be signed or verified */
> > > > HashEdDSA will require a message digest; pure EdDSA will require
> > > > the message itself. For HW it will be more complicated.
> >
> > Do you mean some hardware may not have HashEdDSA support ?
> Not in full. For example: ECDSA in QAT and Octeon accepts a digest, not a
> message. So it does not support the full process, but EdDSA is more
> complicated than that because of the two hash rounds, similar to the SM2.
> 
> For now we have only OpenSSL PMD that supports it, and it accepts a
> message not a digest, so this should be changed to "message to be signed".
> 
Ack.

<cut>
> > > > All instances are using the same curve, where they differ is the
> > > > way of handling input message.
> > > > And I think this should be a session variable -> new xform for the EdDSA.
> >
> > Based on prehash and context string, these instances are listed in RFC.
> > A context string per operation helps ensure each signature is uniquely
> > tied to its specific context, thereby preventing reuse of signatures
> > across different contexts or operations.
> > Prehashing adds additional security by ensuring new prehash is
> > computed from the message.
> > Therefor it is more appropriate to treat both of these as operational
> variables.
> 
> Different 'instance' are basically different algorithms.
> 
> About the 'context' I am not sure, as not any major protocol specifies its usage
> (TLS and IKEv2 forbids PH though), But from RFC8032, it looks like it was
> defined to be used per protocol basis, or some subprotocol routine. But about
> this I am not sure.
> 
> Yet, EdDSA should not be delayed really; it is basically a network standard for
> quite a time.
> These changes may be discussed later.
> 

Sure Arkadiusz.

Regards,
Gowrishankar


^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
  2024-10-08 11:37                   ` Kusztal, ArkadiuszX
  2024-10-09  3:43                     ` Gowrishankar Muthukrishnan
@ 2024-10-09 19:43                     ` Akhil Goyal
  1 sibling, 0 replies; 47+ messages in thread
From: Akhil Goyal @ 2024-10-09 19:43 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, Gowrishankar Muthukrishnan, dev, Fan Zhang
  Cc: Anoob Joseph, Richardson, Bruce, Jerin Jacob, Ji, Kai,
	jack.bond-preston, Marchand, David, hemant.agrawal,
	De Lara Guarch, Pablo, Trahe, Fiona, Doherty, Declan, matan,
	ruifeng.wang

> > Subject: RE: [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm
> >
> > > Acked-by: Arkadiusz Kusztal <arkadiuszx. kusztal@ intel. com
Series Acked-by: Akhil Goyal <gakhil@marvell.com>

Series Applied to dpdk-next-crypto

Thanks.
Updated release notes and removed deprecation notices for EDDSA.

^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2024-10-09 19:44 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-29 16:10 [PATCH v1 1/3] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
2023-11-29 16:10 ` [PATCH v1 2/3] crypto/openssl: add EDDSA support Gowrishankar Muthukrishnan
2023-11-29 16:10 ` [PATCH v1 3/3] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
2024-09-05 13:36 ` [PATCH v2 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
2024-09-05 13:39 ` Gowrishankar Muthukrishnan
2024-09-05 13:39   ` [PATCH v2 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
2024-09-09  9:56     ` Jack Bond-Preston
2024-09-05 13:39   ` [PATCH v2 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
2024-09-20 13:09     ` [PATCH v3 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
2024-09-20 13:09       ` [PATCH v3 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
2024-09-20 14:36         ` Akhil Goyal
2024-09-20 13:09       ` [PATCH v3 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
2024-09-20 13:09       ` [PATCH v3 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
2024-09-20 13:09       ` [PATCH v3 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
2024-09-20 13:09       ` [PATCH v3 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
2024-10-03  6:42         ` Akhil Goyal
2024-10-03 17:56       ` [PATCH v4 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
2024-10-03 17:56         ` [PATCH v4 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
2024-10-03 17:56         ` [PATCH v4 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
2024-10-03 17:56         ` [PATCH v4 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
2024-10-03 17:56         ` [PATCH v4 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
2024-10-03 17:56         ` [PATCH v4 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
2024-10-04  5:30         ` [PATCH v5 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
2024-10-04  5:30           ` [PATCH v5 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
2024-10-04  5:30           ` [PATCH v5 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
2024-10-04  5:30           ` [PATCH v5 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
2024-10-04  5:30           ` [PATCH v5 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
2024-10-04  5:30           ` [PATCH v5 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
2024-10-04  8:26           ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Gowrishankar Muthukrishnan
2024-10-04  8:26             ` [PATCH v6 2/6] crypto/openssl: support EDDSA Gowrishankar Muthukrishnan
2024-10-07  9:50               ` Ji, Kai
2024-10-07 16:27               ` Kusztal, ArkadiuszX
2024-10-04  8:26             ` [PATCH v6 3/6] crypto/cnxk: " Gowrishankar Muthukrishnan
2024-10-04  8:26             ` [PATCH v6 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
2024-10-04  8:26             ` [PATCH v6 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
2024-10-04 16:19               ` Dooley, Brian
2024-10-04  8:26             ` [PATCH v6 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan
2024-10-04 16:20               ` Dooley, Brian
2024-10-07 16:03             ` [PATCH v6 1/6] cryptodev: add EDDSA asymmetric crypto algorithm Kusztal, ArkadiuszX
2024-10-08  7:40               ` Kusztal, ArkadiuszX
2024-10-08  9:31                 ` Gowrishankar Muthukrishnan
2024-10-08 11:37                   ` Kusztal, ArkadiuszX
2024-10-09  3:43                     ` Gowrishankar Muthukrishnan
2024-10-09 19:43                     ` Akhil Goyal
2024-09-05 13:39   ` [PATCH v2 4/6] test/crypto: add asymmetric EDDSA test cases Gowrishankar Muthukrishnan
2024-09-05 13:39   ` [PATCH v2 5/6] examples/fips_validation: support EDDSA Gowrishankar Muthukrishnan
2024-09-05 13:39   ` [PATCH v2 6/6] app/crypto-perf: " Gowrishankar Muthukrishnan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).