/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2018 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_sha3); asmlinkage size_t sha3_ce_transform(struct sha3_state *state, const u8 *data, size_t nblocks, size_t block_size); static void sha3_absorb_blocks(struct sha3_state *state, const u8 *data, size_t nblocks, size_t block_size) { if (static_branch_likely(&have_sha3) && likely(may_use_simd())) { do { size_t rem; scoped_ksimd() rem = sha3_ce_transform(state, data, nblocks, block_size); data += (nblocks - rem) * block_size; nblocks = rem; } while (nblocks); } else { sha3_absorb_blocks_generic(state, data, nblocks, block_size); } } static void sha3_keccakf(struct sha3_state *state) { if (static_branch_likely(&have_sha3) && likely(may_use_simd())) { /* * Passing zeroes into sha3_ce_transform() gives the plain * Keccak-f permutation, which is what we want here. Any * supported block size may be used. Use SHA3_512_BLOCK_SIZE * since it's the shortest. */ static const u8 zeroes[SHA3_512_BLOCK_SIZE]; scoped_ksimd() sha3_ce_transform(state, zeroes, 1, sizeof(zeroes)); } else { sha3_keccakf_generic(state); } } #define sha3_mod_init_arch sha3_mod_init_arch static void sha3_mod_init_arch(void) { if (cpu_have_named_feature(SHA3)) static_branch_enable(&have_sha3); }