aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/mac/cmac
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-08-15 14:34:06 -0400
committerJack Lloyd <[email protected]>2017-08-15 14:34:06 -0400
commit2266362024009f0364a07dd1bcff5115180f40a7 (patch)
tree18804ff157bab625de6c095099f74971e529b566 /src/lib/mac/cmac
parentba2c6c7b020497178776b4574ed329586f97c211 (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.cpp42
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());
}
/*