aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils/mem_ops.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-09-16 14:45:17 -0400
committerJack Lloyd <[email protected]>2017-09-16 14:45:17 -0400
commitf39aa7bb4e43e27b10d3f890da7ba1acba9f14ca (patch)
tree44eb974c45b4c644c2932502962a6c403b00f8b4 /src/lib/utils/mem_ops.cpp
parent4c8b0316defbe9e6bfb3b3ce68c506b437760af0 (diff)
De-inline xor_buf, add SIMD and unrolling
Improves CBC and OCB performance with AES-NI quite noticably
Diffstat (limited to 'src/lib/utils/mem_ops.cpp')
-rw-r--r--src/lib/utils/mem_ops.cpp86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/lib/utils/mem_ops.cpp b/src/lib/utils/mem_ops.cpp
new file mode 100644
index 000000000..41a1bc547
--- /dev/null
+++ b/src/lib/utils/mem_ops.cpp
@@ -0,0 +1,86 @@
+/*
+* (C) 2017 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/mem_ops.h>
+
+#if defined(BOTAN_HAS_SIMD_32)
+ #include <botan/internal/simd_32.h>
+ #include <botan/cpuid.h>
+#endif
+
+namespace Botan {
+
+bool constant_time_compare(const uint8_t x[],
+ const uint8_t y[],
+ size_t len)
+ {
+ volatile uint8_t difference = 0;
+
+ for(size_t i = 0; i != len; ++i)
+ difference |= (x[i] ^ y[i]);
+
+ return difference == 0;
+ }
+
+void xor_buf(uint8_t x[],
+ const uint8_t y[],
+ size_t len)
+ {
+#if defined(BOTAN_HAS_SIMD_32)
+ if(CPUID::has_simd_32())
+ {
+ while(len >= 16)
+ {
+ SIMD_32 x16 = SIMD_32::load_le(x);
+ SIMD_32 y16 = SIMD_32::load_le(y);
+ x16 ^= y16;
+ x16.store_le(x);
+
+ len -= 16;
+ x += 16;
+ y += 16;
+ }
+ }
+#endif
+
+ while(len >= 8)
+ {
+ x[0] ^= y[0]; x[1] ^= y[1];
+ x[2] ^= y[2]; x[3] ^= y[3];
+ x[4] ^= y[4]; x[5] ^= y[5];
+ x[6] ^= y[6]; x[7] ^= y[7];
+ x += 8; y += 8; len -= 8;
+ }
+
+ for(size_t i = 0; i != len; ++i)
+ {
+ x[i] ^= y[i];
+ }
+ }
+
+void xor_buf(uint8_t out[],
+ const uint8_t in[],
+ const uint8_t in2[],
+ size_t length)
+ {
+ while(length >= 8)
+ {
+ out[0] = in[0] ^ in2[0];
+ out[1] = in[1] ^ in2[1];
+ out[2] = in[2] ^ in2[2];
+ out[3] = in[3] ^ in2[3];
+ out[4] = in[4] ^ in2[4];
+ out[5] = in[5] ^ in2[5];
+ out[6] = in[6] ^ in2[6];
+ out[7] = in[7] ^ in2[7];
+ in += 8; in2 += 8; out += 8; length -= 8;
+ }
+
+ for(size_t i = 0; i != length; ++i)
+ out[i] = in[i] ^ in2[i];
+ }
+
+}