The capi engine uses stdio, so don't build it when configuring 'no-stdio'
[openssl.git] / include / internal / constant_time_locl.h
1 /*
2  * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #ifndef HEADER_CONSTANT_TIME_LOCL_H
11 # define HEADER_CONSTANT_TIME_LOCL_H
12
13 # include <openssl/e_os2.h>              /* For 'ossl_inline' */
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18
19 /*-
20  * The boolean methods return a bitmask of all ones (0xff...f) for true
21  * and 0 for false. This is useful for choosing a value based on the result
22  * of a conditional in constant time. For example,
23  *
24  * if (a < b) {
25  *   c = a;
26  * } else {
27  *   c = b;
28  * }
29  *
30  * can be written as
31  *
32  * unsigned int lt = constant_time_lt(a, b);
33  * c = constant_time_select(lt, a, b);
34  */
35
36 /*
37  * Returns the given value with the MSB copied to all the other
38  * bits. Uses the fact that arithmetic shift shifts-in the sign bit.
39  * However, this is not ensured by the C standard so you may need to
40  * replace this with something else on odd CPUs.
41  */
42 static ossl_inline unsigned int constant_time_msb(unsigned int a);
43
44 /*
45  * Returns 0xff..f if a < b and 0 otherwise.
46  */
47 static ossl_inline unsigned int constant_time_lt(unsigned int a,
48                                                  unsigned int b);
49 /* Convenience method for getting an 8-bit mask. */
50 static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
51                                                     unsigned int b);
52
53 /*
54  * Returns 0xff..f if a >= b and 0 otherwise.
55  */
56 static ossl_inline unsigned int constant_time_ge(unsigned int a,
57                                                  unsigned int b);
58 /* Convenience method for getting an 8-bit mask. */
59 static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
60                                                     unsigned int b);
61
62 /*
63  * Returns 0xff..f if a == 0 and 0 otherwise.
64  */
65 static ossl_inline unsigned int constant_time_is_zero(unsigned int a);
66 /* Convenience method for getting an 8-bit mask. */
67 static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a);
68
69 /*
70  * Returns 0xff..f if a == b and 0 otherwise.
71  */
72 static ossl_inline unsigned int constant_time_eq(unsigned int a,
73                                                  unsigned int b);
74 /* Convenience method for getting an 8-bit mask. */
75 static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
76                                                     unsigned int b);
77 /* Signed integers. */
78 static ossl_inline unsigned int constant_time_eq_int(int a, int b);
79 /* Convenience method for getting an 8-bit mask. */
80 static ossl_inline unsigned char constant_time_eq_int_8(int a, int b);
81
82 /*-
83  * Returns (mask & a) | (~mask & b).
84  *
85  * When |mask| is all 1s or all 0s (as returned by the methods above),
86  * the select methods return either |a| (if |mask| is nonzero) or |b|
87  * (if |mask| is zero).
88  */
89 static ossl_inline unsigned int constant_time_select(unsigned int mask,
90                                                      unsigned int a,
91                                                      unsigned int b);
92 /* Convenience method for unsigned chars. */
93 static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
94                                                         unsigned char a,
95                                                         unsigned char b);
96 /* Convenience method for signed integers. */
97 static ossl_inline int constant_time_select_int(unsigned int mask, int a,
98                                                 int b);
99
100 static ossl_inline unsigned int constant_time_msb(unsigned int a)
101 {
102     return 0 - (a >> (sizeof(a) * 8 - 1));
103 }
104
105 static ossl_inline unsigned int constant_time_lt(unsigned int a,
106                                                  unsigned int b)
107 {
108     return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
109 }
110
111 static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
112                                                     unsigned int b)
113 {
114     return (unsigned char)(constant_time_lt(a, b));
115 }
116
117 static ossl_inline unsigned int constant_time_ge(unsigned int a,
118                                                  unsigned int b)
119 {
120     return ~constant_time_lt(a, b);
121 }
122
123 static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
124                                                     unsigned int b)
125 {
126     return (unsigned char)(constant_time_ge(a, b));
127 }
128
129 static ossl_inline unsigned int constant_time_is_zero(unsigned int a)
130 {
131     return constant_time_msb(~a & (a - 1));
132 }
133
134 static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a)
135 {
136     return (unsigned char)(constant_time_is_zero(a));
137 }
138
139 static ossl_inline unsigned int constant_time_eq(unsigned int a,
140                                                  unsigned int b)
141 {
142     return constant_time_is_zero(a ^ b);
143 }
144
145 static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
146                                                     unsigned int b)
147 {
148     return (unsigned char)(constant_time_eq(a, b));
149 }
150
151 static ossl_inline unsigned int constant_time_eq_int(int a, int b)
152 {
153     return constant_time_eq((unsigned)(a), (unsigned)(b));
154 }
155
156 static ossl_inline unsigned char constant_time_eq_int_8(int a, int b)
157 {
158     return constant_time_eq_8((unsigned)(a), (unsigned)(b));
159 }
160
161 static ossl_inline unsigned int constant_time_select(unsigned int mask,
162                                                      unsigned int a,
163                                                      unsigned int b)
164 {
165     return (mask & a) | (~mask & b);
166 }
167
168 static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
169                                                         unsigned char a,
170                                                         unsigned char b)
171 {
172     return (unsigned char)(constant_time_select(mask, a, b));
173 }
174
175 static ossl_inline int constant_time_select_int(unsigned int mask, int a,
176                                                 int b)
177 {
178     return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
179 }
180
181 #ifdef __cplusplus
182 }
183 #endif
184
185 #endif                          /* HEADER_CONSTANT_TIME_LOCL_H */