aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
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
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')
-rw-r--r--src/lib/mac/cmac/cmac.cpp42
-rw-r--r--src/lib/modes/aead/ocb/info.txt4
-rw-r--r--src/lib/modes/aead/ocb/ocb.cpp6
-rw-r--r--src/lib/modes/aead/siv/siv.cpp7
-rw-r--r--src/lib/utils/info.txt1
-rw-r--r--src/lib/utils/poly_dbl.cpp129
-rw-r--r--src/lib/utils/poly_dbl.h25
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