All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
@ 2023-11-09  9:47 LeoLiu-oc
  2023-11-09 15:00 ` Dave Hansen
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: LeoLiu-oc @ 2023-11-09  9:47 UTC (permalink / raw)
  To: herbert, davem, tglx, mingo, bp, dave.hansen, x86, hpa, seanjc,
	kim.phillips, pbonzini, babu.moger, jiaxi.chen, jmattson,
	pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu, LeoLiuoc

From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>

Add support for SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI
Instruction. The purpose of this driver is to ensure that the application
has both high performance and high security.

Signed-off-by: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
---
 arch/x86/crypto/Kconfig                |  11 ++
 arch/x86/crypto/Makefile               |   3 +
 arch/x86/crypto/sm2-zhaoxin-gmi_asm.S  |  59 ++++++++++
 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c | 145 +++++++++++++++++++++++++
 arch/x86/include/asm/cpufeatures.h     |   2 +
 5 files changed, 220 insertions(+)
 create mode 100644 arch/x86/crypto/sm2-zhaoxin-gmi_asm.S
 create mode 100644 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c

diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
index 9bbfd01cfa2f..a771a9da2abd 100644
--- a/arch/x86/crypto/Kconfig
+++ b/arch/x86/crypto/Kconfig
@@ -519,4 +519,15 @@ config CRYPTO_CRCT10DIF_PCLMUL
 	  Architecture: x86_64 using:
 	  - PCLMULQDQ (carry-less multiplication)
 
+config CRYPTO_SM2_ZHAOXIN_GMI
+	tristate "SM2 Cipher algorithm (Zhaoxin GMI Instruction)"
+	depends on X86
+	select CRYPTO_AKCIPHER
+	select CRYPTO_MANAGER
+	help
+	  SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI Instruction
+
+	  Published by State Encryption Management Bureau, China,
+	  as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012.
+
 endmenu
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 9aa46093c91b..c23b328a3ecd 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -109,6 +109,9 @@ aria-aesni-avx2-x86_64-y := aria-aesni-avx2-asm_64.o aria_aesni_avx2_glue.o
 obj-$(CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64) += aria-gfni-avx512-x86_64.o
 aria-gfni-avx512-x86_64-y := aria-gfni-avx512-asm_64.o aria_gfni_avx512_glue.o
 
+obj-$(CONFIG_CRYPTO_SM2_ZHAOXIN_GMI) += sm2-zhaoxin-gmi.o
+sm2-zhaoxin-gmi-y := sm2-zhaoxin-gmi_asm.o sm2-zhaoxin-gmi_glue.o
+
 quiet_cmd_perlasm = PERLASM $@
       cmd_perlasm = $(PERL) $< > $@
 $(obj)/%.S: $(src)/%.pl FORCE
diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S b/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S
new file mode 100644
index 000000000000..4ee5194557a0
--- /dev/null
+++ b/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Zhaoxin GMI implementation of a SM2 function
+ *
+ * Copyright(c) 2023 Zhaoxin Semiconductor LTD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * Contact Information:
+ *  YunShen <YunShen@zhaoxin.com>
+ */
+#include <linux/linkage.h>
+
+#define KEY_PTR     %rdi /* 1st arg */
+#define HASH_PTR    %rsi /* 2nd arg */
+#define SIG_PTR     %rdx /* 3rd arg */
+#define SCRATCH_PTR %rcx /* 4rd arg */
+#define VER_RESULT  %rax /* ret     */
+
+.text
+.align 32
+###############################################################################
+# int zhaoxin_gmi_sm2_verify (
+#         unsigned char *key, /*key*/
+#         unsigned char *hash, /*hash*/
+#         unsigned char *sig, /*signature*/
+#         unsigned char *scratch /*8 kbytes scratch space*/
+#     );
+###############################################################################
+SYM_FUNC_START(zhaoxin_gmi_sm2_verify)
+	push %r12
+	push %rbx
+
+	mov HASH_PTR, %rax
+	mov KEY_PTR, %rbx
+	mov SIG_PTR, %r12
+	mov $8, %rdx
+	mov SCRATCH_PTR, %rsi
+	mov %r12, %rdi
+
+	.byte 0XF2
+	.byte 0X0F
+	.byte 0XA6
+	.byte 0XC0
+
+	mov %rcx, %rax
+
+	pop %rbx
+	pop %r12
+
+	RET
+SYM_FUNC_END(zhaoxin_gmi_sm2_verify)
diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
new file mode 100644
index 000000000000..4d0d18f68266
--- /dev/null
+++ b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SM2 asymmetric public-key algorithm
+ * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and
+ * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
+ *
+ * Copyright (c) 2023 Shanghai Zhaoxin Semiconductor LTD.
+ * Authors: YunShen <yunshen@zhaoxin.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mpi.h>
+#include <crypto/internal/akcipher.h>
+#include <crypto/akcipher.h>
+#include <crypto/sm2.h>
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define SCRATCH_SIZE (4 * 2048)
+
+asmlinkage int zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash, unsigned char *sig,
+				unsigned char *scratch);
+
+struct sm2_cipher_data {
+	u8 pub_key[65]; /* public key */
+};
+
+/* Load supported features of the CPU to see if the SM2 is available. */
+static int zhaoxin_gmi_available(void)
+{
+	if (!boot_cpu_has(X86_FEATURE_SM2_EN)) {
+		pr_err("can't enable hardware SM2 if Zhaoxin GMI SM2 is not enabled\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+/* Zhaoxin sm2 verify function */
+static int _zhaoxin_sm2_verify(struct sm2_cipher_data *ec, unsigned char *hash, unsigned char *sig)
+{
+	int ret = -EKEYREJECTED;
+	uint64_t f_ok = 0;
+	unsigned char *scratch = kzalloc(SCRATCH_SIZE, GFP_KERNEL);
+
+	f_ok = zhaoxin_gmi_sm2_verify(ec->pub_key, hash, sig, scratch);
+	if (f_ok == 1)
+		ret = 0;
+
+	kfree(scratch);
+
+	return ret;
+}
+
+static int zhaoxin_sm2_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+	unsigned char *buffer;
+	int ret;
+
+	buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	sg_pcopy_to_buffer(req->src, sg_nents_for_len(req->src, req->src_len + req->dst_len),
+		buffer, req->src_len + req->dst_len, 0);
+
+	ret = _zhaoxin_sm2_verify(ec, buffer + req->src_len, buffer);
+	kfree(buffer);
+
+	return ret;
+}
+
+static int zhaoxin_sm2_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+				unsigned int keylen)
+{
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+
+	memcpy(ec->pub_key, key, keylen);
+
+	return 0;
+}
+
+static unsigned int zhaoxin_sm2_max_size(struct crypto_akcipher *tfm)
+{
+	/* Unlimited max size */
+	return PAGE_SIZE;
+}
+
+static int zhaoxin_sm2_init_tfm(struct crypto_akcipher *tfm)
+{
+	return zhaoxin_gmi_available();
+}
+
+static void zhaoxin_sm2_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+
+	memset(ec, 0, sizeof(*ec));
+}
+
+static struct akcipher_alg zhaoxin_sm2 = {
+	.verify = zhaoxin_sm2_verify,
+	.set_pub_key = zhaoxin_sm2_set_pub_key,
+	.max_size = zhaoxin_sm2_max_size,
+	.init = zhaoxin_sm2_init_tfm,
+	.exit = zhaoxin_sm2_exit_tfm,
+	.base = {
+		.cra_name = "sm2",
+		.cra_driver_name = "zhaoxin-gmi-sm2",
+		.cra_priority = 150,
+		.cra_module = THIS_MODULE,
+		.cra_ctxsize = sizeof(struct sm2_cipher_data),
+	},
+};
+
+static const struct x86_cpu_id zhaoxin_sm2_cpu_ids[] = {
+	X86_MATCH_FEATURE(X86_FEATURE_SM2, NULL),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, zhaoxin_sm2_cpu_ids);
+
+static int __init zhaoxin_sm2_init(void)
+{
+	if (!x86_match_cpu(zhaoxin_sm2_cpu_ids)) {
+		pr_err("The CPU isn't support hardware SM2.\n");
+		return -ENODEV;
+	}
+
+	return crypto_register_akcipher(&zhaoxin_sm2);
+}
+
+static void __exit zhaoxin_sm2_exit(void)
+{
+	crypto_unregister_akcipher(&zhaoxin_sm2);
+}
+
+module_init(zhaoxin_sm2_init);
+module_exit(zhaoxin_sm2_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("YunShen <yunshen@zhaoxin.com>");
+MODULE_DESCRIPTION("SM2 Zhaoxin GMI Algorithm");
+MODULE_ALIAS_CRYPTO("zhaoxin-gmi-sm2");
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 4af140cf5719..07a78ec83bed 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -146,6 +146,8 @@
 #define X86_FEATURE_HYPERVISOR		( 4*32+31) /* Running on a hypervisor */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+#define X86_FEATURE_SM2			(5*32 + 0) /* SM2 ZhaoXin GMI present */
+#define X86_FEATURE_SM2_EN			(5*32 + 1) /* SM2 ZhaoXin GMI enabled */
 #define X86_FEATURE_XSTORE		( 5*32+ 2) /* "rng" RNG present (xstore) */
 #define X86_FEATURE_XSTORE_EN		( 5*32+ 3) /* "rng_en" RNG enabled */
 #define X86_FEATURE_XCRYPT		( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
-- 
2.34.1


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

* Re: [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-09  9:47 [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation LeoLiu-oc
@ 2023-11-09 15:00 ` Dave Hansen
  2023-11-15  2:05   ` LeoLiu-oc
  2023-11-10 14:27 ` kernel test robot
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Dave Hansen @ 2023-11-09 15:00 UTC (permalink / raw)
  To: LeoLiu-oc, herbert, davem, tglx, mingo, bp, dave.hansen, x86,
	hpa, seanjc, kim.phillips, pbonzini, babu.moger, jiaxi.chen,
	jmattson, pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu

