With GCC 13, the compiler apparently applies new aliasing optimizations
when compiled with -O2 and without -fno-strict-aliasing. This caused
the application of the second padding bit, where the state was accessed
via uint8_t[], to be moved before the loop that absorbs the buffer into
the state, where the state is accessed via uint64_t[], resulting in
incorrect output. By only accessing the state via uint64_t[] here the
compiler won't reorder the instructions.
this->rate_index = 0;
}
-
METHOD(sha3_keccak_t, absorb, void,
private_sha3_keccak_t *this, chunk_t data)
{
state_lanes[i] ^= buffer_lanes[i];
}
- /* Add the second bit of padding */
- this->state[this->rate - 1] ^= 0x80;
+ /* Add the second bit of padding, do this consistently via state_lanes[] and
+ * not state[] to avoid that the compiler reorders this due to aliasing
+ * optimizations */
+ rate_lanes = (this->rate - 1) / sizeof(uint64_t);
+ remainder = (this->rate - 1) % sizeof(uint64_t);
+ state_lanes[rate_lanes] ^= (0x80ULL << remainder * 8);
/* Switch to the squeezing phase */
keccak_f1600_state_permute(this->state);