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 4a0d187..75ae7d3 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 10526d4..8afb393 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 0000000..a537e6f --- /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 0000000..e1f6d3aa --- /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 db8a4a2..ea1676b 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 @@ struct ecc_domain_parms { .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 = { -- 1.8.3.1