1 // Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "internal.h"
16 
17 #include <limits.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 
21 #include <limits>
22 
23 #include <gtest/gtest.h>
24 #include "test/test_util.h"
25 
26 #include <openssl/mem.h>
27 #include <openssl/rand.h>
28 
29 
FromBool8(bool b)30 static uint8_t FromBool8(bool b) {
31   return b ? CONSTTIME_TRUE_8 : CONSTTIME_FALSE_8;
32 }
33 
FromBoolW(bool b)34 static crypto_word_t FromBoolW(bool b) {
35   return b ? CONSTTIME_TRUE_W : CONSTTIME_FALSE_W;
36 }
37 
38 static const uint8_t test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
39 
40 static crypto_word_t test_values_w[] = {
41     0,
42     1,
43     1024,
44     12345,
45     32000,
46 #if defined(OPENSSL_64_BIT)
47     0xffffffff / 2 - 1,
48     0xffffffff / 2,
49     0xffffffff / 2 + 1,
50     0xffffffff - 1,
51     0xffffffff,
52 #endif
53     std::numeric_limits<crypto_word_t>::max() / 2 - 1,
54     std::numeric_limits<crypto_word_t>::max() / 2,
55     std::numeric_limits<crypto_word_t>::max() / 2 + 1,
56     std::numeric_limits<crypto_word_t>::max() - 1,
57     std::numeric_limits<crypto_word_t>::max(),
58 };
59 
60 static int signed_test_values[] = {
61     0,     1,      -1,      1024,    -1024,       12345,      -12345,
62     32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1, INT_MIN + 1};
63 
TEST(ConstantTimeTest,Test)64 TEST(ConstantTimeTest, Test) {
65   for (crypto_word_t a : test_values_w) {
66     SCOPED_TRACE(a);
67 
68     EXPECT_EQ(FromBoolW(a == 0), constant_time_is_zero_w(a));
69     EXPECT_EQ(FromBool8(a == 0), constant_time_is_zero_8(a));
70 
71     for (crypto_word_t b : test_values_w) {
72       SCOPED_TRACE(b);
73 
74       EXPECT_EQ(FromBoolW(a < b), constant_time_lt_w(a, b));
75       EXPECT_EQ(FromBool8(a < b), constant_time_lt_8(a, b));
76 
77       EXPECT_EQ(FromBoolW(a >= b), constant_time_ge_w(a, b));
78       EXPECT_EQ(FromBool8(a >= b), constant_time_ge_8(a, b));
79 
80       EXPECT_EQ(FromBoolW(a == b), constant_time_eq_w(a, b));
81       EXPECT_EQ(FromBool8(a == b), constant_time_eq_8(a, b));
82 
83       EXPECT_EQ(a, constant_time_select_w(CONSTTIME_TRUE_W, a, b));
84       EXPECT_EQ(b, constant_time_select_w(CONSTTIME_FALSE_W, a, b));
85     }
86   }
87 
88   for (int a : signed_test_values) {
89     SCOPED_TRACE(a);
90     for (int b : signed_test_values) {
91       SCOPED_TRACE(b);
92 
93       EXPECT_EQ(a, constant_time_select_int(CONSTTIME_TRUE_W, a, b));
94       EXPECT_EQ(b, constant_time_select_int(CONSTTIME_FALSE_W, a, b));
95 
96       EXPECT_EQ(FromBoolW(a == b), constant_time_eq_int(a, b));
97       EXPECT_EQ(FromBool8(a == b), constant_time_eq_int_8(a, b));
98     }
99   }
100 
101   for (uint8_t a : test_values_8) {
102     SCOPED_TRACE(static_cast<int>(a));
103     for (uint8_t b : test_values_8) {
104       SCOPED_TRACE(static_cast<int>(b));
105       EXPECT_EQ(a, constant_time_select_8(CONSTTIME_TRUE_8, a, b));
106       EXPECT_EQ(b, constant_time_select_8(CONSTTIME_FALSE_8, a, b));
107     }
108   }
109 }
110 
TEST(ConstantTimeTest,MemCmp)111 TEST(ConstantTimeTest, MemCmp) {
112   uint8_t buf[256], copy[256];
113   RAND_bytes(buf, sizeof(buf));
114 
115   OPENSSL_memcpy(copy, buf, sizeof(buf));
116   EXPECT_EQ(0, CRYPTO_memcmp(buf, copy, sizeof(buf)));
117 
118   for (size_t i = 0; i < sizeof(buf); i++) {
119     for (uint8_t bit = 1; bit != 0; bit <<= 1) {
120       OPENSSL_memcpy(copy, buf, sizeof(buf));
121       copy[i] ^= bit;
122       EXPECT_NE(0, CRYPTO_memcmp(buf, copy, sizeof(buf)));
123     }
124   }
125 }
126 
TEST(ConstantTimeTest,ValueBarrier)127 TEST(ConstantTimeTest, ValueBarrier) {
128   for (int i = 0; i < 10; i++) {
129     crypto_word_t word;
130     RAND_bytes(reinterpret_cast<uint8_t *>(&word), sizeof(word));
131     EXPECT_EQ(word, value_barrier_w(word));
132 
133     uint32_t u32;
134     RAND_bytes(reinterpret_cast<uint8_t *>(&u32), sizeof(u32));
135     EXPECT_EQ(u32, value_barrier_u32(u32));
136 
137     uint64_t u64;
138     RAND_bytes(reinterpret_cast<uint8_t *>(&u64), sizeof(u64));
139     EXPECT_EQ(u64, value_barrier_u64(u64));
140   }
141 }
142 
TEST(ConstantTimeTest,MemCmov)143 TEST(ConstantTimeTest, MemCmov) {
144   for (int i = 0; i < 100; i++) {
145     uint8_t out[256], in[256];
146     RAND_bytes(out, sizeof(out));
147     RAND_bytes(in, sizeof(in));
148 
149     uint8_t b = 0;
150     RAND_bytes(&b, 1);
151     b = constant_time_is_zero_8(b & 0xf);
152 
153     uint8_t ref_in[256];
154     OPENSSL_memcpy(ref_in, in, sizeof(in));
155 
156     uint8_t ref_out[256];
157     OPENSSL_memcpy(ref_out, out, sizeof(out));
158     if (b) {
159       OPENSSL_memcpy(ref_out, in, sizeof(in));
160     }
161 
162     CONSTTIME_SECRET(out, sizeof(out));
163     CONSTTIME_SECRET(in, sizeof(in));
164     CONSTTIME_SECRET(&b, 1);
165 
166     constant_time_conditional_memcpy(out, in, sizeof(out), b);
167 
168     CONSTTIME_DECLASSIFY(&in, sizeof(in));
169     CONSTTIME_DECLASSIFY(&out, sizeof(out));
170 
171     EXPECT_EQ(Bytes(in), Bytes(ref_in));
172     EXPECT_EQ(Bytes(out), Bytes(ref_out));
173   }
174 }
175 
TEST(ConstantTimeTest,MemCxor)176 TEST(ConstantTimeTest, MemCxor) {
177   for (int i = 0; i < 100; i++) {
178     uint8_t out[256], in[256];
179     RAND_bytes(out, sizeof(out));
180     RAND_bytes(in, sizeof(in));
181 
182     uint8_t b = 0;
183     RAND_bytes(&b, 1);
184     b = constant_time_is_zero_8(b & 0xf);
185 
186     uint8_t ref_in[256];
187     OPENSSL_memcpy(ref_in, in, sizeof(in));
188 
189     uint8_t ref_out[256];
190     OPENSSL_memcpy(ref_out, out, sizeof(out));
191     if (b) {
192       for (size_t j = 0; j < sizeof(ref_out); ++j) {
193         ref_out[j] ^= in[j];
194       }
195     }
196 
197     CONSTTIME_SECRET(out, sizeof(out));
198     CONSTTIME_SECRET(in, sizeof(in));
199     CONSTTIME_SECRET(&b, 1);
200 
201     constant_time_conditional_memxor(out, in, sizeof(out), b);
202 
203     CONSTTIME_DECLASSIFY(&in, sizeof(in));
204     CONSTTIME_DECLASSIFY(&out, sizeof(out));
205 
206     EXPECT_EQ(Bytes(in), Bytes(ref_in));
207     EXPECT_EQ(Bytes(out), Bytes(ref_out));
208   }
209 }
210