1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2140aa50dSArd Biesheuvel /*
3140aa50dSArd Biesheuvel * sm3-ce-glue.c - SM3 secure hash using ARMv8.2 Crypto Extensions
4140aa50dSArd Biesheuvel *
5140aa50dSArd Biesheuvel * Copyright (C) 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
6140aa50dSArd Biesheuvel */
7140aa50dSArd Biesheuvel
8140aa50dSArd Biesheuvel #include <asm/neon.h>
9140aa50dSArd Biesheuvel #include <asm/simd.h>
10140aa50dSArd Biesheuvel #include <asm/unaligned.h>
11140aa50dSArd Biesheuvel #include <crypto/internal/hash.h>
12e52b7023SEric Biggers #include <crypto/internal/simd.h>
13140aa50dSArd Biesheuvel #include <crypto/sm3.h>
14140aa50dSArd Biesheuvel #include <crypto/sm3_base.h>
15140aa50dSArd Biesheuvel #include <linux/cpufeature.h>
16140aa50dSArd Biesheuvel #include <linux/crypto.h>
17140aa50dSArd Biesheuvel #include <linux/module.h>
18140aa50dSArd Biesheuvel
19140aa50dSArd Biesheuvel MODULE_DESCRIPTION("SM3 secure hash using ARMv8 Crypto Extensions");
20140aa50dSArd Biesheuvel MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
21140aa50dSArd Biesheuvel MODULE_LICENSE("GPL v2");
22140aa50dSArd Biesheuvel
23140aa50dSArd Biesheuvel asmlinkage void sm3_ce_transform(struct sm3_state *sst, u8 const *src,
24140aa50dSArd Biesheuvel int blocks);
25140aa50dSArd Biesheuvel
sm3_ce_update(struct shash_desc * desc,const u8 * data,unsigned int len)26140aa50dSArd Biesheuvel static int sm3_ce_update(struct shash_desc *desc, const u8 *data,
27140aa50dSArd Biesheuvel unsigned int len)
28140aa50dSArd Biesheuvel {
29f3a03d31STianjia Zhang if (!crypto_simd_usable()) {
30f3a03d31STianjia Zhang sm3_update(shash_desc_ctx(desc), data, len);
31f3a03d31STianjia Zhang return 0;
32f3a03d31STianjia Zhang }
33140aa50dSArd Biesheuvel
34140aa50dSArd Biesheuvel kernel_neon_begin();
35140aa50dSArd Biesheuvel sm3_base_do_update(desc, data, len, sm3_ce_transform);
36140aa50dSArd Biesheuvel kernel_neon_end();
37140aa50dSArd Biesheuvel
38140aa50dSArd Biesheuvel return 0;
39140aa50dSArd Biesheuvel }
40140aa50dSArd Biesheuvel
sm3_ce_final(struct shash_desc * desc,u8 * out)41140aa50dSArd Biesheuvel static int sm3_ce_final(struct shash_desc *desc, u8 *out)
42140aa50dSArd Biesheuvel {
43f3a03d31STianjia Zhang if (!crypto_simd_usable()) {
44f3a03d31STianjia Zhang sm3_final(shash_desc_ctx(desc), out);
45f3a03d31STianjia Zhang return 0;
46f3a03d31STianjia Zhang }
47140aa50dSArd Biesheuvel
48140aa50dSArd Biesheuvel kernel_neon_begin();
49140aa50dSArd Biesheuvel sm3_base_do_finalize(desc, sm3_ce_transform);
50140aa50dSArd Biesheuvel kernel_neon_end();
51140aa50dSArd Biesheuvel
52140aa50dSArd Biesheuvel return sm3_base_finish(desc, out);
53140aa50dSArd Biesheuvel }
54140aa50dSArd Biesheuvel
sm3_ce_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)55140aa50dSArd Biesheuvel static int sm3_ce_finup(struct shash_desc *desc, const u8 *data,
56140aa50dSArd Biesheuvel unsigned int len, u8 *out)
57140aa50dSArd Biesheuvel {
58f3a03d31STianjia Zhang if (!crypto_simd_usable()) {
59f3a03d31STianjia Zhang struct sm3_state *sctx = shash_desc_ctx(desc);
60f3a03d31STianjia Zhang
61f3a03d31STianjia Zhang if (len)
62f3a03d31STianjia Zhang sm3_update(sctx, data, len);
63f3a03d31STianjia Zhang sm3_final(sctx, out);
64f3a03d31STianjia Zhang return 0;
65f3a03d31STianjia Zhang }
66140aa50dSArd Biesheuvel
67140aa50dSArd Biesheuvel kernel_neon_begin();
68f3a03d31STianjia Zhang if (len)
69140aa50dSArd Biesheuvel sm3_base_do_update(desc, data, len, sm3_ce_transform);
70f3a03d31STianjia Zhang sm3_base_do_finalize(desc, sm3_ce_transform);
71140aa50dSArd Biesheuvel kernel_neon_end();
72140aa50dSArd Biesheuvel
73f3a03d31STianjia Zhang return sm3_base_finish(desc, out);
74140aa50dSArd Biesheuvel }
75140aa50dSArd Biesheuvel
76140aa50dSArd Biesheuvel static struct shash_alg sm3_alg = {
77140aa50dSArd Biesheuvel .digestsize = SM3_DIGEST_SIZE,
78140aa50dSArd Biesheuvel .init = sm3_base_init,
79140aa50dSArd Biesheuvel .update = sm3_ce_update,
80140aa50dSArd Biesheuvel .final = sm3_ce_final,
81140aa50dSArd Biesheuvel .finup = sm3_ce_finup,
82140aa50dSArd Biesheuvel .descsize = sizeof(struct sm3_state),
83140aa50dSArd Biesheuvel .base.cra_name = "sm3",
84140aa50dSArd Biesheuvel .base.cra_driver_name = "sm3-ce",
85140aa50dSArd Biesheuvel .base.cra_blocksize = SM3_BLOCK_SIZE,
86140aa50dSArd Biesheuvel .base.cra_module = THIS_MODULE,
87*e1fa51aaSTianjia Zhang .base.cra_priority = 400,
88140aa50dSArd Biesheuvel };
89140aa50dSArd Biesheuvel
sm3_ce_mod_init(void)90140aa50dSArd Biesheuvel static int __init sm3_ce_mod_init(void)
91140aa50dSArd Biesheuvel {
92140aa50dSArd Biesheuvel return crypto_register_shash(&sm3_alg);
93140aa50dSArd Biesheuvel }
94140aa50dSArd Biesheuvel
sm3_ce_mod_fini(void)95140aa50dSArd Biesheuvel static void __exit sm3_ce_mod_fini(void)
96140aa50dSArd Biesheuvel {
97140aa50dSArd Biesheuvel crypto_unregister_shash(&sm3_alg);
98140aa50dSArd Biesheuvel }
99140aa50dSArd Biesheuvel
100140aa50dSArd Biesheuvel module_cpu_feature_match(SM3, sm3_ce_mod_init);
101140aa50dSArd Biesheuvel module_exit(sm3_ce_mod_fini);
102