xref: /linux/lib/crypto/arm64/sha3.h (revision 2f22115709fc7ebcfa40af3367a508fbbd2f71e9)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9 
10 #include <asm/neon.h>
11 #include <asm/simd.h>
12 #include <linux/cpufeature.h>
13 
14 static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_sha3);
15 
16 asmlinkage size_t sha3_ce_transform(struct sha3_state *state, const u8 *data,
17 				    size_t nblocks, size_t block_size);
18 
19 static void sha3_absorb_blocks(struct sha3_state *state, const u8 *data,
20 			       size_t nblocks, size_t block_size)
21 {
22 	if (static_branch_likely(&have_sha3) && likely(may_use_simd())) {
23 		do {
24 			size_t rem;
25 
26 			kernel_neon_begin();
27 			rem = sha3_ce_transform(state, data, nblocks,
28 						block_size);
29 			kernel_neon_end();
30 			data += (nblocks - rem) * block_size;
31 			nblocks = rem;
32 		} while (nblocks);
33 	} else {
34 		sha3_absorb_blocks_generic(state, data, nblocks, block_size);
35 	}
36 }
37 
38 static void sha3_keccakf(struct sha3_state *state)
39 {
40 	if (static_branch_likely(&have_sha3) && likely(may_use_simd())) {
41 		/*
42 		 * Passing zeroes into sha3_ce_transform() gives the plain
43 		 * Keccak-f permutation, which is what we want here.  Any
44 		 * supported block size may be used.  Use SHA3_512_BLOCK_SIZE
45 		 * since it's the shortest.
46 		 */
47 		static const u8 zeroes[SHA3_512_BLOCK_SIZE];
48 
49 		kernel_neon_begin();
50 		sha3_ce_transform(state, zeroes, 1, sizeof(zeroes));
51 		kernel_neon_end();
52 	} else {
53 		sha3_keccakf_generic(state);
54 	}
55 }
56 
57 #define sha3_mod_init_arch sha3_mod_init_arch
58 static void sha3_mod_init_arch(void)
59 {
60 	if (cpu_have_named_feature(SHA3))
61 		static_branch_enable(&have_sha3);
62 }
63