[PATCH v2 5/7] crypto: move common code in sm2 to ec_mpi.c and ec_mpi.h

From: Hongbo Li
Date: Thu May 27 2021 - 09:55:00 EST


From: Hongbo Li <herberthbli@xxxxxxxxxxx>

Some structs and functions in sm2 are common codes, and could be
used by the following eddsa patch. So move them to common files:
ec_mpi.c and ec_mpi.h.

Signed-off-by: Hongbo Li <herberthbli@xxxxxxxxxxx>
---
crypto/Kconfig | 4 ++
crypto/Makefile | 1 +
crypto/ec_mpi.c | 82 +++++++++++++++++++++++++++++++++++++++++
crypto/ec_mpi.h | 37 +++++++++++++++++++
crypto/sm2.c | 98 ++-----------------------------------------------
5 files changed, 127 insertions(+), 95 deletions(-)
create mode 100644 crypto/ec_mpi.c
create mode 100644 crypto/ec_mpi.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 4a0d1876aadb..75ae7d3f6f92 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -265,6 +265,9 @@ config CRYPTO_ECRDSA
standard algorithms (called GOST algorithms). Only signature verification
is implemented.

+config CRYPTO_EC_MPI
+ tristate
+
config CRYPTO_SM2
tristate "SM2 algorithm"
select CRYPTO_SM3
@@ -272,6 +275,7 @@ config CRYPTO_SM2
select CRYPTO_MANAGER
select MPILIB
select ASN1
+ select CRYPTO_EC_MPI
help
Generic implementation of the SM2 public key algorithm. It was
published by State Encryption Management Bureau, China.
diff --git a/crypto/Makefile b/crypto/Makefile
index 10526d4559b8..8afb39359776 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -177,6 +177,7 @@ obj-$(CONFIG_CRYPTO_OFB) += ofb.o
obj-$(CONFIG_CRYPTO_ECC) += ecc.o
obj-$(CONFIG_CRYPTO_ESSIV) += essiv.o
obj-$(CONFIG_CRYPTO_CURVE25519) += curve25519-generic.o
+obj-$(CONFIG_CRYPTO_EC_MPI) += ec_mpi.o

