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