Botan  1.10.16
ct_utils.h
Go to the documentation of this file.
1 /*
2 * Functions for constant time operations on data and testing of
3 * constant time annotations using valgrind.
4 *
5 * For more information about constant time programming see
6 * Wagner, Molnar, et al "The Program Counter Security Model"
7 *
8 * (C) 2010 Falko Strenzke
9 * (C) 2015,2016 Jack Lloyd
10 *
11 * Botan is released under the Simplified BSD License (see license.txt)
12 */
13 
14 #ifndef BOTAN_TIMING_ATTACK_CM_H__
15 #define BOTAN_TIMING_ATTACK_CM_H__
16 
17 #include <botan/secmem.h>
18 #include <vector>
19 
20 namespace Botan {
21 
22 namespace CT {
23 
24 /*
25 * T should be an unsigned machine integer type
26 * Expand to a mask used for other operations
27 * @param in an integer
28 * @return If n is zero, returns zero. Otherwise
29 * returns a T with all bits set for use as a mask with
30 * select.
31 */
32 template<typename T>
33 inline T expand_mask(T x)
34  {
35  T r = x;
36  // First fold r down to a single bit
37  for(size_t i = 1; i != sizeof(T)*8; i *= 2)
38  r |= r >> i;
39  r &= 1;
40  r = ~(r - 1);
41  return r;
42  }
43 
44 template<typename T>
45 inline T select(T mask, T from0, T from1)
46  {
47  return (from0 & mask) | (from1 & ~mask);
48  }
49 
50 template<typename PredT, typename ValT>
51 inline ValT val_or_zero(PredT pred_val, ValT val)
52  {
53  return select(CT::expand_mask<ValT>(pred_val), val, static_cast<ValT>(0));
54  }
55 
56 template<typename T>
57 inline T is_zero(T x)
58  {
59  return ~expand_mask(x);
60  }
61 
62 template<typename T>
63 inline T is_equal(T x, T y)
64  {
65  return is_zero(x ^ y);
66  }
67 
68 template<typename T>
69 inline T is_less(T x, T y)
70  {
71  /*
72  This expands to a constant time sequence with GCC 5.2.0 on x86-64
73  but something more complicated may be needed for portable const time.
74  */
75  return expand_mask<T>(x < y);
76  }
77 
78 template<typename T>
79 inline T is_lte(T x, T y)
80  {
81  return expand_mask<T>(x <= y);
82  }
83 
84 template<typename T>
85 inline void conditional_copy_mem(T value,
86  T* to,
87  const T* from0,
88  const T* from1,
89  size_t elems)
90  {
91  const T mask = CT::expand_mask(value);
92 
93  for(size_t i = 0; i != elems; ++i)
94  {
95  to[i] = CT::select(mask, from0[i], from1[i]);
96  }
97  }
98 
99 template<typename T>
100 inline void cond_zero_mem(T cond,
101  T* array,
102  size_t elems)
103  {
104  const T mask = CT::expand_mask(cond);
105  const T zero(0);
106 
107  for(size_t i = 0; i != elems; ++i)
108  {
109  array[i] = CT::select(mask, zero, array[i]);
110  }
111  }
112 
113 template<typename T>
114 inline T expand_top_bit(T a)
115  {
116  return expand_mask<T>(a >> (sizeof(T)*8-1));
117  }
118 
119 template<typename T>
120 inline T max(T a, T b)
121  {
122  const T a_larger = b - a; // negative if a is larger
123  return select(expand_top_bit(a), a, b);
124  }
125 
126 template<typename T>
127 inline T min(T a, T b)
128  {
129  const T a_larger = b - a; // negative if a is larger
130  return select(expand_top_bit(b), b, a);
131  }
132 
133 }
134 
135 }
136 
137 #endif
T expand_top_bit(T a)
Definition: ct_utils.h:114
void conditional_copy_mem(T value, T *to, const T *from0, const T *from1, size_t elems)
Definition: ct_utils.h:85
T is_less(T x, T y)
Definition: ct_utils.h:69
T is_lte(T x, T y)
Definition: ct_utils.h:79
T is_equal(T x, T y)
Definition: ct_utils.h:63
void cond_zero_mem(T cond, T *array, size_t elems)
Definition: ct_utils.h:100
T expand_mask(T x)
Definition: ct_utils.h:33
T select(T mask, T from0, T from1)
Definition: ct_utils.h:45
T max(T a, T b)
Definition: ct_utils.h:120
ValT val_or_zero(PredT pred_val, ValT val)
Definition: ct_utils.h:51
T is_zero(T x)
Definition: ct_utils.h:57
T min(T a, T b)
Definition: ct_utils.h:127