xref: /linux/lib/crypto/arm64/poly1305.h (revision d8768fb12a14c30436bd0466b4fc28edeef45078)
1*b646b782SEric Biggers /* SPDX-License-Identifier: GPL-2.0 */
2*b646b782SEric Biggers /*
3*b646b782SEric Biggers  * OpenSSL/Cryptogams accelerated Poly1305 transform for arm64
4*b646b782SEric Biggers  *
5*b646b782SEric Biggers  * Copyright (C) 2019 Linaro Ltd. <ard.biesheuvel@linaro.org>
6*b646b782SEric Biggers  */
7*b646b782SEric Biggers 
8*b646b782SEric Biggers #include <asm/hwcap.h>
9*b646b782SEric Biggers #include <asm/neon.h>
10*b646b782SEric Biggers #include <asm/simd.h>
11*b646b782SEric Biggers #include <linux/cpufeature.h>
12*b646b782SEric Biggers #include <linux/jump_label.h>
13*b646b782SEric Biggers #include <linux/kernel.h>
14*b646b782SEric Biggers 
15*b646b782SEric Biggers asmlinkage void poly1305_block_init(struct poly1305_block_state *state,
16*b646b782SEric Biggers 				    const u8 raw_key[POLY1305_BLOCK_SIZE]);
17*b646b782SEric Biggers asmlinkage void poly1305_blocks_arm64(struct poly1305_block_state *state,
18*b646b782SEric Biggers 				      const u8 *src, u32 len, u32 hibit);
19*b646b782SEric Biggers asmlinkage void poly1305_blocks_neon(struct poly1305_block_state *state,
20*b646b782SEric Biggers 				     const u8 *src, u32 len, u32 hibit);
21*b646b782SEric Biggers asmlinkage void poly1305_emit(const struct poly1305_state *state,
22*b646b782SEric Biggers 			      u8 digest[POLY1305_DIGEST_SIZE],
23*b646b782SEric Biggers 			      const u32 nonce[4]);
24*b646b782SEric Biggers 
25*b646b782SEric Biggers static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon);
26*b646b782SEric Biggers 
poly1305_blocks(struct poly1305_block_state * state,const u8 * src,unsigned int len,u32 padbit)27*b646b782SEric Biggers static void poly1305_blocks(struct poly1305_block_state *state, const u8 *src,
28*b646b782SEric Biggers 			    unsigned int len, u32 padbit)
29*b646b782SEric Biggers {
30*b646b782SEric Biggers 	if (static_branch_likely(&have_neon) && likely(may_use_simd())) {
31*b646b782SEric Biggers 		do {
32*b646b782SEric Biggers 			unsigned int todo = min_t(unsigned int, len, SZ_4K);
33*b646b782SEric Biggers 
34*b646b782SEric Biggers 			kernel_neon_begin();
35*b646b782SEric Biggers 			poly1305_blocks_neon(state, src, todo, padbit);
36*b646b782SEric Biggers 			kernel_neon_end();
37*b646b782SEric Biggers 
38*b646b782SEric Biggers 			len -= todo;
39*b646b782SEric Biggers 			src += todo;
40*b646b782SEric Biggers 		} while (len);
41*b646b782SEric Biggers 	} else
42*b646b782SEric Biggers 		poly1305_blocks_arm64(state, src, len, padbit);
43*b646b782SEric Biggers }
44*b646b782SEric Biggers 
45*b646b782SEric Biggers #define poly1305_mod_init_arch poly1305_mod_init_arch
poly1305_mod_init_arch(void)46*b646b782SEric Biggers static void poly1305_mod_init_arch(void)
47*b646b782SEric Biggers {
48*b646b782SEric Biggers 	if (cpu_have_named_feature(ASIMD))
49*b646b782SEric Biggers 		static_branch_enable(&have_neon);
50*b646b782SEric Biggers }
51