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 | |
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')
-rw-r--r-- | src/lib/mac/cmac/cmac.cpp | 42 | ||||
-rw-r--r-- | src/lib/modes/aead/ocb/info.txt | 4 | ||||
-rw-r--r-- | src/lib/modes/aead/ocb/ocb.cpp | 6 | ||||
-rw-r--r-- | src/lib/modes/aead/siv/siv.cpp | 7 | ||||
-rw-r--r-- | src/lib/utils/info.txt | 1 | ||||
-rw-r--r-- | src/lib/utils/poly_dbl.cpp | 129 | ||||
-rw-r--r-- | src/lib/utils/poly_dbl.h | 25 |
7 files changed, 169 insertions, 45 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()); } /* diff --git a/src/lib/modes/aead/ocb/info.txt b/src/lib/modes/aead/ocb/info.txt index 738d7c20e..ab4c5297e 100644 --- a/src/lib/modes/aead/ocb/info.txt +++ b/src/lib/modes/aead/ocb/info.txt @@ -1,7 +1,3 @@ <defines> AEAD_OCB -> 20131128 </defines> - -<requires> -cmac -</requires> diff --git a/src/lib/modes/aead/ocb/ocb.cpp b/src/lib/modes/aead/ocb/ocb.cpp index e1fae911b..42118c25c 100644 --- a/src/lib/modes/aead/ocb/ocb.cpp +++ b/src/lib/modes/aead/ocb/ocb.cpp @@ -7,7 +7,7 @@ */ #include <botan/ocb.h> -#include <botan/cmac.h> +#include <botan/internal/poly_dbl.h> #include <botan/internal/bit_ops.h> namespace Botan { @@ -56,7 +56,9 @@ class L_computer secure_vector<uint8_t> poly_double(const secure_vector<uint8_t>& in) const { - return CMAC::poly_double(in); + secure_vector<uint8_t> out = in; + poly_double_n(out.data(), out.size()); + return out; } secure_vector<uint8_t> m_L_dollar, m_L_star; diff --git a/src/lib/modes/aead/siv/siv.cpp b/src/lib/modes/aead/siv/siv.cpp index c4db3d785..70545243b 100644 --- a/src/lib/modes/aead/siv/siv.cpp +++ b/src/lib/modes/aead/siv/siv.cpp @@ -8,6 +8,7 @@ #include <botan/siv.h> #include <botan/cmac.h> +#include <botan/internal/poly_dbl.h> #include <botan/ctr.h> #include <botan/parsing.h> @@ -106,19 +107,19 @@ secure_vector<uint8_t> SIV_Mode::S2V(const uint8_t* text, size_t text_len) for(size_t i = 0; i != m_ad_macs.size(); ++i) { - V = CMAC::poly_double(V); + poly_double_n(V.data(), V.size()); V ^= m_ad_macs[i]; } if(m_nonce.size()) { - V = CMAC::poly_double(V); + poly_double_n(V.data(), V.size()); V ^= m_nonce; } if(text_len < 16) { - V = CMAC::poly_double(V); + poly_double_n(V.data(), V.size()); xor_buf(V.data(), text, text_len); V[text_len] ^= 0x80; return m_cmac->process(V); diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt index 193145c5d..cd0b4bc45 100644 --- a/src/lib/utils/info.txt +++ b/src/lib/utils/info.txt @@ -32,6 +32,7 @@ ct_utils.h donna128.h filesystem.h os_utils.h +poly_dbl.h prefetch.h rounding.h safeint.h diff --git a/src/lib/utils/poly_dbl.cpp b/src/lib/utils/poly_dbl.cpp new file mode 100644 index 000000000..0cea4957b --- /dev/null +++ b/src/lib/utils/poly_dbl.cpp @@ -0,0 +1,129 @@ +/* +* (C) 2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/internal/poly_dbl.h> +#include <botan/loadstor.h> +#include <botan/exceptn.h> + +namespace Botan { + +void poly_double_n(uint8_t b[], size_t n) + { + if(n == 8) + return poly_double_8(b); + else if(n == 16) + return poly_double_16(b); + else if(n == 24) + return poly_double_24(b); + else if(n == 32) + return poly_double_32(b); + else if(n == 64) + return poly_double_64(b); + else + throw Invalid_Argument("Unsupported size for poly_double_n"); + } + +void poly_double_8(uint8_t b[8]) + { + const uint64_t poly = 0x1B; + uint64_t b0 = load_be<uint64_t>(b, 0); + const uint64_t carry0 = (b0 >> 63); + b0 = (b0 << 1) ^ (carry0 * poly); + store_be(b0, b); + } + +void poly_double_16(uint8_t b[16]) + { + const uint64_t poly = 0x87; + + uint64_t b0 = load_be<uint64_t>(b, 0); + uint64_t b1 = load_be<uint64_t>(b, 1); + + const uint64_t carry0 = (b0 >> 63); + + b0 = (b0 << 1) ^ (b1 >> 63); + b1 = (b1 << 1) ^ (carry0 * poly); + + store_be(b0, b); + store_be(b1, b+8); + } + +void poly_double_24(uint8_t b[24]) + { + const uint64_t poly = 0x87; + + uint64_t b0 = load_be<uint64_t>(b, 0); + uint64_t b1 = load_be<uint64_t>(b, 1); + uint64_t b2 = load_be<uint64_t>(b, 2); + + const uint64_t carry0 = (b0 >> 63); + + b0 = (b0 << 1) ^ (b1 >> 63); + b1 = (b1 << 1) ^ (b2 >> 63); + b2 = (b2 << 1) ^ (carry0 * poly); + + store_be(b0, b); + store_be(b1, b+8); + store_be(b2, b+16); + } + +void poly_double_32(uint8_t b[32]) + { + const uint64_t poly = 0x425; + + uint64_t b0 = load_be<uint64_t>(b, 0); + uint64_t b1 = load_be<uint64_t>(b, 1); + uint64_t b2 = load_be<uint64_t>(b, 2); + uint64_t b3 = load_be<uint64_t>(b, 3); + + const uint64_t carry0 = (b0 >> 63); + + b0 = (b0 << 1) ^ (b1 >> 63); + b1 = (b1 << 1) ^ (b2 >> 63); + b2 = (b2 << 1) ^ (b3 >> 63); + b3 = (b3 << 1) ^ (carry0 * poly); + + store_be(b0, b); + store_be(b1, b+8); + store_be(b2, b+16); + store_be(b3, b+24); + } + +void poly_double_64(uint8_t b[64]) + { + const uint64_t poly = 0x125; + + uint64_t b0 = load_be<uint64_t>(b, 0); + uint64_t b1 = load_be<uint64_t>(b, 1); + uint64_t b2 = load_be<uint64_t>(b, 2); + uint64_t b3 = load_be<uint64_t>(b, 3); + uint64_t b4 = load_be<uint64_t>(b, 4); + uint64_t b5 = load_be<uint64_t>(b, 5); + uint64_t b6 = load_be<uint64_t>(b, 6); + uint64_t b7 = load_be<uint64_t>(b, 7); + + const uint64_t carry0 = (b0 >> 63); + + b0 = (b0 << 1) ^ (b1 >> 63); + b1 = (b1 << 1) ^ (b2 >> 63); + b2 = (b2 << 1) ^ (b3 >> 63); + b3 = (b3 << 1) ^ (b4 >> 63); + b4 = (b4 << 1) ^ (b5 >> 63); + b5 = (b5 << 1) ^ (b6 >> 63); + b6 = (b6 << 1) ^ (b7 >> 63); + b7 = (b7 << 1) ^ (carry0 * poly); + + store_be(b0, b); + store_be(b1, b+8); + store_be(b2, b+16); + store_be(b3, b+24); + store_be(b4, b+32); + store_be(b5, b+40); + store_be(b6, b+48); + store_be(b7, b+56); + } + +} diff --git a/src/lib/utils/poly_dbl.h b/src/lib/utils/poly_dbl.h new file mode 100644 index 000000000..df3b419c3 --- /dev/null +++ b/src/lib/utils/poly_dbl.h @@ -0,0 +1,25 @@ +/* +* (C) 2017 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_POLY_DBL_H__ +#define BOTAN_POLY_DBL_H__ + +#include <botan/types.h> + +namespace Botan { + +void BOTAN_DLL poly_double_n(uint8_t b[], size_t n); + +void poly_double_8(uint8_t b[8]); +void poly_double_16(uint8_t b[16]); +void poly_double_24(uint8_t b[24]); +void poly_double_32(uint8_t b[32]); +void poly_double_64(uint8_t b[64]); + + +} + +#endif |