diff options
author | Jack Lloyd <[email protected]> | 2016-04-23 07:01:19 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-04-23 07:01:19 -0400 |
commit | bcf13fa153a11b3e0ad54e2af6962441cea3adf1 (patch) | |
tree | 1d08847e69956f84d55b7ccc077f5c30d4c8cd94 /src/utils | |
parent | 6514b1379bf313d83fc008907e2bab5146702810 (diff) |
Fixes for CVE-2015-7827 and CVE-2016-2849
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/ct_utils.h | 137 | ||||
-rw-r--r-- | src/utils/info.txt | 1 |
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 |