• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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