On 11/9/23 01:47, LeoLiu-oc wrote:
...
> diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
> index 9bbfd01cfa2f..a771a9da2abd 100644
> --- a/arch/x86/crypto/Kconfig
> +++ b/arch/x86/crypto/Kconfig
> @@ -519,4 +519,15 @@ config CRYPTO_CRCT10DIF_PCLMUL
>  	  Architecture: x86_64 using:
>  	  - PCLMULQDQ (carry-less multiplication)
>  
> +config CRYPTO_SM2_ZHAOXIN_GMI
> +	tristate "SM2 Cipher algorithm (Zhaoxin GMI Instruction)"
> +	depends on X86

Why does this not have "depends on CPU_SUP_ZHAOXIN"?

Also, the assembly in here looks suspiciously like x86_64 assembly.
How, exactly, does this build when !X86_64?

> +	select CRYPTO_AKCIPHER
> +	select CRYPTO_MANAGER
> +	help
> +	  SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI Instruction
> +
> +	  Published by State Encryption Management Bureau, China,
> +	  as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012.
> +
>  endmenu
> diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
> index 9aa46093c91b..c23b328a3ecd 100644
> --- a/arch/x86/crypto/Makefile
> +++ b/arch/x86/crypto/Makefile
> @@ -109,6 +109,9 @@ aria-aesni-avx2-x86_64-y := aria-aesni-avx2-asm_64.o aria_aesni_avx2_glue.o
>  obj-$(CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64) += aria-gfni-avx512-x86_64.o
>  aria-gfni-avx512-x86_64-y := aria-gfni-avx512-asm_64.o aria_gfni_avx512_glue.o
>  
> +obj-$(CONFIG_CRYPTO_SM2_ZHAOXIN_GMI) += sm2-zhaoxin-gmi.o
> +sm2-zhaoxin-gmi-y := sm2-zhaoxin-gmi_asm.o sm2-zhaoxin-gmi_glue.o
> +
>  quiet_cmd_perlasm = PERLASM $@
>        cmd_perlasm = $(PERL) $< > $@
>  $(obj)/%.S: $(src)/%.pl FORCE
> diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S b/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S
> new file mode 100644
> index 000000000000..4ee5194557a0
> --- /dev/null
> +++ b/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S
> @@ -0,0 +1,59 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Zhaoxin GMI implementation of a SM2 function
> + *
> + * Copyright(c) 2023 Zhaoxin Semiconductor LTD.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of version 2 of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + *
> + * Contact Information:
> + *  YunShen <YunShen@zhaoxin.com>
> + */

I thought we were using SPDX instead of blown-up license text now.  Why
does this need the GPLv2 blurb?

> +#include <linux/linkage.h>
> +
> +#define KEY_PTR     %rdi /* 1st arg */
> +#define HASH_PTR    %rsi /* 2nd arg */
> +#define SIG_PTR     %rdx /* 3rd arg */
> +#define SCRATCH_PTR %rcx /* 4rd arg */
> +#define VER_RESULT  %rax /* ret     */
> +
> +.text
> +.align 32
> +###############################################################################
> +# int zhaoxin_gmi_sm2_verify (
> +#         unsigned char *key, /*key*/
> +#         unsigned char *hash, /*hash*/
> +#         unsigned char *sig, /*signature*/
> +#         unsigned char *scratch /*8 kbytes scratch space*/
> +#     );
> +###############################################################################

This comment is just a waste of space.  The types here are completely
uninformative and the comments:

	unsigned char *key, /*key*/

are, um, equally uninformative considering the #defines above.

> +SYM_FUNC_START(zhaoxin_gmi_sm2_verify)
> +	push %r12
> +	push %rbx

Please mention that these are callee-saved registers that the
instruction will clobber.

> +	mov HASH_PTR, %rax
> +	mov KEY_PTR, %rbx
> +	mov SIG_PTR, %r12
> +	mov $8, %rdx
> +	mov SCRATCH_PTR, %rsi
> +	mov %r12, %rdi
> +
> +	.byte 0XF2
> +	.byte 0X0F
> +	.byte 0XA6
> +	.byte 0XC0

Please look around the codebase and see what folks do with assembly for
instructions that might not be supported in the assembler.  There's an
existing standard here.

> +	mov %rcx, %rax
> +
> +	pop %rbx
> +	pop %r12
> +
> +	RET
> +SYM_FUNC_END(zhaoxin_gmi_sm2_verify)
> diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
> new file mode 100644
> index 000000000000..4d0d18f68266
> --- /dev/null
> +++ b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
> @@ -0,0 +1,145 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * SM2 asymmetric public-key algorithm
> + * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and
> + * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
> + *
> + * Copyright (c) 2023 Shanghai Zhaoxin Semiconductor LTD.
> + * Authors: YunShen <yunshen@zhaoxin.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/mpi.h>
> +#include <crypto/internal/akcipher.h>
> +#include <crypto/akcipher.h>
> +#include <crypto/sm2.h>
> +#include <asm/cpufeature.h>
> +#include <asm/processor.h>
> +#include <asm/cpu_device_id.h>
> +
> +#define SCRATCH_SIZE (4 * 2048)
> +
> +asmlinkage int zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash, unsigned char *sig,
> +				unsigned char *scratch);
> +
> +struct sm2_cipher_data {
> +	u8 pub_key[65]; /* public key */
> +};
> +
> +/* Load supported features of the CPU to see if the SM2 is available. */
> +static int zhaoxin_gmi_available(void)
> +{
> +	if (!boot_cpu_has(X86_FEATURE_SM2_EN)) {
> +		pr_err("can't enable hardware SM2 if Zhaoxin GMI SM2 is not enabled\n");
> +		return -ENODEV;
> +	}
> +	return 0;
> +}

How can this code even be reached if X86_FEATURE_SM2_EN is clear?  How
will the cipher even get registered?

> +/* Zhaoxin sm2 verify function */
> +static int _zhaoxin_sm2_verify(struct sm2_cipher_data *ec, unsigned char *hash, unsigned char *sig)
> +{
> +	int ret = -EKEYREJECTED;
> +	uint64_t f_ok = 0;

This is an odd type choice since this is far from a user/kernel ABI and
also the zhaoxin_gmi_sm2_verify() declared return type is 'int'.

> +	unsigned char *scratch = kzalloc(SCRATCH_SIZE, GFP_KERNEL);
> +
> +	f_ok = zhaoxin_gmi_sm2_verify(ec->pub_key, hash, sig, scratch);
> +	if (f_ok == 1)
> +		ret = 0;
> +
> +	kfree(scratch);
> +
> +	return ret;
> +}
> +
> +static int zhaoxin_sm2_verify(struct akcipher_request *req)
> +{
> +	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
> +	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
> +	unsigned char *buffer;
> +	int ret;
> +
> +	buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL);
> +	if (!buffer)
> +		return -ENOMEM;
> +
> +	sg_pcopy_to_buffer(req->src, sg_nents_for_len(req->src, req->src_len + req->dst_len),
> +		buffer, req->src_len + req->dst_len, 0);

While sg_pcopy_to_buffer() calls in general seem
readablility-challenged, this one in particular is pretty bad.  Please
break this up logically (one line per argument seems commonplace) or use
some helper intermediate variables.  I do notice that 'req->src_len +
req->dst_len' is repeated quite a few times in this function, for instance.

> +	ret = _zhaoxin_sm2_verify(ec, buffer + req->src_len, buffer);
> +	kfree(buffer);
> +
> +	return ret;
> +}
> +
> +static int zhaoxin_sm2_set_pub_key(struct crypto_akcipher *tfm, const void *key,
> +				unsigned int keylen)
> +{
> +	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
> +
> +	memcpy(ec->pub_key, key, keylen);
> +
> +	return 0;
> +}
> +
> +static unsigned int zhaoxin_sm2_max_size(struct crypto_akcipher *tfm)
> +{
> +	/* Unlimited max size */
> +	return PAGE_SIZE;
> +}

I don't know the crypto API well, but does this mean that for every 4k
of data that this code deals with, it needs to kmalloc()/kfree() 8k?

> +static int zhaoxin_sm2_init_tfm(struct crypto_akcipher *tfm)
> +{
> +	return zhaoxin_gmi_available();
> +}
> +
> +static void zhaoxin_sm2_exit_tfm(struct crypto_akcipher *tfm)
> +{
> +	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
> +
> +	memset(ec, 0, sizeof(*ec));
> +}
> +
> +static struct akcipher_alg zhaoxin_sm2 = {
> +	.verify = zhaoxin_sm2_verify,
> +	.set_pub_key = zhaoxin_sm2_set_pub_key,
> +	.max_size = zhaoxin_sm2_max_size,
> +	.init = zhaoxin_sm2_init_tfm,
> +	.exit = zhaoxin_sm2_exit_tfm,
> +	.base = {
> +		.cra_name = "sm2",
> +		.cra_driver_name = "zhaoxin-gmi-sm2",
> +		.cra_priority = 150,
> +		.cra_module = THIS_MODULE,
> +		.cra_ctxsize = sizeof(struct sm2_cipher_data),
> +	},
> +};
> +
> +static const struct x86_cpu_id zhaoxin_sm2_cpu_ids[] = {
> +	X86_MATCH_FEATURE(X86_FEATURE_SM2, NULL),
> +	{}
> +};
> +MODULE_DEVICE_TABLE(x86cpu, zhaoxin_sm2_cpu_ids);
> +
> +static int __init zhaoxin_sm2_init(void)
> +{
> +	if (!x86_match_cpu(zhaoxin_sm2_cpu_ids)) {
> +		pr_err("The CPU isn't support hardware SM2.\n");
> +		return -ENODEV;
> +	}
> +
> +	return crypto_register_akcipher(&zhaoxin_sm2);
> +}

Again, please look around the code base.  There are a bunch of crypto
drivers that do checks like this.  *None* have a pr_err().  Few spew any
spam to dmesg.  Why does this one?

