aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-04-23 07:01:19 -0400
committerJack Lloyd <[email protected]>2016-04-23 07:01:19 -0400
commitbcf13fa153a11b3e0ad54e2af6962441cea3adf1 (patch)
tree1d08847e69956f84d55b7ccc077f5c30d4c8cd94 /src/utils
parent6514b1379bf313d83fc008907e2bab5146702810 (diff)
Fixes for CVE-2015-7827 and CVE-2016-2849
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/ct_utils.h137
-rw-r--r--src/utils/info.txt1
2 files changed, 138 insertions, 0 deletions
diff --git a/src/utils/ct_utils.h b/src/utils/ct_utils.h
new file mode 100644
index 000000000..0eab90636
--- /dev/null
+++ b/src/utils/ct_utils.h
@@ -0,0 +1,137 @@
+/*
+* Functions for constant time operations on data and testing of
+* constant time annotations using valgrind.
+*
+* For more information about constant time programming see
+* Wagner, Molnar, et al "The Program Counter Security Model"
+*
+* (C) 2010 Falko Strenzke
+* (C) 2015,2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_TIMING_ATTACK_CM_H__
+#define BOTAN_TIMING_ATTACK_CM_H__
+
+#include <botan/secmem.h>
+#include <vector>
+
+namespace Botan {
+
+namespace CT {
+
+/*
+* T should be an unsigned machine integer type
+* Expand to a mask used for other operations
+* @param in an integer
+* @return If n is zero, returns zero. Otherwise
+* returns a T with all bits set for use as a mask with
+* select.
+*/
+template<typename T>
+inline T expand_mask(T x)
+ {
+ T r = x;
+ // First fold r down to a single bit
+ for(size_t i = 1; i != sizeof(T)*8; i *= 2)
+ r |= r >> i;
+ r &= 1;
+ r = ~(r - 1);
+ return r;
+ }
+
+template<typename T>
+inline T select(T mask, T from0, T from1)
+ {
+ return (from0 & mask) | (from1 & ~mask);
+ }
+
+template<typename PredT, typename ValT>
+inline ValT val_or_zero(PredT pred_val, ValT val)
+ {
+ return select(CT::expand_mask<ValT>(pred_val), val, static_cast<ValT>(0));
+ }
+
+template<typename T>
+inline T is_zero(T x)
+ {
+ return ~expand_mask(x);
+ }
+
+template<typename T>
+inline T is_equal(T x, T y)
+ {
+ return is_zero(x ^ y);
+ }
+
+template<typename T>
+inline T is_less(T x, T y)
+ {
+ /*
+ This expands to a constant time sequence with GCC 5.2.0 on x86-64
+ but something more complicated may be needed for portable const time.
+ */
+ return expand_mask<T>(x < y);
+ }
+
+template<typename T>
+inline T is_lte(T x, T y)
+ {
+ return expand_mask<T>(x <= y);
+ }
+
+template<typename T>
+inline void conditional_copy_mem(T value,
+ T* to,
+ const T* from0,
+ const T* from1,
+ size_t elems)
+ {
+ const T mask = CT::expand_mask(value);
+
+ for(size_t i = 0; i != elems; ++i)
+ {
+ to[i] = CT::select(mask, from0[i], from1[i]);
+ }
+ }
+
+template<typename T>
+inline void cond_zero_mem(T cond,
+ T* array,
+ size_t elems)
+ {
+ const T mask = CT::expand_mask(cond);
+ const T zero(0);
+
+ for(size_t i = 0; i != elems; ++i)
+ {
+ array[i] = CT::select(mask, zero, array[i]);
+ }
+ }
+
+template<typename T>
+inline T expand_top_bit(T a)
+ {
+ return expand_mask<T>(a >> (sizeof(T)*8-1));
+ }
+
+template<typename T>
+inline T max(T a, T b)
+ {
+ const T a_larger = b - a; // negative if a is larger
+ return select(expand_top_bit(a), a, b);
+ }
+
+template<typename T>
+inline T min(T a, T b)
+ {
+ const T a_larger = b - a; // negative if a is larger
+ return select(expand_top_bit(b), b, a);
+ }
+
+}
+
+}
+
+#endif
diff --git a/src/utils/info.txt b/src/utils/info.txt
index fcf16bd5a..57b6a2740 100644
--- a/src/utils/info.txt
+++ b/src/utils/info.txt
@@ -16,6 +16,7 @@ version.cpp
<header:internal>
assert.h
bit_ops.h
+ct_utils.h
mlock.h
prefetch.h
rounding.h