diff options
author | Jack Lloyd <[email protected]> | 2015-12-04 15:57:41 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2015-12-04 15:57:41 -0500 |
commit | 2a472e9b33617afa62f5f899ec7eba90eb2f7ece (patch) | |
tree | a1a7d879e1edfe80939817936fb55212a423b3e1 /src/lib | |
parent | 760c8434227be7cea3ac315b3d5610e959af600e (diff) |
Make portable GCM multiply operation run in constant time.
Checked with ctgrind
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/modes/aead/gcm/gcm.cpp | 25 |
1 files changed, 16 insertions, 9 deletions
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 <botan/gcm.h> #include <botan/internal/mode_utils.h> +#include <botan/internal/ct_utils.h> #include <botan/ctr.h> #if defined(BOTAN_HAS_GCM_CLMUL) @@ -32,28 +33,34 @@ void GHASH::gcm_multiply(secure_vector<byte>& 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<u64bit>(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<u64bit>(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<u64bit>(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<u64bit>(x.data(), Z[0], Z[1]); + CT::unpoison(x.data(), x.size()); } void GHASH::ghash_update(secure_vector<byte>& ghash, |