xref: /openssl/test/constant_time_test.c (revision 1287dabd)
1 /*
2  * Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 #include <stdio.h>
11 #include <stdlib.h>
12 
13 #include "internal/nelem.h"
14 #include "internal/constant_time.h"
15 #include "testutil.h"
16 #include "internal/numbers.h"
17 
18 static const unsigned int CONSTTIME_TRUE = (unsigned)(~0);
19 static const unsigned int CONSTTIME_FALSE = 0;
20 static const unsigned char CONSTTIME_TRUE_8 = 0xff;
21 static const unsigned char CONSTTIME_FALSE_8 = 0;
22 static const size_t CONSTTIME_TRUE_S = ~((size_t)0);
23 static const size_t CONSTTIME_FALSE_S = 0;
24 static uint32_t CONSTTIME_TRUE_32 = (uint32_t)(~(uint32_t)0);
25 static uint32_t CONSTTIME_FALSE_32 = 0;
26 static uint64_t CONSTTIME_TRUE_64 = (uint64_t)(~(uint64_t)0);
27 static uint64_t CONSTTIME_FALSE_64 = 0;
28 
29 static unsigned int test_values[] = {
30     0, 1, 1024, 12345, 32000, UINT_MAX / 2 - 1,
31     UINT_MAX / 2, UINT_MAX / 2 + 1, UINT_MAX - 1,
32     UINT_MAX
33 };
34 
35 static unsigned char test_values_8[] = {
36     0, 1, 2, 20, 32, 127, 128, 129, 255
37 };
38 
39 static int signed_test_values[] = {
40     0, 1, -1, 1024, -1024, 12345, -12345,
41     32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1,
42     INT_MIN + 1
43 };
44 
45 static size_t test_values_s[] = {
46     0, 1, 1024, 12345, 32000, SIZE_MAX / 2 - 1,
47     SIZE_MAX / 2, SIZE_MAX / 2 + 1, SIZE_MAX - 1,
48     SIZE_MAX
49 };
50 
51 static uint32_t test_values_32[] = {
52     0, 1, 1024, 12345, 32000, UINT32_MAX / 2, UINT32_MAX / 2 + 1,
53     UINT32_MAX - 1, UINT32_MAX
54 };
55 
56 static uint64_t test_values_64[] = {
57     0, 1, 1024, 12345, 32000, 32000000, 32000000001, UINT64_MAX / 2,
58     UINT64_MAX / 2 + 1, UINT64_MAX - 1, UINT64_MAX
59 };
60 
test_binary_op(unsigned int (* op)(unsigned int a,unsigned int b),const char * op_name,unsigned int a,unsigned int b,int is_true)61 static int test_binary_op(unsigned int (*op) (unsigned int a, unsigned int b),
62                           const char *op_name, unsigned int a, unsigned int b,
63                           int is_true)
64 {
65     if (is_true && !TEST_uint_eq(op(a, b), CONSTTIME_TRUE))
66         return 0;
67     if (!is_true && !TEST_uint_eq(op(a, b), CONSTTIME_FALSE))
68         return 0;
69     return 1;
70 }
71 
test_binary_op_8(unsigned char (* op)(unsigned int a,unsigned int b),const char * op_name,unsigned int a,unsigned int b,int is_true)72 static int test_binary_op_8(unsigned
73                             char (*op) (unsigned int a, unsigned int b),
74                             const char *op_name, unsigned int a,
75                             unsigned int b, int is_true)
76 {
77     if (is_true && !TEST_uint_eq(op(a, b), CONSTTIME_TRUE_8))
78         return 0;
79     if (!is_true && !TEST_uint_eq(op(a, b), CONSTTIME_FALSE_8))
80         return 0;
81     return 1;
82 }
83 
test_binary_op_s(size_t (* op)(size_t a,size_t b),const char * op_name,size_t a,size_t b,int is_true)84 static int test_binary_op_s(size_t (*op) (size_t a, size_t b),
85                             const char *op_name, size_t a, size_t b,
86                             int is_true)
87 {
88     if (is_true && !TEST_size_t_eq(op(a, b), CONSTTIME_TRUE_S))
89         return 0;
90     if (!is_true && !TEST_uint_eq(op(a, b), CONSTTIME_FALSE_S))
91         return 0;
92     return 1;
93 }
94 
test_binary_op_64(uint64_t (* op)(uint64_t a,uint64_t b),const char * op_name,uint64_t a,uint64_t b,int is_true)95 static int test_binary_op_64(uint64_t (*op)(uint64_t a, uint64_t b),
96                              const char *op_name, uint64_t a, uint64_t b,
97                              int is_true)
98 {
99     uint64_t c = op(a, b);
100 
101     if (is_true && c != CONSTTIME_TRUE_64) {
102         TEST_error("TRUE %s op failed", op_name);
103         BIO_printf(bio_err, "a=%jx b=%jx\n", a, b);
104         return 0;
105     } else if (!is_true && c != CONSTTIME_FALSE_64) {
106         TEST_error("FALSE %s op failed", op_name);
107         BIO_printf(bio_err, "a=%jx b=%jx\n", a, b);
108         return 0;
109     }
110     return 1;
111 }
112 
test_is_zero(int i)113 static int test_is_zero(int i)
114 {
115     unsigned int a = test_values[i];
116 
117     if (a == 0 && !TEST_uint_eq(constant_time_is_zero(a), CONSTTIME_TRUE))
118         return 0;
119     if (a != 0 && !TEST_uint_eq(constant_time_is_zero(a), CONSTTIME_FALSE))
120         return 0;
121     return 1;
122 }
123 
test_is_zero_8(int i)124 static int test_is_zero_8(int i)
125 {
126     unsigned int a = test_values_8[i];
127 
128     if (a == 0 && !TEST_uint_eq(constant_time_is_zero_8(a), CONSTTIME_TRUE_8))
129         return 0;
130     if (a != 0 && !TEST_uint_eq(constant_time_is_zero_8(a), CONSTTIME_FALSE_8))
131         return 0;
132     return 1;
133 }
134 
test_is_zero_32(int i)135 static int test_is_zero_32(int i)
136 {
137     uint32_t a = test_values_32[i];
138 
139     if (a == 0 && !TEST_true(constant_time_is_zero_32(a) == CONSTTIME_TRUE_32))
140         return 0;
141     if (a != 0 && !TEST_true(constant_time_is_zero_32(a) == CONSTTIME_FALSE_32))
142         return 0;
143     return 1;
144 }
145 
test_is_zero_s(int i)146 static int test_is_zero_s(int i)
147 {
148     size_t a = test_values_s[i];
149 
150     if (a == 0 && !TEST_size_t_eq(constant_time_is_zero_s(a), CONSTTIME_TRUE_S))
151         return 0;
152     if (a != 0 && !TEST_uint_eq(constant_time_is_zero_s(a), CONSTTIME_FALSE_S))
153         return 0;
154     return 1;
155 }
156 
test_select(unsigned int a,unsigned int b)157 static int test_select(unsigned int a, unsigned int b)
158 {
159     if (!TEST_uint_eq(constant_time_select(CONSTTIME_TRUE, a, b), a))
160         return 0;
161     if (!TEST_uint_eq(constant_time_select(CONSTTIME_FALSE, a, b), b))
162         return 0;
163     return 1;
164 }
165 
test_select_8(unsigned char a,unsigned char b)166 static int test_select_8(unsigned char a, unsigned char b)
167 {
168     if (!TEST_uint_eq(constant_time_select_8(CONSTTIME_TRUE_8, a, b), a))
169         return 0;
170     if (!TEST_uint_eq(constant_time_select_8(CONSTTIME_FALSE_8, a, b), b))
171         return 0;
172     return 1;
173 }
174 
test_select_32(uint32_t a,uint32_t b)175 static int test_select_32(uint32_t a, uint32_t b)
176 {
177     if (!TEST_true(constant_time_select_32(CONSTTIME_TRUE_32, a, b) == a))
178         return 0;
179     if (!TEST_true(constant_time_select_32(CONSTTIME_FALSE_32, a, b) == b))
180         return 0;
181     return 1;
182 }
183 
test_select_s(size_t a,size_t b)184 static int test_select_s(size_t a, size_t b)
185 {
186     if (!TEST_uint_eq(constant_time_select_s(CONSTTIME_TRUE_S, a, b), a))
187         return 0;
188     if (!TEST_uint_eq(constant_time_select_s(CONSTTIME_FALSE_S, a, b), b))
189         return 0;
190     return 1;
191 }
192 
test_select_64(uint64_t a,uint64_t b)193 static int test_select_64(uint64_t a, uint64_t b)
194 {
195     uint64_t selected = constant_time_select_64(CONSTTIME_TRUE_64, a, b);
196 
197     if (selected != a) {
198         TEST_error("test_select_64 TRUE failed");
199         BIO_printf(bio_err, "a=%jx b=%jx got %jx wanted a\n", a, b, selected);
200         return 0;
201     }
202     selected = constant_time_select_64(CONSTTIME_FALSE_64, a, b);
203     if (selected != b) {
204         BIO_printf(bio_err, "a=%jx b=%jx got %jx wanted b\n", a, b, selected);
205         return 0;
206     }
207     return 1;
208 }
209 
test_select_int(int a,int b)210 static int test_select_int(int a, int b)
211 {
212     if (!TEST_int_eq(constant_time_select_int(CONSTTIME_TRUE, a, b), a))
213         return 0;
214     if (!TEST_int_eq(constant_time_select_int(CONSTTIME_FALSE, a, b), b))
215         return 0;
216     return 1;
217 }
218 
test_eq_int_8(int a,int b)219 static int test_eq_int_8(int a, int b)
220 {
221     if (a == b && !TEST_int_eq(constant_time_eq_int_8(a, b), CONSTTIME_TRUE_8))
222         return 0;
223     if (a != b && !TEST_int_eq(constant_time_eq_int_8(a, b), CONSTTIME_FALSE_8))
224         return 0;
225     return 1;
226 }
227 
test_eq_s(size_t a,size_t b)228 static int test_eq_s(size_t a, size_t b)
229 {
230     if (a == b && !TEST_size_t_eq(constant_time_eq_s(a, b), CONSTTIME_TRUE_S))
231         return 0;
232     if (a != b && !TEST_int_eq(constant_time_eq_s(a, b), CONSTTIME_FALSE_S))
233         return 0;
234     return 1;
235 }
236 
test_eq_int(int a,int b)237 static int test_eq_int(int a, int b)
238 {
239     if (a == b && !TEST_uint_eq(constant_time_eq_int(a, b), CONSTTIME_TRUE))
240         return 0;
241     if (a != b && !TEST_uint_eq(constant_time_eq_int(a, b), CONSTTIME_FALSE))
242         return 0;
243     return 1;
244 }
245 
test_sizeofs(void)246 static int test_sizeofs(void)
247 {
248     if (!TEST_uint_eq(OSSL_NELEM(test_values), OSSL_NELEM(test_values_s)))
249         return 0;
250     return 1;
251 }
252 
test_binops(int i)253 static int test_binops(int i)
254 {
255     unsigned int a = test_values[i];
256     int j;
257     int ret = 1;
258 
259     for (j = 0; j < (int)OSSL_NELEM(test_values); ++j) {
260         unsigned int b = test_values[j];
261 
262         if (!test_select(a, b)
263                 || !test_binary_op(&constant_time_lt, "ct_lt",
264                                    a, b, a < b)
265                 || !test_binary_op(&constant_time_lt, "constant_time_lt",
266                                    b, a, b < a)
267                 || !test_binary_op(&constant_time_ge, "constant_time_ge",
268                                    a, b, a >= b)
269                 || !test_binary_op(&constant_time_ge, "constant_time_ge",
270                                    b, a, b >= a)
271                 || !test_binary_op(&constant_time_eq, "constant_time_eq",
272                                    a, b, a == b)
273                 || !test_binary_op(&constant_time_eq, "constant_time_eq",
274                                    b, a, b == a))
275             ret = 0;
276     }
277     return ret;
278 }
279 
test_binops_8(int i)280 static int test_binops_8(int i)
281 {
282     unsigned int a = test_values_8[i];
283     int j;
284     int ret = 1;
285 
286     for (j = 0; j < (int)OSSL_NELEM(test_values_8); ++j) {
287         unsigned int b = test_values_8[j];
288 
289         if (!test_binary_op_8(&constant_time_lt_8, "constant_time_lt_8",
290                                      a, b, a < b)
291                 || !test_binary_op_8(&constant_time_lt_8, "constant_time_lt_8",
292                                      b, a, b < a)
293                 || !test_binary_op_8(&constant_time_ge_8, "constant_time_ge_8",
294                                      a, b, a >= b)
295                 || !test_binary_op_8(&constant_time_ge_8, "constant_time_ge_8",
296                                      b, a, b >= a)
297                 || !test_binary_op_8(&constant_time_eq_8, "constant_time_eq_8",
298                                      a, b, a == b)
299                 || !test_binary_op_8(&constant_time_eq_8, "constant_time_eq_8",
300                                      b, a, b == a))
301             ret = 0;
302     }
303     return ret;
304 }
305 
test_binops_s(int i)306 static int test_binops_s(int i)
307 {
308     size_t a = test_values_s[i];
309     int j;
310     int ret = 1;
311 
312     for (j = 0; j < (int)OSSL_NELEM(test_values_s); ++j) {
313         size_t b = test_values_s[j];
314 
315         if (!test_select_s(a, b)
316                 || !test_eq_s(a, b)
317                 || !test_binary_op_s(&constant_time_lt_s, "constant_time_lt_s",
318                                      a, b, a < b)
319                 || !test_binary_op_s(&constant_time_lt_s, "constant_time_lt_s",
320                                      b, a, b < a)
321                 || !test_binary_op_s(&constant_time_ge_s, "constant_time_ge_s",
322                                      a, b, a >= b)
323                 || !test_binary_op_s(&constant_time_ge_s, "constant_time_ge_s",
324                                      b, a, b >= a)
325                 || !test_binary_op_s(&constant_time_eq_s, "constant_time_eq_s",
326                                      a, b, a == b)
327                 || !test_binary_op_s(&constant_time_eq_s, "constant_time_eq_s",
328                                      b, a, b == a))
329             ret = 0;
330     }
331     return ret;
332 }
333 
test_signed(int i)334 static int test_signed(int i)
335 {
336     int c = signed_test_values[i];
337     unsigned int j;
338     int ret = 1;
339 
340     for (j = 0; j < OSSL_NELEM(signed_test_values); ++j) {
341         int d = signed_test_values[j];
342 
343         if (!test_select_int(c, d)
344                 || !test_eq_int(c, d)
345                 || !test_eq_int_8(c, d))
346             ret = 0;
347     }
348     return ret;
349 }
350 
test_8values(int i)351 static int test_8values(int i)
352 {
353     unsigned char e = test_values_8[i];
354     unsigned int j;
355     int ret = 1;
356 
357     for (j = 0; j < sizeof(test_values_8); ++j) {
358         unsigned char f = test_values_8[j];
359 
360         if (!test_select_8(e, f))
361             ret = 0;
362     }
363     return ret;
364 }
365 
test_32values(int i)366 static int test_32values(int i)
367 {
368     uint32_t e = test_values_32[i];
369     size_t j;
370     int ret = 1;
371 
372     for (j = 0; j < OSSL_NELEM(test_values_32); j++) {
373         uint32_t f = test_values_32[j];
374 
375         if (!test_select_32(e, f))
376             ret = 0;
377     }
378     return ret;
379 }
380 
test_64values(int i)381 static int test_64values(int i)
382 {
383     uint64_t g = test_values_64[i];
384     int j, ret = 1;
385 
386     for (j = i + 1; j < (int)OSSL_NELEM(test_values_64); j++) {
387         uint64_t h = test_values_64[j];
388 
389         if (!test_binary_op_64(&constant_time_lt_64, "constant_time_lt_64",
390                                g, h, g < h)
391                 || !test_select_64(g, h)) {
392             TEST_info("test_64values failed i=%d j=%d", i, j);
393             ret = 0;
394         }
395     }
396     return ret;
397 }
398 
setup_tests(void)399 int setup_tests(void)
400 {
401     ADD_TEST(test_sizeofs);
402     ADD_ALL_TESTS(test_is_zero, OSSL_NELEM(test_values));
403     ADD_ALL_TESTS(test_is_zero_8, OSSL_NELEM(test_values_8));
404     ADD_ALL_TESTS(test_is_zero_32, OSSL_NELEM(test_values_32));
405     ADD_ALL_TESTS(test_is_zero_s, OSSL_NELEM(test_values_s));
406     ADD_ALL_TESTS(test_binops, OSSL_NELEM(test_values));
407     ADD_ALL_TESTS(test_binops_8, OSSL_NELEM(test_values_8));
408     ADD_ALL_TESTS(test_binops_s, OSSL_NELEM(test_values_s));
409     ADD_ALL_TESTS(test_signed, OSSL_NELEM(signed_test_values));
410     ADD_ALL_TESTS(test_8values, OSSL_NELEM(test_values_8));
411     ADD_ALL_TESTS(test_32values, OSSL_NELEM(test_values_32));
412     ADD_ALL_TESTS(test_64values, OSSL_NELEM(test_values_64));
413     return 1;
414 }
415