DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/4] add ECDSA support
@ 2019-12-05 11:43 Anoob Joseph
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA Anoob Joseph
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: Anoob Joseph @ 2019-12-05 11:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Anoob Joseph, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, Sunila Sahu, dev

This series adds support for ECDSA asymmetric operations. Library changes
and PMD changes for crypto_octeontx & crypto_octoentx2 is added. The final
patch adds the required test vectors and verification routines.

Ayuj Verma (2):
  lib/crypto: add support for ECDSA
  app/test: add ECDSA sign/verify tests

Sunila Sahu (2):
  crypto/octeontx: add ECDSA support
  crypto/octeontx2: add ECDSA support

 app/test/test_cryptodev_asym.c                     |  219 +++-
 app/test/test_cryptodev_asym_util.h                |   11 +
 app/test/test_cryptodev_ecdsa_test_vectors.h       |  501 +++++++++
 doc/guides/cryptodevs/features/default.ini         |   11 +-
 doc/guides/cryptodevs/features/octeontx.ini        |    8 +-
 doc/guides/cryptodevs/features/octeontx2.ini       |    8 +-
 drivers/common/cpt/Makefile                        |    1 +
 drivers/common/cpt/cpt_fpm_tables.c                | 1138 ++++++++++++++++++++
 drivers/common/cpt/cpt_mcode_defines.h             |   38 +
 drivers/common/cpt/cpt_pmd_ops_helper.h            |   19 +
 drivers/common/cpt/cpt_ucode_asym.h                |  378 +++++++
 drivers/common/cpt/meson.build                     |    3 +-
 drivers/common/cpt/rte_common_cpt_version.map      |    9 +
 .../crypto/octeontx/otx_cryptodev_capabilities.c   |   11 +
 drivers/crypto/octeontx/otx_cryptodev_ops.c        |   43 +-
 .../crypto/octeontx2/otx2_cryptodev_capabilities.c |   11 +
 drivers/crypto/octeontx2/otx2_cryptodev_ops.c      |   39 +-
 lib/librte_cryptodev/rte_crypto_asym.h             |   83 ++
 lib/librte_cryptodev/rte_cryptodev.c               |    1 +
 19 files changed, 2517 insertions(+), 15 deletions(-)
 create mode 100644 app/test/test_cryptodev_ecdsa_test_vectors.h
 create mode 100644 drivers/common/cpt/cpt_fpm_tables.c

-- 
2.7.4


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

* [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA
  2019-12-05 11:43 [dpdk-dev] [PATCH 0/4] add ECDSA support Anoob Joseph
@ 2019-12-05 11:43 ` Anoob Joseph
  2019-12-20 16:05   ` Kusztal, ArkadiuszX
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 2/4] crypto/octeontx: add ECDSA support Anoob Joseph
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 19+ messages in thread
From: Anoob Joseph @ 2019-12-05 11:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Ayuj Verma, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, Sunila Sahu, dev,
	Anoob Joseph

From: Ayuj Verma <ayverma@marvell.com>

Elliptic curve xform and ECDSA op params are added.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Ayuj Verma <ayverma@marvell.com>
Signed-off-by: Sunila Sahu <ssahu@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini | 11 ++--
 lib/librte_cryptodev/rte_crypto_asym.h     | 83 ++++++++++++++++++++++++++++++
 lib/librte_cryptodev/rte_cryptodev.c       |  1 +
 3 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index b7f9a0a..2f6c785 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -103,8 +103,9 @@ AES CCM (256) =
 ; Supported Asymmetric algorithms of a default crypto driver.
 ;
 [Asymmetric]
-RSA =
-DSA =
-Modular Exponentiation =
-Modular Inversion =
-Diffie-hellman =
\ No newline at end of file
+RSA                     =
+DSA                     =
+Modular Exponentiation  =
+Modular Inversion       =
+Diffie-hellman          =
+ECDSA                   =
diff --git a/lib/librte_cryptodev/rte_crypto_asym.h b/lib/librte_cryptodev/rte_crypto_asym.h
index 0d34ce8..dd5e6e3 100644
--- a/lib/librte_cryptodev/rte_crypto_asym.h
+++ b/lib/librte_cryptodev/rte_crypto_asym.h
@@ -81,6 +81,10 @@ enum rte_crypto_asym_xform_type {
 	/**< Modular Exponentiation
 	 * Perform Modular Exponentiation b^e mod n
 	 */
+	RTE_CRYPTO_ASYM_XFORM_ECDSA,
+	/**< Elliptic Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -319,6 +323,46 @@ struct rte_crypto_dsa_xform {
 };
 
 /**
+ * TLS named curves
+ * https://www.iana.org/assignments/tls-parameters/
+ * tls-parameters.xhtml#tls-parameters-8
+ * secp192r1 = 19,
+ * secp224r1 = 21,
+ * secp256r1 = 23,
+ * secp384r1 = 24,
+ * secp521r1 = 25,
+ */
+enum rte_crypto_ec_group {
+	RTE_CRYPTO_EC_GROUP_UNKNOWN  = 0,
+	RTE_CRYPTO_EC_GROUP_NISTP192 = 19,
+	RTE_CRYPTO_EC_GROUP_NISTP224 = 21,
+	RTE_CRYPTO_EC_GROUP_NISTP256 = 23,
+	RTE_CRYPTO_EC_GROUP_NISTP384 = 24,
+	RTE_CRYPTO_EC_GROUP_NISTP521 = 25,
+};
+
+/**
+ * Structure for elliptic curve point
+ */
+struct rte_crypto_ec_point {
+	rte_crypto_param x;
+	/**< X coordinate */
+	rte_crypto_param y;
+	/**< Y coordinate */
+};
+
+/**
+ * Asymmetric elliptic curve transform data
+ *
+ * Structure describing all EC based xform params
+ *
+ */
+struct rte_crypto_ec_xform {
+	enum rte_crypto_ec_group curve_id;
+	/**< Pre-defined ec groups */
+};
+
+/**
  * Operations params for modular operations:
  * exponentiation and multiplicative inverse
  *
@@ -372,6 +416,11 @@ struct rte_crypto_asym_xform {
 
 		struct rte_crypto_dsa_xform dsa;
 		/**< DSA xform parameters */
+
+		struct rte_crypto_ec_xform ec;
+		/**< EC xform parameters, used by elliptic curve based
+		 * operations.
+		 */
 	};
 };
 
@@ -516,6 +565,39 @@ struct rte_crypto_dsa_op_param {
 };
 
 /**
+ * ECDSA operation params
+ */
+struct rte_crypto_ecdsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param pkey;
+	/**< Private key of the signer for signature generation */
+
+	struct rte_crypto_ec_point q;
+	/**< Public key of the signer for verification */
+
+	rte_crypto_param message;
+	/**< Input message to be signed or verified */
+
+	rte_crypto_param k;
+	/**< The ECDSA per-message secret number, which is an integer
+	 * in the interval (1, n-1)
+	 */
+
+	rte_crypto_param r;
+	/**< r component of elliptic curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+	rte_crypto_param s;
+	/**< s component of elliptic curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
+/**
  * Asymmetric Cryptographic Operation.
  *
  * Structure describing asymmetric crypto operation params.
@@ -537,6 +619,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_mod_op_param modinv;
 		struct rte_crypto_dh_op_param dh;
 		struct rte_crypto_dsa_op_param dsa;
+		struct rte_crypto_ecdsa_op_param ecdsa;
 	};
 };
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 89aa2ed..0d6babb 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -173,6 +173,7 @@ const char *rte_crypto_asym_xform_strings[] = {
 	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
 	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
 	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
+	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
 };
 
 /**
-- 
2.7.4


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

* [dpdk-dev] [PATCH 2/4] crypto/octeontx: add ECDSA support
  2019-12-05 11:43 [dpdk-dev] [PATCH 0/4] add ECDSA support Anoob Joseph
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA Anoob Joseph
@ 2019-12-05 11:43 ` Anoob Joseph
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 3/4] crypto/octeontx2: " Anoob Joseph
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Anoob Joseph @ 2019-12-05 11:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Sunila Sahu, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, dev, Anoob Joseph,
	Ayuj Verma

From: Sunila Sahu <ssahu@marvell.com>

Adding support for ECDSA operations in crypto_octeontx PMD.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Ayuj Verma <ayverma@marvell.com>
Signed-off-by: Sunila Sahu <ssahu@marvell.com>
---
 doc/guides/cryptodevs/features/octeontx.ini        |    8 +-
 drivers/common/cpt/Makefile                        |    1 +
 drivers/common/cpt/cpt_fpm_tables.c                | 1138 ++++++++++++++++++++
 drivers/common/cpt/cpt_mcode_defines.h             |   38 +
 drivers/common/cpt/cpt_pmd_ops_helper.h            |   19 +
 drivers/common/cpt/cpt_ucode_asym.h                |  378 +++++++
 drivers/common/cpt/meson.build                     |    3 +-
 drivers/common/cpt/rte_common_cpt_version.map      |    9 +
 .../crypto/octeontx/otx_cryptodev_capabilities.c   |   11 +
 drivers/crypto/octeontx/otx_cryptodev_ops.c        |   43 +-
 10 files changed, 1643 insertions(+), 5 deletions(-)
 create mode 100644 drivers/common/cpt/cpt_fpm_tables.c

diff --git a/doc/guides/cryptodevs/features/octeontx.ini b/doc/guides/cryptodevs/features/octeontx.ini
index 1c036c5..544bb46 100644
--- a/doc/guides/cryptodevs/features/octeontx.ini
+++ b/doc/guides/cryptodevs/features/octeontx.ini
@@ -67,5 +67,9 @@ AES GCM (256) = Y
 ; Supported Asymmetric algorithms of the 'octeontx' crypto driver.
 ;
 [Asymmetric]
-RSA                    = Y
-Modular Exponentiation = Y
+RSA                     = Y
+DSA                     =
+Modular Exponentiation  = Y
+Modular Inversion       =
+Diffie-hellman          =
+ECDSA                   = Y
diff --git a/drivers/common/cpt/Makefile b/drivers/common/cpt/Makefile
index 8594432..cab9da7 100644
--- a/drivers/common/cpt/Makefile
+++ b/drivers/common/cpt/Makefile
@@ -16,6 +16,7 @@ EXPORT_MAP := rte_common_cpt_version.map
 #
 # all source are stored in SRCS-y
 #
+SRCS-y += cpt_fpm_tables.c
 SRCS-y += cpt_pmd_ops_helper.c
 
 LDLIBS += -lrte_eal
diff --git a/drivers/common/cpt/cpt_fpm_tables.c b/drivers/common/cpt/cpt_fpm_tables.c
new file mode 100644
index 0000000..15b665d
--- /dev/null
+++ b/drivers/common/cpt/cpt_fpm_tables.c
@@ -0,0 +1,1138 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2019 Marvell International Ltd.
+ */
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "cpt_mcode_defines.h"
+#include "cpt_pmd_logs.h"
+#include "cpt_pmd_ops_helper.h"
+
+/*
+ * CPT FPM table sizes Enumeration
+ *
+ * 15 table entries * (X, Y, Z coordinates) * Coordinate Offset
+ * Coordinate Offset depends on elliptic curve as mentioned below,
+ * 6 quadwords for P-192, P-224 and P-256
+ * 7 quadwords for P-384
+ * 9 quadwords for P-521
+ */
+typedef enum {
+	CPT_P192_LEN = 2160,
+	CPT_P224_LEN = 2160,
+	CPT_P256_LEN = 2160,
+	CPT_P384_LEN = 2520,
+	CPT_P521_LEN = 3240
+} cpt_fpm_len_t;
+
+/* FPM table address and length */
+struct fpm_entry {
+	const uint8_t *data;
+	int len;
+};
+
+/*
+ * Pre-computed ECC FMUL tables needed by cpt microcode
+ * for NIST curves P-192, P-256, P-384, P-521, P-224.
+ */
+
+static const uint8_t fpm_table_p192[CPT_P192_LEN] = {
+	0xf4, 0xff, 0x0a, 0xfd, 0x82, 0xff, 0x10, 0x12, 0x7c, 0xbf, 0x20, 0xeb,
+	0x43, 0xa1, 0x88, 0x00, 0x18, 0x8d, 0xa8, 0x0e, 0xb0, 0x30, 0x90, 0xf6,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11, 0x63, 0x10, 0x11, 0xed,
+	0x6b, 0x24, 0xcd, 0xd5, 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78,
+	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, 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,
+	0xc3, 0x96, 0x49, 0xc5, 0x5d, 0x7c, 0x48, 0xd8, 0xeb, 0x2c, 0xdf, 0xae,
+	0x5a, 0x92, 0x7c, 0x35, 0x67, 0xe3, 0x0c, 0xbd, 0xcb, 0xa6, 0x71, 0xfb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7a, 0x83, 0xce, 0xe1, 0xec, 0xbf, 0xbe, 0x7d, 0xce, 0x32, 0xd0, 0x3c,
+	0x06, 0x30, 0x15, 0x77, 0xa9, 0x35, 0x49, 0xc4, 0x58, 0x10, 0xf5, 0xc3,
+	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, 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,
+	0x6f, 0x5e, 0xf8, 0x89, 0x66, 0xe3, 0xea, 0xd3, 0xf2, 0x9e, 0x6f, 0xea,
+	0xdf, 0xc9, 0xbf, 0x1a, 0xce, 0x21, 0x6b, 0xb8, 0x45, 0x20, 0x06, 0xe0,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0xb9, 0x09, 0x2d, 0x92, 0x7b, 0x37, 0x79, 0x1d, 0x0a, 0xeb, 0x4b,
+	0xb5, 0xb8, 0x0a, 0x20, 0xd9, 0x8a, 0x2e, 0xe2, 0x5a, 0xae, 0xc9, 0x58,
+	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, 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,
+	0xb1, 0x99, 0x63, 0xd8, 0xc0, 0xa1, 0xe3, 0x40, 0x47, 0x30, 0xd4, 0xf4,
+	0x80, 0xd1, 0x09, 0x0b, 0x51, 0xa5, 0x81, 0xd9, 0x18, 0x4a, 0xc7, 0x37,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xec, 0xc5, 0x67, 0x31, 0xe6, 0x99, 0x12, 0xa5, 0x7c, 0xdf, 0xce, 0xa0,
+	0x2f, 0x68, 0x3f, 0x16, 0x5b, 0xd8, 0x1e, 0xe2, 0xe0, 0xbb, 0x9f, 0x6e,
+	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, 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,
+	0xe4, 0xb1, 0x5a, 0x2d, 0xd4, 0xf4, 0x33, 0x74, 0x07, 0x57, 0xee, 0xa7,
+	0xf2, 0x92, 0xc3, 0x41, 0x0c, 0x73, 0x06, 0x91, 0xd0, 0xf8, 0xdc, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xdf, 0x79, 0x78, 0x90, 0xbb, 0xf4, 0x5e, 0x00, 0x00, 0x8a, 0x9e, 0x83,
+	0xe9, 0xde, 0x87, 0x08, 0x31, 0xb2, 0x4c, 0x31, 0x93, 0x54, 0xde, 0x3e,
+	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, 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,
+	0xcb, 0x5e, 0xc0, 0x43, 0xdd, 0xf6, 0x3a, 0xba, 0xc9, 0x4c, 0x21, 0xd9,
+	0xf8, 0x4f, 0x41, 0xe1, 0xf0, 0xf4, 0x08, 0x83, 0x61, 0xd2, 0x44, 0x16,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf3, 0x75, 0x85, 0xb0, 0x40, 0x64, 0x95, 0xf7, 0xe5, 0xde, 0x3b, 0x5b,
+	0x16, 0xbc, 0xd0, 0xca, 0x27, 0x85, 0x3c, 0x1a, 0xe1, 0x3e, 0xa4, 0x88,
+	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, 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,
+	0xd0, 0x74, 0x23, 0x2a, 0x8e, 0x8a, 0xe6, 0x8f, 0x74, 0x9e, 0x52, 0x8e,
+	0xee, 0x29, 0xf7, 0xa9, 0x06, 0x11, 0xde, 0xa3, 0x97, 0x16, 0x46, 0x9f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x66, 0xb8, 0x67, 0xdd, 0x0d, 0x80, 0x43, 0xcc, 0x6a, 0x65, 0x46, 0x54,
+	0x3a, 0x72, 0x7d, 0xe6, 0xf9, 0x54, 0x60, 0x52, 0x83, 0x38, 0xbd, 0xc9,
+	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, 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,
+	0xb6, 0xeb, 0x71, 0x93, 0x0c, 0x5d, 0x8f, 0x50, 0x1c, 0x24, 0x5c, 0x02,
+	0xb9, 0x04, 0xb5, 0x96, 0x04, 0xbc, 0x1f, 0x71, 0x95, 0x1f, 0x75, 0x13,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0xd0, 0x91, 0x6e, 0xbe, 0x34, 0x80, 0x3d, 0x8b, 0xec, 0x94, 0x8a,
+	0x8c, 0x21, 0x96, 0x2a, 0x15, 0x00, 0x96, 0xe7, 0xfd, 0x69, 0xf8, 0xd0,
+	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, 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,
+	0xbd, 0x44, 0xff, 0xe8, 0xe7, 0x1a, 0xac, 0x0c, 0x7d, 0x69, 0xa0, 0xb0,
+	0x43, 0x22, 0xd0, 0x65, 0x9f, 0x56, 0xd9, 0x6c, 0xec, 0xa3, 0xba, 0x2a,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xee, 0x59, 0xf0, 0xd1, 0x25, 0xa5, 0x9d, 0xce, 0x83, 0x7d, 0x62, 0xdd,
+	0xc3, 0xf4, 0x57, 0x5a, 0xa4, 0xe0, 0x7f, 0xb3, 0x35, 0xde, 0x73, 0xd9,
+	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, 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,
+	0xec, 0x76, 0x76, 0x0c, 0x1c, 0xf4, 0x6a, 0xe2, 0xff, 0x54, 0x98, 0x32,
+	0xa3, 0x3d, 0x44, 0xb0, 0xe9, 0x5a, 0xd2, 0x10, 0xf3, 0x18, 0x5c, 0x11,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x27, 0x3e, 0x5e, 0xc5, 0x38, 0xed, 0x37, 0x2e, 0x51, 0xd3, 0x91, 0x36,
+	0xb0, 0xab, 0x11, 0x69, 0xa5, 0xea, 0x86, 0xf6, 0x8f, 0x3a, 0x27, 0xc8,
+	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, 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,
+	0x29, 0x12, 0x37, 0xea, 0x74, 0xd2, 0xd7, 0xd5, 0x95, 0x36, 0x36, 0xee,
+	0x56, 0x33, 0x8e, 0x9b, 0x0d, 0xa6, 0x5e, 0x86, 0x28, 0x5c, 0x12, 0x0c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x13, 0x02, 0xf0, 0x4c, 0xf1, 0x3c, 0x32, 0x33, 0xfc, 0x89, 0x8a, 0xb9,
+	0x97, 0x83, 0x91, 0xb2, 0x26, 0xd6, 0x5c, 0x2e, 0x3a, 0xa0, 0x62, 0x72,
+	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, 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,
+	0xd5, 0x09, 0x47, 0xa8, 0x18, 0xc5, 0xef, 0xe6, 0x45, 0xdb, 0x23, 0xae,
+	0xfe, 0x11, 0x3c, 0x6c, 0x91, 0xf1, 0x99, 0xf2, 0xe5, 0xbb, 0xe8, 0x6d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x37, 0x68, 0x81, 0xb6, 0x60, 0xfe, 0xc0, 0x64, 0x38, 0x73, 0x43, 0xe9,
+	0x47, 0x5d, 0xae, 0xa4, 0xec, 0xcd, 0x57, 0xe8, 0xac, 0x8d, 0x8a, 0x19,
+	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, 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,
+	0xc9, 0xfe, 0xf5, 0xb9, 0x5b, 0x51, 0x02, 0x28, 0x37, 0x4c, 0x0a, 0x4c,
+	0x19, 0x2e, 0xbc, 0xd6, 0x22, 0x98, 0xf2, 0x04, 0xce, 0x6a, 0x83, 0xf9,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0xe4, 0xb8, 0x20, 0xf4, 0xc5, 0x74, 0xd0, 0x06, 0xd5, 0x86, 0x44,
+	0xef, 0xeb, 0x2c, 0xc0, 0xe7, 0x13, 0xa4, 0x00, 0x10, 0xc3, 0xc9, 0x49,
+	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, 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,
+	0x61, 0x78, 0xcb, 0x0e, 0x2d, 0x64, 0xee, 0xdf, 0x27, 0xaf, 0x7d, 0x5e,
+	0xb8, 0x5e, 0x1f, 0x99, 0xd8, 0x73, 0xce, 0xd7, 0x6c, 0xb7, 0xbe, 0x1f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xef, 0xc9, 0x12, 0x9c, 0x52, 0xa6, 0x7f, 0x9c, 0xa3, 0xd7, 0xb9, 0x57,
+	0x60, 0x04, 0xd9, 0xad, 0xfc, 0x59, 0x98, 0x08, 0xdc, 0x41, 0xf8, 0xe2,
+	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, 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,
+	0xbb, 0x6c, 0x6b, 0x59, 0x7f, 0xdf, 0x92, 0x8a, 0xad, 0x16, 0x7e, 0xf0,
+	0xd7, 0xf9, 0x3b, 0xf4, 0xfa, 0xa9, 0xe4, 0x32, 0x15, 0x4e, 0x06, 0x1c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x0c, 0x3d, 0x0d, 0x63, 0xd5, 0x2c, 0x8f, 0x3f, 0x61, 0x01, 0xb2, 0xbe,
+	0xd5, 0xf7, 0xe0, 0x8f, 0xd8, 0x77, 0xcd, 0xdd, 0xd6, 0xae, 0x3c, 0xf3,
+	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, 0x01
+};
+
+static const uint8_t fpm_table_p224[CPT_P224_LEN] = {
+	0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c, 0x1d, 0x21, 0x4a, 0x03, 0xc1, 0xd3,
+	0x56, 0xc2, 0x11, 0x22, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, 0x90, 0xb9,
+	0x00, 0x00, 0x00, 0x00, 0xb7, 0x0e, 0x0c, 0xbd, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34, 0xcd, 0x43, 0x75, 0xa0,
+	0x5a, 0x07, 0x47, 0x64, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
+	0x00, 0x00, 0x00, 0x00, 0xbd, 0x37, 0x63, 0x88, 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,
+	0xc8, 0xae, 0x4d, 0x94, 0xff, 0x48, 0xdb, 0xc5, 0xb5, 0xc8, 0x8b, 0x66,
+	0x32, 0xc8, 0x7a, 0x44, 0x66, 0xc7, 0x27, 0x87, 0x2b, 0x8d, 0x08, 0x1c,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0xe5, 0xde, 0x8b, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc6, 0xf8, 0x1e, 0x08, 0x47, 0xfb, 0x64, 0xdb, 0xc8, 0xe3, 0x75, 0x3e,
+	0x9d, 0x5a, 0x58, 0x31, 0xa2, 0x13, 0x38, 0x8c, 0x65, 0x8a, 0x02, 0xae,
+	0x00, 0x00, 0x00, 0x00, 0xde, 0x52, 0x6c, 0x0d, 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,
+	0xee, 0x8f, 0x93, 0x0d, 0x2b, 0x30, 0x9e, 0xe8, 0xb6, 0x78, 0xea, 0x1a,
+	0x0f, 0x59, 0x7e, 0x02, 0x14, 0x74, 0x52, 0x56, 0x6c, 0x25, 0x7d, 0x3e,
+	0x00, 0x00, 0x00, 0x00, 0x09, 0xbe, 0x54, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf6, 0x12, 0x1f, 0xdd, 0x96, 0xa2, 0x05, 0xda, 0x12, 0xa8, 0xe4, 0xf9,
+	0x98, 0x15, 0x8e, 0xe1, 0x1b, 0x1d, 0x05, 0x44, 0x47, 0xf2, 0xc3, 0x3a,
+	0x00, 0x00, 0x00, 0x00, 0x32, 0xf7, 0x1c, 0x32, 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,
+	0x26, 0x73, 0x99, 0x28, 0x0e, 0x4e, 0x09, 0x58, 0x79, 0xab, 0xae, 0x5c,
+	0xa8, 0xeb, 0x9c, 0x0b, 0xe9, 0xa8, 0xac, 0xf0, 0x74, 0x0e, 0xa3, 0x35,
+	0x00, 0x00, 0x00, 0x00, 0x0f, 0xb6, 0xce, 0x42, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x92, 0x09, 0xdc, 0xfe, 0x40, 0x85, 0x7c, 0x64, 0xa2, 0x3f, 0xe4, 0x34,
+	0x50, 0xb4, 0x25, 0x87, 0x2a, 0x6f, 0x38, 0x62, 0xb6, 0xfe, 0x44, 0xb1,
+	0x00, 0x00, 0x00, 0x00, 0x9e, 0xd1, 0x3b, 0x1b, 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,
+	0xf9, 0xfb, 0xf4, 0x91, 0x9a, 0x5f, 0x1c, 0x42, 0x56, 0x8b, 0xc4, 0x34,
+	0x8a, 0x69, 0xdd, 0x65, 0x3d, 0x01, 0x11, 0x6e, 0x47, 0x78, 0xdf, 0x49,
+	0x00, 0x00, 0x00, 0x00, 0x56, 0x65, 0xff, 0xd2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0x4b, 0x80, 0x12, 0xe5, 0x3d, 0x3f, 0xb4, 0xe7, 0x61, 0x44, 0x25,
+	0x89, 0xec, 0x86, 0x76, 0x1f, 0xde, 0x69, 0x6f, 0xcb, 0x2b, 0xe1, 0x15,
+	0x00, 0x00, 0x00, 0x00, 0xc5, 0xf0, 0x98, 0xeb, 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,
+	0xe6, 0xf2, 0x88, 0xf1, 0x39, 0xb0, 0xa5, 0xad, 0x0c, 0x76, 0x16, 0x85,
+	0x58, 0x72, 0xd0, 0x94, 0x8a, 0xbc, 0x69, 0xb6, 0x6d, 0x7a, 0xc7, 0xfb,
+	0x00, 0x00, 0x00, 0x00, 0x64, 0xe1, 0x68, 0x02, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe1, 0x94, 0x7b, 0x17, 0x96, 0xa9, 0x76, 0xcf, 0x67, 0x78, 0x38, 0x8a,
+	0xd9, 0xb7, 0x68, 0xd7, 0x75, 0x39, 0xb7, 0x24, 0x17, 0x76, 0xa8, 0x39,
+	0x00, 0x00, 0x00, 0x00, 0xb4, 0xdb, 0x5a, 0x94, 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,
+	0x86, 0x5a, 0x09, 0xbe, 0xdf, 0x5b, 0x10, 0x74, 0x74, 0xc0, 0xce, 0xf5,
+	0x95, 0xab, 0xef, 0xf7, 0xba, 0x69, 0x9c, 0xe4, 0x14, 0xb3, 0x90, 0xb1,
+	0x00, 0x00, 0x00, 0x00, 0xc0, 0xca, 0x10, 0xcb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x55, 0x87, 0xbb, 0x19, 0x41, 0x02, 0x67, 0xde, 0xa7, 0x71, 0xb8, 0xce,
+	0xa6, 0x3f, 0xcc, 0x78, 0xbc, 0xa5, 0x91, 0x7d, 0x0e, 0x8d, 0x16, 0x65,
+	0x00, 0x00, 0x00, 0x00, 0x63, 0x9e, 0x9e, 0x20, 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,
+	0xe8, 0xb7, 0x37, 0x97, 0x4e, 0x1b, 0xfb, 0x82, 0x16, 0x71, 0x58, 0x39,
+	0x55, 0xb6, 0x32, 0xb8, 0xf6, 0x75, 0x2f, 0xdd, 0x34, 0x7a, 0x0d, 0x7b,
+	0x00, 0x00, 0x00, 0x00, 0xff, 0x24, 0xb5, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0xce, 0x1f, 0x14, 0x00, 0xe2, 0xe0, 0x16, 0x71, 0xe5, 0x9b, 0x8c,
+	0x60, 0x8d, 0x20, 0x97, 0x2b, 0x07, 0xec, 0x89, 0x89, 0x37, 0x5d, 0x09,
+	0x00, 0x00, 0x00, 0x00, 0xc3, 0xe2, 0x8c, 0xdc, 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,
+	0x9a, 0x88, 0x5f, 0xdf, 0xf5, 0x12, 0x07, 0xbf, 0xc5, 0xbd, 0xd8, 0x15,
+	0x01, 0x55, 0x75, 0x02, 0xf1, 0x96, 0x50, 0x03, 0x6b, 0xbd, 0xd0, 0x72,
+	0x00, 0x00, 0x00, 0x00, 0xda, 0x9b, 0x7e, 0x0c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0xa7, 0x4c, 0xce, 0x47, 0xb9, 0x7d, 0x42, 0xf7, 0xb5, 0x5d, 0x63,
+	0x28, 0xf5, 0xde, 0x75, 0x06, 0x13, 0xe9, 0x5d, 0x9b, 0x48, 0x88, 0x67,
+	0x00, 0x00, 0x00, 0x00, 0xd6, 0x05, 0x07, 0x13, 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,
+	0xa4, 0xee, 0x4e, 0xe7, 0xb4, 0x4a, 0xda, 0x48, 0xe3, 0x67, 0x5f, 0xf9,
+	0x15, 0xda, 0x1a, 0x27, 0x33, 0x6b, 0x97, 0x6a, 0x82, 0x0d, 0xa0, 0x86,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0x6e, 0x9f, 0xfd, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf5, 0x2c, 0xd8, 0x87, 0x2f, 0xf4, 0xa8, 0x85, 0x53, 0x29, 0x86, 0xf1,
+	0xb9, 0x1a, 0x28, 0xdc, 0xaf, 0x35, 0x40, 0xdd, 0x75, 0xbf, 0x86, 0x56,
+	0x00, 0x00, 0x00, 0x00, 0xce, 0x4f, 0x78, 0xa9, 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,
+	0x4d, 0x51, 0xfa, 0xb9, 0xe8, 0x49, 0xeb, 0x79, 0xd4, 0xc3, 0x0d, 0x04,
+	0xdd, 0xf6, 0xb1, 0xcd, 0x6d, 0x51, 0xe5, 0x58, 0x06, 0x2a, 0x7e, 0x65,
+	0x00, 0x00, 0x00, 0x00, 0xe6, 0xe4, 0xf0, 0x9a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe0, 0x85, 0xf1, 0x4f, 0xe7, 0x07, 0x60, 0xb5, 0x45, 0x7a, 0xc8, 0x3d,
+	0xf3, 0x26, 0xd8, 0xb0, 0xc7, 0x94, 0x33, 0x72, 0x7e, 0xef, 0x87, 0x70,
+	0x00, 0x00, 0x00, 0x00, 0x74, 0x6d, 0x83, 0xb0, 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,
+	0x7a, 0x24, 0xee, 0x7e, 0x21, 0x7b, 0x0a, 0x33, 0x4e, 0xa1, 0x1e, 0x5c,
+	0xca, 0x30, 0xf9, 0x68, 0xc2, 0xc4, 0x7d, 0x0a, 0xa0, 0xc7, 0xbe, 0xeb,
+	0x00, 0x00, 0x00, 0x00, 0xca, 0x62, 0xa6, 0x8b, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5c, 0x26, 0x7c, 0x9c, 0xfb, 0xe5, 0x6a, 0x33, 0x89, 0x37, 0x74, 0x21,
+	0x13, 0x71, 0x46, 0x6b, 0x60, 0xd0, 0x38, 0xc4, 0x90, 0xef, 0x7d, 0xec,
+	0x00, 0x00, 0x00, 0x00, 0x27, 0xde, 0xcf, 0x82, 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,
+	0x23, 0x14, 0xf5, 0x42, 0xbe, 0x9e, 0x07, 0x9c, 0x4a, 0x60, 0x56, 0x3b,
+	0xcf, 0xe2, 0x06, 0x81, 0xb0, 0xc0, 0x46, 0x49, 0xfb, 0x97, 0x61, 0x5a,
+	0x00, 0x00, 0x00, 0x00, 0x2f, 0xa4, 0x2d, 0x2b, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x86, 0xe5, 0x99, 0xb4, 0xcf, 0x64, 0x05, 0x25, 0xa3, 0x44, 0xe4, 0x18,
+	0x5f, 0x72, 0x58, 0x47, 0x7f, 0xbd, 0x84, 0xd7, 0x0a, 0x38, 0xa0, 0xd4,
+	0x00, 0x00, 0x00, 0x00, 0x11, 0x8d, 0x15, 0xd5, 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,
+	0xe8, 0x5b, 0x13, 0xf0, 0x09, 0xc6, 0x14, 0x58, 0xc4, 0xf3, 0x1b, 0x3d,
+	0x17, 0x0f, 0x1c, 0xfa, 0x7d, 0x61, 0x7e, 0x7e, 0x9c, 0xea, 0x52, 0x0a,
+	0x00, 0x00, 0x00, 0x00, 0x89, 0x05, 0xdb, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x26, 0xf8, 0xab, 0x68, 0xb4, 0x27, 0x56, 0x1d, 0x04, 0xed, 0x8c, 0x65,
+	0xfd, 0xd1, 0x62, 0x2e, 0x80, 0x4c, 0x4a, 0x1d, 0x67, 0x90, 0x50, 0xed,
+	0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x2a, 0x4b, 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,
+	0x11, 0xe9, 0x36, 0x25, 0x8d, 0x97, 0x84, 0xea, 0xe9, 0x50, 0x4a, 0x27,
+	0x66, 0x6e, 0x0c, 0xd2, 0xce, 0x40, 0xfe, 0xfb, 0xf2, 0xc6, 0x53, 0xb4,
+	0x00, 0x00, 0x00, 0x00, 0xb6, 0x32, 0x22, 0x76, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xfc, 0x88, 0xcf, 0x76, 0x3c, 0x0b, 0x0d, 0x76, 0xb2, 0xc3, 0xc7, 0x8c,
+	0x8c, 0x53, 0x5f, 0x4c, 0xba, 0x0d, 0x13, 0xdb, 0x7b, 0xac, 0xf0, 0x19,
+	0x00, 0x00, 0x00, 0x00, 0x7e, 0x11, 0x95, 0x29, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static const uint8_t fpm_table_p256[CPT_P256_LEN] = {
+	0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x77, 0x03, 0x7d, 0x81,
+	0x2d, 0xeb, 0x33, 0xa0, 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
+	0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, 0x2b, 0xce, 0x33, 0x57,
+	0x6b, 0x31, 0x5e, 0xce, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+	0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 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,
+	0x90, 0xe7, 0x5c, 0xb4, 0x8e, 0x14, 0xdb, 0x63, 0x29, 0x49, 0x3b, 0xaa,
+	0xad, 0x65, 0x1f, 0x7e, 0x84, 0x92, 0x59, 0x2e, 0x32, 0x6e, 0x25, 0xde,
+	0x0f, 0xa8, 0x22, 0xbc, 0x28, 0x11, 0xaa, 0xa5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe4, 0x11, 0x24, 0x54, 0x5f, 0x46, 0x2e, 0xe7, 0x34, 0xb1, 0xa6, 0x50,
+	0x50, 0xfe, 0x82, 0xf5, 0x6f, 0x4a, 0xd4, 0xbc, 0xb3, 0xdf, 0x18, 0x8b,
+	0xbf, 0xf4, 0x4a, 0xe8, 0xf5, 0xdb, 0xa8, 0x0d, 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,
+	0x93, 0x39, 0x1c, 0xe2, 0x09, 0x79, 0x92, 0xaf, 0xe9, 0x6c, 0x98, 0xfd,
+	0x0d, 0x35, 0xf1, 0xfa, 0xb2, 0x57, 0xc0, 0xde, 0x95, 0xe0, 0x27, 0x89,
+	0x30, 0x0a, 0x4b, 0xbc, 0x89, 0xd6, 0x72, 0x6f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaa, 0x54, 0xa2, 0x91, 0xc0, 0x81, 0x27, 0xa0, 0x5b, 0xb1, 0xee, 0xad,
+	0xa9, 0xd8, 0x06, 0xa5, 0x7f, 0x1d, 0xdb, 0x25, 0xff, 0x1e, 0x3c, 0x6f,
+	0x72, 0xaa, 0xc7, 0xe0, 0xd0, 0x9b, 0x46, 0x44, 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,
+	0x57, 0xc8, 0x4f, 0xc9, 0xd7, 0x89, 0xbd, 0x85, 0xfc, 0x35, 0xff, 0x7d,
+	0xc2, 0x97, 0xea, 0xc3, 0xfb, 0x98, 0x2f, 0xd5, 0x88, 0xc6, 0x76, 0x6e,
+	0x44, 0x7d, 0x73, 0x9b, 0xee, 0xdb, 0x5e, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x0c, 0x7e, 0x33, 0xc9, 0x72, 0xe2, 0x5b, 0x32, 0x3d, 0x34, 0x9b, 0x95,
+	0xa7, 0xfa, 0xe5, 0x00, 0xe1, 0x2e, 0x9d, 0x95, 0x3a, 0x4a, 0xaf, 0xf7,
+	0x2d, 0x48, 0x25, 0xab, 0x83, 0x41, 0x31, 0xee, 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,
+	0x13, 0x94, 0x9c, 0x93, 0x2a, 0x1d, 0x36, 0x7f, 0xef, 0x7f, 0xbd, 0x2b,
+	0x1a, 0x0a, 0x11, 0xb7, 0xdd, 0xc6, 0x06, 0x8b, 0xb9, 0x1d, 0xfc, 0x60,
+	0xef, 0x95, 0x19, 0x32, 0x8a, 0x9c, 0x72, 0xff, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x19, 0x60, 0x35, 0xa7, 0x73, 0x76, 0xd8, 0xa8, 0x23, 0x18, 0x3b, 0x08,
+	0x95, 0xca, 0x17, 0x40, 0xc1, 0xee, 0x98, 0x07, 0x02, 0x2c, 0x21, 0x9c,
+	0x61, 0x1e, 0x9f, 0xc3, 0x7d, 0xbb, 0x2c, 0x9b, 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,
+	0xca, 0xe2, 0xb1, 0x92, 0x0b, 0x57, 0xf4, 0xbc, 0x29, 0x36, 0xdf, 0x5e,
+	0xc6, 0xc9, 0xbc, 0x36, 0x7d, 0xea, 0x64, 0x82, 0xe1, 0x12, 0x38, 0xbf,
+	0x55, 0x06, 0x63, 0x79, 0x7b, 0x51, 0xf5, 0xd8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0xff, 0xe2, 0x16, 0x34, 0x8a, 0x96, 0x4c, 0x9f, 0xb3, 0xd5, 0x76,
+	0xdb, 0xde, 0xfb, 0xe1, 0x0a, 0xfa, 0x40, 0x01, 0x8d, 0x9d, 0x50, 0xe5,
+	0x15, 0x71, 0x64, 0x84, 0x8a, 0xec, 0xb8, 0x51, 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,
+	0xe4, 0x8e, 0xca, 0xff, 0xfc, 0x5c, 0xde, 0x01, 0x7c, 0xcd, 0x84, 0xe7,
+	0x0d, 0x71, 0x5f, 0x26, 0xa2, 0xe8, 0xf4, 0x83, 0xf4, 0x3e, 0x43, 0x91,
+	0xeb, 0x5d, 0x77, 0x45, 0xb2, 0x11, 0x41, 0xea, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0xc9, 0x17, 0xe2, 0x73, 0x1a, 0x34, 0x79, 0x85, 0xf2, 0x2c, 0xfe,
+	0x28, 0x44, 0xb6, 0x45, 0x09, 0x90, 0xe6, 0xa1, 0x58, 0x00, 0x6c, 0xee,
+	0xea, 0xfd, 0x72, 0xeb, 0xdb, 0xec, 0xc1, 0x7b, 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,
+	0x6c, 0xf2, 0x0f, 0xfb, 0x31, 0x37, 0x28, 0xbe, 0x96, 0x43, 0x95, 0x91,
+	0xa3, 0xc6, 0xb9, 0x4a, 0x27, 0x36, 0xff, 0x83, 0x44, 0x31, 0x5f, 0xc5,
+	0xa6, 0xd3, 0x96, 0x77, 0xa7, 0x84, 0x92, 0x76, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0xba, 0xb8, 0x33, 0xc3, 0x57, 0xf5, 0xf4, 0x82, 0x4a, 0x92, 0x0c,
+	0x22, 0x84, 0x05, 0x9b, 0x66, 0xb8, 0xba, 0xbd, 0x2d, 0x27, 0xec, 0xdf,
+	0x67, 0x4f, 0x84, 0x74, 0x9b, 0x0b, 0x88, 0x16, 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,
+	0x2d, 0xf4, 0x8c, 0x04, 0x67, 0x7c, 0x8a, 0x3e, 0x74, 0xe0, 0x2f, 0x08,
+	0x02, 0x03, 0xa5, 0x6b, 0x31, 0x85, 0x5f, 0x7d, 0xb8, 0xc7, 0xfe, 0xdb,
+	0x4e, 0x76, 0x9e, 0x76, 0x72, 0xc9, 0xdd, 0xad, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0xc3, 0x61, 0x65, 0xb8, 0x24, 0xbb, 0xb0, 0xfb, 0x9a, 0xe1, 0x6f,
+	0x3b, 0x91, 0x22, 0xa5, 0x1e, 0xc0, 0x05, 0x72, 0x06, 0x94, 0x72, 0x81,
+	0x42, 0xb9, 0x90, 0x82, 0xde, 0x83, 0x06, 0x63, 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,
+	0x6e, 0xf9, 0x51, 0x50, 0xdd, 0xa8, 0x68, 0xb9, 0xd1, 0xf8, 0x9e, 0x79,
+	0x9c, 0x0c, 0xe1, 0x31, 0x7f, 0xdc, 0x1c, 0xa0, 0x08, 0xa1, 0xc4, 0x78,
+	0x78, 0x87, 0x8e, 0xf6, 0x1c, 0x6c, 0xe0, 0x4d, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9c, 0x62, 0xb9, 0x12, 0x1f, 0xe0, 0xd9, 0x76, 0x6a, 0xce, 0x57, 0x0e,
+	0xbd, 0xe0, 0x8d, 0x4f, 0xde, 0x53, 0x14, 0x2c, 0x12, 0x30, 0x9d, 0xef,
+	0xb6, 0xcb, 0x3f, 0x5d, 0x7b, 0x72, 0xc3, 0x21, 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,
+	0x7f, 0x99, 0x1e, 0xd2, 0xc3, 0x1a, 0x35, 0x73, 0x5b, 0x82, 0xdd, 0x5b,
+	0xd5, 0x4f, 0xb4, 0x96, 0x59, 0x5c, 0x52, 0x20, 0x81, 0x2f, 0xfc, 0xae,
+	0x0c, 0x88, 0xbc, 0x4d, 0x71, 0x6b, 0x12, 0x87, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3a, 0x57, 0xbf, 0x63, 0x5f, 0x48, 0xac, 0xa8, 0x7c, 0x81, 0x81, 0xf4,
+	0xdf, 0x25, 0x64, 0xf3, 0x18, 0xd1, 0xb5, 0xb3, 0x9c, 0x04, 0xe6, 0xaa,
+	0xdd, 0x5d, 0xde, 0xa3, 0xf3, 0x90, 0x1d, 0xc6, 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,
+	0xe9, 0x6a, 0x79, 0xfb, 0x3e, 0x72, 0xad, 0x0c, 0x43, 0xa0, 0xa2, 0x8c,
+	0x42, 0xba, 0x79, 0x2f, 0xef, 0xe0, 0xa4, 0x23, 0x08, 0x3e, 0x49, 0xf3,
+	0x68, 0xf3, 0x44, 0xaf, 0x6b, 0x31, 0x74, 0x66, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xcd, 0xfe, 0x17, 0xdb, 0x3f, 0xb2, 0x4d, 0x4a, 0x66, 0x8b, 0xfc, 0x22,
+	0x71, 0xf5, 0xc6, 0x26, 0x60, 0x4e, 0xd9, 0x3c, 0x24, 0xd6, 0x7f, 0xf3,
+	0x31, 0xb9, 0xc4, 0x05, 0xf8, 0x54, 0x0a, 0x20, 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,
+	0xd3, 0x6b, 0x47, 0x89, 0xa2, 0x58, 0x2e, 0x7f, 0x0d, 0x1a, 0x10, 0x14,
+	0x4e, 0xc3, 0x9c, 0x28, 0x66, 0x3c, 0x62, 0xc3, 0xed, 0xba, 0xd7, 0xa0,
+	0x40, 0x52, 0xbf, 0x4b, 0x6f, 0x46, 0x1d, 0xb9, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x23, 0x5a, 0x27, 0xc3, 0x18, 0x8d, 0x25, 0xeb, 0xe7, 0x24, 0xf3, 0x39,
+	0x99, 0xbf, 0xcc, 0x5b, 0x86, 0x2b, 0xe6, 0xbd, 0x71, 0xd7, 0x0c, 0xc8,
+	0xfe, 0xcf, 0x4d, 0x51, 0x90, 0xb0, 0xfc, 0x61, 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,
+	0x74, 0x34, 0x6c, 0x10, 0xa1, 0xd4, 0xcf, 0xac, 0xaf, 0xdf, 0x5c, 0xc0,
+	0x85, 0x26, 0xa7, 0xa4, 0x12, 0x32, 0x02, 0xa8, 0xf6, 0x2b, 0xff, 0x7a,
+	0x1e, 0xdd, 0xba, 0xe2, 0xc8, 0x02, 0xe4, 0x1a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8f, 0xa0, 0xaf, 0x2d, 0xd6, 0x03, 0xf8, 0x44, 0x36, 0xe0, 0x6b, 0x7e,
+	0x4c, 0x70, 0x19, 0x17, 0x0c, 0x45, 0xf4, 0x52, 0x73, 0xdb, 0x33, 0xa0,
+	0x43, 0x10, 0x4d, 0x86, 0x56, 0x0e, 0xbc, 0xfc, 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,
+	0x96, 0x15, 0xb5, 0x11, 0x0d, 0x1d, 0x78, 0xe5, 0x66, 0xb0, 0xde, 0x32,
+	0x25, 0xc4, 0x74, 0x4b, 0x0a, 0x4a, 0x46, 0xfb, 0x6a, 0xaf, 0x36, 0x3a,
+	0xb4, 0x8e, 0x26, 0xb4, 0x84, 0xf7, 0xa2, 0x1c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x06, 0xeb, 0xb0, 0xf6, 0x21, 0xa0, 0x1b, 0x2d, 0xc0, 0x04, 0xe4, 0x04,
+	0x8b, 0x7b, 0x0f, 0x98, 0x64, 0x13, 0x1b, 0xcd, 0xfe, 0xd6, 0xf6, 0x68,
+	0xfa, 0xc0, 0x15, 0x40, 0x4d, 0x4d, 0x3d, 0xab, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static const uint8_t fpm_table_p384[CPT_P384_LEN] = {
+	0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, 0x55, 0x02, 0xf2, 0x5d,
+	0xbf, 0x55, 0x29, 0x6c, 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38,
+	0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x8e, 0xb1, 0xc7, 0x1e,
+	0xf3, 0x20, 0xad, 0x74, 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x43, 0x1d, 0x7c,
+	0x90, 0xea, 0x0e, 0x5f, 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
+	0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0xf8, 0xf4, 0x1d, 0xbd,
+	0x28, 0x9a, 0x14, 0x7c, 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29,
+	0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 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,
+	0x39, 0xc1, 0xb3, 0x28, 0xd8, 0xee, 0x21, 0xc9, 0x2c, 0x3e, 0x0c, 0x91,
+	0x55, 0x87, 0x17, 0xdb, 0x4b, 0x58, 0x80, 0x8b, 0x3f, 0x86, 0x86, 0xa9,
+	0x43, 0x60, 0x39, 0x09, 0x18, 0x14, 0x1b, 0x1a, 0xd6, 0xe9, 0x8b, 0x0d,
+	0x37, 0xca, 0x7a, 0xbc, 0xf5, 0x32, 0x38, 0x9a, 0x06, 0x0c, 0xbd, 0x1b,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x7e, 0x18, 0x39,
+	0x23, 0xd8, 0x6e, 0xcd, 0x31, 0xea, 0x31, 0xb1, 0x08, 0x5a, 0x4e, 0x9a,
+	0xbc, 0x40, 0xce, 0x5a, 0xbe, 0x64, 0x36, 0x03, 0xbd, 0x22, 0xcf, 0xb2,
+	0xa2, 0x12, 0x41, 0x63, 0x6f, 0x04, 0xca, 0xa2, 0xde, 0x3a, 0x82, 0xba,
+	0xb9, 0xd2, 0x85, 0x2c, 0xc3, 0xb3, 0x8e, 0x69, 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,
+	0x26, 0x4e, 0x52, 0x46, 0xeb, 0x09, 0xa0, 0xe5, 0xf8, 0xf4, 0xbe, 0x11,
+	0x32, 0xcd, 0xf0, 0x3c, 0xda, 0x9d, 0x54, 0x83, 0x5f, 0xae, 0xfa, 0x4f,
+	0xbb, 0xbc, 0x4f, 0xd0, 0x17, 0xa3, 0x1b, 0x22, 0xc3, 0xde, 0xcd, 0x0c,
+	0x86, 0xf0, 0x61, 0x45, 0x52, 0x8e, 0xf1, 0x67, 0x0a, 0x5f, 0x2c, 0xab,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x1e, 0x98, 0x58,
+	0xc1, 0x4f, 0x0d, 0xd6, 0x55, 0x05, 0x38, 0xa8, 0x09, 0xcb, 0x75, 0x24,
+	0xbd, 0x60, 0xca, 0xb4, 0xc8, 0x7f, 0xed, 0x22, 0xf8, 0xb7, 0x6f, 0xdd,
+	0x63, 0x1d, 0x05, 0x8d, 0x58, 0x03, 0xea, 0xa1, 0x1a, 0x1d, 0xcf, 0x14,
+	0x7b, 0x9b, 0x1f, 0xbe, 0x7b, 0xcc, 0xf5, 0x6c, 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,
+	0xa6, 0x28, 0xb0, 0x9a, 0xaa, 0x03, 0xbd, 0x53, 0xba, 0x06, 0x54, 0x58,
+	0xa4, 0xf5, 0x2d, 0x78, 0xdb, 0x29, 0x87, 0x89, 0x4d, 0x10, 0xdd, 0xea,
+	0xb4, 0x2a, 0x31, 0xaf, 0x8a, 0x3e, 0x29, 0x7d, 0x40, 0xf7, 0xf9, 0xe7,
+	0x06, 0x42, 0x12, 0x79, 0xc1, 0x9e, 0x0b, 0x4c, 0x80, 0x01, 0x19, 0xc4,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x2d, 0x0f, 0xc5,
+	0xe6, 0xc8, 0x8c, 0x41, 0xaf, 0x68, 0xaa, 0x6d, 0xe6, 0x39, 0xd8, 0x58,
+	0xc1, 0xc7, 0xca, 0xd1, 0x35, 0xf6, 0xeb, 0xf2, 0x57, 0x7a, 0x30, 0xea,
+	0xe3, 0x56, 0x7a, 0xf9, 0xe5, 0xa0, 0x19, 0x1d, 0x1f, 0x5b, 0x77, 0xf6,
+	0x16, 0xf3, 0xfd, 0xbf, 0x03, 0x56, 0xb3, 0x01, 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,
+	0x30, 0x99, 0x15, 0x60, 0xaa, 0x13, 0x39, 0x09, 0x90, 0x97, 0xdb, 0xb1,
+	0xc6, 0xcb, 0x00, 0x17, 0xd3, 0x7d, 0xe4, 0x24, 0xb8, 0x60, 0xfa, 0xe6,
+	0x9b, 0xb1, 0x83, 0xb2, 0x70, 0xb3, 0x75, 0xdd, 0x56, 0x7a, 0x62, 0x33,
+	0xcd, 0x6c, 0xe3, 0xa3, 0xaa, 0xb8, 0xbb, 0x9f, 0x0f, 0xdc, 0x30, 0x88,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xc5, 0xb9, 0x81,
+	0x60, 0x0a, 0xd5, 0xa6, 0xeb, 0xdf, 0x73, 0xf2, 0xd6, 0x2f, 0xaa, 0x44,
+	0x6d, 0x95, 0x5b, 0xb3, 0xc9, 0x74, 0x7b, 0xf3, 0xf6, 0x00, 0x5f, 0xc8,
+	0x15, 0xeb, 0x04, 0xac, 0xf0, 0xaf, 0x01, 0xd1, 0x28, 0x20, 0x50, 0xb5,
+	0x48, 0x94, 0x2f, 0x81, 0x31, 0x4f, 0x6d, 0x28, 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,
+	0x20, 0x22, 0x11, 0x21, 0x77, 0x16, 0x60, 0x5e, 0x23, 0x47, 0xd2, 0xc8,
+	0x9e, 0xf2, 0x81, 0xc8, 0x54, 0xba, 0x45, 0x99, 0x56, 0x7d, 0x63, 0x42,
+	0xce, 0x0f, 0xba, 0x30, 0x77, 0xc0, 0xf0, 0x3f, 0x70, 0x22, 0xf8, 0x02,
+	0xcb, 0x36, 0x74, 0x44, 0x73, 0x34, 0xa9, 0x36, 0xa9, 0xa6, 0xa0, 0x52,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x46, 0x1f, 0x68,
+	0xd6, 0x58, 0xa0, 0x1a, 0x0a, 0x64, 0xd5, 0x19, 0xc2, 0xbd, 0x0e, 0xfa,
+	0x9e, 0x2e, 0xee, 0x8f, 0x69, 0x7a, 0x92, 0x80, 0x8e, 0x5d, 0x9b, 0x89,
+	0x7d, 0x0e, 0x01, 0x7a, 0x1f, 0x7c, 0x5c, 0x36, 0x7c, 0xbd, 0x4c, 0xcd,
+	0x7f, 0xfc, 0xef, 0xf7, 0xf6, 0x32, 0xc9, 0x26, 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,
+	0x30, 0x0a, 0xe2, 0xe6, 0x0e, 0x75, 0x83, 0x44, 0x45, 0x1c, 0x70, 0x7a,
+	0x37, 0x1a, 0x2c, 0xa5, 0x25, 0x65, 0x1d, 0x10, 0x50, 0x52, 0xdd, 0x32,
+	0xbf, 0x88, 0xde, 0x7f, 0x48, 0x62, 0xb9, 0x54, 0xfa, 0xfc, 0xe2, 0x6e,
+	0x03, 0x81, 0xef, 0x13, 0xdc, 0x91, 0x6c, 0x17, 0x96, 0x0e, 0x09, 0x0e,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x17, 0xcc, 0x44,
+	0x02, 0x6b, 0x08, 0x89, 0x95, 0xc0, 0x1f, 0xf1, 0x9b, 0x42, 0x44, 0x1b,
+	0x40, 0x89, 0x64, 0x78, 0xcc, 0x16, 0x06, 0x97, 0x52, 0xd1, 0x54, 0xb8,
+	0x0b, 0xa0, 0x4a, 0x35, 0xb3, 0xd9, 0x2e, 0xa4, 0x70, 0x1c, 0x29, 0x52,
+	0x26, 0x6e, 0x8a, 0x40, 0xd6, 0x9e, 0xca, 0x0a, 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,
+	0xe4, 0xbf, 0xc2, 0xc0, 0x49, 0x05, 0xca, 0x71, 0xf3, 0x3a, 0x45, 0x0a,
+	0xd1, 0x56, 0xf7, 0x61, 0x3d, 0x8b, 0x29, 0xdb, 0xd0, 0x88, 0x48, 0xc2,
+	0x09, 0x7d, 0xa3, 0x95, 0xa2, 0x30, 0x96, 0x86, 0x21, 0x19, 0x05, 0x03,
+	0x5f, 0x49, 0x72, 0xd7, 0xb2, 0xd1, 0x05, 0x58, 0x17, 0xcb, 0xaa, 0x12,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0xce, 0xbb, 0x55,
+	0x75, 0x3e, 0xe3, 0x24, 0xe8, 0x7a, 0xb0, 0x7c, 0x69, 0x24, 0x66, 0x6f,
+	0x9b, 0x47, 0x5d, 0x74, 0x4e, 0xcf, 0x1a, 0x68, 0xf8, 0x2b, 0xe8, 0xf5,
+	0x2e, 0x62, 0x36, 0xc0, 0x23, 0x7c, 0x0d, 0xba, 0x3c, 0xfd, 0x05, 0x6b,
+	0x35, 0x4c, 0xd8, 0x72, 0xc3, 0xc6, 0xcb, 0xd2, 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,
+	0x8d, 0x10, 0x4d, 0x24, 0x70, 0x8d, 0x4c, 0xee, 0x19, 0x7d, 0x69, 0x58,
+	0x81, 0x9c, 0xf0, 0x43, 0x47, 0xfc, 0x87, 0xfa, 0xf0, 0x71, 0x22, 0x10,
+	0x10, 0x3d, 0xf7, 0x85, 0x5c, 0x20, 0x15, 0x58, 0x30, 0xb0, 0xa9, 0xe8,
+	0x61, 0x1e, 0xf6, 0x38, 0x00, 0xb1, 0x9a, 0xc8, 0xfd, 0xfe, 0xbf, 0xec,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0e, 0x8d, 0x6f,
+	0xd2, 0x01, 0xe0, 0x3e, 0xbb, 0x7c, 0x96, 0x9c, 0x22, 0x28, 0xff, 0x5f,
+	0x68, 0x81, 0x02, 0x82, 0x63, 0x61, 0x64, 0xc5, 0xcd, 0xbb, 0x3c, 0xd2,
+	0xe7, 0x54, 0x22, 0x0d, 0x14, 0x18, 0xfe, 0x25, 0xe9, 0xf6, 0xed, 0xc4,
+	0xa7, 0x2f, 0x91, 0x05, 0x9e, 0xe3, 0x60, 0x31, 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,
+	0x64, 0xd2, 0xc2, 0x73, 0xb7, 0x69, 0x73, 0x7a, 0x2c, 0xc0, 0x24, 0x51,
+	0x97, 0xd5, 0x3f, 0xfd, 0xc3, 0xb6, 0xac, 0x4b, 0xe8, 0x6c, 0x46, 0xbd,
+	0x17, 0xe9, 0x41, 0x1f, 0x68, 0x5e, 0x92, 0x6d, 0x13, 0x6d, 0xf3, 0x6b,
+	0x75, 0x20, 0x3a, 0x36, 0x3f, 0x95, 0x61, 0xe0, 0x8b, 0xf0, 0xb2, 0x7e,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x6f, 0xf8, 0xd5,
+	0x27, 0xe9, 0x90, 0xa7, 0xc3, 0x4b, 0xe5, 0x86, 0xf9, 0x86, 0x7a, 0x60,
+	0xea, 0x08, 0x87, 0x47, 0x85, 0x54, 0xe0, 0x14, 0xcf, 0xce, 0xd6, 0x64,
+	0x6f, 0x52, 0xe4, 0xcb, 0x4b, 0x1a, 0x5a, 0x20, 0x41, 0x2a, 0xb6, 0x41,
+	0x0b, 0x06, 0xf0, 0x06, 0x39, 0x62, 0x95, 0x87, 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,
+	0x04, 0x4c, 0x0d, 0xd2, 0x85, 0x65, 0x1f, 0x82, 0x32, 0x5c, 0x51, 0xe7,
+	0x78, 0x5d, 0x3e, 0xf7, 0xb8, 0x3a, 0x18, 0x61, 0x88, 0xe9, 0x55, 0x32,
+	0x53, 0x9f, 0x94, 0xad, 0x52, 0x2c, 0x29, 0x31, 0x15, 0x27, 0x4e, 0x5b,
+	0x89, 0x80, 0xf1, 0x37, 0x9f, 0xd7, 0xb0, 0x10, 0xdf, 0x0f, 0x66, 0xd7,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0xa7, 0xb9, 0x4a,
+	0x40, 0x64, 0xe4, 0xc0, 0xd4, 0x4e, 0xba, 0x45, 0x25, 0xd7, 0xd2, 0x11,
+	0x0a, 0x80, 0x6b, 0x54, 0xbe, 0x8a, 0x04, 0xe3, 0x92, 0x92, 0x26, 0xbd,
+	0x14, 0x90, 0x33, 0xde, 0x79, 0x5f, 0x6f, 0xa3, 0xc9, 0x73, 0x92, 0x46,
+	0x32, 0x1a, 0xa9, 0xa3, 0xb9, 0x26, 0x02, 0x25, 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,
+	0x49, 0xbc, 0xc2, 0xf5, 0x8b, 0x70, 0x7b, 0x8e, 0x29, 0x01, 0xb5, 0x19,
+	0x1d, 0x92, 0x89, 0x83, 0x2e, 0x4c, 0x29, 0x56, 0x7d, 0x49, 0xc7, 0x80,
+	0xeb, 0xd1, 0xcf, 0xf8, 0x4c, 0x6a, 0x99, 0x64, 0x2c, 0xae, 0xbb, 0xd3,
+	0x16, 0xee, 0x3e, 0x13, 0x36, 0xa5, 0x43, 0xee, 0xa8, 0x7a, 0x68, 0xf7,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0xb4, 0x1c, 0x29,
+	0xb5, 0x69, 0x94, 0x6d, 0x15, 0x10, 0xe7, 0xd4, 0x3e, 0xf2, 0x26, 0x7e,
+	0x91, 0x23, 0x50, 0x72, 0xd4, 0xb3, 0x39, 0x4d, 0x58, 0xea, 0xff, 0x04,
+	0x8f, 0xbd, 0x85, 0xd1, 0xd3, 0x49, 0xab, 0x03, 0x78, 0xa6, 0x78, 0x47,
+	0xf2, 0x77, 0xba, 0xcd, 0xa5, 0x0e, 0xe4, 0x1c, 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,
+	0x10, 0xb0, 0x56, 0x58, 0x5f, 0x86, 0x3b, 0xbd, 0xe9, 0x2c, 0xdc, 0x5a,
+	0xb4, 0x83, 0x28, 0x3d, 0xeb, 0xb3, 0x12, 0x09, 0xdc, 0x7c, 0x42, 0x1d,
+	0x3a, 0xfc, 0xbd, 0x79, 0x6d, 0x01, 0xa5, 0xa8, 0xe2, 0xb0, 0x67, 0xca,
+	0xa0, 0x8b, 0x6a, 0x51, 0x02, 0x6e, 0x0d, 0xc2, 0xe8, 0xcb, 0x7a, 0xeb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xc3, 0x50, 0x29,
+	0x02, 0xdd, 0xe1, 0x8a, 0x64, 0xc1, 0x5f, 0xac, 0xd8, 0xc6, 0xcf, 0x36,
+	0x17, 0xea, 0x27, 0x01, 0x10, 0x78, 0x1e, 0x45, 0xd6, 0x8d, 0x1f, 0xfc,
+	0x1f, 0x34, 0x43, 0xd8, 0x4b, 0xe2, 0x56, 0x37, 0x8c, 0x74, 0x61, 0xa5,
+	0xae, 0x88, 0x66, 0xba, 0xd8, 0xef, 0x24, 0xe1, 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,
+	0xac, 0x3a, 0x78, 0xd0, 0xd2, 0x65, 0xa9, 0x1c, 0x1a, 0x29, 0xf8, 0xef,
+	0x6c, 0x8f, 0x83, 0xd3, 0xef, 0x98, 0xfd, 0xde, 0x8f, 0xd8, 0xd8, 0x17,
+	0xdf, 0x45, 0x9e, 0xa1, 0xc4, 0x2b, 0xf7, 0x48, 0x14, 0xda, 0xfc, 0x39,
+	0x81, 0xa7, 0x3d, 0xc7, 0xb0, 0x3d, 0xfa, 0x54, 0xc5, 0x2a, 0xfa, 0x2d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x40, 0x6f, 0x6e,
+	0x6c, 0x0d, 0x2c, 0xe7, 0xcd, 0x12, 0x0b, 0x2b, 0x41, 0xfd, 0x72, 0xca,
+	0xef, 0x5d, 0x90, 0x06, 0x78, 0xf6, 0x02, 0xdd, 0xf5, 0xf8, 0xa2, 0xd1,
+	0x8a, 0xcc, 0xf2, 0x29, 0xaa, 0xfd, 0x1f, 0xcf, 0xce, 0x6d, 0x90, 0x8a,
+	0x2c, 0xe2, 0x88, 0x5a, 0x0e, 0x6d, 0x85, 0xf2, 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,
+	0x89, 0x10, 0x9a, 0x0e, 0xc6, 0x26, 0x66, 0xde, 0xc8, 0xc1, 0x2e, 0x75,
+	0x7f, 0xfc, 0xd0, 0x1e, 0xa8, 0x20, 0x61, 0x69, 0xc4, 0x8b, 0x5a, 0xb0,
+	0x4b, 0xc2, 0xfd, 0xcf, 0xf9, 0x83, 0xac, 0x6c, 0x59, 0xcf, 0xca, 0x71,
+	0x55, 0x97, 0x7d, 0x23, 0x12, 0x64, 0xcb, 0x33, 0x57, 0x66, 0xc9, 0x6a,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x13, 0x81,
+	0x2e, 0x01, 0x4b, 0x4b, 0x31, 0xd2, 0x87, 0x07, 0xe4, 0x48, 0x3e, 0xc5,
+	0xcb, 0xf7, 0x19, 0x0c, 0xff, 0xb1, 0x97, 0x58, 0xb6, 0x67, 0x17, 0xa0,
+	0x65, 0xa5, 0xf2, 0x48, 0xd9, 0x4a, 0xd8, 0xfa, 0xc5, 0x3b, 0x4f, 0x69,
+	0x11, 0x9e, 0xbe, 0xee, 0xa1, 0xa1, 0xa3, 0x76, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static const uint8_t fpm_table_p521[CPT_P521_LEN] = {
+	0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x33, 0x48, 0xb3, 0xc1,
+	0x85, 0x6a, 0x42, 0x9b, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde,
+	0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xf8, 0x28, 0xaf, 0x60,
+	0x6b, 0x4d, 0x3d, 0xba, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21,
+	0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x85, 0x8e, 0x06, 0xb7,
+	0x04, 0x04, 0xe9, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6,
+	0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, 0x35, 0x3c, 0x70, 0x86,
+	0xa2, 0x72, 0xc2, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
+	0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0x17, 0xaf, 0xbd, 0x17,
+	0x27, 0x3e, 0x66, 0x2c, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68,
+	0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x39, 0x29, 0x6a, 0x78,
+	0x9a, 0x3b, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x69, 0xca, 0xd3, 0xcc, 0xc4, 0xd6, 0xab, 0x08, 0x3a, 0xdb, 0x57, 0x77,
+	0x3b, 0x89, 0x90, 0xb8, 0xd0, 0xca, 0xd8, 0xce, 0x8d, 0x95, 0x88, 0x01,
+	0xcb, 0x57, 0x2e, 0x66, 0x6d, 0x72, 0x8f, 0x9e, 0xe3, 0xd9, 0xe7, 0xc4,
+	0xcd, 0x51, 0x31, 0xfc, 0xaf, 0xce, 0xb6, 0xb0, 0x61, 0x45, 0xdc, 0x06,
+	0x12, 0xec, 0xd3, 0x92, 0xe2, 0x13, 0x04, 0x3a, 0xbd, 0x59, 0x92, 0x94,
+	0x3a, 0x64, 0xc8, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+	0x86, 0x23, 0xbd, 0xbb, 0xf6, 0xea, 0x9c, 0xf1, 0x3a, 0xad, 0x94, 0x95,
+	0x54, 0x7a, 0xa6, 0x50, 0xd3, 0xd8, 0x53, 0xfc, 0xbe, 0xb2, 0x71, 0x59,
+	0x3d, 0x25, 0xa6, 0x48, 0x30, 0xb4, 0x08, 0x33, 0x12, 0xd1, 0x88, 0xe8,
+	0xde, 0xc5, 0x1b, 0xd1, 0x83, 0x63, 0x30, 0xd2, 0xb3, 0x48, 0xc3, 0xfa,
+	0x9d, 0xf5, 0x0c, 0xfe, 0x73, 0xc2, 0xea, 0x59, 0xb5, 0xdf, 0xfb, 0x20,
+	0x61, 0xde, 0xd0, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xdc, 0x33, 0x41, 0x6e, 0xc8, 0xc5, 0xbc, 0xb2, 0xde, 0xfb, 0x4a, 0x9c,
+	0xe2, 0x44, 0x91, 0x0b, 0x27, 0xc3, 0x56, 0x1b, 0x53, 0xa8, 0xf7, 0xb9,
+	0x10, 0x88, 0xbb, 0x9e, 0xf6, 0x94, 0xd7, 0xb1, 0x98, 0xfa, 0x92, 0xaa,
+	0xa6, 0xd2, 0xc7, 0x82, 0x53, 0xc2, 0xa3, 0xdb, 0x3b, 0xa3, 0x7d, 0xd4,
+	0x67, 0xfc, 0x7c, 0xab, 0xd5, 0x93, 0x4b, 0xbc, 0x0c, 0x72, 0xcf, 0x96,
+	0x93, 0xbb, 0x09, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf,
+	0xf3, 0x2e, 0xbb, 0x1f, 0x13, 0xda, 0xb4, 0x57, 0x7c, 0x36, 0x11, 0xdf,
+	0xad, 0x23, 0x53, 0x70, 0xd8, 0x6d, 0x54, 0xdb, 0xab, 0x9e, 0x13, 0x10,
+	0xbf, 0x40, 0x10, 0xf1, 0x61, 0x85, 0xbf, 0x0d, 0x94, 0x6d, 0xb5, 0x6e,
+	0x31, 0x3c, 0x69, 0xf5, 0x3b, 0x67, 0x3c, 0x92, 0xe3, 0x77, 0x73, 0x27,
+	0x58, 0x7a, 0x4e, 0xa7, 0x47, 0x7a, 0xbd, 0xe6, 0xae, 0x87, 0xa6, 0x00,
+	0xd8, 0xaa, 0xa4, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xbf, 0x2f, 0xfc, 0xb7, 0x6e, 0x64, 0x0a, 0x8d, 0x63, 0x47, 0x95, 0x01,
+	0xa0, 0xb5, 0xa0, 0x7e, 0x55, 0xbb, 0x30, 0x01, 0x5f, 0x36, 0xf2, 0xe7,
+	0x98, 0x90, 0xf9, 0x99, 0x05, 0x8a, 0x67, 0x6a, 0xd9, 0xee, 0x34, 0x1b,
+	0x45, 0x5c, 0x0d, 0x27, 0x6c, 0x95, 0x78, 0x0c, 0x18, 0xe0, 0x8f, 0xc8,
+	0xeb, 0x63, 0xa6, 0x75, 0x44, 0x2a, 0x07, 0x5d, 0xce, 0x46, 0xa1, 0xa5,
+	0xfb, 0x69, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b,
+	0x8c, 0x61, 0x89, 0x34, 0xf3, 0xed, 0x62, 0x53, 0xe0, 0x03, 0x42, 0x44,
+	0x6e, 0x94, 0x33, 0xb4, 0x98, 0x9b, 0x99, 0x21, 0x42, 0x60, 0xb2, 0xc5,
+	0x11, 0x69, 0x98, 0x04, 0xd9, 0xdf, 0x47, 0x47, 0x12, 0x5f, 0xe6, 0x1f,
+	0x76, 0x3a, 0x7f, 0x63, 0xa9, 0x72, 0x78, 0x6d, 0xc6, 0xec, 0x39, 0x5a,
+	0x66, 0x2f, 0x9f, 0xe7, 0xb7, 0xb7, 0xb8, 0xc6, 0xfb, 0x64, 0x4a, 0x61,
+	0x54, 0x56, 0x55, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x52, 0x3c, 0xf9, 0xb2, 0xfd, 0xe7, 0x22, 0x35, 0x5c, 0x90, 0xde, 0xf0,
+	0xe8, 0xe0, 0x99, 0x59, 0xfe, 0x13, 0x1b, 0x9c, 0xd3, 0xcf, 0x46, 0x66,
+	0xc9, 0x14, 0x31, 0x30, 0xc1, 0x32, 0x76, 0xad, 0xa7, 0xdc, 0xdd, 0xc1,
+	0x85, 0xe2, 0x36, 0x37, 0x09, 0x45, 0x74, 0xcc, 0xf5, 0x14, 0x11, 0xd7,
+	0xf3, 0xfc, 0x87, 0xc4, 0xbd, 0x29, 0xfe, 0xd7, 0x2c, 0xc3, 0x2d, 0x3f,
+	0x17, 0x1c, 0xef, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x32,
+	0xdf, 0xa9, 0x2d, 0x3e, 0x35, 0xcc, 0x7a, 0x6c, 0xdd, 0x6d, 0xc6, 0x86,
+	0xd4, 0xe4, 0x78, 0x8b, 0xcb, 0x66, 0xcd, 0xe2, 0x1f, 0x74, 0xbb, 0xe0,
+	0xb0, 0xe9, 0xff, 0x6a, 0xf6, 0x7e, 0xc3, 0x95, 0x18, 0x6c, 0xfa, 0x86,
+	0x07, 0xb9, 0xdd, 0xff, 0xe8, 0x67, 0xde, 0x2f, 0xcf, 0x2d, 0xfd, 0x72,
+	0x49, 0x8c, 0x21, 0x91, 0xe2, 0x4e, 0xd3, 0x15, 0x2d, 0xf0, 0xac, 0xf8,
+	0xf7, 0x37, 0xe8, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x52, 0x6f, 0x00, 0x95, 0x74, 0x31, 0x82, 0x2a, 0x18, 0x5d, 0x92, 0xc3,
+	0xeb, 0x0c, 0x4e, 0xf8, 0xc8, 0x78, 0x13, 0x76, 0x38, 0x89, 0x30, 0x98,
+	0x32, 0x54, 0x7e, 0xec, 0x6a, 0x55, 0x72, 0xd0, 0xe1, 0xe8, 0xea, 0xe8,
+	0xf5, 0x94, 0x62, 0x73, 0x9a, 0x9e, 0x24, 0x00, 0xc8, 0x2f, 0x4f, 0x17,
+	0xfb, 0x98, 0xab, 0xff, 0xdb, 0x9f, 0x0e, 0x9b, 0x3c, 0x20, 0x1a, 0xa5,
+	0x83, 0x28, 0x87, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x95,
+	0x58, 0x76, 0x12, 0xa4, 0x41, 0xc2, 0xb1, 0x4a, 0x11, 0x91, 0xb7, 0x1d,
+	0xfd, 0xbf, 0x12, 0x43, 0x97, 0x39, 0x6e, 0xe7, 0xbc, 0xf5, 0x3f, 0x43,
+	0xd1, 0x4b, 0xf1, 0xa7, 0x90, 0xec, 0xf9, 0x76, 0x7f, 0x14, 0x7a, 0x72,
+	0x0b, 0xc6, 0xa0, 0xea, 0x40, 0x95, 0x18, 0xf8, 0xaf, 0xcb, 0xff, 0x46,
+	0x30, 0x21, 0xdc, 0xa5, 0x32, 0x17, 0x0c, 0x93, 0x88, 0x16, 0xd3, 0xee,
+	0x33, 0xf2, 0x46, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xcc, 0x7d, 0x6e, 0x15, 0x2f, 0x97, 0x03, 0x30, 0x50, 0xb1, 0xf6, 0x9e,
+	0x03, 0x00, 0x75, 0x86, 0xfc, 0x0e, 0x37, 0x04, 0x58, 0x25, 0x83, 0x51,
+	0xa8, 0x5d, 0x47, 0xe3, 0x56, 0xd8, 0xaf, 0x60, 0x1c, 0x89, 0x3b, 0x86,
+	0x8a, 0xc7, 0x42, 0x7f, 0x8e, 0x70, 0xdd, 0xd9, 0x5c, 0xcf, 0x72, 0xde,
+	0x1e, 0xd8, 0x3e, 0x13, 0x16, 0x06, 0x0a, 0x41, 0xc9, 0x00, 0xb8, 0x12,
+	0x6d, 0xa8, 0x80, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+	0x3a, 0xc0, 0x08, 0x85, 0x5c, 0x6c, 0x32, 0x0b, 0x56, 0xa9, 0xb0, 0x12,
+	0x24, 0x1f, 0x0c, 0xd6, 0x47, 0x94, 0x1b, 0x89, 0x97, 0x5d, 0xe7, 0x17,
+	0xe7, 0x09, 0xef, 0x78, 0xdc, 0xe4, 0x8a, 0x06, 0x48, 0x2f, 0x2a, 0x6a,
+	0x01, 0x56, 0xf2, 0xbd, 0xe7, 0xbd, 0xca, 0x0d, 0xae, 0x0a, 0x8a, 0x52,
+	0x8e, 0x41, 0xf9, 0x41, 0x3f, 0x45, 0x94, 0x01, 0xea, 0x6d, 0x1c, 0x40,
+	0x60, 0x16, 0x6a, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa6, 0x6c, 0xcc, 0xc8, 0xd6, 0xe1, 0xbd, 0x72, 0x1e, 0xa4, 0xe9, 0x21,
+	0x4a, 0xe2, 0xfa, 0x5c, 0x66, 0x77, 0x5a, 0xf2, 0x2d, 0x02, 0x1f, 0xa7,
+	0x6d, 0x71, 0x1d, 0xfb, 0x2a, 0x4c, 0x46, 0x77, 0xdd, 0xaa, 0xe8, 0xbb,
+	0x5a, 0xe3, 0x80, 0xb3, 0x53, 0x15, 0x89, 0x94, 0x60, 0x0f, 0x11, 0xfc,
+	0xfe, 0xb1, 0x22, 0xdb, 0xda, 0x94, 0xd4, 0x43, 0x7c, 0xbf, 0x1a, 0xfa,
+	0xdf, 0xfc, 0x21, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+	0x03, 0xcf, 0xa7, 0x31, 0x83, 0x4b, 0xf8, 0x91, 0x4e, 0x01, 0x60, 0x85,
+	0x63, 0x0b, 0x80, 0x32, 0x90, 0xcf, 0x9b, 0x59, 0x49, 0xdb, 0x4d, 0x96,
+	0x96, 0xfd, 0x26, 0x14, 0x33, 0x5c, 0x9d, 0xdd, 0xc0, 0x21, 0x45, 0x10,
+	0x8e, 0x3b, 0x98, 0xfb, 0x6d, 0xed, 0x06, 0x33, 0x1d, 0xa2, 0xea, 0x2f,
+	0x2b, 0xda, 0x6d, 0x76, 0x9d, 0x0e, 0xad, 0x76, 0x4b, 0xa0, 0x0e, 0x99,
+	0xf3, 0xe4, 0xfb, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb0, 0x31, 0x1b, 0x24, 0xcd, 0xed, 0xb3, 0xd3, 0x61, 0x14, 0xed, 0xd7,
+	0xe5, 0xc3, 0xfb, 0x9d, 0x8e, 0x02, 0x64, 0x37, 0x1a, 0x6b, 0xb2, 0xa1,
+	0xd7, 0xcc, 0x12, 0x87, 0x5e, 0xcd, 0xbe, 0x72, 0x6f, 0x71, 0x72, 0x87,
+	0x15, 0x58, 0x28, 0xe1, 0xb8, 0x3a, 0xef, 0xaa, 0x5f, 0x9b, 0xf5, 0x5d,
+	0x29, 0xd8, 0xc7, 0x42, 0x7e, 0x0b, 0x8a, 0xce, 0x18, 0xfe, 0x72, 0xa4,
+	0x64, 0x25, 0x9f, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a,
+	0x80, 0xf7, 0xfb, 0xb6, 0x2a, 0xa4, 0x37, 0x5d, 0x8d, 0x40, 0xb9, 0xee,
+	0x6d, 0x0b, 0xec, 0x41, 0x55, 0xdd, 0x1c, 0xe0, 0x41, 0xdb, 0xbd, 0x4b,
+	0xba, 0x77, 0x95, 0x12, 0x29, 0x4b, 0xc6, 0xcc, 0x38, 0x3d, 0x3a, 0x90,
+	0x4a, 0xa6, 0x6d, 0xb2, 0x3c, 0x46, 0x18, 0x62, 0x6c, 0xa8, 0xd7, 0x01,
+	0xf8, 0x0e, 0x3b, 0x59, 0x19, 0xbc, 0xfc, 0x0b, 0x9b, 0x63, 0x7d, 0x37,
+	0x5f, 0x56, 0xcd, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5e,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x74, 0x3b, 0x45, 0x1f, 0x86, 0xeb, 0x01, 0xd4, 0x63, 0x9c, 0x35, 0xde,
+	0x4d, 0x93, 0xf5, 0x7f, 0xab, 0x5e, 0xaa, 0xc4, 0x71, 0xd1, 0x5e, 0x15,
+	0xb7, 0x7b, 0xd7, 0x5b, 0xbe, 0x29, 0x19, 0xc6, 0x34, 0xb5, 0x39, 0x64,
+	0x2d, 0x2e, 0x8f, 0xa7, 0x1c, 0x04, 0xb3, 0xbf, 0xc5, 0x70, 0xd5, 0x49,
+	0x1b, 0x77, 0x64, 0x58, 0x6e, 0xaf, 0x33, 0xdc, 0xbd, 0x40, 0x33, 0xb2,
+	0x4d, 0xf5, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+	0x35, 0xe3, 0xa8, 0x3d, 0x9d, 0x79, 0x2a, 0xa8, 0x5e, 0xb6, 0x8e, 0xa9,
+	0x73, 0x85, 0xfb, 0xe3, 0xcc, 0x3b, 0xf6, 0xb7, 0x91, 0xd7, 0x82, 0x0f,
+	0x53, 0x9e, 0x98, 0xd0, 0x0b, 0x57, 0x18, 0x65, 0xdc, 0xc8, 0x13, 0x13,
+	0x2f, 0xdc, 0x47, 0x3e, 0x52, 0x40, 0x20, 0x14, 0xb8, 0xa3, 0xef, 0xf6,
+	0x93, 0x7b, 0x43, 0xd3, 0x30, 0x8e, 0x48, 0x85, 0x86, 0xd0, 0xac, 0xd5,
+	0xbb, 0x8e, 0x72, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x49, 0x2d, 0xc8, 0x61, 0xce, 0x07, 0x6e, 0x91, 0x1b, 0xed, 0x06, 0xac,
+	0xb5, 0xa5, 0x79, 0x7a, 0x80, 0x25, 0x4f, 0x8a, 0x10, 0xd2, 0xef, 0x33,
+	0x97, 0x66, 0x0e, 0x4f, 0xd1, 0xa3, 0x6b, 0x3e, 0x7d, 0xa6, 0xe9, 0x2f,
+	0x35, 0xaa, 0xee, 0xfe, 0xed, 0x65, 0x1c, 0x3f, 0x89, 0x08, 0xbd, 0xe5,
+	0x99, 0xed, 0x82, 0xc0, 0x14, 0xb0, 0xc8, 0xd7, 0x76, 0xd6, 0xd5, 0x2e,
+	0x23, 0x42, 0x44, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb,
+	0x49, 0xed, 0x49, 0xd7, 0x20, 0x06, 0x0e, 0x54, 0x5d, 0xae, 0xaa, 0x77,
+	0x53, 0x5d, 0x38, 0x1c, 0x02, 0x7b, 0x07, 0x4e, 0x2f, 0x84, 0x36, 0x83,
+	0xe1, 0xc5, 0x2f, 0x6c, 0x4f, 0x54, 0x94, 0x1d, 0xc5, 0xa9, 0x18, 0x83,
+	0x69, 0xbe, 0x08, 0xb0, 0xd8, 0xe8, 0x81, 0x44, 0x0f, 0xc0, 0x0b, 0x32,
+	0x5c, 0x14, 0x9a, 0x7f, 0x39, 0x77, 0x6c, 0xe6, 0x45, 0xab, 0xab, 0x75,
+	0x48, 0x39, 0xd3, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaf, 0xe2, 0xc9, 0x9e, 0x41, 0xc5, 0xad, 0x4e, 0x91, 0xbd, 0x0f, 0x74,
+	0x04, 0x97, 0x37, 0x24, 0x11, 0x0d, 0x39, 0x02, 0x70, 0x29, 0xce, 0x18,
+	0x31, 0x39, 0x96, 0x1a, 0xe4, 0xd8, 0xcd, 0x86, 0x20, 0x41, 0xf8, 0xf2,
+	0x65, 0x04, 0x09, 0xad, 0xf6, 0x03, 0x67, 0x47, 0x5c, 0x3a, 0xb7, 0xe7,
+	0x0c, 0xfa, 0xe7, 0xe4, 0x5f, 0xc5, 0x9d, 0x58, 0xa2, 0xa1, 0x41, 0x9d,
+	0xb0, 0x1d, 0xc2, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa8,
+	0xe5, 0x88, 0xb5, 0xf2, 0xd7, 0x71, 0x52, 0xe1, 0x94, 0xf5, 0xe2, 0x1e,
+	0x3d, 0x65, 0x7a, 0x29, 0x91, 0xbe, 0x93, 0xd9, 0xb2, 0x9b, 0xea, 0xa5,
+	0x8c, 0xcc, 0xd4, 0x2c, 0xe4, 0x96, 0xf3, 0x7a, 0xbf, 0x29, 0x5a, 0x89,
+	0x7c, 0xc5, 0xff, 0xc9, 0x38, 0x64, 0xd8, 0x5e, 0xd8, 0xe3, 0x06, 0x5a,
+	0xe1, 0x35, 0xda, 0x88, 0x59, 0x3c, 0xc5, 0x50, 0xd2, 0xe2, 0x1f, 0x06,
+	0xa2, 0xac, 0xff, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9f, 0x12, 0xaf, 0x8f, 0xf1, 0x27, 0x32, 0x22, 0x13, 0xd3, 0x23, 0xa3,
+	0xc7, 0xb0, 0xbf, 0x6d, 0x7b, 0xbb, 0x66, 0x7d, 0xa8, 0x35, 0xd8, 0xea,
+	0xd3, 0x14, 0x5f, 0xdd, 0xb3, 0x0e, 0x21, 0x3c, 0xe1, 0xd3, 0x17, 0x0f,
+	0x86, 0x13, 0x38, 0x9c, 0x50, 0x37, 0x17, 0x64, 0x48, 0x12, 0x41, 0xf8,
+	0x53, 0x7c, 0x14, 0xdd, 0xc2, 0xae, 0x9d, 0xbe, 0x86, 0x81, 0x31, 0x96,
+	0x29, 0x64, 0x59, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,
+	0xa4, 0xf4, 0x01, 0x3e, 0x71, 0xb7, 0x6e, 0x68, 0x31, 0x86, 0x62, 0xbc,
+	0xf0, 0x1d, 0xcb, 0xa9, 0xd0, 0x55, 0xec, 0xb8, 0x18, 0xe8, 0x7f, 0x1f,
+	0xc7, 0xcc, 0xf5, 0xfa, 0xbc, 0xf1, 0x44, 0x74, 0x3a, 0x39, 0x90, 0x76,
+	0xf8, 0xa9, 0x58, 0x8a, 0x9f, 0x38, 0x62, 0x02, 0xa5, 0x38, 0x72, 0x4b,
+	0x15, 0x80, 0xc0, 0xbb, 0x18, 0x20, 0xa4, 0xdd, 0xed, 0xb8, 0x90, 0x86,
+	0xca, 0x8f, 0xdd, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf4, 0xab, 0xf8, 0x15, 0x29, 0x73, 0x14, 0x27, 0xf5, 0xb8, 0x6b, 0x12,
+	0xf9, 0xe4, 0x22, 0xc5, 0x4d, 0xd1, 0xa9, 0x71, 0x21, 0x97, 0xfd, 0x42,
+	0x02, 0x10, 0x34, 0x7f, 0x6f, 0xfd, 0x80, 0xff, 0x22, 0x5c, 0xd3, 0xa0,
+	0x7e, 0x37, 0x56, 0x30, 0xc2, 0x59, 0xfe, 0x53, 0xff, 0x95, 0x16, 0xb6,
+	0xc0, 0xb8, 0x01, 0x10, 0xa6, 0x89, 0xdb, 0x24, 0xc3, 0xbd, 0xce, 0xb5,
+	0x77, 0x0e, 0x1f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e,
+	0x0b, 0x89, 0x2f, 0x5c, 0xdd, 0x8c, 0x05, 0xb9, 0x41, 0x7c, 0x1a, 0xce,
+	0xbf, 0x23, 0x01, 0x0c, 0xe9, 0x74, 0x9c, 0x6c, 0xbb, 0xf7, 0xf7, 0x53,
+	0xfe, 0xc2, 0xd2, 0xe4, 0xb3, 0x3f, 0x5a, 0x06, 0x41, 0x02, 0x30, 0xdc,
+	0x2f, 0xa4, 0x1c, 0x6b, 0x29, 0x27, 0x10, 0x68, 0xa1, 0x8a, 0x14, 0x16,
+	0xab, 0xb9, 0xaf, 0xe4, 0x73, 0xb9, 0xec, 0x29, 0x72, 0xd9, 0x03, 0x5c,
+	0x26, 0x79, 0x2a, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x28, 0xff, 0x7b, 0xe0, 0xfc, 0x9e, 0x23, 0xd2, 0xf5, 0xe0, 0x7f, 0xef,
+	0xb8, 0x63, 0xa2, 0x40, 0x1b, 0x61, 0x96, 0xe4, 0x67, 0xcb, 0x5b, 0x0e,
+	0x30, 0xa9, 0xa3, 0x6b, 0x9e, 0xc2, 0xfb, 0xfc, 0x06, 0xef, 0x3f, 0x4e,
+	0xdf, 0x56, 0x80, 0x15, 0x72, 0x9b, 0xb1, 0x97, 0xc9, 0xf5, 0x26, 0x0b,
+	0x52, 0xb0, 0xb4, 0xfe, 0xb6, 0x04, 0x15, 0x86, 0x26, 0x51, 0xb3, 0x20,
+	0x63, 0xf1, 0x99, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x34,
+	0xdc, 0xfa, 0xf4, 0x3a, 0x05, 0xb6, 0x4e, 0xa9, 0x1d, 0xb7, 0x31, 0x9c,
+	0x19, 0x16, 0x32, 0xe8, 0x3a, 0x60, 0xe8, 0xab, 0x97, 0x7a, 0x9c, 0x9d,
+	0x85, 0x42, 0x8e, 0x55, 0xee, 0x3a, 0x97, 0x81, 0x71, 0xc3, 0x42, 0x1b,
+	0x5b, 0x6d, 0x51, 0xc0, 0x01, 0xed, 0x96, 0x12, 0x52, 0x56, 0x02, 0x26,
+	0x6c, 0xc1, 0xdb, 0xed, 0x90, 0x72, 0x2e, 0x36, 0xfa, 0xa6, 0x4f, 0x19,
+	0xc2, 0xc7, 0x0c, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static const struct fpm_entry fpm_table_scalar[CPT_EC_ID_PMAX] = {
+	{
+		.data = fpm_table_p192,
+		.len = sizeof(fpm_table_p192)
+	},
+	{
+		.data = fpm_table_p224,
+		.len = sizeof(fpm_table_p224)
+	},
+	{
+		.data = fpm_table_p256,
+		.len = sizeof(fpm_table_p256)
+	},
+	{
+		.data = fpm_table_p384,
+		.len = sizeof(fpm_table_p384)
+	},
+	{
+		.data = fpm_table_p521,
+		.len = sizeof(fpm_table_p521)
+	}
+};
+
+static rte_spinlock_t lock = RTE_SPINLOCK_INITIALIZER;
+static uint8_t *fpm_table;
+static int nb_devs;
+
+int cpt_fpm_init(uint64_t *fpm_table_iova)
+{
+	int i, len = 0;
+	uint8_t *data;
+
+	if (fpm_table_iova == NULL)
+		return -EINVAL;
+
+	rte_spinlock_lock(&lock);
+
+	if (nb_devs != 0)
+		goto update_nb_devs;
+
+	/* Compute FPM table size for all supported curves */
+	for (i = 0; i < CPT_EC_ID_PMAX; i++)
+		len += fpm_table_scalar[i].len;
+
+	/* Allocate shared FPM table */
+	fpm_table = rte_malloc(NULL, len, 0);
+
+	if (fpm_table == NULL) {
+		rte_spinlock_unlock(&lock);
+		return -ENOMEM;
+	}
+	data = fpm_table;
+
+	for (i = CPT_EC_ID_P192; i < CPT_EC_ID_PMAX; i++) {
+		memcpy(data, fpm_table_scalar[i].data, fpm_table_scalar[i].len);
+		/* Convert iova address to big endian to be used by cpt */
+		fpm_table_iova[i] = rte_cpu_to_be_64(rte_mem_virt2iova(data));
+
+		data = RTE_PTR_ADD(data, fpm_table_scalar[i].len);
+	}
+
+update_nb_devs:
+
+	/* Increment number of devices using FPM table */
+	nb_devs++;
+
+	rte_spinlock_unlock(&lock);
+
+	return 0;
+}
+
+void cpt_fpm_clear(void)
+{
+	rte_spinlock_lock(&lock);
+
+	/* Decrement number of devices using FPM table */
+	nb_devs--;
+	if ((nb_devs == 0) && (fpm_table != NULL))
+		rte_free(fpm_table);
+
+	rte_spinlock_unlock(&lock);
+}
diff --git a/drivers/common/cpt/cpt_mcode_defines.h b/drivers/common/cpt/cpt_mcode_defines.h
index f356e62..64d3e8c 100644
--- a/drivers/common/cpt/cpt_mcode_defines.h
+++ b/drivers/common/cpt/cpt_mcode_defines.h
@@ -23,12 +23,15 @@
 
 /* AE opcodes */
 #define CPT_MAJOR_OP_MODEX	0x03
+#define CPT_MAJOR_OP_ECDSA	0x04
 #define CPT_MINOR_OP_MODEX	0x01
 #define CPT_MINOR_OP_PKCS_ENC	0x02
 #define CPT_MINOR_OP_PKCS_ENC_CRT	0x03
 #define CPT_MINOR_OP_PKCS_DEC	0x04
 #define CPT_MINOR_OP_PKCS_DEC_CRT	0x05
 #define CPT_MINOR_OP_MODEX_CRT	0x06
+#define CPT_MINOR_OP_ECDSA_SIGN	0x01
+#define CPT_MINOR_OP_ECDSA_VERIFY	0x02
 
 #define CPT_BLOCK_TYPE1 0
 #define CPT_BLOCK_TYPE2 1
@@ -203,6 +206,20 @@ typedef enum {
 	CPT_8X_COMP_E_LAST_ENTRY = (0xFF)
 } cpt_comp_e_t;
 
+/**
+ * Enumeration cpt_ec_id
+ *
+ * Enumerates supported elliptic curves
+ */
+typedef enum {
+	CPT_EC_ID_P192 = 0,
+	CPT_EC_ID_P224 = 1,
+	CPT_EC_ID_P256 = 2,
+	CPT_EC_ID_P384 = 3,
+	CPT_EC_ID_P521 = 4,
+	CPT_EC_ID_PMAX = 5
+} cpt_ec_id_t;
+
 typedef struct sglist_comp {
 	union {
 		uint64_t len;
@@ -329,11 +346,32 @@ struct cpt_ctx {
 	uint8_t  auth_key[64];
 };
 
+/* Prime and order fields of built-in elliptic curves */
+struct cpt_ec_group {
+	struct {
+		/* P521 maximum length */
+		uint8_t data[66];
+		unsigned int length;
+	} prime;
+
+	struct {
+		/* P521 maximum length */
+		uint8_t data[66];
+		unsigned int length;
+	} order;
+};
+
+struct cpt_asym_ec_ctx {
+	/* Prime length defined by microcode for EC operations */
+	uint8_t curveid;
+};
+
 struct cpt_asym_sess_misc {
 	enum rte_crypto_asym_xform_type xfrm_type;
 	union {
 		struct rte_crypto_rsa_xform rsa_ctx;
 		struct rte_crypto_modex_xform mod_ctx;
+		struct cpt_asym_ec_ctx ec_ctx;
 	};
 };
 
diff --git a/drivers/common/cpt/cpt_pmd_ops_helper.h b/drivers/common/cpt/cpt_pmd_ops_helper.h
index 24c3559..716ae94 100644
--- a/drivers/common/cpt/cpt_pmd_ops_helper.h
+++ b/drivers/common/cpt/cpt_pmd_ops_helper.h
@@ -40,4 +40,23 @@ cpt_pmd_ops_helper_get_mlen_sg_mode(void);
  */
 int
 cpt_pmd_ops_helper_asym_get_mlen(void);
+
+/*
+ * Initialize ECC FMUL precomputed table
+ *
+ * @param
+ *  - pointer to fpm_table iova address
+ *
+ * @return
+ *  - 0 on success, negative on error
+ */
+__rte_experimental
+int cpt_fpm_init(uint64_t *fpm_table_iova);
+
+/*
+ * Clear ECC FMUL precomputed table
+ */
+__rte_experimental
+void cpt_fpm_clear(void);
+
 #endif /* _CPT_PMD_OPS_HELPER_H_ */
diff --git a/drivers/common/cpt/cpt_ucode_asym.h b/drivers/common/cpt/cpt_ucode_asym.h
index 00e01b5..1f76bd1 100644
--- a/drivers/common/cpt/cpt_ucode_asym.h
+++ b/drivers/common/cpt/cpt_ucode_asym.h
@@ -126,6 +126,37 @@ cpt_fill_rsa_params(struct cpt_asym_sess_misc *sess,
 }
 
 static __rte_always_inline int
+cpt_fill_ec_params(struct cpt_asym_sess_misc *sess,
+		      struct rte_crypto_asym_xform *xform)
+{
+	struct cpt_asym_ec_ctx *ec = &sess->ec_ctx;
+
+	switch (xform->ec.curve_id) {
+	case RTE_CRYPTO_EC_GROUP_NISTP192:
+		ec->curveid = CPT_EC_ID_P192;
+		break;
+	case RTE_CRYPTO_EC_GROUP_NISTP224:
+		ec->curveid = CPT_EC_ID_P224;
+		break;
+	case RTE_CRYPTO_EC_GROUP_NISTP256:
+		ec->curveid = CPT_EC_ID_P256;
+		break;
+	case RTE_CRYPTO_EC_GROUP_NISTP384:
+		ec->curveid = CPT_EC_ID_P384;
+		break;
+	case RTE_CRYPTO_EC_GROUP_NISTP521:
+		ec->curveid = CPT_EC_ID_P521;
+		break;
+	default:
+		/* Only NIST curves (FIPS 186-4) are supported */
+		CPT_LOG_DP_ERR("Unsupported curve");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static __rte_always_inline int
 cpt_fill_asym_session_parameters(struct cpt_asym_sess_misc *sess,
 				 struct rte_crypto_asym_xform *xform)
 {
@@ -140,6 +171,9 @@ cpt_fill_asym_session_parameters(struct cpt_asym_sess_misc *sess,
 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
 		ret = cpt_fill_modex_params(sess, xform);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		ret = cpt_fill_ec_params(sess, xform);
+		break;
 	default:
 		CPT_LOG_DP_ERR("Unsupported transform type");
 		return -ENOTSUP;
@@ -164,6 +198,8 @@ cpt_free_asym_session_parameters(struct cpt_asym_sess_misc *sess)
 		if (mod->modulus.data)
 			rte_free(mod->modulus.data);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		break;
 	default:
 		CPT_LOG_DP_ERR("Invalid transform type");
 		break;
@@ -450,4 +486,346 @@ cpt_enqueue_rsa_op(struct rte_crypto_op *op,
 	}
 	return 0;
 }
+
+static const struct cpt_ec_group ec_grp[CPT_EC_ID_PMAX] = {
+	{
+		.prime = {
+			.data =	{
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+			},
+			.length = 24,
+		},
+		.order = {
+			.data = {
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36,
+				0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31
+			},
+			.length = 24
+		},
+	},
+	{
+		.prime = {
+			.data = {
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x01
+			},
+			.length = 28
+		},
+		.order = {
+			.data = {
+				0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
+				0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X16, 0XA2,
+				0XE0, 0XB8, 0XF0, 0X3E, 0X13, 0XDD, 0X29, 0X45,
+				0X5C, 0X5C, 0X2A, 0X3D
+			},
+			.length = 28
+		},
+	},
+	{
+		.prime = {
+			.data = {
+				0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+			},
+			.length = 32
+		},
+		.order = {
+			.data = {
+				0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
+				0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
+			},
+			.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, 0xFF, 0xFF, 0xFF, 0xFE,
+				0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
+			},
+			.length = 48
+		},
+		.order = {
+			.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,
+				0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF,
+				0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
+				0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
+			},
+			.length = 48
+		}
+	},
+	{
+		.prime = {
+			.data = {
+				0x01, 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, 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, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF
+			},
+			.length = 66
+		},
+		.order = {
+			.data = {
+				0x01, 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, 0xFF,
+				0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
+				0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
+				0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,
+				0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
+				0x64, 0x09
+			},
+			.length = 66
+		}
+	}
+};
+
+static __rte_always_inline void
+cpt_ecdsa_sign_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
+		    struct asym_op_params *ecdsa_params,
+		    uint64_t fpm_table_iova,
+		    uint8_t curveid)
+{
+	struct cpt_request_info *req = ecdsa_params->req;
+	uint16_t message_len = ecdsa->message.length;
+	phys_addr_t mphys = ecdsa_params->meta_buf;
+	uint16_t pkey_len = ecdsa->pkey.length;
+	uint16_t p_align, k_align, m_align;
+	uint16_t k_len = ecdsa->k.length;
+	uint16_t order_len, prime_len;
+	uint16_t o_offset, pk_offset;
+	vq_cmd_word0_t vq_cmd_w0;
+	opcode_info_t opcode;
+	uint16_t rlen, dlen;
+	buf_ptr_t caddr;
+	uint8_t *dptr;
+
+	prime_len = ec_grp[curveid].prime.length;
+	order_len = ec_grp[curveid].order.length;
+
+	/* Truncate input length to curve prime length */
+	if (message_len > prime_len)
+		message_len = prime_len;
+	m_align = ROUNDUP8(message_len);
+
+	p_align = ROUNDUP8(prime_len);
+	k_align = ROUNDUP8(k_len);
+
+	/* Set write offset for order and private key */
+	o_offset = prime_len - order_len;
+	pk_offset = prime_len - pkey_len;
+
+	/* Input buffer */
+	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(scalar len, input len),
+	 * ROUNDUP8(priv key len, prime len, order len)).
+	 * Please note, private key, order cannot exceed prime
+	 * length i.e 3 * p_align.
+	 */
+	dlen = sizeof(fpm_table_iova) + k_align + m_align + p_align * 3;
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr, ecdsa->k.data, k_len);
+	dptr += k_align;
+
+	memcpy(dptr, ec_grp[curveid].prime.data, prime_len);
+	dptr += p_align;
+
+	memcpy(dptr + o_offset, ec_grp[curveid].order.data, order_len);
+	dptr += p_align;
+
+	memcpy(dptr + pk_offset, ecdsa->pkey.data, pkey_len);
+	dptr += p_align;
+
+	memcpy(dptr, ecdsa->message.data, message_len);
+	dptr += m_align;
+
+	/* 2 * prime length (for sign r and s ) */
+	rlen = 2 * p_align;
+
+	/* Setup opcodes */
+	opcode.s.major = CPT_MAJOR_OP_ECDSA;
+	opcode.s.minor = CPT_MINOR_OP_ECDSA_SIGN;
+	vq_cmd_w0.s.opcode = opcode.flags;
+
+	/* GP op header */
+	vq_cmd_w0.s.param1 = curveid | (message_len << 8);
+	vq_cmd_w0.s.param2 = k_len;
+	vq_cmd_w0.s.dlen = dlen;
+
+	/* Filling cpt_request_info structure */
+	req->ist.ei0 = vq_cmd_w0.u64;
+	req->ist.ei1 = mphys;
+	req->ist.ei2 = mphys + dlen;
+
+	/* Result pointer to store result data */
+	req->rptr = dptr;
+
+	/* alternate_caddr to write completion status of the microcode */
+	req->alternate_caddr = (uint64_t *)(dptr + rlen);
+	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
+
+	/* Preparing completion addr, +1 for completion code */
+	caddr.vaddr = dptr + rlen + 1;
+	caddr.dma_addr = mphys + dlen + rlen + 1;
+
+	cpt_fill_req_comp_addr(req, caddr);
+}
+
+static __rte_always_inline void
+cpt_ecdsa_verify_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
+		      struct asym_op_params *ecdsa_params,
+		      uint64_t fpm_table_iova,
+		      uint8_t curveid)
+{
+	struct cpt_request_info *req = ecdsa_params->req;
+	uint32_t message_len = ecdsa->message.length;
+	phys_addr_t mphys = ecdsa_params->meta_buf;
+	uint16_t o_offset, r_offset, s_offset;
+	uint16_t qx_len = ecdsa->q.x.length;
+	uint16_t qy_len = ecdsa->q.y.length;
+	uint16_t r_len = ecdsa->r.length;
+	uint16_t s_len = ecdsa->s.length;
+	uint16_t order_len, prime_len;
+	uint16_t qx_offset, qy_offset;
+	uint16_t p_align, m_align;
+	vq_cmd_word0_t vq_cmd_w0;
+	opcode_info_t opcode;
+	buf_ptr_t caddr;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	prime_len = ec_grp[curveid].prime.length;
+	order_len = ec_grp[curveid].order.length;
+
+	/* Truncate input length to curve prime length */
+	if (message_len > prime_len)
+		message_len = prime_len;
+
+	m_align = ROUNDUP8(message_len);
+	p_align = ROUNDUP8(prime_len);
+
+	/* Set write offset for sign, order and public key coordinates */
+	o_offset = prime_len - order_len;
+	qx_offset = prime_len - qx_len;
+	qy_offset = prime_len - qy_len;
+	r_offset = prime_len - r_len;
+	s_offset = prime_len - s_len;
+
+	/* Input buffer */
+	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(message len),
+	 * ROUNDUP8(sign len(r and s), public key len(x and y coordinates),
+	 * prime len, order len)).
+	 * Please note sign, public key and order can not excede prime length
+	 * i.e. 6 * p_align
+	 */
+	dlen = sizeof(fpm_table_iova) + m_align + (6 * p_align);
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr + r_offset, ecdsa->r.data, r_len);
+	dptr += p_align;
+
+	memcpy(dptr + s_offset, ecdsa->s.data, s_len);
+	dptr += p_align;
+
+	memcpy(dptr, ecdsa->message.data, message_len);
+	dptr += m_align;
+
+	memcpy(dptr + o_offset, ec_grp[curveid].order.data, order_len);
+	dptr += p_align;
+
+	memcpy(dptr, ec_grp[curveid].prime.data, prime_len);
+	dptr += p_align;
+
+	memcpy(dptr + qx_offset, ecdsa->q.x.data, qx_len);
+	dptr += p_align;
+
+	memcpy(dptr + qy_offset, ecdsa->q.y.data, qy_len);
+	dptr += p_align;
+
+	/* Setup opcodes */
+	opcode.s.major = CPT_MAJOR_OP_ECDSA;
+	opcode.s.minor = CPT_MINOR_OP_ECDSA_VERIFY;
+	vq_cmd_w0.s.opcode = opcode.flags;
+
+	/* GP op header */
+	vq_cmd_w0.s.param1 = curveid | (message_len << 8);
+	vq_cmd_w0.s.param2 = 0;
+	vq_cmd_w0.s.dlen = dlen;
+
+	/* Filling cpt_request_info structure */
+	req->ist.ei0 = vq_cmd_w0.u64;
+	req->ist.ei1 = mphys;
+	req->ist.ei2 = mphys + dlen;
+
+	/* Result pointer to store result data */
+	req->rptr = dptr;
+
+	/* alternate_caddr to write completion status of the microcode */
+	req->alternate_caddr = (uint64_t *)dptr;
+	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
+
+	/* Preparing completion addr, +1 for completion code */
+	caddr.vaddr = dptr + 1;
+	caddr.dma_addr = mphys + dlen + 1;
+
+	cpt_fill_req_comp_addr(req, caddr);
+}
+
+static __rte_always_inline int __hot
+cpt_enqueue_ecdsa_op(struct rte_crypto_op *op,
+		     struct asym_op_params *params,
+		     struct cpt_asym_sess_misc *sess,
+		     uint64_t *fpm_iova)
+{
+	struct rte_crypto_ecdsa_op_param *ecdsa = &op->asym->ecdsa;
+	uint8_t curveid = sess->ec_ctx.curveid;
+
+	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+		cpt_ecdsa_sign_prep(ecdsa, params, fpm_iova[curveid], curveid);
+	else if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		cpt_ecdsa_verify_prep(ecdsa, params, fpm_iova[curveid],
+				      curveid);
+	else {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+	return 0;
+}
+
 #endif /* _CPT_UCODE_ASYM_H_ */
diff --git a/drivers/common/cpt/meson.build b/drivers/common/cpt/meson.build
index 0a905aa..d2e84ff 100644
--- a/drivers/common/cpt/meson.build
+++ b/drivers/common/cpt/meson.build
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Cavium, Inc
 
-sources = files('cpt_pmd_ops_helper.c')
+sources = files('cpt_fpm_tables.c',
+		'cpt_pmd_ops_helper.c')
 
 deps = ['kvargs', 'pci', 'cryptodev']
 includes += include_directories('../../crypto/octeontx')
diff --git a/drivers/common/cpt/rte_common_cpt_version.map b/drivers/common/cpt/rte_common_cpt_version.map
index 7f1929d..8c65cde 100644
--- a/drivers/common/cpt/rte_common_cpt_version.map
+++ b/drivers/common/cpt/rte_common_cpt_version.map
@@ -7,3 +7,12 @@ DPDK_20.0 {
 
 	local: *;
 };
+
+EXPERIMENTAL {
+	global:
+
+	cpt_fpm_clear;
+	cpt_fpm_init;
+
+	local: *;
+};
diff --git a/drivers/crypto/octeontx/otx_cryptodev_capabilities.c b/drivers/crypto/octeontx/otx_cryptodev_capabilities.c
index 8c0358f..6418ad2 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_capabilities.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_capabilities.c
@@ -630,6 +630,17 @@ static const struct rte_cryptodev_capabilities otx_asym_capabilities[] = {
 			}
 		}, }
 	},
+	{	/* ECDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+				}
+			},
+		}
+	},
 	/* End of asymmetric capabilities */
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
diff --git a/drivers/crypto/octeontx/otx_cryptodev_ops.c b/drivers/crypto/octeontx/otx_cryptodev_ops.c
index ba56b21..f97ce3a 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_ops.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_ops.c
@@ -17,9 +17,12 @@
 #include "otx_cryptodev_ops.h"
 
 #include "cpt_pmd_logs.h"
+#include "cpt_pmd_ops_helper.h"
 #include "cpt_ucode.h"
 #include "cpt_ucode_asym.h"
 
+static uint64_t otx_fpm_iova[CPT_EC_ID_PMAX];
+
 /* Forward declarations */
 
 static int
@@ -52,11 +55,18 @@ otx_cpt_periodic_alarm_stop(void *arg)
 /* PMD ops */
 
 static int
-otx_cpt_dev_config(struct rte_cryptodev *dev __rte_unused,
+otx_cpt_dev_config(struct rte_cryptodev *dev,
 		   struct rte_cryptodev_config *config __rte_unused)
 {
+	int ret = 0;
+
 	CPT_PMD_INIT_FUNC_TRACE();
-	return 0;
+
+	if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)
+		/* Initialize shared FPM table */
+		ret = cpt_fpm_init(otx_fpm_iova);
+
+	return ret;
 }
 
 static int
@@ -76,6 +86,9 @@ otx_cpt_dev_stop(struct rte_cryptodev *c_dev)
 
 	CPT_PMD_INIT_FUNC_TRACE();
 
+	if (c_dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)
+		cpt_fpm_clear();
+
 	otx_cpt_stop_device(cptvf);
 }
 
@@ -425,6 +438,11 @@ otx_cpt_enq_single_asym(struct cpt_instance *instance,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		ret = cpt_enqueue_ecdsa_op(op, &params, sess, otx_fpm_iova);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	default:
 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
 		ret = -EINVAL;
@@ -668,6 +686,24 @@ otx_cpt_asym_rsa_op(struct rte_crypto_op *cop, struct cpt_request_info *req,
 	}
 }
 
+static __rte_always_inline void
+otx_cpt_asym_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa,
+			    struct cpt_request_info *req,
+			    struct cpt_asym_ec_ctx *ec)
+
+{
+	int prime_len = ec_grp[ec->curveid].prime.length;
+
+	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	memcpy(ecdsa->r.data, req->rptr, prime_len);
+	memcpy(ecdsa->s.data, req->rptr + ROUNDUP8(prime_len), prime_len);
+	ecdsa->r.length = prime_len;
+	ecdsa->s.length = prime_len;
+}
+
 static __rte_always_inline void __hot
 otx_cpt_asym_post_process(struct rte_crypto_op *cop,
 			  struct cpt_request_info *req)
@@ -687,6 +723,9 @@ otx_cpt_asym_post_process(struct rte_crypto_op *cop,
 		memcpy(op->modex.result.data, req->rptr,
 		       op->modex.result.length);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		otx_cpt_asym_dequeue_ecdsa_op(&op->ecdsa, req, &sess->ec_ctx);
+		break;
 	default:
 		CPT_LOG_DP_DEBUG("Invalid crypto xform type");
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
-- 
2.7.4


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

* [dpdk-dev] [PATCH 3/4] crypto/octeontx2: add ECDSA support
  2019-12-05 11:43 [dpdk-dev] [PATCH 0/4] add ECDSA support Anoob Joseph
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA Anoob Joseph
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 2/4] crypto/octeontx: add ECDSA support Anoob Joseph
@ 2019-12-05 11:43 ` Anoob Joseph
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 4/4] app/test: add ECDSA sign/verify tests Anoob Joseph
  2020-01-15 12:43 ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Anoob Joseph
  4 siblings, 0 replies; 19+ messages in thread
From: Anoob Joseph @ 2019-12-05 11:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Sunila Sahu, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, dev, Anoob Joseph,
	Balakrishna Bhamidipati

From: Sunila Sahu <ssahu@marvell.com>

Adding support for ECDSA operations in crypto_octeontx2 PMD.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Balakrishna Bhamidipati <bbhamidipati@marvell.com>
Signed-off-by: Sunila Sahu <ssahu@marvell.com>
---
 doc/guides/cryptodevs/features/octeontx2.ini       |  8 +++--
 .../crypto/octeontx2/otx2_cryptodev_capabilities.c | 11 ++++++
 drivers/crypto/octeontx2/otx2_cryptodev_ops.c      | 39 ++++++++++++++++++++--
 3 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/doc/guides/cryptodevs/features/octeontx2.ini b/doc/guides/cryptodevs/features/octeontx2.ini
index 7d07053..dd6369b 100644
--- a/doc/guides/cryptodevs/features/octeontx2.ini
+++ b/doc/guides/cryptodevs/features/octeontx2.ini
@@ -67,5 +67,9 @@ AES GCM (256) = Y
 ; Supported Asymmetric algorithms of the 'octeontx2' crypto driver.
 ;
 [Asymmetric]
-RSA                    = Y
-Modular Exponentiation = Y
+RSA                     = Y
+DSA                     =
+Modular Exponentiation  = Y
+Modular Inversion       =
+Diffie-hellman          =
+ECDSA                   = Y
diff --git a/drivers/crypto/octeontx2/otx2_cryptodev_capabilities.c b/drivers/crypto/octeontx2/otx2_cryptodev_capabilities.c
index b9e3fe3..f2079e2 100644
--- a/drivers/crypto/octeontx2/otx2_cryptodev_capabilities.c
+++ b/drivers/crypto/octeontx2/otx2_cryptodev_capabilities.c
@@ -628,6 +628,17 @@ rte_cryptodev_capabilities otx2_cpt_capabilities[] = {
 			}
 		}, }
 	},
+	{	/* ECDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+				}
+			},
+		}
+	},
 	/* End of asymmetric capabilities */
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
diff --git a/drivers/crypto/octeontx2/otx2_cryptodev_ops.c b/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
index 65101b0..17c755d 100644
--- a/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
+++ b/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
@@ -22,6 +22,8 @@
 
 #define METABUF_POOL_CACHE_SIZE	512
 
+static uint64_t otx2_fpm_iova[CPT_EC_ID_PMAX];
+
 /* Forward declarations */
 
 static int
@@ -440,6 +442,11 @@ otx2_cpt_enqueue_asym(struct otx2_cpt_qp *qp,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		ret = cpt_enqueue_ecdsa_op(op, &params, sess, otx2_fpm_iova);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	default:
 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
 		ret = -EINVAL;
@@ -641,6 +648,23 @@ otx2_cpt_asym_rsa_op(struct rte_crypto_op *cop, struct cpt_request_info *req,
 	}
 }
 
+static __rte_always_inline void
+otx2_cpt_asym_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa,
+			       struct cpt_request_info *req,
+			       struct cpt_asym_ec_ctx *ec)
+{
+	int prime_len = ec_grp[ec->curveid].prime.length;
+
+	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	memcpy(ecdsa->r.data, req->rptr, prime_len);
+	memcpy(ecdsa->s.data, req->rptr + ROUNDUP8(prime_len), prime_len);
+	ecdsa->r.length = prime_len;
+	ecdsa->s.length = prime_len;
+}
+
 static void
 otx2_cpt_asym_post_process(struct rte_crypto_op *cop,
 			   struct cpt_request_info *req)
@@ -660,6 +684,9 @@ otx2_cpt_asym_post_process(struct rte_crypto_op *cop,
 		memcpy(op->modex.result.data, req->rptr,
 		       op->modex.result.length);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		otx2_cpt_asym_dequeue_ecdsa_op(&op->ecdsa, req, &sess->ec_ctx);
+		break;
 	default:
 		CPT_LOG_DP_DEBUG("Invalid crypto xform type");
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
@@ -824,6 +851,13 @@ otx2_cpt_dev_config(struct rte_cryptodev *dev,
 
 	dev->feature_flags &= ~conf->ff_disable;
 
+	if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) {
+		/* Initialize shared FPM table */
+		ret = cpt_fpm_init(otx2_fpm_iova);
+		if (ret)
+			return ret;
+	}
+
 	/* Unregister error interrupts */
 	if (vf->err_intr_registered)
 		otx2_cpt_err_intr_unregister(dev);
@@ -881,9 +915,10 @@ otx2_cpt_dev_start(struct rte_cryptodev *dev)
 static void
 otx2_cpt_dev_stop(struct rte_cryptodev *dev)
 {
-	RTE_SET_USED(dev);
-
 	CPT_PMD_INIT_FUNC_TRACE();
+
+	if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)
+		cpt_fpm_clear();
 }
 
 static int
-- 
2.7.4


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

* [dpdk-dev] [PATCH 4/4] app/test: add ECDSA sign/verify tests
  2019-12-05 11:43 [dpdk-dev] [PATCH 0/4] add ECDSA support Anoob Joseph
                   ` (2 preceding siblings ...)
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 3/4] crypto/octeontx2: " Anoob Joseph
@ 2019-12-05 11:43 ` Anoob Joseph
  2020-01-15 12:43 ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Anoob Joseph
  4 siblings, 0 replies; 19+ messages in thread
From: Anoob Joseph @ 2019-12-05 11:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Ayuj Verma, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, Sunila Sahu, dev,
	Anoob Joseph

From: Ayuj Verma <ayverma@marvell.com>

This patch adds ECDSA sign and verify test routine and test vectors.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Ayuj Verma <ayverma@marvell.com>
Signed-off-by: Sunila Sahu <ssahu@marvell.com>
---
 app/test/test_cryptodev_asym.c               | 219 +++++++++++-
 app/test/test_cryptodev_asym_util.h          |  11 +
 app/test/test_cryptodev_ecdsa_test_vectors.h | 501 +++++++++++++++++++++++++++
 3 files changed, 730 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_cryptodev_ecdsa_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index 69df293..b913a7d 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -18,6 +18,7 @@
 #include "test_cryptodev.h"
 #include "test_cryptodev_dh_test_vectors.h"
 #include "test_cryptodev_dsa_test_vectors.h"
+#include "test_cryptodev_ecdsa_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_asym_util.h"
@@ -1037,14 +1038,16 @@ static inline void print_asym_capa(
 		case RTE_CRYPTO_ASYM_XFORM_MODEX:
 		case RTE_CRYPTO_ASYM_XFORM_DH:
 		case RTE_CRYPTO_ASYM_XFORM_DSA:
-			printf(" modlen: min %d max %d increment %d\n",
+			printf(" modlen: min %d max %d increment %d",
 					capa->modlen.min,
 					capa->modlen.max,
 					capa->modlen.increment);
 		break;
+		case RTE_CRYPTO_ASYM_XFORM_ECDSA:
 		default:
 			break;
 		}
+		printf("\n");
 }
 
 static int
@@ -1892,6 +1895,218 @@ test_dsa(void)
 	return status;
 }
 
+static int
+test_ecdsa_sign_verify(enum curve curve_id)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct crypto_testsuite_ecdsa_params input_params;
+	struct rte_cryptodev_asym_session *sess = NULL;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	uint8_t output_buf_s[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int status = TEST_SUCCESS, ret;
+
+	switch (curve_id) {
+	case P192:
+		input_params = ecdsa_param_p192;
+		break;
+	case P224:
+		input_params = ecdsa_param_p224;
+		break;
+	case P256:
+		input_params = ecdsa_param_p256;
+		break;
+	case P384:
+		input_params = ecdsa_param_p384;
+		break;
+	case P521:
+		input_params = ecdsa_param_p521;
+		break;
+	default:
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Unsupported curve id\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	sess = rte_cryptodev_asym_session_create(sess_mpool);
+	if (sess == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	/* 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_ECDSA;
+	xform.ec.curve_id = input_params.curve;
+
+	if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
+				sess_mpool) < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Unable to config asym session\n");
+		status = 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 */
+	op->asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	op->asym->ecdsa.message.data = input_params.digest.data;
+	op->asym->ecdsa.message.length = input_params.digest.length;
+	op->asym->ecdsa.k.data = input_params.scalar.data;
+	op->asym->ecdsa.k.length = input_params.scalar.length;
+	op->asym->ecdsa.pkey.data = input_params.pkey.data;
+	op->asym->ecdsa.pkey.length = input_params.pkey.length;
+
+	/* Init out buf */
+	op->asym->ecdsa.r.data = output_buf_r;
+	op->asym->ecdsa.s.data = output_buf_s;
+
+	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");
+		status = TEST_FAILED;
+		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");
+		status = TEST_FAILED;
+		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");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "r:",
+			asym_op->ecdsa.r.data, asym_op->ecdsa.r.length);
+	debug_hexdump(stdout, "s:",
+			asym_op->ecdsa.s.data, asym_op->ecdsa.s.length);
+
+	ret = verify_ecdsa_sign(input_params.sign_r.data,
+				input_params.sign_s.data, result_op);
+	if (ret) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"ECDSA sign failed.\n");
+		goto exit;
+	}
+
+	/* Verify sign */
+
+	/* Populate op with operational details */
+	op->asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	op->asym->ecdsa.q.x.data = input_params.pubkey_qx.data;
+	op->asym->ecdsa.q.x.length = input_params.pubkey_qx.length;
+	op->asym->ecdsa.q.y.data = input_params.pubkey_qy.data;
+	op->asym->ecdsa.q.y.length = input_params.pubkey_qx.length;
+	op->asym->ecdsa.r.data = asym_op->ecdsa.r.data;
+	op->asym->ecdsa.r.length = asym_op->ecdsa.r.length;
+	op->asym->ecdsa.s.data = asym_op->ecdsa.s.data;
+	op->asym->ecdsa.s.length = asym_op->ecdsa.s.length;
+
+	/* Enqueue sign result for verify */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		status = TEST_FAILED;
+		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) {
+		status = TEST_FAILED;
+		goto exit;
+	}
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"ECDSA verify failed.\n");
+		goto exit;
+	}
+
+exit:
+	if (sess != NULL) {
+		rte_cryptodev_asym_session_clear(dev_id, sess);
+		rte_cryptodev_asym_session_free(sess);
+	}
+	if (op != NULL)
+		rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_ecdsa_sign_verify_all_curve(void)
+{
+	int status, overall_status = TEST_SUCCESS;
+	enum curve curve_id;
+	int test_index = 0;
+	const char *msg;
+
+	for (curve_id = P192; curve_id < END_OF_CURVE_LIST; curve_id++) {
+		status = test_ecdsa_sign_verify(curve_id);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Sign/Veriy Curve %s  %s\n",
+		       test_index ++, curve[curve_id], msg);
+	}
+	return overall_status;
+}
 
 static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 	.suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite",
@@ -1931,6 +2146,8 @@ static struct unit_test_suite cryptodev_octeontx_asym_testsuite  = {
 		TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_enc_dec_crt),
 		TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_sign_verify_crt),
 		TEST_CASE_ST(ut_setup, ut_teardown, test_mod_exp),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			     test_ecdsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_asym_util.h b/app/test/test_cryptodev_asym_util.h
index f2a8e6c..bddeda0 100644
--- a/app/test/test_cryptodev_asym_util.h
+++ b/app/test/test_cryptodev_asym_util.h
@@ -35,4 +35,15 @@ static inline int verify_modexp(uint8_t *mod_exp,
 	return 0;
 }
 
+static inline int verify_ecdsa_sign(uint8_t *sign_r,
+		uint8_t *sign_s, struct rte_crypto_op *result_op)
+{
+	if (memcmp(sign_r, result_op->asym->ecdsa.r.data,
+		   result_op->asym->ecdsa.r.length) ||
+		   memcmp(sign_s, result_op->asym->ecdsa.s.data,
+		   result_op->asym->ecdsa.s.length))
+		return -1;
+	return 0;
+}
+
 #endif /* TEST_CRYPTODEV_ASYM_TEST_UTIL_H__ */
diff --git a/app/test/test_cryptodev_ecdsa_test_vectors.h b/app/test/test_cryptodev_ecdsa_test_vectors.h
new file mode 100644
index 0000000..a53c0e9
--- /dev/null
+++ b/app/test/test_cryptodev_ecdsa_test_vectors.h
@@ -0,0 +1,501 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2019 Marvell International Ltd.
+ */
+
+#ifndef __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+struct crypto_testsuite_ecdsa_params {
+	rte_crypto_param pubkey_qx;
+	rte_crypto_param pubkey_qy;
+	rte_crypto_param scalar;
+	rte_crypto_param digest;
+	rte_crypto_param sign_r;
+	rte_crypto_param sign_s;
+	rte_crypto_param pkey;
+	int curve;
+};
+
+/* ECDSA curve id */
+enum curve {
+	P192,
+	P224,
+	P256,
+	P384,
+	P521,
+	END_OF_CURVE_LIST
+};
+
+const char *curve[] = {"P192", "P224", "P256", "P384", "P521"};
+
+/*
+ * Test vector reference:
+ * https://csrc.nist.gov/CSRC/media/Projects/
+ * Cryptographic-Algorithm-Validation-Program/
+ * documents/components/186-3ecdsasiggencomponenttestvectors.zip
+ */
+
+/* P-192 NIST test vector */
+
+static uint8_t digest_p192[] = {
+	0x5a, 0xe8, 0x31, 0x7d, 0x34, 0xd1, 0xe5, 0x95,
+	0xe3, 0xfa, 0x72, 0x47, 0xdb, 0x80, 0xc0, 0xaf,
+	0x43, 0x20, 0xcc, 0xe1, 0x11, 0x6d, 0xe1, 0x87,
+	0xf8, 0xf7, 0xe2, 0xe0, 0x99, 0xc0, 0xd8, 0xd0
+};
+
+static uint8_t pkey_p192[] = {
+	0x24, 0xed, 0xd2, 0x2f, 0x7d, 0xdd, 0x6f, 0xa5,
+	0xbc, 0x61, 0xfc, 0x06, 0x53, 0x47, 0x9a, 0xa4,
+	0x08, 0x09, 0xef, 0x86, 0x5c, 0xf2, 0x7a, 0x47
+};
+
+static uint8_t scalar_p192[] = {
+	0xa5, 0xc8, 0x17, 0xa2, 0x36, 0xa5, 0xf7, 0xfa,
+	0xa3, 0x29, 0xb8, 0xec, 0xc3, 0xc5, 0x96, 0x68,
+	0x7c, 0x71, 0xaa, 0xaf, 0x86, 0xc7, 0x70, 0x3e
+};
+
+static uint8_t pubkey_qx_p192[] = {
+	0x9b, 0xf1, 0x2d, 0x71, 0x74, 0xb7, 0x70, 0x8a,
+	0x07, 0x6a, 0x38, 0xbc, 0x80, 0xaa, 0x28, 0x66,
+	0x2f, 0x25, 0x1e, 0x2e, 0xd8, 0xd4, 0x14, 0xdc
+};
+
+static uint8_t pubkey_qy_p192[] = {
+	0x48, 0x54, 0xc8, 0xd0, 0x7d, 0xfc, 0x08, 0x82,
+	0x4e, 0x9e, 0x47, 0x1c, 0xa2, 0xfe, 0xdc, 0xfc,
+	0xff, 0x3d, 0xdc, 0xb0, 0x11, 0x57, 0x34, 0x98
+};
+
+static uint8_t sign_p192_r[] = {
+	0x35, 0x4a, 0xba, 0xec, 0xf4, 0x36, 0x1f, 0xea,
+	0x90, 0xc2, 0x9b, 0x91, 0x99, 0x88, 0x2e, 0xdf,
+	0x85, 0x73, 0xe6, 0x86, 0xa8, 0x13, 0xef, 0xf8
+};
+
+static uint8_t sign_p192_s[] = {
+	0x80, 0xf5, 0x00, 0x00, 0xac, 0x86, 0x11, 0x1c,
+	0x9b, 0x30, 0x47, 0x38, 0x5a, 0x15, 0xd7, 0x8e,
+	0x63, 0x2c, 0x58, 0xb7, 0x94, 0x9e, 0x82, 0xc1
+};
+
+/** ECDSA P192 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_p192 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_p192,
+		.length = sizeof(pubkey_qx_p192),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_p192,
+		.length = sizeof(pubkey_qy_p192),
+	},
+	.scalar = {
+		.data = scalar_p192,
+		.length = sizeof(scalar_p192),
+	},
+	.digest = {
+		.data = digest_p192,
+		.length = sizeof(digest_p192),
+	},
+	.sign_r = {
+		.data = sign_p192_r,
+		.length = sizeof(sign_p192_r),
+	},
+	.sign_s = {
+		.data = sign_p192_s,
+		.length = sizeof(sign_p192_s),
+	},
+	.pkey = {
+		.data = pkey_p192,
+		.length = sizeof(pkey_p192),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_NISTP192
+};
+
+/* P-224 NIST test vectors */
+
+static uint8_t digest_p224[] = {
+	0x00, 0xc6, 0xfc, 0x53, 0xc1, 0x98, 0x6d, 0x19,
+	0xa8, 0xa8, 0xb5, 0x80, 0xee, 0x55, 0x3d, 0xc1,
+	0x24, 0x07, 0x45, 0xd7, 0x60, 0x64, 0x7d, 0x1c,
+	0x0a, 0xdf, 0x44, 0x2c, 0x13, 0x3c, 0x7f, 0x56
+};
+
+static uint8_t pkey_p224[] = {
+	0x88, 0x8f, 0xc9, 0x92, 0x89, 0x3b, 0xdd, 0x8a,
+	0xa0, 0x2c, 0x80, 0x76, 0x88, 0x32, 0x60, 0x5d,
+	0x02, 0x0b, 0x81, 0xae, 0x0b, 0x25, 0x47, 0x41,
+	0x54, 0xec, 0x89, 0xaa
+};
+
+static uint8_t scalar_p224[] = {
+	0x06, 0xf7, 0xa5, 0x60, 0x07, 0x82, 0x54, 0x33,
+	0xc4, 0xc6, 0x11, 0x53, 0xdf, 0x1a, 0x13, 0x5e,
+	0xee, 0x2f, 0x38, 0xec, 0x68, 0x7b, 0x49, 0x2e,
+	0xd4, 0x0d, 0x9c, 0x90
+};
+
+static uint8_t pubkey_qx_p224[] = {
+	0x4c, 0x74, 0x1e, 0x4d, 0x20, 0x10, 0x36, 0x70,
+	0xb7, 0x16, 0x1a, 0xe7, 0x22, 0x71, 0x08, 0x21,
+	0x55, 0x83, 0x84, 0x18, 0x08, 0x43, 0x35, 0x33,
+	0x8a, 0xc3, 0x8f, 0xa4
+};
+
+static uint8_t pubkey_qy_p224[] = {
+	0xdb, 0x79, 0x19, 0x15, 0x1a, 0xc2, 0x85, 0x87,
+	0xb7, 0x2b, 0xad, 0x7a, 0xb1, 0x80, 0xec, 0x8e,
+	0x95, 0xab, 0x9e, 0x2c, 0x8d, 0x81, 0xd9, 0xb9,
+	0xd7, 0xe2, 0xe3, 0x83
+};
+
+static uint8_t sign_p224_r[] = {
+	0x09, 0x09, 0xc9, 0xb9, 0xca, 0xe8, 0xd2, 0x79,
+	0x0e, 0x29, 0xdb, 0x6a, 0xfd, 0xb4, 0x5c, 0x04,
+	0xf5, 0xb0, 0x72, 0xc4, 0xc2, 0x04, 0x10, 0xc7,
+	0xdc, 0x9b, 0x67, 0x72
+};
+
+static uint8_t sign_p224_s[] = {
+	0x29, 0x8f, 0x4f, 0xca, 0xe1, 0xfe, 0x27, 0x1d,
+	0xa1, 0xe0, 0x34, 0x5d, 0x11, 0xd0, 0x7a, 0x1f,
+	0xca, 0x43, 0xf5, 0x8a, 0xf4, 0xc1, 0x13, 0xb9,
+	0x09, 0xee, 0xde, 0xa0
+};
+
+/** ECDSA P224 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_p224 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_p224,
+		.length = sizeof(pubkey_qx_p224),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_p224,
+		.length = sizeof(pubkey_qy_p224),
+	},
+	.scalar = {
+		.data = scalar_p224,
+		.length = sizeof(scalar_p224),
+	},
+	.digest = {
+		.data = digest_p224,
+		.length = sizeof(digest_p224),
+	},
+	.sign_r = {
+		.data = sign_p224_r,
+		.length = sizeof(sign_p224_r),
+	},
+	.sign_s = {
+		.data = sign_p224_s,
+		.length = sizeof(sign_p224_s),
+	},
+	.pkey = {
+		.data = pkey_p224,
+		.length = sizeof(pkey_p224),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_NISTP224
+};
+
+/* P-256 NIST test vectors */
+
+static uint8_t digest_p256[] = {
+	0x44, 0xac, 0xf6, 0xb7, 0xe3, 0x6c, 0x13, 0x42,
+	0xc2, 0xc5, 0x89, 0x72, 0x04, 0xfe, 0x09, 0x50,
+	0x4e, 0x1e, 0x2e, 0xfb, 0x1a, 0x90, 0x03, 0x77,
+	0xdb, 0xc4, 0xe7, 0xa6, 0xa1, 0x33, 0xec, 0x56
+};
+
+static uint8_t pkey_p256[] = {
+	0x51, 0x9b, 0x42, 0x3d, 0x71, 0x5f, 0x8b, 0x58,
+	0x1f, 0x4f, 0xa8, 0xee, 0x59, 0xf4, 0x77, 0x1a,
+	0x5b, 0x44, 0xc8, 0x13, 0x0b, 0x4e, 0x3e, 0xac,
+	0xca, 0x54, 0xa5, 0x6d, 0xda, 0x72, 0xb4, 0x64
+};
+
+static uint8_t scalar_p256[] = {
+	0x94, 0xa1, 0xbb, 0xb1, 0x4b, 0x90, 0x6a, 0x61,
+	0xa2, 0x80, 0xf2, 0x45, 0xf9, 0xe9, 0x3c, 0x7f,
+	0x3b, 0x4a, 0x62, 0x47, 0x82, 0x4f, 0x5d, 0x33,
+	0xb9, 0x67, 0x07, 0x87, 0x64, 0x2a, 0x68, 0xde
+};
+
+static uint8_t pubkey_qx_p256[] = {
+	0x1c, 0xcb, 0xe9, 0x1c, 0x07, 0x5f, 0xc7, 0xf4,
+	0xf0, 0x33, 0xbf, 0xa2, 0x48, 0xdb, 0x8f, 0xcc,
+	0xd3, 0x56, 0x5d, 0xe9, 0x4b, 0xbf, 0xb1, 0x2f,
+	0x3c, 0x59, 0xff, 0x46, 0xc2, 0x71, 0xbf, 0x83
+};
+
+static uint8_t pubkey_qy_p256[] = {
+	0xce, 0x40, 0x14, 0xc6, 0x88, 0x11, 0xf9, 0xa2,
+	0x1a, 0x1f, 0xdb, 0x2c, 0x0e, 0x61, 0x13, 0xe0,
+	0x6d, 0xb7, 0xca, 0x93, 0xb7, 0x40, 0x4e, 0x78,
+	0xdc, 0x7c, 0xcd, 0x5c, 0xa8, 0x9a, 0x4c, 0xa9
+};
+
+static uint8_t sign_p256_r[] = {
+	0xf3, 0xac, 0x80, 0x61, 0xb5, 0x14, 0x79, 0x5b,
+	0x88, 0x43, 0xe3, 0xd6, 0x62, 0x95, 0x27, 0xed,
+	0x2a, 0xfd, 0x6b, 0x1f, 0x6a, 0x55, 0x5a, 0x7a,
+	0xca, 0xbb, 0x5e, 0x6f, 0x79, 0xc8, 0xc2, 0xac
+};
+
+static uint8_t sign_p256_s[] = {
+	0x8b, 0xf7, 0x78, 0x19, 0xca, 0x05, 0xa6, 0xb2,
+	0x78, 0x6c, 0x76, 0x26, 0x2b, 0xf7, 0x37, 0x1c,
+	0xef, 0x97, 0xb2, 0x18, 0xe9, 0x6f, 0x17, 0x5a,
+	0x3c, 0xcd, 0xda, 0x2a, 0xcc, 0x05, 0x89, 0x03
+};
+
+/** ECDSA P256 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_p256 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_p256,
+		.length = sizeof(pubkey_qx_p256),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_p256,
+		.length = sizeof(pubkey_qy_p256),
+	},
+	.scalar = {
+		.data = scalar_p256,
+		.length = sizeof(scalar_p256),
+	},
+	.digest = {
+		.data = digest_p256,
+		.length = sizeof(digest_p256),
+	},
+	.sign_r = {
+		.data = sign_p256_r,
+		.length = sizeof(sign_p256_r),
+	},
+	.sign_s = {
+		.data = sign_p256_s,
+		.length = sizeof(sign_p256_s),
+	},
+	.pkey = {
+		.data = pkey_p256,
+		.length = sizeof(pkey_p256),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_NISTP256
+};
+
+/* P-384 NIST test vectors */
+
+static uint8_t digest_p384[] = {
+	0xbb, 0xbd, 0x0a, 0x5f, 0x64, 0x5d, 0x3f, 0xda,
+	0x10, 0xe2, 0x88, 0xd1, 0x72, 0xb2, 0x99, 0x45,
+	0x5f, 0x9d, 0xff, 0x00, 0xe0, 0xfb, 0xc2, 0x83,
+	0x3e, 0x18, 0xcd, 0x01, 0x7d, 0x7f, 0x3e, 0xd1
+};
+
+static uint8_t pkey_p384[] = {
+	0xc6, 0x02, 0xbc, 0x74, 0xa3, 0x45, 0x92, 0xc3,
+	0x11, 0xa6, 0x56, 0x96, 0x61, 0xe0, 0x83, 0x2c,
+	0x84, 0xf7, 0x20, 0x72, 0x74, 0x67, 0x6c, 0xc4,
+	0x2a, 0x89, 0xf0, 0x58, 0x16, 0x26, 0x30, 0x18,
+	0x4b, 0x52, 0xf0, 0xd9, 0x9b, 0x85, 0x5a, 0x77,
+	0x83, 0xc9, 0x87, 0x47, 0x6d, 0x7f, 0x9e, 0x6b
+};
+
+static uint8_t scalar_p384[] = {
+	0xc1, 0x0b, 0x5c, 0x25, 0xc4, 0x68, 0x3d, 0x0b,
+	0x78, 0x27, 0xd0, 0xd8, 0x86, 0x97, 0xcd, 0xc0,
+	0x93, 0x24, 0x96, 0xb5, 0x29, 0x9b, 0x79, 0x8c,
+	0x0d, 0xd1, 0xe7, 0xaf, 0x6c, 0xc7, 0x57, 0xcc,
+	0xb3, 0x0f, 0xcd, 0x3d, 0x36, 0xea, 0xd4, 0xa8,
+	0x04, 0x87, 0x7e, 0x24, 0xf3, 0xa3, 0x24, 0x43
+};
+
+static uint8_t pubkey_qx_p384[] = {
+	0x04, 0x00, 0x19, 0x3b, 0x21, 0xf0, 0x7c, 0xd0,
+	0x59, 0x82, 0x6e, 0x94, 0x53, 0xd3, 0xe9, 0x6d,
+	0xd1, 0x45, 0x04, 0x1c, 0x97, 0xd4, 0x9f, 0xf6,
+	0xb7, 0x04, 0x7f, 0x86, 0xbb, 0x0b, 0x04, 0x39,
+	0xe9, 0x09, 0x27, 0x4c, 0xb9, 0xc2, 0x82, 0xbf,
+	0xab, 0x88, 0x67, 0x4c, 0x07, 0x65, 0xbc, 0x75
+};
+
+static uint8_t pubkey_qy_p384[] = {
+	0xf7, 0x0d, 0x89, 0xc5, 0x2a, 0xcb, 0xc7, 0x04,
+	0x68, 0xd2, 0xc5, 0xae, 0x75, 0xc7, 0x6d, 0x7f,
+	0x69, 0xb7, 0x6a, 0xf6, 0x2d, 0xcf, 0x95, 0xe9,
+	0x9e, 0xba, 0x5d, 0xd1, 0x1a, 0xdf, 0x8f, 0x42,
+	0xec, 0x9a, 0x42, 0x5b, 0x0c, 0x5e, 0xc9, 0x8e,
+	0x2f, 0x23, 0x4a, 0x92, 0x6b, 0x82, 0xa1, 0x47
+};
+
+static uint8_t sign_p384_r[] = {
+	0xb1, 0x1d, 0xb0, 0x0c, 0xda, 0xf5, 0x32, 0x86,
+	0xd4, 0x48, 0x3f, 0x38, 0xcd, 0x02, 0x78, 0x59,
+	0x48, 0x47, 0x7e, 0xd7, 0xeb, 0xc2, 0xad, 0x60,
+	0x90, 0x54, 0x55, 0x1d, 0xa0, 0xab, 0x03, 0x59,
+	0x97, 0x8c, 0x61, 0x85, 0x17, 0x88, 0xaa, 0x2e,
+	0xc3, 0x26, 0x79, 0x46, 0xd4, 0x40, 0xe8, 0x78
+};
+
+static uint8_t sign_p384_s[] = {
+	0x16, 0x00, 0x78, 0x73, 0xc5, 0xb0, 0x60, 0x4c,
+	0xe6, 0x81, 0x12, 0xa8, 0xfe, 0xe9, 0x73, 0xe8,
+	0xe2, 0xb6, 0xe3, 0x31, 0x9c, 0x68, 0x3a, 0x76,
+	0x2f, 0xf5, 0x06, 0x5a, 0x07, 0x65, 0x12, 0xd7,
+	0xc9, 0x8b, 0x27, 0xe7, 0x4b, 0x78, 0x87, 0x67,
+	0x10, 0x48, 0xac, 0x02, 0x7d, 0xf8, 0xcb, 0xf2
+};
+
+/** ECDSA P384 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_p384 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_p384,
+		.length = sizeof(pubkey_qx_p384),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_p384,
+		.length = sizeof(pubkey_qy_p384),
+	},
+	.scalar = {
+		.data = scalar_p384,
+		.length = sizeof(scalar_p384),
+	},
+	.digest = {
+		.data = digest_p384,
+		.length = sizeof(digest_p384),
+	},
+	.sign_r = {
+		.data = sign_p384_r,
+		.length = sizeof(sign_p384_r),
+	},
+	.sign_s = {
+		.data = sign_p384_s,
+		.length = sizeof(sign_p384_s),
+	},
+	.pkey = {
+		.data = pkey_p384,
+		.length = sizeof(pkey_p384),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_NISTP384
+};
+
+/* P-521 NIST test vectors */
+
+static uint8_t digest_p521[] = {
+	0x53, 0xe6, 0x53, 0x7c, 0xb6, 0xea, 0x68, 0xae,
+	0x47, 0xa8, 0x16, 0x11, 0xc2, 0x27, 0x56, 0xd7,
+	0x70, 0xd7, 0xa3, 0x7e, 0x33, 0x6c, 0x3a, 0xf0,
+	0xb0, 0x81, 0x4b, 0x04, 0xfa, 0x39, 0x43, 0x4b
+};
+
+static uint8_t pkey_p521[] = {
+	0x01, 0xe8, 0xc0, 0x59, 0x96, 0xb8, 0x5e, 0x6f,
+	0x3f, 0x87, 0x57, 0x12, 0xa0, 0x9c, 0x1b, 0x40,
+	0x67, 0x2b, 0x5e, 0x7a, 0x78, 0xd5, 0x85, 0x2d,
+	0xe0, 0x15, 0x85, 0xc5, 0xfb, 0x99, 0x0b, 0xf3,
+	0x81, 0x2c, 0x32, 0x45, 0x53, 0x4a, 0x71, 0x43,
+	0x89, 0xae, 0x90, 0x14, 0xd6, 0x77, 0xa4, 0x49,
+	0xef, 0xd6, 0x58, 0x25, 0x4e, 0x61, 0x0d, 0xa8,
+	0xe6, 0xca, 0xd3, 0x34, 0x14, 0xb9, 0xd3, 0x3e,
+	0x0d, 0x7a
+};
+
+static uint8_t scalar_p521[] = {
+	0x00, 0xdc, 0x8d, 0xaa, 0xac, 0xdd, 0xb8, 0xfd,
+	0x2f, 0xf5, 0xc3, 0x4a, 0x5c, 0xe1, 0x83, 0xa4,
+	0x22, 0x61, 0xad, 0x3c, 0x64, 0xdb, 0xfc, 0x09,
+	0x5e, 0x58, 0x92, 0x43, 0x64, 0xdc, 0x47, 0xea,
+	0x1c, 0x05, 0xe2, 0x59, 0x9a, 0xae, 0x91, 0x7c,
+	0x2c, 0x95, 0xf4, 0x7d, 0x6b, 0xb3, 0x7d, 0xa0,
+	0x08, 0xaf, 0x9f, 0x55, 0x73, 0x0d, 0xdb, 0xe4,
+	0xd8, 0xde, 0xd2, 0x4f, 0x9e, 0x8d, 0xaa, 0x46,
+	0xdb, 0x6a
+};
+
+static uint8_t pubkey_qx_p521[] = {
+	0x00, 0x7d, 0x04, 0x2c, 0xa1, 0x94, 0x08, 0x52,
+	0x4e, 0x68, 0xb9, 0x81, 0xf1, 0x41, 0x93, 0x51,
+	0xe3, 0xb8, 0x47, 0x36, 0xc7, 0x7f, 0xe5, 0x8f,
+	0xee, 0x7d, 0x11, 0x31, 0x7d, 0xf2, 0xe8, 0x50,
+	0xd9, 0x60, 0xc7, 0xdd, 0x10, 0xd1, 0x0b, 0xa7,
+	0x14, 0xc8, 0xa6, 0x09, 0xd1, 0x63, 0x50, 0x2b,
+	0x79, 0xd6, 0x82, 0xe8, 0xbb, 0xec, 0xd4, 0xf5,
+	0x25, 0x91, 0xd2, 0x74, 0x85, 0x33, 0xe4, 0x5a,
+	0x86, 0x7a
+};
+
+static uint8_t pubkey_qy_p521[] = {
+	0x01, 0x97, 0xac, 0x64, 0x16, 0x11, 0x1c, 0xcf,
+	0x98, 0x7d, 0x29, 0x04, 0x59, 0xeb, 0xc8, 0xad,
+	0x9e, 0xc5, 0x6e, 0x49, 0x05, 0x9c, 0x99, 0x21,
+	0x55, 0x53, 0x9a, 0x36, 0xa6, 0x26, 0x63, 0x1f,
+	0x4a, 0x2d, 0x89, 0x16, 0x4b, 0x98, 0x51, 0x54,
+	0xf2, 0xdd, 0xdc, 0x02, 0x81, 0xee, 0x5b, 0x51,
+	0x78, 0x27, 0x1f, 0x3a, 0x76, 0xa0, 0x91, 0x4c,
+	0x3f, 0xcd, 0x1f, 0x97, 0xbe, 0x8e, 0x83, 0x76,
+	0xef, 0xb3
+};
+
+static uint8_t sign_p521_r[] = {
+	0x00, 0x9d, 0xd1, 0xf2, 0xa7, 0x16, 0x84, 0x3e,
+	0xed, 0xec, 0x7a, 0x66, 0x45, 0xac, 0x83, 0x4d,
+	0x43, 0x36, 0xe7, 0xb1, 0x8e, 0x35, 0x70, 0x1f,
+	0x06, 0xca, 0xe9, 0xd6, 0xb2, 0x90, 0xd4, 0x14,
+	0x91, 0x42, 0x47, 0x35, 0xf3, 0xb5, 0x7e, 0x82,
+	0x9a, 0xd5, 0xde, 0x05, 0x5e, 0xae, 0xef, 0x17,
+	0x78, 0xf0, 0x51, 0xc1, 0xee, 0x15, 0x2b, 0xf2,
+	0x13, 0x1a, 0x08, 0x1e, 0x53, 0xdf, 0x2a, 0x56,
+	0x7a, 0x8a
+};
+
+static uint8_t sign_p521_s[] = {
+	0x00, 0x21, 0x48, 0xe8, 0x42, 0x8d, 0x70, 0xa7,
+	0x2b, 0xc9, 0xfa, 0x98, 0x6c, 0x38, 0xc2, 0xc9,
+	0x7d, 0xed, 0xa0, 0x42, 0x0f, 0x22, 0x2f, 0x9d,
+	0xc9, 0x9d, 0x32, 0xc0, 0xac, 0xba, 0x69, 0x9d,
+	0xc7, 0xba, 0x0a, 0x2b, 0x79, 0xce, 0x59, 0x99,
+	0xff, 0x61, 0xbd, 0x0b, 0x23, 0x3c, 0x74, 0x4a,
+	0x89, 0x3b, 0xc1, 0x05, 0xbc, 0xa5, 0xc2, 0x35,
+	0x42, 0x3e, 0x53, 0x16, 0x12, 0xda, 0x65, 0xd7,
+	0x2e, 0x62
+};
+
+/** ECDSA P521 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_p521 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_p521,
+		.length = sizeof(pubkey_qx_p521),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_p521,
+		.length = sizeof(pubkey_qy_p521),
+	},
+	.scalar = {
+		.data = scalar_p521,
+		.length = sizeof(scalar_p521),
+	},
+	.digest = {
+		.data = digest_p521,
+		.length = sizeof(digest_p521),
+	},
+	.sign_r = {
+		.data = sign_p521_r,
+		.length = sizeof(sign_p521_r),
+	},
+	.sign_s = {
+		.data = sign_p521_s,
+		.length = sizeof(sign_p521_s),
+	},
+	.pkey = {
+		.data = pkey_p521,
+		.length = sizeof(pkey_p521),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_NISTP521
+};
+
+#endif /* __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__ */
-- 
2.7.4


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

* Re: [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA Anoob Joseph
@ 2019-12-20 16:05   ` Kusztal, ArkadiuszX
  2020-01-02  7:55     ` Anoob Joseph
  0 siblings, 1 reply; 19+ messages in thread
From: Kusztal, ArkadiuszX @ 2019-12-20 16:05 UTC (permalink / raw)
  To: Anoob Joseph, Akhil Goyal, Doherty, Declan, De Lara Guarch, Pablo
  Cc: Ayuj Verma, Trahe, Fiona, Jerin Jacob, Narayana Prasad,
	Shally Verma, Ankur Dwivedi, Sunila Sahu, dev

Hi Anoob,

Few suggestions inline.

>  ;
>  [Asymmetric]
> -RSA =
> -DSA =
> -Modular Exponentiation =
> -Modular Inversion =
> -Diffie-hellman =
> \ No newline at end of file
> +RSA                     =
> +DSA                     =
> +Modular Exponentiation  =
> +Modular Inversion       =
> +Diffie-hellman          =
> +ECDSA                   =
> diff --git a/lib/librte_cryptodev/rte_crypto_asym.h
> b/lib/librte_cryptodev/rte_crypto_asym.h
> index 0d34ce8..dd5e6e3 100644
> --- a/lib/librte_cryptodev/rte_crypto_asym.h
> +++ b/lib/librte_cryptodev/rte_crypto_asym.h
> @@ -81,6 +81,10 @@ enum rte_crypto_asym_xform_type {
>  	/**< Modular Exponentiation
>  	 * Perform Modular Exponentiation b^e mod n
>  	 */
> +	RTE_CRYPTO_ASYM_XFORM_ECDSA,
> +	/**< Elliptic Curve Digital Signature Algorithm
> +	 * Perform Signature Generation and Verification.
> +	 */
>  	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
>  	/**< End of list */
>  };
> @@ -319,6 +323,46 @@ struct rte_crypto_dsa_xform {  };
> 
>  /**
> + * TLS named curves
> + * https://www.iana.org/assignments/tls-parameters/
> + * tls-parameters.xhtml#tls-parameters-8
> + * secp192r1 = 19,
> + * secp224r1 = 21,
> + * secp256r1 = 23,
> + * secp384r1 = 24,
> + * secp521r1 = 25,
> + */
> +enum rte_crypto_ec_group {
> +	RTE_CRYPTO_EC_GROUP_UNKNOWN  = 0,
> +	RTE_CRYPTO_EC_GROUP_NISTP192 = 19,
> +	RTE_CRYPTO_EC_GROUP_NISTP224 = 21,
> +	RTE_CRYPTO_EC_GROUP_NISTP256 = 23,
> +	RTE_CRYPTO_EC_GROUP_NISTP384 = 24,
> +	RTE_CRYPTO_EC_GROUP_NISTP521 = 25,
> +};

[Arek] Since in comment we use SECG naming maybe enum should follow to avoid confusion?
> +
> +/**
> + * Structure for elliptic curve point
> + */
> +struct rte_crypto_ec_point {
> +	rte_crypto_param x;
> +	/**< X coordinate */
> +	rte_crypto_param y;
> +	/**< Y coordinate */
> +};
> +
> +/**
> + * Asymmetric elliptic curve transform data
> + *
> + * Structure describing all EC based xform params
> + *
> + */
> +struct rte_crypto_ec_xform {
> +	enum rte_crypto_ec_group curve_id;
> +	/**< Pre-defined ec groups */
> +};
> +
> +/**
>   * Operations params for modular operations:
>   * exponentiation and multiplicative inverse
>   *
> @@ -372,6 +416,11 @@ struct rte_crypto_asym_xform {
> 
>  		struct rte_crypto_dsa_xform dsa;
>  		/**< DSA xform parameters */
> +
> +		struct rte_crypto_ec_xform ec;
> +		/**< EC xform parameters, used by elliptic curve based
> +		 * operations.
> +		 */
>  	};
>  };
> 
> @@ -516,6 +565,39 @@ struct rte_crypto_dsa_op_param {  };
> 
>  /**
> + * ECDSA operation params
> + */
> +struct rte_crypto_ecdsa_op_param {
> +	enum rte_crypto_asym_op_type op_type;
> +	/**< Signature generation or verification */
> +
> +	rte_crypto_param pkey;
> +	/**< Private key of the signer for signature generation */
[Arek] - for DSA we have private key in xform, why this inconsistency?
> +
> +	struct rte_crypto_ec_point q;
> +	/**< Public key of the signer for verification */
> +
> +	rte_crypto_param message;
> +	/**< Input message to be signed or verified */
[Arek] - This I expect should be message digest instead of message itself?
> +
> +	rte_crypto_param k;
> +	/**< The ECDSA per-message secret number, which is an integer
> +	 * in the interval (1, n-1)
> +	 */
[Arek] - If pmd can generate 'k' internally we could do something like:
'if k.data == NULL => PMD will generate 'k' internally, k.data remains untouched.'
Another option is to provide user with some callback function to generate CSRN which could be useful for RSA PSS, OAEP as well (we already discussed that internally in Intel, I will elaborate on this bit more in different thread).

> +
> +	rte_crypto_param r;
> +	/**< r component of elliptic curve signature
> +	 *     output : for signature generation
> +	 *     input  : for signature verification
> +	 */
> +	rte_crypto_param s;
> +	/**< s component of elliptic curve signature
> +	 *     output : for signature generation
> +	 *     input  : for signature verification
> +	 */
[Arek] - Do we want to add any constraints like 'this field should be big enough to hold...'
> +};
> +
> +/**
>   * Asymmetric Cryptographic Operation.
>   *
>   * Structure describing asymmetric crypto operation params.
> @@ -537,6 +619,7 @@ struct rte_crypto_asym_op {
>  		struct rte_crypto_mod_op_param modinv;
>  		struct rte_crypto_dh_op_param dh;
>  		struct rte_crypto_dsa_op_param dsa;
> +		struct rte_crypto_ecdsa_op_param ecdsa;
>  	};
>  };
> 
> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> b/lib/librte_cryptodev/rte_cryptodev.c
> index 89aa2ed..0d6babb 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.c
> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> @@ -173,6 +173,7 @@ const char *rte_crypto_asym_xform_strings[] = {
>  	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
>  	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
>  	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
> +	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
>  };
> 
>  /**
> --
> 2.7.4

Regards,
Arek

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

* Re: [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA
  2019-12-20 16:05   ` Kusztal, ArkadiuszX
@ 2020-01-02  7:55     ` Anoob Joseph
  2020-01-09 13:03       ` Kusztal, ArkadiuszX
  0 siblings, 1 reply; 19+ messages in thread
From: Anoob Joseph @ 2020-01-02  7:55 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, Akhil Goyal, Doherty, Declan, De Lara Guarch, Pablo
  Cc: Ayuj Verma, Trahe, Fiona, Jerin Jacob Kollanukkaran,
	Narayana Prasad Raju Athreya, Shally Verma, Ankur Dwivedi,
	Sunila Sahu, dev

Hi Arek,

Please see inline.

Thanks,
Anoob

> -----Original Message-----
> From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> Sent: Friday, December 20, 2019 9:36 PM
> To: Anoob Joseph <anoobj@marvell.com>; Akhil Goyal
> <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>; De
> Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Cc: Ayuj Verma <ayverma@marvell.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Narayana Prasad Raju Athreya <pathreya@marvell.com>; Shally Verma
> <shallyv@marvell.com>; Ankur Dwivedi <adwivedi@marvell.com>; Sunila
> Sahu <ssahu@marvell.com>; dev@dpdk.org
> Subject: [EXT] RE: [PATCH 1/4] lib/crypto: add support for ECDSA
> 
> External Email
> 
> ----------------------------------------------------------------------
> Hi Anoob,
> 
> Few suggestions inline.
> 
> >  ;
> >  [Asymmetric]
> > -RSA =
> > -DSA =
> > -Modular Exponentiation =
> > -Modular Inversion =
> > -Diffie-hellman =
> > \ No newline at end of file
> > +RSA                     =
> > +DSA                     =
> > +Modular Exponentiation  =
> > +Modular Inversion       =
> > +Diffie-hellman          =
> > +ECDSA                   =
> > diff --git a/lib/librte_cryptodev/rte_crypto_asym.h
> > b/lib/librte_cryptodev/rte_crypto_asym.h
> > index 0d34ce8..dd5e6e3 100644
> > --- a/lib/librte_cryptodev/rte_crypto_asym.h
> > +++ b/lib/librte_cryptodev/rte_crypto_asym.h
> > @@ -81,6 +81,10 @@ enum rte_crypto_asym_xform_type {
> >  	/**< Modular Exponentiation
> >  	 * Perform Modular Exponentiation b^e mod n
> >  	 */
> > +	RTE_CRYPTO_ASYM_XFORM_ECDSA,
> > +	/**< Elliptic Curve Digital Signature Algorithm
> > +	 * Perform Signature Generation and Verification.
> > +	 */
> >  	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
> >  	/**< End of list */
> >  };
> > @@ -319,6 +323,46 @@ struct rte_crypto_dsa_xform {  };
> >
> >  /**
> > + * TLS named curves
> > + *
> > +https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__www.iana.org_ass
> > +ignments_tls-
> 2Dparameters_&d=DwIFAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=jPfB8r
> > +wwviRSxyLWs2n6B-WYLn1v9SyTMrT5EQqh2TU&m=nYBsHHO1NEdu-
> JmNULDH0kx7auwQd
> >
> +SbI0VYNVNxmm1w&s=RKZgomFiHpm9Yp8AYEn4FjlPpzbdavkMv5cRUggVid
> A&e=
> > + * tls-parameters.xhtml#tls-parameters-8
> > + * secp192r1 = 19,
> > + * secp224r1 = 21,
> > + * secp256r1 = 23,
> > + * secp384r1 = 24,
> > + * secp521r1 = 25,
> > + */
> > +enum rte_crypto_ec_group {
> > +	RTE_CRYPTO_EC_GROUP_UNKNOWN  = 0,
> > +	RTE_CRYPTO_EC_GROUP_NISTP192 = 19,
> > +	RTE_CRYPTO_EC_GROUP_NISTP224 = 21,
> > +	RTE_CRYPTO_EC_GROUP_NISTP256 = 23,
> > +	RTE_CRYPTO_EC_GROUP_NISTP384 = 24,
> > +	RTE_CRYPTO_EC_GROUP_NISTP521 = 25,
> > +};
> 
> [Arek] Since in comment we use SECG naming maybe enum should follow to
> avoid confusion?

[Anoob] How about RTE_CRYPTO_EC_GROUP_SECP521R1 and so on?

> > +
> > +/**
> > + * Structure for elliptic curve point  */ struct rte_crypto_ec_point
> > +{
> > +	rte_crypto_param x;
> > +	/**< X coordinate */
> > +	rte_crypto_param y;
> > +	/**< Y coordinate */
> > +};
> > +
> > +/**
> > + * Asymmetric elliptic curve transform data
> > + *
> > + * Structure describing all EC based xform params
> > + *
> > + */
> > +struct rte_crypto_ec_xform {
> > +	enum rte_crypto_ec_group curve_id;
> > +	/**< Pre-defined ec groups */
> > +};
> > +
> > +/**
> >   * Operations params for modular operations:
> >   * exponentiation and multiplicative inverse
> >   *
> > @@ -372,6 +416,11 @@ struct rte_crypto_asym_xform {
> >
> >  		struct rte_crypto_dsa_xform dsa;
> >  		/**< DSA xform parameters */
> > +
> > +		struct rte_crypto_ec_xform ec;
> > +		/**< EC xform parameters, used by elliptic curve based
> > +		 * operations.
> > +		 */
> >  	};
> >  };
> >
> > @@ -516,6 +565,39 @@ struct rte_crypto_dsa_op_param {  };
> >
> >  /**
> > + * ECDSA operation params
> > + */
> > +struct rte_crypto_ecdsa_op_param {
> > +	enum rte_crypto_asym_op_type op_type;
> > +	/**< Signature generation or verification */
> > +
> > +	rte_crypto_param pkey;
> > +	/**< Private key of the signer for signature generation */
> [Arek] - for DSA we have private key in xform, why this inconsistency?

[Anoob] Putting key in the session would limit the number of ops we can perform with one session. In regular use cases, the number of ops done with one key is very minimal. But the number of ops using same EC group is more. So if we define the session to one per EC group, then we will have better usage of session. Otherwise, the session need to be created and destroyed every few operations.
 
> > +
> > +	struct rte_crypto_ec_point q;
> > +	/**< Public key of the signer for verification */
> > +
> > +	rte_crypto_param message;
> > +	/**< Input message to be signed or verified */
> [Arek] - This I expect should be message digest instead of message itself?

[Anoob] Yes. Message digest is what is expected. This is following what is done with DSA & RSA. Do you recommend any changes? Variable name or description. 

> > +
> > +	rte_crypto_param k;
> > +	/**< The ECDSA per-message secret number, which is an integer
> > +	 * in the interval (1, n-1)
> > +	 */
> [Arek] - If pmd can generate 'k' internally we could do something like:
> 'if k.data == NULL => PMD will generate 'k' internally, k.data remains
> untouched.'

[Anoob] So that will be exposed as a new capability, right? Do you suggest any changes here to accommodate that? 

> Another option is to provide user with some callback function to generate
> CSRN which could be useful for RSA PSS, OAEP as well (we already discussed
> that internally in Intel, I will elaborate on this bit more in different thread).

[Anoob] Do you intend to keep the generated CSRN hidden in the PMD? 
 
> 
> > +
> > +	rte_crypto_param r;
> > +	/**< r component of elliptic curve signature
> > +	 *     output : for signature generation
> > +	 *     input  : for signature verification
> > +	 */
> > +	rte_crypto_param s;
> > +	/**< s component of elliptic curve signature
> > +	 *     output : for signature generation
> > +	 *     input  : for signature verification
> > +	 */
> [Arek] - Do we want to add any constraints like 'this field should be big
> enough to hold...'

[Anoob] For every case where rte_crypto_param is used for 'output', application should make sure the buffers are large enough. Do you think we could document it somewhere common instead of adding per operation?
 
> > +};
> > +
> > +/**
> >   * Asymmetric Cryptographic Operation.
> >   *
> >   * Structure describing asymmetric crypto operation params.
> > @@ -537,6 +619,7 @@ struct rte_crypto_asym_op {
> >  		struct rte_crypto_mod_op_param modinv;
> >  		struct rte_crypto_dh_op_param dh;
> >  		struct rte_crypto_dsa_op_param dsa;
> > +		struct rte_crypto_ecdsa_op_param ecdsa;
> >  	};
> >  };
> >
> > diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> > b/lib/librte_cryptodev/rte_cryptodev.c
> > index 89aa2ed..0d6babb 100644
> > --- a/lib/librte_cryptodev/rte_cryptodev.c
> > +++ b/lib/librte_cryptodev/rte_cryptodev.c
> > @@ -173,6 +173,7 @@ const char *rte_crypto_asym_xform_strings[] = {
> >  	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
> >  	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
> >  	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
> > +	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
> >  };
> >
> >  /**
> > --
> > 2.7.4
> 
> Regards,
> Arek

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

* Re: [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA
  2020-01-02  7:55     ` Anoob Joseph
@ 2020-01-09 13:03       ` Kusztal, ArkadiuszX
  2020-01-13 12:47         ` Akhil Goyal
  2020-01-13 16:36         ` Anoob Joseph
  0 siblings, 2 replies; 19+ messages in thread
From: Kusztal, ArkadiuszX @ 2020-01-09 13:03 UTC (permalink / raw)
  To: Anoob Joseph, Akhil Goyal, Doherty, Declan, De Lara Guarch, Pablo
  Cc: Ayuj Verma, Trahe, Fiona, Jerin Jacob Kollanukkaran,
	Narayana Prasad Raju Athreya, Shally Verma, Ankur Dwivedi,
	Sunila Sahu, dev

Hi Anoob,

> -----Original Message-----
> From: Anoob Joseph <anoobj@marvell.com>
> Sent: Thursday, January 2, 2020 8:55 AM
> To: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; Akhil Goyal
> <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>; De
> Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Cc: Ayuj Verma <ayverma@marvell.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Narayana Prasad Raju Athreya <pathreya@marvell.com>; Shally Verma
> <shallyv@marvell.com>; Ankur Dwivedi <adwivedi@marvell.com>; Sunila
> Sahu <ssahu@marvell.com>; dev@dpdk.org
> Subject: RE: [PATCH 1/4] lib/crypto: add support for ECDSA
> 
> Hi Arek,
> 
> Please see inline.
> 
> Thanks,
> Anoob
> 
> > -----Original Message-----
> > From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> > Sent: Friday, December 20, 2019 9:36 PM
> > To: Anoob Joseph <anoobj@marvell.com>; Akhil Goyal
> > <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>; De
> > Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> > Cc: Ayuj Verma <ayverma@marvell.com>; Trahe, Fiona
> > <fiona.trahe@intel.com>; Jerin Jacob Kollanukkaran
> > <jerinj@marvell.com>; Narayana Prasad Raju Athreya
> > <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>; Ankur
> > Dwivedi <adwivedi@marvell.com>; Sunila Sahu <ssahu@marvell.com>;
> > dev@dpdk.org
> > Subject: [EXT] RE: [PATCH 1/4] lib/crypto: add support for ECDSA
> >
> > External Email
> >
> > ----------------------------------------------------------------------
> > Hi Anoob,
> >
> > Few suggestions inline.
> >
> > >  ;
> > >  [Asymmetric]
> > > -RSA =
> > > -DSA =
> > > -Modular Exponentiation =
> > > -Modular Inversion =
> > > -Diffie-hellman =
> > > \ No newline at end of file
> > > +RSA                     =
> > > +DSA                     =
> > > +Modular Exponentiation  =
> > > +Modular Inversion       =
> > > +Diffie-hellman          =
> > > +ECDSA                   =
> > > diff --git a/lib/librte_cryptodev/rte_crypto_asym.h
> > > b/lib/librte_cryptodev/rte_crypto_asym.h
> > > index 0d34ce8..dd5e6e3 100644
> > > --- a/lib/librte_cryptodev/rte_crypto_asym.h
> > > +++ b/lib/librte_cryptodev/rte_crypto_asym.h
> > > @@ -81,6 +81,10 @@ enum rte_crypto_asym_xform_type {
> > >  	/**< Modular Exponentiation
> > >  	 * Perform Modular Exponentiation b^e mod n
> > >  	 */
> > > +	RTE_CRYPTO_ASYM_XFORM_ECDSA,
> > > +	/**< Elliptic Curve Digital Signature Algorithm
> > > +	 * Perform Signature Generation and Verification.
> > > +	 */
> > >  	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
> > >  	/**< End of list */
> > >  };
> > > @@ -319,6 +323,46 @@ struct rte_crypto_dsa_xform {  };
> > >
> > >  /**
> > > + * TLS named curves
> > > + *
> > > +https://urldefense.proofpoint.com/v2/url?u=https-
> > 3A__www.iana.org_ass
> > > +ignments_tls-
> > 2Dparameters_&d=DwIFAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=jPfB8r
> > > +wwviRSxyLWs2n6B-WYLn1v9SyTMrT5EQqh2TU&m=nYBsHHO1NEdu-
> > JmNULDH0kx7auwQd
> > >
> >
> +SbI0VYNVNxmm1w&s=RKZgomFiHpm9Yp8AYEn4FjlPpzbdavkMv5cRUggVid
> > A&e=
> > > + * tls-parameters.xhtml#tls-parameters-8
> > > + * secp192r1 = 19,
> > > + * secp224r1 = 21,
> > > + * secp256r1 = 23,
> > > + * secp384r1 = 24,
> > > + * secp521r1 = 25,
> > > + */
> > > +enum rte_crypto_ec_group {
> > > +	RTE_CRYPTO_EC_GROUP_UNKNOWN  = 0,
> > > +	RTE_CRYPTO_EC_GROUP_NISTP192 = 19,
> > > +	RTE_CRYPTO_EC_GROUP_NISTP224 = 21,
> > > +	RTE_CRYPTO_EC_GROUP_NISTP256 = 23,
> > > +	RTE_CRYPTO_EC_GROUP_NISTP384 = 24,
> > > +	RTE_CRYPTO_EC_GROUP_NISTP521 = 25, };
> >
> > [Arek] Since in comment we use SECG naming maybe enum should follow
> to
> > avoid confusion?
> 
> [Anoob] How about RTE_CRYPTO_EC_GROUP_SECP521R1 and so on?
[Arek] Iam ok with that.
> 
> > > +
> > > +/**
> > > + * Structure for elliptic curve point  */ struct
> > > +rte_crypto_ec_point {
> > > +	rte_crypto_param x;
> > > +	/**< X coordinate */
> > > +	rte_crypto_param y;
> > > +	/**< Y coordinate */
> > > +};
> > > +
> > > +/**
> > > + * Asymmetric elliptic curve transform data
> > > + *
> > > + * Structure describing all EC based xform params
> > > + *
> > > + */
> > > +struct rte_crypto_ec_xform {
> > > +	enum rte_crypto_ec_group curve_id;
> > > +	/**< Pre-defined ec groups */
> > > +};
> > > +
> > > +/**
> > >   * Operations params for modular operations:
> > >   * exponentiation and multiplicative inverse
> > >   *
> > > @@ -372,6 +416,11 @@ struct rte_crypto_asym_xform {
> > >
> > >  		struct rte_crypto_dsa_xform dsa;
> > >  		/**< DSA xform parameters */
> > > +
> > > +		struct rte_crypto_ec_xform ec;
> > > +		/**< EC xform parameters, used by elliptic curve based
> > > +		 * operations.
> > > +		 */
> > >  	};
> > >  };
> > >
> > > @@ -516,6 +565,39 @@ struct rte_crypto_dsa_op_param {  };
> > >
> > >  /**
> > > + * ECDSA operation params
> > > + */
> > > +struct rte_crypto_ecdsa_op_param {
> > > +	enum rte_crypto_asym_op_type op_type;
> > > +	/**< Signature generation or verification */
> > > +
> > > +	rte_crypto_param pkey;
> > > +	/**< Private key of the signer for signature generation */
> > [Arek] - for DSA we have private key in xform, why this inconsistency?
> 
> [Anoob] Putting key in the session would limit the number of ops we can
> perform with one session. In regular use cases, the number of ops done with
> one key is very minimal. But the number of ops using same EC group is more.
> So if we define the session to one per EC group, then we will have better
> usage of session. Otherwise, the session need to be created and destroyed
> every few operations.
[Arek] I agree with that, so maybe we could change DSA similar way (leave only group params?)
> 
> > > +
> > > +	struct rte_crypto_ec_point q;
> > > +	/**< Public key of the signer for verification */
> > > +
> > > +	rte_crypto_param message;
> > > +	/**< Input message to be signed or verified */
> > [Arek] - This I expect should be message digest instead of message itself?
> 
> [Anoob] Yes. Message digest is what is expected. This is following what is
> done with DSA & RSA. Do you recommend any changes? Variable name or
> description.
[Arek] Some information would be good I think.
> 
> > > +
> > > +	rte_crypto_param k;
> > > +	/**< The ECDSA per-message secret number, which is an integer
> > > +	 * in the interval (1, n-1)
> > > +	 */
> > [Arek] - If pmd can generate 'k' internally we could do something like:
> > 'if k.data == NULL => PMD will generate 'k' internally, k.data remains
> > untouched.'
> 
> [Anoob] So that will be exposed as a new capability, right? Do you suggest
> any changes here to accommodate that?
[Arek] Or maybe feature flag, it would apply to DSA as well.
> 
> > Another option is to provide user with some callback function to
> > generate CSRN which could be useful for RSA PSS, OAEP as well (we
> > already discussed that internally in Intel, I will elaborate on this bit more in
> different thread).
> 
> [Anoob] Do you intend to keep the generated CSRN hidden in the PMD?
[Arek] Openssl PMD does that with DSA but iam not a fan of that. But if some hw can do DSA/ECDSA by generating 'k' by itself it would have to be added anyway. Other option is to add aforementioned callbacks (for HW that not generate 'k' by itself)
> 
> >
> > > +
> > > +	rte_crypto_param r;
> > > +	/**< r component of elliptic curve signature
> > > +	 *     output : for signature generation
> > > +	 *     input  : for signature verification
> > > +	 */
> > > +	rte_crypto_param s;
> > > +	/**< s component of elliptic curve signature
> > > +	 *     output : for signature generation
> > > +	 *     input  : for signature verification
> > > +	 */
> > [Arek] - Do we want to add any constraints like 'this field should be
> > big enough to hold...'
> 
> [Anoob] For every case where rte_crypto_param is used for 'output',
> application should make sure the buffers are large enough. Do you think we
> could document it somewhere common instead of adding per operation?
[Arek]
Both options look good to me.
> 
> > > +};
> > > +
> > > +/**
> > >   * Asymmetric Cryptographic Operation.
> > >   *
> > >   * Structure describing asymmetric crypto operation params.
> > > @@ -537,6 +619,7 @@ struct rte_crypto_asym_op {
> > >  		struct rte_crypto_mod_op_param modinv;
> > >  		struct rte_crypto_dh_op_param dh;
> > >  		struct rte_crypto_dsa_op_param dsa;
> > > +		struct rte_crypto_ecdsa_op_param ecdsa;
> > >  	};
> > >  };
> > >
> > > diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> > > b/lib/librte_cryptodev/rte_cryptodev.c
> > > index 89aa2ed..0d6babb 100644
> > > --- a/lib/librte_cryptodev/rte_cryptodev.c
> > > +++ b/lib/librte_cryptodev/rte_cryptodev.c
> > > @@ -173,6 +173,7 @@ const char *rte_crypto_asym_xform_strings[] = {
> > >  	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
> > >  	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
> > >  	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
> > > +	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
> > >  };
> > >
> > >  /**
> > > --
> > > 2.7.4
> >
> > Regards,
> > Arek

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

* Re: [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA
  2020-01-09 13:03       ` Kusztal, ArkadiuszX
@ 2020-01-13 12:47         ` Akhil Goyal
  2020-01-13 16:36         ` Anoob Joseph
  1 sibling, 0 replies; 19+ messages in thread
From: Akhil Goyal @ 2020-01-13 12:47 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, Anoob Joseph, Doherty, Declan,
	De Lara Guarch, Pablo
  Cc: Ayuj Verma, Trahe, Fiona, Jerin Jacob Kollanukkaran,
	Narayana Prasad Raju Athreya, Shally Verma, Ankur Dwivedi,
	Sunila Sahu, dev

Hi Anoob,

Could you please send the updated patch with the changes suggested?

We need to merge it by Wednesday(15th Jan).

Thanks,
Akhil

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

* Re: [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA
  2020-01-09 13:03       ` Kusztal, ArkadiuszX
  2020-01-13 12:47         ` Akhil Goyal
@ 2020-01-13 16:36         ` Anoob Joseph
  2020-01-14  5:12           ` Shally Verma
  1 sibling, 1 reply; 19+ messages in thread
From: Anoob Joseph @ 2020-01-13 16:36 UTC (permalink / raw)
  To: Kusztal, ArkadiuszX, Akhil Goyal, Doherty, Declan, De Lara Guarch, Pablo
  Cc: Ayuj Verma, Trahe, Fiona, Jerin Jacob Kollanukkaran,
	Narayana Prasad Raju Athreya, Shally Verma, Ankur Dwivedi,
	Sunila Sahu, dev

Hi Akhil,

Do you suggest any change for the title here? As in, should I make it,

cryptodev: support ECDSA

@Arek, please see inline for responses.

Thanks,
Anoob

> -----Original Message-----
> From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> Sent: Thursday, January 9, 2020 6:34 PM
> To: Anoob Joseph <anoobj@marvell.com>; Akhil Goyal <akhil.goyal@nxp.com>;
> Doherty, Declan <declan.doherty@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>
> Cc: Ayuj Verma <ayverma@marvell.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Narayana Prasad Raju Athreya <pathreya@marvell.com>; Shally Verma
> <shallyv@marvell.com>; Ankur Dwivedi <adwivedi@marvell.com>; Sunila Sahu
> <ssahu@marvell.com>; dev@dpdk.org
> Subject: [EXT] RE: [PATCH 1/4] lib/crypto: add support for ECDSA
> 
> External Email
> 
> ----------------------------------------------------------------------
> Hi Anoob,
> 
> > -----Original Message-----
> > From: Anoob Joseph <anoobj@marvell.com>
> > Sent: Thursday, January 2, 2020 8:55 AM
> > To: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; Akhil Goyal
> > <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>; De
> > Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> > Cc: Ayuj Verma <ayverma@marvell.com>; Trahe, Fiona
> > <fiona.trahe@intel.com>; Jerin Jacob Kollanukkaran
> > <jerinj@marvell.com>; Narayana Prasad Raju Athreya
> > <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>; Ankur
> > Dwivedi <adwivedi@marvell.com>; Sunila Sahu <ssahu@marvell.com>;
> > dev@dpdk.org
> > Subject: RE: [PATCH 1/4] lib/crypto: add support for ECDSA
> >
> > Hi Arek,
> >
> > Please see inline.
> >
> > Thanks,
> > Anoob
> >
> > > -----Original Message-----
> > > From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> > > Sent: Friday, December 20, 2019 9:36 PM
> > > To: Anoob Joseph <anoobj@marvell.com>; Akhil Goyal
> > > <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>;
> > > De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> > > Cc: Ayuj Verma <ayverma@marvell.com>; Trahe, Fiona
> > > <fiona.trahe@intel.com>; Jerin Jacob Kollanukkaran
> > > <jerinj@marvell.com>; Narayana Prasad Raju Athreya
> > > <pathreya@marvell.com>; Shally Verma <shallyv@marvell.com>; Ankur
> > > Dwivedi <adwivedi@marvell.com>; Sunila Sahu <ssahu@marvell.com>;
> > > dev@dpdk.org
> > > Subject: [EXT] RE: [PATCH 1/4] lib/crypto: add support for ECDSA
> > >
> > > External Email
> > >
> > > --------------------------------------------------------------------
> > > --
> > > Hi Anoob,
> > >
> > > Few suggestions inline.
> > >
> > > >  ;
> > > >  [Asymmetric]
> > > > -RSA =
> > > > -DSA =
> > > > -Modular Exponentiation =
> > > > -Modular Inversion =
> > > > -Diffie-hellman =
> > > > \ No newline at end of file
> > > > +RSA                     =
> > > > +DSA                     =
> > > > +Modular Exponentiation  =
> > > > +Modular Inversion       =
> > > > +Diffie-hellman          =
> > > > +ECDSA                   =
> > > > diff --git a/lib/librte_cryptodev/rte_crypto_asym.h
> > > > b/lib/librte_cryptodev/rte_crypto_asym.h
> > > > index 0d34ce8..dd5e6e3 100644
> > > > --- a/lib/librte_cryptodev/rte_crypto_asym.h
> > > > +++ b/lib/librte_cryptodev/rte_crypto_asym.h
> > > > @@ -81,6 +81,10 @@ enum rte_crypto_asym_xform_type {
> > > >  	/**< Modular Exponentiation
> > > >  	 * Perform Modular Exponentiation b^e mod n
> > > >  	 */
> > > > +	RTE_CRYPTO_ASYM_XFORM_ECDSA,
> > > > +	/**< Elliptic Curve Digital Signature Algorithm
> > > > +	 * Perform Signature Generation and Verification.
> > > > +	 */
> > > >  	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
> > > >  	/**< End of list */
> > > >  };
> > > > @@ -319,6 +323,46 @@ struct rte_crypto_dsa_xform {  };
> > > >
> > > >  /**
> > > > + * TLS named curves
> > > > + *
> > > > +https://urldefense.proofpoint.com/v2/url?u=https-
> > > 3A__www.iana.org_ass
> > > > +ignments_tls-
> > > 2Dparameters_&d=DwIFAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=jPfB8r
> > > > +wwviRSxyLWs2n6B-WYLn1v9SyTMrT5EQqh2TU&m=nYBsHHO1NEdu-
> > > JmNULDH0kx7auwQd
> > > >
> > >
> > +SbI0VYNVNxmm1w&s=RKZgomFiHpm9Yp8AYEn4FjlPpzbdavkMv5cRUggVid
> > > A&e=
> > > > + * tls-parameters.xhtml#tls-parameters-8
> > > > + * secp192r1 = 19,
> > > > + * secp224r1 = 21,
> > > > + * secp256r1 = 23,
> > > > + * secp384r1 = 24,
> > > > + * secp521r1 = 25,
> > > > + */
> > > > +enum rte_crypto_ec_group {
> > > > +	RTE_CRYPTO_EC_GROUP_UNKNOWN  = 0,
> > > > +	RTE_CRYPTO_EC_GROUP_NISTP192 = 19,
> > > > +	RTE_CRYPTO_EC_GROUP_NISTP224 = 21,
> > > > +	RTE_CRYPTO_EC_GROUP_NISTP256 = 23,
> > > > +	RTE_CRYPTO_EC_GROUP_NISTP384 = 24,
> > > > +	RTE_CRYPTO_EC_GROUP_NISTP521 = 25, };
> > >
> > > [Arek] Since in comment we use SECG naming maybe enum should follow
> > to
> > > avoid confusion?
> >
> > [Anoob] How about RTE_CRYPTO_EC_GROUP_SECP521R1 and so on?
> [Arek] Iam ok with that.

[Anoob] Will update in v2.
 
> >
> > > > +
> > > > +/**
> > > > + * Structure for elliptic curve point  */ struct
> > > > +rte_crypto_ec_point {
> > > > +	rte_crypto_param x;
> > > > +	/**< X coordinate */
> > > > +	rte_crypto_param y;
> > > > +	/**< Y coordinate */
> > > > +};
> > > > +
> > > > +/**
> > > > + * Asymmetric elliptic curve transform data
> > > > + *
> > > > + * Structure describing all EC based xform params
> > > > + *
> > > > + */
> > > > +struct rte_crypto_ec_xform {
> > > > +	enum rte_crypto_ec_group curve_id;
> > > > +	/**< Pre-defined ec groups */
> > > > +};
> > > > +
> > > > +/**
> > > >   * Operations params for modular operations:
> > > >   * exponentiation and multiplicative inverse
> > > >   *
> > > > @@ -372,6 +416,11 @@ struct rte_crypto_asym_xform {
> > > >
> > > >  		struct rte_crypto_dsa_xform dsa;
> > > >  		/**< DSA xform parameters */
> > > > +
> > > > +		struct rte_crypto_ec_xform ec;
> > > > +		/**< EC xform parameters, used by elliptic curve based
> > > > +		 * operations.
> > > > +		 */
> > > >  	};
> > > >  };
> > > >
> > > > @@ -516,6 +565,39 @@ struct rte_crypto_dsa_op_param {  };
> > > >
> > > >  /**
> > > > + * ECDSA operation params
> > > > + */
> > > > +struct rte_crypto_ecdsa_op_param {
> > > > +	enum rte_crypto_asym_op_type op_type;
> > > > +	/**< Signature generation or verification */
> > > > +
> > > > +	rte_crypto_param pkey;
> > > > +	/**< Private key of the signer for signature generation */
> > > [Arek] - for DSA we have private key in xform, why this inconsistency?
> >
> > [Anoob] Putting key in the session would limit the number of ops we
> > can perform with one session. In regular use cases, the number of ops
> > done with one key is very minimal. But the number of ops using same EC group
> is more.
> > So if we define the session to one per EC group, then we will have
> > better usage of session. Otherwise, the session need to be created and
> > destroyed every few operations.
> [Arek] I agree with that, so maybe we could change DSA similar way (leave only
> group params?)

[Anoob] I'm okay with that. But that will have to be taken up separately, I guess. Shall I take that you are in agreement with the proposed change here?
 
> >
> > > > +
> > > > +	struct rte_crypto_ec_point q;
> > > > +	/**< Public key of the signer for verification */
> > > > +
> > > > +	rte_crypto_param message;
> > > > +	/**< Input message to be signed or verified */
> > > [Arek] - This I expect should be message digest instead of message itself?
> >
> > [Anoob] Yes. Message digest is what is expected. This is following
> > what is done with DSA & RSA. Do you recommend any changes? Variable
> > name or description.
> [Arek] Some information would be good I think.

[Anoob] I'll update the comment to state the same

/**< Input message digest to be signed or verified */

Is this fine?
 
> >
> > > > +
> > > > +	rte_crypto_param k;
> > > > +	/**< The ECDSA per-message secret number, which is an integer
> > > > +	 * in the interval (1, n-1)
> > > > +	 */
> > > [Arek] - If pmd can generate 'k' internally we could do something like:
> > > 'if k.data == NULL => PMD will generate 'k' internally, k.data
> > > remains untouched.'
> >
> > [Anoob] So that will be exposed as a new capability, right? Do you
> > suggest any changes here to accommodate that?
> [Arek] Or maybe feature flag, it would apply to DSA as well.

[Anoob] I meant feature flag only! Capability is for net devs etc.
 
> >
> > > Another option is to provide user with some callback function to
> > > generate CSRN which could be useful for RSA PSS, OAEP as well (we
> > > already discussed that internally in Intel, I will elaborate on this
> > > bit more in
> > different thread).
> >
> > [Anoob] Do you intend to keep the generated CSRN hidden in the PMD?
> [Arek] Openssl PMD does that with DSA but iam not a fan of that. But if some hw
> can do DSA/ECDSA by generating 'k' by itself it would have to be added anyway.
> Other option is to add aforementioned callbacks (for HW that not generate 'k'
> by itself)

[Anoob] I think we can support either case. Our h/w also can generate CSRN and so are open to ideas. Can you explain the proposed callback function? Also, we can defer that discussion to a separate thread, if we have an agreement on the approach here. 
 
> >
> > >
> > > > +
> > > > +	rte_crypto_param r;
> > > > +	/**< r component of elliptic curve signature
> > > > +	 *     output : for signature generation
> > > > +	 *     input  : for signature verification
> > > > +	 */
> > > > +	rte_crypto_param s;
> > > > +	/**< s component of elliptic curve signature
> > > > +	 *     output : for signature generation
> > > > +	 *     input  : for signature verification
> > > > +	 */
> > > [Arek] - Do we want to add any constraints like 'this field should
> > > be big enough to hold...'
> >
> > [Anoob] For every case where rte_crypto_param is used for 'output',
> > application should make sure the buffers are large enough. Do you
> > think we could document it somewhere common instead of adding per
> operation?
> [Arek]
> Both options look good to me.

[Anoob] How about updating the description of 'rte_crypto_param' to reflect the same? I can update it in v2, if you can confirm.
 
> >
> > > > +};
> > > > +
> > > > +/**
> > > >   * Asymmetric Cryptographic Operation.
> > > >   *
> > > >   * Structure describing asymmetric crypto operation params.
> > > > @@ -537,6 +619,7 @@ struct rte_crypto_asym_op {
> > > >  		struct rte_crypto_mod_op_param modinv;
> > > >  		struct rte_crypto_dh_op_param dh;
> > > >  		struct rte_crypto_dsa_op_param dsa;
> > > > +		struct rte_crypto_ecdsa_op_param ecdsa;
> > > >  	};
> > > >  };
> > > >
> > > > diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> > > > b/lib/librte_cryptodev/rte_cryptodev.c
> > > > index 89aa2ed..0d6babb 100644
> > > > --- a/lib/librte_cryptodev/rte_cryptodev.c
> > > > +++ b/lib/librte_cryptodev/rte_cryptodev.c
> > > > @@ -173,6 +173,7 @@ const char *rte_crypto_asym_xform_strings[] = {
> > > >  	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
> > > >  	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
> > > >  	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
> > > > +	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
> > > >  };
> > > >
> > > >  /**
> > > > --
> > > > 2.7.4
> > >
> > > Regards,
> > > Arek

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

* Re: [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA
  2020-01-13 16:36         ` Anoob Joseph
@ 2020-01-14  5:12           ` Shally Verma
  2020-01-14 11:01             ` Kusztal, ArkadiuszX
  0 siblings, 1 reply; 19+ messages in thread
From: Shally Verma @ 2020-01-14  5:12 UTC (permalink / raw)
  To: Anoob Joseph, Kusztal, ArkadiuszX, Akhil Goyal, Doherty, Declan,
	De Lara Guarch, Pablo
  Cc: Ayuj Verma, Trahe, Fiona, Jerin Jacob Kollanukkaran,
	Narayana Prasad Raju Athreya, Ankur Dwivedi, Sunila Sahu, dev

Hi Anoob, Akhil



> -----Original Message-----
> From: Anoob Joseph <anoobj@marvell.com>
> Sent: Monday, January 13, 2020 10:07 PM
> To: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; Akhil Goyal
> <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>; De
> Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>
> Cc: Ayuj Verma <ayverma@marvell.com>; Trahe, Fiona
> <fiona.trahe@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Narayana Prasad Raju Athreya <pathreya@marvell.com>; Shally Verma
> <shallyv@marvell.com>; Ankur Dwivedi <adwivedi@marvell.com>; Sunila
> Sahu <ssahu@marvell.com>; dev@dpdk.org
> Subject: RE: [PATCH 1/4] lib/crypto: add support for ECDSA
> 
....
> 
> > >
> > > > > +
> > > > > +	rte_crypto_param k;
> > > > > +	/**< The ECDSA per-message secret number, which is an
> integer
> > > > > +	 * in the interval (1, n-1)
> > > > > +	 */
> > > > [Arek] - If pmd can generate 'k' internally we could do something like:
> > > > 'if k.data == NULL => PMD will generate 'k' internally, k.data
> > > > remains untouched.'
> > >
> > > [Anoob] So that will be exposed as a new capability, right? Do you
> > > suggest any changes here to accommodate that?
> > [Arek] Or maybe feature flag, it would apply to DSA as well.
> 
> [Anoob] I meant feature flag only! Capability is for net devs etc.
> 
> > >
> > > > Another option is to provide user with some callback function to
> > > > generate CSRN which could be useful for RSA PSS, OAEP as well (we
> > > > already discussed that internally in Intel, I will elaborate on
> > > > this bit more in
> > > different thread).
> > >
> > > [Anoob] Do you intend to keep the generated CSRN hidden in the PMD?
> > [Arek] Openssl PMD does that with DSA but iam not a fan of that. But
> > if some hw can do DSA/ECDSA by generating 'k' by itself it would have to be
> added anyway.
> > Other option is to add aforementioned callbacks (for HW that not generate
> 'k'
> > by itself)
> 
> [Anoob] I think we can support either case. Our h/w also can generate CSRN
> and so are open to ideas. Can you explain the proposed callback function?
> Also, we can defer that discussion to a separate thread, if we have an
> agreement on the approach here.
> 
[Shally] Just a thought here. It can also be supported by exposing an API to application, like pre-compute / pre-setup which can generate 'k' or 'PRF' for other algo usage purpose. If PMD support it, return will be success with relevant o/p.. if not, return will be failure. Or no offload at all. In any case, generation of prf or 'k' is heavy on data path... app can call these pre-setup APIs to save cycles on actual sign op.

Shally
> > >
> > > >
> > > > > +
> > > > > +	rte_crypto_param r;
> > > > > +	/**< r component of elliptic curve signature
> > > > > +	 *     output : for signature generation
> > > > > +	 *     input  : for signature verification
> > > > > +	 */
> > > > > +	rte_crypto_param s;
> > > > > +	/**< s component of elliptic curve signature
> > > > > +	 *     output : for signature generation
> > > > > +	 *     input  : for signature verification
> > > > > +	 */
> > > > [Arek] - Do we want to add any constraints like 'this field should
> > > > be big enough to hold...'
> > >
> > > [Anoob] For every case where rte_crypto_param is used for 'output',
> > > application should make sure the buffers are large enough. Do you
> > > think we could document it somewhere common instead of adding per
> > operation?
> > [Arek]
> > Both options look good to me.
> 
> [Anoob] How about updating the description of 'rte_crypto_param' to reflect
> the same? I can update it in v2, if you can confirm.
> 
> > >
> > > > > +};
> > > > > +
> > > > > +/**
> > > > >   * Asymmetric Cryptographic Operation.
> > > > >   *
> > > > >   * Structure describing asymmetric crypto operation params.
> > > > > @@ -537,6 +619,7 @@ struct rte_crypto_asym_op {
> > > > >  		struct rte_crypto_mod_op_param modinv;
> > > > >  		struct rte_crypto_dh_op_param dh;
> > > > >  		struct rte_crypto_dsa_op_param dsa;
> > > > > +		struct rte_crypto_ecdsa_op_param ecdsa;
> > > > >  	};
> > > > >  };
> > > > >
> > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> > > > > b/lib/librte_cryptodev/rte_cryptodev.c
> > > > > index 89aa2ed..0d6babb 100644
> > > > > --- a/lib/librte_cryptodev/rte_cryptodev.c
> > > > > +++ b/lib/librte_cryptodev/rte_cryptodev.c
> > > > > @@ -173,6 +173,7 @@ const char *rte_crypto_asym_xform_strings[]
> = {
> > > > >  	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
> > > > >  	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
> > > > >  	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
> > > > > +	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
> > > > >  };
> > > > >
> > > > >  /**
> > > > > --
> > > > > 2.7.4
> > > >
> > > > Regards,
> > > > Arek

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

* Re: [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA
  2020-01-14  5:12           ` Shally Verma
@ 2020-01-14 11:01             ` Kusztal, ArkadiuszX
  0 siblings, 0 replies; 19+ messages in thread
From: Kusztal, ArkadiuszX @ 2020-01-14 11:01 UTC (permalink / raw)
  To: Shally Verma, Anoob Joseph, Akhil Goyal, Doherty, Declan,
	De Lara Guarch, Pablo
  Cc: Ayuj Verma, Trahe, Fiona, Jerin Jacob Kollanukkaran,
	Narayana Prasad Raju Athreya, Ankur Dwivedi, Sunila Sahu, dev

Hi guys,

> >
> > > >
> > > > > > +
> > > > > > +	rte_crypto_param k;
> > > > > > +	/**< The ECDSA per-message secret number, which is an
> > integer
> > > > > > +	 * in the interval (1, n-1)
> > > > > > +	 */
> > > > > [Arek] - If pmd can generate 'k' internally we could do something like:
> > > > > 'if k.data == NULL => PMD will generate 'k' internally, k.data
> > > > > remains untouched.'
> > > >
> > > > [Anoob] So that will be exposed as a new capability, right? Do you
> > > > suggest any changes here to accommodate that?
> > > [Arek] Or maybe feature flag, it would apply to DSA as well.
> >
> > [Anoob] I meant feature flag only! Capability is for net devs etc.
> >
> > > >
> > > > > Another option is to provide user with some callback function to
> > > > > generate CSRN which could be useful for RSA PSS, OAEP as well
> > > > > (we already discussed that internally in Intel, I will elaborate
> > > > > on this bit more in
> > > > different thread).
> > > >
> > > > [Anoob] Do you intend to keep the generated CSRN hidden in the PMD?
> > > [Arek] Openssl PMD does that with DSA but iam not a fan of that. But
> > > if some hw can do DSA/ECDSA by generating 'k' by itself it would
> > > have to be
> > added anyway.
> > > Other option is to add aforementioned callbacks (for HW that not
> > > generate
> > 'k'
> > > by itself)
> >
> > [Anoob] I think we can support either case. Our h/w also can generate
> > CSRN and so are open to ideas. Can you explain the proposed callback
> function?
> > Also, we can defer that discussion to a separate thread, if we have an
> > agreement on the approach here.
> >
> [Shally] Just a thought here. It can also be supported by exposing an API to
> application, like pre-compute / pre-setup which can generate 'k' or 'PRF' for
> other algo usage purpose. If PMD support it, return will be success with
> relevant o/p.. if not, return will be failure. Or no offload at all. In any case,
> generation of prf or 'k' is heavy on data path... app can call these pre-setup
> APIs to save cycles on actual sign op.
[AK] - We can start another thread on that. For now this implementation is good too, we can extend API by PMD CSRN option later.
> 
> Shally
> > > >
> > > > >
> > > > > > +
> > > > > > +	rte_crypto_param r;
> > > > > > +	/**< r component of elliptic curve signature
> > > > > > +	 *     output : for signature generation
> > > > > > +	 *     input  : for signature verification
> > > > > > +	 */
> > > > > > +	rte_crypto_param s;
> > > > > > +	/**< s component of elliptic curve signature
> > > > > > +	 *     output : for signature generation
> > > > > > +	 *     input  : for signature verification
> > > > > > +	 */
> > > > > [Arek] - Do we want to add any constraints like 'this field
> > > > > should be big enough to hold...'
> > > >
> > > > [Anoob] For every case where rte_crypto_param is used for
> > > > 'output', application should make sure the buffers are large
> > > > enough. Do you think we could document it somewhere common
> instead
> > > > of adding per
> > > operation?
> > > [Arek]
> > > Both options look good to me.
> >
> > [Anoob] How about updating the description of 'rte_crypto_param' to
> > reflect the same? I can update it in v2, if you can confirm.
[AK] It is ok to me.
> >
> > > >
> > > > > > +};
> > > > > > +
> > > > > > +/**
> > > > > >   * Asymmetric Cryptographic Operation.
> > > > > >   *
> > > > > >   * Structure describing asymmetric crypto operation params.
> > > > > > @@ -537,6 +619,7 @@ struct rte_crypto_asym_op {
> > > > > >  		struct rte_crypto_mod_op_param modinv;
> > > > > >  		struct rte_crypto_dh_op_param dh;
> > > > > >  		struct rte_crypto_dsa_op_param dsa;
> > > > > > +		struct rte_crypto_ecdsa_op_param ecdsa;
> > > > > >  	};
> > > > > >  };
> > > > > >
> > > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> > > > > > b/lib/librte_cryptodev/rte_cryptodev.c
> > > > > > index 89aa2ed..0d6babb 100644
> > > > > > --- a/lib/librte_cryptodev/rte_cryptodev.c
> > > > > > +++ b/lib/librte_cryptodev/rte_cryptodev.c
> > > > > > @@ -173,6 +173,7 @@ const char
> > > > > > *rte_crypto_asym_xform_strings[]
> > = {
> > > > > >  	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
> > > > > >  	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
> > > > > >  	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
> > > > > > +	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
> > > > > >  };
> > > > > >
> > > > > >  /**
> > > > > > --
> > > > > > 2.7.4
> > > > >
> > > > > Regards,
> > > > > Arek

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

* [dpdk-dev] [PATCH v2 0/4]  add ECDSA support
  2019-12-05 11:43 [dpdk-dev] [PATCH 0/4] add ECDSA support Anoob Joseph
                   ` (3 preceding siblings ...)
  2019-12-05 11:43 ` [dpdk-dev] [PATCH 4/4] app/test: add ECDSA sign/verify tests Anoob Joseph
@ 2020-01-15 12:43 ` Anoob Joseph
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 1/4] cryptodev: support ECDSA Anoob Joseph
                     ` (4 more replies)
  4 siblings, 5 replies; 19+ messages in thread
From: Anoob Joseph @ 2020-01-15 12:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Anoob Joseph, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, Sunila Sahu, dev

This series adds support for ECDSA asymmetric operations. Library changes
and PMD changes for crypto_octeontx & crypto_octoentx2 is added. The final
patch adds the required test vectors and verification routines.

v2:
* Changed all NIST references to use SECP.
* Minor updates to documentation/comments as suggested by Arek
* Updated release notes

Ayuj Verma (2):
  cryptodev: support ECDSA
  app/test: add ECDSA sign/verify tests

Sunila Sahu (2):
  crypto/octeontx: add ECDSA support
  crypto/octeontx2: add ECDSA support

 app/test/test_cryptodev_asym.c                     |  219 +++-
 app/test/test_cryptodev_asym_util.h                |   11 +
 app/test/test_cryptodev_ecdsa_test_vectors.h       |  505 +++++++++
 doc/guides/cryptodevs/features/default.ini         |   11 +-
 doc/guides/cryptodevs/features/octeontx.ini        |    8 +-
 doc/guides/cryptodevs/features/octeontx2.ini       |    8 +-
 doc/guides/rel_notes/release_20_02.rst             |    4 +
 drivers/common/cpt/Makefile                        |    1 +
 drivers/common/cpt/cpt_fpm_tables.c                | 1138 ++++++++++++++++++++
 drivers/common/cpt/cpt_mcode_defines.h             |   38 +
 drivers/common/cpt/cpt_pmd_ops_helper.h            |   19 +
 drivers/common/cpt/cpt_ucode_asym.h                |  378 +++++++
 drivers/common/cpt/meson.build                     |    3 +-
 drivers/common/cpt/rte_common_cpt_version.map      |    9 +
 .../crypto/octeontx/otx_cryptodev_capabilities.c   |   11 +
 drivers/crypto/octeontx/otx_cryptodev_ops.c        |   43 +-
 .../crypto/octeontx2/otx2_cryptodev_capabilities.c |   11 +
 drivers/crypto/octeontx2/otx2_cryptodev_ops.c      |   39 +-
 lib/librte_cryptodev/rte_crypto_asym.h             |   84 ++
 lib/librte_cryptodev/rte_cryptodev.c               |    1 +
 20 files changed, 2526 insertions(+), 15 deletions(-)
 create mode 100644 app/test/test_cryptodev_ecdsa_test_vectors.h
 create mode 100644 drivers/common/cpt/cpt_fpm_tables.c

-- 
2.7.4


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

* [dpdk-dev] [PATCH v2 1/4] cryptodev: support ECDSA
  2020-01-15 12:43 ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Anoob Joseph
@ 2020-01-15 12:43   ` Anoob Joseph
  2020-01-15 15:51     ` Akhil Goyal
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 2/4] crypto/octeontx: add ECDSA support Anoob Joseph
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 19+ messages in thread
From: Anoob Joseph @ 2020-01-15 12:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Ayuj Verma, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, Sunila Sahu, dev,
	Anoob Joseph

From: Ayuj Verma <ayverma@marvell.com>

Asymmetric crypto library is extended to add ECDSA. Elliptic curve
xform and ECDSA op params are introduced.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Ayuj Verma <ayverma@marvell.com>
Signed-off-by: Sunila Sahu <ssahu@marvell.com>
---
 doc/guides/cryptodevs/features/default.ini | 11 ++--
 doc/guides/rel_notes/release_20_02.rst     |  4 ++
 lib/librte_cryptodev/rte_crypto_asym.h     | 84 ++++++++++++++++++++++++++++++
 lib/librte_cryptodev/rte_cryptodev.c       |  1 +
 4 files changed, 95 insertions(+), 5 deletions(-)

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index b7f9a0a..2f6c785 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -103,8 +103,9 @@ AES CCM (256) =
 ; Supported Asymmetric algorithms of a default crypto driver.
 ;
 [Asymmetric]
-RSA =
-DSA =
-Modular Exponentiation =
-Modular Inversion =
-Diffie-hellman =
\ No newline at end of file
+RSA                     =
+DSA                     =
+Modular Exponentiation  =
+Modular Inversion       =
+Diffie-hellman          =
+ECDSA                   =
diff --git a/doc/guides/rel_notes/release_20_02.rst b/doc/guides/rel_notes/release_20_02.rst
index 0eaa45a..2e97c60 100644
--- a/doc/guides/rel_notes/release_20_02.rst
+++ b/doc/guides/rel_notes/release_20_02.rst
@@ -56,6 +56,10 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Added support for ECDSA.**
+
+  Added ECDSA(Elliptic Curve Digital Signature Algorithm) support to asymmetric
+  crypto library specifications.
 
 Removed Items
 -------------
diff --git a/lib/librte_cryptodev/rte_crypto_asym.h b/lib/librte_cryptodev/rte_crypto_asym.h
index 0d34ce8..e17614e 100644
--- a/lib/librte_cryptodev/rte_crypto_asym.h
+++ b/lib/librte_cryptodev/rte_crypto_asym.h
@@ -27,6 +27,13 @@ extern "C" {
 
 #include "rte_crypto_sym.h"
 
+/**
+ * Buffer to hold crypto params required for asym operations.
+ *
+ * These buffers can be used for both input to PMD and output from PMD. When
+ * used for output from PMD, application has to ensure the buffer is large
+ * enough to hold the target data.
+ */
 typedef struct rte_crypto_param_t {
 	uint8_t *data;
 	/**< pointer to buffer holding data */
@@ -81,6 +88,10 @@ enum rte_crypto_asym_xform_type {
 	/**< Modular Exponentiation
 	 * Perform Modular Exponentiation b^e mod n
 	 */
+	RTE_CRYPTO_ASYM_XFORM_ECDSA,
+	/**< Elliptic Curve Digital Signature Algorithm
+	 * Perform Signature Generation and Verification.
+	 */
 	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
 	/**< End of list */
 };
@@ -319,6 +330,40 @@ struct rte_crypto_dsa_xform {
 };
 
 /**
+ * TLS named curves
+ * https://tools.ietf.org/html/rfc8422
+ */
+enum rte_crypto_ec_group {
+	RTE_CRYPTO_EC_GROUP_UNKNOWN  = 0,
+	RTE_CRYPTO_EC_GROUP_SECP192R1 = 19,
+	RTE_CRYPTO_EC_GROUP_SECP224R1 = 21,
+	RTE_CRYPTO_EC_GROUP_SECP256R1 = 23,
+	RTE_CRYPTO_EC_GROUP_SECP384R1 = 24,
+	RTE_CRYPTO_EC_GROUP_SECP521R1 = 25,
+};
+
+/**
+ * Structure for elliptic curve point
+ */
+struct rte_crypto_ec_point {
+	rte_crypto_param x;
+	/**< X coordinate */
+	rte_crypto_param y;
+	/**< Y coordinate */
+};
+
+/**
+ * Asymmetric elliptic curve transform data
+ *
+ * Structure describing all EC based xform params
+ *
+ */
+struct rte_crypto_ec_xform {
+	enum rte_crypto_ec_group curve_id;
+	/**< Pre-defined ec groups */
+};
+
+/**
  * Operations params for modular operations:
  * exponentiation and multiplicative inverse
  *
@@ -372,6 +417,11 @@ struct rte_crypto_asym_xform {
 
 		struct rte_crypto_dsa_xform dsa;
 		/**< DSA xform parameters */
+
+		struct rte_crypto_ec_xform ec;
+		/**< EC xform parameters, used by elliptic curve based
+		 * operations.
+		 */
 	};
 };
 
@@ -516,6 +566,39 @@ struct rte_crypto_dsa_op_param {
 };
 
 /**
+ * ECDSA operation params
+ */
+struct rte_crypto_ecdsa_op_param {
+	enum rte_crypto_asym_op_type op_type;
+	/**< Signature generation or verification */
+
+	rte_crypto_param pkey;
+	/**< Private key of the signer for signature generation */
+
+	struct rte_crypto_ec_point q;
+	/**< Public key of the signer for verification */
+
+	rte_crypto_param message;
+	/**< Input message digest to be signed or verified */
+
+	rte_crypto_param k;
+	/**< The ECDSA per-message secret number, which is an integer
+	 * in the interval (1, n-1)
+	 */
+
+	rte_crypto_param r;
+	/**< r component of elliptic curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+	rte_crypto_param s;
+	/**< s component of elliptic curve signature
+	 *     output : for signature generation
+	 *     input  : for signature verification
+	 */
+};
+
+/**
  * Asymmetric Cryptographic Operation.
  *
  * Structure describing asymmetric crypto operation params.
@@ -537,6 +620,7 @@ struct rte_crypto_asym_op {
 		struct rte_crypto_mod_op_param modinv;
 		struct rte_crypto_dh_op_param dh;
 		struct rte_crypto_dsa_op_param dsa;
+		struct rte_crypto_ecdsa_op_param ecdsa;
 	};
 };
 
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 89aa2ed..0d6babb 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -173,6 +173,7 @@ const char *rte_crypto_asym_xform_strings[] = {
 	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
 	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
 	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
+	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
 };
 
 /**
-- 
2.7.4


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

* [dpdk-dev] [PATCH v2 2/4] crypto/octeontx: add ECDSA support
  2020-01-15 12:43 ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Anoob Joseph
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 1/4] cryptodev: support ECDSA Anoob Joseph
@ 2020-01-15 12:43   ` Anoob Joseph
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 3/4] crypto/octeontx2: " Anoob Joseph
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Anoob Joseph @ 2020-01-15 12:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Sunila Sahu, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, dev, Anoob Joseph,
	Ayuj Verma

From: Sunila Sahu <ssahu@marvell.com>

Adding support for ECDSA operations in crypto_octeontx PMD.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Ayuj Verma <ayverma@marvell.com>
Signed-off-by: Sunila Sahu <ssahu@marvell.com>
---
 doc/guides/cryptodevs/features/octeontx.ini        |    8 +-
 drivers/common/cpt/Makefile                        |    1 +
 drivers/common/cpt/cpt_fpm_tables.c                | 1138 ++++++++++++++++++++
 drivers/common/cpt/cpt_mcode_defines.h             |   38 +
 drivers/common/cpt/cpt_pmd_ops_helper.h            |   19 +
 drivers/common/cpt/cpt_ucode_asym.h                |  378 +++++++
 drivers/common/cpt/meson.build                     |    3 +-
 drivers/common/cpt/rte_common_cpt_version.map      |    9 +
 .../crypto/octeontx/otx_cryptodev_capabilities.c   |   11 +
 drivers/crypto/octeontx/otx_cryptodev_ops.c        |   43 +-
 10 files changed, 1643 insertions(+), 5 deletions(-)
 create mode 100644 drivers/common/cpt/cpt_fpm_tables.c

diff --git a/doc/guides/cryptodevs/features/octeontx.ini b/doc/guides/cryptodevs/features/octeontx.ini
index 1c036c5..544bb46 100644
--- a/doc/guides/cryptodevs/features/octeontx.ini
+++ b/doc/guides/cryptodevs/features/octeontx.ini
@@ -67,5 +67,9 @@ AES GCM (256) = Y
 ; Supported Asymmetric algorithms of the 'octeontx' crypto driver.
 ;
 [Asymmetric]
-RSA                    = Y
-Modular Exponentiation = Y
+RSA                     = Y
+DSA                     =
+Modular Exponentiation  = Y
+Modular Inversion       =
+Diffie-hellman          =
+ECDSA                   = Y
diff --git a/drivers/common/cpt/Makefile b/drivers/common/cpt/Makefile
index 8594432..cab9da7 100644
--- a/drivers/common/cpt/Makefile
+++ b/drivers/common/cpt/Makefile
@@ -16,6 +16,7 @@ EXPORT_MAP := rte_common_cpt_version.map
 #
 # all source are stored in SRCS-y
 #
+SRCS-y += cpt_fpm_tables.c
 SRCS-y += cpt_pmd_ops_helper.c
 
 LDLIBS += -lrte_eal
diff --git a/drivers/common/cpt/cpt_fpm_tables.c b/drivers/common/cpt/cpt_fpm_tables.c
new file mode 100644
index 0000000..15b665d
--- /dev/null
+++ b/drivers/common/cpt/cpt_fpm_tables.c
@@ -0,0 +1,1138 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2019 Marvell International Ltd.
+ */
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "cpt_mcode_defines.h"
+#include "cpt_pmd_logs.h"
+#include "cpt_pmd_ops_helper.h"
+
+/*
+ * CPT FPM table sizes Enumeration
+ *
+ * 15 table entries * (X, Y, Z coordinates) * Coordinate Offset
+ * Coordinate Offset depends on elliptic curve as mentioned below,
+ * 6 quadwords for P-192, P-224 and P-256
+ * 7 quadwords for P-384
+ * 9 quadwords for P-521
+ */
+typedef enum {
+	CPT_P192_LEN = 2160,
+	CPT_P224_LEN = 2160,
+	CPT_P256_LEN = 2160,
+	CPT_P384_LEN = 2520,
+	CPT_P521_LEN = 3240
+} cpt_fpm_len_t;
+
+/* FPM table address and length */
+struct fpm_entry {
+	const uint8_t *data;
+	int len;
+};
+
+/*
+ * Pre-computed ECC FMUL tables needed by cpt microcode
+ * for NIST curves P-192, P-256, P-384, P-521, P-224.
+ */
+
+static const uint8_t fpm_table_p192[CPT_P192_LEN] = {
+	0xf4, 0xff, 0x0a, 0xfd, 0x82, 0xff, 0x10, 0x12, 0x7c, 0xbf, 0x20, 0xeb,
+	0x43, 0xa1, 0x88, 0x00, 0x18, 0x8d, 0xa8, 0x0e, 0xb0, 0x30, 0x90, 0xf6,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11, 0x63, 0x10, 0x11, 0xed,
+	0x6b, 0x24, 0xcd, 0xd5, 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78,
+	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, 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,
+	0xc3, 0x96, 0x49, 0xc5, 0x5d, 0x7c, 0x48, 0xd8, 0xeb, 0x2c, 0xdf, 0xae,
+	0x5a, 0x92, 0x7c, 0x35, 0x67, 0xe3, 0x0c, 0xbd, 0xcb, 0xa6, 0x71, 0xfb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7a, 0x83, 0xce, 0xe1, 0xec, 0xbf, 0xbe, 0x7d, 0xce, 0x32, 0xd0, 0x3c,
+	0x06, 0x30, 0x15, 0x77, 0xa9, 0x35, 0x49, 0xc4, 0x58, 0x10, 0xf5, 0xc3,
+	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, 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,
+	0x6f, 0x5e, 0xf8, 0x89, 0x66, 0xe3, 0xea, 0xd3, 0xf2, 0x9e, 0x6f, 0xea,
+	0xdf, 0xc9, 0xbf, 0x1a, 0xce, 0x21, 0x6b, 0xb8, 0x45, 0x20, 0x06, 0xe0,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0xb9, 0x09, 0x2d, 0x92, 0x7b, 0x37, 0x79, 0x1d, 0x0a, 0xeb, 0x4b,
+	0xb5, 0xb8, 0x0a, 0x20, 0xd9, 0x8a, 0x2e, 0xe2, 0x5a, 0xae, 0xc9, 0x58,
+	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, 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,
+	0xb1, 0x99, 0x63, 0xd8, 0xc0, 0xa1, 0xe3, 0x40, 0x47, 0x30, 0xd4, 0xf4,
+	0x80, 0xd1, 0x09, 0x0b, 0x51, 0xa5, 0x81, 0xd9, 0x18, 0x4a, 0xc7, 0x37,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xec, 0xc5, 0x67, 0x31, 0xe6, 0x99, 0x12, 0xa5, 0x7c, 0xdf, 0xce, 0xa0,
+	0x2f, 0x68, 0x3f, 0x16, 0x5b, 0xd8, 0x1e, 0xe2, 0xe0, 0xbb, 0x9f, 0x6e,
+	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, 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,
+	0xe4, 0xb1, 0x5a, 0x2d, 0xd4, 0xf4, 0x33, 0x74, 0x07, 0x57, 0xee, 0xa7,
+	0xf2, 0x92, 0xc3, 0x41, 0x0c, 0x73, 0x06, 0x91, 0xd0, 0xf8, 0xdc, 0x24,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xdf, 0x79, 0x78, 0x90, 0xbb, 0xf4, 0x5e, 0x00, 0x00, 0x8a, 0x9e, 0x83,
+	0xe9, 0xde, 0x87, 0x08, 0x31, 0xb2, 0x4c, 0x31, 0x93, 0x54, 0xde, 0x3e,
+	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, 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,
+	0xcb, 0x5e, 0xc0, 0x43, 0xdd, 0xf6, 0x3a, 0xba, 0xc9, 0x4c, 0x21, 0xd9,
+	0xf8, 0x4f, 0x41, 0xe1, 0xf0, 0xf4, 0x08, 0x83, 0x61, 0xd2, 0x44, 0x16,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf3, 0x75, 0x85, 0xb0, 0x40, 0x64, 0x95, 0xf7, 0xe5, 0xde, 0x3b, 0x5b,
+	0x16, 0xbc, 0xd0, 0xca, 0x27, 0x85, 0x3c, 0x1a, 0xe1, 0x3e, 0xa4, 0x88,
+	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, 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,
+	0xd0, 0x74, 0x23, 0x2a, 0x8e, 0x8a, 0xe6, 0x8f, 0x74, 0x9e, 0x52, 0x8e,
+	0xee, 0x29, 0xf7, 0xa9, 0x06, 0x11, 0xde, 0xa3, 0x97, 0x16, 0x46, 0x9f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x66, 0xb8, 0x67, 0xdd, 0x0d, 0x80, 0x43, 0xcc, 0x6a, 0x65, 0x46, 0x54,
+	0x3a, 0x72, 0x7d, 0xe6, 0xf9, 0x54, 0x60, 0x52, 0x83, 0x38, 0xbd, 0xc9,
+	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, 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,
+	0xb6, 0xeb, 0x71, 0x93, 0x0c, 0x5d, 0x8f, 0x50, 0x1c, 0x24, 0x5c, 0x02,
+	0xb9, 0x04, 0xb5, 0x96, 0x04, 0xbc, 0x1f, 0x71, 0x95, 0x1f, 0x75, 0x13,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0xd0, 0x91, 0x6e, 0xbe, 0x34, 0x80, 0x3d, 0x8b, 0xec, 0x94, 0x8a,
+	0x8c, 0x21, 0x96, 0x2a, 0x15, 0x00, 0x96, 0xe7, 0xfd, 0x69, 0xf8, 0xd0,
+	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, 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,
+	0xbd, 0x44, 0xff, 0xe8, 0xe7, 0x1a, 0xac, 0x0c, 0x7d, 0x69, 0xa0, 0xb0,
+	0x43, 0x22, 0xd0, 0x65, 0x9f, 0x56, 0xd9, 0x6c, 0xec, 0xa3, 0xba, 0x2a,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xee, 0x59, 0xf0, 0xd1, 0x25, 0xa5, 0x9d, 0xce, 0x83, 0x7d, 0x62, 0xdd,
+	0xc3, 0xf4, 0x57, 0x5a, 0xa4, 0xe0, 0x7f, 0xb3, 0x35, 0xde, 0x73, 0xd9,
+	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, 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,
+	0xec, 0x76, 0x76, 0x0c, 0x1c, 0xf4, 0x6a, 0xe2, 0xff, 0x54, 0x98, 0x32,
+	0xa3, 0x3d, 0x44, 0xb0, 0xe9, 0x5a, 0xd2, 0x10, 0xf3, 0x18, 0x5c, 0x11,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x27, 0x3e, 0x5e, 0xc5, 0x38, 0xed, 0x37, 0x2e, 0x51, 0xd3, 0x91, 0x36,
+	0xb0, 0xab, 0x11, 0x69, 0xa5, 0xea, 0x86, 0xf6, 0x8f, 0x3a, 0x27, 0xc8,
+	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, 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,
+	0x29, 0x12, 0x37, 0xea, 0x74, 0xd2, 0xd7, 0xd5, 0x95, 0x36, 0x36, 0xee,
+	0x56, 0x33, 0x8e, 0x9b, 0x0d, 0xa6, 0x5e, 0x86, 0x28, 0x5c, 0x12, 0x0c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x13, 0x02, 0xf0, 0x4c, 0xf1, 0x3c, 0x32, 0x33, 0xfc, 0x89, 0x8a, 0xb9,
+	0x97, 0x83, 0x91, 0xb2, 0x26, 0xd6, 0x5c, 0x2e, 0x3a, 0xa0, 0x62, 0x72,
+	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, 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,
+	0xd5, 0x09, 0x47, 0xa8, 0x18, 0xc5, 0xef, 0xe6, 0x45, 0xdb, 0x23, 0xae,
+	0xfe, 0x11, 0x3c, 0x6c, 0x91, 0xf1, 0x99, 0xf2, 0xe5, 0xbb, 0xe8, 0x6d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x37, 0x68, 0x81, 0xb6, 0x60, 0xfe, 0xc0, 0x64, 0x38, 0x73, 0x43, 0xe9,
+	0x47, 0x5d, 0xae, 0xa4, 0xec, 0xcd, 0x57, 0xe8, 0xac, 0x8d, 0x8a, 0x19,
+	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, 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,
+	0xc9, 0xfe, 0xf5, 0xb9, 0x5b, 0x51, 0x02, 0x28, 0x37, 0x4c, 0x0a, 0x4c,
+	0x19, 0x2e, 0xbc, 0xd6, 0x22, 0x98, 0xf2, 0x04, 0xce, 0x6a, 0x83, 0xf9,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x46, 0xe4, 0xb8, 0x20, 0xf4, 0xc5, 0x74, 0xd0, 0x06, 0xd5, 0x86, 0x44,
+	0xef, 0xeb, 0x2c, 0xc0, 0xe7, 0x13, 0xa4, 0x00, 0x10, 0xc3, 0xc9, 0x49,
+	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, 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,
+	0x61, 0x78, 0xcb, 0x0e, 0x2d, 0x64, 0xee, 0xdf, 0x27, 0xaf, 0x7d, 0x5e,
+	0xb8, 0x5e, 0x1f, 0x99, 0xd8, 0x73, 0xce, 0xd7, 0x6c, 0xb7, 0xbe, 0x1f,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xef, 0xc9, 0x12, 0x9c, 0x52, 0xa6, 0x7f, 0x9c, 0xa3, 0xd7, 0xb9, 0x57,
+	0x60, 0x04, 0xd9, 0xad, 0xfc, 0x59, 0x98, 0x08, 0xdc, 0x41, 0xf8, 0xe2,
+	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, 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,
+	0xbb, 0x6c, 0x6b, 0x59, 0x7f, 0xdf, 0x92, 0x8a, 0xad, 0x16, 0x7e, 0xf0,
+	0xd7, 0xf9, 0x3b, 0xf4, 0xfa, 0xa9, 0xe4, 0x32, 0x15, 0x4e, 0x06, 0x1c,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x0c, 0x3d, 0x0d, 0x63, 0xd5, 0x2c, 0x8f, 0x3f, 0x61, 0x01, 0xb2, 0xbe,
+	0xd5, 0xf7, 0xe0, 0x8f, 0xd8, 0x77, 0xcd, 0xdd, 0xd6, 0xae, 0x3c, 0xf3,
+	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, 0x01
+};
+
+static const uint8_t fpm_table_p224[CPT_P224_LEN] = {
+	0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c, 0x1d, 0x21, 0x4a, 0x03, 0xc1, 0xd3,
+	0x56, 0xc2, 0x11, 0x22, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, 0x90, 0xb9,
+	0x00, 0x00, 0x00, 0x00, 0xb7, 0x0e, 0x0c, 0xbd, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34, 0xcd, 0x43, 0x75, 0xa0,
+	0x5a, 0x07, 0x47, 0x64, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
+	0x00, 0x00, 0x00, 0x00, 0xbd, 0x37, 0x63, 0x88, 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,
+	0xc8, 0xae, 0x4d, 0x94, 0xff, 0x48, 0xdb, 0xc5, 0xb5, 0xc8, 0x8b, 0x66,
+	0x32, 0xc8, 0x7a, 0x44, 0x66, 0xc7, 0x27, 0x87, 0x2b, 0x8d, 0x08, 0x1c,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0xe5, 0xde, 0x8b, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc6, 0xf8, 0x1e, 0x08, 0x47, 0xfb, 0x64, 0xdb, 0xc8, 0xe3, 0x75, 0x3e,
+	0x9d, 0x5a, 0x58, 0x31, 0xa2, 0x13, 0x38, 0x8c, 0x65, 0x8a, 0x02, 0xae,
+	0x00, 0x00, 0x00, 0x00, 0xde, 0x52, 0x6c, 0x0d, 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,
+	0xee, 0x8f, 0x93, 0x0d, 0x2b, 0x30, 0x9e, 0xe8, 0xb6, 0x78, 0xea, 0x1a,
+	0x0f, 0x59, 0x7e, 0x02, 0x14, 0x74, 0x52, 0x56, 0x6c, 0x25, 0x7d, 0x3e,
+	0x00, 0x00, 0x00, 0x00, 0x09, 0xbe, 0x54, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf6, 0x12, 0x1f, 0xdd, 0x96, 0xa2, 0x05, 0xda, 0x12, 0xa8, 0xe4, 0xf9,
+	0x98, 0x15, 0x8e, 0xe1, 0x1b, 0x1d, 0x05, 0x44, 0x47, 0xf2, 0xc3, 0x3a,
+	0x00, 0x00, 0x00, 0x00, 0x32, 0xf7, 0x1c, 0x32, 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,
+	0x26, 0x73, 0x99, 0x28, 0x0e, 0x4e, 0x09, 0x58, 0x79, 0xab, 0xae, 0x5c,
+	0xa8, 0xeb, 0x9c, 0x0b, 0xe9, 0xa8, 0xac, 0xf0, 0x74, 0x0e, 0xa3, 0x35,
+	0x00, 0x00, 0x00, 0x00, 0x0f, 0xb6, 0xce, 0x42, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x92, 0x09, 0xdc, 0xfe, 0x40, 0x85, 0x7c, 0x64, 0xa2, 0x3f, 0xe4, 0x34,
+	0x50, 0xb4, 0x25, 0x87, 0x2a, 0x6f, 0x38, 0x62, 0xb6, 0xfe, 0x44, 0xb1,
+	0x00, 0x00, 0x00, 0x00, 0x9e, 0xd1, 0x3b, 0x1b, 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,
+	0xf9, 0xfb, 0xf4, 0x91, 0x9a, 0x5f, 0x1c, 0x42, 0x56, 0x8b, 0xc4, 0x34,
+	0x8a, 0x69, 0xdd, 0x65, 0x3d, 0x01, 0x11, 0x6e, 0x47, 0x78, 0xdf, 0x49,
+	0x00, 0x00, 0x00, 0x00, 0x56, 0x65, 0xff, 0xd2, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0x4b, 0x80, 0x12, 0xe5, 0x3d, 0x3f, 0xb4, 0xe7, 0x61, 0x44, 0x25,
+	0x89, 0xec, 0x86, 0x76, 0x1f, 0xde, 0x69, 0x6f, 0xcb, 0x2b, 0xe1, 0x15,
+	0x00, 0x00, 0x00, 0x00, 0xc5, 0xf0, 0x98, 0xeb, 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,
+	0xe6, 0xf2, 0x88, 0xf1, 0x39, 0xb0, 0xa5, 0xad, 0x0c, 0x76, 0x16, 0x85,
+	0x58, 0x72, 0xd0, 0x94, 0x8a, 0xbc, 0x69, 0xb6, 0x6d, 0x7a, 0xc7, 0xfb,
+	0x00, 0x00, 0x00, 0x00, 0x64, 0xe1, 0x68, 0x02, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe1, 0x94, 0x7b, 0x17, 0x96, 0xa9, 0x76, 0xcf, 0x67, 0x78, 0x38, 0x8a,
+	0xd9, 0xb7, 0x68, 0xd7, 0x75, 0x39, 0xb7, 0x24, 0x17, 0x76, 0xa8, 0x39,
+	0x00, 0x00, 0x00, 0x00, 0xb4, 0xdb, 0x5a, 0x94, 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,
+	0x86, 0x5a, 0x09, 0xbe, 0xdf, 0x5b, 0x10, 0x74, 0x74, 0xc0, 0xce, 0xf5,
+	0x95, 0xab, 0xef, 0xf7, 0xba, 0x69, 0x9c, 0xe4, 0x14, 0xb3, 0x90, 0xb1,
+	0x00, 0x00, 0x00, 0x00, 0xc0, 0xca, 0x10, 0xcb, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x55, 0x87, 0xbb, 0x19, 0x41, 0x02, 0x67, 0xde, 0xa7, 0x71, 0xb8, 0xce,
+	0xa6, 0x3f, 0xcc, 0x78, 0xbc, 0xa5, 0x91, 0x7d, 0x0e, 0x8d, 0x16, 0x65,
+	0x00, 0x00, 0x00, 0x00, 0x63, 0x9e, 0x9e, 0x20, 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,
+	0xe8, 0xb7, 0x37, 0x97, 0x4e, 0x1b, 0xfb, 0x82, 0x16, 0x71, 0x58, 0x39,
+	0x55, 0xb6, 0x32, 0xb8, 0xf6, 0x75, 0x2f, 0xdd, 0x34, 0x7a, 0x0d, 0x7b,
+	0x00, 0x00, 0x00, 0x00, 0xff, 0x24, 0xb5, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xea, 0xce, 0x1f, 0x14, 0x00, 0xe2, 0xe0, 0x16, 0x71, 0xe5, 0x9b, 0x8c,
+	0x60, 0x8d, 0x20, 0x97, 0x2b, 0x07, 0xec, 0x89, 0x89, 0x37, 0x5d, 0x09,
+	0x00, 0x00, 0x00, 0x00, 0xc3, 0xe2, 0x8c, 0xdc, 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,
+	0x9a, 0x88, 0x5f, 0xdf, 0xf5, 0x12, 0x07, 0xbf, 0xc5, 0xbd, 0xd8, 0x15,
+	0x01, 0x55, 0x75, 0x02, 0xf1, 0x96, 0x50, 0x03, 0x6b, 0xbd, 0xd0, 0x72,
+	0x00, 0x00, 0x00, 0x00, 0xda, 0x9b, 0x7e, 0x0c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0xa7, 0x4c, 0xce, 0x47, 0xb9, 0x7d, 0x42, 0xf7, 0xb5, 0x5d, 0x63,
+	0x28, 0xf5, 0xde, 0x75, 0x06, 0x13, 0xe9, 0x5d, 0x9b, 0x48, 0x88, 0x67,
+	0x00, 0x00, 0x00, 0x00, 0xd6, 0x05, 0x07, 0x13, 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,
+	0xa4, 0xee, 0x4e, 0xe7, 0xb4, 0x4a, 0xda, 0x48, 0xe3, 0x67, 0x5f, 0xf9,
+	0x15, 0xda, 0x1a, 0x27, 0x33, 0x6b, 0x97, 0x6a, 0x82, 0x0d, 0xa0, 0x86,
+	0x00, 0x00, 0x00, 0x00, 0x5b, 0x6e, 0x9f, 0xfd, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf5, 0x2c, 0xd8, 0x87, 0x2f, 0xf4, 0xa8, 0x85, 0x53, 0x29, 0x86, 0xf1,
+	0xb9, 0x1a, 0x28, 0xdc, 0xaf, 0x35, 0x40, 0xdd, 0x75, 0xbf, 0x86, 0x56,
+	0x00, 0x00, 0x00, 0x00, 0xce, 0x4f, 0x78, 0xa9, 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,
+	0x4d, 0x51, 0xfa, 0xb9, 0xe8, 0x49, 0xeb, 0x79, 0xd4, 0xc3, 0x0d, 0x04,
+	0xdd, 0xf6, 0xb1, 0xcd, 0x6d, 0x51, 0xe5, 0x58, 0x06, 0x2a, 0x7e, 0x65,
+	0x00, 0x00, 0x00, 0x00, 0xe6, 0xe4, 0xf0, 0x9a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe0, 0x85, 0xf1, 0x4f, 0xe7, 0x07, 0x60, 0xb5, 0x45, 0x7a, 0xc8, 0x3d,
+	0xf3, 0x26, 0xd8, 0xb0, 0xc7, 0x94, 0x33, 0x72, 0x7e, 0xef, 0x87, 0x70,
+	0x00, 0x00, 0x00, 0x00, 0x74, 0x6d, 0x83, 0xb0, 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,
+	0x7a, 0x24, 0xee, 0x7e, 0x21, 0x7b, 0x0a, 0x33, 0x4e, 0xa1, 0x1e, 0x5c,
+	0xca, 0x30, 0xf9, 0x68, 0xc2, 0xc4, 0x7d, 0x0a, 0xa0, 0xc7, 0xbe, 0xeb,
+	0x00, 0x00, 0x00, 0x00, 0xca, 0x62, 0xa6, 0x8b, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x5c, 0x26, 0x7c, 0x9c, 0xfb, 0xe5, 0x6a, 0x33, 0x89, 0x37, 0x74, 0x21,
+	0x13, 0x71, 0x46, 0x6b, 0x60, 0xd0, 0x38, 0xc4, 0x90, 0xef, 0x7d, 0xec,
+	0x00, 0x00, 0x00, 0x00, 0x27, 0xde, 0xcf, 0x82, 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,
+	0x23, 0x14, 0xf5, 0x42, 0xbe, 0x9e, 0x07, 0x9c, 0x4a, 0x60, 0x56, 0x3b,
+	0xcf, 0xe2, 0x06, 0x81, 0xb0, 0xc0, 0x46, 0x49, 0xfb, 0x97, 0x61, 0x5a,
+	0x00, 0x00, 0x00, 0x00, 0x2f, 0xa4, 0x2d, 0x2b, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x86, 0xe5, 0x99, 0xb4, 0xcf, 0x64, 0x05, 0x25, 0xa3, 0x44, 0xe4, 0x18,
+	0x5f, 0x72, 0x58, 0x47, 0x7f, 0xbd, 0x84, 0xd7, 0x0a, 0x38, 0xa0, 0xd4,
+	0x00, 0x00, 0x00, 0x00, 0x11, 0x8d, 0x15, 0xd5, 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,
+	0xe8, 0x5b, 0x13, 0xf0, 0x09, 0xc6, 0x14, 0x58, 0xc4, 0xf3, 0x1b, 0x3d,
+	0x17, 0x0f, 0x1c, 0xfa, 0x7d, 0x61, 0x7e, 0x7e, 0x9c, 0xea, 0x52, 0x0a,
+	0x00, 0x00, 0x00, 0x00, 0x89, 0x05, 0xdb, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x26, 0xf8, 0xab, 0x68, 0xb4, 0x27, 0x56, 0x1d, 0x04, 0xed, 0x8c, 0x65,
+	0xfd, 0xd1, 0x62, 0x2e, 0x80, 0x4c, 0x4a, 0x1d, 0x67, 0x90, 0x50, 0xed,
+	0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x2a, 0x4b, 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,
+	0x11, 0xe9, 0x36, 0x25, 0x8d, 0x97, 0x84, 0xea, 0xe9, 0x50, 0x4a, 0x27,
+	0x66, 0x6e, 0x0c, 0xd2, 0xce, 0x40, 0xfe, 0xfb, 0xf2, 0xc6, 0x53, 0xb4,
+	0x00, 0x00, 0x00, 0x00, 0xb6, 0x32, 0x22, 0x76, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xfc, 0x88, 0xcf, 0x76, 0x3c, 0x0b, 0x0d, 0x76, 0xb2, 0xc3, 0xc7, 0x8c,
+	0x8c, 0x53, 0x5f, 0x4c, 0xba, 0x0d, 0x13, 0xdb, 0x7b, 0xac, 0xf0, 0x19,
+	0x00, 0x00, 0x00, 0x00, 0x7e, 0x11, 0x95, 0x29, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static const uint8_t fpm_table_p256[CPT_P256_LEN] = {
+	0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x77, 0x03, 0x7d, 0x81,
+	0x2d, 0xeb, 0x33, 0xa0, 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
+	0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, 0x2b, 0xce, 0x33, 0x57,
+	0x6b, 0x31, 0x5e, 0xce, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+	0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 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,
+	0x90, 0xe7, 0x5c, 0xb4, 0x8e, 0x14, 0xdb, 0x63, 0x29, 0x49, 0x3b, 0xaa,
+	0xad, 0x65, 0x1f, 0x7e, 0x84, 0x92, 0x59, 0x2e, 0x32, 0x6e, 0x25, 0xde,
+	0x0f, 0xa8, 0x22, 0xbc, 0x28, 0x11, 0xaa, 0xa5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xe4, 0x11, 0x24, 0x54, 0x5f, 0x46, 0x2e, 0xe7, 0x34, 0xb1, 0xa6, 0x50,
+	0x50, 0xfe, 0x82, 0xf5, 0x6f, 0x4a, 0xd4, 0xbc, 0xb3, 0xdf, 0x18, 0x8b,
+	0xbf, 0xf4, 0x4a, 0xe8, 0xf5, 0xdb, 0xa8, 0x0d, 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,
+	0x93, 0x39, 0x1c, 0xe2, 0x09, 0x79, 0x92, 0xaf, 0xe9, 0x6c, 0x98, 0xfd,
+	0x0d, 0x35, 0xf1, 0xfa, 0xb2, 0x57, 0xc0, 0xde, 0x95, 0xe0, 0x27, 0x89,
+	0x30, 0x0a, 0x4b, 0xbc, 0x89, 0xd6, 0x72, 0x6f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaa, 0x54, 0xa2, 0x91, 0xc0, 0x81, 0x27, 0xa0, 0x5b, 0xb1, 0xee, 0xad,
+	0xa9, 0xd8, 0x06, 0xa5, 0x7f, 0x1d, 0xdb, 0x25, 0xff, 0x1e, 0x3c, 0x6f,
+	0x72, 0xaa, 0xc7, 0xe0, 0xd0, 0x9b, 0x46, 0x44, 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,
+	0x57, 0xc8, 0x4f, 0xc9, 0xd7, 0x89, 0xbd, 0x85, 0xfc, 0x35, 0xff, 0x7d,
+	0xc2, 0x97, 0xea, 0xc3, 0xfb, 0x98, 0x2f, 0xd5, 0x88, 0xc6, 0x76, 0x6e,
+	0x44, 0x7d, 0x73, 0x9b, 0xee, 0xdb, 0x5e, 0x67, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x0c, 0x7e, 0x33, 0xc9, 0x72, 0xe2, 0x5b, 0x32, 0x3d, 0x34, 0x9b, 0x95,
+	0xa7, 0xfa, 0xe5, 0x00, 0xe1, 0x2e, 0x9d, 0x95, 0x3a, 0x4a, 0xaf, 0xf7,
+	0x2d, 0x48, 0x25, 0xab, 0x83, 0x41, 0x31, 0xee, 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,
+	0x13, 0x94, 0x9c, 0x93, 0x2a, 0x1d, 0x36, 0x7f, 0xef, 0x7f, 0xbd, 0x2b,
+	0x1a, 0x0a, 0x11, 0xb7, 0xdd, 0xc6, 0x06, 0x8b, 0xb9, 0x1d, 0xfc, 0x60,
+	0xef, 0x95, 0x19, 0x32, 0x8a, 0x9c, 0x72, 0xff, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x19, 0x60, 0x35, 0xa7, 0x73, 0x76, 0xd8, 0xa8, 0x23, 0x18, 0x3b, 0x08,
+	0x95, 0xca, 0x17, 0x40, 0xc1, 0xee, 0x98, 0x07, 0x02, 0x2c, 0x21, 0x9c,
+	0x61, 0x1e, 0x9f, 0xc3, 0x7d, 0xbb, 0x2c, 0x9b, 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,
+	0xca, 0xe2, 0xb1, 0x92, 0x0b, 0x57, 0xf4, 0xbc, 0x29, 0x36, 0xdf, 0x5e,
+	0xc6, 0xc9, 0xbc, 0x36, 0x7d, 0xea, 0x64, 0x82, 0xe1, 0x12, 0x38, 0xbf,
+	0x55, 0x06, 0x63, 0x79, 0x7b, 0x51, 0xf5, 0xd8, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x44, 0xff, 0xe2, 0x16, 0x34, 0x8a, 0x96, 0x4c, 0x9f, 0xb3, 0xd5, 0x76,
+	0xdb, 0xde, 0xfb, 0xe1, 0x0a, 0xfa, 0x40, 0x01, 0x8d, 0x9d, 0x50, 0xe5,
+	0x15, 0x71, 0x64, 0x84, 0x8a, 0xec, 0xb8, 0x51, 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,
+	0xe4, 0x8e, 0xca, 0xff, 0xfc, 0x5c, 0xde, 0x01, 0x7c, 0xcd, 0x84, 0xe7,
+	0x0d, 0x71, 0x5f, 0x26, 0xa2, 0xe8, 0xf4, 0x83, 0xf4, 0x3e, 0x43, 0x91,
+	0xeb, 0x5d, 0x77, 0x45, 0xb2, 0x11, 0x41, 0xea, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xca, 0xc9, 0x17, 0xe2, 0x73, 0x1a, 0x34, 0x79, 0x85, 0xf2, 0x2c, 0xfe,
+	0x28, 0x44, 0xb6, 0x45, 0x09, 0x90, 0xe6, 0xa1, 0x58, 0x00, 0x6c, 0xee,
+	0xea, 0xfd, 0x72, 0xeb, 0xdb, 0xec, 0xc1, 0x7b, 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,
+	0x6c, 0xf2, 0x0f, 0xfb, 0x31, 0x37, 0x28, 0xbe, 0x96, 0x43, 0x95, 0x91,
+	0xa3, 0xc6, 0xb9, 0x4a, 0x27, 0x36, 0xff, 0x83, 0x44, 0x31, 0x5f, 0xc5,
+	0xa6, 0xd3, 0x96, 0x77, 0xa7, 0x84, 0x92, 0x76, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf2, 0xba, 0xb8, 0x33, 0xc3, 0x57, 0xf5, 0xf4, 0x82, 0x4a, 0x92, 0x0c,
+	0x22, 0x84, 0x05, 0x9b, 0x66, 0xb8, 0xba, 0xbd, 0x2d, 0x27, 0xec, 0xdf,
+	0x67, 0x4f, 0x84, 0x74, 0x9b, 0x0b, 0x88, 0x16, 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,
+	0x2d, 0xf4, 0x8c, 0x04, 0x67, 0x7c, 0x8a, 0x3e, 0x74, 0xe0, 0x2f, 0x08,
+	0x02, 0x03, 0xa5, 0x6b, 0x31, 0x85, 0x5f, 0x7d, 0xb8, 0xc7, 0xfe, 0xdb,
+	0x4e, 0x76, 0x9e, 0x76, 0x72, 0xc9, 0xdd, 0xad, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa4, 0xc3, 0x61, 0x65, 0xb8, 0x24, 0xbb, 0xb0, 0xfb, 0x9a, 0xe1, 0x6f,
+	0x3b, 0x91, 0x22, 0xa5, 0x1e, 0xc0, 0x05, 0x72, 0x06, 0x94, 0x72, 0x81,
+	0x42, 0xb9, 0x90, 0x82, 0xde, 0x83, 0x06, 0x63, 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,
+	0x6e, 0xf9, 0x51, 0x50, 0xdd, 0xa8, 0x68, 0xb9, 0xd1, 0xf8, 0x9e, 0x79,
+	0x9c, 0x0c, 0xe1, 0x31, 0x7f, 0xdc, 0x1c, 0xa0, 0x08, 0xa1, 0xc4, 0x78,
+	0x78, 0x87, 0x8e, 0xf6, 0x1c, 0x6c, 0xe0, 0x4d, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9c, 0x62, 0xb9, 0x12, 0x1f, 0xe0, 0xd9, 0x76, 0x6a, 0xce, 0x57, 0x0e,
+	0xbd, 0xe0, 0x8d, 0x4f, 0xde, 0x53, 0x14, 0x2c, 0x12, 0x30, 0x9d, 0xef,
+	0xb6, 0xcb, 0x3f, 0x5d, 0x7b, 0x72, 0xc3, 0x21, 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,
+	0x7f, 0x99, 0x1e, 0xd2, 0xc3, 0x1a, 0x35, 0x73, 0x5b, 0x82, 0xdd, 0x5b,
+	0xd5, 0x4f, 0xb4, 0x96, 0x59, 0x5c, 0x52, 0x20, 0x81, 0x2f, 0xfc, 0xae,
+	0x0c, 0x88, 0xbc, 0x4d, 0x71, 0x6b, 0x12, 0x87, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3a, 0x57, 0xbf, 0x63, 0x5f, 0x48, 0xac, 0xa8, 0x7c, 0x81, 0x81, 0xf4,
+	0xdf, 0x25, 0x64, 0xf3, 0x18, 0xd1, 0xb5, 0xb3, 0x9c, 0x04, 0xe6, 0xaa,
+	0xdd, 0x5d, 0xde, 0xa3, 0xf3, 0x90, 0x1d, 0xc6, 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,
+	0xe9, 0x6a, 0x79, 0xfb, 0x3e, 0x72, 0xad, 0x0c, 0x43, 0xa0, 0xa2, 0x8c,
+	0x42, 0xba, 0x79, 0x2f, 0xef, 0xe0, 0xa4, 0x23, 0x08, 0x3e, 0x49, 0xf3,
+	0x68, 0xf3, 0x44, 0xaf, 0x6b, 0x31, 0x74, 0x66, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xcd, 0xfe, 0x17, 0xdb, 0x3f, 0xb2, 0x4d, 0x4a, 0x66, 0x8b, 0xfc, 0x22,
+	0x71, 0xf5, 0xc6, 0x26, 0x60, 0x4e, 0xd9, 0x3c, 0x24, 0xd6, 0x7f, 0xf3,
+	0x31, 0xb9, 0xc4, 0x05, 0xf8, 0x54, 0x0a, 0x20, 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,
+	0xd3, 0x6b, 0x47, 0x89, 0xa2, 0x58, 0x2e, 0x7f, 0x0d, 0x1a, 0x10, 0x14,
+	0x4e, 0xc3, 0x9c, 0x28, 0x66, 0x3c, 0x62, 0xc3, 0xed, 0xba, 0xd7, 0xa0,
+	0x40, 0x52, 0xbf, 0x4b, 0x6f, 0x46, 0x1d, 0xb9, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x23, 0x5a, 0x27, 0xc3, 0x18, 0x8d, 0x25, 0xeb, 0xe7, 0x24, 0xf3, 0x39,
+	0x99, 0xbf, 0xcc, 0x5b, 0x86, 0x2b, 0xe6, 0xbd, 0x71, 0xd7, 0x0c, 0xc8,
+	0xfe, 0xcf, 0x4d, 0x51, 0x90, 0xb0, 0xfc, 0x61, 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,
+	0x74, 0x34, 0x6c, 0x10, 0xa1, 0xd4, 0xcf, 0xac, 0xaf, 0xdf, 0x5c, 0xc0,
+	0x85, 0x26, 0xa7, 0xa4, 0x12, 0x32, 0x02, 0xa8, 0xf6, 0x2b, 0xff, 0x7a,
+	0x1e, 0xdd, 0xba, 0xe2, 0xc8, 0x02, 0xe4, 0x1a, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x8f, 0xa0, 0xaf, 0x2d, 0xd6, 0x03, 0xf8, 0x44, 0x36, 0xe0, 0x6b, 0x7e,
+	0x4c, 0x70, 0x19, 0x17, 0x0c, 0x45, 0xf4, 0x52, 0x73, 0xdb, 0x33, 0xa0,
+	0x43, 0x10, 0x4d, 0x86, 0x56, 0x0e, 0xbc, 0xfc, 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,
+	0x96, 0x15, 0xb5, 0x11, 0x0d, 0x1d, 0x78, 0xe5, 0x66, 0xb0, 0xde, 0x32,
+	0x25, 0xc4, 0x74, 0x4b, 0x0a, 0x4a, 0x46, 0xfb, 0x6a, 0xaf, 0x36, 0x3a,
+	0xb4, 0x8e, 0x26, 0xb4, 0x84, 0xf7, 0xa2, 0x1c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x06, 0xeb, 0xb0, 0xf6, 0x21, 0xa0, 0x1b, 0x2d, 0xc0, 0x04, 0xe4, 0x04,
+	0x8b, 0x7b, 0x0f, 0x98, 0x64, 0x13, 0x1b, 0xcd, 0xfe, 0xd6, 0xf6, 0x68,
+	0xfa, 0xc0, 0x15, 0x40, 0x4d, 0x4d, 0x3d, 0xab, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static const uint8_t fpm_table_p384[CPT_P384_LEN] = {
+	0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, 0x55, 0x02, 0xf2, 0x5d,
+	0xbf, 0x55, 0x29, 0x6c, 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38,
+	0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x8e, 0xb1, 0xc7, 0x1e,
+	0xf3, 0x20, 0xad, 0x74, 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x43, 0x1d, 0x7c,
+	0x90, 0xea, 0x0e, 0x5f, 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d,
+	0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0xf8, 0xf4, 0x1d, 0xbd,
+	0x28, 0x9a, 0x14, 0x7c, 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29,
+	0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 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,
+	0x39, 0xc1, 0xb3, 0x28, 0xd8, 0xee, 0x21, 0xc9, 0x2c, 0x3e, 0x0c, 0x91,
+	0x55, 0x87, 0x17, 0xdb, 0x4b, 0x58, 0x80, 0x8b, 0x3f, 0x86, 0x86, 0xa9,
+	0x43, 0x60, 0x39, 0x09, 0x18, 0x14, 0x1b, 0x1a, 0xd6, 0xe9, 0x8b, 0x0d,
+	0x37, 0xca, 0x7a, 0xbc, 0xf5, 0x32, 0x38, 0x9a, 0x06, 0x0c, 0xbd, 0x1b,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x7e, 0x18, 0x39,
+	0x23, 0xd8, 0x6e, 0xcd, 0x31, 0xea, 0x31, 0xb1, 0x08, 0x5a, 0x4e, 0x9a,
+	0xbc, 0x40, 0xce, 0x5a, 0xbe, 0x64, 0x36, 0x03, 0xbd, 0x22, 0xcf, 0xb2,
+	0xa2, 0x12, 0x41, 0x63, 0x6f, 0x04, 0xca, 0xa2, 0xde, 0x3a, 0x82, 0xba,
+	0xb9, 0xd2, 0x85, 0x2c, 0xc3, 0xb3, 0x8e, 0x69, 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,
+	0x26, 0x4e, 0x52, 0x46, 0xeb, 0x09, 0xa0, 0xe5, 0xf8, 0xf4, 0xbe, 0x11,
+	0x32, 0xcd, 0xf0, 0x3c, 0xda, 0x9d, 0x54, 0x83, 0x5f, 0xae, 0xfa, 0x4f,
+	0xbb, 0xbc, 0x4f, 0xd0, 0x17, 0xa3, 0x1b, 0x22, 0xc3, 0xde, 0xcd, 0x0c,
+	0x86, 0xf0, 0x61, 0x45, 0x52, 0x8e, 0xf1, 0x67, 0x0a, 0x5f, 0x2c, 0xab,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x1e, 0x98, 0x58,
+	0xc1, 0x4f, 0x0d, 0xd6, 0x55, 0x05, 0x38, 0xa8, 0x09, 0xcb, 0x75, 0x24,
+	0xbd, 0x60, 0xca, 0xb4, 0xc8, 0x7f, 0xed, 0x22, 0xf8, 0xb7, 0x6f, 0xdd,
+	0x63, 0x1d, 0x05, 0x8d, 0x58, 0x03, 0xea, 0xa1, 0x1a, 0x1d, 0xcf, 0x14,
+	0x7b, 0x9b, 0x1f, 0xbe, 0x7b, 0xcc, 0xf5, 0x6c, 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,
+	0xa6, 0x28, 0xb0, 0x9a, 0xaa, 0x03, 0xbd, 0x53, 0xba, 0x06, 0x54, 0x58,
+	0xa4, 0xf5, 0x2d, 0x78, 0xdb, 0x29, 0x87, 0x89, 0x4d, 0x10, 0xdd, 0xea,
+	0xb4, 0x2a, 0x31, 0xaf, 0x8a, 0x3e, 0x29, 0x7d, 0x40, 0xf7, 0xf9, 0xe7,
+	0x06, 0x42, 0x12, 0x79, 0xc1, 0x9e, 0x0b, 0x4c, 0x80, 0x01, 0x19, 0xc4,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x2d, 0x0f, 0xc5,
+	0xe6, 0xc8, 0x8c, 0x41, 0xaf, 0x68, 0xaa, 0x6d, 0xe6, 0x39, 0xd8, 0x58,
+	0xc1, 0xc7, 0xca, 0xd1, 0x35, 0xf6, 0xeb, 0xf2, 0x57, 0x7a, 0x30, 0xea,
+	0xe3, 0x56, 0x7a, 0xf9, 0xe5, 0xa0, 0x19, 0x1d, 0x1f, 0x5b, 0x77, 0xf6,
+	0x16, 0xf3, 0xfd, 0xbf, 0x03, 0x56, 0xb3, 0x01, 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,
+	0x30, 0x99, 0x15, 0x60, 0xaa, 0x13, 0x39, 0x09, 0x90, 0x97, 0xdb, 0xb1,
+	0xc6, 0xcb, 0x00, 0x17, 0xd3, 0x7d, 0xe4, 0x24, 0xb8, 0x60, 0xfa, 0xe6,
+	0x9b, 0xb1, 0x83, 0xb2, 0x70, 0xb3, 0x75, 0xdd, 0x56, 0x7a, 0x62, 0x33,
+	0xcd, 0x6c, 0xe3, 0xa3, 0xaa, 0xb8, 0xbb, 0x9f, 0x0f, 0xdc, 0x30, 0x88,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xc5, 0xb9, 0x81,
+	0x60, 0x0a, 0xd5, 0xa6, 0xeb, 0xdf, 0x73, 0xf2, 0xd6, 0x2f, 0xaa, 0x44,
+	0x6d, 0x95, 0x5b, 0xb3, 0xc9, 0x74, 0x7b, 0xf3, 0xf6, 0x00, 0x5f, 0xc8,
+	0x15, 0xeb, 0x04, 0xac, 0xf0, 0xaf, 0x01, 0xd1, 0x28, 0x20, 0x50, 0xb5,
+	0x48, 0x94, 0x2f, 0x81, 0x31, 0x4f, 0x6d, 0x28, 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,
+	0x20, 0x22, 0x11, 0x21, 0x77, 0x16, 0x60, 0x5e, 0x23, 0x47, 0xd2, 0xc8,
+	0x9e, 0xf2, 0x81, 0xc8, 0x54, 0xba, 0x45, 0x99, 0x56, 0x7d, 0x63, 0x42,
+	0xce, 0x0f, 0xba, 0x30, 0x77, 0xc0, 0xf0, 0x3f, 0x70, 0x22, 0xf8, 0x02,
+	0xcb, 0x36, 0x74, 0x44, 0x73, 0x34, 0xa9, 0x36, 0xa9, 0xa6, 0xa0, 0x52,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x46, 0x1f, 0x68,
+	0xd6, 0x58, 0xa0, 0x1a, 0x0a, 0x64, 0xd5, 0x19, 0xc2, 0xbd, 0x0e, 0xfa,
+	0x9e, 0x2e, 0xee, 0x8f, 0x69, 0x7a, 0x92, 0x80, 0x8e, 0x5d, 0x9b, 0x89,
+	0x7d, 0x0e, 0x01, 0x7a, 0x1f, 0x7c, 0x5c, 0x36, 0x7c, 0xbd, 0x4c, 0xcd,
+	0x7f, 0xfc, 0xef, 0xf7, 0xf6, 0x32, 0xc9, 0x26, 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,
+	0x30, 0x0a, 0xe2, 0xe6, 0x0e, 0x75, 0x83, 0x44, 0x45, 0x1c, 0x70, 0x7a,
+	0x37, 0x1a, 0x2c, 0xa5, 0x25, 0x65, 0x1d, 0x10, 0x50, 0x52, 0xdd, 0x32,
+	0xbf, 0x88, 0xde, 0x7f, 0x48, 0x62, 0xb9, 0x54, 0xfa, 0xfc, 0xe2, 0x6e,
+	0x03, 0x81, 0xef, 0x13, 0xdc, 0x91, 0x6c, 0x17, 0x96, 0x0e, 0x09, 0x0e,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x17, 0xcc, 0x44,
+	0x02, 0x6b, 0x08, 0x89, 0x95, 0xc0, 0x1f, 0xf1, 0x9b, 0x42, 0x44, 0x1b,
+	0x40, 0x89, 0x64, 0x78, 0xcc, 0x16, 0x06, 0x97, 0x52, 0xd1, 0x54, 0xb8,
+	0x0b, 0xa0, 0x4a, 0x35, 0xb3, 0xd9, 0x2e, 0xa4, 0x70, 0x1c, 0x29, 0x52,
+	0x26, 0x6e, 0x8a, 0x40, 0xd6, 0x9e, 0xca, 0x0a, 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,
+	0xe4, 0xbf, 0xc2, 0xc0, 0x49, 0x05, 0xca, 0x71, 0xf3, 0x3a, 0x45, 0x0a,
+	0xd1, 0x56, 0xf7, 0x61, 0x3d, 0x8b, 0x29, 0xdb, 0xd0, 0x88, 0x48, 0xc2,
+	0x09, 0x7d, 0xa3, 0x95, 0xa2, 0x30, 0x96, 0x86, 0x21, 0x19, 0x05, 0x03,
+	0x5f, 0x49, 0x72, 0xd7, 0xb2, 0xd1, 0x05, 0x58, 0x17, 0xcb, 0xaa, 0x12,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0xce, 0xbb, 0x55,
+	0x75, 0x3e, 0xe3, 0x24, 0xe8, 0x7a, 0xb0, 0x7c, 0x69, 0x24, 0x66, 0x6f,
+	0x9b, 0x47, 0x5d, 0x74, 0x4e, 0xcf, 0x1a, 0x68, 0xf8, 0x2b, 0xe8, 0xf5,
+	0x2e, 0x62, 0x36, 0xc0, 0x23, 0x7c, 0x0d, 0xba, 0x3c, 0xfd, 0x05, 0x6b,
+	0x35, 0x4c, 0xd8, 0x72, 0xc3, 0xc6, 0xcb, 0xd2, 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,
+	0x8d, 0x10, 0x4d, 0x24, 0x70, 0x8d, 0x4c, 0xee, 0x19, 0x7d, 0x69, 0x58,
+	0x81, 0x9c, 0xf0, 0x43, 0x47, 0xfc, 0x87, 0xfa, 0xf0, 0x71, 0x22, 0x10,
+	0x10, 0x3d, 0xf7, 0x85, 0x5c, 0x20, 0x15, 0x58, 0x30, 0xb0, 0xa9, 0xe8,
+	0x61, 0x1e, 0xf6, 0x38, 0x00, 0xb1, 0x9a, 0xc8, 0xfd, 0xfe, 0xbf, 0xec,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0e, 0x8d, 0x6f,
+	0xd2, 0x01, 0xe0, 0x3e, 0xbb, 0x7c, 0x96, 0x9c, 0x22, 0x28, 0xff, 0x5f,
+	0x68, 0x81, 0x02, 0x82, 0x63, 0x61, 0x64, 0xc5, 0xcd, 0xbb, 0x3c, 0xd2,
+	0xe7, 0x54, 0x22, 0x0d, 0x14, 0x18, 0xfe, 0x25, 0xe9, 0xf6, 0xed, 0xc4,
+	0xa7, 0x2f, 0x91, 0x05, 0x9e, 0xe3, 0x60, 0x31, 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,
+	0x64, 0xd2, 0xc2, 0x73, 0xb7, 0x69, 0x73, 0x7a, 0x2c, 0xc0, 0x24, 0x51,
+	0x97, 0xd5, 0x3f, 0xfd, 0xc3, 0xb6, 0xac, 0x4b, 0xe8, 0x6c, 0x46, 0xbd,
+	0x17, 0xe9, 0x41, 0x1f, 0x68, 0x5e, 0x92, 0x6d, 0x13, 0x6d, 0xf3, 0x6b,
+	0x75, 0x20, 0x3a, 0x36, 0x3f, 0x95, 0x61, 0xe0, 0x8b, 0xf0, 0xb2, 0x7e,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x6f, 0xf8, 0xd5,
+	0x27, 0xe9, 0x90, 0xa7, 0xc3, 0x4b, 0xe5, 0x86, 0xf9, 0x86, 0x7a, 0x60,
+	0xea, 0x08, 0x87, 0x47, 0x85, 0x54, 0xe0, 0x14, 0xcf, 0xce, 0xd6, 0x64,
+	0x6f, 0x52, 0xe4, 0xcb, 0x4b, 0x1a, 0x5a, 0x20, 0x41, 0x2a, 0xb6, 0x41,
+	0x0b, 0x06, 0xf0, 0x06, 0x39, 0x62, 0x95, 0x87, 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,
+	0x04, 0x4c, 0x0d, 0xd2, 0x85, 0x65, 0x1f, 0x82, 0x32, 0x5c, 0x51, 0xe7,
+	0x78, 0x5d, 0x3e, 0xf7, 0xb8, 0x3a, 0x18, 0x61, 0x88, 0xe9, 0x55, 0x32,
+	0x53, 0x9f, 0x94, 0xad, 0x52, 0x2c, 0x29, 0x31, 0x15, 0x27, 0x4e, 0x5b,
+	0x89, 0x80, 0xf1, 0x37, 0x9f, 0xd7, 0xb0, 0x10, 0xdf, 0x0f, 0x66, 0xd7,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0xa7, 0xb9, 0x4a,
+	0x40, 0x64, 0xe4, 0xc0, 0xd4, 0x4e, 0xba, 0x45, 0x25, 0xd7, 0xd2, 0x11,
+	0x0a, 0x80, 0x6b, 0x54, 0xbe, 0x8a, 0x04, 0xe3, 0x92, 0x92, 0x26, 0xbd,
+	0x14, 0x90, 0x33, 0xde, 0x79, 0x5f, 0x6f, 0xa3, 0xc9, 0x73, 0x92, 0x46,
+	0x32, 0x1a, 0xa9, 0xa3, 0xb9, 0x26, 0x02, 0x25, 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,
+	0x49, 0xbc, 0xc2, 0xf5, 0x8b, 0x70, 0x7b, 0x8e, 0x29, 0x01, 0xb5, 0x19,
+	0x1d, 0x92, 0x89, 0x83, 0x2e, 0x4c, 0x29, 0x56, 0x7d, 0x49, 0xc7, 0x80,
+	0xeb, 0xd1, 0xcf, 0xf8, 0x4c, 0x6a, 0x99, 0x64, 0x2c, 0xae, 0xbb, 0xd3,
+	0x16, 0xee, 0x3e, 0x13, 0x36, 0xa5, 0x43, 0xee, 0xa8, 0x7a, 0x68, 0xf7,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0xb4, 0x1c, 0x29,
+	0xb5, 0x69, 0x94, 0x6d, 0x15, 0x10, 0xe7, 0xd4, 0x3e, 0xf2, 0x26, 0x7e,
+	0x91, 0x23, 0x50, 0x72, 0xd4, 0xb3, 0x39, 0x4d, 0x58, 0xea, 0xff, 0x04,
+	0x8f, 0xbd, 0x85, 0xd1, 0xd3, 0x49, 0xab, 0x03, 0x78, 0xa6, 0x78, 0x47,
+	0xf2, 0x77, 0xba, 0xcd, 0xa5, 0x0e, 0xe4, 0x1c, 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,
+	0x10, 0xb0, 0x56, 0x58, 0x5f, 0x86, 0x3b, 0xbd, 0xe9, 0x2c, 0xdc, 0x5a,
+	0xb4, 0x83, 0x28, 0x3d, 0xeb, 0xb3, 0x12, 0x09, 0xdc, 0x7c, 0x42, 0x1d,
+	0x3a, 0xfc, 0xbd, 0x79, 0x6d, 0x01, 0xa5, 0xa8, 0xe2, 0xb0, 0x67, 0xca,
+	0xa0, 0x8b, 0x6a, 0x51, 0x02, 0x6e, 0x0d, 0xc2, 0xe8, 0xcb, 0x7a, 0xeb,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xc3, 0x50, 0x29,
+	0x02, 0xdd, 0xe1, 0x8a, 0x64, 0xc1, 0x5f, 0xac, 0xd8, 0xc6, 0xcf, 0x36,
+	0x17, 0xea, 0x27, 0x01, 0x10, 0x78, 0x1e, 0x45, 0xd6, 0x8d, 0x1f, 0xfc,
+	0x1f, 0x34, 0x43, 0xd8, 0x4b, 0xe2, 0x56, 0x37, 0x8c, 0x74, 0x61, 0xa5,
+	0xae, 0x88, 0x66, 0xba, 0xd8, 0xef, 0x24, 0xe1, 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,
+	0xac, 0x3a, 0x78, 0xd0, 0xd2, 0x65, 0xa9, 0x1c, 0x1a, 0x29, 0xf8, 0xef,
+	0x6c, 0x8f, 0x83, 0xd3, 0xef, 0x98, 0xfd, 0xde, 0x8f, 0xd8, 0xd8, 0x17,
+	0xdf, 0x45, 0x9e, 0xa1, 0xc4, 0x2b, 0xf7, 0x48, 0x14, 0xda, 0xfc, 0x39,
+	0x81, 0xa7, 0x3d, 0xc7, 0xb0, 0x3d, 0xfa, 0x54, 0xc5, 0x2a, 0xfa, 0x2d,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x40, 0x6f, 0x6e,
+	0x6c, 0x0d, 0x2c, 0xe7, 0xcd, 0x12, 0x0b, 0x2b, 0x41, 0xfd, 0x72, 0xca,
+	0xef, 0x5d, 0x90, 0x06, 0x78, 0xf6, 0x02, 0xdd, 0xf5, 0xf8, 0xa2, 0xd1,
+	0x8a, 0xcc, 0xf2, 0x29, 0xaa, 0xfd, 0x1f, 0xcf, 0xce, 0x6d, 0x90, 0x8a,
+	0x2c, 0xe2, 0x88, 0x5a, 0x0e, 0x6d, 0x85, 0xf2, 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,
+	0x89, 0x10, 0x9a, 0x0e, 0xc6, 0x26, 0x66, 0xde, 0xc8, 0xc1, 0x2e, 0x75,
+	0x7f, 0xfc, 0xd0, 0x1e, 0xa8, 0x20, 0x61, 0x69, 0xc4, 0x8b, 0x5a, 0xb0,
+	0x4b, 0xc2, 0xfd, 0xcf, 0xf9, 0x83, 0xac, 0x6c, 0x59, 0xcf, 0xca, 0x71,
+	0x55, 0x97, 0x7d, 0x23, 0x12, 0x64, 0xcb, 0x33, 0x57, 0x66, 0xc9, 0x6a,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x69, 0x13, 0x81,
+	0x2e, 0x01, 0x4b, 0x4b, 0x31, 0xd2, 0x87, 0x07, 0xe4, 0x48, 0x3e, 0xc5,
+	0xcb, 0xf7, 0x19, 0x0c, 0xff, 0xb1, 0x97, 0x58, 0xb6, 0x67, 0x17, 0xa0,
+	0x65, 0xa5, 0xf2, 0x48, 0xd9, 0x4a, 0xd8, 0xfa, 0xc5, 0x3b, 0x4f, 0x69,
+	0x11, 0x9e, 0xbe, 0xee, 0xa1, 0xa1, 0xa3, 0x76, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static const uint8_t fpm_table_p521[CPT_P521_LEN] = {
+	0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x33, 0x48, 0xb3, 0xc1,
+	0x85, 0x6a, 0x42, 0x9b, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde,
+	0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xf8, 0x28, 0xaf, 0x60,
+	0x6b, 0x4d, 0x3d, 0xba, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21,
+	0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x85, 0x8e, 0x06, 0xb7,
+	0x04, 0x04, 0xe9, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6,
+	0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, 0x35, 0x3c, 0x70, 0x86,
+	0xa2, 0x72, 0xc2, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61,
+	0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0x17, 0xaf, 0xbd, 0x17,
+	0x27, 0x3e, 0x66, 0x2c, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68,
+	0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x39, 0x29, 0x6a, 0x78,
+	0x9a, 0x3b, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x69, 0xca, 0xd3, 0xcc, 0xc4, 0xd6, 0xab, 0x08, 0x3a, 0xdb, 0x57, 0x77,
+	0x3b, 0x89, 0x90, 0xb8, 0xd0, 0xca, 0xd8, 0xce, 0x8d, 0x95, 0x88, 0x01,
+	0xcb, 0x57, 0x2e, 0x66, 0x6d, 0x72, 0x8f, 0x9e, 0xe3, 0xd9, 0xe7, 0xc4,
+	0xcd, 0x51, 0x31, 0xfc, 0xaf, 0xce, 0xb6, 0xb0, 0x61, 0x45, 0xdc, 0x06,
+	0x12, 0xec, 0xd3, 0x92, 0xe2, 0x13, 0x04, 0x3a, 0xbd, 0x59, 0x92, 0x94,
+	0x3a, 0x64, 0xc8, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+	0x86, 0x23, 0xbd, 0xbb, 0xf6, 0xea, 0x9c, 0xf1, 0x3a, 0xad, 0x94, 0x95,
+	0x54, 0x7a, 0xa6, 0x50, 0xd3, 0xd8, 0x53, 0xfc, 0xbe, 0xb2, 0x71, 0x59,
+	0x3d, 0x25, 0xa6, 0x48, 0x30, 0xb4, 0x08, 0x33, 0x12, 0xd1, 0x88, 0xe8,
+	0xde, 0xc5, 0x1b, 0xd1, 0x83, 0x63, 0x30, 0xd2, 0xb3, 0x48, 0xc3, 0xfa,
+	0x9d, 0xf5, 0x0c, 0xfe, 0x73, 0xc2, 0xea, 0x59, 0xb5, 0xdf, 0xfb, 0x20,
+	0x61, 0xde, 0xd0, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xdc, 0x33, 0x41, 0x6e, 0xc8, 0xc5, 0xbc, 0xb2, 0xde, 0xfb, 0x4a, 0x9c,
+	0xe2, 0x44, 0x91, 0x0b, 0x27, 0xc3, 0x56, 0x1b, 0x53, 0xa8, 0xf7, 0xb9,
+	0x10, 0x88, 0xbb, 0x9e, 0xf6, 0x94, 0xd7, 0xb1, 0x98, 0xfa, 0x92, 0xaa,
+	0xa6, 0xd2, 0xc7, 0x82, 0x53, 0xc2, 0xa3, 0xdb, 0x3b, 0xa3, 0x7d, 0xd4,
+	0x67, 0xfc, 0x7c, 0xab, 0xd5, 0x93, 0x4b, 0xbc, 0x0c, 0x72, 0xcf, 0x96,
+	0x93, 0xbb, 0x09, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf,
+	0xf3, 0x2e, 0xbb, 0x1f, 0x13, 0xda, 0xb4, 0x57, 0x7c, 0x36, 0x11, 0xdf,
+	0xad, 0x23, 0x53, 0x70, 0xd8, 0x6d, 0x54, 0xdb, 0xab, 0x9e, 0x13, 0x10,
+	0xbf, 0x40, 0x10, 0xf1, 0x61, 0x85, 0xbf, 0x0d, 0x94, 0x6d, 0xb5, 0x6e,
+	0x31, 0x3c, 0x69, 0xf5, 0x3b, 0x67, 0x3c, 0x92, 0xe3, 0x77, 0x73, 0x27,
+	0x58, 0x7a, 0x4e, 0xa7, 0x47, 0x7a, 0xbd, 0xe6, 0xae, 0x87, 0xa6, 0x00,
+	0xd8, 0xaa, 0xa4, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xbf, 0x2f, 0xfc, 0xb7, 0x6e, 0x64, 0x0a, 0x8d, 0x63, 0x47, 0x95, 0x01,
+	0xa0, 0xb5, 0xa0, 0x7e, 0x55, 0xbb, 0x30, 0x01, 0x5f, 0x36, 0xf2, 0xe7,
+	0x98, 0x90, 0xf9, 0x99, 0x05, 0x8a, 0x67, 0x6a, 0xd9, 0xee, 0x34, 0x1b,
+	0x45, 0x5c, 0x0d, 0x27, 0x6c, 0x95, 0x78, 0x0c, 0x18, 0xe0, 0x8f, 0xc8,
+	0xeb, 0x63, 0xa6, 0x75, 0x44, 0x2a, 0x07, 0x5d, 0xce, 0x46, 0xa1, 0xa5,
+	0xfb, 0x69, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b,
+	0x8c, 0x61, 0x89, 0x34, 0xf3, 0xed, 0x62, 0x53, 0xe0, 0x03, 0x42, 0x44,
+	0x6e, 0x94, 0x33, 0xb4, 0x98, 0x9b, 0x99, 0x21, 0x42, 0x60, 0xb2, 0xc5,
+	0x11, 0x69, 0x98, 0x04, 0xd9, 0xdf, 0x47, 0x47, 0x12, 0x5f, 0xe6, 0x1f,
+	0x76, 0x3a, 0x7f, 0x63, 0xa9, 0x72, 0x78, 0x6d, 0xc6, 0xec, 0x39, 0x5a,
+	0x66, 0x2f, 0x9f, 0xe7, 0xb7, 0xb7, 0xb8, 0xc6, 0xfb, 0x64, 0x4a, 0x61,
+	0x54, 0x56, 0x55, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x52, 0x3c, 0xf9, 0xb2, 0xfd, 0xe7, 0x22, 0x35, 0x5c, 0x90, 0xde, 0xf0,
+	0xe8, 0xe0, 0x99, 0x59, 0xfe, 0x13, 0x1b, 0x9c, 0xd3, 0xcf, 0x46, 0x66,
+	0xc9, 0x14, 0x31, 0x30, 0xc1, 0x32, 0x76, 0xad, 0xa7, 0xdc, 0xdd, 0xc1,
+	0x85, 0xe2, 0x36, 0x37, 0x09, 0x45, 0x74, 0xcc, 0xf5, 0x14, 0x11, 0xd7,
+	0xf3, 0xfc, 0x87, 0xc4, 0xbd, 0x29, 0xfe, 0xd7, 0x2c, 0xc3, 0x2d, 0x3f,
+	0x17, 0x1c, 0xef, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x32,
+	0xdf, 0xa9, 0x2d, 0x3e, 0x35, 0xcc, 0x7a, 0x6c, 0xdd, 0x6d, 0xc6, 0x86,
+	0xd4, 0xe4, 0x78, 0x8b, 0xcb, 0x66, 0xcd, 0xe2, 0x1f, 0x74, 0xbb, 0xe0,
+	0xb0, 0xe9, 0xff, 0x6a, 0xf6, 0x7e, 0xc3, 0x95, 0x18, 0x6c, 0xfa, 0x86,
+	0x07, 0xb9, 0xdd, 0xff, 0xe8, 0x67, 0xde, 0x2f, 0xcf, 0x2d, 0xfd, 0x72,
+	0x49, 0x8c, 0x21, 0x91, 0xe2, 0x4e, 0xd3, 0x15, 0x2d, 0xf0, 0xac, 0xf8,
+	0xf7, 0x37, 0xe8, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x52, 0x6f, 0x00, 0x95, 0x74, 0x31, 0x82, 0x2a, 0x18, 0x5d, 0x92, 0xc3,
+	0xeb, 0x0c, 0x4e, 0xf8, 0xc8, 0x78, 0x13, 0x76, 0x38, 0x89, 0x30, 0x98,
+	0x32, 0x54, 0x7e, 0xec, 0x6a, 0x55, 0x72, 0xd0, 0xe1, 0xe8, 0xea, 0xe8,
+	0xf5, 0x94, 0x62, 0x73, 0x9a, 0x9e, 0x24, 0x00, 0xc8, 0x2f, 0x4f, 0x17,
+	0xfb, 0x98, 0xab, 0xff, 0xdb, 0x9f, 0x0e, 0x9b, 0x3c, 0x20, 0x1a, 0xa5,
+	0x83, 0x28, 0x87, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x95,
+	0x58, 0x76, 0x12, 0xa4, 0x41, 0xc2, 0xb1, 0x4a, 0x11, 0x91, 0xb7, 0x1d,
+	0xfd, 0xbf, 0x12, 0x43, 0x97, 0x39, 0x6e, 0xe7, 0xbc, 0xf5, 0x3f, 0x43,
+	0xd1, 0x4b, 0xf1, 0xa7, 0x90, 0xec, 0xf9, 0x76, 0x7f, 0x14, 0x7a, 0x72,
+	0x0b, 0xc6, 0xa0, 0xea, 0x40, 0x95, 0x18, 0xf8, 0xaf, 0xcb, 0xff, 0x46,
+	0x30, 0x21, 0xdc, 0xa5, 0x32, 0x17, 0x0c, 0x93, 0x88, 0x16, 0xd3, 0xee,
+	0x33, 0xf2, 0x46, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xcc, 0x7d, 0x6e, 0x15, 0x2f, 0x97, 0x03, 0x30, 0x50, 0xb1, 0xf6, 0x9e,
+	0x03, 0x00, 0x75, 0x86, 0xfc, 0x0e, 0x37, 0x04, 0x58, 0x25, 0x83, 0x51,
+	0xa8, 0x5d, 0x47, 0xe3, 0x56, 0xd8, 0xaf, 0x60, 0x1c, 0x89, 0x3b, 0x86,
+	0x8a, 0xc7, 0x42, 0x7f, 0x8e, 0x70, 0xdd, 0xd9, 0x5c, 0xcf, 0x72, 0xde,
+	0x1e, 0xd8, 0x3e, 0x13, 0x16, 0x06, 0x0a, 0x41, 0xc9, 0x00, 0xb8, 0x12,
+	0x6d, 0xa8, 0x80, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+	0x3a, 0xc0, 0x08, 0x85, 0x5c, 0x6c, 0x32, 0x0b, 0x56, 0xa9, 0xb0, 0x12,
+	0x24, 0x1f, 0x0c, 0xd6, 0x47, 0x94, 0x1b, 0x89, 0x97, 0x5d, 0xe7, 0x17,
+	0xe7, 0x09, 0xef, 0x78, 0xdc, 0xe4, 0x8a, 0x06, 0x48, 0x2f, 0x2a, 0x6a,
+	0x01, 0x56, 0xf2, 0xbd, 0xe7, 0xbd, 0xca, 0x0d, 0xae, 0x0a, 0x8a, 0x52,
+	0x8e, 0x41, 0xf9, 0x41, 0x3f, 0x45, 0x94, 0x01, 0xea, 0x6d, 0x1c, 0x40,
+	0x60, 0x16, 0x6a, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xa6, 0x6c, 0xcc, 0xc8, 0xd6, 0xe1, 0xbd, 0x72, 0x1e, 0xa4, 0xe9, 0x21,
+	0x4a, 0xe2, 0xfa, 0x5c, 0x66, 0x77, 0x5a, 0xf2, 0x2d, 0x02, 0x1f, 0xa7,
+	0x6d, 0x71, 0x1d, 0xfb, 0x2a, 0x4c, 0x46, 0x77, 0xdd, 0xaa, 0xe8, 0xbb,
+	0x5a, 0xe3, 0x80, 0xb3, 0x53, 0x15, 0x89, 0x94, 0x60, 0x0f, 0x11, 0xfc,
+	0xfe, 0xb1, 0x22, 0xdb, 0xda, 0x94, 0xd4, 0x43, 0x7c, 0xbf, 0x1a, 0xfa,
+	0xdf, 0xfc, 0x21, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+	0x03, 0xcf, 0xa7, 0x31, 0x83, 0x4b, 0xf8, 0x91, 0x4e, 0x01, 0x60, 0x85,
+	0x63, 0x0b, 0x80, 0x32, 0x90, 0xcf, 0x9b, 0x59, 0x49, 0xdb, 0x4d, 0x96,
+	0x96, 0xfd, 0x26, 0x14, 0x33, 0x5c, 0x9d, 0xdd, 0xc0, 0x21, 0x45, 0x10,
+	0x8e, 0x3b, 0x98, 0xfb, 0x6d, 0xed, 0x06, 0x33, 0x1d, 0xa2, 0xea, 0x2f,
+	0x2b, 0xda, 0x6d, 0x76, 0x9d, 0x0e, 0xad, 0x76, 0x4b, 0xa0, 0x0e, 0x99,
+	0xf3, 0xe4, 0xfb, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xb0, 0x31, 0x1b, 0x24, 0xcd, 0xed, 0xb3, 0xd3, 0x61, 0x14, 0xed, 0xd7,
+	0xe5, 0xc3, 0xfb, 0x9d, 0x8e, 0x02, 0x64, 0x37, 0x1a, 0x6b, 0xb2, 0xa1,
+	0xd7, 0xcc, 0x12, 0x87, 0x5e, 0xcd, 0xbe, 0x72, 0x6f, 0x71, 0x72, 0x87,
+	0x15, 0x58, 0x28, 0xe1, 0xb8, 0x3a, 0xef, 0xaa, 0x5f, 0x9b, 0xf5, 0x5d,
+	0x29, 0xd8, 0xc7, 0x42, 0x7e, 0x0b, 0x8a, 0xce, 0x18, 0xfe, 0x72, 0xa4,
+	0x64, 0x25, 0x9f, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a,
+	0x80, 0xf7, 0xfb, 0xb6, 0x2a, 0xa4, 0x37, 0x5d, 0x8d, 0x40, 0xb9, 0xee,
+	0x6d, 0x0b, 0xec, 0x41, 0x55, 0xdd, 0x1c, 0xe0, 0x41, 0xdb, 0xbd, 0x4b,
+	0xba, 0x77, 0x95, 0x12, 0x29, 0x4b, 0xc6, 0xcc, 0x38, 0x3d, 0x3a, 0x90,
+	0x4a, 0xa6, 0x6d, 0xb2, 0x3c, 0x46, 0x18, 0x62, 0x6c, 0xa8, 0xd7, 0x01,
+	0xf8, 0x0e, 0x3b, 0x59, 0x19, 0xbc, 0xfc, 0x0b, 0x9b, 0x63, 0x7d, 0x37,
+	0x5f, 0x56, 0xcd, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5e,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x74, 0x3b, 0x45, 0x1f, 0x86, 0xeb, 0x01, 0xd4, 0x63, 0x9c, 0x35, 0xde,
+	0x4d, 0x93, 0xf5, 0x7f, 0xab, 0x5e, 0xaa, 0xc4, 0x71, 0xd1, 0x5e, 0x15,
+	0xb7, 0x7b, 0xd7, 0x5b, 0xbe, 0x29, 0x19, 0xc6, 0x34, 0xb5, 0x39, 0x64,
+	0x2d, 0x2e, 0x8f, 0xa7, 0x1c, 0x04, 0xb3, 0xbf, 0xc5, 0x70, 0xd5, 0x49,
+	0x1b, 0x77, 0x64, 0x58, 0x6e, 0xaf, 0x33, 0xdc, 0xbd, 0x40, 0x33, 0xb2,
+	0x4d, 0xf5, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+	0x35, 0xe3, 0xa8, 0x3d, 0x9d, 0x79, 0x2a, 0xa8, 0x5e, 0xb6, 0x8e, 0xa9,
+	0x73, 0x85, 0xfb, 0xe3, 0xcc, 0x3b, 0xf6, 0xb7, 0x91, 0xd7, 0x82, 0x0f,
+	0x53, 0x9e, 0x98, 0xd0, 0x0b, 0x57, 0x18, 0x65, 0xdc, 0xc8, 0x13, 0x13,
+	0x2f, 0xdc, 0x47, 0x3e, 0x52, 0x40, 0x20, 0x14, 0xb8, 0xa3, 0xef, 0xf6,
+	0x93, 0x7b, 0x43, 0xd3, 0x30, 0x8e, 0x48, 0x85, 0x86, 0xd0, 0xac, 0xd5,
+	0xbb, 0x8e, 0x72, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x49, 0x2d, 0xc8, 0x61, 0xce, 0x07, 0x6e, 0x91, 0x1b, 0xed, 0x06, 0xac,
+	0xb5, 0xa5, 0x79, 0x7a, 0x80, 0x25, 0x4f, 0x8a, 0x10, 0xd2, 0xef, 0x33,
+	0x97, 0x66, 0x0e, 0x4f, 0xd1, 0xa3, 0x6b, 0x3e, 0x7d, 0xa6, 0xe9, 0x2f,
+	0x35, 0xaa, 0xee, 0xfe, 0xed, 0x65, 0x1c, 0x3f, 0x89, 0x08, 0xbd, 0xe5,
+	0x99, 0xed, 0x82, 0xc0, 0x14, 0xb0, 0xc8, 0xd7, 0x76, 0xd6, 0xd5, 0x2e,
+	0x23, 0x42, 0x44, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb,
+	0x49, 0xed, 0x49, 0xd7, 0x20, 0x06, 0x0e, 0x54, 0x5d, 0xae, 0xaa, 0x77,
+	0x53, 0x5d, 0x38, 0x1c, 0x02, 0x7b, 0x07, 0x4e, 0x2f, 0x84, 0x36, 0x83,
+	0xe1, 0xc5, 0x2f, 0x6c, 0x4f, 0x54, 0x94, 0x1d, 0xc5, 0xa9, 0x18, 0x83,
+	0x69, 0xbe, 0x08, 0xb0, 0xd8, 0xe8, 0x81, 0x44, 0x0f, 0xc0, 0x0b, 0x32,
+	0x5c, 0x14, 0x9a, 0x7f, 0x39, 0x77, 0x6c, 0xe6, 0x45, 0xab, 0xab, 0x75,
+	0x48, 0x39, 0xd3, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xaf, 0xe2, 0xc9, 0x9e, 0x41, 0xc5, 0xad, 0x4e, 0x91, 0xbd, 0x0f, 0x74,
+	0x04, 0x97, 0x37, 0x24, 0x11, 0x0d, 0x39, 0x02, 0x70, 0x29, 0xce, 0x18,
+	0x31, 0x39, 0x96, 0x1a, 0xe4, 0xd8, 0xcd, 0x86, 0x20, 0x41, 0xf8, 0xf2,
+	0x65, 0x04, 0x09, 0xad, 0xf6, 0x03, 0x67, 0x47, 0x5c, 0x3a, 0xb7, 0xe7,
+	0x0c, 0xfa, 0xe7, 0xe4, 0x5f, 0xc5, 0x9d, 0x58, 0xa2, 0xa1, 0x41, 0x9d,
+	0xb0, 0x1d, 0xc2, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa8,
+	0xe5, 0x88, 0xb5, 0xf2, 0xd7, 0x71, 0x52, 0xe1, 0x94, 0xf5, 0xe2, 0x1e,
+	0x3d, 0x65, 0x7a, 0x29, 0x91, 0xbe, 0x93, 0xd9, 0xb2, 0x9b, 0xea, 0xa5,
+	0x8c, 0xcc, 0xd4, 0x2c, 0xe4, 0x96, 0xf3, 0x7a, 0xbf, 0x29, 0x5a, 0x89,
+	0x7c, 0xc5, 0xff, 0xc9, 0x38, 0x64, 0xd8, 0x5e, 0xd8, 0xe3, 0x06, 0x5a,
+	0xe1, 0x35, 0xda, 0x88, 0x59, 0x3c, 0xc5, 0x50, 0xd2, 0xe2, 0x1f, 0x06,
+	0xa2, 0xac, 0xff, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x9f, 0x12, 0xaf, 0x8f, 0xf1, 0x27, 0x32, 0x22, 0x13, 0xd3, 0x23, 0xa3,
+	0xc7, 0xb0, 0xbf, 0x6d, 0x7b, 0xbb, 0x66, 0x7d, 0xa8, 0x35, 0xd8, 0xea,
+	0xd3, 0x14, 0x5f, 0xdd, 0xb3, 0x0e, 0x21, 0x3c, 0xe1, 0xd3, 0x17, 0x0f,
+	0x86, 0x13, 0x38, 0x9c, 0x50, 0x37, 0x17, 0x64, 0x48, 0x12, 0x41, 0xf8,
+	0x53, 0x7c, 0x14, 0xdd, 0xc2, 0xae, 0x9d, 0xbe, 0x86, 0x81, 0x31, 0x96,
+	0x29, 0x64, 0x59, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79,
+	0xa4, 0xf4, 0x01, 0x3e, 0x71, 0xb7, 0x6e, 0x68, 0x31, 0x86, 0x62, 0xbc,
+	0xf0, 0x1d, 0xcb, 0xa9, 0xd0, 0x55, 0xec, 0xb8, 0x18, 0xe8, 0x7f, 0x1f,
+	0xc7, 0xcc, 0xf5, 0xfa, 0xbc, 0xf1, 0x44, 0x74, 0x3a, 0x39, 0x90, 0x76,
+	0xf8, 0xa9, 0x58, 0x8a, 0x9f, 0x38, 0x62, 0x02, 0xa5, 0x38, 0x72, 0x4b,
+	0x15, 0x80, 0xc0, 0xbb, 0x18, 0x20, 0xa4, 0xdd, 0xed, 0xb8, 0x90, 0x86,
+	0xca, 0x8f, 0xdd, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xf4, 0xab, 0xf8, 0x15, 0x29, 0x73, 0x14, 0x27, 0xf5, 0xb8, 0x6b, 0x12,
+	0xf9, 0xe4, 0x22, 0xc5, 0x4d, 0xd1, 0xa9, 0x71, 0x21, 0x97, 0xfd, 0x42,
+	0x02, 0x10, 0x34, 0x7f, 0x6f, 0xfd, 0x80, 0xff, 0x22, 0x5c, 0xd3, 0xa0,
+	0x7e, 0x37, 0x56, 0x30, 0xc2, 0x59, 0xfe, 0x53, 0xff, 0x95, 0x16, 0xb6,
+	0xc0, 0xb8, 0x01, 0x10, 0xa6, 0x89, 0xdb, 0x24, 0xc3, 0xbd, 0xce, 0xb5,
+	0x77, 0x0e, 0x1f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e,
+	0x0b, 0x89, 0x2f, 0x5c, 0xdd, 0x8c, 0x05, 0xb9, 0x41, 0x7c, 0x1a, 0xce,
+	0xbf, 0x23, 0x01, 0x0c, 0xe9, 0x74, 0x9c, 0x6c, 0xbb, 0xf7, 0xf7, 0x53,
+	0xfe, 0xc2, 0xd2, 0xe4, 0xb3, 0x3f, 0x5a, 0x06, 0x41, 0x02, 0x30, 0xdc,
+	0x2f, 0xa4, 0x1c, 0x6b, 0x29, 0x27, 0x10, 0x68, 0xa1, 0x8a, 0x14, 0x16,
+	0xab, 0xb9, 0xaf, 0xe4, 0x73, 0xb9, 0xec, 0x29, 0x72, 0xd9, 0x03, 0x5c,
+	0x26, 0x79, 0x2a, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e,
+	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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x28, 0xff, 0x7b, 0xe0, 0xfc, 0x9e, 0x23, 0xd2, 0xf5, 0xe0, 0x7f, 0xef,
+	0xb8, 0x63, 0xa2, 0x40, 0x1b, 0x61, 0x96, 0xe4, 0x67, 0xcb, 0x5b, 0x0e,
+	0x30, 0xa9, 0xa3, 0x6b, 0x9e, 0xc2, 0xfb, 0xfc, 0x06, 0xef, 0x3f, 0x4e,
+	0xdf, 0x56, 0x80, 0x15, 0x72, 0x9b, 0xb1, 0x97, 0xc9, 0xf5, 0x26, 0x0b,
+	0x52, 0xb0, 0xb4, 0xfe, 0xb6, 0x04, 0x15, 0x86, 0x26, 0x51, 0xb3, 0x20,
+	0x63, 0xf1, 0x99, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x34,
+	0xdc, 0xfa, 0xf4, 0x3a, 0x05, 0xb6, 0x4e, 0xa9, 0x1d, 0xb7, 0x31, 0x9c,
+	0x19, 0x16, 0x32, 0xe8, 0x3a, 0x60, 0xe8, 0xab, 0x97, 0x7a, 0x9c, 0x9d,
+	0x85, 0x42, 0x8e, 0x55, 0xee, 0x3a, 0x97, 0x81, 0x71, 0xc3, 0x42, 0x1b,
+	0x5b, 0x6d, 0x51, 0xc0, 0x01, 0xed, 0x96, 0x12, 0x52, 0x56, 0x02, 0x26,
+	0x6c, 0xc1, 0xdb, 0xed, 0x90, 0x72, 0x2e, 0x36, 0xfa, 0xa6, 0x4f, 0x19,
+	0xc2, 0xc7, 0x0c, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static const struct fpm_entry fpm_table_scalar[CPT_EC_ID_PMAX] = {
+	{
+		.data = fpm_table_p192,
+		.len = sizeof(fpm_table_p192)
+	},
+	{
+		.data = fpm_table_p224,
+		.len = sizeof(fpm_table_p224)
+	},
+	{
+		.data = fpm_table_p256,
+		.len = sizeof(fpm_table_p256)
+	},
+	{
+		.data = fpm_table_p384,
+		.len = sizeof(fpm_table_p384)
+	},
+	{
+		.data = fpm_table_p521,
+		.len = sizeof(fpm_table_p521)
+	}
+};
+
+static rte_spinlock_t lock = RTE_SPINLOCK_INITIALIZER;
+static uint8_t *fpm_table;
+static int nb_devs;
+
+int cpt_fpm_init(uint64_t *fpm_table_iova)
+{
+	int i, len = 0;
+	uint8_t *data;
+
+	if (fpm_table_iova == NULL)
+		return -EINVAL;
+
+	rte_spinlock_lock(&lock);
+
+	if (nb_devs != 0)
+		goto update_nb_devs;
+
+	/* Compute FPM table size for all supported curves */
+	for (i = 0; i < CPT_EC_ID_PMAX; i++)
+		len += fpm_table_scalar[i].len;
+
+	/* Allocate shared FPM table */
+	fpm_table = rte_malloc(NULL, len, 0);
+
+	if (fpm_table == NULL) {
+		rte_spinlock_unlock(&lock);
+		return -ENOMEM;
+	}
+	data = fpm_table;
+
+	for (i = CPT_EC_ID_P192; i < CPT_EC_ID_PMAX; i++) {
+		memcpy(data, fpm_table_scalar[i].data, fpm_table_scalar[i].len);
+		/* Convert iova address to big endian to be used by cpt */
+		fpm_table_iova[i] = rte_cpu_to_be_64(rte_mem_virt2iova(data));
+
+		data = RTE_PTR_ADD(data, fpm_table_scalar[i].len);
+	}
+
+update_nb_devs:
+
+	/* Increment number of devices using FPM table */
+	nb_devs++;
+
+	rte_spinlock_unlock(&lock);
+
+	return 0;
+}
+
+void cpt_fpm_clear(void)
+{
+	rte_spinlock_lock(&lock);
+
+	/* Decrement number of devices using FPM table */
+	nb_devs--;
+	if ((nb_devs == 0) && (fpm_table != NULL))
+		rte_free(fpm_table);
+
+	rte_spinlock_unlock(&lock);
+}
diff --git a/drivers/common/cpt/cpt_mcode_defines.h b/drivers/common/cpt/cpt_mcode_defines.h
index f356e62..64d3e8c 100644
--- a/drivers/common/cpt/cpt_mcode_defines.h
+++ b/drivers/common/cpt/cpt_mcode_defines.h
@@ -23,12 +23,15 @@
 
 /* AE opcodes */
 #define CPT_MAJOR_OP_MODEX	0x03
+#define CPT_MAJOR_OP_ECDSA	0x04
 #define CPT_MINOR_OP_MODEX	0x01
 #define CPT_MINOR_OP_PKCS_ENC	0x02
 #define CPT_MINOR_OP_PKCS_ENC_CRT	0x03
 #define CPT_MINOR_OP_PKCS_DEC	0x04
 #define CPT_MINOR_OP_PKCS_DEC_CRT	0x05
 #define CPT_MINOR_OP_MODEX_CRT	0x06
+#define CPT_MINOR_OP_ECDSA_SIGN	0x01
+#define CPT_MINOR_OP_ECDSA_VERIFY	0x02
 
 #define CPT_BLOCK_TYPE1 0
 #define CPT_BLOCK_TYPE2 1
@@ -203,6 +206,20 @@ typedef enum {
 	CPT_8X_COMP_E_LAST_ENTRY = (0xFF)
 } cpt_comp_e_t;
 
+/**
+ * Enumeration cpt_ec_id
+ *
+ * Enumerates supported elliptic curves
+ */
+typedef enum {
+	CPT_EC_ID_P192 = 0,
+	CPT_EC_ID_P224 = 1,
+	CPT_EC_ID_P256 = 2,
+	CPT_EC_ID_P384 = 3,
+	CPT_EC_ID_P521 = 4,
+	CPT_EC_ID_PMAX = 5
+} cpt_ec_id_t;
+
 typedef struct sglist_comp {
 	union {
 		uint64_t len;
@@ -329,11 +346,32 @@ struct cpt_ctx {
 	uint8_t  auth_key[64];
 };
 
+/* Prime and order fields of built-in elliptic curves */
+struct cpt_ec_group {
+	struct {
+		/* P521 maximum length */
+		uint8_t data[66];
+		unsigned int length;
+	} prime;
+
+	struct {
+		/* P521 maximum length */
+		uint8_t data[66];
+		unsigned int length;
+	} order;
+};
+
+struct cpt_asym_ec_ctx {
+	/* Prime length defined by microcode for EC operations */
+	uint8_t curveid;
+};
+
 struct cpt_asym_sess_misc {
 	enum rte_crypto_asym_xform_type xfrm_type;
 	union {
 		struct rte_crypto_rsa_xform rsa_ctx;
 		struct rte_crypto_modex_xform mod_ctx;
+		struct cpt_asym_ec_ctx ec_ctx;
 	};
 };
 
diff --git a/drivers/common/cpt/cpt_pmd_ops_helper.h b/drivers/common/cpt/cpt_pmd_ops_helper.h
index 24c3559..716ae94 100644
--- a/drivers/common/cpt/cpt_pmd_ops_helper.h
+++ b/drivers/common/cpt/cpt_pmd_ops_helper.h
@@ -40,4 +40,23 @@ cpt_pmd_ops_helper_get_mlen_sg_mode(void);
  */
 int
 cpt_pmd_ops_helper_asym_get_mlen(void);
+
+/*
+ * Initialize ECC FMUL precomputed table
+ *
+ * @param
+ *  - pointer to fpm_table iova address
+ *
+ * @return
+ *  - 0 on success, negative on error
+ */
+__rte_experimental
+int cpt_fpm_init(uint64_t *fpm_table_iova);
+
+/*
+ * Clear ECC FMUL precomputed table
+ */
+__rte_experimental
+void cpt_fpm_clear(void);
+
 #endif /* _CPT_PMD_OPS_HELPER_H_ */
diff --git a/drivers/common/cpt/cpt_ucode_asym.h b/drivers/common/cpt/cpt_ucode_asym.h
index 00e01b5..0caa313 100644
--- a/drivers/common/cpt/cpt_ucode_asym.h
+++ b/drivers/common/cpt/cpt_ucode_asym.h
@@ -126,6 +126,37 @@ cpt_fill_rsa_params(struct cpt_asym_sess_misc *sess,
 }
 
 static __rte_always_inline int
+cpt_fill_ec_params(struct cpt_asym_sess_misc *sess,
+		      struct rte_crypto_asym_xform *xform)
+{
+	struct cpt_asym_ec_ctx *ec = &sess->ec_ctx;
+
+	switch (xform->ec.curve_id) {
+	case RTE_CRYPTO_EC_GROUP_SECP192R1:
+		ec->curveid = CPT_EC_ID_P192;
+		break;
+	case RTE_CRYPTO_EC_GROUP_SECP224R1:
+		ec->curveid = CPT_EC_ID_P224;
+		break;
+	case RTE_CRYPTO_EC_GROUP_SECP256R1:
+		ec->curveid = CPT_EC_ID_P256;
+		break;
+	case RTE_CRYPTO_EC_GROUP_SECP384R1:
+		ec->curveid = CPT_EC_ID_P384;
+		break;
+	case RTE_CRYPTO_EC_GROUP_SECP521R1:
+		ec->curveid = CPT_EC_ID_P521;
+		break;
+	default:
+		/* Only NIST curves (FIPS 186-4) are supported */
+		CPT_LOG_DP_ERR("Unsupported curve");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static __rte_always_inline int
 cpt_fill_asym_session_parameters(struct cpt_asym_sess_misc *sess,
 				 struct rte_crypto_asym_xform *xform)
 {
@@ -140,6 +171,9 @@ cpt_fill_asym_session_parameters(struct cpt_asym_sess_misc *sess,
 	case RTE_CRYPTO_ASYM_XFORM_MODEX:
 		ret = cpt_fill_modex_params(sess, xform);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		ret = cpt_fill_ec_params(sess, xform);
+		break;
 	default:
 		CPT_LOG_DP_ERR("Unsupported transform type");
 		return -ENOTSUP;
@@ -164,6 +198,8 @@ cpt_free_asym_session_parameters(struct cpt_asym_sess_misc *sess)
 		if (mod->modulus.data)
 			rte_free(mod->modulus.data);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		break;
 	default:
 		CPT_LOG_DP_ERR("Invalid transform type");
 		break;
@@ -450,4 +486,346 @@ cpt_enqueue_rsa_op(struct rte_crypto_op *op,
 	}
 	return 0;
 }
+
+static const struct cpt_ec_group ec_grp[CPT_EC_ID_PMAX] = {
+	{
+		.prime = {
+			.data =	{
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+			},
+			.length = 24,
+		},
+		.order = {
+			.data = {
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36,
+				0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31
+			},
+			.length = 24
+		},
+	},
+	{
+		.prime = {
+			.data = {
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x01
+			},
+			.length = 28
+		},
+		.order = {
+			.data = {
+				0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
+				0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X16, 0XA2,
+				0XE0, 0XB8, 0XF0, 0X3E, 0X13, 0XDD, 0X29, 0X45,
+				0X5C, 0X5C, 0X2A, 0X3D
+			},
+			.length = 28
+		},
+	},
+	{
+		.prime = {
+			.data = {
+				0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+			},
+			.length = 32
+		},
+		.order = {
+			.data = {
+				0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+				0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+				0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
+				0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
+			},
+			.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, 0xFF, 0xFF, 0xFF, 0xFE,
+				0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
+			},
+			.length = 48
+		},
+		.order = {
+			.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,
+				0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF,
+				0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A,
+				0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
+			},
+			.length = 48
+		}
+	},
+	{
+		.prime = {
+			.data = {
+				0x01, 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, 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, 0xFF, 0xFF, 0xFF,
+				0xFF, 0xFF
+			},
+			.length = 66
+		},
+		.order = {
+			.data = {
+				0x01, 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, 0xFF,
+				0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
+				0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
+				0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,
+				0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
+				0x64, 0x09
+			},
+			.length = 66
+		}
+	}
+};
+
+static __rte_always_inline void
+cpt_ecdsa_sign_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
+		    struct asym_op_params *ecdsa_params,
+		    uint64_t fpm_table_iova,
+		    uint8_t curveid)
+{
+	struct cpt_request_info *req = ecdsa_params->req;
+	uint16_t message_len = ecdsa->message.length;
+	phys_addr_t mphys = ecdsa_params->meta_buf;
+	uint16_t pkey_len = ecdsa->pkey.length;
+	uint16_t p_align, k_align, m_align;
+	uint16_t k_len = ecdsa->k.length;
+	uint16_t order_len, prime_len;
+	uint16_t o_offset, pk_offset;
+	vq_cmd_word0_t vq_cmd_w0;
+	opcode_info_t opcode;
+	uint16_t rlen, dlen;
+	buf_ptr_t caddr;
+	uint8_t *dptr;
+
+	prime_len = ec_grp[curveid].prime.length;
+	order_len = ec_grp[curveid].order.length;
+
+	/* Truncate input length to curve prime length */
+	if (message_len > prime_len)
+		message_len = prime_len;
+	m_align = ROUNDUP8(message_len);
+
+	p_align = ROUNDUP8(prime_len);
+	k_align = ROUNDUP8(k_len);
+
+	/* Set write offset for order and private key */
+	o_offset = prime_len - order_len;
+	pk_offset = prime_len - pkey_len;
+
+	/* Input buffer */
+	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(scalar len, input len),
+	 * ROUNDUP8(priv key len, prime len, order len)).
+	 * Please note, private key, order cannot exceed prime
+	 * length i.e 3 * p_align.
+	 */
+	dlen = sizeof(fpm_table_iova) + k_align + m_align + p_align * 3;
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr, ecdsa->k.data, k_len);
+	dptr += k_align;
+
+	memcpy(dptr, ec_grp[curveid].prime.data, prime_len);
+	dptr += p_align;
+
+	memcpy(dptr + o_offset, ec_grp[curveid].order.data, order_len);
+	dptr += p_align;
+
+	memcpy(dptr + pk_offset, ecdsa->pkey.data, pkey_len);
+	dptr += p_align;
+
+	memcpy(dptr, ecdsa->message.data, message_len);
+	dptr += m_align;
+
+	/* 2 * prime length (for sign r and s ) */
+	rlen = 2 * p_align;
+
+	/* Setup opcodes */
+	opcode.s.major = CPT_MAJOR_OP_ECDSA;
+	opcode.s.minor = CPT_MINOR_OP_ECDSA_SIGN;
+	vq_cmd_w0.s.opcode = opcode.flags;
+
+	/* GP op header */
+	vq_cmd_w0.s.param1 = curveid | (message_len << 8);
+	vq_cmd_w0.s.param2 = k_len;
+	vq_cmd_w0.s.dlen = dlen;
+
+	/* Filling cpt_request_info structure */
+	req->ist.ei0 = vq_cmd_w0.u64;
+	req->ist.ei1 = mphys;
+	req->ist.ei2 = mphys + dlen;
+
+	/* Result pointer to store result data */
+	req->rptr = dptr;
+
+	/* alternate_caddr to write completion status of the microcode */
+	req->alternate_caddr = (uint64_t *)(dptr + rlen);
+	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
+
+	/* Preparing completion addr, +1 for completion code */
+	caddr.vaddr = dptr + rlen + 1;
+	caddr.dma_addr = mphys + dlen + rlen + 1;
+
+	cpt_fill_req_comp_addr(req, caddr);
+}
+
+static __rte_always_inline void
+cpt_ecdsa_verify_prep(struct rte_crypto_ecdsa_op_param *ecdsa,
+		      struct asym_op_params *ecdsa_params,
+		      uint64_t fpm_table_iova,
+		      uint8_t curveid)
+{
+	struct cpt_request_info *req = ecdsa_params->req;
+	uint32_t message_len = ecdsa->message.length;
+	phys_addr_t mphys = ecdsa_params->meta_buf;
+	uint16_t o_offset, r_offset, s_offset;
+	uint16_t qx_len = ecdsa->q.x.length;
+	uint16_t qy_len = ecdsa->q.y.length;
+	uint16_t r_len = ecdsa->r.length;
+	uint16_t s_len = ecdsa->s.length;
+	uint16_t order_len, prime_len;
+	uint16_t qx_offset, qy_offset;
+	uint16_t p_align, m_align;
+	vq_cmd_word0_t vq_cmd_w0;
+	opcode_info_t opcode;
+	buf_ptr_t caddr;
+	uint16_t dlen;
+	uint8_t *dptr;
+
+	prime_len = ec_grp[curveid].prime.length;
+	order_len = ec_grp[curveid].order.length;
+
+	/* Truncate input length to curve prime length */
+	if (message_len > prime_len)
+		message_len = prime_len;
+
+	m_align = ROUNDUP8(message_len);
+	p_align = ROUNDUP8(prime_len);
+
+	/* Set write offset for sign, order and public key coordinates */
+	o_offset = prime_len - order_len;
+	qx_offset = prime_len - qx_len;
+	qy_offset = prime_len - qy_len;
+	r_offset = prime_len - r_len;
+	s_offset = prime_len - s_len;
+
+	/* Input buffer */
+	dptr = RTE_PTR_ADD(req, sizeof(struct cpt_request_info));
+
+	/*
+	 * Set dlen = sum(sizeof(fpm address), ROUNDUP8(message len),
+	 * ROUNDUP8(sign len(r and s), public key len(x and y coordinates),
+	 * prime len, order len)).
+	 * Please note sign, public key and order can not excede prime length
+	 * i.e. 6 * p_align
+	 */
+	dlen = sizeof(fpm_table_iova) + m_align + (6 * p_align);
+
+	memset(dptr, 0, dlen);
+
+	*(uint64_t *)dptr = fpm_table_iova;
+	dptr += sizeof(fpm_table_iova);
+
+	memcpy(dptr + r_offset, ecdsa->r.data, r_len);
+	dptr += p_align;
+
+	memcpy(dptr + s_offset, ecdsa->s.data, s_len);
+	dptr += p_align;
+
+	memcpy(dptr, ecdsa->message.data, message_len);
+	dptr += m_align;
+
+	memcpy(dptr + o_offset, ec_grp[curveid].order.data, order_len);
+	dptr += p_align;
+
+	memcpy(dptr, ec_grp[curveid].prime.data, prime_len);
+	dptr += p_align;
+
+	memcpy(dptr + qx_offset, ecdsa->q.x.data, qx_len);
+	dptr += p_align;
+
+	memcpy(dptr + qy_offset, ecdsa->q.y.data, qy_len);
+	dptr += p_align;
+
+	/* Setup opcodes */
+	opcode.s.major = CPT_MAJOR_OP_ECDSA;
+	opcode.s.minor = CPT_MINOR_OP_ECDSA_VERIFY;
+	vq_cmd_w0.s.opcode = opcode.flags;
+
+	/* GP op header */
+	vq_cmd_w0.s.param1 = curveid | (message_len << 8);
+	vq_cmd_w0.s.param2 = 0;
+	vq_cmd_w0.s.dlen = dlen;
+
+	/* Filling cpt_request_info structure */
+	req->ist.ei0 = vq_cmd_w0.u64;
+	req->ist.ei1 = mphys;
+	req->ist.ei2 = mphys + dlen;
+
+	/* Result pointer to store result data */
+	req->rptr = dptr;
+
+	/* alternate_caddr to write completion status of the microcode */
+	req->alternate_caddr = (uint64_t *)dptr;
+	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
+
+	/* Preparing completion addr, +1 for completion code */
+	caddr.vaddr = dptr + 1;
+	caddr.dma_addr = mphys + dlen + 1;
+
+	cpt_fill_req_comp_addr(req, caddr);
+}
+
+static __rte_always_inline int __hot
+cpt_enqueue_ecdsa_op(struct rte_crypto_op *op,
+		     struct asym_op_params *params,
+		     struct cpt_asym_sess_misc *sess,
+		     uint64_t *fpm_iova)
+{
+	struct rte_crypto_ecdsa_op_param *ecdsa = &op->asym->ecdsa;
+	uint8_t curveid = sess->ec_ctx.curveid;
+
+	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_SIGN)
+		cpt_ecdsa_sign_prep(ecdsa, params, fpm_iova[curveid], curveid);
+	else if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		cpt_ecdsa_verify_prep(ecdsa, params, fpm_iova[curveid],
+				      curveid);
+	else {
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
+		return -EINVAL;
+	}
+	return 0;
+}
+
 #endif /* _CPT_UCODE_ASYM_H_ */
diff --git a/drivers/common/cpt/meson.build b/drivers/common/cpt/meson.build
index 0a905aa..d2e84ff 100644
--- a/drivers/common/cpt/meson.build
+++ b/drivers/common/cpt/meson.build
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Cavium, Inc
 
-sources = files('cpt_pmd_ops_helper.c')
+sources = files('cpt_fpm_tables.c',
+		'cpt_pmd_ops_helper.c')
 
 deps = ['kvargs', 'pci', 'cryptodev']
 includes += include_directories('../../crypto/octeontx')
diff --git a/drivers/common/cpt/rte_common_cpt_version.map b/drivers/common/cpt/rte_common_cpt_version.map
index 7f1929d..8c65cde 100644
--- a/drivers/common/cpt/rte_common_cpt_version.map
+++ b/drivers/common/cpt/rte_common_cpt_version.map
@@ -7,3 +7,12 @@ DPDK_20.0 {
 
 	local: *;
 };
+
+EXPERIMENTAL {
+	global:
+
+	cpt_fpm_clear;
+	cpt_fpm_init;
+
+	local: *;
+};
diff --git a/drivers/crypto/octeontx/otx_cryptodev_capabilities.c b/drivers/crypto/octeontx/otx_cryptodev_capabilities.c
index 8c0358f..6418ad2 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_capabilities.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_capabilities.c
@@ -630,6 +630,17 @@ static const struct rte_cryptodev_capabilities otx_asym_capabilities[] = {
 			}
 		}, }
 	},
+	{	/* ECDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+				}
+			},
+		}
+	},
 	/* End of asymmetric capabilities */
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
diff --git a/drivers/crypto/octeontx/otx_cryptodev_ops.c b/drivers/crypto/octeontx/otx_cryptodev_ops.c
index ba56b21..f97ce3a 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_ops.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_ops.c
@@ -17,9 +17,12 @@
 #include "otx_cryptodev_ops.h"
 
 #include "cpt_pmd_logs.h"
+#include "cpt_pmd_ops_helper.h"
 #include "cpt_ucode.h"
 #include "cpt_ucode_asym.h"
 
+static uint64_t otx_fpm_iova[CPT_EC_ID_PMAX];
+
 /* Forward declarations */
 
 static int
@@ -52,11 +55,18 @@ otx_cpt_periodic_alarm_stop(void *arg)
 /* PMD ops */
 
 static int
-otx_cpt_dev_config(struct rte_cryptodev *dev __rte_unused,
+otx_cpt_dev_config(struct rte_cryptodev *dev,
 		   struct rte_cryptodev_config *config __rte_unused)
 {
+	int ret = 0;
+
 	CPT_PMD_INIT_FUNC_TRACE();
-	return 0;
+
+	if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)
+		/* Initialize shared FPM table */
+		ret = cpt_fpm_init(otx_fpm_iova);
+
+	return ret;
 }
 
 static int
@@ -76,6 +86,9 @@ otx_cpt_dev_stop(struct rte_cryptodev *c_dev)
 
 	CPT_PMD_INIT_FUNC_TRACE();
 
+	if (c_dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)
+		cpt_fpm_clear();
+
 	otx_cpt_stop_device(cptvf);
 }
 
@@ -425,6 +438,11 @@ otx_cpt_enq_single_asym(struct cpt_instance *instance,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		ret = cpt_enqueue_ecdsa_op(op, &params, sess, otx_fpm_iova);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	default:
 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
 		ret = -EINVAL;
@@ -668,6 +686,24 @@ otx_cpt_asym_rsa_op(struct rte_crypto_op *cop, struct cpt_request_info *req,
 	}
 }
 
+static __rte_always_inline void
+otx_cpt_asym_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa,
+			    struct cpt_request_info *req,
+			    struct cpt_asym_ec_ctx *ec)
+
+{
+	int prime_len = ec_grp[ec->curveid].prime.length;
+
+	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	memcpy(ecdsa->r.data, req->rptr, prime_len);
+	memcpy(ecdsa->s.data, req->rptr + ROUNDUP8(prime_len), prime_len);
+	ecdsa->r.length = prime_len;
+	ecdsa->s.length = prime_len;
+}
+
 static __rte_always_inline void __hot
 otx_cpt_asym_post_process(struct rte_crypto_op *cop,
 			  struct cpt_request_info *req)
@@ -687,6 +723,9 @@ otx_cpt_asym_post_process(struct rte_crypto_op *cop,
 		memcpy(op->modex.result.data, req->rptr,
 		       op->modex.result.length);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		otx_cpt_asym_dequeue_ecdsa_op(&op->ecdsa, req, &sess->ec_ctx);
+		break;
 	default:
 		CPT_LOG_DP_DEBUG("Invalid crypto xform type");
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
-- 
2.7.4


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

* [dpdk-dev] [PATCH v2 3/4] crypto/octeontx2: add ECDSA support
  2020-01-15 12:43 ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Anoob Joseph
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 1/4] cryptodev: support ECDSA Anoob Joseph
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 2/4] crypto/octeontx: add ECDSA support Anoob Joseph
@ 2020-01-15 12:43   ` Anoob Joseph
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 4/4] app/test: add ECDSA sign/verify tests Anoob Joseph
  2020-01-15 15:50   ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Akhil Goyal
  4 siblings, 0 replies; 19+ messages in thread
From: Anoob Joseph @ 2020-01-15 12:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Sunila Sahu, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, dev, Anoob Joseph,
	Balakrishna Bhamidipati

From: Sunila Sahu <ssahu@marvell.com>

Adding support for ECDSA operations in crypto_octeontx2 PMD.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Balakrishna Bhamidipati <bbhamidipati@marvell.com>
Signed-off-by: Sunila Sahu <ssahu@marvell.com>
---
 doc/guides/cryptodevs/features/octeontx2.ini       |  8 +++--
 .../crypto/octeontx2/otx2_cryptodev_capabilities.c | 11 ++++++
 drivers/crypto/octeontx2/otx2_cryptodev_ops.c      | 39 ++++++++++++++++++++--
 3 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/doc/guides/cryptodevs/features/octeontx2.ini b/doc/guides/cryptodevs/features/octeontx2.ini
index 7d07053..dd6369b 100644
--- a/doc/guides/cryptodevs/features/octeontx2.ini
+++ b/doc/guides/cryptodevs/features/octeontx2.ini
@@ -67,5 +67,9 @@ AES GCM (256) = Y
 ; Supported Asymmetric algorithms of the 'octeontx2' crypto driver.
 ;
 [Asymmetric]
-RSA                    = Y
-Modular Exponentiation = Y
+RSA                     = Y
+DSA                     =
+Modular Exponentiation  = Y
+Modular Inversion       =
+Diffie-hellman          =
+ECDSA                   = Y
diff --git a/drivers/crypto/octeontx2/otx2_cryptodev_capabilities.c b/drivers/crypto/octeontx2/otx2_cryptodev_capabilities.c
index b9e3fe3..f2079e2 100644
--- a/drivers/crypto/octeontx2/otx2_cryptodev_capabilities.c
+++ b/drivers/crypto/octeontx2/otx2_cryptodev_capabilities.c
@@ -628,6 +628,17 @@ rte_cryptodev_capabilities otx2_cpt_capabilities[] = {
 			}
 		}, }
 	},
+	{	/* ECDSA */
+		.op = RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+		{.asym = {
+			.xform_capa = {
+				.xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA,
+				.op_types = ((1 << RTE_CRYPTO_ASYM_OP_SIGN) |
+					(1 << RTE_CRYPTO_ASYM_OP_VERIFY)),
+				}
+			},
+		}
+	},
 	/* End of asymmetric capabilities */
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
diff --git a/drivers/crypto/octeontx2/otx2_cryptodev_ops.c b/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
index 65101b0..17c755d 100644
--- a/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
+++ b/drivers/crypto/octeontx2/otx2_cryptodev_ops.c
@@ -22,6 +22,8 @@
 
 #define METABUF_POOL_CACHE_SIZE	512
 
+static uint64_t otx2_fpm_iova[CPT_EC_ID_PMAX];
+
 /* Forward declarations */
 
 static int
@@ -440,6 +442,11 @@ otx2_cpt_enqueue_asym(struct otx2_cpt_qp *qp,
 		if (unlikely(ret))
 			goto req_fail;
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		ret = cpt_enqueue_ecdsa_op(op, &params, sess, otx2_fpm_iova);
+		if (unlikely(ret))
+			goto req_fail;
+		break;
 	default:
 		op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
 		ret = -EINVAL;
@@ -641,6 +648,23 @@ otx2_cpt_asym_rsa_op(struct rte_crypto_op *cop, struct cpt_request_info *req,
 	}
 }
 
+static __rte_always_inline void
+otx2_cpt_asym_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa,
+			       struct cpt_request_info *req,
+			       struct cpt_asym_ec_ctx *ec)
+{
+	int prime_len = ec_grp[ec->curveid].prime.length;
+
+	if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
+		return;
+
+	/* Separate out sign r and s components */
+	memcpy(ecdsa->r.data, req->rptr, prime_len);
+	memcpy(ecdsa->s.data, req->rptr + ROUNDUP8(prime_len), prime_len);
+	ecdsa->r.length = prime_len;
+	ecdsa->s.length = prime_len;
+}
+
 static void
 otx2_cpt_asym_post_process(struct rte_crypto_op *cop,
 			   struct cpt_request_info *req)
@@ -660,6 +684,9 @@ otx2_cpt_asym_post_process(struct rte_crypto_op *cop,
 		memcpy(op->modex.result.data, req->rptr,
 		       op->modex.result.length);
 		break;
+	case RTE_CRYPTO_ASYM_XFORM_ECDSA:
+		otx2_cpt_asym_dequeue_ecdsa_op(&op->ecdsa, req, &sess->ec_ctx);
+		break;
 	default:
 		CPT_LOG_DP_DEBUG("Invalid crypto xform type");
 		cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
@@ -824,6 +851,13 @@ otx2_cpt_dev_config(struct rte_cryptodev *dev,
 
 	dev->feature_flags &= ~conf->ff_disable;
 
+	if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) {
+		/* Initialize shared FPM table */
+		ret = cpt_fpm_init(otx2_fpm_iova);
+		if (ret)
+			return ret;
+	}
+
 	/* Unregister error interrupts */
 	if (vf->err_intr_registered)
 		otx2_cpt_err_intr_unregister(dev);
@@ -881,9 +915,10 @@ otx2_cpt_dev_start(struct rte_cryptodev *dev)
 static void
 otx2_cpt_dev_stop(struct rte_cryptodev *dev)
 {
-	RTE_SET_USED(dev);
-
 	CPT_PMD_INIT_FUNC_TRACE();
+
+	if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)
+		cpt_fpm_clear();
 }
 
 static int
-- 
2.7.4


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

* [dpdk-dev] [PATCH v2 4/4] app/test: add ECDSA sign/verify tests
  2020-01-15 12:43 ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Anoob Joseph
                     ` (2 preceding siblings ...)
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 3/4] crypto/octeontx2: " Anoob Joseph
@ 2020-01-15 12:43   ` Anoob Joseph
  2020-01-15 15:50   ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Akhil Goyal
  4 siblings, 0 replies; 19+ messages in thread
From: Anoob Joseph @ 2020-01-15 12:43 UTC (permalink / raw)
  To: Akhil Goyal, Declan Doherty, Pablo de Lara
  Cc: Ayuj Verma, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, Sunila Sahu, dev,
	Anoob Joseph

From: Ayuj Verma <ayverma@marvell.com>

This patch adds ECDSA sign and verify test routine and test vectors.

Signed-off-by: Anoob Joseph <anoobj@marvell.com>
Signed-off-by: Ayuj Verma <ayverma@marvell.com>
Signed-off-by: Sunila Sahu <ssahu@marvell.com>
---
 app/test/test_cryptodev_asym.c               | 219 +++++++++++-
 app/test/test_cryptodev_asym_util.h          |  11 +
 app/test/test_cryptodev_ecdsa_test_vectors.h | 505 +++++++++++++++++++++++++++
 3 files changed, 734 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_cryptodev_ecdsa_test_vectors.h

diff --git a/app/test/test_cryptodev_asym.c b/app/test/test_cryptodev_asym.c
index 69df293..08479bb 100644
--- a/app/test/test_cryptodev_asym.c
+++ b/app/test/test_cryptodev_asym.c
@@ -18,6 +18,7 @@
 #include "test_cryptodev.h"
 #include "test_cryptodev_dh_test_vectors.h"
 #include "test_cryptodev_dsa_test_vectors.h"
+#include "test_cryptodev_ecdsa_test_vectors.h"
 #include "test_cryptodev_mod_test_vectors.h"
 #include "test_cryptodev_rsa_test_vectors.h"
 #include "test_cryptodev_asym_util.h"
@@ -1037,14 +1038,16 @@ static inline void print_asym_capa(
 		case RTE_CRYPTO_ASYM_XFORM_MODEX:
 		case RTE_CRYPTO_ASYM_XFORM_DH:
 		case RTE_CRYPTO_ASYM_XFORM_DSA:
-			printf(" modlen: min %d max %d increment %d\n",
+			printf(" modlen: min %d max %d increment %d",
 					capa->modlen.min,
 					capa->modlen.max,
 					capa->modlen.increment);
 		break;
+		case RTE_CRYPTO_ASYM_XFORM_ECDSA:
 		default:
 			break;
 		}
+		printf("\n");
 }
 
 static int
@@ -1892,6 +1895,218 @@ test_dsa(void)
 	return status;
 }
 
+static int
+test_ecdsa_sign_verify(enum curve curve_id)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct rte_mempool *sess_mpool = ts_params->session_mpool;
+	struct rte_mempool *op_mpool = ts_params->op_mpool;
+	struct crypto_testsuite_ecdsa_params input_params;
+	struct rte_cryptodev_asym_session *sess = NULL;
+	uint8_t dev_id = ts_params->valid_devs[0];
+	struct rte_crypto_op *result_op = NULL;
+	uint8_t output_buf_r[TEST_DATA_SIZE];
+	uint8_t output_buf_s[TEST_DATA_SIZE];
+	struct rte_crypto_asym_xform xform;
+	struct rte_crypto_asym_op *asym_op;
+	struct rte_cryptodev_info dev_info;
+	struct rte_crypto_op *op = NULL;
+	int status = TEST_SUCCESS, ret;
+
+	switch (curve_id) {
+	case SECP192R1:
+		input_params = ecdsa_param_secp192r1;
+		break;
+	case SECP224R1:
+		input_params = ecdsa_param_secp224r1;
+		break;
+	case SECP256R1:
+		input_params = ecdsa_param_secp256r1;
+		break;
+	case SECP384R1:
+		input_params = ecdsa_param_secp384r1;
+		break;
+	case SECP521R1:
+		input_params = ecdsa_param_secp521r1;
+		break;
+	default:
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Unsupported curve id\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	rte_cryptodev_info_get(dev_id, &dev_info);
+
+	sess = rte_cryptodev_asym_session_create(sess_mpool);
+	if (sess == NULL) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Session creation failed\n");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	/* 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_ECDSA;
+	xform.ec.curve_id = input_params.curve;
+
+	if (rte_cryptodev_asym_session_init(dev_id, sess, &xform,
+				sess_mpool) < 0) {
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"Unable to config asym session\n");
+		status = 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 */
+	op->asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+	op->asym->ecdsa.message.data = input_params.digest.data;
+	op->asym->ecdsa.message.length = input_params.digest.length;
+	op->asym->ecdsa.k.data = input_params.scalar.data;
+	op->asym->ecdsa.k.length = input_params.scalar.length;
+	op->asym->ecdsa.pkey.data = input_params.pkey.data;
+	op->asym->ecdsa.pkey.length = input_params.pkey.length;
+
+	/* Init out buf */
+	op->asym->ecdsa.r.data = output_buf_r;
+	op->asym->ecdsa.s.data = output_buf_s;
+
+	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");
+		status = TEST_FAILED;
+		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");
+		status = TEST_FAILED;
+		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");
+		status = TEST_FAILED;
+		goto exit;
+	}
+
+	asym_op = result_op->asym;
+
+	debug_hexdump(stdout, "r:",
+			asym_op->ecdsa.r.data, asym_op->ecdsa.r.length);
+	debug_hexdump(stdout, "s:",
+			asym_op->ecdsa.s.data, asym_op->ecdsa.s.length);
+
+	ret = verify_ecdsa_sign(input_params.sign_r.data,
+				input_params.sign_s.data, result_op);
+	if (ret) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"ECDSA sign failed.\n");
+		goto exit;
+	}
+
+	/* Verify sign */
+
+	/* Populate op with operational details */
+	op->asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+	op->asym->ecdsa.q.x.data = input_params.pubkey_qx.data;
+	op->asym->ecdsa.q.x.length = input_params.pubkey_qx.length;
+	op->asym->ecdsa.q.y.data = input_params.pubkey_qy.data;
+	op->asym->ecdsa.q.y.length = input_params.pubkey_qx.length;
+	op->asym->ecdsa.r.data = asym_op->ecdsa.r.data;
+	op->asym->ecdsa.r.length = asym_op->ecdsa.r.length;
+	op->asym->ecdsa.s.data = asym_op->ecdsa.s.data;
+	op->asym->ecdsa.s.length = asym_op->ecdsa.s.length;
+
+	/* Enqueue sign result for verify */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		status = TEST_FAILED;
+		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) {
+		status = TEST_FAILED;
+		goto exit;
+	}
+	if (result_op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		status = TEST_FAILED;
+		RTE_LOG(ERR, USER1,
+				"line %u FAILED: %s", __LINE__,
+				"ECDSA verify failed.\n");
+		goto exit;
+	}
+
+exit:
+	if (sess != NULL) {
+		rte_cryptodev_asym_session_clear(dev_id, sess);
+		rte_cryptodev_asym_session_free(sess);
+	}
+	if (op != NULL)
+		rte_crypto_op_free(op);
+	return status;
+};
+
+static int
+test_ecdsa_sign_verify_all_curve(void)
+{
+	int status, overall_status = TEST_SUCCESS;
+	enum curve curve_id;
+	int test_index = 0;
+	const char *msg;
+
+	for (curve_id = SECP192R1; curve_id < END_OF_CURVE_LIST; curve_id++) {
+		status = test_ecdsa_sign_verify(curve_id);
+		if (status == TEST_SUCCESS) {
+			msg = "succeeded";
+		} else {
+			msg = "failed";
+			overall_status = status;
+		}
+		printf("  %u) TestCase Sign/Veriy Curve %s  %s\n",
+		       test_index ++, curve[curve_id], msg);
+	}
+	return overall_status;
+}
 
 static struct unit_test_suite cryptodev_openssl_asym_testsuite  = {
 	.suite_name = "Crypto Device OPENSSL ASYM Unit Test Suite",
@@ -1931,6 +2146,8 @@ static struct unit_test_suite cryptodev_octeontx_asym_testsuite  = {
 		TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_enc_dec_crt),
 		TEST_CASE_ST(ut_setup, ut_teardown, test_rsa_sign_verify_crt),
 		TEST_CASE_ST(ut_setup, ut_teardown, test_mod_exp),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			     test_ecdsa_sign_verify_all_curve),
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_asym_util.h b/app/test/test_cryptodev_asym_util.h
index f2a8e6c..bddeda0 100644
--- a/app/test/test_cryptodev_asym_util.h
+++ b/app/test/test_cryptodev_asym_util.h
@@ -35,4 +35,15 @@ static inline int verify_modexp(uint8_t *mod_exp,
 	return 0;
 }
 
+static inline int verify_ecdsa_sign(uint8_t *sign_r,
+		uint8_t *sign_s, struct rte_crypto_op *result_op)
+{
+	if (memcmp(sign_r, result_op->asym->ecdsa.r.data,
+		   result_op->asym->ecdsa.r.length) ||
+		   memcmp(sign_s, result_op->asym->ecdsa.s.data,
+		   result_op->asym->ecdsa.s.length))
+		return -1;
+	return 0;
+}
+
 #endif /* TEST_CRYPTODEV_ASYM_TEST_UTIL_H__ */
diff --git a/app/test/test_cryptodev_ecdsa_test_vectors.h b/app/test/test_cryptodev_ecdsa_test_vectors.h
new file mode 100644
index 0000000..55fbda5
--- /dev/null
+++ b/app/test/test_cryptodev_ecdsa_test_vectors.h
@@ -0,0 +1,505 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__
+#define __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__
+
+#include "rte_crypto_asym.h"
+
+/* EC curve id */
+enum curve {
+	SECP192R1,
+	SECP224R1,
+	SECP256R1,
+	SECP384R1,
+	SECP521R1,
+	END_OF_CURVE_LIST
+};
+
+const char *curve[] = {"SECP192R1",
+		       "SECP224R1",
+		       "SECP256R1",
+		       "SECP384R1",
+		       "SECP521R1"};
+
+struct crypto_testsuite_ecdsa_params {
+	rte_crypto_param pubkey_qx;
+	rte_crypto_param pubkey_qy;
+	rte_crypto_param scalar;
+	rte_crypto_param digest;
+	rte_crypto_param sign_r;
+	rte_crypto_param sign_s;
+	rte_crypto_param pkey;
+	int curve;
+};
+
+/*
+ * Test vector reference:
+ * https://csrc.nist.gov/CSRC/media/Projects/
+ * Cryptographic-Algorithm-Validation-Program/
+ * documents/components/186-3ecdsasiggencomponenttestvectors.zip
+ */
+
+/* SECP192R1 (P-192 NIST) test vector */
+
+static uint8_t digest_secp192r1[] = {
+	0x5a, 0xe8, 0x31, 0x7d, 0x34, 0xd1, 0xe5, 0x95,
+	0xe3, 0xfa, 0x72, 0x47, 0xdb, 0x80, 0xc0, 0xaf,
+	0x43, 0x20, 0xcc, 0xe1, 0x11, 0x6d, 0xe1, 0x87,
+	0xf8, 0xf7, 0xe2, 0xe0, 0x99, 0xc0, 0xd8, 0xd0
+};
+
+static uint8_t pkey_secp192r1[] = {
+	0x24, 0xed, 0xd2, 0x2f, 0x7d, 0xdd, 0x6f, 0xa5,
+	0xbc, 0x61, 0xfc, 0x06, 0x53, 0x47, 0x9a, 0xa4,
+	0x08, 0x09, 0xef, 0x86, 0x5c, 0xf2, 0x7a, 0x47
+};
+
+static uint8_t scalar_secp192r1[] = {
+	0xa5, 0xc8, 0x17, 0xa2, 0x36, 0xa5, 0xf7, 0xfa,
+	0xa3, 0x29, 0xb8, 0xec, 0xc3, 0xc5, 0x96, 0x68,
+	0x7c, 0x71, 0xaa, 0xaf, 0x86, 0xc7, 0x70, 0x3e
+};
+
+static uint8_t pubkey_qx_secp192r1[] = {
+	0x9b, 0xf1, 0x2d, 0x71, 0x74, 0xb7, 0x70, 0x8a,
+	0x07, 0x6a, 0x38, 0xbc, 0x80, 0xaa, 0x28, 0x66,
+	0x2f, 0x25, 0x1e, 0x2e, 0xd8, 0xd4, 0x14, 0xdc
+};
+
+static uint8_t pubkey_qy_secp192r1[] = {
+	0x48, 0x54, 0xc8, 0xd0, 0x7d, 0xfc, 0x08, 0x82,
+	0x4e, 0x9e, 0x47, 0x1c, 0xa2, 0xfe, 0xdc, 0xfc,
+	0xff, 0x3d, 0xdc, 0xb0, 0x11, 0x57, 0x34, 0x98
+};
+
+static uint8_t sign_secp192r1_r[] = {
+	0x35, 0x4a, 0xba, 0xec, 0xf4, 0x36, 0x1f, 0xea,
+	0x90, 0xc2, 0x9b, 0x91, 0x99, 0x88, 0x2e, 0xdf,
+	0x85, 0x73, 0xe6, 0x86, 0xa8, 0x13, 0xef, 0xf8
+};
+
+static uint8_t sign_secp192r1_s[] = {
+	0x80, 0xf5, 0x00, 0x00, 0xac, 0x86, 0x11, 0x1c,
+	0x9b, 0x30, 0x47, 0x38, 0x5a, 0x15, 0xd7, 0x8e,
+	0x63, 0x2c, 0x58, 0xb7, 0x94, 0x9e, 0x82, 0xc1
+};
+
+/** ECDSA SECP192R1 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_secp192r1 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_secp192r1,
+		.length = sizeof(pubkey_qx_secp192r1),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_secp192r1,
+		.length = sizeof(pubkey_qy_secp192r1),
+	},
+	.scalar = {
+		.data = scalar_secp192r1,
+		.length = sizeof(scalar_secp192r1),
+	},
+	.digest = {
+		.data = digest_secp192r1,
+		.length = sizeof(digest_secp192r1),
+	},
+	.sign_r = {
+		.data = sign_secp192r1_r,
+		.length = sizeof(sign_secp192r1_r),
+	},
+	.sign_s = {
+		.data = sign_secp192r1_s,
+		.length = sizeof(sign_secp192r1_s),
+	},
+	.pkey = {
+		.data = pkey_secp192r1,
+		.length = sizeof(pkey_secp192r1),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_SECP192R1
+};
+
+/* SECP224R1 (P-224 NIST) test vectors */
+
+static uint8_t digest_secp224r1[] = {
+	0x00, 0xc6, 0xfc, 0x53, 0xc1, 0x98, 0x6d, 0x19,
+	0xa8, 0xa8, 0xb5, 0x80, 0xee, 0x55, 0x3d, 0xc1,
+	0x24, 0x07, 0x45, 0xd7, 0x60, 0x64, 0x7d, 0x1c,
+	0x0a, 0xdf, 0x44, 0x2c, 0x13, 0x3c, 0x7f, 0x56
+};
+
+static uint8_t pkey_secp224r1[] = {
+	0x88, 0x8f, 0xc9, 0x92, 0x89, 0x3b, 0xdd, 0x8a,
+	0xa0, 0x2c, 0x80, 0x76, 0x88, 0x32, 0x60, 0x5d,
+	0x02, 0x0b, 0x81, 0xae, 0x0b, 0x25, 0x47, 0x41,
+	0x54, 0xec, 0x89, 0xaa
+};
+
+static uint8_t scalar_secp224r1[] = {
+	0x06, 0xf7, 0xa5, 0x60, 0x07, 0x82, 0x54, 0x33,
+	0xc4, 0xc6, 0x11, 0x53, 0xdf, 0x1a, 0x13, 0x5e,
+	0xee, 0x2f, 0x38, 0xec, 0x68, 0x7b, 0x49, 0x2e,
+	0xd4, 0x0d, 0x9c, 0x90
+};
+
+static uint8_t pubkey_qx_secp224r1[] = {
+	0x4c, 0x74, 0x1e, 0x4d, 0x20, 0x10, 0x36, 0x70,
+	0xb7, 0x16, 0x1a, 0xe7, 0x22, 0x71, 0x08, 0x21,
+	0x55, 0x83, 0x84, 0x18, 0x08, 0x43, 0x35, 0x33,
+	0x8a, 0xc3, 0x8f, 0xa4
+};
+
+static uint8_t pubkey_qy_secp224r1[] = {
+	0xdb, 0x79, 0x19, 0x15, 0x1a, 0xc2, 0x85, 0x87,
+	0xb7, 0x2b, 0xad, 0x7a, 0xb1, 0x80, 0xec, 0x8e,
+	0x95, 0xab, 0x9e, 0x2c, 0x8d, 0x81, 0xd9, 0xb9,
+	0xd7, 0xe2, 0xe3, 0x83
+};
+
+static uint8_t sign_secp224r1_r[] = {
+	0x09, 0x09, 0xc9, 0xb9, 0xca, 0xe8, 0xd2, 0x79,
+	0x0e, 0x29, 0xdb, 0x6a, 0xfd, 0xb4, 0x5c, 0x04,
+	0xf5, 0xb0, 0x72, 0xc4, 0xc2, 0x04, 0x10, 0xc7,
+	0xdc, 0x9b, 0x67, 0x72
+};
+
+static uint8_t sign_secp224r1_s[] = {
+	0x29, 0x8f, 0x4f, 0xca, 0xe1, 0xfe, 0x27, 0x1d,
+	0xa1, 0xe0, 0x34, 0x5d, 0x11, 0xd0, 0x7a, 0x1f,
+	0xca, 0x43, 0xf5, 0x8a, 0xf4, 0xc1, 0x13, 0xb9,
+	0x09, 0xee, 0xde, 0xa0
+};
+
+/** ECDSA SECP224R1 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_secp224r1 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_secp224r1,
+		.length = sizeof(pubkey_qx_secp224r1),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_secp224r1,
+		.length = sizeof(pubkey_qy_secp224r1),
+	},
+	.scalar = {
+		.data = scalar_secp224r1,
+		.length = sizeof(scalar_secp224r1),
+	},
+	.digest = {
+		.data = digest_secp224r1,
+		.length = sizeof(digest_secp224r1),
+	},
+	.sign_r = {
+		.data = sign_secp224r1_r,
+		.length = sizeof(sign_secp224r1_r),
+	},
+	.sign_s = {
+		.data = sign_secp224r1_s,
+		.length = sizeof(sign_secp224r1_s),
+	},
+	.pkey = {
+		.data = pkey_secp224r1,
+		.length = sizeof(pkey_secp224r1),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_SECP224R1
+};
+
+/* SECP256R1 (P-256 NIST) test vectors */
+
+static uint8_t digest_secp256r1[] = {
+	0x44, 0xac, 0xf6, 0xb7, 0xe3, 0x6c, 0x13, 0x42,
+	0xc2, 0xc5, 0x89, 0x72, 0x04, 0xfe, 0x09, 0x50,
+	0x4e, 0x1e, 0x2e, 0xfb, 0x1a, 0x90, 0x03, 0x77,
+	0xdb, 0xc4, 0xe7, 0xa6, 0xa1, 0x33, 0xec, 0x56
+};
+
+static uint8_t pkey_secp256r1[] = {
+	0x51, 0x9b, 0x42, 0x3d, 0x71, 0x5f, 0x8b, 0x58,
+	0x1f, 0x4f, 0xa8, 0xee, 0x59, 0xf4, 0x77, 0x1a,
+	0x5b, 0x44, 0xc8, 0x13, 0x0b, 0x4e, 0x3e, 0xac,
+	0xca, 0x54, 0xa5, 0x6d, 0xda, 0x72, 0xb4, 0x64
+};
+
+static uint8_t scalar_secp256r1[] = {
+	0x94, 0xa1, 0xbb, 0xb1, 0x4b, 0x90, 0x6a, 0x61,
+	0xa2, 0x80, 0xf2, 0x45, 0xf9, 0xe9, 0x3c, 0x7f,
+	0x3b, 0x4a, 0x62, 0x47, 0x82, 0x4f, 0x5d, 0x33,
+	0xb9, 0x67, 0x07, 0x87, 0x64, 0x2a, 0x68, 0xde
+};
+
+static uint8_t pubkey_qx_secp256r1[] = {
+	0x1c, 0xcb, 0xe9, 0x1c, 0x07, 0x5f, 0xc7, 0xf4,
+	0xf0, 0x33, 0xbf, 0xa2, 0x48, 0xdb, 0x8f, 0xcc,
+	0xd3, 0x56, 0x5d, 0xe9, 0x4b, 0xbf, 0xb1, 0x2f,
+	0x3c, 0x59, 0xff, 0x46, 0xc2, 0x71, 0xbf, 0x83
+};
+
+static uint8_t pubkey_qy_secp256r1[] = {
+	0xce, 0x40, 0x14, 0xc6, 0x88, 0x11, 0xf9, 0xa2,
+	0x1a, 0x1f, 0xdb, 0x2c, 0x0e, 0x61, 0x13, 0xe0,
+	0x6d, 0xb7, 0xca, 0x93, 0xb7, 0x40, 0x4e, 0x78,
+	0xdc, 0x7c, 0xcd, 0x5c, 0xa8, 0x9a, 0x4c, 0xa9
+};
+
+static uint8_t sign_secp256r1_r[] = {
+	0xf3, 0xac, 0x80, 0x61, 0xb5, 0x14, 0x79, 0x5b,
+	0x88, 0x43, 0xe3, 0xd6, 0x62, 0x95, 0x27, 0xed,
+	0x2a, 0xfd, 0x6b, 0x1f, 0x6a, 0x55, 0x5a, 0x7a,
+	0xca, 0xbb, 0x5e, 0x6f, 0x79, 0xc8, 0xc2, 0xac
+};
+
+static uint8_t sign_secp256r1_s[] = {
+	0x8b, 0xf7, 0x78, 0x19, 0xca, 0x05, 0xa6, 0xb2,
+	0x78, 0x6c, 0x76, 0x26, 0x2b, 0xf7, 0x37, 0x1c,
+	0xef, 0x97, 0xb2, 0x18, 0xe9, 0x6f, 0x17, 0x5a,
+	0x3c, 0xcd, 0xda, 0x2a, 0xcc, 0x05, 0x89, 0x03
+};
+
+/** ECDSA SECP256R1 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_secp256r1 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_secp256r1,
+		.length = sizeof(pubkey_qx_secp256r1),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_secp256r1,
+		.length = sizeof(pubkey_qy_secp256r1),
+	},
+	.scalar = {
+		.data = scalar_secp256r1,
+		.length = sizeof(scalar_secp256r1),
+	},
+	.digest = {
+		.data = digest_secp256r1,
+		.length = sizeof(digest_secp256r1),
+	},
+	.sign_r = {
+		.data = sign_secp256r1_r,
+		.length = sizeof(sign_secp256r1_r),
+	},
+	.sign_s = {
+		.data = sign_secp256r1_s,
+		.length = sizeof(sign_secp256r1_s),
+	},
+	.pkey = {
+		.data = pkey_secp256r1,
+		.length = sizeof(pkey_secp256r1),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_SECP256R1
+};
+
+/* SECP384R1 (P-384 NIST) test vectors */
+
+static uint8_t digest_secp384r1[] = {
+	0xbb, 0xbd, 0x0a, 0x5f, 0x64, 0x5d, 0x3f, 0xda,
+	0x10, 0xe2, 0x88, 0xd1, 0x72, 0xb2, 0x99, 0x45,
+	0x5f, 0x9d, 0xff, 0x00, 0xe0, 0xfb, 0xc2, 0x83,
+	0x3e, 0x18, 0xcd, 0x01, 0x7d, 0x7f, 0x3e, 0xd1
+};
+
+static uint8_t pkey_secp384r1[] = {
+	0xc6, 0x02, 0xbc, 0x74, 0xa3, 0x45, 0x92, 0xc3,
+	0x11, 0xa6, 0x56, 0x96, 0x61, 0xe0, 0x83, 0x2c,
+	0x84, 0xf7, 0x20, 0x72, 0x74, 0x67, 0x6c, 0xc4,
+	0x2a, 0x89, 0xf0, 0x58, 0x16, 0x26, 0x30, 0x18,
+	0x4b, 0x52, 0xf0, 0xd9, 0x9b, 0x85, 0x5a, 0x77,
+	0x83, 0xc9, 0x87, 0x47, 0x6d, 0x7f, 0x9e, 0x6b
+};
+
+static uint8_t scalar_secp384r1[] = {
+	0xc1, 0x0b, 0x5c, 0x25, 0xc4, 0x68, 0x3d, 0x0b,
+	0x78, 0x27, 0xd0, 0xd8, 0x86, 0x97, 0xcd, 0xc0,
+	0x93, 0x24, 0x96, 0xb5, 0x29, 0x9b, 0x79, 0x8c,
+	0x0d, 0xd1, 0xe7, 0xaf, 0x6c, 0xc7, 0x57, 0xcc,
+	0xb3, 0x0f, 0xcd, 0x3d, 0x36, 0xea, 0xd4, 0xa8,
+	0x04, 0x87, 0x7e, 0x24, 0xf3, 0xa3, 0x24, 0x43
+};
+
+static uint8_t pubkey_qx_secp384r1[] = {
+	0x04, 0x00, 0x19, 0x3b, 0x21, 0xf0, 0x7c, 0xd0,
+	0x59, 0x82, 0x6e, 0x94, 0x53, 0xd3, 0xe9, 0x6d,
+	0xd1, 0x45, 0x04, 0x1c, 0x97, 0xd4, 0x9f, 0xf6,
+	0xb7, 0x04, 0x7f, 0x86, 0xbb, 0x0b, 0x04, 0x39,
+	0xe9, 0x09, 0x27, 0x4c, 0xb9, 0xc2, 0x82, 0xbf,
+	0xab, 0x88, 0x67, 0x4c, 0x07, 0x65, 0xbc, 0x75
+};
+
+static uint8_t pubkey_qy_secp384r1[] = {
+	0xf7, 0x0d, 0x89, 0xc5, 0x2a, 0xcb, 0xc7, 0x04,
+	0x68, 0xd2, 0xc5, 0xae, 0x75, 0xc7, 0x6d, 0x7f,
+	0x69, 0xb7, 0x6a, 0xf6, 0x2d, 0xcf, 0x95, 0xe9,
+	0x9e, 0xba, 0x5d, 0xd1, 0x1a, 0xdf, 0x8f, 0x42,
+	0xec, 0x9a, 0x42, 0x5b, 0x0c, 0x5e, 0xc9, 0x8e,
+	0x2f, 0x23, 0x4a, 0x92, 0x6b, 0x82, 0xa1, 0x47
+};
+
+static uint8_t sign_secp384r1_r[] = {
+	0xb1, 0x1d, 0xb0, 0x0c, 0xda, 0xf5, 0x32, 0x86,
+	0xd4, 0x48, 0x3f, 0x38, 0xcd, 0x02, 0x78, 0x59,
+	0x48, 0x47, 0x7e, 0xd7, 0xeb, 0xc2, 0xad, 0x60,
+	0x90, 0x54, 0x55, 0x1d, 0xa0, 0xab, 0x03, 0x59,
+	0x97, 0x8c, 0x61, 0x85, 0x17, 0x88, 0xaa, 0x2e,
+	0xc3, 0x26, 0x79, 0x46, 0xd4, 0x40, 0xe8, 0x78
+};
+
+static uint8_t sign_secp384r1_s[] = {
+	0x16, 0x00, 0x78, 0x73, 0xc5, 0xb0, 0x60, 0x4c,
+	0xe6, 0x81, 0x12, 0xa8, 0xfe, 0xe9, 0x73, 0xe8,
+	0xe2, 0xb6, 0xe3, 0x31, 0x9c, 0x68, 0x3a, 0x76,
+	0x2f, 0xf5, 0x06, 0x5a, 0x07, 0x65, 0x12, 0xd7,
+	0xc9, 0x8b, 0x27, 0xe7, 0x4b, 0x78, 0x87, 0x67,
+	0x10, 0x48, 0xac, 0x02, 0x7d, 0xf8, 0xcb, 0xf2
+};
+
+/** ECDSA SECP384R1 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_secp384r1 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_secp384r1,
+		.length = sizeof(pubkey_qx_secp384r1),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_secp384r1,
+		.length = sizeof(pubkey_qy_secp384r1),
+	},
+	.scalar = {
+		.data = scalar_secp384r1,
+		.length = sizeof(scalar_secp384r1),
+	},
+	.digest = {
+		.data = digest_secp384r1,
+		.length = sizeof(digest_secp384r1),
+	},
+	.sign_r = {
+		.data = sign_secp384r1_r,
+		.length = sizeof(sign_secp384r1_r),
+	},
+	.sign_s = {
+		.data = sign_secp384r1_s,
+		.length = sizeof(sign_secp384r1_s),
+	},
+	.pkey = {
+		.data = pkey_secp384r1,
+		.length = sizeof(pkey_secp384r1),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_SECP384R1
+};
+
+/* SECP521R1 (P-521 NIST) test vectors */
+
+static uint8_t digest_secp521r1[] = {
+	0x53, 0xe6, 0x53, 0x7c, 0xb6, 0xea, 0x68, 0xae,
+	0x47, 0xa8, 0x16, 0x11, 0xc2, 0x27, 0x56, 0xd7,
+	0x70, 0xd7, 0xa3, 0x7e, 0x33, 0x6c, 0x3a, 0xf0,
+	0xb0, 0x81, 0x4b, 0x04, 0xfa, 0x39, 0x43, 0x4b
+};
+
+static uint8_t pkey_secp521r1[] = {
+	0x01, 0xe8, 0xc0, 0x59, 0x96, 0xb8, 0x5e, 0x6f,
+	0x3f, 0x87, 0x57, 0x12, 0xa0, 0x9c, 0x1b, 0x40,
+	0x67, 0x2b, 0x5e, 0x7a, 0x78, 0xd5, 0x85, 0x2d,
+	0xe0, 0x15, 0x85, 0xc5, 0xfb, 0x99, 0x0b, 0xf3,
+	0x81, 0x2c, 0x32, 0x45, 0x53, 0x4a, 0x71, 0x43,
+	0x89, 0xae, 0x90, 0x14, 0xd6, 0x77, 0xa4, 0x49,
+	0xef, 0xd6, 0x58, 0x25, 0x4e, 0x61, 0x0d, 0xa8,
+	0xe6, 0xca, 0xd3, 0x34, 0x14, 0xb9, 0xd3, 0x3e,
+	0x0d, 0x7a
+};
+
+static uint8_t scalar_secp521r1[] = {
+	0x00, 0xdc, 0x8d, 0xaa, 0xac, 0xdd, 0xb8, 0xfd,
+	0x2f, 0xf5, 0xc3, 0x4a, 0x5c, 0xe1, 0x83, 0xa4,
+	0x22, 0x61, 0xad, 0x3c, 0x64, 0xdb, 0xfc, 0x09,
+	0x5e, 0x58, 0x92, 0x43, 0x64, 0xdc, 0x47, 0xea,
+	0x1c, 0x05, 0xe2, 0x59, 0x9a, 0xae, 0x91, 0x7c,
+	0x2c, 0x95, 0xf4, 0x7d, 0x6b, 0xb3, 0x7d, 0xa0,
+	0x08, 0xaf, 0x9f, 0x55, 0x73, 0x0d, 0xdb, 0xe4,
+	0xd8, 0xde, 0xd2, 0x4f, 0x9e, 0x8d, 0xaa, 0x46,
+	0xdb, 0x6a
+};
+
+static uint8_t pubkey_qx_secp521r1[] = {
+	0x00, 0x7d, 0x04, 0x2c, 0xa1, 0x94, 0x08, 0x52,
+	0x4e, 0x68, 0xb9, 0x81, 0xf1, 0x41, 0x93, 0x51,
+	0xe3, 0xb8, 0x47, 0x36, 0xc7, 0x7f, 0xe5, 0x8f,
+	0xee, 0x7d, 0x11, 0x31, 0x7d, 0xf2, 0xe8, 0x50,
+	0xd9, 0x60, 0xc7, 0xdd, 0x10, 0xd1, 0x0b, 0xa7,
+	0x14, 0xc8, 0xa6, 0x09, 0xd1, 0x63, 0x50, 0x2b,
+	0x79, 0xd6, 0x82, 0xe8, 0xbb, 0xec, 0xd4, 0xf5,
+	0x25, 0x91, 0xd2, 0x74, 0x85, 0x33, 0xe4, 0x5a,
+	0x86, 0x7a
+};
+
+static uint8_t pubkey_qy_secp521r1[] = {
+	0x01, 0x97, 0xac, 0x64, 0x16, 0x11, 0x1c, 0xcf,
+	0x98, 0x7d, 0x29, 0x04, 0x59, 0xeb, 0xc8, 0xad,
+	0x9e, 0xc5, 0x6e, 0x49, 0x05, 0x9c, 0x99, 0x21,
+	0x55, 0x53, 0x9a, 0x36, 0xa6, 0x26, 0x63, 0x1f,
+	0x4a, 0x2d, 0x89, 0x16, 0x4b, 0x98, 0x51, 0x54,
+	0xf2, 0xdd, 0xdc, 0x02, 0x81, 0xee, 0x5b, 0x51,
+	0x78, 0x27, 0x1f, 0x3a, 0x76, 0xa0, 0x91, 0x4c,
+	0x3f, 0xcd, 0x1f, 0x97, 0xbe, 0x8e, 0x83, 0x76,
+	0xef, 0xb3
+};
+
+static uint8_t sign_secp521r1_r[] = {
+	0x00, 0x9d, 0xd1, 0xf2, 0xa7, 0x16, 0x84, 0x3e,
+	0xed, 0xec, 0x7a, 0x66, 0x45, 0xac, 0x83, 0x4d,
+	0x43, 0x36, 0xe7, 0xb1, 0x8e, 0x35, 0x70, 0x1f,
+	0x06, 0xca, 0xe9, 0xd6, 0xb2, 0x90, 0xd4, 0x14,
+	0x91, 0x42, 0x47, 0x35, 0xf3, 0xb5, 0x7e, 0x82,
+	0x9a, 0xd5, 0xde, 0x05, 0x5e, 0xae, 0xef, 0x17,
+	0x78, 0xf0, 0x51, 0xc1, 0xee, 0x15, 0x2b, 0xf2,
+	0x13, 0x1a, 0x08, 0x1e, 0x53, 0xdf, 0x2a, 0x56,
+	0x7a, 0x8a
+};
+
+static uint8_t sign_secp521r1_s[] = {
+	0x00, 0x21, 0x48, 0xe8, 0x42, 0x8d, 0x70, 0xa7,
+	0x2b, 0xc9, 0xfa, 0x98, 0x6c, 0x38, 0xc2, 0xc9,
+	0x7d, 0xed, 0xa0, 0x42, 0x0f, 0x22, 0x2f, 0x9d,
+	0xc9, 0x9d, 0x32, 0xc0, 0xac, 0xba, 0x69, 0x9d,
+	0xc7, 0xba, 0x0a, 0x2b, 0x79, 0xce, 0x59, 0x99,
+	0xff, 0x61, 0xbd, 0x0b, 0x23, 0x3c, 0x74, 0x4a,
+	0x89, 0x3b, 0xc1, 0x05, 0xbc, 0xa5, 0xc2, 0x35,
+	0x42, 0x3e, 0x53, 0x16, 0x12, 0xda, 0x65, 0xd7,
+	0x2e, 0x62
+};
+
+/** ECDSA SECP521R1 elliptic curve param */
+
+struct crypto_testsuite_ecdsa_params ecdsa_param_secp521r1 = {
+	.pubkey_qx = {
+		.data = pubkey_qx_secp521r1,
+		.length = sizeof(pubkey_qx_secp521r1),
+	},
+	.pubkey_qy = {
+		.data = pubkey_qy_secp521r1,
+		.length = sizeof(pubkey_qy_secp521r1),
+	},
+	.scalar = {
+		.data = scalar_secp521r1,
+		.length = sizeof(scalar_secp521r1),
+	},
+	.digest = {
+		.data = digest_secp521r1,
+		.length = sizeof(digest_secp521r1),
+	},
+	.sign_r = {
+		.data = sign_secp521r1_r,
+		.length = sizeof(sign_secp521r1_r),
+	},
+	.sign_s = {
+		.data = sign_secp521r1_s,
+		.length = sizeof(sign_secp521r1_s),
+	},
+	.pkey = {
+		.data = pkey_secp521r1,
+		.length = sizeof(pkey_secp521r1),
+	},
+	.curve = RTE_CRYPTO_EC_GROUP_SECP521R1
+};
+
+#endif /* __TEST_CRYPTODEV_ECDSA_TEST_VECTORS_H__ */
-- 
2.7.4


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

* Re: [dpdk-dev] [PATCH v2 0/4]  add ECDSA support
  2020-01-15 12:43 ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Anoob Joseph
                     ` (3 preceding siblings ...)
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 4/4] app/test: add ECDSA sign/verify tests Anoob Joseph
@ 2020-01-15 15:50   ` Akhil Goyal
  4 siblings, 0 replies; 19+ messages in thread
From: Akhil Goyal @ 2020-01-15 15:50 UTC (permalink / raw)
  To: Anoob Joseph, Declan Doherty, Pablo de Lara
  Cc: Fiona Trahe, Arek Kusztal, Jerin Jacob, Narayana Prasad,
	Shally Verma, Ankur Dwivedi, Sunila Sahu, dev



> This series adds support for ECDSA asymmetric operations. Library changes
> and PMD changes for crypto_octeontx & crypto_octoentx2 is added. The final
> patch adds the required test vectors and verification routines.
> 
> v2:
> * Changed all NIST references to use SECP.
> * Minor updates to documentation/comments as suggested by Arek
> * Updated release notes
> 
> Ayuj Verma (2):
>   cryptodev: support ECDSA
>   app/test: add ECDSA sign/verify tests
> 
> Sunila Sahu (2):
>   crypto/octeontx: add ECDSA support
>   crypto/octeontx2: add ECDSA support
> 
>  app/test/test_cryptodev_asym.c                     |  219 +++-
>  app/test/test_cryptodev_asym_util.h                |   11 +
>  app/test/test_cryptodev_ecdsa_test_vectors.h       |  505 +++++++++
>  doc/guides/cryptodevs/features/default.ini         |   11 +-
>  doc/guides/cryptodevs/features/octeontx.ini        |    8 +-
>  doc/guides/cryptodevs/features/octeontx2.ini       |    8 +-
>  doc/guides/rel_notes/release_20_02.rst             |    4 +
>  drivers/common/cpt/Makefile                        |    1 +
>  drivers/common/cpt/cpt_fpm_tables.c                | 1138 ++++++++++++++++++++
>  drivers/common/cpt/cpt_mcode_defines.h             |   38 +
>  drivers/common/cpt/cpt_pmd_ops_helper.h            |   19 +
>  drivers/common/cpt/cpt_ucode_asym.h                |  378 +++++++
>  drivers/common/cpt/meson.build                     |    3 +-
>  drivers/common/cpt/rte_common_cpt_version.map      |    9 +
>  .../crypto/octeontx/otx_cryptodev_capabilities.c   |   11 +
>  drivers/crypto/octeontx/otx_cryptodev_ops.c        |   43 +-
>  .../crypto/octeontx2/otx2_cryptodev_capabilities.c |   11 +
>  drivers/crypto/octeontx2/otx2_cryptodev_ops.c      |   39 +-
>  lib/librte_cryptodev/rte_crypto_asym.h             |   84 ++
>  lib/librte_cryptodev/rte_cryptodev.c               |    1 +
>  20 files changed, 2526 insertions(+), 15 deletions(-)
>  create mode 100644 app/test/test_cryptodev_ecdsa_test_vectors.h
>  create mode 100644 drivers/common/cpt/cpt_fpm_tables.c
> 
Applied to dpdk-next-crypto

Thanks.


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

* Re: [dpdk-dev] [PATCH v2 1/4] cryptodev: support ECDSA
  2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 1/4] cryptodev: support ECDSA Anoob Joseph
@ 2020-01-15 15:51     ` Akhil Goyal
  0 siblings, 0 replies; 19+ messages in thread
From: Akhil Goyal @ 2020-01-15 15:51 UTC (permalink / raw)
  To: Anoob Joseph, Declan Doherty, Pablo de Lara
  Cc: Ayuj Verma, Fiona Trahe, Arek Kusztal, Jerin Jacob,
	Narayana Prasad, Shally Verma, Ankur Dwivedi, Sunila Sahu, dev

> From: Ayuj Verma <ayverma@marvell.com>
> 
> Asymmetric crypto library is extended to add ECDSA. Elliptic curve
> xform and ECDSA op params are introduced.
> 
> Signed-off-by: Anoob Joseph <anoobj@marvell.com>
> Signed-off-by: Ayuj Verma <ayverma@marvell.com>
> Signed-off-by: Sunila Sahu <ssahu@marvell.com>
> ---
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>


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

end of thread, other threads:[~2020-01-15 15:51 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-05 11:43 [dpdk-dev] [PATCH 0/4] add ECDSA support Anoob Joseph
2019-12-05 11:43 ` [dpdk-dev] [PATCH 1/4] lib/crypto: add support for ECDSA Anoob Joseph
2019-12-20 16:05   ` Kusztal, ArkadiuszX
2020-01-02  7:55     ` Anoob Joseph
2020-01-09 13:03       ` Kusztal, ArkadiuszX
2020-01-13 12:47         ` Akhil Goyal
2020-01-13 16:36         ` Anoob Joseph
2020-01-14  5:12           ` Shally Verma
2020-01-14 11:01             ` Kusztal, ArkadiuszX
2019-12-05 11:43 ` [dpdk-dev] [PATCH 2/4] crypto/octeontx: add ECDSA support Anoob Joseph
2019-12-05 11:43 ` [dpdk-dev] [PATCH 3/4] crypto/octeontx2: " Anoob Joseph
2019-12-05 11:43 ` [dpdk-dev] [PATCH 4/4] app/test: add ECDSA sign/verify tests Anoob Joseph
2020-01-15 12:43 ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Anoob Joseph
2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 1/4] cryptodev: support ECDSA Anoob Joseph
2020-01-15 15:51     ` Akhil Goyal
2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 2/4] crypto/octeontx: add ECDSA support Anoob Joseph
2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 3/4] crypto/octeontx2: " Anoob Joseph
2020-01-15 12:43   ` [dpdk-dev] [PATCH v2 4/4] app/test: add ECDSA sign/verify tests Anoob Joseph
2020-01-15 15:50   ` [dpdk-dev] [PATCH v2 0/4] add ECDSA support Akhil Goyal

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).