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