From 98e1f0dba724808776ed59d41e388461ee2dabd2 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 5 Feb 2026 23:08:48 +0100 Subject: [PATCH] SHAKE: in case update is called right after squeezing, permute Calling update after squeezing is undocumented and non standard, but if an application still decides to do it, permute the state before absorbing so that it's still safe to do so. We can easily do it since we keep track of the state. Still return an error as this is not the expected usage of SHAKE, and zeroing the state is another thing we could do. --- src/libsodium/crypto_xof/shake128/ref/shake128_ref.c | 5 ++++- src/libsodium/crypto_xof/shake256/ref/shake256_ref.c | 5 ++++- .../crypto_xof/turboshake128/ref/turboshake128_ref.c | 5 ++++- .../crypto_xof/turboshake256/ref/turboshake256_ref.c | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c b/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c index 5df0f8d9..94a151a7 100644 --- a/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c +++ b/src/libsodium/crypto_xof/shake128/ref/shake128_ref.c @@ -28,10 +28,13 @@ shake128_ref_update(shake128_state_internal *state, const unsigned char *in, siz { size_t consumed = 0; size_t chunk_size; + int ret = 0; if (state->phase != SHAKE128_PHASE_ABSORBING) { + crypto_core_keccak1600_permute_24(&state->state); state->phase = SHAKE128_PHASE_ABSORBING; state->offset = 0; + ret = -1; } while (consumed < inlen) { @@ -48,7 +51,7 @@ shake128_ref_update(shake128_state_internal *state, const unsigned char *in, siz consumed += chunk_size; } - return 0; + return ret; } static void diff --git a/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c b/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c index 7b4b4909..1ca46206 100644 --- a/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c +++ b/src/libsodium/crypto_xof/shake256/ref/shake256_ref.c @@ -28,10 +28,13 @@ shake256_ref_update(shake256_state_internal *state, const unsigned char *in, siz { size_t consumed = 0; size_t chunk_size; + int ret = 0; if (state->phase != SHAKE256_PHASE_ABSORBING) { + crypto_core_keccak1600_permute_24(&state->state); state->phase = SHAKE256_PHASE_ABSORBING; state->offset = 0; + ret = -1; } while (consumed < inlen) { @@ -48,7 +51,7 @@ shake256_ref_update(shake256_state_internal *state, const unsigned char *in, siz consumed += chunk_size; } - return 0; + return ret; } static void diff --git a/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c b/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c index 0adc33c7..6e281891 100644 --- a/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c +++ b/src/libsodium/crypto_xof/turboshake128/ref/turboshake128_ref.c @@ -28,10 +28,13 @@ turboshake128_ref_update(turboshake128_state_internal *state, const unsigned cha { size_t consumed = 0; size_t chunk_size; + int ret = 0; if (state->phase != TURBOSHAKE128_PHASE_ABSORBING) { + crypto_core_keccak1600_permute_12(&state->state); state->phase = TURBOSHAKE128_PHASE_ABSORBING; state->offset = 0; + ret = -1; } while (consumed < inlen) { @@ -48,7 +51,7 @@ turboshake128_ref_update(turboshake128_state_internal *state, const unsigned cha consumed += chunk_size; } - return 0; + return ret; } static void diff --git a/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c b/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c index 4193ae71..3d5e6f06 100644 --- a/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c +++ b/src/libsodium/crypto_xof/turboshake256/ref/turboshake256_ref.c @@ -28,10 +28,13 @@ turboshake256_ref_update(turboshake256_state_internal *state, const unsigned cha { size_t consumed = 0; size_t chunk_size; + int ret = 0; if (state->phase != TURBOSHAKE256_PHASE_ABSORBING) { + crypto_core_keccak1600_permute_12(&state->state); state->phase = TURBOSHAKE256_PHASE_ABSORBING; state->offset = 0; + ret = -1; } while (consumed < inlen) { @@ -48,7 +51,7 @@ turboshake256_ref_update(turboshake256_state_internal *state, const unsigned cha consumed += chunk_size; } - return 0; + return ret; } static void