Botan 1.10.17
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
20namespace Botan {
21
22namespace 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*/
32template<typename T>
33inline 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
44template<typename T>
45inline T select(T mask, T from0, T from1)
46 {
47 return (from0 & mask) | (from1 & ~mask);
48 }
49
50template<typename PredT, typename ValT>
51inline 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
56template<typename T>
57inline T is_zero(T x)
58 {
59 return ~expand_mask(x);
60 }
61
62template<typename T>
63inline T is_equal(T x, T y)
64 {
65 return is_zero(x ^ y);
66 }
67
68template<typename T>
69inline 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
78template<typename T>
79inline T is_lte(T x, T y)
80 {
81 return expand_mask<T>(x <= y);
82 }
83
84template<typename T>
85inline 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
99template<typename T>
100inline 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
113template<typename T>
114inline T expand_top_bit(T a)
115 {
116 return expand_mask<T>(a >> (sizeof(T)*8-1));
117 }
118
119template<typename T>
120inline 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
126template<typename T>
127inline 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 max(T a, T b)
Definition ct_utils.h:120
void cond_zero_mem(T cond, T *array, size_t elems)
Definition ct_utils.h:100
void conditional_copy_mem(T value, T *to, const T *from0, const T *from1, size_t elems)
Definition ct_utils.h:85
T is_equal(T x, T y)
Definition ct_utils.h:63
T min(T a, T b)
Definition ct_utils.h:127
T is_less(T x, T y)
Definition ct_utils.h:69
T expand_mask(T x)
Definition ct_utils.h:33
T select(T mask, T from0, T from1)
Definition ct_utils.h:45
T expand_top_bit(T a)
Definition ct_utils.h:114
T is_lte(T x, T y)
Definition ct_utils.h:79
T is_zero(T x)
Definition ct_utils.h:57
ValT val_or_zero(PredT pred_val, ValT val)
Definition ct_utils.h:51