Unverified Commit e2b058b2 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3182 [OLK-6.6] Add support for Zhaoxin GMI SM2 Secure Hash algorithm

Merge Pull Request from: @leoliu-oc 
 
This SM2 algorithm driver is developed to support the SM2 instruction,
making user develop their applications with both high performance and high
security.

### Issue
https://gitee.com/openeuler/kernel/issues/I8WZHX

### Test
Pass: The drive module is installed successfully and functions correctly 
 
Link:https://gitee.com/openeuler/kernel/pulls/3182

 

Reviewed-by: default avatarLiu Chao <liuchao173@huawei.com>
Reviewed-by: default avatarJason Zeng <jason.zeng@intel.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents cd428475 4fc6f517
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8752,6 +8752,7 @@ CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m
CONFIG_CRYPTO_CRC32C_INTEL=m
CONFIG_CRYPTO_CRC32_PCLMUL=m
CONFIG_CRYPTO_CRCT10DIF_PCLMUL=m
CONFIG_CRYPTO_SM2_ZHAOXIN_GMI=m
# end of Accelerated Cryptographic Algorithms for CPU (x86)

CONFIG_CRYPTO_HW=y
+11 −0
Original line number Diff line number Diff line
@@ -551,4 +551,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
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ 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
obj-$(CONFIG_CRYPTO_SM3_ZHAOXIN_GMI) += sm3-zhaoxin-gmi.o
obj-$(CONFIG_CRYPTO_SM4_ZHAOXIN_GMI) += sm4-zhaoxin-gmi.o

+158 −0
Original line number Diff line number Diff line
// 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");
+2 −0
Original line number Diff line number Diff line
@@ -144,6 +144,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_CCS        (5*32+4) /*  "sm3 sm4" present */