> +static void __exit zhaoxin_sm2_exit(void)
> +{
> +	crypto_unregister_akcipher(&zhaoxin_sm2);
> +}
> +
> +module_init(zhaoxin_sm2_init);
> +module_exit(zhaoxin_sm2_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("YunShen <yunshen@zhaoxin.com>");
> +MODULE_DESCRIPTION("SM2 Zhaoxin GMI Algorithm");
> +MODULE_ALIAS_CRYPTO("zhaoxin-gmi-sm2");
> diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
> index 4af140cf5719..07a78ec83bed 100644
> --- a/arch/x86/include/asm/cpufeatures.h
> +++ b/arch/x86/include/asm/cpufeatures.h
> @@ -146,6 +146,8 @@
>  #define X86_FEATURE_HYPERVISOR		( 4*32+31) /* Running on a hypervisor */
>  
>  /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
> +#define X86_FEATURE_SM2			(5*32 + 0) /* SM2 ZhaoXin GMI present */
> +#define X86_FEATURE_SM2_EN			(5*32 + 1) /* SM2 ZhaoXin GMI enabled */

Ahh, so I actually misread the two CPUID flags that got checked earlier.

What does it take to get "GMI enabled"?  How can it be present but not
enabled?


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

* Re: [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-09  9:47 [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation LeoLiu-oc
  2023-11-09 15:00 ` Dave Hansen
@ 2023-11-10 14:27 ` kernel test robot
  2023-11-15  7:17 ` [PATCH v2] " LeoLiu-oc
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 15+ messages in thread
From: kernel test robot @ 2023-11-10 14:27 UTC (permalink / raw)
  To: LeoLiu-oc, herbert, davem, tglx, mingo, bp, dave.hansen, x86,
	hpa, seanjc, kim.phillips, pbonzini, babu.moger, jiaxi.chen,
	jmattson, pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: oe-kbuild-all, CobeChen, TonyWWang, YunShen, Leoliu, LeoLiuoc

Hi LeoLiu-oc,

kernel test robot noticed the following build errors:

[auto build test ERROR on herbert-cryptodev-2.6/master]
[also build test ERROR on herbert-crypto-2.6/master tip/x86/core linus/master v6.6 next-20231110]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/LeoLiu-oc/crypto-x86-sm2-add-Zhaoxin-SM2-algorithm-implementation/20231109-231229
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
patch link:    https://lore.kernel.org/r/20231109094744.545887-1-LeoLiu-oc%40zhaoxin.com
patch subject: [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20231110/202311102217.ZDrXGyK9-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231110/202311102217.ZDrXGyK9-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311102217.ZDrXGyK9-lkp@intel.com/

All errors (new ones prefixed by >>):

   arch/x86/crypto/sm2-zhaoxin-gmi_asm.S: Assembler messages:
>> arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:38: Error: bad register name `%r12'
>> arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:39: Error: bad register name `%rbx'
>> arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:41: Error: bad register name `%rsi'
>> arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:42: Error: bad register name `%rdi'
>> arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:43: Error: bad register name `%rdx'
   arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:44: Error: bad register name `%rdx'
>> arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:45: Error: bad register name `%rcx'
   arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:46: Error: bad register name `%r12'
   arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:53: Error: bad register name `%rcx'
   arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:55: Error: bad register name `%rbx'
   arch/x86/crypto/sm2-zhaoxin-gmi_asm.S:56: Error: bad register name `%r12'


vim +38 arch/x86/crypto/sm2-zhaoxin-gmi_asm.S

    26	
    27	.text
    28	.align 32
    29	###############################################################################
    30	# int zhaoxin_gmi_sm2_verify (
    31	#         unsigned char *key, /*key*/
    32	#         unsigned char *hash, /*hash*/
    33	#         unsigned char *sig, /*signature*/
    34	#         unsigned char *scratch /*8 kbytes scratch space*/
    35	#     );
    36	###############################################################################
    37	SYM_FUNC_START(zhaoxin_gmi_sm2_verify)
  > 38		push %r12
  > 39		push %rbx
    40	
  > 41		mov HASH_PTR, %rax
  > 42		mov KEY_PTR, %rbx
  > 43		mov SIG_PTR, %r12
    44		mov $8, %rdx
  > 45		mov SCRATCH_PTR, %rsi

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-09 15:00 ` Dave Hansen
@ 2023-11-15  2:05   ` LeoLiu-oc
  0 siblings, 0 replies; 15+ messages in thread
From: LeoLiu-oc @ 2023-11-15  2:05 UTC (permalink / raw)
  To: Dave Hansen, herbert, davem, tglx, mingo, bp, dave.hansen, x86,
	hpa, seanjc, kim.phillips, pbonzini, babu.moger, jiaxi.chen,
	jmattson, pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu



在 2023/11/9 23:00, Dave Hansen 写道:
> On 11/9/23 01:47, LeoLiu-oc wrote:
> ...
>> diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
>> index 9bbfd01cfa2f..a771a9da2abd 100644
>> --- a/arch/x86/crypto/Kconfig
>> +++ b/arch/x86/crypto/Kconfig
>> @@ -519,4 +519,15 @@ config CRYPTO_CRCT10DIF_PCLMUL
>>   	  Architecture: x86_64 using:
>>   	  - PCLMULQDQ (carry-less multiplication)
>>   
>> +config CRYPTO_SM2_ZHAOXIN_GMI
>> +	tristate "SM2 Cipher algorithm (Zhaoxin GMI Instruction)"
>> +	depends on X86
> 
> Why does this not have "depends on CPU_SUP_ZHAOXIN"?
> 
Thank you for your suggestion. It is indeed necessary to add a
dependency on CPU_SUP_ZHAOXIN here, which will be updated in the next
version.

> Also, the assembly in here looks suspiciously like x86_64 assembly.
> How, exactly, does this build when !X86_64?
> 
The assembly code will be modified to be embedded in the .c file in the
next version, which will be compatible with !X86_64.

>> +	select CRYPTO_AKCIPHER
>> +	select CRYPTO_MANAGER
>> +	help
>> +	  SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI Instruction
>> +
>> +	  Published by State Encryption Management Bureau, China,
>> +	  as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012.
>> +
>>   endmenu
>> diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
>> index 9aa46093c91b..c23b328a3ecd 100644
>> --- a/arch/x86/crypto/Makefile
>> +++ b/arch/x86/crypto/Makefile
>> @@ -109,6 +109,9 @@ aria-aesni-avx2-x86_64-y := aria-aesni-avx2-asm_64.o aria_aesni_avx2_glue.o
>>   obj-$(CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64) += aria-gfni-avx512-x86_64.o
>>   aria-gfni-avx512-x86_64-y := aria-gfni-avx512-asm_64.o aria_gfni_avx512_glue.o
>>   
>> +obj-$(CONFIG_CRYPTO_SM2_ZHAOXIN_GMI) += sm2-zhaoxin-gmi.o
>> +sm2-zhaoxin-gmi-y := sm2-zhaoxin-gmi_asm.o sm2-zhaoxin-gmi_glue.o
>> +
>>   quiet_cmd_perlasm = PERLASM $@
>>         cmd_perlasm = $(PERL) $< > $@
>>   $(obj)/%.S: $(src)/%.pl FORCE
>> diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S b/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S
>> new file mode 100644
>> index 000000000000..4ee5194557a0
>> --- /dev/null
>> +++ b/arch/x86/crypto/sm2-zhaoxin-gmi_asm.S
>> @@ -0,0 +1,59 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * Zhaoxin GMI implementation of a SM2 function
>> + *
>> + * Copyright(c) 2023 Zhaoxin Semiconductor LTD.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of version 2 of the GNU General Public License as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * General Public License for more details.
>> + *
>> + * Contact Information:
>> + *  YunShen <YunShen@zhaoxin.com>
>> + */
> 
> I thought we were using SPDX instead of blown-up license text now.  Why
> does this need the GPLv2 blurb?
> 
Thank you for your reminder. I will remove it in the subsequent version.

>> +#include <linux/linkage.h>
>> +
>> +#define KEY_PTR     %rdi /* 1st arg */
>> +#define HASH_PTR    %rsi /* 2nd arg */
>> +#define SIG_PTR     %rdx /* 3rd arg */
>> +#define SCRATCH_PTR %rcx /* 4rd arg */
>> +#define VER_RESULT  %rax /* ret     */
>> +
>> +.text
>> +.align 32
>> +###############################################################################
>> +# int zhaoxin_gmi_sm2_verify (
>> +#         unsigned char *key, /*key*/
>> +#         unsigned char *hash, /*hash*/
>> +#         unsigned char *sig, /*signature*/
>> +#         unsigned char *scratch /*8 kbytes scratch space*/
>> +#     );
>> +###############################################################################
> 
> This comment is just a waste of space.  The types here are completely
> uninformative and the comments:
> 
> 	unsigned char *key, /*key*/
> 
> are, um, equally uninformative considering the #defines above.
> 
The assembly code here will be abandoned in the next version and will be
modified to be embedded in the C language code. There will be no such
problem in the future.

>> +SYM_FUNC_START(zhaoxin_gmi_sm2_verify)
>> +	push %r12
>> +	push %rbx
> 
> Please mention that these are callee-saved registers that the
> instruction will clobber.
> 
As mentioned above.

>> +	mov HASH_PTR, %rax
>> +	mov KEY_PTR, %rbx
>> +	mov SIG_PTR, %r12
>> +	mov $8, %rdx
>> +	mov SCRATCH_PTR, %rsi
>> +	mov %r12, %rdi
>> +
>> +	.byte 0XF2
>> +	.byte 0X0F
>> +	.byte 0XA6
>> +	.byte 0XC0
> 
> Please look around the codebase and see what folks do with assembly for
> instructions that might not be supported in the assembler.  There's an
> existing standard here.
> 
As mentioned above.

>> +	mov %rcx, %rax
>> +
>> +	pop %rbx
>> +	pop %r12
>> +
>> +	RET
>> +SYM_FUNC_END(zhaoxin_gmi_sm2_verify)
>> diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
>> new file mode 100644
>> index 000000000000..4d0d18f68266
>> --- /dev/null
>> +++ b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
>> @@ -0,0 +1,145 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * SM2 asymmetric public-key algorithm
>> + * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and
>> + * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
>> + *
>> + * Copyright (c) 2023 Shanghai Zhaoxin Semiconductor LTD.
>> + * Authors: YunShen <yunshen@zhaoxin.com>
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/mpi.h>
>> +#include <crypto/internal/akcipher.h>
>> +#include <crypto/akcipher.h>
>> +#include <crypto/sm2.h>
>> +#include <asm/cpufeature.h>
>> +#include <asm/processor.h>
>> +#include <asm/cpu_device_id.h>
>> +
>> +#define SCRATCH_SIZE (4 * 2048)
>> +
>> +asmlinkage int zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash, unsigned char *sig,
>> +				unsigned char *scratch);
>> +
>> +struct sm2_cipher_data {
>> +	u8 pub_key[65]; /* public key */
>> +};
>> +
>> +/* Load supported features of the CPU to see if the SM2 is available. */
>> +static int zhaoxin_gmi_available(void)
>> +{
>> +	if (!boot_cpu_has(X86_FEATURE_SM2_EN)) {
>> +		pr_err("can't enable hardware SM2 if Zhaoxin GMI SM2 is not enabled\n");
>> +		return -ENODEV;
>> +	}
>> +	return 0;
>> +}
> 
> How can this code even be reached if X86_FEATURE_SM2_EN is clear?  How
> will the cipher even get registered?
> 
SM2 has two macro definitions, one representing the existence of SM2
functionality; the other SM2_EN represents that the functionality is
enabled and can be modified in the firmware.
In the initialization function, the detection of X86_FEATURE_SM2 will be
performed to verify if SM2 functionality is supported.
This is the detection of X86_FEATURE_SM2_EN to verify whether the SM2
function is enabled in the firmware.

>> +/* Zhaoxin sm2 verify function */
>> +static int _zhaoxin_sm2_verify(struct sm2_cipher_data *ec, unsigned char *hash, unsigned char *sig)
>> +{
>> +	int ret = -EKEYREJECTED;
>> +	uint64_t f_ok = 0;
> 
> This is an odd type choice since this is far from a user/kernel ABI and
> also the zhaoxin_gmi_sm2_verify() declared return type is 'int'.
> 
Yes, it will be modified in the next version.

>> +	unsigned char *scratch = kzalloc(SCRATCH_SIZE, GFP_KERNEL);
>> +
>> +	f_ok = zhaoxin_gmi_sm2_verify(ec->pub_key, hash, sig, scratch);
>> +	if (f_ok == 1)
>> +		ret = 0;
>> +
>> +	kfree(scratch);
>> +
>> +	return ret;
>> +}
>> +
>> +static int zhaoxin_sm2_verify(struct akcipher_request *req)
>> +{
>> +	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
>> +	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
>> +	unsigned char *buffer;
>> +	int ret;
>> +
>> +	buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL);
>> +	if (!buffer)
>> +		return -ENOMEM;
>> +
>> +	sg_pcopy_to_buffer(req->src, sg_nents_for_len(req->src, req->src_len + req->dst_len),
>> +		buffer, req->src_len + req->dst_len, 0);
> 
> While sg_pcopy_to_buffer() calls in general seem
> readablility-challenged, this one in particular is pretty bad.  Please
> break this up logically (one line per argument seems commonplace) or use
> some helper intermediate variables.  I do notice that 'req->src_len +
> req->dst_len' is repeated quite a few times in this function, for instance.
> 
Yes, this change will make the code clearer, and will be modified in the
next version as you suggested.

>> +	ret = _zhaoxin_sm2_verify(ec, buffer + req->src_len, buffer);
>> +	kfree(buffer);
>> +
>> +	return ret;
>> +}
>> +
>> +static int zhaoxin_sm2_set_pub_key(struct crypto_akcipher *tfm, const void *key,
>> +				unsigned int keylen)
>> +{
>> +	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
>> +
>> +	memcpy(ec->pub_key, key, keylen);
>> +
>> +	return 0;
>> +}
>> +
>> +static unsigned int zhaoxin_sm2_max_size(struct crypto_akcipher *tfm)
>> +{
>> +	/* Unlimited max size */
>> +	return PAGE_SIZE;
>> +}
> 
> I don't know the crypto API well, but does this mean that for every 4k
> of data that this code deals with, it needs to kmalloc()/kfree() 8k?
> 
The return value of the zhaoxin_sm2_max_size function is the maximum
length of the algorithm's output buffer.Generally,the length of the
output data of the SM2 algorithm is not greater than PAGE_SIZE.
In addition, it also references the setting of the software-implemented
SM2 algorithm in the kernel.

>> +static int zhaoxin_sm2_init_tfm(struct crypto_akcipher *tfm)
>> +{
>> +	return zhaoxin_gmi_available();
>> +}
>> +
>> +static void zhaoxin_sm2_exit_tfm(struct crypto_akcipher *tfm)
>> +{
>> +	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
>> +
>> +	memset(ec, 0, sizeof(*ec));
>> +}
>> +
>> +static struct akcipher_alg zhaoxin_sm2 = {
>> +	.verify = zhaoxin_sm2_verify,
>> +	.set_pub_key = zhaoxin_sm2_set_pub_key,
>> +	.max_size = zhaoxin_sm2_max_size,
>> +	.init = zhaoxin_sm2_init_tfm,
>> +	.exit = zhaoxin_sm2_exit_tfm,
>> +	.base = {
>> +		.cra_name = "sm2",
>> +		.cra_driver_name = "zhaoxin-gmi-sm2",
>> +		.cra_priority = 150,
>> +		.cra_module = THIS_MODULE,
>> +		.cra_ctxsize = sizeof(struct sm2_cipher_data),
>> +	},
>> +};
>> +
>> +static const struct x86_cpu_id zhaoxin_sm2_cpu_ids[] = {
>> +	X86_MATCH_FEATURE(X86_FEATURE_SM2, NULL),
>> +	{}
>> +};
>> +MODULE_DEVICE_TABLE(x86cpu, zhaoxin_sm2_cpu_ids);
>> +
>> +static int __init zhaoxin_sm2_init(void)
>> +{
>> +	if (!x86_match_cpu(zhaoxin_sm2_cpu_ids)) {
>> +		pr_err("The CPU isn't support hardware SM2.\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	return crypto_register_akcipher(&zhaoxin_sm2);
>> +}
> 
> Again, please look around the code base.  There are a bunch of crypto
> drivers that do checks like this.  *None* have a pr_err().  Few spew any
> spam to dmesg.  Why does this one?
> 
OK, The pr_err statement here will be removed in the next version.

>> +static void __exit zhaoxin_sm2_exit(void)
>> +{
>> +	crypto_unregister_akcipher(&zhaoxin_sm2);
>> +}
>> +
>> +module_init(zhaoxin_sm2_init);
>> +module_exit(zhaoxin_sm2_exit);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("YunShen <yunshen@zhaoxin.com>");
>> +MODULE_DESCRIPTION("SM2 Zhaoxin GMI Algorithm");
>> +MODULE_ALIAS_CRYPTO("zhaoxin-gmi-sm2");
>> diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
>> index 4af140cf5719..07a78ec83bed 100644
>> --- a/arch/x86/include/asm/cpufeatures.h
>> +++ b/arch/x86/include/asm/cpufeatures.h
>> @@ -146,6 +146,8 @@
>>   #define X86_FEATURE_HYPERVISOR		( 4*32+31) /* Running on a hypervisor */
>>   
>>   /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
>> +#define X86_FEATURE_SM2			(5*32 + 0) /* SM2 ZhaoXin GMI present */
>> +#define X86_FEATURE_SM2_EN			(5*32 + 1) /* SM2 ZhaoXin GMI enabled */
> 
> Ahh, so I actually misread the two CPUID flags that got checked earlier.
> 
> What does it take to get "GMI enabled"?  How can it be present but not
> enabled?
> 
As mentioned earlier, SM2 and SM2_EN represent the existence and
enablement of SM2 functionality, respectively. SM2_EN can be turned on
or off in the firmware.

Best Regards
LeoLiu-oc

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

* [PATCH v2] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-09  9:47 [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation LeoLiu-oc
  2023-11-09 15:00 ` Dave Hansen
  2023-11-10 14:27 ` kernel test robot
@ 2023-11-15  7:17 ` LeoLiu-oc
  2023-11-15 16:58   ` kernel test robot
  2023-11-22  6:43 ` [PATCH v3] " LeoLiu-oc
  2023-12-21  6:21 ` [PATCH v4] " LeoLiu-oc
  4 siblings, 1 reply; 15+ messages in thread
From: LeoLiu-oc @ 2023-11-15  7:17 UTC (permalink / raw)
  To: herbert, davem, tglx, mingo, bp, dave.hansen, x86, hpa, seanjc,
	kim.phillips, pbonzini, babu.moger, jiaxi.chen, jmattson,
	pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu, LeoLiuoc

From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>

Add support for SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI
Instruction. The purpose of this driver is to ensure that the application
has both high performance and high security.

---

v1 -> v2:
1. The assembly code is modified to be embedded in the .c file.
2. Optimize code style and details.

Signed-off-by: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
---
 arch/x86/crypto/Kconfig                |  11 ++
 arch/x86/crypto/Makefile               |   2 +
 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c | 154 +++++++++++++++++++++++++
 arch/x86/include/asm/cpufeatures.h     |   2 +
 4 files changed, 169 insertions(+)
 create mode 100644 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c

diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
index 9bbfd01cfa2f..974d4c3806ff 100644
--- a/arch/x86/crypto/Kconfig
+++ b/arch/x86/crypto/Kconfig
@@ -519,4 +519,15 @@ config CRYPTO_CRCT10DIF_PCLMUL
 	  Architecture: x86_64 using:
 	  - PCLMULQDQ (carry-less multiplication)
 
+config CRYPTO_SM2_ZHAOXIN_GMI
+	tristate "SM2 Cipher algorithm (Zhaoxin GMI Instruction)"
+	depends on X86 && (CPU_SUP_CENTAUR || CPU_SUP_ZHAOXIN)
+	select CRYPTO_AKCIPHER
+	select CRYPTO_MANAGER
+	help
+	  SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI Instruction
+
+	  Published by State Encryption Management Bureau, China,
+	  as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012.
+
 endmenu
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 9aa46093c91b..be37a4a7fc3f 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -109,6 +109,8 @@ aria-aesni-avx2-x86_64-y := aria-aesni-avx2-asm_64.o aria_aesni_avx2_glue.o
 obj-$(CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64) += aria-gfni-avx512-x86_64.o
 aria-gfni-avx512-x86_64-y := aria-gfni-avx512-asm_64.o aria_gfni_avx512_glue.o
 
+obj-$(CONFIG_CRYPTO_SM2_ZHAOXIN_GMI) += sm2-zhaoxin-gmi_glue.o
+
 quiet_cmd_perlasm = PERLASM $@
       cmd_perlasm = $(PERL) $< > $@
 $(obj)/%.S: $(src)/%.pl FORCE
diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
new file mode 100644
index 000000000000..80a3c739a9a7
--- /dev/null
+++ b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SM2 asymmetric public-key algorithm
+ * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and
+ * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
+ *
+ * Copyright (c) 2023 Shanghai Zhaoxin Semiconductor LTD.
+ * Authors: YunShen <yunshen@zhaoxin.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mpi.h>
+#include <crypto/internal/akcipher.h>
+#include <crypto/akcipher.h>
+#include <crypto/sm2.h>
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define SCRATCH_SIZE (4 * 2048)
+
+struct sm2_cipher_data {
+	u8 pub_key[65]; /* public key */
+};
+
+/* Load supported features of the CPU to see if the SM2 is available. */
+static int zhaoxin_gmi_available(void)
+{
+	if (!boot_cpu_has(X86_FEATURE_SM2_EN)) {
+		pr_err("can't enable hardware SM2 if Zhaoxin GMI SM2 is not enabled\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+/* Zhaoxin sm2 verify function */
+static inline int zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash, unsigned char *sig,
+				unsigned char *scratch)
+{
+	uint64_t cword, f_ok;
+	cword = (uint64_t)0x8;
+
+	asm(".byte 0xf2, 0x0f, 0xa6, 0xc0"
+		:"=c"(f_ok), "+a"(hash), "+b"(key), "+d"(cword), "+S"(scratch), "+D"(sig));
+
+	return f_ok;
+}
+
+/* Zhaoxin sm2 verify function */
+static int _zhaoxin_sm2_verify(struct sm2_cipher_data *ec, unsigned char *hash, unsigned char *sig)
+{
+	int ret = -EKEYREJECTED;
+	uint64_t f_ok = 0;
+	unsigned char *scratch = kzalloc(SCRATCH_SIZE, GFP_KERNEL);
+
+	f_ok = zhaoxin_gmi_sm2_verify(ec->pub_key, hash, sig, scratch);
+	if (f_ok == 1)
+		ret = 0;
+
+	kfree(scratch);
+
+	return ret;
+}
+
+static int zhaoxin_sm2_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+	unsigned char *buffer;
+	int ret, buf_len;
+
+	buf_len = req->src_len + req->dst_len;
+
+	buffer = kmalloc(buf_len, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	sg_pcopy_to_buffer(req->src, sg_nents_for_len(req->src, buf_len), buffer, buf_len, 0);
+	ret = _zhaoxin_sm2_verify(ec, buffer + req->src_len, buffer);
+
+	kfree(buffer);
+
+	return ret;
+}
+
+static int zhaoxin_sm2_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+				unsigned int keylen)
+{
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+
+	memcpy(ec->pub_key, key, keylen);
+
+	return 0;
+}
+
+static unsigned int zhaoxin_sm2_max_size(struct crypto_akcipher *tfm)
+{
+	/* Unlimited max size */
+	return PAGE_SIZE;
+}
+
+static int zhaoxin_sm2_init_tfm(struct crypto_akcipher *tfm)
+{
+	return zhaoxin_gmi_available();
+}
+
+static void zhaoxin_sm2_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+
+	memset(ec, 0, sizeof(*ec));
+}
+
+static struct akcipher_alg zhaoxin_sm2 = {
+	.verify = zhaoxin_sm2_verify,
+	.set_pub_key = zhaoxin_sm2_set_pub_key,
+	.max_size = zhaoxin_sm2_max_size,
+	.init = zhaoxin_sm2_init_tfm,
+	.exit = zhaoxin_sm2_exit_tfm,
+	.base = {
+		.cra_name = "sm2",
+		.cra_driver_name = "zhaoxin-gmi-sm2",
+		.cra_priority = 150,
+		.cra_module = THIS_MODULE,
+		.cra_ctxsize = sizeof(struct sm2_cipher_data),
+	},
+};
+
+static const struct x86_cpu_id zhaoxin_sm2_cpu_ids[] = {
+	X86_MATCH_FEATURE(X86_FEATURE_SM2, NULL),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, zhaoxin_sm2_cpu_ids);
+
+static int __init zhaoxin_sm2_init(void)
+{
+	if (!x86_match_cpu(zhaoxin_sm2_cpu_ids))
+		return -ENODEV;
+
+	return crypto_register_akcipher(&zhaoxin_sm2);
+}
+
+static void __exit zhaoxin_sm2_exit(void)
+{
+	crypto_unregister_akcipher(&zhaoxin_sm2);
+}
+
+module_init(zhaoxin_sm2_init);
+module_exit(zhaoxin_sm2_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("YunShen <yunshen@zhaoxin.com>");
+MODULE_DESCRIPTION("SM2 Zhaoxin GMI Algorithm");
+MODULE_ALIAS_CRYPTO("zhaoxin-gmi-sm2");
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 4af140cf5719..07a78ec83bed 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -146,6 +146,8 @@
 #define X86_FEATURE_HYPERVISOR		( 4*32+31) /* Running on a hypervisor */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+#define X86_FEATURE_SM2			(5*32 + 0) /* SM2 ZhaoXin GMI present */
+#define X86_FEATURE_SM2_EN			(5*32 + 1) /* SM2 ZhaoXin GMI enabled */
 #define X86_FEATURE_XSTORE		( 5*32+ 2) /* "rng" RNG present (xstore) */
 #define X86_FEATURE_XSTORE_EN		( 5*32+ 3) /* "rng_en" RNG enabled */
 #define X86_FEATURE_XCRYPT		( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
-- 
2.34.1


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

* Re: [PATCH v2] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-15  7:17 ` [PATCH v2] " LeoLiu-oc
@ 2023-11-15 16:58   ` kernel test robot
  2023-11-15 19:21     ` Dave Hansen
  0 siblings, 1 reply; 15+ messages in thread
From: kernel test robot @ 2023-11-15 16:58 UTC (permalink / raw)
  To: LeoLiu-oc, herbert, davem, tglx, mingo, bp, dave.hansen, x86,
	hpa, seanjc, kim.phillips, pbonzini, babu.moger, jiaxi.chen,
	jmattson, pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: oe-kbuild-all, CobeChen, TonyWWang, YunShen, Leoliu, LeoLiuoc

Hi LeoLiu-oc,

kernel test robot noticed the following build errors:

[auto build test ERROR on herbert-cryptodev-2.6/master]
[also build test ERROR on herbert-crypto-2.6/master tip/x86/core linus/master v6.7-rc1 next-20231115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/LeoLiu-oc/crypto-x86-sm2-add-Zhaoxin-SM2-algorithm-implementation/20231115-163848
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
patch link:    https://lore.kernel.org/r/20231115071724.575356-1-LeoLiu-oc%40zhaoxin.com
patch subject: [PATCH v2] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
config: i386-allmodconfig (https://download.01.org/0day-ci/archive/20231116/202311160022.csCILGmA-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231116/202311160022.csCILGmA-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311160022.csCILGmA-lkp@intel.com/

All errors (new ones prefixed by >>):

   In function 'zhaoxin_gmi_sm2_verify',
       inlined from '_zhaoxin_sm2_verify' at arch/x86/crypto/sm2-zhaoxin-gmi_glue.c:56:9,
       inlined from 'zhaoxin_sm2_verify' at arch/x86/crypto/sm2-zhaoxin-gmi_glue.c:79:8:
>> arch/x86/crypto/sm2-zhaoxin-gmi_glue.c:43:9: error: inconsistent operand constraints in an 'asm'
      43 |         asm(".byte 0xf2, 0x0f, 0xa6, 0xc0"
         |         ^~~


vim +/asm +43 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c

    35	
    36	/* Zhaoxin sm2 verify function */
    37	static inline int zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash, unsigned char *sig,
    38					unsigned char *scratch)
    39	{
    40		uint64_t cword, f_ok;
    41		cword = (uint64_t)0x8;
    42	
  > 43		asm(".byte 0xf2, 0x0f, 0xa6, 0xc0"
    44			:"=c"(f_ok), "+a"(hash), "+b"(key), "+d"(cword), "+S"(scratch), "+D"(sig));
    45	
    46		return f_ok;
    47	}
    48	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v2] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-15 16:58   ` kernel test robot
@ 2023-11-15 19:21     ` Dave Hansen
  2023-11-21  8:04       ` LeoLiu-oc
  0 siblings, 1 reply; 15+ messages in thread
From: Dave Hansen @ 2023-11-15 19:21 UTC (permalink / raw)
  To: kernel test robot, LeoLiu-oc, herbert, davem, tglx, mingo, bp,
	dave.hansen, x86, hpa, seanjc, kim.phillips, pbonzini,
	babu.moger, jiaxi.chen, jmattson, pawan.kumar.gupta,
	linux-crypto, linux-kernel
  Cc: oe-kbuild-all, CobeChen, TonyWWang, YunShen, Leoliu


> vim +/asm +43 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
> 
>     35	
>     36	/* Zhaoxin sm2 verify function */
>     37	static inline int zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash, unsigned char *sig,
>     38					unsigned char *scratch)
>     39	{
>     40		uint64_t cword, f_ok;
>     41		cword = (uint64_t)0x8;
>     42	
>   > 43		asm(".byte 0xf2, 0x0f, 0xa6, 0xc0"
>     44			:"=c"(f_ok), "+a"(hash), "+b"(key), "+d"(cword), "+S"(scratch), "+D"(sig));
>     45	
>     46		return f_ok;
>     47	}
>     48	

When you go fix your compile error, can you please look around the tree
and see what folks do for replacing .byte?  AS_SHA1_NI, for example.

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

* Re: [PATCH v2] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-15 19:21     ` Dave Hansen
@ 2023-11-21  8:04       ` LeoLiu-oc
  0 siblings, 0 replies; 15+ messages in thread
From: LeoLiu-oc @ 2023-11-21  8:04 UTC (permalink / raw)
  To: Dave Hansen, kernel test robot, herbert, davem, tglx, mingo, bp,
	dave.hansen, x86, hpa, seanjc, kim.phillips, pbonzini,
	babu.moger, jiaxi.chen, jmattson, pawan.kumar.gupta,
	linux-crypto, linux-kernel
  Cc: oe-kbuild-all, CobeChen, TonyWWang, YunShen, Leoliu



在 2023/11/16 3:21, Dave Hansen 写道:
> 
>> vim +/asm +43 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
>>
>>      35	
>>      36	/* Zhaoxin sm2 verify function */
>>      37	static inline int zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash, unsigned char *sig,
>>      38					unsigned char *scratch)
>>      39	{
>>      40		uint64_t cword, f_ok;
>>      41		cword = (uint64_t)0x8;
>>      42	
>>    > 43		asm(".byte 0xf2, 0x0f, 0xa6, 0xc0"
>>      44			:"=c"(f_ok), "+a"(hash), "+b"(key), "+d"(cword), "+S"(scratch), "+D"(sig));
>>      45	
>>      46		return f_ok;
>>      47	}
>>      48	
> 
> When you go fix your compile error, can you please look around the tree
> and see what folks do for replacing .byte?  AS_SHA1_NI, for example.

Thank you for your advice. We have found the root cause of the compile 
error and conducted detailed testing again. A corrected version will be 
released soon.

Sincerely.
Leoliu-oc




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

* [PATCH v3] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-09  9:47 [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation LeoLiu-oc
                   ` (2 preceding siblings ...)
  2023-11-15  7:17 ` [PATCH v2] " LeoLiu-oc
@ 2023-11-22  6:43 ` LeoLiu-oc
  2023-11-22 14:26   ` Dave Hansen
  2023-12-01  9:27   ` Herbert Xu
  2023-12-21  6:21 ` [PATCH v4] " LeoLiu-oc
  4 siblings, 2 replies; 15+ messages in thread
From: LeoLiu-oc @ 2023-11-22  6:43 UTC (permalink / raw)
  To: herbert, davem, tglx, mingo, bp, dave.hansen, x86, hpa, seanjc,
	kim.phillips, pbonzini, babu.moger, jiaxi.chen, jmattson,
	pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu, LeoLiuoc

From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>

Add support for SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI
Instruction. The purpose of this driver is to ensure that the application
has both high performance and high security.

---

v1 -> v2:
1. The assembly code is modified to be embedded in the .c file.
2. Optimize code style and details.

v2 -> v3:
1. Increase compatibility with i386 architecture.
2. Optimize variable and return value types in some functions..

Signed-off-by: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
---
 arch/x86/crypto/Kconfig                |  11 ++
 arch/x86/crypto/Makefile               |   2 +
 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c | 158 +++++++++++++++++++++++++
 arch/x86/include/asm/cpufeatures.h     |   2 +
 4 files changed, 173 insertions(+)
 create mode 100644 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c

diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
index 9bbfd01cfa2f..974d4c3806ff 100644
--- a/arch/x86/crypto/Kconfig
+++ b/arch/x86/crypto/Kconfig
@@ -519,4 +519,15 @@ config CRYPTO_CRCT10DIF_PCLMUL
 	  Architecture: x86_64 using:
 	  - PCLMULQDQ (carry-less multiplication)
 
+config CRYPTO_SM2_ZHAOXIN_GMI
+	tristate "SM2 Cipher algorithm (Zhaoxin GMI Instruction)"
+	depends on X86 && (CPU_SUP_CENTAUR || CPU_SUP_ZHAOXIN)
+	select CRYPTO_AKCIPHER
+	select CRYPTO_MANAGER
+	help
+	  SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI Instruction
+
+	  Published by State Encryption Management Bureau, China,
+	  as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012.
+
 endmenu
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 9aa46093c91b..be37a4a7fc3f 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -109,6 +109,8 @@ aria-aesni-avx2-x86_64-y := aria-aesni-avx2-asm_64.o aria_aesni_avx2_glue.o
 obj-$(CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64) += aria-gfni-avx512-x86_64.o
 aria-gfni-avx512-x86_64-y := aria-gfni-avx512-asm_64.o aria_gfni_avx512_glue.o
 
+obj-$(CONFIG_CRYPTO_SM2_ZHAOXIN_GMI) += sm2-zhaoxin-gmi_glue.o
+
 quiet_cmd_perlasm = PERLASM $@
       cmd_perlasm = $(PERL) $< > $@
 $(obj)/%.S: $(src)/%.pl FORCE
diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
new file mode 100644
index 000000000000..264c7948a49b
--- /dev/null
+++ b/arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SM2 asymmetric public-key algorithm
+ * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and
+ * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
+ *
+ * Copyright (c) 2023 Shanghai Zhaoxin Semiconductor LTD.
+ * Authors: YunShen <yunshen@zhaoxin.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mpi.h>
+#include <crypto/internal/akcipher.h>
+#include <crypto/akcipher.h>
+#include <crypto/sm2.h>
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define SCRATCH_SIZE (4 * 2048)
+
+#define SM2_CWORD_VERIFY 0x8
+#define SM2_VERIFY_PASS 1
+
+struct sm2_cipher_data {
+	u8 pub_key[65]; /* public key */
+};
+
+/* Load supported features of the CPU to see if the SM2 is available. */
+static int zhaoxin_gmi_available(void)
+{
+	if (!boot_cpu_has(X86_FEATURE_SM2_EN)) {
+		pr_err("can't enable hardware SM2 if Zhaoxin GMI SM2 is not enabled\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+/* Zhaoxin sm2 verify function */
+static inline size_t zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash,
+				unsigned char *sig, unsigned char *scratch)
+{
+	size_t result;
+
+	asm volatile(
+		".byte 0xf2, 0x0f, 0xa6, 0xc0"
+		:"=c"(result)
+		:"a"(hash), "b"(key), "d"(SM2_CWORD_VERIFY), "S"(scratch), "D"(sig)
+		:"memory");
+
+	return result;
+}
+
+/* Zhaoxin sm2 verify function */
+static int _zhaoxin_sm2_verify(struct sm2_cipher_data *ec, unsigned char *hash, unsigned char *sig)
+{
+	unsigned char *scratch = kzalloc(SCRATCH_SIZE, GFP_KERNEL);
+	int ret = -EKEYREJECTED;
+	size_t result;
+
+	result = zhaoxin_gmi_sm2_verify(ec->pub_key, hash, sig, scratch);
+	if (result == SM2_VERIFY_PASS)
+		ret = 0;
+
+	kfree(scratch);
+
+	return ret;
+}
+
+static int zhaoxin_sm2_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+	unsigned char *buffer;
+	int ret, buf_len;
+
+	buf_len = req->src_len + req->dst_len;
+	buffer = kmalloc(buf_len, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	sg_pcopy_to_buffer(req->src, sg_nents_for_len(req->src, buf_len), buffer, buf_len, 0);
+	ret = _zhaoxin_sm2_verify(ec, buffer + req->src_len, buffer);
+
+	kfree(buffer);
+
+	return ret;
+}
+
+static int zhaoxin_sm2_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+				unsigned int keylen)
+{
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+
+	memcpy(ec->pub_key, key, keylen);
+
+	return 0;
+}
+
+static unsigned int zhaoxin_sm2_max_size(struct crypto_akcipher *tfm)
+{
+	/* Unlimited max size */
+	return PAGE_SIZE;
+}
+
+static int zhaoxin_sm2_init_tfm(struct crypto_akcipher *tfm)
+{
+	return zhaoxin_gmi_available();
+}
+
+static void zhaoxin_sm2_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+
+	memset(ec, 0, sizeof(*ec));
+}
+
+static struct akcipher_alg zhaoxin_sm2 = {
+	.verify = zhaoxin_sm2_verify,
+	.set_pub_key = zhaoxin_sm2_set_pub_key,
+	.max_size = zhaoxin_sm2_max_size,
+	.init = zhaoxin_sm2_init_tfm,
+	.exit = zhaoxin_sm2_exit_tfm,
+	.base = {
+		.cra_name = "sm2",
+		.cra_driver_name = "zhaoxin-gmi-sm2",
+		.cra_priority = 150,
+		.cra_module = THIS_MODULE,
+		.cra_ctxsize = sizeof(struct sm2_cipher_data),
+	},
+};
+
+static const struct x86_cpu_id zhaoxin_sm2_cpu_ids[] = {
+	X86_MATCH_FEATURE(X86_FEATURE_SM2, NULL),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, zhaoxin_sm2_cpu_ids);
+
+static int __init zhaoxin_sm2_init(void)
+{
+	if (!x86_match_cpu(zhaoxin_sm2_cpu_ids))
+		return -ENODEV;
+
+	return crypto_register_akcipher(&zhaoxin_sm2);
+}
+
+static void __exit zhaoxin_sm2_exit(void)
+{
+	crypto_unregister_akcipher(&zhaoxin_sm2);
+}
+
+module_init(zhaoxin_sm2_init);
+module_exit(zhaoxin_sm2_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("YunShen <yunshen@zhaoxin.com>");
+MODULE_DESCRIPTION("SM2 Zhaoxin GMI Algorithm");
+MODULE_ALIAS_CRYPTO("zhaoxin-gmi-sm2");
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 4af140cf5719..07a78ec83bed 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -146,6 +146,8 @@
 #define X86_FEATURE_HYPERVISOR		( 4*32+31) /* Running on a hypervisor */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+#define X86_FEATURE_SM2			(5*32 + 0) /* SM2 ZhaoXin GMI present */
+#define X86_FEATURE_SM2_EN			(5*32 + 1) /* SM2 ZhaoXin GMI enabled */
 #define X86_FEATURE_XSTORE		( 5*32+ 2) /* "rng" RNG present (xstore) */
 #define X86_FEATURE_XSTORE_EN		( 5*32+ 3) /* "rng_en" RNG enabled */
 #define X86_FEATURE_XCRYPT		( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
-- 
2.34.1


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

* Re: [PATCH v3] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-22  6:43 ` [PATCH v3] " LeoLiu-oc
@ 2023-11-22 14:26   ` Dave Hansen
  2023-11-29  7:24     ` LeoLiu-oc
  2023-12-01  9:27   ` Herbert Xu
  1 sibling, 1 reply; 15+ messages in thread
From: Dave Hansen @ 2023-11-22 14:26 UTC (permalink / raw)
  To: LeoLiu-oc, herbert, davem, tglx, mingo, bp, dave.hansen, x86,
	hpa, seanjc, kim.phillips, pbonzini, babu.moger, jiaxi.chen,
	jmattson, pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu

> +/* Zhaoxin sm2 verify function */
> +static inline size_t zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash,
> +				unsigned char *sig, unsigned char *scratch)
> +{
> +	size_t result;
> +
> +	asm volatile(
> +		".byte 0xf2, 0x0f, 0xa6, 0xc0"
> +		:"=c"(result)
> +		:"a"(hash), "b"(key), "d"(SM2_CWORD_VERIFY), "S"(scratch), "D"(sig)
> +		:"memory");
> +
> +	return result;
> +}

What version of binutils supports this new instruction?


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

* Re: [PATCH v3] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-22 14:26   ` Dave Hansen
@ 2023-11-29  7:24     ` LeoLiu-oc
  2023-11-29  8:04       ` LeoLiu-oc
  0 siblings, 1 reply; 15+ messages in thread
From: LeoLiu-oc @ 2023-11-29  7:24 UTC (permalink / raw)
  To: Dave Hansen, herbert, davem, tglx, mingo, bp, dave.hansen, x86,
	hpa, seanjc, kim.phillips, pbonzini, babu.moger, jiaxi.chen,
	jmattson, pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu



在 2023/11/22 22:26, Dave Hansen 写道:
>> +/* Zhaoxin sm2 verify function */
>> +static inline size_t zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash,
>> +				unsigned char *sig, unsigned char *scratch)
>> +{
>> +	size_t result;
>> +
>> +	asm volatile(
>> +		".byte 0xf2, 0x0f, 0xa6, 0xc0"
>> +		:"=c"(result)
>> +		:"a"(hash), "b"(key), "d"(SM2_CWORD_VERIFY), "S"(scratch), "D"(sig)
>> +		:"memory");
>> +
>> +	return result;
>> +}
> 
> What version of binutils supports this new instruction?
> 

The instruction has not yet been submitted to binutils. It will only be 
used in the Zhaoxin-rng driver, and we are evaluating the necessity of 
submitting it to binutils.

Yours sincerely,
Leoliu-oc

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

* Re: [PATCH v3] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-29  7:24     ` LeoLiu-oc
@ 2023-11-29  8:04       ` LeoLiu-oc
  0 siblings, 0 replies; 15+ messages in thread
From: LeoLiu-oc @ 2023-11-29  8:04 UTC (permalink / raw)
  To: Dave Hansen, herbert, davem, tglx, mingo, bp, dave.hansen, x86,
	hpa, seanjc, kim.phillips, pbonzini, babu.moger, jiaxi.chen,
	jmattson, pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu



在 2023/11/29 15:24, LeoLiu-oc 写道:
> 
> 
> 在 2023/11/22 22:26, Dave Hansen 写道:
>>> +/* Zhaoxin sm2 verify function */
>>> +static inline size_t zhaoxin_gmi_sm2_verify(unsigned char *key, 
>>> unsigned char *hash,
>>> +                unsigned char *sig, unsigned char *scratch)
>>> +{
>>> +    size_t result;
>>> +
>>> +    asm volatile(
>>> +        ".byte 0xf2, 0x0f, 0xa6, 0xc0"
>>> +        :"=c"(result)
>>> +        :"a"(hash), "b"(key), "d"(SM2_CWORD_VERIFY), "S"(scratch), 
>>> "D"(sig)
>>> +        :"memory");
>>> +
>>> +    return result;
>>> +}
>>
>> What version of binutils supports this new instruction?
>>
> 
> The instruction has not yet been submitted to binutils. It will only be 
> used in the Zhaoxin sm2 driver, and we are evaluating the necessity of 
> submitting it to binutils.
> 
> Yours sincerely,
> Leoliu-oc

Sorry, Correct a clerical error. "Zhaoxin-rng" --> "Zhaoxin sm2".

Yours sincerely,
Leoliu-oc

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

* Re: [PATCH v3] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-22  6:43 ` [PATCH v3] " LeoLiu-oc
  2023-11-22 14:26   ` Dave Hansen
@ 2023-12-01  9:27   ` Herbert Xu
  2023-12-05  7:26     ` LeoLiu-oc
  1 sibling, 1 reply; 15+ messages in thread
From: Herbert Xu @ 2023-12-01  9:27 UTC (permalink / raw)
  To: LeoLiu-oc
  Cc: davem, tglx, mingo, bp, dave.hansen, x86, hpa, seanjc,
	kim.phillips, pbonzini, babu.moger, jiaxi.chen, jmattson,
	pawan.kumar.gupta, linux-crypto, linux-kernel, CobeChen,
	TonyWWang, YunShen, Leoliu

On Wed, Nov 22, 2023 at 02:43:55PM +0800, LeoLiu-oc wrote:
> From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
> 
> Add support for SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI
> Instruction. The purpose of this driver is to ensure that the application
> has both high performance and high security.
> 
> ---
> 
> v1 -> v2:
> 1. The assembly code is modified to be embedded in the .c file.
> 2. Optimize code style and details.
> 
> v2 -> v3:
> 1. Increase compatibility with i386 architecture.
> 2. Optimize variable and return value types in some functions..
> 
> Signed-off-by: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
> ---
>  arch/x86/crypto/Kconfig                |  11 ++
>  arch/x86/crypto/Makefile               |   2 +
>  arch/x86/crypto/sm2-zhaoxin-gmi_glue.c | 158 +++++++++++++++++++++++++
>  arch/x86/include/asm/cpufeatures.h     |   2 +
>  4 files changed, 173 insertions(+)
>  create mode 100644 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
> 
> diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
> index 9bbfd01cfa2f..974d4c3806ff 100644
> --- a/arch/x86/crypto/Kconfig
> +++ b/arch/x86/crypto/Kconfig
> @@ -519,4 +519,15 @@ config CRYPTO_CRCT10DIF_PCLMUL
>  	  Architecture: x86_64 using:
>  	  - PCLMULQDQ (carry-less multiplication)
>  
> +config CRYPTO_SM2_ZHAOXIN_GMI
> +	tristate "SM2 Cipher algorithm (Zhaoxin GMI Instruction)"
> +	depends on X86 && (CPU_SUP_CENTAUR || CPU_SUP_ZHAOXIN)
> +	select CRYPTO_AKCIPHER
> +	select CRYPTO_MANAGER

Why does this depend on CRYPTO_MANAGER?

> +static int zhaoxin_sm2_verify(struct akcipher_request *req)
> +{
> +	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
> +	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
> +	unsigned char *buffer;
> +	int ret, buf_len;
> +
> +	buf_len = req->src_len + req->dst_len;

What if this overflows? I know you copied this from the generic sm2
code, but that's still broken and both should be fixed up.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH v3] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-12-01  9:27   ` Herbert Xu
@ 2023-12-05  7:26     ` LeoLiu-oc
  0 siblings, 0 replies; 15+ messages in thread
From: LeoLiu-oc @ 2023-12-05  7:26 UTC (permalink / raw)
  To: Herbert Xu
  Cc: davem, tglx, mingo, bp, dave.hansen, x86, hpa, seanjc,
	kim.phillips, pbonzini, babu.moger, jiaxi.chen, jmattson,
	pawan.kumar.gupta, linux-crypto, linux-kernel, CobeChen,
	TonyWWang, YunShen, Leoliu



在 2023/12/1 17:27, Herbert Xu 写道:
> On Wed, Nov 22, 2023 at 02:43:55PM +0800, LeoLiu-oc wrote:
>> From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
>>
>> Add support for SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI
>> Instruction. The purpose of this driver is to ensure that the application
>> has both high performance and high security.
>>
>> ---
>>
>> v1 -> v2:
>> 1. The assembly code is modified to be embedded in the .c file.
>> 2. Optimize code style and details.
>>
>> v2 -> v3:
>> 1. Increase compatibility with i386 architecture.
>> 2. Optimize variable and return value types in some functions..
>>
>> Signed-off-by: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
>> ---
>>   arch/x86/crypto/Kconfig                |  11 ++
>>   arch/x86/crypto/Makefile               |   2 +
>>   arch/x86/crypto/sm2-zhaoxin-gmi_glue.c | 158 +++++++++++++++++++++++++
>>   arch/x86/include/asm/cpufeatures.h     |   2 +
>>   4 files changed, 173 insertions(+)
>>   create mode 100644 arch/x86/crypto/sm2-zhaoxin-gmi_glue.c
>>
>> diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
>> index 9bbfd01cfa2f..974d4c3806ff 100644
>> --- a/arch/x86/crypto/Kconfig
>> +++ b/arch/x86/crypto/Kconfig
>> @@ -519,4 +519,15 @@ config CRYPTO_CRCT10DIF_PCLMUL
>>   	  Architecture: x86_64 using:
>>   	  - PCLMULQDQ (carry-less multiplication)
>>   
>> +config CRYPTO_SM2_ZHAOXIN_GMI
>> +	tristate "SM2 Cipher algorithm (Zhaoxin GMI Instruction)"
>> +	depends on X86 && (CPU_SUP_CENTAUR || CPU_SUP_ZHAOXIN)
>> +	select CRYPTO_AKCIPHER
>> +	select CRYPTO_MANAGER
> 
> Why does this depend on CRYPTO_MANAGER?
> 
Yes, this is redundant and will be removed in the next version.

>> +static int zhaoxin_sm2_verify(struct akcipher_request *req)
>> +{
>> +	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
>> +	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
>> +	unsigned char *buffer;
>> +	int ret, buf_len;
>> +
>> +	buf_len = req->src_len + req->dst_len;
> 
> What if this overflows? I know you copied this from the generic sm2
> code, but that's still broken and both should be fixed up.
> 
> Thanks,
Yes, you are right. Thank you for your advice. The variable types will 
be adjusted according to the actual needs of the code in the next version.

Sincerely,
LeoLiu-oc

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

* [PATCH v4] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation
  2023-11-09  9:47 [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation LeoLiu-oc
                   ` (3 preceding siblings ...)
  2023-11-22  6:43 ` [PATCH v3] " LeoLiu-oc
@ 2023-12-21  6:21 ` LeoLiu-oc
  4 siblings, 0 replies; 15+ messages in thread
From: LeoLiu-oc @ 2023-12-21  6:21 UTC (permalink / raw)
  To: herbert, davem, tglx, mingo, bp, dave.hansen, x86, hpa, seanjc,
	kim.phillips, pbonzini, babu.moger, jiaxi.chen, jmattson,
	pawan.kumar.gupta, linux-crypto, linux-kernel
  Cc: CobeChen, TonyWWang, YunShen, Leoliu, LeoLiuoc

From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>

Add support for SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI
Instruction. The purpose of this driver is to ensure that the application
has both high performance and high security.
---
 arch/x86/crypto/Kconfig            |  10 ++
 arch/x86/crypto/Makefile           |   2 +
 arch/x86/crypto/sm2-zhaoxin-gmi.c  | 160 +++++++++++++++++++++++++++++
 arch/x86/include/asm/cpufeatures.h |   2 +
 4 files changed, 174 insertions(+)
 create mode 100644 arch/x86/crypto/sm2-zhaoxin-gmi.c

diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig
index 9bbfd01cfa2f..b168596924e6 100644
--- a/arch/x86/crypto/Kconfig
+++ b/arch/x86/crypto/Kconfig
@@ -519,4 +519,14 @@ config CRYPTO_CRCT10DIF_PCLMUL
 	  Architecture: x86_64 using:
 	  - PCLMULQDQ (carry-less multiplication)
 
+config CRYPTO_SM2_ZHAOXIN_GMI
+	tristate "SM2 Cipher algorithm (Zhaoxin GMI Instruction)"
+	depends on X86 && (CPU_SUP_CENTAUR || CPU_SUP_ZHAOXIN)
+	select CRYPTO_AKCIPHER
+	help
+	  SM2 (ShangMi 2) public key algorithm by Zhaoxin GMI Instruction
+
+	  Published by State Encryption Management Bureau, China,
+	  as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012.
+
 endmenu
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 9aa46093c91b..f1d64ff7b907 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -109,6 +109,8 @@ aria-aesni-avx2-x86_64-y := aria-aesni-avx2-asm_64.o aria_aesni_avx2_glue.o
 obj-$(CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64) += aria-gfni-avx512-x86_64.o
 aria-gfni-avx512-x86_64-y := aria-gfni-avx512-asm_64.o aria_gfni_avx512_glue.o
 
+obj-$(CONFIG_CRYPTO_SM2_ZHAOXIN_GMI) += sm2-zhaoxin-gmi.o
+
 quiet_cmd_perlasm = PERLASM $@
       cmd_perlasm = $(PERL) $< > $@
 $(obj)/%.S: $(src)/%.pl FORCE
diff --git a/arch/x86/crypto/sm2-zhaoxin-gmi.c b/arch/x86/crypto/sm2-zhaoxin-gmi.c
new file mode 100644
index 000000000000..dbf2f701b832
--- /dev/null
+++ b/arch/x86/crypto/sm2-zhaoxin-gmi.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SM2 asymmetric public-key algorithm
+ * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and
+ * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
+ *
+ * Copyright (c) 2023 Shanghai Zhaoxin Semiconductor LTD.
+ * Authors: YunShen <yunshen@zhaoxin.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mpi.h>
+#include <crypto/internal/akcipher.h>
+#include <crypto/akcipher.h>
+#include <crypto/sm2.h>
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
+#include <asm/cpu_device_id.h>
+
+#define SCRATCH_SIZE (4 * 2048)
+
+#define SM2_CWORD_VERIFY 0x8
+#define SM2_VERIFY_PASS 1
+
+struct sm2_cipher_data {
+	u8 pub_key[65]; /* public key */
+};
+
+/* Load supported features of the CPU to see if the SM2 is available. */
+static int zhaoxin_gmi_available(void)
+{
+	if (!boot_cpu_has(X86_FEATURE_SM2_EN)) {
+		pr_err("can't enable hardware SM2 if Zhaoxin GMI SM2 is not enabled\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+/* Zhaoxin sm2 verify function */
+static inline size_t zhaoxin_gmi_sm2_verify(unsigned char *key, unsigned char *hash,
+				unsigned char *sig, unsigned char *scratch)
+{
+	size_t result;
+
+	asm volatile(
+		".byte 0xf2, 0x0f, 0xa6, 0xc0"
+		: "=c"(result)
+		: "a"(hash), "b"(key), "d"(SM2_CWORD_VERIFY), "S"(scratch), "D"(sig)
+		: "memory");
+
+	return result;
+}
+
+/* Zhaoxin sm2 verify function */
+static int _zhaoxin_sm2_verify(struct sm2_cipher_data *ec, unsigned char *hash, unsigned char *sig)
+{
+	unsigned char *scratch = kzalloc(SCRATCH_SIZE, GFP_KERNEL);
+	int ret = -EKEYREJECTED;
+	size_t result;
+
+	result = zhaoxin_gmi_sm2_verify(ec->pub_key, hash, sig, scratch);
+	if (result == SM2_VERIFY_PASS)
+		ret = 0;
+
+	kfree(scratch);
+
+	return ret;
+}
+
+static int zhaoxin_sm2_verify(struct akcipher_request *req)
+{
+	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+	unsigned char *buffer;
+	unsigned int buf_len;
+	int ret;
+
+	buf_len = req->src_len + req->dst_len;
+	buffer = kmalloc(buf_len, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	sg_pcopy_to_buffer(req->src, sg_nents_for_len(req->src, (u64)buf_len), buffer,
+			(size_t)buf_len, 0);
+	ret = _zhaoxin_sm2_verify(ec, buffer + req->src_len, buffer);
+
+	kfree(buffer);
+
+	return ret;
+}
+
+static int zhaoxin_sm2_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+				unsigned int keylen)
+{
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+
+	memcpy(ec->pub_key, key, keylen);
+
+	return 0;
+}
+
+static unsigned int zhaoxin_sm2_max_size(struct crypto_akcipher *tfm)
+{
+	/* Unlimited max size */
+	return PAGE_SIZE;
+}
+
+static int zhaoxin_sm2_init_tfm(struct crypto_akcipher *tfm)
+{
+	return zhaoxin_gmi_available();
+}
+
+static void zhaoxin_sm2_exit_tfm(struct crypto_akcipher *tfm)
+{
+	struct sm2_cipher_data *ec = akcipher_tfm_ctx(tfm);
+
+	memset(ec, 0, sizeof(*ec));
+}
+
+static struct akcipher_alg zhaoxin_sm2 = {
+	.verify = zhaoxin_sm2_verify,
+	.set_pub_key = zhaoxin_sm2_set_pub_key,
+	.max_size = zhaoxin_sm2_max_size,
+	.init = zhaoxin_sm2_init_tfm,
+	.exit = zhaoxin_sm2_exit_tfm,
+	.base = {
+		.cra_name = "sm2",
+		.cra_driver_name = "zhaoxin-gmi-sm2",
+		.cra_priority = 150,
+		.cra_module = THIS_MODULE,
+		.cra_ctxsize = sizeof(struct sm2_cipher_data),
+	},
+};
+
+static const struct x86_cpu_id zhaoxin_sm2_cpu_ids[] = {
+	X86_MATCH_FEATURE(X86_FEATURE_SM2, NULL),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, zhaoxin_sm2_cpu_ids);
+
+static int __init zhaoxin_sm2_init(void)
+{
+	if (!x86_match_cpu(zhaoxin_sm2_cpu_ids))
+		return -ENODEV;
+
+	return crypto_register_akcipher(&zhaoxin_sm2);
+}
+
+static void __exit zhaoxin_sm2_exit(void)
+{
+	crypto_unregister_akcipher(&zhaoxin_sm2);
+}
+
+module_init(zhaoxin_sm2_init);
+module_exit(zhaoxin_sm2_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("YunShen <yunshen@zhaoxin.com>");
+MODULE_DESCRIPTION("SM2 Zhaoxin GMI Algorithm");
+MODULE_ALIAS_CRYPTO("zhaoxin-gmi-sm2");
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 4af140cf5719..07a78ec83bed 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -146,6 +146,8 @@
 #define X86_FEATURE_HYPERVISOR		( 4*32+31) /* Running on a hypervisor */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+#define X86_FEATURE_SM2			(5*32 + 0) /* SM2 ZhaoXin GMI present */
+#define X86_FEATURE_SM2_EN			(5*32 + 1) /* SM2 ZhaoXin GMI enabled */
 #define X86_FEATURE_XSTORE		( 5*32+ 2) /* "rng" RNG present (xstore) */
 #define X86_FEATURE_XSTORE_EN		( 5*32+ 3) /* "rng_en" RNG enabled */
 #define X86_FEATURE_XCRYPT		( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
-- 
2.34.1


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

end of thread, other threads:[~2023-12-21  6:21 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-09  9:47 [PATCH] crypto: x86/sm2 -add Zhaoxin SM2 algorithm implementation LeoLiu-oc
2023-11-09 15:00 ` Dave Hansen
2023-11-15  2:05   ` LeoLiu-oc
2023-11-10 14:27 ` kernel test robot
2023-11-15  7:17 ` [PATCH v2] " LeoLiu-oc
2023-11-15 16:58   ` kernel test robot
2023-11-15 19:21     ` Dave Hansen
2023-11-21  8:04       ` LeoLiu-oc
2023-11-22  6:43 ` [PATCH v3] " LeoLiu-oc
2023-11-22 14:26   ` Dave Hansen
2023-11-29  7:24     ` LeoLiu-oc
2023-11-29  8:04       ` LeoLiu-oc
2023-12-01  9:27   ` Herbert Xu
2023-12-05  7:26     ` LeoLiu-oc
2023-12-21  6:21 ` [PATCH v4] " LeoLiu-oc

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.