]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
sha3: Fix Keccak when compiled with GCC 13.x
authorTobias Brunner <tobias@strongswan.org>
Thu, 28 Mar 2024 10:51:15 +0000 (11:51 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 2 Apr 2024 12:19:40 +0000 (14:19 +0200)
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.

src/libstrongswan/plugins/sha3/sha3_keccak.c

index e56df011051d7e15aa6f54e6aa396e3b629f3739..69df057d33116724ac318a08e3191534cb2a297f 100644 (file)
@@ -372,7 +372,6 @@ METHOD(sha3_keccak_t, reset, void,
        this->rate_index = 0;
 }
 
-
 METHOD(sha3_keccak_t, absorb, void,
        private_sha3_keccak_t *this, chunk_t data)
 {
@@ -431,8 +430,12 @@ METHOD(sha3_keccak_t, finalize, void,
                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);