1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Cryptographic API.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Glue code for the SHA1 Secure Hash Algorithm assembler implementation using
6*4882a593Smuzhiyun * Supplemental SSE3 instructions.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * This file is based on sha1_generic.c
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Copyright (c) Alan Smithee.
11*4882a593Smuzhiyun * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
12*4882a593Smuzhiyun * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
13*4882a593Smuzhiyun * Copyright (c) Mathias Krause <minipli@googlemail.com>
14*4882a593Smuzhiyun * Copyright (c) Chandramouli Narayanan <mouli@linux.intel.com>
15*4882a593Smuzhiyun */
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <crypto/internal/hash.h>
20*4882a593Smuzhiyun #include <crypto/internal/simd.h>
21*4882a593Smuzhiyun #include <linux/init.h>
22*4882a593Smuzhiyun #include <linux/module.h>
23*4882a593Smuzhiyun #include <linux/mm.h>
24*4882a593Smuzhiyun #include <linux/types.h>
25*4882a593Smuzhiyun #include <crypto/sha.h>
26*4882a593Smuzhiyun #include <crypto/sha1_base.h>
27*4882a593Smuzhiyun #include <asm/simd.h>
28*4882a593Smuzhiyun
sha1_update(struct shash_desc * desc,const u8 * data,unsigned int len,sha1_block_fn * sha1_xform)29*4882a593Smuzhiyun static int sha1_update(struct shash_desc *desc, const u8 *data,
30*4882a593Smuzhiyun unsigned int len, sha1_block_fn *sha1_xform)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun struct sha1_state *sctx = shash_desc_ctx(desc);
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun if (!crypto_simd_usable() ||
35*4882a593Smuzhiyun (sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE)
36*4882a593Smuzhiyun return crypto_sha1_update(desc, data, len);
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun /*
39*4882a593Smuzhiyun * Make sure struct sha1_state begins directly with the SHA1
40*4882a593Smuzhiyun * 160-bit internal state, as this is what the asm functions expect.
41*4882a593Smuzhiyun */
42*4882a593Smuzhiyun BUILD_BUG_ON(offsetof(struct sha1_state, state) != 0);
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun kernel_fpu_begin();
45*4882a593Smuzhiyun sha1_base_do_update(desc, data, len, sha1_xform);
46*4882a593Smuzhiyun kernel_fpu_end();
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun return 0;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
sha1_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out,sha1_block_fn * sha1_xform)51*4882a593Smuzhiyun static int sha1_finup(struct shash_desc *desc, const u8 *data,
52*4882a593Smuzhiyun unsigned int len, u8 *out, sha1_block_fn *sha1_xform)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun if (!crypto_simd_usable())
55*4882a593Smuzhiyun return crypto_sha1_finup(desc, data, len, out);
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun kernel_fpu_begin();
58*4882a593Smuzhiyun if (len)
59*4882a593Smuzhiyun sha1_base_do_update(desc, data, len, sha1_xform);
60*4882a593Smuzhiyun sha1_base_do_finalize(desc, sha1_xform);
61*4882a593Smuzhiyun kernel_fpu_end();
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun return sha1_base_finish(desc, out);
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun asmlinkage void sha1_transform_ssse3(struct sha1_state *state,
67*4882a593Smuzhiyun const u8 *data, int blocks);
68*4882a593Smuzhiyun
sha1_ssse3_update(struct shash_desc * desc,const u8 * data,unsigned int len)69*4882a593Smuzhiyun static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
70*4882a593Smuzhiyun unsigned int len)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun return sha1_update(desc, data, len, sha1_transform_ssse3);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
sha1_ssse3_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)75*4882a593Smuzhiyun static int sha1_ssse3_finup(struct shash_desc *desc, const u8 *data,
76*4882a593Smuzhiyun unsigned int len, u8 *out)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun return sha1_finup(desc, data, len, out, sha1_transform_ssse3);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /* Add padding and return the message digest. */
sha1_ssse3_final(struct shash_desc * desc,u8 * out)82*4882a593Smuzhiyun static int sha1_ssse3_final(struct shash_desc *desc, u8 *out)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun return sha1_ssse3_finup(desc, NULL, 0, out);
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun static struct shash_alg sha1_ssse3_alg = {
88*4882a593Smuzhiyun .digestsize = SHA1_DIGEST_SIZE,
89*4882a593Smuzhiyun .init = sha1_base_init,
90*4882a593Smuzhiyun .update = sha1_ssse3_update,
91*4882a593Smuzhiyun .final = sha1_ssse3_final,
92*4882a593Smuzhiyun .finup = sha1_ssse3_finup,
93*4882a593Smuzhiyun .descsize = sizeof(struct sha1_state),
94*4882a593Smuzhiyun .base = {
95*4882a593Smuzhiyun .cra_name = "sha1",
96*4882a593Smuzhiyun .cra_driver_name = "sha1-ssse3",
97*4882a593Smuzhiyun .cra_priority = 150,
98*4882a593Smuzhiyun .cra_blocksize = SHA1_BLOCK_SIZE,
99*4882a593Smuzhiyun .cra_module = THIS_MODULE,
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun
register_sha1_ssse3(void)103*4882a593Smuzhiyun static int register_sha1_ssse3(void)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun if (boot_cpu_has(X86_FEATURE_SSSE3))
106*4882a593Smuzhiyun return crypto_register_shash(&sha1_ssse3_alg);
107*4882a593Smuzhiyun return 0;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun
unregister_sha1_ssse3(void)110*4882a593Smuzhiyun static void unregister_sha1_ssse3(void)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun if (boot_cpu_has(X86_FEATURE_SSSE3))
113*4882a593Smuzhiyun crypto_unregister_shash(&sha1_ssse3_alg);
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun asmlinkage void sha1_transform_avx(struct sha1_state *state,
117*4882a593Smuzhiyun const u8 *data, int blocks);
118*4882a593Smuzhiyun
sha1_avx_update(struct shash_desc * desc,const u8 * data,unsigned int len)119*4882a593Smuzhiyun static int sha1_avx_update(struct shash_desc *desc, const u8 *data,
120*4882a593Smuzhiyun unsigned int len)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun return sha1_update(desc, data, len, sha1_transform_avx);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
sha1_avx_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)125*4882a593Smuzhiyun static int sha1_avx_finup(struct shash_desc *desc, const u8 *data,
126*4882a593Smuzhiyun unsigned int len, u8 *out)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun return sha1_finup(desc, data, len, out, sha1_transform_avx);
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
sha1_avx_final(struct shash_desc * desc,u8 * out)131*4882a593Smuzhiyun static int sha1_avx_final(struct shash_desc *desc, u8 *out)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun return sha1_avx_finup(desc, NULL, 0, out);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun static struct shash_alg sha1_avx_alg = {
137*4882a593Smuzhiyun .digestsize = SHA1_DIGEST_SIZE,
138*4882a593Smuzhiyun .init = sha1_base_init,
139*4882a593Smuzhiyun .update = sha1_avx_update,
140*4882a593Smuzhiyun .final = sha1_avx_final,
141*4882a593Smuzhiyun .finup = sha1_avx_finup,
142*4882a593Smuzhiyun .descsize = sizeof(struct sha1_state),
143*4882a593Smuzhiyun .base = {
144*4882a593Smuzhiyun .cra_name = "sha1",
145*4882a593Smuzhiyun .cra_driver_name = "sha1-avx",
146*4882a593Smuzhiyun .cra_priority = 160,
147*4882a593Smuzhiyun .cra_blocksize = SHA1_BLOCK_SIZE,
148*4882a593Smuzhiyun .cra_module = THIS_MODULE,
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun };
151*4882a593Smuzhiyun
avx_usable(void)152*4882a593Smuzhiyun static bool avx_usable(void)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
155*4882a593Smuzhiyun if (boot_cpu_has(X86_FEATURE_AVX))
156*4882a593Smuzhiyun pr_info("AVX detected but unusable.\n");
157*4882a593Smuzhiyun return false;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun return true;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
register_sha1_avx(void)163*4882a593Smuzhiyun static int register_sha1_avx(void)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun if (avx_usable())
166*4882a593Smuzhiyun return crypto_register_shash(&sha1_avx_alg);
167*4882a593Smuzhiyun return 0;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
unregister_sha1_avx(void)170*4882a593Smuzhiyun static void unregister_sha1_avx(void)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun if (avx_usable())
173*4882a593Smuzhiyun crypto_unregister_shash(&sha1_avx_alg);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun #define SHA1_AVX2_BLOCK_OPTSIZE 4 /* optimal 4*64 bytes of SHA1 blocks */
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun asmlinkage void sha1_transform_avx2(struct sha1_state *state,
179*4882a593Smuzhiyun const u8 *data, int blocks);
180*4882a593Smuzhiyun
avx2_usable(void)181*4882a593Smuzhiyun static bool avx2_usable(void)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun if (avx_usable() && boot_cpu_has(X86_FEATURE_AVX2)
184*4882a593Smuzhiyun && boot_cpu_has(X86_FEATURE_BMI1)
185*4882a593Smuzhiyun && boot_cpu_has(X86_FEATURE_BMI2))
186*4882a593Smuzhiyun return true;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun return false;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun
sha1_apply_transform_avx2(struct sha1_state * state,const u8 * data,int blocks)191*4882a593Smuzhiyun static void sha1_apply_transform_avx2(struct sha1_state *state,
192*4882a593Smuzhiyun const u8 *data, int blocks)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun /* Select the optimal transform based on data block size */
195*4882a593Smuzhiyun if (blocks >= SHA1_AVX2_BLOCK_OPTSIZE)
196*4882a593Smuzhiyun sha1_transform_avx2(state, data, blocks);
197*4882a593Smuzhiyun else
198*4882a593Smuzhiyun sha1_transform_avx(state, data, blocks);
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
sha1_avx2_update(struct shash_desc * desc,const u8 * data,unsigned int len)201*4882a593Smuzhiyun static int sha1_avx2_update(struct shash_desc *desc, const u8 *data,
202*4882a593Smuzhiyun unsigned int len)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun return sha1_update(desc, data, len, sha1_apply_transform_avx2);
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun
sha1_avx2_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)207*4882a593Smuzhiyun static int sha1_avx2_finup(struct shash_desc *desc, const u8 *data,
208*4882a593Smuzhiyun unsigned int len, u8 *out)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun return sha1_finup(desc, data, len, out, sha1_apply_transform_avx2);
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun
sha1_avx2_final(struct shash_desc * desc,u8 * out)213*4882a593Smuzhiyun static int sha1_avx2_final(struct shash_desc *desc, u8 *out)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun return sha1_avx2_finup(desc, NULL, 0, out);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun static struct shash_alg sha1_avx2_alg = {
219*4882a593Smuzhiyun .digestsize = SHA1_DIGEST_SIZE,
220*4882a593Smuzhiyun .init = sha1_base_init,
221*4882a593Smuzhiyun .update = sha1_avx2_update,
222*4882a593Smuzhiyun .final = sha1_avx2_final,
223*4882a593Smuzhiyun .finup = sha1_avx2_finup,
224*4882a593Smuzhiyun .descsize = sizeof(struct sha1_state),
225*4882a593Smuzhiyun .base = {
226*4882a593Smuzhiyun .cra_name = "sha1",
227*4882a593Smuzhiyun .cra_driver_name = "sha1-avx2",
228*4882a593Smuzhiyun .cra_priority = 170,
229*4882a593Smuzhiyun .cra_blocksize = SHA1_BLOCK_SIZE,
230*4882a593Smuzhiyun .cra_module = THIS_MODULE,
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun };
233*4882a593Smuzhiyun
register_sha1_avx2(void)234*4882a593Smuzhiyun static int register_sha1_avx2(void)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun if (avx2_usable())
237*4882a593Smuzhiyun return crypto_register_shash(&sha1_avx2_alg);
238*4882a593Smuzhiyun return 0;
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun
unregister_sha1_avx2(void)241*4882a593Smuzhiyun static void unregister_sha1_avx2(void)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun if (avx2_usable())
244*4882a593Smuzhiyun crypto_unregister_shash(&sha1_avx2_alg);
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun #ifdef CONFIG_AS_SHA1_NI
248*4882a593Smuzhiyun asmlinkage void sha1_ni_transform(struct sha1_state *digest, const u8 *data,
249*4882a593Smuzhiyun int rounds);
250*4882a593Smuzhiyun
sha1_ni_update(struct shash_desc * desc,const u8 * data,unsigned int len)251*4882a593Smuzhiyun static int sha1_ni_update(struct shash_desc *desc, const u8 *data,
252*4882a593Smuzhiyun unsigned int len)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun return sha1_update(desc, data, len, sha1_ni_transform);
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
sha1_ni_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)257*4882a593Smuzhiyun static int sha1_ni_finup(struct shash_desc *desc, const u8 *data,
258*4882a593Smuzhiyun unsigned int len, u8 *out)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun return sha1_finup(desc, data, len, out, sha1_ni_transform);
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
sha1_ni_final(struct shash_desc * desc,u8 * out)263*4882a593Smuzhiyun static int sha1_ni_final(struct shash_desc *desc, u8 *out)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun return sha1_ni_finup(desc, NULL, 0, out);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun static struct shash_alg sha1_ni_alg = {
269*4882a593Smuzhiyun .digestsize = SHA1_DIGEST_SIZE,
270*4882a593Smuzhiyun .init = sha1_base_init,
271*4882a593Smuzhiyun .update = sha1_ni_update,
272*4882a593Smuzhiyun .final = sha1_ni_final,
273*4882a593Smuzhiyun .finup = sha1_ni_finup,
274*4882a593Smuzhiyun .descsize = sizeof(struct sha1_state),
275*4882a593Smuzhiyun .base = {
276*4882a593Smuzhiyun .cra_name = "sha1",
277*4882a593Smuzhiyun .cra_driver_name = "sha1-ni",
278*4882a593Smuzhiyun .cra_priority = 250,
279*4882a593Smuzhiyun .cra_blocksize = SHA1_BLOCK_SIZE,
280*4882a593Smuzhiyun .cra_module = THIS_MODULE,
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun };
283*4882a593Smuzhiyun
register_sha1_ni(void)284*4882a593Smuzhiyun static int register_sha1_ni(void)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun if (boot_cpu_has(X86_FEATURE_SHA_NI))
287*4882a593Smuzhiyun return crypto_register_shash(&sha1_ni_alg);
288*4882a593Smuzhiyun return 0;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
unregister_sha1_ni(void)291*4882a593Smuzhiyun static void unregister_sha1_ni(void)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun if (boot_cpu_has(X86_FEATURE_SHA_NI))
294*4882a593Smuzhiyun crypto_unregister_shash(&sha1_ni_alg);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun #else
register_sha1_ni(void)298*4882a593Smuzhiyun static inline int register_sha1_ni(void) { return 0; }
unregister_sha1_ni(void)299*4882a593Smuzhiyun static inline void unregister_sha1_ni(void) { }
300*4882a593Smuzhiyun #endif
301*4882a593Smuzhiyun
sha1_ssse3_mod_init(void)302*4882a593Smuzhiyun static int __init sha1_ssse3_mod_init(void)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun if (register_sha1_ssse3())
305*4882a593Smuzhiyun goto fail;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun if (register_sha1_avx()) {
308*4882a593Smuzhiyun unregister_sha1_ssse3();
309*4882a593Smuzhiyun goto fail;
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun if (register_sha1_avx2()) {
313*4882a593Smuzhiyun unregister_sha1_avx();
314*4882a593Smuzhiyun unregister_sha1_ssse3();
315*4882a593Smuzhiyun goto fail;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun if (register_sha1_ni()) {
319*4882a593Smuzhiyun unregister_sha1_avx2();
320*4882a593Smuzhiyun unregister_sha1_avx();
321*4882a593Smuzhiyun unregister_sha1_ssse3();
322*4882a593Smuzhiyun goto fail;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun return 0;
326*4882a593Smuzhiyun fail:
327*4882a593Smuzhiyun return -ENODEV;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
sha1_ssse3_mod_fini(void)330*4882a593Smuzhiyun static void __exit sha1_ssse3_mod_fini(void)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun unregister_sha1_ni();
333*4882a593Smuzhiyun unregister_sha1_avx2();
334*4882a593Smuzhiyun unregister_sha1_avx();
335*4882a593Smuzhiyun unregister_sha1_ssse3();
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun module_init(sha1_ssse3_mod_init);
339*4882a593Smuzhiyun module_exit(sha1_ssse3_mod_fini);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun MODULE_LICENSE("GPL");
342*4882a593Smuzhiyun MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, Supplemental SSE3 accelerated");
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun MODULE_ALIAS_CRYPTO("sha1");
345*4882a593Smuzhiyun MODULE_ALIAS_CRYPTO("sha1-ssse3");
346*4882a593Smuzhiyun MODULE_ALIAS_CRYPTO("sha1-avx");
347*4882a593Smuzhiyun MODULE_ALIAS_CRYPTO("sha1-avx2");
348*4882a593Smuzhiyun #ifdef CONFIG_AS_SHA1_NI
349*4882a593Smuzhiyun MODULE_ALIAS_CRYPTO("sha1-ni");
350*4882a593Smuzhiyun #endif
351