xref: /openbmc/linux/arch/x86/crypto/blake2s-glue.c (revision b71e2a69)
1ed0356edSJason A. Donenfeld // SPDX-License-Identifier: GPL-2.0 OR MIT
2ed0356edSJason A. Donenfeld /*
3ed0356edSJason A. Donenfeld  * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4ed0356edSJason A. Donenfeld  */
5ed0356edSJason A. Donenfeld 
6ed0356edSJason A. Donenfeld #include <crypto/internal/blake2s.h>
7ed0356edSJason A. Donenfeld 
8ed0356edSJason A. Donenfeld #include <linux/types.h>
9ed0356edSJason A. Donenfeld #include <linux/jump_label.h>
10ed0356edSJason A. Donenfeld #include <linux/kernel.h>
110c3dc787SHerbert Xu #include <linux/sizes.h>
12ed0356edSJason A. Donenfeld 
13ed0356edSJason A. Donenfeld #include <asm/cpufeature.h>
14ed0356edSJason A. Donenfeld #include <asm/fpu/api.h>
15ed0356edSJason A. Donenfeld #include <asm/processor.h>
16ed0356edSJason A. Donenfeld #include <asm/simd.h>
17ed0356edSJason A. Donenfeld 
18ed0356edSJason A. Donenfeld asmlinkage void blake2s_compress_ssse3(struct blake2s_state *state,
19ed0356edSJason A. Donenfeld 				       const u8 *block, const size_t nblocks,
20ed0356edSJason A. Donenfeld 				       const u32 inc);
21ed0356edSJason A. Donenfeld asmlinkage void blake2s_compress_avx512(struct blake2s_state *state,
22ed0356edSJason A. Donenfeld 					const u8 *block, const size_t nblocks,
23ed0356edSJason A. Donenfeld 					const u32 inc);
24ed0356edSJason A. Donenfeld 
25ed0356edSJason A. Donenfeld static __ro_after_init DEFINE_STATIC_KEY_FALSE(blake2s_use_ssse3);
26ed0356edSJason A. Donenfeld static __ro_after_init DEFINE_STATIC_KEY_FALSE(blake2s_use_avx512);
27ed0356edSJason A. Donenfeld 
blake2s_compress(struct blake2s_state * state,const u8 * block,size_t nblocks,const u32 inc)286048fdccSJason A. Donenfeld void blake2s_compress(struct blake2s_state *state, const u8 *block,
296048fdccSJason A. Donenfeld 		      size_t nblocks, const u32 inc)
30ed0356edSJason A. Donenfeld {
31ed0356edSJason A. Donenfeld 	/* SIMD disables preemption, so relax after processing each page. */
32706024a5SJason A. Donenfeld 	BUILD_BUG_ON(SZ_4K / BLAKE2S_BLOCK_SIZE < 8);
33ed0356edSJason A. Donenfeld 
342d16803cSJason A. Donenfeld 	if (!static_branch_likely(&blake2s_use_ssse3) || !may_use_simd()) {
35ed0356edSJason A. Donenfeld 		blake2s_compress_generic(state, block, nblocks, inc);
36ed0356edSJason A. Donenfeld 		return;
37ed0356edSJason A. Donenfeld 	}
38ed0356edSJason A. Donenfeld 
39706024a5SJason A. Donenfeld 	do {
40ed0356edSJason A. Donenfeld 		const size_t blocks = min_t(size_t, nblocks,
41706024a5SJason A. Donenfeld 					    SZ_4K / BLAKE2S_BLOCK_SIZE);
42ed0356edSJason A. Donenfeld 
43ed0356edSJason A. Donenfeld 		kernel_fpu_begin();
44ed0356edSJason A. Donenfeld 		if (IS_ENABLED(CONFIG_AS_AVX512) &&
45ed0356edSJason A. Donenfeld 		    static_branch_likely(&blake2s_use_avx512))
46ed0356edSJason A. Donenfeld 			blake2s_compress_avx512(state, block, blocks, inc);
47ed0356edSJason A. Donenfeld 		else
48ed0356edSJason A. Donenfeld 			blake2s_compress_ssse3(state, block, blocks, inc);
49ed0356edSJason A. Donenfeld 		kernel_fpu_end();
50ed0356edSJason A. Donenfeld 
51ed0356edSJason A. Donenfeld 		nblocks -= blocks;
52ed0356edSJason A. Donenfeld 		block += blocks * BLAKE2S_BLOCK_SIZE;
53706024a5SJason A. Donenfeld 	} while (nblocks);
54ed0356edSJason A. Donenfeld }
556048fdccSJason A. Donenfeld EXPORT_SYMBOL(blake2s_compress);
56ed0356edSJason A. Donenfeld 
blake2s_mod_init(void)57ed0356edSJason A. Donenfeld static int __init blake2s_mod_init(void)
58ed0356edSJason A. Donenfeld {
596048fdccSJason A. Donenfeld 	if (boot_cpu_has(X86_FEATURE_SSSE3))
60ed0356edSJason A. Donenfeld 		static_branch_enable(&blake2s_use_ssse3);
61ed0356edSJason A. Donenfeld 
62ed0356edSJason A. Donenfeld 	if (IS_ENABLED(CONFIG_AS_AVX512) &&
63ed0356edSJason A. Donenfeld 	    boot_cpu_has(X86_FEATURE_AVX) &&
64ed0356edSJason A. Donenfeld 	    boot_cpu_has(X86_FEATURE_AVX2) &&
65ed0356edSJason A. Donenfeld 	    boot_cpu_has(X86_FEATURE_AVX512F) &&
66ed0356edSJason A. Donenfeld 	    boot_cpu_has(X86_FEATURE_AVX512VL) &&
67ed0356edSJason A. Donenfeld 	    cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM |
68ed0356edSJason A. Donenfeld 			      XFEATURE_MASK_AVX512, NULL))
69ed0356edSJason A. Donenfeld 		static_branch_enable(&blake2s_use_avx512);
70ed0356edSJason A. Donenfeld 
716048fdccSJason A. Donenfeld 	return 0;
72ed0356edSJason A. Donenfeld }
73ed0356edSJason A. Donenfeld 
74*b71e2a69SNick Alcock subsys_initcall(blake2s_mod_init);
75