Skip to content

Commit 1bc23be

Browse files
leoliu-ocopsiff
authored andcommitted
crypto: Add support for Zhaoxin GMI SM3 Secure Hash algorithm
zhaoxin inclusion category: feature CVE: NA ----------------- This SM3 algorithm driver is developed to support the SM3 instruction, making user develop their applications with both high performance and high security. Signed-off-by: leoliu-oc <leoliu-oc@zhaoxin.com> Link: deepin-community#272 (cherry picked from commit 010e5440887db19407ae7fb797eab9dea02b1aa6) Signed-off-by: Wentao Guan <guanwentao@uniontech.com> Conflicts: arch/x86/crypto/Makefile
1 parent 636d5b4 commit 1bc23be

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed

arch/x86/crypto/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,19 @@ config CRYPTO_SM3_AVX_X86_64
376376

377377
If unsure, say N.
378378

379+
config CRYPTO_SM3_ZHAOXIN_GMI
380+
tristate "Hash functions: SM3 (Zhaoxin GMI)"
381+
depends on X86 && CRYPTO
382+
select CRYPTO_HASH
383+
select CRYPTO_SM3
384+
help
385+
SM3 cipher algorithms (Zhaoxin GMI Instruction).
386+
387+
SM3 secure hash function as defined by OSCCA GM/T 0004-2012 SM3).
388+
It is part of the Chinese Commercial Cryptography suite.
389+
390+
If unsure, say N.
391+
379392
config CRYPTO_GHASH_CLMUL_NI_INTEL
380393
tristate "Hash functions: GHASH (CLMUL-NI)"
381394
depends on 64BIT

arch/x86/crypto/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,5 @@ aria-aesni-avx2-x86_64-y := aria-aesni-avx2-asm_64.o aria_aesni_avx2_glue.o
7777

7878
obj-$(CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64) += aria-gfni-avx512-x86_64.o
7979
aria-gfni-avx512-x86_64-y := aria-gfni-avx512-asm_64.o aria_gfni_avx512_glue.o
80+
81+
obj-$(CONFIG_CRYPTO_SM3_ZHAOXIN_GMI) += sm3-zhaoxin-gmi.o

