aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-08-13 04:21:24 -0400
committerJack Lloyd <[email protected]>2017-08-13 04:21:24 -0400
commit3e1312d905dac01f317138b68fd284799a5abc29 (patch)
treef1ab113603d6dd26888a2d4317a8e893ee69d264
parent1b1ba82d317528314ab679dd9b8aeb004d6f201e (diff)
Modify GOST-34.11 hash to avoid a GCC miscompilation.
For whatever reason GCC 7 on i386 miscompiles this loop under -O3. I was not able to reduce the bug to a small testcase - extracting the problem section of the code to its own file, it behaves correctly. Also oddly, I was never able to repro this using Arch's gcc-multilib i386 compiler. But when compiled with the 'native' i386 compiler in a chroot it immediately fails. See GH #1148 and GH #882
-rw-r--r--src/lib/hash/gost_3411/gost_3411.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/lib/hash/gost_3411/gost_3411.cpp b/src/lib/hash/gost_3411/gost_3411.cpp
index 2e2ed962d..27773c795 100644
--- a/src/lib/hash/gost_3411/gost_3411.cpp
+++ b/src/lib/hash/gost_3411/gost_3411.cpp
@@ -92,8 +92,11 @@ void GOST_34_11::compress_n(const uint8_t input[], size_t blocks)
// P transformation
for(size_t k = 0; k != 4; ++k)
+ {
+ const uint64_t UVk = U[k] ^ V[k];
for(size_t l = 0; l != 8; ++l)
- key[4*l+k] = get_byte(l, U[k]) ^ get_byte(l, V[k]);
+ key[4*l+k] = get_byte(l, UVk);
+ }
m_cipher.set_key(key, 32);
m_cipher.encrypt(&m_hash[8*j], S + 8*j);