From 2a472e9b33617afa62f5f899ec7eba90eb2f7ece Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 4 Dec 2015 15:57:41 -0500 Subject: Make portable GCM multiply operation run in constant time. Checked with ctgrind --- src/lib/modes/aead/gcm/gcm.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp index 7dcdd0d31..15820069d 100644 --- a/src/lib/modes/aead/gcm/gcm.cpp +++ b/src/lib/modes/aead/gcm/gcm.cpp @@ -1,12 +1,13 @@ /* * GCM Mode Encryption -* (C) 2013 Jack Lloyd +* (C) 2013,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include #include +#include #include #if defined(BOTAN_HAS_GCM_CLMUL) @@ -32,28 +33,34 @@ void GHASH::gcm_multiply(secure_vector& x) const u64bit Z[2] = { 0, 0 }; + CT::poison(H, 2); + CT::poison(Z, 2); + CT::poison(x.data(), x.size()); + // SSE2 might be useful here for(size_t i = 0; i != 2; ++i) { const u64bit X = load_be(x.data(), i); + u64bit mask = 0x8000000000000000; for(size_t j = 0; j != 64; ++j) { - if((X >> (63-j)) & 1) - { - Z[0] ^= H[0]; - Z[1] ^= H[1]; - } + const u64bit XMASK = CT::expand_mask(X & mask); + mask >>= 1; + Z[0] ^= H[0] & XMASK; + Z[1] ^= H[1] & XMASK; - const u64bit r = (H[1] & 1) ? R : 0; + // GCM's bit ops are reversed so we carry out of the bottom + const u64bit carry = R & CT::expand_mask(H[1] & 1); - H[1] = (H[0] << 63) | (H[1] >> 1); - H[0] = (H[0] >> 1) ^ r; + H[1] = (H[1] >> 1) | (H[0] << 63); + H[0] = (H[0] >> 1) ^ carry; } } store_be(x.data(), Z[0], Z[1]); + CT::unpoison(x.data(), x.size()); } void GHASH::ghash_update(secure_vector& ghash, -- cgit v1.2.3