arch/x86/crypto/sm3-zhaoxin-gmi.c

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* sm3_zhaoxin_gmi.c - wrapper code for Zhaoxin GMI.
4+
*
5+
* Copyright (C) 2023 Shanghai Zhaoxin Semiconductor LTD.
6+
*
7+
* This program is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License version 2 as
9+
* published by the Free Software Foundation.
10+
*/
11+
12+
#include <crypto/internal/hash.h>
13+
#include <linux/init.h>
14+
#include <linux/module.h>
15+
#include <linux/mm.h>
16+
#include <linux/types.h>
17+
#include <crypto/sm3.h>
18+
#include <crypto/sm3_base.h>
19+
#include <linux/bitops.h>
20+
#include <asm/byteorder.h>
21+
#include <asm/unaligned.h>
22+
#include <linux/cpufeature.h>
23+
#include <linux/processor.h>
24+
25+
/*
26+
* Load supported features of the CPU to see if the SM3/SM4 is available.
27+
*/
28+
static int gmi_available(void)
29+
{
30+
struct cpuinfo_x86 *c = &cpu_data(0);
31+
u32 eax, edx;
32+
33+
if (((c->x86 == 6) && (c->x86_model >= 0x0f)) ||
34+
((c->x86 == 6) && (c->x86_model == 0x09)) ||
35+
(c->x86 > 6)) {
36+
if (!boot_cpu_has(X86_FEATURE_CCS) || !boot_cpu_has(X86_FEATURE_CCS_EN)) {
37+
eax = 0xC0000001;
38+
__asm__ __volatile__ ("cpuid":"=d"(edx):"a"(eax) : );
39+
40+
if ((edx & 0x0030) != 0x0030)
41+
return -ENODEV;
42+
43+
pr_debug("GMI SM3 detected by CPUID\n");
44+
return 0;
45+
}
46+
pr_debug("GMI SM3 is available\n");
47+
return 0;
48+
}
49+
return -ENODEV;
50+
}
51+
52+
static void sm3_generic_block_fn(struct sm3_state *sst, const u8 *inp, int blockcnt)
53+
{
54+
unsigned long in, out, cnt, blksz, ctrl;
55+
56+
if (!blockcnt)
57+
return;
58+
59+
in = (unsigned long)inp;
60+
out = (unsigned long)(sst->state);
61+
cnt = (unsigned long)blockcnt;
62+
blksz = 0x20;
63+
ctrl = -1;
64+
65+
__asm__ __volatile__(
66+
".byte 0xf3,0x0f,0xa6,0xe8\n"
67+
: "+S"(in)
68+
: "S"(in), "D"(out), "c"(cnt), "b"(blksz), "a"(ctrl)
69+
: "memory"
70+
);
71+
}
72+
73+
static inline int zx_sm3_init(struct shash_desc *desc)
74+
{
75+
struct sm3_state *sctx;
76+
77+
if (!desc)
78+
return -EINVAL;
79+
80+
sctx = shash_desc_ctx(desc);
81+
82+
sctx->state[0] = 0x6f168073UL;
83+
sctx->state[1] = 0xb9b21449UL;
84+
sctx->state[2] = 0xd7422417UL;
85+
sctx->state[3] = 0x00068adaUL;
86+
sctx->state[4] = 0xbc306fa9UL;
87+
sctx->state[5] = 0xaa383116UL;
88+
sctx->state[6] = 0x4dee8de3UL;
89+
sctx->state[7] = 0x4e0efbb0UL;
90+
91+
sctx->count = 0;
92+
93+
return 0;
94+
}
95+
96+
static inline int zx_sm3_base_finish(struct shash_desc *desc, u8 *out)
97+
{
98+
struct sm3_state *sctx = shash_desc_ctx(desc);
99+
__be32 *digest = (__be32 *)out;
100+
101+
memcpy(digest, sctx->state, SM3_DIGEST_SIZE);
102+
103+
*sctx = (struct sm3_state){};
104+
return 0;
105+
}
106+
107+
static int zx_sm3_update(struct shash_desc *desc, const u8 *data, unsigned int len)
108+
{
109+
return sm3_base_do_update(desc, data, len, sm3_generic_block_fn);
110+
}
111+
112+
static int zx_sm3_final(struct shash_desc *desc, u8 *out)
113+
{
114+
sm3_base_do_finalize(desc, sm3_generic_block_fn);
115+
116+
return zx_sm3_base_finish(desc, out);
117+
}
118+
119+
static int zx_sm3_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *hash)
120+
{
121+
sm3_base_do_update(desc, data, len, sm3_generic_block_fn);
122+
123+
return zx_sm3_final(desc, hash);
124+
}
125+
126+
static struct shash_alg zx_sm3_alg = {
127+
.digestsize = SM3_DIGEST_SIZE,
128+
.init = zx_sm3_init,
129+
.update = zx_sm3_update,
130+
.final = zx_sm3_final,
131+
.finup = zx_sm3_finup,
132+
.descsize = sizeof(struct sm3_state),
133+
.base = {
134+
.cra_name = "sm3",
135+
.cra_driver_name = "sm3-zhaoxin-gmi",
136+
.cra_priority = 300,
137+
.cra_blocksize = SM3_BLOCK_SIZE,
138+
.cra_module = THIS_MODULE,
139+
}
140+
};
141+
142+
static int __init zx_sm3_generic_mod_init(void)
143+
{
144+
if (!!gmi_available())
145+
return -ENODEV;
146+
147+
pr_info("GMI is available on this platform.");
148+
return crypto_register_shash(&zx_sm3_alg);
149+
}
150+
151+
static void __exit zx_sm3_generic_mod_fini(void)
152+
{
153+
crypto_unregister_shash(&zx_sm3_alg);
154+
}
155+
156+
module_init(zx_sm3_generic_mod_init);
157+
module_exit(zx_sm3_generic_mod_fini);
158+
159+
MODULE_LICENSE("GPL v2");
160+
MODULE_DESCRIPTION("SM3 Secure Hash Algorithm");
161+
162+
MODULE_ALIAS_CRYPTO("sm3-zhaoxin");
163+
MODULE_ALIAS_CRYPTO("sm3-zhaoxin-gmi");

0 commit comments

Comments
 (0)