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 #include "internal.h"
11
12 #include <limits.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #include <limits>
17
18 #include <gtest/gtest.h>
19 #include "test/test_util.h"
20
21 #include <openssl/mem.h>
22 #include <openssl/rand.h>
23
24
FromBool8(bool b)25 static uint8_t FromBool8(bool b) {
26 return b ? CONSTTIME_TRUE_8 : CONSTTIME_FALSE_8;
27 }
28
FromBoolW(bool b)29 static crypto_word_t FromBoolW(bool b) {
30 return b ? CONSTTIME_TRUE_W : CONSTTIME_FALSE_W;
31 }
32
33 static const uint8_t test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
34
35 static crypto_word_t test_values_w[] = {
36 0,
37 1,
38 1024,
39 12345,
40 32000,
41 #if defined(OPENSSL_64_BIT)
42 0xffffffff / 2 - 1,
43 0xffffffff / 2,
44 0xffffffff / 2 + 1,
45 0xffffffff - 1,
46 0xffffffff,
47 #endif
48 std::numeric_limits<crypto_word_t>::max() / 2 - 1,
49 std::numeric_limits<crypto_word_t>::max() / 2,
50 std::numeric_limits<crypto_word_t>::max() / 2 + 1,
51 std::numeric_limits<crypto_word_t>::max() - 1,
52 std::numeric_limits<crypto_word_t>::max(),
53 };
54
55 static int signed_test_values[] = {
56 0, 1, -1, 1024, -1024, 12345, -12345,
57 32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1, INT_MIN + 1};
58
TEST(ConstantTimeTest,Test)59 TEST(ConstantTimeTest, Test) {
60 for (crypto_word_t a : test_values_w) {
61 SCOPED_TRACE(a);
62
63 EXPECT_EQ(FromBoolW(a == 0), constant_time_is_zero_w(a));
64 EXPECT_EQ(FromBool8(a == 0), constant_time_is_zero_8(a));
65
66 for (crypto_word_t b : test_values_w) {
67 SCOPED_TRACE(b);
68
69 EXPECT_EQ(FromBoolW(a < b), constant_time_lt_w(a, b));
70 EXPECT_EQ(FromBool8(a < b), constant_time_lt_8(a, b));
71
72 EXPECT_EQ(FromBoolW(a >= b), constant_time_ge_w(a, b));
73 EXPECT_EQ(FromBool8(a >= b), constant_time_ge_8(a, b));
74
75 EXPECT_EQ(FromBoolW(a == b), constant_time_eq_w(a, b));
76 EXPECT_EQ(FromBool8(a == b), constant_time_eq_8(a, b));
77
78 EXPECT_EQ(a, constant_time_select_w(CONSTTIME_TRUE_W, a, b));
79 EXPECT_EQ(b, constant_time_select_w(CONSTTIME_FALSE_W, a, b));
80 }
81 }
82
83 for (int a : signed_test_values) {
84 SCOPED_TRACE(a);
85 for (int b : signed_test_values) {
86 SCOPED_TRACE(b);
87
88 EXPECT_EQ(a, constant_time_select_int(CONSTTIME_TRUE_W, a, b));
89 EXPECT_EQ(b, constant_time_select_int(CONSTTIME_FALSE_W, a, b));
90
91 EXPECT_EQ(FromBoolW(a == b), constant_time_eq_int(a, b));
92 EXPECT_EQ(FromBool8(a == b), constant_time_eq_int_8(a, b));
93 }
94 }
95
96 for (uint8_t a : test_values_8) {
97 SCOPED_TRACE(static_cast<int>(a));
98 for (uint8_t b : test_values_8) {
99 SCOPED_TRACE(static_cast<int>(b));
100 EXPECT_EQ(a, constant_time_select_8(CONSTTIME_TRUE_8, a, b));
101 EXPECT_EQ(b, constant_time_select_8(CONSTTIME_FALSE_8, a, b));
102 }
103 }
104 }
105
TEST(ConstantTimeTest,MemCmp)106 TEST(ConstantTimeTest, MemCmp) {
107 uint8_t buf[256], copy[256];
108 RAND_bytes(buf, sizeof(buf));
109
110 OPENSSL_memcpy(copy, buf, sizeof(buf));
111 EXPECT_EQ(0, CRYPTO_memcmp(buf, copy, sizeof(buf)));
112
113 for (size_t i = 0; i < sizeof(buf); i++) {
114 for (uint8_t bit = 1; bit != 0; bit <<= 1) {
115 OPENSSL_memcpy(copy, buf, sizeof(buf));
116 copy[i] ^= bit;
117 EXPECT_NE(0, CRYPTO_memcmp(buf, copy, sizeof(buf)));
118 }
119 }
120 }
121
TEST(ConstantTimeTest,ValueBarrier)122 TEST(ConstantTimeTest, ValueBarrier) {
123 for (int i = 0; i < 10; i++) {
124 crypto_word_t word;
125 RAND_bytes(reinterpret_cast<uint8_t *>(&word), sizeof(word));
126 EXPECT_EQ(word, value_barrier_w(word));
127
128 uint32_t u32;
129 RAND_bytes(reinterpret_cast<uint8_t *>(&u32), sizeof(u32));
130 EXPECT_EQ(u32, value_barrier_u32(u32));
131
132 uint64_t u64;
133 RAND_bytes(reinterpret_cast<uint8_t *>(&u64), sizeof(u64));
134 EXPECT_EQ(u64, value_barrier_u64(u64));
135 }
136 }
137
TEST(ConstantTimeTest,MemCmov)138 TEST(ConstantTimeTest, MemCmov) {
139 for (int i = 0; i < 100; i++) {
140 uint8_t out[256], in[256];
141 RAND_bytes(out, sizeof(out));
142 RAND_bytes(in, sizeof(in));
143
144 uint8_t b = 0;
145 RAND_bytes(&b, 1);
146 b = constant_time_is_zero_8(b & 0xf);
147
148 uint8_t ref_in[256];
149 OPENSSL_memcpy(ref_in, in, sizeof(in));
150
151 uint8_t ref_out[256];
152 OPENSSL_memcpy(ref_out, out, sizeof(out));
153 if (b) {
154 OPENSSL_memcpy(ref_out, in, sizeof(in));
155 }
156
157 CONSTTIME_SECRET(out, sizeof(out));
158 CONSTTIME_SECRET(in, sizeof(in));
159 CONSTTIME_SECRET(&b, 1);
160
161 constant_time_conditional_memcpy(out, in, sizeof(out), b);
162
163 CONSTTIME_DECLASSIFY(&in, sizeof(in));
164 CONSTTIME_DECLASSIFY(&out, sizeof(out));
165
166 EXPECT_EQ(Bytes(in), Bytes(ref_in));
167 EXPECT_EQ(Bytes(out), Bytes(ref_out));
168 }
169 }
170
TEST(ConstantTimeTest,MemCxor)171 TEST(ConstantTimeTest, MemCxor) {
172 for (int i = 0; i < 100; i++) {
173 uint8_t out[256], in[256];
174 RAND_bytes(out, sizeof(out));
175 RAND_bytes(in, sizeof(in));
176
177 uint8_t b = 0;
178 RAND_bytes(&b, 1);
179 b = constant_time_is_zero_8(b & 0xf);
180
181 uint8_t ref_in[256];
182 OPENSSL_memcpy(ref_in, in, sizeof(in));
183
184 uint8_t ref_out[256];
185 OPENSSL_memcpy(ref_out, out, sizeof(out));
186 if (b) {
187 for (size_t j = 0; j < sizeof(ref_out); ++j) {
188 ref_out[j] ^= in[j];
189 }
190 }
191
192 CONSTTIME_SECRET(out, sizeof(out));
193 CONSTTIME_SECRET(in, sizeof(in));
194 CONSTTIME_SECRET(&b, 1);
195
196 constant_time_conditional_memxor(out, in, sizeof(out), b);
197
198 CONSTTIME_DECLASSIFY(&in, sizeof(in));
199 CONSTTIME_DECLASSIFY(&out, sizeof(out));
200
201 EXPECT_EQ(Bytes(in), Bytes(ref_in));
202 EXPECT_EQ(Bytes(out), Bytes(ref_out));
203 }
204 }
205