ecdh_generic-y += ecdh.o
ecdh_generic-y += ecdh_helper.o
diff --git a/crypto/ec_mpi.c b/crypto/ec_mpi.c
new file mode 100644
index 000000000000..a537e6fc713f
--- /dev/null
+++ b/crypto/ec_mpi.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * EC MPI common functions.
+ *
+ * Copyright (c) 2020, Alibaba Group.
+ * Authors: Tianjia Zhang <tianjia.zhang@xxxxxxxxxxxxxxxxx>
+ */
+
+#include <linux/module.h>
+#include <linux/mpi.h>
+#include "ec_mpi.h"
+
+int ec_mpi_ctx_init(struct mpi_ec_ctx *ec, const struct ecc_domain_parms *ecp)
+{
+ MPI p, a, b;
+ MPI x, y;
+ int rc = -EINVAL;
+
+ p = mpi_scanval(ecp->p);
+ a = mpi_scanval(ecp->a);
+ b = mpi_scanval(ecp->b);
+ if (!p || !a || !b)
+ goto free_p;
+
+ x = mpi_scanval(ecp->g_x);
+ y = mpi_scanval(ecp->g_y);
+ if (!x || !y)
+ goto free;
+
+ rc = -ENOMEM;
+
+ ec->Q = mpi_point_new(0);
+ if (!ec->Q)
+ goto free;
+
+ /* mpi_ec_setup_elliptic_curve */
+ ec->G = mpi_point_new(0);
+ if (!ec->G) {
+ mpi_point_release(ec->Q);
+ goto free;
+ }
+
+ mpi_set(ec->G->x, x);
+ mpi_set(ec->G->y, y);
+ mpi_set_ui(ec->G->z, 1);
+
+ rc = -EINVAL;
+ ec->n = mpi_scanval(ecp->n);
+ if (!ec->n) {
+ mpi_point_release(ec->Q);
+ mpi_point_release(ec->G);
+ goto free;
+ }
+
+ ec->h = ecp->h;
+ ec->name = ecp->desc;
+ mpi_ec_init(ec, ecp->model, ecp->dialect, 0, p, a, b);
+
+ rc = 0;
+
+free:
+ mpi_free(x);
+ mpi_free(y);
+free_p:
+ mpi_free(p);
+ mpi_free(a);
+ mpi_free(b);
+
+ return rc;
+}
+EXPORT_SYMBOL(ec_mpi_ctx_init);
+
+void ec_mpi_ctx_deinit(struct mpi_ec_ctx *ec)
+{
+ mpi_ec_deinit(ec);
+
+ memset(ec, 0, sizeof(*ec));
+}
+EXPORT_SYMBOL(ec_mpi_ctx_deinit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tianjia Zhang <tianjia.zhang@xxxxxxxxxxxxxxxxx>");
diff --git a/crypto/ec_mpi.h b/crypto/ec_mpi.h
new file mode 100644
index 000000000000..e1f6d3aaeef9
--- /dev/null
+++ b/crypto/ec_mpi.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * EC MPI common structs.
+ *
+ * Copyright (c) 2020, Alibaba Group.
+ * Authors: Tianjia Zhang <tianjia.zhang@xxxxxxxxxxxxxxxxx>
+ */
+
+#include <linux/mpi.h>
+
+struct ecc_domain_parms {
+ const char *desc; /* Description of the curve. */
+ unsigned int nbits; /* Number of bits. */
+ unsigned int fips:1; /* True if this is a FIPS140-2 approved curve */
+
+ /* The model describing this curve. This is mainly used to select
+ * the group equation.
+ */
+ enum gcry_mpi_ec_models model;
+
+ /* The actual ECC dialect used. This is used for curve specific
+ * optimizations and to select encodings etc.
+ */
+ enum ecc_dialects dialect;
+
+ const char *p; /* The prime defining the field. */
+ const char *a, *b; /* The coefficients. For Twisted Edwards
+ * Curves b is used for d. For Montgomery
+ * Curves (a,b) has ((A-2)/4,B^-1).
+ */
+ const char *n; /* The order of the base point. */
+ const char *g_x, *g_y; /* Base point. */
+ unsigned int h; /* Cofactor. */
+};
+
+int ec_mpi_ctx_init(struct mpi_ec_ctx *ec, const struct ecc_domain_parms *ecp);
+void ec_mpi_ctx_deinit(struct mpi_ec_ctx *ec);
diff --git a/crypto/sm2.c b/crypto/sm2.c
index db8a4a265669..ea1676ba1a9a 100644
--- a/crypto/sm2.c
+++ b/crypto/sm2.c
@@ -9,42 +9,17 @@
*/

#include <linux/module.h>
-#include <linux/mpi.h>
#include <crypto/internal/akcipher.h>
#include <crypto/akcipher.h>
#include <crypto/hash.h>
#include <crypto/sm3_base.h>
#include <crypto/rng.h>
#include <crypto/sm2.h>
+#include "ec_mpi.h"
#include "sm2signature.asn1.h"

#define MPI_NBYTES(m) ((mpi_get_nbits(m) + 7) / 8)

-struct ecc_domain_parms {
- const char *desc; /* Description of the curve. */
- unsigned int nbits; /* Number of bits. */
- unsigned int fips:1; /* True if this is a FIPS140-2 approved curve */
-
- /* The model describing this curve. This is mainly used to select
- * the group equation.
- */
- enum gcry_mpi_ec_models model;
-
- /* The actual ECC dialect used. This is used for curve specific
- * optimizations and to select encodings etc.
- */
- enum ecc_dialects dialect;
-
- const char *p; /* The prime defining the field. */
- const char *a, *b; /* The coefficients. For Twisted Edwards
- * Curves b is used for d. For Montgomery
- * Curves (a,b) has ((A-2)/4,B^-1).
- */
- const char *n; /* The order of the base point. */
- const char *g_x, *g_y; /* Base point. */
- unsigned int h; /* Cofactor. */
-};
-
static const struct ecc_domain_parms sm2_ecp = {
.desc = "sm2p256v1",
.nbits = 256,
@@ -60,73 +35,6 @@ static const struct ecc_domain_parms sm2_ecp = {
.h = 1
};

-static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
-{
- const struct ecc_domain_parms *ecp = &sm2_ecp;
- MPI p, a, b;
- MPI x, y;
- int rc = -EINVAL;
-
- p = mpi_scanval(ecp->p);
- a = mpi_scanval(ecp->a);
- b = mpi_scanval(ecp->b);
- if (!p || !a || !b)
- goto free_p;
-
- x = mpi_scanval(ecp->g_x);
- y = mpi_scanval(ecp->g_y);
- if (!x || !y)
- goto free;
-
- rc = -ENOMEM;
-
- ec->Q = mpi_point_new(0);
- if (!ec->Q)
- goto free;
-
- /* mpi_ec_setup_elliptic_curve */
- ec->G = mpi_point_new(0);
- if (!ec->G) {
- mpi_point_release(ec->Q);
- goto free;
- }
-
- mpi_set(ec->G->x, x);
- mpi_set(ec->G->y, y);
- mpi_set_ui(ec->G->z, 1);
-
- rc = -EINVAL;
- ec->n = mpi_scanval(ecp->n);
- if (!ec->n) {
- mpi_point_release(ec->Q);
- mpi_point_release(ec->G);
- goto free;
- }
-
- ec->h = ecp->h;
- ec->name = ecp->desc;
- mpi_ec_init(ec, ecp->model, ecp->dialect, 0, p, a, b);
-
- rc = 0;
-
-free:
- mpi_free(x);
- mpi_free(y);
-free_p:
- mpi_free(p);
- mpi_free(a);
- mpi_free(b);
-
- return rc;
-}
-
-static void sm2_ec_ctx_deinit(struct mpi_ec_ctx *ec)
-{
- mpi_ec_deinit(ec);
-
- memset(ec, 0, sizeof(*ec));
-}
-
/* RESULT must have been initialized and is set on success to the
* point given by VALUE.
*/
@@ -416,14 +324,14 @@ static int sm2_init_tfm(struct crypto_akcipher *tfm)
{
struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);

- return sm2_ec_ctx_init(ec);
+ return ec_mpi_ctx_init(ec, &sm2_ecp);
}

static void sm2_exit_tfm(struct crypto_akcipher *tfm)
{
struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);

- sm2_ec_ctx_deinit(ec);
+ ec_mpi_ctx_deinit(ec);
}

static struct akcipher_alg sm2 = {
--
2.27.0