aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-12-04 15:57:41 -0500
committerJack Lloyd <[email protected]>2015-12-04 15:57:41 -0500
commit2a472e9b33617afa62f5f899ec7eba90eb2f7ece (patch)
treea1a7d879e1edfe80939817936fb55212a423b3e1
parent760c8434227be7cea3ac315b3d5610e959af600e (diff)
Make portable GCM multiply operation run in constant time.
Checked with ctgrind
-rw-r--r--src/lib/modes/aead/gcm/gcm.cpp25
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,