In crypto/sha3_generic.c, the keccakf() function calls keccakf_round() to do most of the transforms, but not the Iota transform - presumably because that is dependent on round number, whereas the Theta, Rho, Pi and Chi transforms are not.
Note that the keccakf_round() function needs to be explicitly non-inlined on certain architectures as gcc's produced output will (or used to) use over 1KiB of stack space if inlined. Now, this code was copied more or less verbatim into lib/crypto/sha3.c, so that has the same aesthetic issue. Fix this there by passing the round number into sha3_keccakf_one_round_generic() and doing the Iota transform there. crypto/sha3_generic.c is left untouched as that will be converted to use lib/crypto/sha3.c at some point. Suggested-by: Eric Biggers <[email protected]> Signed-off-by: David Howells <[email protected]> cc: Eric Biggers <[email protected]> cc: Jason A. Donenfeld <[email protected]> cc: Ard Biesheuvel <[email protected]> cc: Herbert Xu <[email protected]> cc: Stephan Mueller <[email protected]> cc: [email protected] --- lib/crypto/sha3.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index 5f847a5eecdc..2c292b0b3db3 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -48,7 +48,8 @@ static const u64 sha3_keccakf_rndc[24] = { /* * Perform a single round of Keccak mixing. */ -static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state) +static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state, + int round) { u64 *st = state->st; u64 t[5], tt, bc[5]; @@ -150,15 +151,15 @@ static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *state) st[22] ^= bc[ 2]; st[23] ^= bc[ 3]; st[24] ^= bc[ 4]; + + /* Iota */ + state->st[0] ^= sha3_keccakf_rndc[round]; } static void sha3_keccakf_rounds_generic(struct sha3_state *state) { - for (int round = 0; round < SHA3_KECCAK_ROUNDS; round++) { - sha3_keccakf_one_round_generic(state); - /* Iota */ - state->st[0] ^= sha3_keccakf_rndc[round]; - } + for (int round = 0; round < SHA3_KECCAK_ROUNDS; round++) + sha3_keccakf_one_round_generic(state, round); } /*
