diff options
author | Jack Lloyd <[email protected]> | 2017-08-15 14:34:06 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-08-15 14:34:06 -0400 |
commit | 2266362024009f0364a07dd1bcff5115180f40a7 (patch) | |
tree | 18804ff157bab625de6c095099f74971e529b566 /src/lib/mac/cmac | |
parent | ba2c6c7b020497178776b4574ed329586f97c211 (diff) |
Improve polynomial doubling code, move to util
Now does 64-bits at a time instead of 8 bits, and avoids conditional
timing channel on the XOR carry. Confirmed that at least GCC 7 and
Clang 4 on x86-64 compile the functions without conditional jumps.
Also removes CMAC as a dependency of OCB, which only needed it in
order to call CMAC::poly_double
Diffstat (limited to 'src/lib/mac/cmac')
-rw-r--r-- | src/lib/mac/cmac/cmac.cpp | 42 |
1 files changed, 6 insertions, 36 deletions
diff --git a/src/lib/mac/cmac/cmac.cpp b/src/lib/mac/cmac/cmac.cpp index bb862196f..4d76e4a20 100644 --- a/src/lib/mac/cmac/cmac.cpp +++ b/src/lib/mac/cmac/cmac.cpp @@ -6,6 +6,7 @@ */ #include <botan/cmac.h> +#include <botan/internal/poly_dbl.h> namespace Botan { @@ -14,41 +15,8 @@ namespace Botan { */ secure_vector<uint8_t> CMAC::poly_double(const secure_vector<uint8_t>& in) { - const bool top_carry = static_cast<bool>((in[0] & 0x80) != 0); - secure_vector<uint8_t> out = in; - - uint8_t carry = 0; - for(size_t i = out.size(); i != 0; --i) - { - uint8_t temp = out[i-1]; - out[i-1] = (temp << 1) | carry; - carry = (temp >> 7); - } - - if(top_carry) - { - switch(in.size()) - { - case 8: - out[out.size()-1] ^= 0x1B; - break; - case 16: - out[out.size()-1] ^= 0x87; - break; - case 32: - out[out.size()-2] ^= 0x4; - out[out.size()-1] ^= 0x25; - break; - case 64: - out[out.size()-2] ^= 0x1; - out[out.size()-1] ^= 0x25; - break; - default: - throw Exception("Unsupported CMAC size " + std::to_string(in.size())); - } - } - + poly_double_n(out.data(), out.size()); return out; } @@ -112,8 +80,10 @@ void CMAC::key_schedule(const uint8_t key[], size_t length) clear(); m_cipher->set_key(key, length); m_cipher->encrypt(m_B); - m_B = poly_double(m_B); - m_P = poly_double(m_B); + poly_double_n(m_B.data(), m_B.size()); + + m_P = m_B; + poly_double_n(m_P.data(), m_P.size()); } /* |