linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/5] add ECDH and CURVE25519 algorithms support for Kunpeng 930
@ 2020-12-11  6:30 Meng Yu
  2020-12-11  6:30 ` [PATCH v4 1/5] crypto: hisilicon/hpre - add some updates to adapt to " Meng Yu
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Meng Yu @ 2020-12-11  6:30 UTC (permalink / raw)
  To: herbert, davem; +Cc: linux-crypto, xuzaibo, wangzhou1, yumeng18, linux-kernel

1. Move elliptic curve parameter definitions out to "include/crypto";
2. Add some new elliptic curve parameters definitions, and reorder
   ECC 'Curves IDs';
3. Add ECDH and CURVE25519 algorithms support for Kunpeng 930.

These patches depend on:
[v2,1/6] crypto: hisilicon/hpre - add version adapt to new algorithms,
https://patchwork.kernel.org/project/linux-crypto/patch/1607598607-8728-
2-git-send-email-liulongfang@huawei.com/

v3 -> v4:
- patch #3: add new, move ecc_curve params to "include/crypto"

v2 -> v3:
- patch #5: fix sparse warnings
- patch #5: add 'CRYPTO_LIB_CURVE25519_GENERIC' in 'Kconfig'

v1 -> v2:
- patch #5: delete `curve25519_null_point'

Hui Tang (1):
  crypto: hisilicon/hpre - add some updates to adapt to Kunpeng 930

Meng Yu (4):
  crypto: hisilicon/hpre - add algorithm type
  crypto: expose elliptic curve parameters as Crypto APIs
  crypto: hisilicon/hpre - add 'ECDH' algorithm
  crypto: hisilicon/hpre - add 'CURVE25519' algorithm

 crypto/ecc.c                                |   5 +-
 crypto/ecc.h                                |  37 +-
 crypto/ecc_curve_defs.h                     |  57 --
 crypto/ecrdsa_defs.h                        |   2 +-
 crypto/testmgr.h                            |  12 +-
 drivers/crypto/hisilicon/Kconfig            |   1 +
 drivers/crypto/hisilicon/hpre/hpre.h        |  22 +-
 drivers/crypto/hisilicon/hpre/hpre_crypto.c | 868 +++++++++++++++++++++++++++-
 drivers/crypto/hisilicon/hpre/hpre_main.c   | 105 +++-
 include/crypto/ecc_curve_defs.h             | 261 +++++++++
 include/crypto/ecdh.h                       |   9 +-
 11 files changed, 1228 insertions(+), 151 deletions(-)
 delete mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 include/crypto/ecc_curve_defs.h

-- 
2.8.1


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

* [PATCH v4 1/5] crypto: hisilicon/hpre - add some updates to adapt to Kunpeng 930
  2020-12-11  6:30 [PATCH v4 0/5] add ECDH and CURVE25519 algorithms support for Kunpeng 930 Meng Yu
@ 2020-12-11  6:30 ` Meng Yu
  2020-12-11  6:30 ` [PATCH v4 2/5] crypto: hisilicon/hpre - add algorithm type Meng Yu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 15+ messages in thread
From: Meng Yu @ 2020-12-11  6:30 UTC (permalink / raw)
  To: herbert, davem; +Cc: linux-crypto, xuzaibo, wangzhou1, yumeng18, linux-kernel

From: Hui Tang <tanghui20@huawei.com>

HPRE of Kunpeng 930 is updated on cluster numbers and configurations
of Kunpeng 920 HPRE, so we try to update this driver to make it running
okay on both chips.

Signed-off-by: Hui Tang <tanghui20@huawei.com>
Signed-off-by: Meng Yu <yumeng18@huawei.com>
Reviewed-by: Zaibo Xu <xuzaibo@huawei.com>
---
 drivers/crypto/hisilicon/hpre/hpre.h      |  8 ++-
 drivers/crypto/hisilicon/hpre/hpre_main.c | 93 +++++++++++++++++++++----------
 2 files changed, 68 insertions(+), 33 deletions(-)

