Remove /* foo.c */ comments
[openssl.git] / include / internal / constant_time_locl.h
1 /*-
2  * Utilities for constant-time cryptography.
3  *
4  * Author: Emilia Kasper (emilia@openssl.org)
5  * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
6  * (Google).
7  * ====================================================================
8  * Copyright (c) 2014 The OpenSSL Project.  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *    "This product includes cryptographic software written by
21  *     Eric Young (eay@cryptsoft.com)"
22  *    The word 'cryptographic' can be left out if the rouines from the library
23  *    being used are not cryptographic related :-).
24  * 4. If you include any Windows specific code (or a derivative thereof) from
25  *    the apps directory (application code) you must include an acknowledgement:
26  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
27  *
28  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  * The licence and distribution terms for any publically available version or
41  * derivative of this code cannot be changed.  i.e. this code cannot simply be
42  * copied and put under another distribution licence
43  * [including the GNU Public Licence.]
44  */
45
46 #ifndef HEADER_CONSTANT_TIME_LOCL_H
47 # define HEADER_CONSTANT_TIME_LOCL_H
48
49 # include <openssl/e_os2.h>              /* For 'ossl_inline' */
50
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54
55 /*-
56  * The boolean methods return a bitmask of all ones (0xff...f) for true
57  * and 0 for false. This is useful for choosing a value based on the result
58  * of a conditional in constant time. For example,
59  *
60  * if (a < b) {
61  *   c = a;
62  * } else {
63  *   c = b;
64  * }
65  *
66  * can be written as
67  *
68  * unsigned int lt = constant_time_lt(a, b);
69  * c = constant_time_select(lt, a, b);
70  */
71
72 /*
73  * Returns the given value with the MSB copied to all the other
74  * bits. Uses the fact that arithmetic shift shifts-in the sign bit.
75  * However, this is not ensured by the C standard so you may need to
76  * replace this with something else on odd CPUs.
77  */
78 static ossl_inline unsigned int constant_time_msb(unsigned int a);
79
80 /*
81  * Returns 0xff..f if a < b and 0 otherwise.
82  */
83 static ossl_inline unsigned int constant_time_lt(unsigned int a,
84                                                  unsigned int b);
85 /* Convenience method for getting an 8-bit mask. */
86 static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
87                                                     unsigned int b);
88
89 /*
90  * Returns 0xff..f if a >= b and 0 otherwise.
91  */
92 static ossl_inline unsigned int constant_time_ge(unsigned int a,
93                                                  unsigned int b);
94 /* Convenience method for getting an 8-bit mask. */
95 static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
96                                                     unsigned int b);
97
98 /*
99  * Returns 0xff..f if a == 0 and 0 otherwise.
100  */
101 static ossl_inline unsigned int constant_time_is_zero(unsigned int a);
102 /* Convenience method for getting an 8-bit mask. */
103 static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a);
104
105 /*
106  * Returns 0xff..f if a == b and 0 otherwise.
107  */
108 static ossl_inline unsigned int constant_time_eq(unsigned int a,
109                                                  unsigned int b);
110 /* Convenience method for getting an 8-bit mask. */
111 static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
112                                                     unsigned int b);
113 /* Signed integers. */
114 static ossl_inline unsigned int constant_time_eq_int(int a, int b);
115 /* Convenience method for getting an 8-bit mask. */
116 static ossl_inline unsigned char constant_time_eq_int_8(int a, int b);
117
118 /*-
119  * Returns (mask & a) | (~mask & b).
120  *
121  * When |mask| is all 1s or all 0s (as returned by the methods above),
122  * the select methods return either |a| (if |mask| is nonzero) or |b|
123  * (if |mask| is zero).
124  */
125 static ossl_inline unsigned int constant_time_select(unsigned int mask,
126                                                      unsigned int a,
127                                                      unsigned int b);
128 /* Convenience method for unsigned chars. */
129 static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
130                                                         unsigned char a,
131                                                         unsigned char b);
132 /* Convenience method for signed integers. */
133 static ossl_inline int constant_time_select_int(unsigned int mask, int a,
134                                                 int b);
135
136 static ossl_inline unsigned int constant_time_msb(unsigned int a)
137 {
138     return 0 - (a >> (sizeof(a) * 8 - 1));
139 }
140
141 static ossl_inline unsigned int constant_time_lt(unsigned int a,
142                                                  unsigned int b)
143 {
144     return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
145 }
146
147 static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
148                                                     unsigned int b)
149 {
150     return (unsigned char)(constant_time_lt(a, b));
151 }
152
153 static ossl_inline unsigned int constant_time_ge(unsigned int a,
154                                                  unsigned int b)
155 {
156     return ~constant_time_lt(a, b);
157 }
158
159 static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
160                                                     unsigned int b)
161 {
162     return (unsigned char)(constant_time_ge(a, b));
163 }
164
165 static ossl_inline unsigned int constant_time_is_zero(unsigned int a)
166 {
167     return constant_time_msb(~a & (a - 1));
168 }
169
170 static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a)
171 {
172     return (unsigned char)(constant_time_is_zero(a));
173 }
174
175 static ossl_inline unsigned int constant_time_eq(unsigned int a,
176                                                  unsigned int b)
177 {
178     return constant_time_is_zero(a ^ b);
179 }
180
181 static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
182                                                     unsigned int b)
183 {
184     return (unsigned char)(constant_time_eq(a, b));
185 }
186
187 static ossl_inline unsigned int constant_time_eq_int(int a, int b)
188 {
189     return constant_time_eq((unsigned)(a), (unsigned)(b));
190 }
191
192 static ossl_inline unsigned char constant_time_eq_int_8(int a, int b)
193 {
194     return constant_time_eq_8((unsigned)(a), (unsigned)(b));
195 }
196
197 static ossl_inline unsigned int constant_time_select(unsigned int mask,
198                                                      unsigned int a,
199                                                      unsigned int b)
200 {
201     return (mask & a) | (~mask & b);
202 }
203
204 static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
205                                                         unsigned char a,
206                                                         unsigned char b)
207 {
208     return (unsigned char)(constant_time_select(mask, a, b));
209 }
210
211 static ossl_inline int constant_time_select_int(unsigned int mask, int a,
212                                                 int b)
213 {
214     return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
215 }
216
217 #ifdef __cplusplus
218 }
219 #endif
220
221 #endif                          /* HEADER_CONSTANT_TIME_LOCL_H */