blob: 14dc8ae5cda9997cf3f691ce2e90a775fd60aea1 [file] [log] [blame]
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +01001/* BEGIN_HEADER */
2/** \file test_suite_constant_time.function
3 *
4 * Functional testing of functions in the constant_time module.
5 *
6 * The tests are instrumented with #TEST_CF_SECRET and #TEST_CF_PUBLIC
7 * (see tests/include/test/constant_flow.h) so that running the tests
8 * under MSan or Valgrind will detect a non-constant-time implementation.
9 */
10
11#include <mbedtls/constant_time.h>
12#include <constant_time_internal.h>
13#include <constant_time_invasive.h>
14
15#include <test/constant_flow.h>
16/* END_HEADER */
17
Dave Rodgman39188c02022-12-23 12:27:04 +000018/* BEGIN_CASE */
19void mbedtls_ct_memcmp_null()
20{
21 uint32_t x;
22 TEST_ASSERT(mbedtls_ct_memcmp(&x, NULL, 0) == 0);
23 TEST_ASSERT(mbedtls_ct_memcmp(NULL, &x, 0) == 0);
24 TEST_ASSERT(mbedtls_ct_memcmp(NULL, NULL, 0) == 0);
25}
26/* END_CASE */
27
28/* BEGIN_CASE */
29void mbedtls_ct_memcmp(int same, int size, int offset)
30{
31 uint8_t *a = NULL, *b = NULL;
32 ASSERT_ALLOC(a, size + offset);
33 ASSERT_ALLOC(b, size + offset);
34
35 TEST_CF_SECRET(a + offset, size);
36 TEST_CF_SECRET(b + offset, size);
37
Dave Rodgman22b0d1a2023-01-21 10:29:00 +000038 /* Construct data that matches, if same == -1, otherwise
39 * same gives the number of bytes (after the initial offset)
40 * that will match; after that it will differ.
41 */
Dave Rodgman39188c02022-12-23 12:27:04 +000042 for (int i = 0; i < size + offset; i++) {
43 a[i] = i & 0xff;
Dave Rodgman22b0d1a2023-01-21 10:29:00 +000044 if (same == -1 || (i - offset) < same) {
45 b[i] = a[i];
46 } else {
47 b[i] = (i + 1) & 0xff;
48 }
Dave Rodgman39188c02022-12-23 12:27:04 +000049 }
50
51 int reference = memcmp(a + offset, b + offset, size);
52 int actual = mbedtls_ct_memcmp(a + offset, b + offset, size);
53 TEST_CF_PUBLIC(a + offset, size);
54 TEST_CF_PUBLIC(b + offset, size);
55
Dave Rodgman22b0d1a2023-01-21 10:29:00 +000056 if (same == -1 || same >= size) {
Dave Rodgman39188c02022-12-23 12:27:04 +000057 TEST_ASSERT(reference == 0);
58 TEST_ASSERT(actual == 0);
59 } else {
60 TEST_ASSERT(reference != 0);
61 TEST_ASSERT(actual != 0);
62 }
63exit:
64 mbedtls_free(a);
65 mbedtls_free(b);
66}
67/* END_CASE */
68
69/* BEGIN_CASE depends_on:MBEDTLS_SSL_SOME_SUITES_USE_MAC */
70void mbedtls_ct_memcpy_if_eq(int eq, int size, int offset)
71{
72 uint8_t *src = NULL, *result = NULL, *expected = NULL;
73 ASSERT_ALLOC(src, size + offset);
74 ASSERT_ALLOC(result, size + offset);
75 ASSERT_ALLOC(expected, size + offset);
76
77 for (int i = 0; i < size + offset; i++) {
78 src[i] = 1;
79 result[i] = 0xff;
80 expected[i] = eq ? 1 : 0xff;
81 }
82
Dave Rodgman58c721e2023-01-21 11:00:30 +000083 int one, secret_eq;
84 TEST_CF_SECRET(&one, sizeof(one));
85 TEST_CF_SECRET(&secret_eq, sizeof(secret_eq));
86 one = 1;
87 secret_eq = eq;
88
89 mbedtls_ct_memcpy_if_eq(result + offset, src, size, secret_eq, one);
90
91 TEST_CF_PUBLIC(&one, sizeof(one));
92 TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq));
93
Dave Rodgman39188c02022-12-23 12:27:04 +000094 ASSERT_COMPARE(expected, size, result + offset, size);
95
96 for (int i = 0; i < size + offset; i++) {
97 src[i] = 1;
98 result[i] = 0xff;
99 expected[i] = eq ? 1 : 0xff;
100 }
Dave Rodgman39188c02022-12-23 12:27:04 +0000101
Dave Rodgman58c721e2023-01-21 11:00:30 +0000102 TEST_CF_SECRET(&one, sizeof(one));
103 TEST_CF_SECRET(&secret_eq, sizeof(secret_eq));
104 one = 1;
105 secret_eq = eq;
106
107 mbedtls_ct_memcpy_if_eq(result, src + offset, size, secret_eq, one);
108
109 TEST_CF_PUBLIC(&one, sizeof(one));
110 TEST_CF_PUBLIC(&secret_eq, sizeof(secret_eq));
111
112 ASSERT_COMPARE(expected, size, result, size);
Dave Rodgman39188c02022-12-23 12:27:04 +0000113exit:
114 mbedtls_free(src);
115 mbedtls_free(result);
116 mbedtls_free(expected);
117}
118/* END_CASE */
119
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +0100120/* BEGIN_CASE depends_on:MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC:MBEDTLS_TEST_HOOKS */
Gilles Peskine449bd832023-01-11 14:50:10 +0100121void ssl_cf_memcpy_offset(int offset_min, int offset_max, int len)
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +0100122{
123 unsigned char *dst = NULL;
124 unsigned char *src = NULL;
125 size_t src_len = offset_max + len;
126 size_t secret;
127
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 ASSERT_ALLOC(dst, len);
129 ASSERT_ALLOC(src, src_len);
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +0100130
131 /* Fill src in a way that we can detect if we copied the right bytes */
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 mbedtls_test_rnd_std_rand(NULL, src, src_len);
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +0100133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 for (secret = offset_min; secret <= (size_t) offset_max; secret++) {
135 mbedtls_test_set_step((int) secret);
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +0100136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 TEST_CF_SECRET(&secret, sizeof(secret));
138 mbedtls_ct_memcpy_offset(dst, src, secret,
139 offset_min, offset_max, len);
140 TEST_CF_PUBLIC(&secret, sizeof(secret));
141 TEST_CF_PUBLIC(dst, len);
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +0100142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 ASSERT_COMPARE(dst, len, src + secret, len);
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +0100144 }
145
146exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 mbedtls_free(dst);
148 mbedtls_free(src);
Gilles Peskine3ffd6bc2022-11-29 15:44:21 +0100149}
150/* END_CASE */