diff --git a/drivers/crypto/hisilicon/hpre/hpre.h b/drivers/crypto/hisilicon/hpre/hpre.h
index e784712..cc50f23 100644
--- a/drivers/crypto/hisilicon/hpre/hpre.h
+++ b/drivers/crypto/hisilicon/hpre/hpre.h
@@ -14,8 +14,7 @@ enum {
 	HPRE_CLUSTER0,
 	HPRE_CLUSTER1,
 	HPRE_CLUSTER2,
-	HPRE_CLUSTER3,
-	HPRE_CLUSTERS_NUM,
+	HPRE_CLUSTER3
 };
 
 enum hpre_ctrl_dbgfs_file {
@@ -36,7 +35,10 @@ enum hpre_dfx_dbgfs_file {
 	HPRE_DFX_FILE_NUM
 };
 
-#define HPRE_DEBUGFS_FILE_NUM    (HPRE_DEBUG_FILE_NUM + HPRE_CLUSTERS_NUM - 1)
+#define HPRE_CLUSTERS_NUM_V2		(HPRE_CLUSTER3 + 1)
+#define HPRE_CLUSTERS_NUM_V3		1
+#define HPRE_CLUSTERS_NUM_MAX		HPRE_CLUSTERS_NUM_V2
+#define HPRE_DEBUGFS_FILE_NUM (HPRE_DEBUG_FILE_NUM + HPRE_CLUSTERS_NUM_MAX - 1)
 
 struct hpre_debugfs_file {
 	int index;
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index e5c9919..fc7173a 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -29,6 +29,8 @@
 #define HPRE_BD_ARUSR_CFG		0x301030
 #define HPRE_BD_AWUSR_CFG		0x301034
 #define HPRE_TYPES_ENB			0x301038
+#define HPRE_RSA_ENB			BIT(0)
+#define HPRE_ECC_ENB			BIT(1)
 #define HPRE_DATA_RUSER_CFG		0x30103c
 #define HPRE_DATA_WUSER_CFG		0x301040
 #define HPRE_INT_MASK			0x301400
@@ -73,7 +75,8 @@
 #define HPRE_QM_AXI_CFG_MASK		0xffff
 #define HPRE_QM_VFG_AX_MASK		0xff
 #define HPRE_BD_USR_MASK		0x3
-#define HPRE_CLUSTER_CORE_MASK		0xf
+#define HPRE_CLUSTER_CORE_MASK_V2	0xf
+#define HPRE_CLUSTER_CORE_MASK_V3	0xff
 
 #define HPRE_AM_OOO_SHUTDOWN_ENB	0x301044
 #define HPRE_AM_OOO_SHUTDOWN_ENABLE	BIT(0)
@@ -86,6 +89,11 @@
 #define HPRE_QM_PM_FLR			BIT(11)
 #define HPRE_QM_SRIOV_FLR		BIT(12)
 
+#define HPRE_CLUSTERS_NUM(qm)		\
+	(((qm)->ver >= QM_HW_V3) ? HPRE_CLUSTERS_NUM_V3 : HPRE_CLUSTERS_NUM_V2)
+#define HPRE_CLUSTER_CORE_MASK(qm)	\
+	(((qm)->ver >= QM_HW_V3) ? HPRE_CLUSTER_CORE_MASK_V3 :\
+		HPRE_CLUSTER_CORE_MASK_V2)
 #define HPRE_VIA_MSI_DSM		1
 #define HPRE_SQE_MASK_OFFSET		8
 #define HPRE_SQE_MASK_LEN		24
@@ -238,8 +246,40 @@ static int hpre_cfg_by_dsm(struct hisi_qm *qm)
 	return 0;
 }
 
+static int hpre_set_cluster(struct hisi_qm *qm)
+{
+	u32 cluster_core_mask = HPRE_CLUSTER_CORE_MASK(qm);
+	u8 clusters_num = HPRE_CLUSTERS_NUM(qm);
+	struct device *dev = &qm->pdev->dev;
+	unsigned long offset;
+	u32 val = 0;
+	int ret, i;
+
+	for (i = 0; i < clusters_num; i++) {
+		offset = i * HPRE_CLSTR_ADDR_INTRVL;
+
+		/* clusters initiating */
+		writel(cluster_core_mask,
+		       HPRE_ADDR(qm, offset + HPRE_CORE_ENB));
+		writel(0x1, HPRE_ADDR(qm, offset + HPRE_CORE_INI_CFG));
+		ret = readl_relaxed_poll_timeout(HPRE_ADDR(qm, offset +
+					HPRE_CORE_INI_STATUS), val,
+					((val & cluster_core_mask) ==
+					cluster_core_mask),
+					HPRE_REG_RD_INTVRL_US,
+					HPRE_REG_RD_TMOUT_US);
+		if (ret) {
+			dev_err(dev,
+				"cluster %d int st status timeout!\n", i);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
 /*
- * For Hi1620, we shoul disable FLR triggered by hardware (BME/PM/SRIOV).
+ * For Kunpeng 920, we shoul disable FLR triggered by hardware (BME/PM/SRIOV).
  * Or it may stay in D3 state when we bind and unbind hpre quickly,
  * as it does FLR triggered by hardware.
  */
@@ -257,9 +297,8 @@ static void disable_flr_of_bme(struct hisi_qm *qm)
 static int hpre_set_user_domain_and_cache(struct hisi_qm *qm)
 {
 	struct device *dev = &qm->pdev->dev;
-	unsigned long offset;
-	int ret, i;
 	u32 val;
+	int ret;
 
 	writel(HPRE_QM_USR_CFG_MASK, HPRE_ADDR(qm, QM_ARUSER_M_CFG_ENABLE));
 	writel(HPRE_QM_USR_CFG_MASK, HPRE_ADDR(qm, QM_AWUSER_M_CFG_ENABLE));
@@ -270,7 +309,12 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm)
 	val |= BIT(HPRE_TIMEOUT_ABNML_BIT);
 	writel_relaxed(val, HPRE_ADDR(qm, HPRE_QM_ABNML_INT_MASK));
 
-	writel(0x1, HPRE_ADDR(qm, HPRE_TYPES_ENB));
+	if (qm->ver >= QM_HW_V3)
+		writel(HPRE_RSA_ENB | HPRE_ECC_ENB,
+			HPRE_ADDR(qm, HPRE_TYPES_ENB));
+	else
+		writel(HPRE_RSA_ENB, HPRE_ADDR(qm, HPRE_TYPES_ENB));
+
 	writel(HPRE_QM_VFG_AX_MASK, HPRE_ADDR(qm, HPRE_VFG_AXCACHE));
 	writel(0x0, HPRE_ADDR(qm, HPRE_BD_ENDIAN));
 	writel(0x0, HPRE_ADDR(qm, HPRE_INT_MASK));
@@ -291,37 +335,25 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm)
 		return -ETIMEDOUT;
 	}
 
-	for (i = 0; i < HPRE_CLUSTERS_NUM; i++) {
-		offset = i * HPRE_CLSTR_ADDR_INTRVL;
-
-		/* clusters initiating */
-		writel(HPRE_CLUSTER_CORE_MASK,
-		       HPRE_ADDR(qm, offset + HPRE_CORE_ENB));
-		writel(0x1, HPRE_ADDR(qm, offset + HPRE_CORE_INI_CFG));
-		ret = readl_relaxed_poll_timeout(HPRE_ADDR(qm, offset +
-					HPRE_CORE_INI_STATUS), val,
-					((val & HPRE_CLUSTER_CORE_MASK) ==
-					HPRE_CLUSTER_CORE_MASK),
-					HPRE_REG_RD_INTVRL_US,
-					HPRE_REG_RD_TMOUT_US);
-		if (ret) {
-			dev_err(dev,
-				"cluster %d int st status timeout!\n", i);
-			return -ETIMEDOUT;
-		}
-	}
-
-	ret = hpre_cfg_by_dsm(qm);
+	ret = hpre_set_cluster(qm);
 	if (ret)
-		dev_err(dev, "acpi_evaluate_dsm err.\n");
+		return -ETIMEDOUT;
 
-	disable_flr_of_bme(qm);
+	/* This setting is only needed by Kunpeng 920. */
+	if (qm->ver == QM_HW_V2) {
+		ret = hpre_cfg_by_dsm(qm);
+		if (ret)
+			dev_err(dev, "acpi_evaluate_dsm err.\n");
+
+		disable_flr_of_bme(qm);
+	}
 
 	return ret;
 }
 
 static void hpre_cnt_regs_clear(struct hisi_qm *qm)
 {
+	u8 clusters_num = HPRE_CLUSTERS_NUM(qm);
 	unsigned long offset;
 	int i;
 
@@ -330,7 +362,7 @@ static void hpre_cnt_regs_clear(struct hisi_qm *qm)
 	writel(0x0, qm->io_base + QM_DFX_DB_CNT_VF);
 
 	/* clear clusterX/cluster_ctrl */
-	for (i = 0; i < HPRE_CLUSTERS_NUM; i++) {
+	for (i = 0; i < clusters_num; i++) {
 		offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL;
 		writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY);
 	}
@@ -629,13 +661,14 @@ static int hpre_pf_comm_regs_debugfs_init(struct hisi_qm *qm)
 
 static int hpre_cluster_debugfs_init(struct hisi_qm *qm)
 {
+	u8 clusters_num = HPRE_CLUSTERS_NUM(qm);
 	struct device *dev = &qm->pdev->dev;
 	char buf[HPRE_DBGFS_VAL_MAX_LEN];
 	struct debugfs_regset32 *regset;
 	struct dentry *tmp_d;
 	int i, ret;
 
-	for (i = 0; i < HPRE_CLUSTERS_NUM; i++) {
+	for (i = 0; i < clusters_num; i++) {
 		ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i);
 		if (ret < 0)
 			return -EINVAL;
-- 
2.8.1


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

* [PATCH v4 2/5] crypto: hisilicon/hpre - add algorithm type
  2020-12-11  6:30 [PATCH v4 0/5] add ECDH and CURVE25519 algorithms support for Kunpeng 930 Meng Yu
  2020-12-11  6:30 ` [PATCH v4 1/5] crypto: hisilicon/hpre - add some updates to adapt to " Meng Yu
@ 2020-12-11  6:30 ` Meng Yu
  2020-12-11  6:30 ` [PATCH v4 3/5] crypto: expose elliptic curve parameters as Crypto APIs Meng Yu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 15+ messages in thread
From: Meng Yu @ 2020-12-11  6:30 UTC (permalink / raw)
  To: herbert, davem; +Cc: linux-crypto, xuzaibo, wangzhou1, yumeng18, linux-kernel

Algorithm type is brought in to get hardware HPRE queue
to support different algorithms.

Signed-off-by: Meng Yu <yumeng18@huawei.com>
Reviewed-by: Zaibo Xu <xuzaibo@huawei.com>
---
 drivers/crypto/hisilicon/hpre/hpre.h        | 10 +++++++++-
 drivers/crypto/hisilicon/hpre/hpre_crypto.c | 12 ++++++------
 drivers/crypto/hisilicon/hpre/hpre_main.c   | 11 +++++++++--
 3 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/hisilicon/hpre/hpre.h b/drivers/crypto/hisilicon/hpre/hpre.h
index cc50f23..02193e1 100644
--- a/drivers/crypto/hisilicon/hpre/hpre.h
+++ b/drivers/crypto/hisilicon/hpre/hpre.h
@@ -10,6 +10,14 @@
 #define HPRE_PF_DEF_Q_NUM		64
 #define HPRE_PF_DEF_Q_BASE		0
 
+/*
+ * type used in qm sqc DW6.
+ * 0 - Algorithm which has been supported in V2, like RSA, DH and so on;
+ * 1 - ECC algorithm in V3.
+ */
+#define HPRE_V2_ALG_TYPE	0
+#define HPRE_V3_ECC_ALG_TYPE	1
+
 enum {
 	HPRE_CLUSTER0,
 	HPRE_CLUSTER1,
@@ -92,7 +100,7 @@ struct hpre_sqe {
 	__le32 rsvd1[_HPRE_SQE_ALIGN_EXT];
 };
 
-struct hisi_qp *hpre_create_qp(void);
+struct hisi_qp *hpre_create_qp(u8 type);
 int hpre_algs_register(struct hisi_qm *qm);
 void hpre_algs_unregister(struct hisi_qm *qm);
 
diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
index d89b2f5..712bea9 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
@@ -152,12 +152,12 @@ static void hpre_rm_req_from_ctx(struct hpre_asym_request *hpre_req)
 	}
 }
 
-static struct hisi_qp *hpre_get_qp_and_start(void)
+static struct hisi_qp *hpre_get_qp_and_start(u8 type)
 {
 	struct hisi_qp *qp;
 	int ret;
 
-	qp = hpre_create_qp();
+	qp = hpre_create_qp(type);
 	if (!qp) {
 		pr_err("Can not create hpre qp!\n");
 		return ERR_PTR(-ENODEV);
@@ -422,11 +422,11 @@ static void hpre_alg_cb(struct hisi_qp *qp, void *resp)
 	req->cb(ctx, resp);
 }
 
-static int hpre_ctx_init(struct hpre_ctx *ctx)
+static int hpre_ctx_init(struct hpre_ctx *ctx, u8 type)
 {
 	struct hisi_qp *qp;
 
-	qp = hpre_get_qp_and_start();
+	qp = hpre_get_qp_and_start(type);
 	if (IS_ERR(qp))
 		return PTR_ERR(qp);
 
@@ -674,7 +674,7 @@ static int hpre_dh_init_tfm(struct crypto_kpp *tfm)
 {
 	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
 
-	return hpre_ctx_init(ctx);
+	return hpre_ctx_init(ctx, HPRE_V2_ALG_TYPE);
 }
 
 static void hpre_dh_exit_tfm(struct crypto_kpp *tfm)
@@ -1100,7 +1100,7 @@ static int hpre_rsa_init_tfm(struct crypto_akcipher *tfm)
 		return PTR_ERR(ctx->rsa.soft_tfm);
 	}
 
-	ret = hpre_ctx_init(ctx);
+	ret = hpre_ctx_init(ctx, HPRE_V2_ALG_TYPE);
 	if (ret)
 		crypto_free_akcipher(ctx->rsa.soft_tfm);
 
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index fc7173a..1ae8fa1 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -209,13 +209,20 @@ static u32 vfs_num;
 module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
 MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)");
 
-struct hisi_qp *hpre_create_qp(void)
+struct hisi_qp *hpre_create_qp(u8 type)
 {
 	int node = cpu_to_node(smp_processor_id());
 	struct hisi_qp *qp = NULL;
 	int ret;
 
-	ret = hisi_qm_alloc_qps_node(&hpre_devices, 1, 0, node, &qp);
+	if (type != HPRE_V2_ALG_TYPE && type != HPRE_V3_ECC_ALG_TYPE)
+		return NULL;
+
+	/*
+	 * type: 0 - RSA/DH. algorithm supported in V2,
+	 *       1 - ECC algorithm in V3.
+	 */
+	ret = hisi_qm_alloc_qps_node(&hpre_devices, 1, type, node, &qp);
 	if (!ret)
 		return qp;
 
-- 
2.8.1


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

* [PATCH v4 3/5] crypto: expose elliptic curve parameters as Crypto APIs
  2020-12-11  6:30 [PATCH v4 0/5] add ECDH and CURVE25519 algorithms support for Kunpeng 930 Meng Yu
  2020-12-11  6:30 ` [PATCH v4 1/5] crypto: hisilicon/hpre - add some updates to adapt to " Meng Yu
  2020-12-11  6:30 ` [PATCH v4 2/5] crypto: hisilicon/hpre - add algorithm type Meng Yu
@ 2020-12-11  6:30 ` Meng Yu
  2020-12-11 13:13   ` Vitaly Chikunov
  2020-12-11  6:30 ` [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm Meng Yu
  2020-12-11  6:30 ` [PATCH v4 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm Meng Yu
  4 siblings, 1 reply; 15+ messages in thread
From: Meng Yu @ 2020-12-11  6:30 UTC (permalink / raw)
  To: herbert, davem; +Cc: linux-crypto, xuzaibo, wangzhou1, yumeng18, linux-kernel

Move elliptic curves definition to 'include/crypto/ecc_curve_defs.h',
so all can use it,

Signed-off-by: Meng Yu <yumeng18@huawei.com>
Reviewed-by: Zaibo Xu <xuzaibo@huawei.com>
---
 crypto/ecc.c                    |  1 -
 crypto/ecc.h                    | 37 +----------------
 crypto/ecc_curve_defs.h         | 57 -------------------------
 crypto/ecrdsa_defs.h            |  2 +-
 include/crypto/ecc_curve_defs.h | 92 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 95 insertions(+), 94 deletions(-)
 delete mode 100644 crypto/ecc_curve_defs.h
 create mode 100644 include/crypto/ecc_curve_defs.h

diff --git a/crypto/ecc.c b/crypto/ecc.c
index c80aa25..f23efdd 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -35,7 +35,6 @@
 #include <linux/ratelimit.h>
 
 #include "ecc.h"
-#include "ecc_curve_defs.h"
 
 typedef struct {
 	u64 m_low;
diff --git a/crypto/ecc.h b/crypto/ecc.h
index d4e546b..e5afaf3 100644
--- a/crypto/ecc.h
+++ b/crypto/ecc.h
@@ -26,6 +26,8 @@
 #ifndef _CRYPTO_ECC_H
 #define _CRYPTO_ECC_H
 
+#include <crypto/ecc_curve_defs.h>
+
 /* One digit is u64 qword. */
 #define ECC_CURVE_NIST_P192_DIGITS  3
 #define ECC_CURVE_NIST_P256_DIGITS  4
@@ -33,44 +35,9 @@
 
 #define ECC_DIGITS_TO_BYTES_SHIFT 3
 
-/**
- * struct ecc_point - elliptic curve point in affine coordinates
- *
- * @x:		X coordinate in vli form.
- * @y:		Y coordinate in vli form.
- * @ndigits:	Length of vlis in u64 qwords.
- */
-struct ecc_point {
-	u64 *x;
-	u64 *y;
-	u8 ndigits;
-};
-
 #define ECC_POINT_INIT(x, y, ndigits)	(struct ecc_point) { x, y, ndigits }
 
 /**
- * struct ecc_curve - definition of elliptic curve
- *
- * @name:	Short name of the curve.
- * @g:		Generator point of the curve.
- * @p:		Prime number, if Barrett's reduction is used for this curve
- *		pre-calculated value 'mu' is appended to the @p after ndigits.
- *		Use of Barrett's reduction is heuristically determined in
- *		vli_mmod_fast().
- * @n:		Order of the curve group.
- * @a:		Curve parameter a.
- * @b:		Curve parameter b.
- */
-struct ecc_curve {
-	char *name;
-	struct ecc_point g;
-	u64 *p;
-	u64 *n;
-	u64 *a;
-	u64 *b;
-};
-
-/**
  * ecc_is_key_valid() - Validate a given ECDH private key
  *
  * @curve_id:		id representing the curve to use
diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
deleted file mode 100644
index 69be6c7..0000000
--- a/crypto/ecc_curve_defs.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _CRYTO_ECC_CURVE_DEFS_H
-#define _CRYTO_ECC_CURVE_DEFS_H
-
-/* NIST P-192: a = p - 3 */
-static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
-				0x188DA80EB03090F6ull };
-static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
-				0x07192B95FFC8DA78ull };
-static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
-				0xFFFFFFFFFFFFFFFFull };
-static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
-				0xFFFFFFFFFFFFFFFFull };
-static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
-				0xFFFFFFFFFFFFFFFFull };
-static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
-				0x64210519E59C80E7ull };
-static struct ecc_curve nist_p192 = {
-	.name = "nist_192",
-	.g = {
-		.x = nist_p192_g_x,
-		.y = nist_p192_g_y,
-		.ndigits = 3,
-	},
-	.p = nist_p192_p,
-	.n = nist_p192_n,
-	.a = nist_p192_a,
-	.b = nist_p192_b
-};
-
-/* NIST P-256: a = p - 3 */
-static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
-				0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
-static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
-				0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull };
-static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
-				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
-static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
-				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
-static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
-				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
-static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
-				0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
-static struct ecc_curve nist_p256 = {
-	.name = "nist_256",
-	.g = {
-		.x = nist_p256_g_x,
-		.y = nist_p256_g_y,
-		.ndigits = 4,
-	},
-	.p = nist_p256_p,
-	.n = nist_p256_n,
-	.a = nist_p256_a,
-	.b = nist_p256_b
-};
-
-#endif
diff --git a/crypto/ecrdsa_defs.h b/crypto/ecrdsa_defs.h
index 170baf0..2074099 100644
--- a/crypto/ecrdsa_defs.h
+++ b/crypto/ecrdsa_defs.h
@@ -13,7 +13,7 @@
 #ifndef _CRYTO_ECRDSA_DEFS_H
 #define _CRYTO_ECRDSA_DEFS_H
 
-#include "ecc.h"
+#include <crypto/ecc_curve_defs.h>
 
 #define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8)
 #define ECRDSA_MAX_DIGITS (512 / 64)
diff --git a/include/crypto/ecc_curve_defs.h b/include/crypto/ecc_curve_defs.h
new file mode 100644
index 0000000..1080766
--- /dev/null
+++ b/include/crypto/ecc_curve_defs.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _CRYTO_ECC_CURVE_DEFS_H
+#define _CRYTO_ECC_CURVE_DEFS_H
+
+/**
+ * struct ecc_point - elliptic curve point in affine coordinates
+ *
+ * @x:		X coordinate in vli form.
+ * @y:		Y coordinate in vli form.
+ * @ndigits:	Length of vlis in u64 qwords.
+ */
+struct ecc_point {
+	u64 *x;
+	u64 *y;
+	u8 ndigits;
+};
+
+/**
+ * struct ecc_curve - definition of elliptic curve
+ *
+ * @name:	Short name of the curve.
+ * @g:		Generator point of the curve.
+ * @p:		Prime number, if Barrett's reduction is used for this curve
+ *		pre-calculated value 'mu' is appended to the @p after ndigits.
+ *		Use of Barrett's reduction is heuristically determined in
+ *		vli_mmod_fast().
+ * @n:		Order of the curve group.
+ * @a:		Curve parameter a.
+ * @b:		Curve parameter b.
+ */
+struct ecc_curve {
+	char *name;
+	struct ecc_point g;
+	u64 *p;
+	u64 *n;
+	u64 *a;
+	u64 *b;
+};
+
+/* NIST P-192: a = p - 3 */
+static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
+				0x188DA80EB03090F6ull };
+static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
+				0x07192B95FFC8DA78ull };
+static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
+				0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
+				0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
+				0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
+				0x64210519E59C80E7ull };
+static struct ecc_curve nist_p192 = {
+	.name = "nist_192",
+	.g = {
+		.x = nist_p192_g_x,
+		.y = nist_p192_g_y,
+		.ndigits = 3,
+	},
+	.p = nist_p192_p,
+	.n = nist_p192_n,
+	.a = nist_p192_a,
+	.b = nist_p192_b
+};
+
+/* NIST P-256: a = p - 3 */
+static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
+				0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
+static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
+				0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull };
+static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
+				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
+static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
+static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
+				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
+static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
+				0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
+static struct ecc_curve nist_p256 = {
+	.name = "nist_256",
+	.g = {
+		.x = nist_p256_g_x,
+		.y = nist_p256_g_y,
+		.ndigits = 4,
+	},
+	.p = nist_p256_p,
+	.n = nist_p256_n,
+	.a = nist_p256_a,
+	.b = nist_p256_b
+};
+
+#endif
-- 
2.8.1


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

* [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm
  2020-12-11  6:30 [PATCH v4 0/5] add ECDH and CURVE25519 algorithms support for Kunpeng 930 Meng Yu
                   ` (2 preceding siblings ...)
  2020-12-11  6:30 ` [PATCH v4 3/5] crypto: expose elliptic curve parameters as Crypto APIs Meng Yu
@ 2020-12-11  6:30 ` Meng Yu
  2020-12-11 14:08   ` Stephan Mueller
  2020-12-11  6:30 ` [PATCH v4 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm Meng Yu
  4 siblings, 1 reply; 15+ messages in thread
From: Meng Yu @ 2020-12-11  6:30 UTC (permalink / raw)
  To: herbert, davem; +Cc: linux-crypto, xuzaibo, wangzhou1, yumeng18, linux-kernel

1. Add some new 'ECDH' curve parameter definitions to
   'include/crypto/ecc_curve_defs.h', and reorder ECC 'Curves IDs'
   in 'include/crypto/ecdh.h';
2. Enable 'ECDH' algorithm in Kunpeng 930.

Signed-off-by: Meng Yu <yumeng18@huawei.com>
Reviewed-by: Zaibo Xu <xuzaibo@huawei.com>
---
 crypto/ecc.c                                |   4 +-
 crypto/testmgr.h                            |  12 +-
 drivers/crypto/hisilicon/hpre/hpre.h        |   2 +-
 drivers/crypto/hisilicon/hpre/hpre_crypto.c | 510 +++++++++++++++++++++++++++-
 drivers/crypto/hisilicon/hpre/hpre_main.c   |   1 +
 include/crypto/ecc_curve_defs.h             | 198 +++++++++--
 include/crypto/ecdh.h                       |   9 +-
 7 files changed, 698 insertions(+), 38 deletions(-)

diff --git a/crypto/ecc.c b/crypto/ecc.c
index f23efdd..6adcae2 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -46,9 +46,9 @@ static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
 	switch (curve_id) {
 	/* In FIPS mode only allow P256 and higher */
 	case ECC_CURVE_NIST_P192:
-		return fips_enabled ? NULL : &nist_p192;
+		return fips_enabled ? NULL : &ecc_curve_list[ECC_CURVE_NIST_P192 - 1];
 	case ECC_CURVE_NIST_P256:
-		return &nist_p256;
+		return &ecc_curve_list[ECC_CURVE_NIST_P256 - 1];
 	default:
 		return NULL;
 	}
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 8c83811..371692e 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -2268,12 +2268,12 @@ static const struct kpp_testvec ecdh_tv_template[] = {
 #ifdef __LITTLE_ENDIAN
 	"\x02\x00" /* type */
 	"\x20\x00" /* len */
-	"\x01\x00" /* curve_id */
+	"\x02\x00" /* curve_id */
 	"\x18\x00" /* key_size */
 #else
 	"\x00\x02" /* type */
 	"\x00\x20" /* len */
-	"\x00\x01" /* curve_id */
+	"\x00\x02" /* curve_id */
 	"\x00\x18" /* key_size */
 #endif
 	"\xb5\x05\xb1\x71\x1e\xbf\x8c\xda"
@@ -2307,12 +2307,12 @@ static const struct kpp_testvec ecdh_tv_template[] = {
 #ifdef __LITTLE_ENDIAN
 	"\x02\x00" /* type */
 	"\x28\x00" /* len */
-	"\x02\x00" /* curve_id */
+	"\x04\x00" /* curve_id */
 	"\x20\x00" /* key_size */
 #else
 	"\x00\x02" /* type */
 	"\x00\x28" /* len */
-	"\x00\x02" /* curve_id */
+	"\x00\x04" /* curve_id */
 	"\x00\x20" /* key_size */
 #endif
 	"\x24\xd1\x21\xeb\xe5\xcf\x2d\x83"
@@ -2351,12 +2351,12 @@ static const struct kpp_testvec ecdh_tv_template[] = {
 #ifdef __LITTLE_ENDIAN
 	"\x02\x00" /* type */
 	"\x08\x00" /* len */
-	"\x02\x00" /* curve_id */
+	"\x04\x00" /* curve_id */
 	"\x00\x00", /* key_size */
 #else
 	"\x00\x02" /* type */
 	"\x00\x08" /* len */
-	"\x00\x02" /* curve_id */
+	"\x00\x04" /* curve_id */
 	"\x00\x00", /* key_size */
 #endif
 	.b_secret =
diff --git a/drivers/crypto/hisilicon/hpre/hpre.h b/drivers/crypto/hisilicon/hpre/hpre.h
index 02193e1..50e6b2e 100644
--- a/drivers/crypto/hisilicon/hpre/hpre.h
+++ b/drivers/crypto/hisilicon/hpre/hpre.h
@@ -83,6 +83,7 @@ enum hpre_alg_type {
 	HPRE_ALG_KG_CRT = 0x3,
 	HPRE_ALG_DH_G2 = 0x4,
 	HPRE_ALG_DH = 0x5,
+	HPRE_ALG_ECC_MUL = 0xD,
 };
 
 struct hpre_sqe {
@@ -104,5 +105,4 @@ struct hisi_qp *hpre_create_qp(u8 type);
 int hpre_algs_register(struct hisi_qm *qm);
 void hpre_algs_unregister(struct hisi_qm *qm);
 
-
 #endif
diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
index 712bea9..58f847b 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
@@ -2,6 +2,8 @@
 /* Copyright (c) 2019 HiSilicon Limited. */
 #include <crypto/akcipher.h>
 #include <crypto/dh.h>
+#include <crypto/ecc_curve_defs.h>
+#include <crypto/ecdh.h>
 #include <crypto/internal/akcipher.h>
 #include <crypto/internal/kpp.h>
 #include <crypto/internal/rsa.h>
@@ -36,6 +38,22 @@ struct hpre_ctx;
 #define HPRE_DFX_SEC_TO_US	1000000
 #define HPRE_DFX_US_TO_NS	1000
 
+/* size in bytes of the n prime */
+#define HPRE_ECC_NIST_P128_N_SIZE	16
+#define HPRE_ECC_NIST_P192_N_SIZE	24
+#define HPRE_ECC_NIST_P224_N_SIZE	28
+#define HPRE_ECC_NIST_P256_N_SIZE	32
+#define HPRE_ECC_NIST_P320_N_SIZE	40
+#define HPRE_ECC_NIST_P384_N_SIZE	48
+#define HPRE_ECC_NIST_P521_N_SIZE	66
+
+/* size in bytes */
+#define HPRE_ECC_HW256_KSZ_B	32
+#define HPRE_ECC_HW384_KSZ_B	48
+#define HPRE_ECC_HW576_KSZ_B	72
+
+#define HPRE_ECDH_MAX_SZ	HPRE_ECC_HW576_KSZ_B
+
 typedef void (*hpre_cb)(struct hpre_ctx *ctx, void *sqe);
 
 struct hpre_rsa_ctx {
@@ -61,14 +79,25 @@ struct hpre_dh_ctx {
 	 * else if base if the counterpart public key we
 	 * compute the shared secret
 	 *	ZZ = yb^xa mod p; [RFC2631 sec 2.1.1]
+	 * low address: d--->n, please refer to Hisilicon HPRE UM
 	 */
-	char *xa_p; /* low address: d--->n, please refer to Hisilicon HPRE UM */
+	char *xa_p;
 	dma_addr_t dma_xa_p;
 
 	char *g; /* m */
 	dma_addr_t dma_g;
 };
 
+struct hpre_ecdh_ctx {
+	/* low address: p->a->k->b */
+	unsigned char *p;
+	dma_addr_t dma_p;
+
+	/* low address: x->y */
+	unsigned char *g;
+	dma_addr_t dma_g;
+};
+
 struct hpre_ctx {
 	struct hisi_qp *qp;
 	struct hpre_asym_request **req_list;
@@ -80,7 +109,10 @@ struct hpre_ctx {
 	union {
 		struct hpre_rsa_ctx rsa;
 		struct hpre_dh_ctx dh;
+		struct hpre_ecdh_ctx ecdh;
 	};
+	/* for ecc algorithms */
+	unsigned int curve_id;
 };
 
 struct hpre_asym_request {
@@ -91,6 +123,7 @@ struct hpre_asym_request {
 	union {
 		struct akcipher_request *rsa;
 		struct kpp_request *dh;
+		struct kpp_request *ecdh;
 	} areq;
 	int err;
 	int req_id;
@@ -1115,6 +1148,443 @@ static void hpre_rsa_exit_tfm(struct crypto_akcipher *tfm)
 	crypto_free_akcipher(ctx->rsa.soft_tfm);
 }
 
+static void hpre_key_to_big_end(u8 *data, int len)
+{
+	int i, j;
+	u8 tmp;
+
+	for (i = 0; i < len / 2; i++) {
+		j = len - i - 1;
+		tmp = data[j];
+		data[j] = data[i];
+		data[i] = tmp;
+	}
+}
+
+static void hpre_ecc_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all,
+			       bool is_ecdh)
+{
+	struct device *dev = HPRE_DEV(ctx);
+	unsigned int sz = ctx->key_sz;
+	unsigned int shift = sz << 1;
+
+	if (is_clear_all)
+		hisi_qm_stop_qp(ctx->qp);
+
+	if (is_ecdh && ctx->ecdh.p) {
+		/* ecdh: p->a->k->b */
+		memzero_explicit(ctx->ecdh.p + shift, sz);
+		dma_free_coherent(dev, sz << 3, ctx->ecdh.p, ctx->ecdh.dma_p);
+		ctx->ecdh.p = NULL;
+	}
+
+	ctx->curve_id = 0;
+	hpre_ctx_clear(ctx, is_clear_all);
+}
+
+/*
+ * only the bits of 128/192/224/256/320/384/521 are supported by HPRE,
+ * and convert the bits like:
+ * bits<=256, bits=256; 256<bits<=384, bits=384; 384<bits<=576, bits=576;
+ * If the parameter bit width is insufficient, then we fill in the
+ * high-order zeros by soft, so TASK_LENGTH1 is 0x3/0x5/0x8;
+ */
+static unsigned int hpre_ecdh_supported_curve(unsigned int curve_id)
+{
+	switch (curve_id) {
+	case ECC_CURVE_NIST_P192:
+	case ECC_CURVE_NIST_P256:
+	case ECC_CURVE_NIST_P128:
+	case ECC_CURVE_NIST_P224:
+		return HPRE_ECC_HW256_KSZ_B;
+	case ECC_CURVE_NIST_P320:
+	case ECC_CURVE_NIST_P384:
+		return HPRE_ECC_HW384_KSZ_B;
+	case ECC_CURVE_NIST_P521:
+		return HPRE_ECC_HW576_KSZ_B;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+void fill_curve_param(void *addr, u64 *param, unsigned int cur_sz, u8 ndigits)
+{
+	unsigned int sz = cur_sz - (ndigits - 1) * sizeof(u64);
+	u8 i = 0;
+
+	while (i < ndigits - 1) {
+		memcpy(addr + sizeof(u64) * i, &param[i], sizeof(u64));
+		i++;
+	}
+
+	memcpy(addr + sizeof(u64) * i, &param[ndigits - 1], sz);
+	hpre_key_to_big_end((u8 *)addr, cur_sz);
+}
+
+static const struct ecc_curve *ecdh_get_curve_param(__u32 curve_id)
+{
+	if (curve_id >= ECC_CURVE_NIST_P128 &&
+	    curve_id <= ECC_CURVE_NIST_P521)
+		return &ecc_curve_list[curve_id - 1];
+
+	return NULL;
+}
+
+static int hpre_ecdh_fill_curve(struct hpre_ctx *ctx, struct ecdh *params,
+				unsigned int cur_sz)
+{
+	unsigned int shifta = ctx->key_sz << 1;
+	unsigned int shiftb = ctx->key_sz << 2;
+	void *p = ctx->ecdh.p + ctx->key_sz - cur_sz;
+	void *a = ctx->ecdh.p + shifta - cur_sz;
+	void *b = ctx->ecdh.p + shiftb - cur_sz;
+	void *x = ctx->ecdh.g + ctx->key_sz - cur_sz;
+	void *y = ctx->ecdh.g + shifta - cur_sz;
+	const struct ecc_curve *curve;
+	char *n;
+
+	n = kzalloc(ctx->key_sz, GFP_KERNEL);
+	if (!n)
+		return -ENOMEM;
+
+	curve = ecdh_get_curve_param(params->curve_id);
+	if (!curve)
+		goto free;
+
+	fill_curve_param(p, curve->p, cur_sz, curve->g.ndigits);
+	fill_curve_param(a, curve->a, cur_sz, curve->g.ndigits);
+	fill_curve_param(b, curve->b, cur_sz, curve->g.ndigits);
+	fill_curve_param(x, curve->g.x, cur_sz, curve->g.ndigits);
+	fill_curve_param(y, curve->g.y, cur_sz, curve->g.ndigits);
+	fill_curve_param(n, curve->n, cur_sz, curve->g.ndigits);
+
+	if (params->key_size == cur_sz && strcmp(params->key, n) >= 0)
+		goto free;
+
+	kfree(n);
+	return 0;
+
+free:
+	kfree(n);
+	return -EINVAL;
+}
+
+static unsigned int hpre_ecdh_get_curvesz(unsigned short id)
+{
+	switch (id) {
+	case ECC_CURVE_NIST_P192:
+		return HPRE_ECC_NIST_P192_N_SIZE;
+	case ECC_CURVE_NIST_P256:
+		return HPRE_ECC_NIST_P256_N_SIZE;
+	case ECC_CURVE_NIST_P128:
+		return HPRE_ECC_NIST_P128_N_SIZE;
+	case ECC_CURVE_NIST_P224:
+		return HPRE_ECC_NIST_P224_N_SIZE;
+	case ECC_CURVE_NIST_P320:
+		return HPRE_ECC_NIST_P320_N_SIZE;
+	case ECC_CURVE_NIST_P384:
+		return HPRE_ECC_NIST_P384_N_SIZE;
+	case ECC_CURVE_NIST_P521:
+		return HPRE_ECC_NIST_P521_N_SIZE;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int hpre_ecdh_set_param(struct hpre_ctx *ctx, struct ecdh *params)
+{
+	struct device *dev = HPRE_DEV(ctx);
+	unsigned int sz, shift, curve_sz;
+	int ret;
+
+	ctx->key_sz = hpre_ecdh_supported_curve(params->curve_id);
+	if (!ctx->key_sz)
+		return -EINVAL;
+
+	curve_sz = hpre_ecdh_get_curvesz(params->curve_id);
+	if (!curve_sz || params->key_size > curve_sz)
+		return -EINVAL;
+
+	sz = ctx->key_sz;
+	ctx->curve_id = params->curve_id;
+
+	if (!ctx->ecdh.p) {
+		ctx->ecdh.p = dma_alloc_coherent(dev, sz << 3, &ctx->ecdh.dma_p,
+						 GFP_KERNEL);
+		if (!ctx->ecdh.p)
+			return -ENOMEM;
+	}
+
+	shift = sz << 2;
+	ctx->ecdh.g = ctx->ecdh.p + shift;
+	ctx->ecdh.dma_g = ctx->ecdh.dma_p + shift;
+
+	ret = hpre_ecdh_fill_curve(ctx, params, curve_sz);
+	if (ret) {
+		dev_err(dev, "failed to fill curve_param, ret = %d!\n", ret);
+		dma_free_coherent(dev, sz << 3, ctx->ecdh.p, ctx->ecdh.dma_p);
+		ctx->ecdh.p = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+static bool hpre_key_is_valid(char *key, unsigned short key_sz)
+{
+	int i;
+
+	for (i = 0; i < key_sz; i++)
+		if (key[i])
+			return true;
+
+	return false;
+}
+
+static int hpre_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
+				unsigned int len)
+{
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+	struct device *dev = HPRE_DEV(ctx);
+	unsigned int sz, sz_shift;
+	struct ecdh params;
+	int ret;
+
+	if (crypto_ecdh_decode_key(buf, len, &params) < 0) {
+		dev_err(dev, "failed to decode ecdh key!\n");
+		return -EINVAL;
+	}
+
+	if (!hpre_key_is_valid(params.key, params.key_size)) {
+		dev_err(dev, "Invalid hpre key!\n");
+		return -EINVAL;
+	}
+
+	hpre_ecc_clear_ctx(ctx, false, true);
+
+	ret = hpre_ecdh_set_param(ctx, &params);
+	if (ret < 0) {
+		dev_err(dev, "failed to set hpre param, ret = %d!\n", ret);
+		return ret;
+	}
+
+	sz = ctx->key_sz;
+	sz_shift = (sz << 1) + sz - params.key_size;
+	memcpy(ctx->ecdh.p + sz_shift, params.key, params.key_size);
+
+	return 0;
+}
+
+static void hpre_ecdh_hw_data_clr_all(struct hpre_ctx *ctx,
+				      struct hpre_asym_request *req,
+				      struct scatterlist *dst,
+				      struct scatterlist *src)
+{
+	struct device *dev = HPRE_DEV(ctx);
+	struct hpre_sqe *sqe = &req->req;
+	dma_addr_t dma;
+
+	dma = le64_to_cpu(sqe->in);
+	if (unlikely(!dma))
+		return;
+
+	if (src && req->src)
+		dma_free_coherent(dev, ctx->key_sz << 2, req->src, dma);
+
+	dma = le64_to_cpu(sqe->out);
+	if (unlikely(!dma))
+		return;
+
+	if (req->dst)
+		dma_free_coherent(dev, ctx->key_sz << 1, req->dst, dma);
+	if (dst)
+		dma_unmap_single(dev, dma, ctx->key_sz << 1, DMA_FROM_DEVICE);
+}
+
+static void hpre_ecdh_cb(struct hpre_ctx *ctx, void *resp)
+{
+	unsigned int curve_sz = hpre_ecdh_get_curvesz(ctx->curve_id);
+	struct hpre_dfx *dfx = ctx->hpre->debug.dfx;
+	struct hpre_asym_request *req = NULL;
+	struct kpp_request *areq;
+	u64 overtime_thrhld;
+	char *p;
+	int ret;
+
+	ret = hpre_alg_res_post_hf(ctx, resp, (void **)&req);
+	areq = req->areq.ecdh;
+	areq->dst_len = ctx->key_sz << 1;
+
+	overtime_thrhld = atomic64_read(&dfx[HPRE_OVERTIME_THRHLD].value);
+	if (overtime_thrhld && hpre_is_bd_timeout(req, overtime_thrhld))
+		atomic64_inc(&dfx[HPRE_OVER_THRHLD_CNT].value);
+
+	p = sg_virt(areq->dst);
+	memmove(p, p + ctx->key_sz - curve_sz, curve_sz);
+	memmove(p + curve_sz, p + areq->dst_len - curve_sz, curve_sz);
+
+	hpre_ecdh_hw_data_clr_all(ctx, req, areq->dst, areq->src);
+	kpp_request_complete(areq, ret);
+
+	atomic64_inc(&dfx[HPRE_RECV_CNT].value);
+}
+
+static int hpre_ecdh_msg_request_set(struct hpre_ctx *ctx,
+				     struct kpp_request *req)
+{
+	struct hpre_asym_request *h_req;
+	struct hpre_sqe *msg;
+	int req_id;
+	void *tmp;
+
+	if (req->dst_len < ctx->key_sz << 1) {
+		req->dst_len = ctx->key_sz << 1;
+		return -EINVAL;
+	}
+
+	tmp = kpp_request_ctx(req);
+	h_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ);
+	h_req->cb = hpre_ecdh_cb;
+	h_req->areq.ecdh = req;
+	msg = &h_req->req;
+	memset(msg, 0, sizeof(*msg));
+	msg->key = cpu_to_le64(ctx->ecdh.dma_p);
+
+	msg->dw0 |= cpu_to_le32(0x1U << HPRE_SQE_DONE_SHIFT);
+	msg->task_len1 = (ctx->key_sz >> HPRE_BITS_2_BYTES_SHIFT) - 1;
+	h_req->ctx = ctx;
+
+	req_id = hpre_add_req_to_ctx(h_req);
+	if (req_id < 0)
+		return -EBUSY;
+
+	msg->tag = cpu_to_le16((u16)req_id);
+	return 0;
+}
+
+static int hpre_ecdh_src_data_init(struct hpre_asym_request *hpre_req,
+				   struct scatterlist *data, unsigned int len)
+{
+	struct hpre_sqe *msg = &hpre_req->req;
+	struct hpre_ctx *ctx = hpre_req->ctx;
+	struct device *dev = HPRE_DEV(ctx);
+	unsigned int tmpshift;
+	dma_addr_t dma = 0;
+	void *ptr;
+	int shift;
+
+	/* Src_data include gx and gy. */
+	shift = ctx->key_sz - (len >> 1);
+	if (unlikely(shift < 0))
+		return -EINVAL;
+
+	ptr = dma_alloc_coherent(dev, ctx->key_sz << 2, &dma, GFP_KERNEL);
+	if (unlikely(!ptr))
+		return -ENOMEM;
+
+	tmpshift = ctx->key_sz << 1;
+	scatterwalk_map_and_copy(ptr + tmpshift, data, 0, len, 0);
+	memcpy(ptr + shift, ptr + tmpshift, len >> 1);
+	memcpy(ptr + ctx->key_sz + shift, ptr + tmpshift + (len >> 1), len >> 1);
+
+	hpre_req->src = ptr;
+	msg->in = cpu_to_le64(dma);
+	return 0;
+}
+
+static int hpre_ecdh_dst_data_init(struct hpre_asym_request *hpre_req,
+				   struct scatterlist *data, unsigned int len)
+{
+	struct hpre_sqe *msg = &hpre_req->req;
+	struct hpre_ctx *ctx = hpre_req->ctx;
+	struct device *dev = HPRE_DEV(ctx);
+	dma_addr_t dma = 0;
+
+	if (unlikely(!data || !sg_is_last(data) || len != ctx->key_sz << 1)) {
+		dev_err(dev, "data or data length is illegal!\n");
+		return -EINVAL;
+	}
+
+	hpre_req->dst = NULL;
+	dma = dma_map_single(dev, sg_virt(data), len, DMA_FROM_DEVICE);
+	if (unlikely(dma_mapping_error(dev, dma))) {
+		dev_err(dev, "dma map data err!\n");
+		return -ENOMEM;
+	}
+
+	msg->out = cpu_to_le64(dma);
+	return 0;
+}
+
+static int hpre_ecdh_compute_value(struct kpp_request *req)
+{
+	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+	struct device *dev = HPRE_DEV(ctx);
+	void *tmp = kpp_request_ctx(req);
+	struct hpre_asym_request *hpre_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ);
+	struct hpre_sqe *msg = &hpre_req->req;
+	int ret;
+
+	ret = hpre_ecdh_msg_request_set(ctx, req);
+	if (unlikely(ret)) {
+		dev_err(dev, "failed to set ecdh request, ret = %d!\n", ret);
+		return ret;
+	}
+
+	if (req->src) {
+		ret = hpre_ecdh_src_data_init(hpre_req, req->src, req->src_len);
+		if (unlikely(ret)) {
+			dev_err(dev, "failed to init src data, ret = %d!\n", ret);
+			goto clear_all;
+		}
+	} else {
+		msg->in = cpu_to_le64(ctx->ecdh.dma_g);
+	}
+
+	ret = hpre_ecdh_dst_data_init(hpre_req, req->dst, req->dst_len);
+	if (unlikely(ret)) {
+		dev_err(dev, "failed to init dst data, ret = %d!\n", ret);
+		goto clear_all;
+	}
+
+	msg->dw0 = cpu_to_le32(le32_to_cpu(msg->dw0) | HPRE_ALG_ECC_MUL);
+	ret = hpre_send(ctx, msg);
+	if (likely(!ret))
+		return -EINPROGRESS;
+
+clear_all:
+	hpre_rm_req_from_ctx(hpre_req);
+	hpre_ecdh_hw_data_clr_all(ctx, hpre_req, req->dst, req->src);
+	return ret;
+}
+
+static unsigned int hpre_ecdh_max_size(struct crypto_kpp *tfm)
+{
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+
+	/* max size is the pub_key_size, include x and y */
+	return ctx->key_sz << 1;
+}
+
+static int hpre_ecdh_init_tfm(struct crypto_kpp *tfm)
+{
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+
+	return hpre_ctx_init(ctx, HPRE_V3_ECC_ALG_TYPE);
+}
+
+static void hpre_ecdh_exit_tfm(struct crypto_kpp *tfm)
+{
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+
+	hpre_ecc_clear_ctx(ctx, true, true);
+}
+
 static struct akcipher_alg rsa = {
 	.sign = hpre_rsa_dec,
 	.verify = hpre_rsa_enc,
@@ -1154,6 +1624,22 @@ static struct kpp_alg dh = {
 };
 #endif
 
+static struct kpp_alg ecdh = {
+	.set_secret = hpre_ecdh_set_secret,
+	.generate_public_key = hpre_ecdh_compute_value,
+	.compute_shared_secret = hpre_ecdh_compute_value,
+	.max_size = hpre_ecdh_max_size,
+	.init = hpre_ecdh_init_tfm,
+	.exit = hpre_ecdh_exit_tfm,
+	.reqsize = sizeof(struct hpre_asym_request) + HPRE_ALIGN_SZ,
+	.base = {
+		.cra_ctxsize = sizeof(struct hpre_ctx),
+		.cra_priority = HPRE_CRYPTO_ALG_PRI,
+		.cra_name = "ecdh",
+		.cra_driver_name = "hpre-ecdh",
+		.cra_module = THIS_MODULE,
+	},
+};
 int hpre_algs_register(struct hisi_qm *qm)
 {
 	int ret;
@@ -1164,17 +1650,33 @@ int hpre_algs_register(struct hisi_qm *qm)
 		return ret;
 #ifdef CONFIG_CRYPTO_DH
 	ret = crypto_register_kpp(&dh);
-	if (ret)
+	if (ret) {
 		crypto_unregister_akcipher(&rsa);
+		return ret;
+	}
 #endif
 
-	return ret;
+	if (qm->ver >= QM_HW_V3) {
+		ret = crypto_register_kpp(&ecdh);
+		if (ret) {
+#ifdef CONFIG_CRYPTO_DH
+			crypto_unregister_kpp(&dh);
+#endif
+			crypto_unregister_akcipher(&rsa);
+			return ret;
+		}
+	}
+
+	return 0;
 }
 
 void hpre_algs_unregister(struct hisi_qm *qm)
 {
-	crypto_unregister_akcipher(&rsa);
+	if (qm->ver >= QM_HW_V3)
+		crypto_unregister_kpp(&ecdh);
+
 #ifdef CONFIG_CRYPTO_DH
 	crypto_unregister_kpp(&dh);
 #endif
+	crypto_unregister_akcipher(&rsa);
 }
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index 1ae8fa1..2ccc3dc 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -1020,4 +1020,5 @@ module_exit(hpre_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Zaibo Xu <xuzaibo@huawei.com>");
+MODULE_AUTHOR("Meng Yu <yumeng18@huawei.com>");
 MODULE_DESCRIPTION("Driver for HiSilicon HPRE accelerator");
diff --git a/include/crypto/ecc_curve_defs.h b/include/crypto/ecc_curve_defs.h
index 1080766..bf30338 100644
--- a/include/crypto/ecc_curve_defs.h
+++ b/include/crypto/ecc_curve_defs.h
@@ -37,6 +37,14 @@ struct ecc_curve {
 	u64 *b;
 };
 
+/* NIST P-128: a = p - 3 */
+static u64 nist_p128_g_x[] = { 0x0C28607CA52C5B86ull, 0x161FF7528B899B2Dull };
+static u64 nist_p128_g_y[] = { 0xc02da292dded7a83ull, 0xcf5ac8395bafeb13ull };
+static u64 nist_p128_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFDFFFFFFFFull };
+static u64 nist_p128_n[] = { 0x75A30D1B9038A115ull, 0xFFFFFFFE00000000ull };
+static u64 nist_p128_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFDFFFFFFFFull };
+static u64 nist_p128_b[] = { 0xD824993C2CEE5ED3ull, 0xE87579C11079F43Dull };
+
 /* NIST P-192: a = p - 3 */
 static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
 				0x188DA80EB03090F6ull };
@@ -50,18 +58,20 @@ static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
 				0xFFFFFFFFFFFFFFFFull };
 static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
 				0x64210519E59C80E7ull };
-static struct ecc_curve nist_p192 = {
-	.name = "nist_192",
-	.g = {
-		.x = nist_p192_g_x,
-		.y = nist_p192_g_y,
-		.ndigits = 3,
-	},
-	.p = nist_p192_p,
-	.n = nist_p192_n,
-	.a = nist_p192_a,
-	.b = nist_p192_b
-};
+
+/* NIST P-224 */
+static u64 nist_p224_g_x[] = { 0x343280D6115C1D21ull, 0x4A03C1D356C21122ull,
+				0x6BB4BF7F321390B9ull, 0xB70E0CBDull };
+static u64 nist_p224_g_y[] = { 0x44d5819985007e34ull, 0xcd4375a05a074764ull,
+				0xb5f723fb4c22dfe6ull, 0xbd376388ull };
+static u64 nist_p224_p[] = { 0x0000000000000001ull, 0xFFFFFFFF00000000ull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFull };
+static u64 nist_p224_n[] = { 0x13DD29455C5C2A3Dull, 0xFFFF16A2E0B8F03Eull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFull };
+static u64 nist_p224_a[] = { 0xFFFFFFFFFFFFFFFEull, 0xFFFFFFFEFFFFFFFFull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFull };
+static u64 nist_p224_b[] = { 0x270B39432355FFB4ull, 0x5044B0B7D7BFD8BAull,
+				0x0C04B3ABF5413256ull, 0xB4050A85ull };
 
 /* NIST P-256: a = p - 3 */
 static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
@@ -76,17 +86,159 @@ static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
 				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
 static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
 				0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
-static struct ecc_curve nist_p256 = {
-	.name = "nist_256",
-	.g = {
-		.x = nist_p256_g_x,
-		.y = nist_p256_g_y,
-		.ndigits = 4,
-	},
-	.p = nist_p256_p,
-	.n = nist_p256_n,
-	.a = nist_p256_a,
-	.b = nist_p256_b
+
+/* NIST P-320 */
+static u64 nist_p320_g_x[] = { 0x10AF8D0D39E20611ull, 0xE7871E2A10A599C7ull,
+				0xF20137D10A087EB6ull, 0x5289BCC48EE5BFE6ull,
+				0x43BD7E9AFB53D8B8ull };
+static u64 nist_p320_g_y[] = { 0xD35245D1692E8EE1ull, 0xA9C77877AAAC6AC7ull,
+				0x0743FFED117182EAull, 0xAB4093247F77275Eull,
+				0x14FDD05545EC1CC8ull };
+static u64 nist_p320_p[] = { 0xFCD412B1F1B32E27ull, 0x4F92B9EC7893EC28ull,
+				0xF98FCFA6F6F40DEFull, 0xE13C785ED201E065ull,
+				0xD35E472036BC4FB7ull };
+static u64 nist_p320_n[] = { 0x8691555B44C59311ull, 0x2D482EC7EE8658E9ull,
+				0xF98FCFA5B68F12A3ull, 0xE13C785ED201E065ull,
+				0xD35E472036BC4FB7ull };
+static u64 nist_p320_a[] = { 0x92F375A97D860EB4ull, 0x66190EB085FFA9F4ull,
+				0xA2A73513F5EB79DAull, 0x83CCEBD46D3F3BB8ull,
+				0x3EE30B568FBAB0F8ull };
+static u64 nist_p320_b[] = { 0x6F5EB4AC8FB1F1A6ull, 0xCC31DCCD88453981ull,
+				0xE13F41349554B49Aull, 0xD3AD198640688A6Full,
+				0x520883949DFDBC42ull };
+
+/* NIST P-384 */
+static u64 nist_p384_g_x[] = { 0xEF87B2E247D4AF1Eull, 0xE826E03436D646AAull,
+				0xDB7FCAFE0CBD10E8ull, 0x8847A3E77EF14FE3ull,
+				0xA2A63A81B7C13F6Bull, 0x1D1C64F068CF45FFull };
+static u64 nist_p384_g_y[] = { 0x42820341263C5315ull, 0x0E46462177918111ull,
+				0xE19C054FF9912928ull, 0x62B70B29FEEC5864ull,
+				0x5CB1EB8E95CFD552ull, 0x8ABE1D7520F9C2A4ull };
+static u64 nist_p384_p[] = { 0x874700133107EC53ull, 0xACD3A729901D1A71ull,
+				0x12B1DA197FB71123ull, 0x152F7109ED5456B4ull,
+				0x0F5D6F7E50E641DFull, 0x8CB91E82A3386D28ull };
+static u64 nist_p384_n[] = { 0x3B883202E9046565ull, 0xCF3AB6AF6B7FC310ull,
+				0x1F166E6CAC0425A7ull, 0x152F7109ED5456B3ull,
+				0x0F5D6F7E50E641DFull, 0x8CB91E82A3386D28ull };
+static u64 nist_p384_a[] = { 0x04A8C7DD22CE2826ull, 0x8AA5814A503AD4EBull,
+				0x139165EFBA91F90Full, 0xC2BEA28E4FB22787ull,
+				0x3C72080ACE05AFA0ull, 0x7BC382C63D8C150Cull };
+static u64 nist_p384_b[] = { 0x3AB78696FA504C11ull, 0x7CB4390295DBC994ull,
+				0x2E880EA53EEB62D5ull, 0x2FB77DE107DCD2A6ull,
+				0x8B39B55416F0447Cull, 0x04A8C7DD22CE2826ull };
+
+/* NIST P-521: a = p - 3 */
+static u64 nist_p521_g_x[] = { 0xF97E7E31C2E5BD66ull, 0x3348B3C1856A429Bull,
+				0xFE1DC127A2FFA8DEull, 0xA14B5E77EFE75928ull,
+				0xF828AF606B4D3DBAull, 0x9C648139053FB521ull,
+				0x9E3ECB662395B442ull, 0x858E06B70404E9CDull,
+				0x00C6ull };
+static u64 nist_p521_g_y[] = { 0x88be94769fd16650ull, 0x353c7086a272c240ull,
+				0xc550b9013fad0761ull, 0x97ee72995ef42640ull,
+				0x17afbd17273e662cull, 0x98f54449579b4468ull,
+				0x5c8a5fb42c7d1bd9ull, 0x39296a789a3bc004ull,
+				0x0118ull };
+static u64 nist_p521_p[] = {0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+				0x01FFull };
+static u64 nist_p521_n[] = { 0xBB6FB71E91386409ull, 0x3BB5C9B8899C47AEull,
+				0x7FCC0148F709A5D0ull, 0x51868783BF2F966Bull,
+				0xFFFFFFFFFFFFFFFAull, 0xFFFFFFFFFFFFFFFFull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+				0x01FFull };
+static u64 nist_p521_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFFull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull,
+				0x01FFull };
+static u64 nist_p521_b[] = { 0xEF451FD46B503F00ull, 0x3573DF883D2C34F1ull,
+				0x1652C0BD3BB1BF07ull, 0x56193951EC7E937Bull,
+				0xB8B489918EF109E1ull, 0xA2DA725B99B315F3ull,
+				0x929A21A0B68540EEull, 0x953EB9618E1C9A1Full,
+				0x0051ull };
+
+
+static const struct ecc_curve ecc_curve_list[] = {
+	{
+		.name = "nist_128",
+		.g = {
+			.x = nist_p128_g_x,
+			.y = nist_p128_g_y,
+			.ndigits = 2,
+		},
+		.p = nist_p128_p,
+		.n = nist_p128_n,
+		.a = nist_p128_a,
+		.b = nist_p128_b,
+	}, {
+		.name = "nist_192",
+		.g = {
+			.x = nist_p192_g_x,
+			.y = nist_p192_g_y,
+			.ndigits = 3,
+		},
+		.p = nist_p192_p,
+		.n = nist_p192_n,
+		.a = nist_p192_a,
+		.b = nist_p192_b,
+	}, {
+		.name = "nist_224",
+		.g = {
+			.x = nist_p224_g_x,
+			.y = nist_p224_g_y,
+			.ndigits = 4,
+		},
+		.p = nist_p224_p,
+		.n = nist_p224_n,
+		.a = nist_p224_a,
+		.b = nist_p224_b,
+	}, {
+		.name = "nist_256",
+		.g = {
+			.x = nist_p256_g_x,
+			.y = nist_p256_g_y,
+			.ndigits = 4,
+		},
+		.p = nist_p256_p,
+		.n = nist_p256_n,
+		.a = nist_p256_a,
+		.b = nist_p256_b,
+	}, {
+		.name = "nist_320",
+		.g = {
+			.x = nist_p320_g_x,
+			.y = nist_p320_g_y,
+			.ndigits = 5,
+		},
+		.p = nist_p320_p,
+		.n = nist_p320_n,
+		.a = nist_p320_a,
+		.b = nist_p320_b,
+	}, {
+		.name = "nist_384",
+		.g = {
+			.x = nist_p384_g_x,
+			.y = nist_p384_g_y,
+			.ndigits = 6,
+		},
+		.p = nist_p384_p,
+		.n = nist_p384_n,
+		.a = nist_p384_a,
+		.b = nist_p384_b,
+	}, {
+		.name = "nist_521",
+		.g = {
+			.x = nist_p521_g_x,
+			.y = nist_p521_g_y,
+			.ndigits = 9,
+		},
+		.p = nist_p521_p,
+		.n = nist_p521_n,
+		.a = nist_p521_a,
+		.b = nist_p521_b,
+	}
 };
 
 #endif
diff --git a/include/crypto/ecdh.h b/include/crypto/ecdh.h
index a5b805b..7d4fd3a 100644
--- a/include/crypto/ecdh.h
+++ b/include/crypto/ecdh.h
@@ -23,8 +23,13 @@
  */
 
 /* Curves IDs */
-#define ECC_CURVE_NIST_P192	0x0001
-#define ECC_CURVE_NIST_P256	0x0002
+#define ECC_CURVE_NIST_P128	0x0001
+#define ECC_CURVE_NIST_P192	0x0002
+#define ECC_CURVE_NIST_P224	0x0003
+#define ECC_CURVE_NIST_P256	0x0004
+#define ECC_CURVE_NIST_P320	0x0005
+#define ECC_CURVE_NIST_P384	0x0006
+#define ECC_CURVE_NIST_P521	0x0007
 
 /**
  * struct ecdh - define an ECDH private key
-- 
2.8.1


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

* [PATCH v4 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm
  2020-12-11  6:30 [PATCH v4 0/5] add ECDH and CURVE25519 algorithms support for Kunpeng 930 Meng Yu
                   ` (3 preceding siblings ...)
  2020-12-11  6:30 ` [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm Meng Yu
@ 2020-12-11  6:30 ` Meng Yu
  2020-12-11 14:14   ` Stephan Mueller
  4 siblings, 1 reply; 15+ messages in thread
From: Meng Yu @ 2020-12-11  6:30 UTC (permalink / raw)
  To: herbert, davem; +Cc: linux-crypto, xuzaibo, wangzhou1, yumeng18, linux-kernel

1. Add 'CURVE25519' curve parameter definition to
   'include/crypto/ecc_curve_defs.h';
2. Enable 'CURVE25519' algorithm in Kunpeng 930.

Signed-off-by: Meng Yu <yumeng18@huawei.com>
Reviewed-by: Zaibo Xu <xuzaibo@huawei.com>
Reported-by: kernel test robot <lkp@intel.com>
---
 drivers/crypto/hisilicon/Kconfig            |   1 +
 drivers/crypto/hisilicon/hpre/hpre.h        |   2 +
 drivers/crypto/hisilicon/hpre/hpre_crypto.c | 364 +++++++++++++++++++++++++++-
 include/crypto/ecc_curve_defs.h             |  17 ++
 4 files changed, 375 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/hisilicon/Kconfig b/drivers/crypto/hisilicon/Kconfig
index 8431926..c45adb1 100644
--- a/drivers/crypto/hisilicon/Kconfig
+++ b/drivers/crypto/hisilicon/Kconfig
@@ -65,6 +65,7 @@ config CRYPTO_DEV_HISI_HPRE
 	depends on UACCE || UACCE=n
 	depends on ARM64 || (COMPILE_TEST && 64BIT)
 	depends on ACPI
+	select CRYPTO_LIB_CURVE25519_GENERIC
 	select CRYPTO_DEV_HISI_QM
 	select CRYPTO_DH
 	select CRYPTO_RSA
diff --git a/drivers/crypto/hisilicon/hpre/hpre.h b/drivers/crypto/hisilicon/hpre/hpre.h
index 50e6b2e..92892e3 100644
--- a/drivers/crypto/hisilicon/hpre/hpre.h
+++ b/drivers/crypto/hisilicon/hpre/hpre.h
@@ -84,6 +84,8 @@ enum hpre_alg_type {
 	HPRE_ALG_DH_G2 = 0x4,
 	HPRE_ALG_DH = 0x5,
 	HPRE_ALG_ECC_MUL = 0xD,
+	/* shared by x25519 and x448, but x448 is not supported now */
+	HPRE_ALG_CURVE25519_MUL = 0x10,
 };
 
 struct hpre_sqe {
diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
index 58f847b..e135732 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) 2019 HiSilicon Limited. */
 #include <crypto/akcipher.h>
+#include <crypto/curve25519.h>
 #include <crypto/dh.h>
 #include <crypto/ecc_curve_defs.h>
 #include <crypto/ecdh.h>
@@ -98,6 +99,16 @@ struct hpre_ecdh_ctx {
 	dma_addr_t dma_g;
 };
 
+struct hpre_curve25519_ctx {
+	/* low address: p->a->k */
+	unsigned char *p;
+	dma_addr_t dma_p;
+
+	/* gx coordinate */
+	unsigned char *g;
+	dma_addr_t dma_g;
+};
+
 struct hpre_ctx {
 	struct hisi_qp *qp;
 	struct hpre_asym_request **req_list;
@@ -110,6 +121,7 @@ struct hpre_ctx {
 		struct hpre_rsa_ctx rsa;
 		struct hpre_dh_ctx dh;
 		struct hpre_ecdh_ctx ecdh;
+		struct hpre_curve25519_ctx curve25519;
 	};
 	/* for ecc algorithms */
 	unsigned int curve_id;
@@ -124,6 +136,7 @@ struct hpre_asym_request {
 		struct akcipher_request *rsa;
 		struct kpp_request *dh;
 		struct kpp_request *ecdh;
+		struct kpp_request *curve25519;
 	} areq;
 	int err;
 	int req_id;
@@ -446,7 +459,6 @@ static void hpre_alg_cb(struct hisi_qp *qp, void *resp)
 	struct hpre_sqe *sqe = resp;
 	struct hpre_asym_request *req = ctx->req_list[le16_to_cpu(sqe->tag)];
 
-
 	if (unlikely(!req)) {
 		atomic64_inc(&dfx[HPRE_INVALID_REQ_CNT].value);
 		return;
@@ -1176,6 +1188,12 @@ static void hpre_ecc_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all,
 		memzero_explicit(ctx->ecdh.p + shift, sz);
 		dma_free_coherent(dev, sz << 3, ctx->ecdh.p, ctx->ecdh.dma_p);
 		ctx->ecdh.p = NULL;
+	} else if (!is_ecdh && ctx->curve25519.p) {
+		/* curve25519: p->a->k */
+		memzero_explicit(ctx->curve25519.p + shift, sz);
+		dma_free_coherent(dev, sz << 2, ctx->curve25519.p,
+				  ctx->curve25519.dma_p);
+		ctx->curve25519.p = NULL;
 	}
 
 	ctx->curve_id = 0;
@@ -1585,6 +1603,307 @@ static void hpre_ecdh_exit_tfm(struct crypto_kpp *tfm)
 	hpre_ecc_clear_ctx(ctx, true, true);
 }
 
+static void hpre_curve25519_fill_curve(struct hpre_ctx *ctx, const void *buf,
+				       unsigned int len)
+{
+	u8 secret[CURVE25519_KEY_SIZE] = { 0 };
+	unsigned int sz = ctx->key_sz;
+	unsigned int shift = sz << 1;
+	void *p;
+
+	/**
+	 * The key from 'buf' is in little-endian, we should preprocess it as
+	 * the description in rfc7748: "k[0] &= 248, k[31] &= 127, k[31] |= 64",
+	 * then convert it to big endian. Only in this way, the result can be
+	 * the same as the software curve-25519 that exists in crypto.
+	 */
+	memcpy(secret, buf, len);
+	curve25519_clamp_secret(secret);
+	hpre_key_to_big_end(secret, CURVE25519_KEY_SIZE);
+
+	p = ctx->curve25519.p + sz - len;
+
+	/* fill curve parameters */
+	fill_curve_param(p, ecc_25519.p, len, ecc_25519.g.ndigits);
+	fill_curve_param(p + sz, ecc_25519.a, len, ecc_25519.g.ndigits);
+	memcpy(p + shift, secret, len);
+	fill_curve_param(p + shift + sz, ecc_25519.g.x, len, ecc_25519.g.ndigits);
+	memzero_explicit(secret, CURVE25519_KEY_SIZE);
+}
+
+static int hpre_curve25519_set_param(struct hpre_ctx *ctx, const void *buf,
+				     unsigned int len)
+{
+	struct device *dev = HPRE_DEV(ctx);
+	unsigned int sz = ctx->key_sz;
+	unsigned int shift = sz << 1;
+
+	/* p->a->k->gx */
+	if (!ctx->curve25519.p) {
+		ctx->curve25519.p = dma_alloc_coherent(dev, sz << 2,
+						       &ctx->curve25519.dma_p,
+						       GFP_KERNEL);
+		if (!ctx->curve25519.p)
+			return -ENOMEM;
+	}
+
+	ctx->curve25519.g = ctx->curve25519.p + shift + sz;
+	ctx->curve25519.dma_g = ctx->curve25519.dma_p + shift + sz;
+
+	hpre_curve25519_fill_curve(ctx, buf, len);
+
+	return 0;
+}
+
+static int hpre_curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
+				      unsigned int len)
+{
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+	struct device *dev = HPRE_DEV(ctx);
+	int ret = -EINVAL;
+
+	if (len != CURVE25519_KEY_SIZE ||
+	    !crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE)) {
+		dev_err(dev, "key is null or key len is not 32bytes!\n");
+		return ret;
+	}
+
+	/* Free old secret if any */
+	hpre_ecc_clear_ctx(ctx, false, false);
+
+	ctx->key_sz = CURVE25519_KEY_SIZE;
+	ret = hpre_curve25519_set_param(ctx, buf, CURVE25519_KEY_SIZE);
+	if (ret) {
+		dev_err(dev, "failed to set curve25519 param, ret = %d!\n", ret);
+		hpre_ecc_clear_ctx(ctx, false, false);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void hpre_curve25519_hw_data_clr_all(struct hpre_ctx *ctx,
+					    struct hpre_asym_request *req,
+					    struct scatterlist *dst,
+					    struct scatterlist *src)
+{
+	struct device *dev = HPRE_DEV(ctx);
+	struct hpre_sqe *sqe = &req->req;
+	dma_addr_t dma;
+
+	dma = le64_to_cpu(sqe->in);
+	if (unlikely(!dma))
+		return;
+
+	if (src && req->src)
+		dma_free_coherent(dev, ctx->key_sz, req->src, dma);
+
+	dma = le64_to_cpu(sqe->out);
+	if (unlikely(!dma))
+		return;
+
+	if (req->dst)
+		dma_free_coherent(dev, ctx->key_sz, req->dst, dma);
+	if (dst)
+		dma_unmap_single(dev, dma, ctx->key_sz, DMA_FROM_DEVICE);
+}
+
+static void hpre_curve25519_cb(struct hpre_ctx *ctx, void *resp)
+{
+	struct hpre_dfx *dfx = ctx->hpre->debug.dfx;
+	struct hpre_asym_request *req = NULL;
+	struct kpp_request *areq;
+	u64 overtime_thrhld;
+	int ret;
+
+	ret = hpre_alg_res_post_hf(ctx, resp, (void **)&req);
+	areq = req->areq.curve25519;
+	areq->dst_len = ctx->key_sz;
+
+	overtime_thrhld = atomic64_read(&dfx[HPRE_OVERTIME_THRHLD].value);
+	if (overtime_thrhld && hpre_is_bd_timeout(req, overtime_thrhld))
+		atomic64_inc(&dfx[HPRE_OVER_THRHLD_CNT].value);
+
+	hpre_key_to_big_end(sg_virt(areq->dst), CURVE25519_KEY_SIZE);
+
+	hpre_curve25519_hw_data_clr_all(ctx, req, areq->dst, areq->src);
+	kpp_request_complete(areq, ret);
+
+	atomic64_inc(&dfx[HPRE_RECV_CNT].value);
+}
+
+static int hpre_curve25519_msg_request_set(struct hpre_ctx *ctx,
+					   struct kpp_request *req)
+{
+	struct hpre_asym_request *h_req;
+	struct hpre_sqe *msg;
+	int req_id;
+	void *tmp;
+
+	if (unlikely(req->dst_len < ctx->key_sz)) {
+		req->dst_len = ctx->key_sz;
+		return -EINVAL;
+	}
+
+	tmp = kpp_request_ctx(req);
+	h_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ);
+	h_req->cb = hpre_curve25519_cb;
+	h_req->areq.curve25519 = req;
+	msg = &h_req->req;
+	memset(msg, 0, sizeof(*msg));
+	msg->key = cpu_to_le64(ctx->curve25519.dma_p);
+
+	msg->dw0 |= cpu_to_le32(0x1U << HPRE_SQE_DONE_SHIFT);
+	msg->task_len1 = (ctx->key_sz >> HPRE_BITS_2_BYTES_SHIFT) - 1;
+	h_req->ctx = ctx;
+
+	req_id = hpre_add_req_to_ctx(h_req);
+	if (req_id < 0)
+		return -EBUSY;
+
+	msg->tag = cpu_to_le16((u16)req_id);
+	return 0;
+}
+
+static int hpre_curve25519_src_init(struct hpre_asym_request *hpre_req,
+				    struct scatterlist *data, unsigned int len)
+{
+	struct hpre_sqe *msg = &hpre_req->req;
+	struct hpre_ctx *ctx = hpre_req->ctx;
+	struct device *dev = HPRE_DEV(ctx);
+	u8 p[CURVE25519_KEY_SIZE] = { 0 };
+	dma_addr_t dma = 0;
+	u8 *ptr;
+
+	if (len != CURVE25519_KEY_SIZE) {
+		dev_err(dev, "sourc_data len is not 32bytes, len = %u!\n", len);
+		return -EINVAL;
+	}
+
+	ptr = dma_alloc_coherent(dev, ctx->key_sz, &dma, GFP_KERNEL);
+	if (unlikely(!ptr))
+		return -ENOMEM;
+
+	scatterwalk_map_and_copy(ptr, data, 0, len, 0);
+
+	if (!crypto_memneq(ptr, curve25519_null_point, CURVE25519_KEY_SIZE)) {
+		dev_err(dev, "gx is null!\n");
+		goto err;
+	}
+
+	/**
+	 * Src_data(gx) is in little-endian order, MSB in the final byte should
+	 * be masked as discribed in RFC7748, then transform it to big-endian
+	 * form, then hisi_hpre can use the data.
+	 */
+	ptr[31] &= 0x7f;
+	hpre_key_to_big_end(ptr, CURVE25519_KEY_SIZE);
+
+	fill_curve_param(p, ecc_25519.p, CURVE25519_KEY_SIZE,
+			 ecc_25519.g.ndigits);
+	if (strcmp(ptr, p) >= 0) {
+		dev_err(dev, "gx is out of p!\n");
+		goto err;
+	}
+
+	hpre_req->src = ptr;
+	msg->in = cpu_to_le64(dma);
+	return 0;
+
+err:
+	dma_free_coherent(dev, ctx->key_sz, ptr, dma);
+	return -EINVAL;
+}
+
+static int hpre_curve25519_dst_init(struct hpre_asym_request *hpre_req,
+				    struct scatterlist *data, unsigned int len)
+{
+	struct hpre_sqe *msg = &hpre_req->req;
+	struct hpre_ctx *ctx = hpre_req->ctx;
+	struct device *dev = HPRE_DEV(ctx);
+	dma_addr_t dma = 0;
+
+	if (!data || !sg_is_last(data) || len != ctx->key_sz) {
+		dev_err(dev, "data or data length is illegal!\n");
+		return -EINVAL;
+	}
+
+	hpre_req->dst = NULL;
+	dma = dma_map_single(dev, sg_virt(data), len, DMA_FROM_DEVICE);
+	if (unlikely(dma_mapping_error(dev, dma))) {
+		dev_err(dev, "dma map data err!\n");
+		return -ENOMEM;
+	}
+
+	msg->out = cpu_to_le64(dma);
+	return 0;
+}
+
+static int hpre_curve25519_compute_value(struct kpp_request *req)
+{
+	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+	struct device *dev = HPRE_DEV(ctx);
+	void *tmp = kpp_request_ctx(req);
+	struct hpre_asym_request *hpre_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ);
+	struct hpre_sqe *msg = &hpre_req->req;
+	int ret;
+
+	ret = hpre_curve25519_msg_request_set(ctx, req);
+	if (unlikely(ret)) {
+		dev_err(dev, "failed to set curve25519 request, ret = %d!\n", ret);
+		return ret;
+	}
+
+	if (req->src) {
+		ret = hpre_curve25519_src_init(hpre_req, req->src, req->src_len);
+		if (unlikely(ret)) {
+			dev_err(dev, "failed to init src data, ret = %d!\n",
+				ret);
+			goto clear_all;
+		}
+	} else {
+		msg->in = cpu_to_le64(ctx->curve25519.dma_g);
+	}
+
+	ret = hpre_curve25519_dst_init(hpre_req, req->dst, req->dst_len);
+	if (unlikely(ret)) {
+		dev_err(dev, "failed to init dst data, ret = %d!\n", ret);
+		goto clear_all;
+	}
+
+	msg->dw0 = cpu_to_le32(le32_to_cpu(msg->dw0) | HPRE_ALG_CURVE25519_MUL);
+	ret = hpre_send(ctx, msg);
+	if (likely(!ret))
+		return -EINPROGRESS;
+
+clear_all:
+	hpre_rm_req_from_ctx(hpre_req);
+	hpre_curve25519_hw_data_clr_all(ctx, hpre_req, req->dst, req->src);
+	return ret;
+}
+
+static unsigned int hpre_curve25519_max_size(struct crypto_kpp *tfm)
+{
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+
+	return ctx->key_sz;
+}
+
+static int hpre_curve25519_init_tfm(struct crypto_kpp *tfm)
+{
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+
+	return hpre_ctx_init(ctx, HPRE_V3_ECC_ALG_TYPE);
+}
+
+static void hpre_curve25519_exit_tfm(struct crypto_kpp *tfm)
+{
+	struct hpre_ctx *ctx = kpp_tfm_ctx(tfm);
+
+	hpre_ecc_clear_ctx(ctx, true, false);
+}
+
 static struct akcipher_alg rsa = {
 	.sign = hpre_rsa_dec,
 	.verify = hpre_rsa_enc,
@@ -1640,6 +1959,24 @@ static struct kpp_alg ecdh = {
 		.cra_module = THIS_MODULE,
 	},
 };
+
+static struct kpp_alg curve25519_alg = {
+	.set_secret = hpre_curve25519_set_secret,
+	.generate_public_key = hpre_curve25519_compute_value,
+	.compute_shared_secret = hpre_curve25519_compute_value,
+	.max_size = hpre_curve25519_max_size,
+	.init = hpre_curve25519_init_tfm,
+	.exit = hpre_curve25519_exit_tfm,
+	.reqsize = sizeof(struct hpre_asym_request) + HPRE_ALIGN_SZ,
+	.base = {
+		.cra_ctxsize = sizeof(struct hpre_ctx),
+		.cra_priority = HPRE_CRYPTO_ALG_PRI,
+		.cra_name = "curve25519",
+		.cra_driver_name = "hpre-curve25519",
+		.cra_module = THIS_MODULE,
+	},
+};
+
 int hpre_algs_register(struct hisi_qm *qm)
 {
 	int ret;
@@ -1654,26 +1991,35 @@ int hpre_algs_register(struct hisi_qm *qm)
 		crypto_unregister_akcipher(&rsa);
 		return ret;
 	}
-#endif
 
+#endif
 	if (qm->ver >= QM_HW_V3) {
 		ret = crypto_register_kpp(&ecdh);
+		if (ret)
+			goto reg_err;
+
+		ret = crypto_register_kpp(&curve25519_alg);
 		if (ret) {
-#ifdef CONFIG_CRYPTO_DH
-			crypto_unregister_kpp(&dh);
-#endif
-			crypto_unregister_akcipher(&rsa);
-			return ret;
+			crypto_unregister_kpp(&ecdh);
+			goto reg_err;
 		}
 	}
-
 	return 0;
+
+reg_err:
+#ifdef CONFIG_CRYPTO_DH
+	crypto_unregister_kpp(&dh);
+#endif
+	crypto_unregister_akcipher(&rsa);
+	return ret;
 }
 
 void hpre_algs_unregister(struct hisi_qm *qm)
 {
-	if (qm->ver >= QM_HW_V3)
+	if (qm->ver >= QM_HW_V3) {
+		crypto_unregister_kpp(&curve25519_alg);
 		crypto_unregister_kpp(&ecdh);
+	}
 
 #ifdef CONFIG_CRYPTO_DH
 	crypto_unregister_kpp(&dh);
diff --git a/include/crypto/ecc_curve_defs.h b/include/crypto/ecc_curve_defs.h
index bf30338..7a2a4aa 100644
--- a/include/crypto/ecc_curve_defs.h
+++ b/include/crypto/ecc_curve_defs.h
@@ -241,4 +241,21 @@ static const struct ecc_curve ecc_curve_list[] = {
 	}
 };
 
+/* curve25519 */
+static u64 curve25519_g_x[] = { 0x0000000000000009, 0x0000000000000000,
+				0x0000000000000000, 0x0000000000000000 };
+static u64 curve25519_p[] = { 0xffffffffffffffed, 0xffffffffffffffff,
+				0xffffffffffffffff, 0x7fffffffffffffff };
+static u64 curve25519_a[] = { 0x000000000001DB41, 0x0000000000000000,
+				0x0000000000000000, 0x0000000000000000 };
+static const struct ecc_curve ecc_25519 = {
+	.name = "curve25519",
+	.g = {
+		.x = curve25519_g_x,
+		.ndigits = 4,
+	},
+	.p = curve25519_p,
+	.a = curve25519_a,
+};
+
 #endif
-- 
2.8.1


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

* Re: [PATCH v4 3/5] crypto: expose elliptic curve parameters as Crypto APIs
  2020-12-11  6:30 ` [PATCH v4 3/5] crypto: expose elliptic curve parameters as Crypto APIs Meng Yu
@ 2020-12-11 13:13   ` Vitaly Chikunov
       [not found]     ` <75a25392-464d-b76e-ba92-4287e24acbf7@huawei.com>
  0 siblings, 1 reply; 15+ messages in thread
From: Vitaly Chikunov @ 2020-12-11 13:13 UTC (permalink / raw)
  To: Meng Yu; +Cc: herbert, davem, linux-crypto, xuzaibo, wangzhou1, linux-kernel

Meng,

It looks like not just definitions but some static data is moved to
includes. Why?

Thanks,

On Fri, Dec 11, 2020 at 02:30:32PM +0800, Meng Yu wrote:
> Move elliptic curves definition to 'include/crypto/ecc_curve_defs.h',
> so all can use it,
> 
> Signed-off-by: Meng Yu <yumeng18@huawei.com>
> Reviewed-by: Zaibo Xu <xuzaibo@huawei.com>
> ---
>  crypto/ecc.c                    |  1 -
>  crypto/ecc.h                    | 37 +----------------
>  crypto/ecc_curve_defs.h         | 57 -------------------------
>  crypto/ecrdsa_defs.h            |  2 +-
>  include/crypto/ecc_curve_defs.h | 92 +++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 95 insertions(+), 94 deletions(-)
>  delete mode 100644 crypto/ecc_curve_defs.h
>  create mode 100644 include/crypto/ecc_curve_defs.h
> 
> diff --git a/crypto/ecc.c b/crypto/ecc.c
> index c80aa25..f23efdd 100644
> --- a/crypto/ecc.c
> +++ b/crypto/ecc.c
> @@ -35,7 +35,6 @@
>  #include <linux/ratelimit.h>
>  
>  #include "ecc.h"
> -#include "ecc_curve_defs.h"
>  
>  typedef struct {
>  	u64 m_low;
> diff --git a/crypto/ecc.h b/crypto/ecc.h
> index d4e546b..e5afaf3 100644
> --- a/crypto/ecc.h
> +++ b/crypto/ecc.h
> @@ -26,6 +26,8 @@
>  #ifndef _CRYPTO_ECC_H
>  #define _CRYPTO_ECC_H
>  
> +#include <crypto/ecc_curve_defs.h>
> +
>  /* One digit is u64 qword. */
>  #define ECC_CURVE_NIST_P192_DIGITS  3
>  #define ECC_CURVE_NIST_P256_DIGITS  4
> @@ -33,44 +35,9 @@
>  
>  #define ECC_DIGITS_TO_BYTES_SHIFT 3
>  
> -/**
> - * struct ecc_point - elliptic curve point in affine coordinates
> - *
> - * @x:		X coordinate in vli form.
> - * @y:		Y coordinate in vli form.
> - * @ndigits:	Length of vlis in u64 qwords.
> - */
> -struct ecc_point {
> -	u64 *x;
> -	u64 *y;
> -	u8 ndigits;
> -};
> -
>  #define ECC_POINT_INIT(x, y, ndigits)	(struct ecc_point) { x, y, ndigits }
>  
>  /**
> - * struct ecc_curve - definition of elliptic curve
> - *
> - * @name:	Short name of the curve.
> - * @g:		Generator point of the curve.
> - * @p:		Prime number, if Barrett's reduction is used for this curve
> - *		pre-calculated value 'mu' is appended to the @p after ndigits.
> - *		Use of Barrett's reduction is heuristically determined in
> - *		vli_mmod_fast().
> - * @n:		Order of the curve group.
> - * @a:		Curve parameter a.
> - * @b:		Curve parameter b.
> - */
> -struct ecc_curve {
> -	char *name;
> -	struct ecc_point g;
> -	u64 *p;
> -	u64 *n;
> -	u64 *a;
> -	u64 *b;
> -};
> -
> -/**
>   * ecc_is_key_valid() - Validate a given ECDH private key
>   *
>   * @curve_id:		id representing the curve to use
> diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
> deleted file mode 100644
> index 69be6c7..0000000
> --- a/crypto/ecc_curve_defs.h
> +++ /dev/null
> @@ -1,57 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef _CRYTO_ECC_CURVE_DEFS_H
> -#define _CRYTO_ECC_CURVE_DEFS_H
> -
> -/* NIST P-192: a = p - 3 */
> -static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
> -				0x188DA80EB03090F6ull };
> -static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
> -				0x07192B95FFC8DA78ull };
> -static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
> -				0xFFFFFFFFFFFFFFFFull };
> -static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
> -				0xFFFFFFFFFFFFFFFFull };
> -static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
> -				0xFFFFFFFFFFFFFFFFull };
> -static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
> -				0x64210519E59C80E7ull };
> -static struct ecc_curve nist_p192 = {
> -	.name = "nist_192",
> -	.g = {
> -		.x = nist_p192_g_x,
> -		.y = nist_p192_g_y,
> -		.ndigits = 3,
> -	},
> -	.p = nist_p192_p,
> -	.n = nist_p192_n,
> -	.a = nist_p192_a,
> -	.b = nist_p192_b
> -};
> -
> -/* NIST P-256: a = p - 3 */
> -static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
> -				0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
> -static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
> -				0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull };
> -static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
> -				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
> -static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
> -				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
> -static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
> -				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
> -static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
> -				0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
> -static struct ecc_curve nist_p256 = {
> -	.name = "nist_256",
> -	.g = {
> -		.x = nist_p256_g_x,
> -		.y = nist_p256_g_y,
> -		.ndigits = 4,
> -	},
> -	.p = nist_p256_p,
> -	.n = nist_p256_n,
> -	.a = nist_p256_a,
> -	.b = nist_p256_b
> -};
> -
> -#endif
> diff --git a/crypto/ecrdsa_defs.h b/crypto/ecrdsa_defs.h
> index 170baf0..2074099 100644
> --- a/crypto/ecrdsa_defs.h
> +++ b/crypto/ecrdsa_defs.h
> @@ -13,7 +13,7 @@
>  #ifndef _CRYTO_ECRDSA_DEFS_H
>  #define _CRYTO_ECRDSA_DEFS_H
>  
> -#include "ecc.h"
> +#include <crypto/ecc_curve_defs.h>
>  
>  #define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8)
>  #define ECRDSA_MAX_DIGITS (512 / 64)
> diff --git a/include/crypto/ecc_curve_defs.h b/include/crypto/ecc_curve_defs.h
> new file mode 100644
> index 0000000..1080766
> --- /dev/null
> +++ b/include/crypto/ecc_curve_defs.h
> @@ -0,0 +1,92 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _CRYTO_ECC_CURVE_DEFS_H
> +#define _CRYTO_ECC_CURVE_DEFS_H
> +
> +/**
> + * struct ecc_point - elliptic curve point in affine coordinates
> + *
> + * @x:		X coordinate in vli form.
> + * @y:		Y coordinate in vli form.
> + * @ndigits:	Length of vlis in u64 qwords.
> + */
> +struct ecc_point {
> +	u64 *x;
> +	u64 *y;
> +	u8 ndigits;
> +};
> +
> +/**
> + * struct ecc_curve - definition of elliptic curve
> + *
> + * @name:	Short name of the curve.
> + * @g:		Generator point of the curve.
> + * @p:		Prime number, if Barrett's reduction is used for this curve
> + *		pre-calculated value 'mu' is appended to the @p after ndigits.
> + *		Use of Barrett's reduction is heuristically determined in
> + *		vli_mmod_fast().
> + * @n:		Order of the curve group.
> + * @a:		Curve parameter a.
> + * @b:		Curve parameter b.
> + */
> +struct ecc_curve {
> +	char *name;
> +	struct ecc_point g;
> +	u64 *p;
> +	u64 *n;
> +	u64 *a;
> +	u64 *b;
> +};
> +
> +/* NIST P-192: a = p - 3 */
> +static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
> +				0x188DA80EB03090F6ull };
> +static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
> +				0x07192B95FFC8DA78ull };
> +static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
> +				0xFFFFFFFFFFFFFFFFull };
> +static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
> +				0xFFFFFFFFFFFFFFFFull };
> +static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
> +				0xFFFFFFFFFFFFFFFFull };
> +static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
> +				0x64210519E59C80E7ull };
> +static struct ecc_curve nist_p192 = {
> +	.name = "nist_192",
> +	.g = {
> +		.x = nist_p192_g_x,
> +		.y = nist_p192_g_y,
> +		.ndigits = 3,
> +	},
> +	.p = nist_p192_p,
> +	.n = nist_p192_n,
> +	.a = nist_p192_a,
> +	.b = nist_p192_b
> +};
> +
> +/* NIST P-256: a = p - 3 */
> +static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
> +				0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
> +static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
> +				0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull };
> +static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
> +				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
> +static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
> +				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
> +static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
> +				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
> +static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
> +				0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
> +static struct ecc_curve nist_p256 = {
> +	.name = "nist_256",
> +	.g = {
> +		.x = nist_p256_g_x,
> +		.y = nist_p256_g_y,
> +		.ndigits = 4,
> +	},
> +	.p = nist_p256_p,
> +	.n = nist_p256_n,
> +	.a = nist_p256_a,
> +	.b = nist_p256_b
> +};
> +
> +#endif
> -- 
> 2.8.1

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

* Re: [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm
  2020-12-11  6:30 ` [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm Meng Yu
@ 2020-12-11 14:08   ` Stephan Mueller
       [not found]     ` <3903e2e8-165f-51b5-056c-24b8ce52e842@huawei.com>
  0 siblings, 1 reply; 15+ messages in thread
From: Stephan Mueller @ 2020-12-11 14:08 UTC (permalink / raw)
  To: Meng Yu, herbert, davem; +Cc: linux-crypto, xuzaibo, wangzhou1, linux-kernel

Am Freitag, den 11.12.2020, 14:30 +0800 schrieb Meng Yu:
> 
> +/* size in bytes of the n prime */
> +#define HPRE_ECC_NIST_P128_N_SIZE      16

Do we truly need P-128? Besides, I do not see that curve being defined in
contemporary cipher specs.

> +#define HPRE_ECC_NIST_P192_N_SIZE      24
> +#define HPRE_ECC_NIST_P224_N_SIZE      28
> +#define HPRE_ECC_NIST_P256_N_SIZE      32
> +#define HPRE_ECC_NIST_P320_N_SIZE      40

Do we truly need P-320? Besides, I do not see that curve being defined in
contemporary cipher specs.

> +#define HPRE_ECC_NIST_P384_N_SIZE      48
> +#define HPRE_ECC_NIST_P521_N_SIZE      66
> +
> +/* size in bytes */
> +#define HPRE_ECC_HW256_KSZ_B   32
> +#define HPRE_ECC_HW384_KSZ_B   48
> +#define HPRE_ECC_HW576_KSZ_B   72
> +
> +#define HPRE_ECDH_MAX_SZ       HPRE_ECC_HW576_KSZ_B]

Ciao
Stephan


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

* Re: [PATCH v4 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm
  2020-12-11  6:30 ` [PATCH v4 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm Meng Yu
@ 2020-12-11 14:14   ` Stephan Mueller
       [not found]     ` <e6bf72e0-38cd-a17e-ecae-e6fabdb313eb@huawei.com>
  0 siblings, 1 reply; 15+ messages in thread
From: Stephan Mueller @ 2020-12-11 14:14 UTC (permalink / raw)
  To: Meng Yu, herbert, davem; +Cc: linux-crypto, xuzaibo, wangzhou1, linux-kernel

Am Freitag, den 11.12.2020, 14:30 +0800 schrieb Meng Yu:
>   
> +/* curve25519 */
> +static u64 curve25519_g_x[] = { 0x0000000000000009, 0x0000000000000000,
> +                               0x0000000000000000, 0x0000000000000000 };
> +static u64 curve25519_p[] = { 0xffffffffffffffed, 0xffffffffffffffff,
> +                               0xffffffffffffffff, 0x7fffffffffffffff };
> +static u64 curve25519_a[] = { 0x000000000001DB41, 0x0000000000000000,
> +                               0x0000000000000000, 0x0000000000000000 };
> +static const struct ecc_curve ecc_25519 = {
> +       .name = "curve25519",
> +       .g = {
> +               .x = curve25519_g_x,
> +               .ndigits = 4,
> +       },
> +       .p = curve25519_p,
> +       .a = curve25519_a,
> +};

With this definition, I am not sure whether ecc_is_pubkey_valid_partial would
work correctly. At least it *seems* that there would be a NULL-pointer
dereference in vli_add with the undefined .b value. Did you test and can you
confirm?

Thanks
Stephan



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

* Re: Fwd: Re: [PATCH v4 3/5] crypto: expose elliptic curve parameters as Crypto APIs
       [not found]     ` <75a25392-464d-b76e-ba92-4287e24acbf7@huawei.com>
@ 2020-12-16  2:32       ` yumeng
  0 siblings, 0 replies; 15+ messages in thread
From: yumeng @ 2020-12-16  2:32 UTC (permalink / raw)
  To: Vitaly Chikunov
  Cc: herbert, davem, linux-crypto, xuzaibo, wangzhou1, linux-kernel


> Meng,
> 
> It looks like not just definitions but some static data is moved to
> includes. Why?
> 
> Thanks,

Yes, as both 'crypto' and HPRE use elliptic curves parameters, once
we keep them in 'include/crypto/ecc_curve_defs.h', crypto drivers
can use curves parameters without redefining them.

Thanks,


> On Fri, Dec 11, 2020 at 02:30:32PM +0800, Meng Yu wrote:
>> Move elliptic curves definition to 'include/crypto/ecc_curve_defs.h',
>> so all can use it,
>> 
>> Signed-off-by: Meng Yu <yumeng18@huawei.com>
>> Reviewed-by: Zaibo Xu <xuzaibo@huawei.com>
>> ---
>>  crypto/ecc.c                    |  1 -
>>  crypto/ecc.h                    | 37 +----------------
>>  crypto/ecc_curve_defs.h         | 57 -------------------------
>>  crypto/ecrdsa_defs.h            |  2 +-
>>  include/crypto/ecc_curve_defs.h | 92 +++++++++++++++++++++++++++++++++++++++++
>>  5 files changed, 95 insertions(+), 94 deletions(-)
>>  delete mode 100644 crypto/ecc_curve_defs.h
>>  create mode 100644 include/crypto/ecc_curve_defs.h
>> 
>> diff --git a/crypto/ecc.c b/crypto/ecc.c
>> index c80aa25..f23efdd 100644
>> --- a/crypto/ecc.c
>> +++ b/crypto/ecc.c
>> @@ -35,7 +35,6 @@
>>  #include <linux/ratelimit.h>
>>  
>>  #include "ecc.h"
>> -#include "ecc_curve_defs.h"
>>  
>>  typedef struct {
>>  	u64 m_low;
>> diff --git a/crypto/ecc.h b/crypto/ecc.h
>> index d4e546b..e5afaf3 100644
>> --- a/crypto/ecc.h
>> +++ b/crypto/ecc.h
>> @@ -26,6 +26,8 @@
>>  #ifndef _CRYPTO_ECC_H
>>  #define _CRYPTO_ECC_H
>>  
>> +#include <crypto/ecc_curve_defs.h>
>> +
>>  /* One digit is u64 qword. */
>>  #define ECC_CURVE_NIST_P192_DIGITS  3
>>  #define ECC_CURVE_NIST_P256_DIGITS  4
>> @@ -33,44 +35,9 @@
>>  
>>  #define ECC_DIGITS_TO_BYTES_SHIFT 3
>>  
>> -/**
>> - * struct ecc_point - elliptic curve point in affine coordinates
>> - *
>> - * @x:		X coordinate in vli form.
>> - * @y:		Y coordinate in vli form.
>> - * @ndigits:	Length of vlis in u64 qwords.
>> - */
>> -struct ecc_point {
>> -	u64 *x;
>> -	u64 *y;
>> -	u8 ndigits;
>> -};
>> -
>>  #define ECC_POINT_INIT(x, y, ndigits)	(struct ecc_point) { x, y, ndigits }
>>  
>>  /**
>> - * struct ecc_curve - definition of elliptic curve
>> - *
>> - * @name:	Short name of the curve.
>> - * @g:		Generator point of the curve.
>> - * @p:		Prime number, if Barrett's reduction is used for this curve
>> - *		pre-calculated value 'mu' is appended to the @p after ndigits.
>> - *		Use of Barrett's reduction is heuristically determined in
>> - *		vli_mmod_fast().
>> - * @n:		Order of the curve group.
>> - * @a:		Curve parameter a.
>> - * @b:		Curve parameter b.
>> - */
>> -struct ecc_curve {
>> -	char *name;
>> -	struct ecc_point g;
>> -	u64 *p;
>> -	u64 *n;
>> -	u64 *a;
>> -	u64 *b;
>> -};
>> -
>> -/**
>>   * ecc_is_key_valid() - Validate a given ECDH private key
>>   *
>>   * @curve_id:		id representing the curve to use
>> diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
>> deleted file mode 100644
>> index 69be6c7..0000000
>> --- a/crypto/ecc_curve_defs.h
>> +++ /dev/null
>> @@ -1,57 +0,0 @@
>> -/* SPDX-License-Identifier: GPL-2.0 */
>> -#ifndef _CRYTO_ECC_CURVE_DEFS_H
>> -#define _CRYTO_ECC_CURVE_DEFS_H
>> -
>> -/* NIST P-192: a = p - 3 */
>> -static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
>> -				0x188DA80EB03090F6ull };
>> -static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
>> -				0x07192B95FFC8DA78ull };
>> -static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
>> -				0xFFFFFFFFFFFFFFFFull };
>> -static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
>> -				0xFFFFFFFFFFFFFFFFull };
>> -static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
>> -				0xFFFFFFFFFFFFFFFFull };
>> -static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
>> -				0x64210519E59C80E7ull };
>> -static struct ecc_curve nist_p192 = {
>> -	.name = "nist_192",
>> -	.g = {
>> -		.x = nist_p192_g_x,
>> -		.y = nist_p192_g_y,
>> -		.ndigits = 3,
>> -	},
>> -	.p = nist_p192_p,
>> -	.n = nist_p192_n,
>> -	.a = nist_p192_a,
>> -	.b = nist_p192_b
>> -};
>> -
>> -/* NIST P-256: a = p - 3 */
>> -static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
>> -				0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
>> -static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
>> -				0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull };
>> -static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
>> -				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
>> -static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
>> -				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
>> -static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
>> -				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
>> -static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
>> -				0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
>> -static struct ecc_curve nist_p256 = {
>> -	.name = "nist_256",
>> -	.g = {
>> -		.x = nist_p256_g_x,
>> -		.y = nist_p256_g_y,
>> -		.ndigits = 4,
>> -	},
>> -	.p = nist_p256_p,
>> -	.n = nist_p256_n,
>> -	.a = nist_p256_a,
>> -	.b = nist_p256_b
>> -};
>> -
>> -#endif
>> diff --git a/crypto/ecrdsa_defs.h b/crypto/ecrdsa_defs.h
>> index 170baf0..2074099 100644
>> --- a/crypto/ecrdsa_defs.h
>> +++ b/crypto/ecrdsa_defs.h
>> @@ -13,7 +13,7 @@
>>  #ifndef _CRYTO_ECRDSA_DEFS_H
>>  #define _CRYTO_ECRDSA_DEFS_H
>>  
>> -#include "ecc.h"
>> +#include <crypto/ecc_curve_defs.h>
>>  
>>  #define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8)
>>  #define ECRDSA_MAX_DIGITS (512 / 64)
>> diff --git a/include/crypto/ecc_curve_defs.h b/include/crypto/ecc_curve_defs.h
>> new file mode 100644
>> index 0000000..1080766
>> --- /dev/null
>> +++ b/include/crypto/ecc_curve_defs.h
>> @@ -0,0 +1,92 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +#ifndef _CRYTO_ECC_CURVE_DEFS_H
>> +#define _CRYTO_ECC_CURVE_DEFS_H
>> +
>> +/**
>> + * struct ecc_point - elliptic curve point in affine coordinates
>> + *
>> + * @x:		X coordinate in vli form.
>> + * @y:		Y coordinate in vli form.
>> + * @ndigits:	Length of vlis in u64 qwords.
>> + */
>> +struct ecc_point {
>> +	u64 *x;
>> +	u64 *y;
>> +	u8 ndigits;
>> +};
>> +
>> +/**
>> + * struct ecc_curve - definition of elliptic curve
>> + *
>> + * @name:	Short name of the curve.
>> + * @g:		Generator point of the curve.
>> + * @p:		Prime number, if Barrett's reduction is used for this curve
>> + *		pre-calculated value 'mu' is appended to the @p after ndigits.
>> + *		Use of Barrett's reduction is heuristically determined in
>> + *		vli_mmod_fast().
>> + * @n:		Order of the curve group.
>> + * @a:		Curve parameter a.
>> + * @b:		Curve parameter b.
>> + */
>> +struct ecc_curve {
>> +	char *name;
>> +	struct ecc_point g;
>> +	u64 *p;
>> +	u64 *n;
>> +	u64 *a;
>> +	u64 *b;
>> +};
>> +
>> +/* NIST P-192: a = p - 3 */
>> +static u64 nist_p192_g_x[] = { 0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull,
>> +				0x188DA80EB03090F6ull };
>> +static u64 nist_p192_g_y[] = { 0x73F977A11E794811ull, 0x631011ED6B24CDD5ull,
>> +				0x07192B95FFC8DA78ull };
>> +static u64 nist_p192_p[] = { 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull,
>> +				0xFFFFFFFFFFFFFFFFull };
>> +static u64 nist_p192_n[] = { 0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull,
>> +				0xFFFFFFFFFFFFFFFFull };
>> +static u64 nist_p192_a[] = { 0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFFFFFFFFFEull,
>> +				0xFFFFFFFFFFFFFFFFull };
>> +static u64 nist_p192_b[] = { 0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull,
>> +				0x64210519E59C80E7ull };
>> +static struct ecc_curve nist_p192 = {
>> +	.name = "nist_192",
>> +	.g = {
>> +		.x = nist_p192_g_x,
>> +		.y = nist_p192_g_y,
>> +		.ndigits = 3,
>> +	},
>> +	.p = nist_p192_p,
>> +	.n = nist_p192_n,
>> +	.a = nist_p192_a,
>> +	.b = nist_p192_b
>> +};
>> +
>> +/* NIST P-256: a = p - 3 */
>> +static u64 nist_p256_g_x[] = { 0xF4A13945D898C296ull, 0x77037D812DEB33A0ull,
>> +				0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull };
>> +static u64 nist_p256_g_y[] = { 0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull,
>> +				0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull };
>> +static u64 nist_p256_p[] = { 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull,
>> +				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
>> +static u64 nist_p256_n[] = { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull,
>> +				0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull };
>> +static u64 nist_p256_a[] = { 0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull,
>> +				0x0000000000000000ull, 0xFFFFFFFF00000001ull };
>> +static u64 nist_p256_b[] = { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull,
>> +				0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull };
>> +static struct ecc_curve nist_p256 = {
>> +	.name = "nist_256",
>> +	.g = {
>> +		.x = nist_p256_g_x,
>> +		.y = nist_p256_g_y,
>> +		.ndigits = 4,
>> +	},
>> +	.p = nist_p256_p,
>> +	.n = nist_p256_n,
>> +	.a = nist_p256_a,
>> +	.b = nist_p256_b
>> +};
>> +
>> +#endif
>> -- 
>> 2.8.1
> .
> 

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

* Re: [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm
       [not found]     ` <3903e2e8-165f-51b5-056c-24b8ce52e842@huawei.com>
@ 2020-12-16  2:39       ` yumeng
  2020-12-16 20:10         ` Stephan Mueller
  0 siblings, 1 reply; 15+ messages in thread
From: yumeng @ 2020-12-16  2:39 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: linux-crypto, xuzaibo, wangzhou1, linux-kernel




> Am Freitag, den 11.12.2020, 14:30 +0800 schrieb Meng Yu:
>> 
>> +/* size in bytes of the n prime */
>> +#define HPRE_ECC_NIST_P128_N_SIZE      16
> 
> Do we truly need P-128? Besides, I do not see that curve being defined in
> contemporary cipher specs.
> 
>> +#define HPRE_ECC_NIST_P192_N_SIZE      24
>> +#define HPRE_ECC_NIST_P224_N_SIZE      28
>> +#define HPRE_ECC_NIST_P256_N_SIZE      32
>> +#define HPRE_ECC_NIST_P320_N_SIZE      40
> 
> Do we truly need P-320? Besides, I do not see that curve being defined in
> contemporary cipher specs.

Yes, in rfc 5903, only P-256, P-384 and P-521 is defined, but in
'rfc5639' and  "SEC 2: Recommended Elliptic Curve Domain Parameters",
other curves like P-128, P-192, P-224, and P-320 curve parameters are
found, and they are used in 'openssl';
How about your idea?

Thanks,


>> +#define HPRE_ECC_NIST_P384_N_SIZE      48
>> +#define HPRE_ECC_NIST_P521_N_SIZE      66
>> +
>> +/* size in bytes */
>> +#define HPRE_ECC_HW256_KSZ_B   32
>> +#define HPRE_ECC_HW384_KSZ_B   48
>> +#define HPRE_ECC_HW576_KSZ_B   72
>> +
>> +#define HPRE_ECDH_MAX_SZ       HPRE_ECC_HW576_KSZ_B]
> 
> Ciao
> Stephan
> 
> .
> 

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

* Re: [PATCH v4 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm
       [not found]     ` <e6bf72e0-38cd-a17e-ecae-e6fabdb313eb@huawei.com>
@ 2020-12-16  2:45       ` yumeng
  0 siblings, 0 replies; 15+ messages in thread
From: yumeng @ 2020-12-16  2:45 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: linux-crypto, xuzaibo, wangzhou1, linux-kernel


> Am Freitag, den 11.12.2020, 14:30 +0800 schrieb Meng Yu:
>>   
>> +/* curve25519 */
>> +static u64 curve25519_g_x[] = { 0x0000000000000009, 0x0000000000000000,
>> +                               0x0000000000000000, 0x0000000000000000 };
>> +static u64 curve25519_p[] = { 0xffffffffffffffed, 0xffffffffffffffff,
>> +                               0xffffffffffffffff, 0x7fffffffffffffff };
>> +static u64 curve25519_a[] = { 0x000000000001DB41, 0x0000000000000000,
>> +                               0x0000000000000000, 0x0000000000000000 };
>> +static const struct ecc_curve ecc_25519 = {
>> +       .name = "curve25519",
>> +       .g = {
>> +               .x = curve25519_g_x,
>> +               .ndigits = 4,
>> +       },
>> +       .p = curve25519_p,
>> +       .a = curve25519_a,
>> +};
> 
> With this definition, I am not sure whether ecc_is_pubkey_valid_partial would
> work correctly. At least it *seems* that there would be a NULL-pointer
> dereference in vli_add with the undefined .b value. Did you test and can you
> confirm?
> 
> Thanks
> Stephan
> 

'static const struct ecc_curve ecc_25519' is curve25519's parameters,
only used in 'curve25519', not used by 'ECDH';

Thanks,

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

* Re: [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm
  2020-12-16  2:39       ` yumeng
@ 2020-12-16 20:10         ` Stephan Mueller
  2020-12-17  3:07           ` yumeng
  0 siblings, 1 reply; 15+ messages in thread
From: Stephan Mueller @ 2020-12-16 20:10 UTC (permalink / raw)
  To: yumeng; +Cc: linux-crypto, xuzaibo, wangzhou1, linux-kernel

Am Mittwoch, dem 16.12.2020 um 10:39 +0800 schrieb yumeng:
> 
> 
> 
> > Am Freitag, den 11.12.2020, 14:30 +0800 schrieb Meng Yu:
> > > 
> > > +/* size in bytes of the n prime */
> > > +#define HPRE_ECC_NIST_P128_N_SIZE      16
> > 
> > Do we truly need P-128? Besides, I do not see that curve being defined in
> > contemporary cipher specs.
> > 
> > > +#define HPRE_ECC_NIST_P192_N_SIZE      24
> > > +#define HPRE_ECC_NIST_P224_N_SIZE      28
> > > +#define HPRE_ECC_NIST_P256_N_SIZE      32
> > > +#define HPRE_ECC_NIST_P320_N_SIZE      40
> > 
> > Do we truly need P-320? Besides, I do not see that curve being defined in
> > contemporary cipher specs.
> 
> Yes, in rfc 5903, only P-256, P-384 and P-521 is defined, but in
> 'rfc5639' and  "SEC 2: Recommended Elliptic Curve Domain Parameters",
> other curves like P-128, P-192, P-224, and P-320 curve parameters are
> found, and they are used in 'openssl';
> How about your idea?

Who is going to use that curve considering that common protocols that are
implemented in the kernel do not use it?

Thanks
Stephan


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

* Re: [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm
  2020-12-16 20:10         ` Stephan Mueller
@ 2020-12-17  3:07           ` yumeng
  2020-12-19 21:25             ` Stephan Müller
  0 siblings, 1 reply; 15+ messages in thread
From: yumeng @ 2020-12-17  3:07 UTC (permalink / raw)
  To: Stephan Mueller; +Cc: linux-crypto, xuzaibo, wangzhou1, linux-kernel



在 2020/12/17 4:10, Stephan Mueller 写道:
> Am Mittwoch, dem 16.12.2020 um 10:39 +0800 schrieb yumeng:
>>
>>
>>
>>> Am Freitag, den 11.12.2020, 14:30 +0800 schrieb Meng Yu:
>>>>
>>>> +/* size in bytes of the n prime */
>>>> +#define HPRE_ECC_NIST_P128_N_SIZE      16
>>>
>>> Do we truly need P-128? Besides, I do not see that curve being defined in
>>> contemporary cipher specs.
>>>
>>>> +#define HPRE_ECC_NIST_P192_N_SIZE      24
>>>> +#define HPRE_ECC_NIST_P224_N_SIZE      28
>>>> +#define HPRE_ECC_NIST_P256_N_SIZE      32
>>>> +#define HPRE_ECC_NIST_P320_N_SIZE      40
>>>
>>> Do we truly need P-320? Besides, I do not see that curve being defined in
>>> contemporary cipher specs.
>>
>> Yes, in rfc 5903, only P-256, P-384 and P-521 is defined, but in
>> 'rfc5639' and  "SEC 2: Recommended Elliptic Curve Domain Parameters",
>> other curves like P-128, P-192, P-224, and P-320 curve parameters are
>> found, and they are used in 'openssl';
>> How about your idea?
> 
> Who is going to use that curve considering that common protocols that are
> implemented in the kernel do not use it?
> 
> Thanks
> Stephan
> 

I see in "SEC 2: Recommended Elliptic Curve Domain ParametersVersion2.0"
that 'Recommend Elliptic Curve Domain Parameters over Fp' are secp192,
secp224, secp256, secp384, and secp521, secp128 and secp320 are not
recommended.
So you mean it's better not to include secp128 and secp320, right?

Thanks,


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

* Re: [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm
  2020-12-17  3:07           ` yumeng
@ 2020-12-19 21:25             ` Stephan Müller
  0 siblings, 0 replies; 15+ messages in thread
From: Stephan Müller @ 2020-12-19 21:25 UTC (permalink / raw)
  To: yumeng; +Cc: linux-crypto, xuzaibo, wangzhou1, linux-kernel

Am Donnerstag, 17. Dezember 2020, 04:07:30 CET schrieb yumeng:

Hi yumeng,

> 
> I see in "SEC 2: Recommended Elliptic Curve Domain ParametersVersion2.0"
> that 'Recommend Elliptic Curve Domain Parameters over Fp' are secp192,
> secp224, secp256, secp384, and secp521, secp128 and secp320 are not
> recommended.
> So you mean it's better not to include secp128 and secp320, right?

Precisely because I do not see the use case in the kernel.
> 
> Thanks,


Ciao
Stephan



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

end of thread, other threads:[~2020-12-19 21:31 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-11  6:30 [PATCH v4 0/5] add ECDH and CURVE25519 algorithms support for Kunpeng 930 Meng Yu
2020-12-11  6:30 ` [PATCH v4 1/5] crypto: hisilicon/hpre - add some updates to adapt to " Meng Yu
2020-12-11  6:30 ` [PATCH v4 2/5] crypto: hisilicon/hpre - add algorithm type Meng Yu
2020-12-11  6:30 ` [PATCH v4 3/5] crypto: expose elliptic curve parameters as Crypto APIs Meng Yu
2020-12-11 13:13   ` Vitaly Chikunov
     [not found]     ` <75a25392-464d-b76e-ba92-4287e24acbf7@huawei.com>
2020-12-16  2:32       ` Fwd: " yumeng
2020-12-11  6:30 ` [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm Meng Yu
2020-12-11 14:08   ` Stephan Mueller
     [not found]     ` <3903e2e8-165f-51b5-056c-24b8ce52e842@huawei.com>
2020-12-16  2:39       ` yumeng
2020-12-16 20:10         ` Stephan Mueller
2020-12-17  3:07           ` yumeng
2020-12-19 21:25             ` Stephan Müller
2020-12-11  6:30 ` [PATCH v4 5/5] crypto: hisilicon/hpre - add 'CURVE25519' algorithm Meng Yu
2020-12-11 14:14   ` Stephan Mueller
     [not found]     ` <e6bf72e0-38cd-a17e-ecae-e6fabdb313eb@huawei.com>
2020-12-16  2:45       ` yumeng

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