1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Unit tests for SecureBlob.
6
7 #include "brillo/asan.h"
8 #include "brillo/secure_blob.h"
9
10 #include <algorithm>
11 #include <iterator>
12 #include <limits>
13 #include <numeric>
14
15 #include <base/logging.h>
16 #include <gtest/gtest.h>
17
18 namespace brillo {
19 using std::string;
20
21 // Tests BlobToString() and BlobFromString().
TEST(BlobTest,StringConversions)22 TEST(BlobTest, StringConversions) {
23 const char kTestBytes[] = {'\0', '\x1', 'a', std::numeric_limits<char>::min(),
24 std::numeric_limits<char>::max()};
25 const Blob blob(std::begin(kTestBytes), std::end(kTestBytes));
26 const string obtained_string = BlobToString(blob);
27 EXPECT_EQ(string(std::begin(kTestBytes), std::end(kTestBytes)),
28 obtained_string);
29 const Blob obtained_blob = BlobFromString(obtained_string);
30 EXPECT_EQ(blob, obtained_blob);
31 }
32
33 // Tests CombineBlobs().
TEST(BlobTest,CombineBlobs)34 TEST(BlobTest, CombineBlobs) {
35 const Blob kEmpty;
36 const Blob kBlob1 = {1};
37 const Blob kBlob2 = {2};
38 const Blob kBlob3 = {3};
39 const Blob kBlob12 = {1, 2};
40 const Blob kBlob123 = {1, 2, 3};
41 EXPECT_EQ(kBlob123, CombineBlobs({kBlob12, kBlob3}));
42 EXPECT_EQ(kBlob123, CombineBlobs({kBlob1, kBlob2, kBlob3}));
43 EXPECT_EQ(kBlob12, CombineBlobs({kBlob12}));
44 EXPECT_EQ(kBlob12, CombineBlobs({kEmpty, kBlob1, kEmpty, kBlob2, kEmpty}));
45 EXPECT_EQ(kEmpty, CombineBlobs({}));
46 }
47
48 class SecureBlobTest : public ::testing::Test {
49 public:
SecureBlobTest()50 SecureBlobTest() {}
~SecureBlobTest()51 virtual ~SecureBlobTest() {}
52
FindBlobInBlob(const brillo::SecureBlob & haystack,const brillo::SecureBlob & needle)53 static bool FindBlobInBlob(const brillo::SecureBlob& haystack,
54 const brillo::SecureBlob& needle) {
55 auto pos = std::search(
56 haystack.begin(), haystack.end(), needle.begin(), needle.end());
57 return (pos != haystack.end());
58 }
59
FindBlobIndexInBlob(const brillo::SecureBlob & haystack,const brillo::SecureBlob & needle)60 static int FindBlobIndexInBlob(const brillo::SecureBlob& haystack,
61 const brillo::SecureBlob& needle) {
62 auto pos = std::search(
63 haystack.begin(), haystack.end(), needle.begin(), needle.end());
64 if (pos == haystack.end()) {
65 return -1;
66 }
67 return std::distance(haystack.begin(), pos);
68 }
69
70 private:
71 DISALLOW_COPY_AND_ASSIGN(SecureBlobTest);
72 };
73
TEST_F(SecureBlobTest,AllocationSizeTest)74 TEST_F(SecureBlobTest, AllocationSizeTest) {
75 // Checks that allocating a SecureBlob of a specified size works.
76 SecureBlob blob(32);
77
78 EXPECT_EQ(32, blob.size());
79 }
80
TEST_F(SecureBlobTest,ConstructorCountValueTest)81 TEST_F(SecureBlobTest, ConstructorCountValueTest) {
82 // Checks that constructing a SecureBlob with |count| copies of |value| works.
83 SecureBlob blob(32, 'a');
84
85 for (size_t i = 0; i < blob.size(); i++) {
86 EXPECT_EQ('a', blob[i]);
87 }
88 }
89
TEST_F(SecureBlobTest,ConstructorAmbiguousTest)90 TEST_F(SecureBlobTest, ConstructorAmbiguousTest) {
91 // This test will become important once SecureBlob stops inheriting from Blob.
92 SecureBlob blob(32, 0);
93
94 for (size_t i = 0; i < blob.size(); i++) {
95 EXPECT_EQ(0, blob[i]);
96 }
97 }
98
TEST_F(SecureBlobTest,ConstructorIteratorTest)99 TEST_F(SecureBlobTest, ConstructorIteratorTest) {
100 // Checks that constructing a SecureBlob with an iterator works.
101 unsigned char from_data[32];
102 std::iota(std::begin(from_data), std::end(from_data), 0);
103
104 SecureBlob blob(std::begin(from_data), std::end(from_data));
105
106 EXPECT_EQ(sizeof(from_data), blob.size());
107
108 for (unsigned int i = 0; i < sizeof(from_data); i++) {
109 EXPECT_EQ(from_data[i], blob[i]);
110 }
111 }
112
TEST_F(SecureBlobTest,BlobConstructorTest)113 TEST_F(SecureBlobTest, BlobConstructorTest) {
114 // Check that constructing a SecureBlob from a Blob works.
115 const std::vector<uint8_t> bytes = {0, 1, 255};
116 const Blob blob(bytes);
117 const SecureBlob secure_blob(blob);
118 EXPECT_EQ(bytes,
119 std::vector<uint8_t>(secure_blob.begin(), secure_blob.end()));
120 }
121
TEST_F(SecureBlobTest,IteratorTest)122 TEST_F(SecureBlobTest, IteratorTest) {
123 // Checks that SecureBlob::begin(), SecureBlob::end() work.
124 unsigned char from_data[32];
125 std::iota(std::begin(from_data), std::end(from_data), 0);
126
127 SecureBlob blob(std::begin(from_data), std::end(from_data));
128
129 EXPECT_EQ(sizeof(from_data), blob.size());
130
131 size_t i = 0;
132 for (auto it = blob.begin(); it != blob.end(); ++it) {
133 EXPECT_EQ(from_data[i], *it);
134 ++i;
135 }
136 }
137
TEST_F(SecureBlobTest,AssignTest)138 TEST_F(SecureBlobTest, AssignTest) {
139 // Checks that .assign() works.
140 unsigned char from_data[32];
141 std::iota(std::begin(from_data), std::end(from_data), 0);
142
143 SecureBlob blob;
144 blob.assign(std::begin(from_data), std::end(from_data));
145
146 EXPECT_EQ(sizeof(from_data), blob.size());
147
148 size_t i = 0;
149 for (auto it = blob.begin(); it != blob.end(); ++it) {
150 EXPECT_EQ(from_data[i], *it);
151 ++i;
152 }
153
154 SecureBlob blob2;
155 blob2.assign(blob.begin(), blob.end());
156
157 EXPECT_EQ(blob, blob2);
158 }
159
160 // Disable ResizeTest with Address Sanitizer.
161 // https://crbug.com/806013
162 #ifndef BRILLO_ASAN_BUILD
TEST_F(SecureBlobTest,ResizeTest)163 TEST_F(SecureBlobTest, ResizeTest) {
164 // Check that resizing a SecureBlob wipes the excess memory. The test assumes
165 // that resize() down by one will not re-allocate the memory, so the last byte
166 // will still be part of the SecureBlob's allocation.
167 size_t length = 1024;
168 SecureBlob blob(length);
169 void* original_data = blob.data();
170 for (size_t i = 0; i < length; i++) {
171 blob[i] = i;
172 }
173
174 blob.resize(length - 1);
175
176 EXPECT_EQ(original_data, blob.data());
177 EXPECT_EQ(length - 1, blob.size());
178 EXPECT_EQ(0, blob.data()[length - 1]);
179 }
180 #endif
181
TEST_F(SecureBlobTest,CombineTest)182 TEST_F(SecureBlobTest, CombineTest) {
183 SecureBlob blob1(32);
184 SecureBlob blob2(32);
185 std::iota(blob1.begin(), blob1.end(), 0);
186 std::iota(blob2.begin(), blob2.end(), 32);
187 SecureBlob combined_blob = SecureBlob::Combine(blob1, blob2);
188 EXPECT_EQ(combined_blob.size(), (blob1.size() + blob2.size()));
189 EXPECT_TRUE(SecureBlobTest::FindBlobInBlob(combined_blob, blob1));
190 EXPECT_TRUE(SecureBlobTest::FindBlobInBlob(combined_blob, blob2));
191 int blob1_index = SecureBlobTest::FindBlobIndexInBlob(combined_blob, blob1);
192 int blob2_index = SecureBlobTest::FindBlobIndexInBlob(combined_blob, blob2);
193 EXPECT_EQ(blob1_index, 0);
194 EXPECT_EQ(blob2_index, 32);
195 }
196
TEST_F(SecureBlobTest,BlobToStringTest)197 TEST_F(SecureBlobTest, BlobToStringTest) {
198 std::string test_string("Test String");
199 SecureBlob blob = SecureBlob(test_string.begin(), test_string.end());
200 EXPECT_EQ(blob.size(), test_string.length());
201 std::string result_string = blob.to_string();
202 EXPECT_EQ(test_string.compare(result_string), 0);
203 }
204
TEST_F(SecureBlobTest,HexStringToSecureBlob)205 TEST_F(SecureBlobTest, HexStringToSecureBlob) {
206 std::string hex_string("112233445566778899aabbccddeeff0f");
207
208 SecureBlob blob;
209 SecureBlob::HexStringToSecureBlob(hex_string, &blob);
210
211 EXPECT_EQ(blob.size(), 16u);
212 EXPECT_EQ(blob[0], 0x11);
213 EXPECT_EQ(blob[1], 0x22);
214 EXPECT_EQ(blob[2], 0x33);
215 EXPECT_EQ(blob[3], 0x44);
216 EXPECT_EQ(blob[4], 0x55);
217 EXPECT_EQ(blob[5], 0x66);
218 EXPECT_EQ(blob[6], 0x77);
219 EXPECT_EQ(blob[7], 0x88);
220 EXPECT_EQ(blob[8], 0x99);
221 EXPECT_EQ(blob[9], 0xaa);
222 EXPECT_EQ(blob[10], 0xbb);
223 EXPECT_EQ(blob[11], 0xcc);
224 EXPECT_EQ(blob[12], 0xdd);
225 EXPECT_EQ(blob[13], 0xee);
226 EXPECT_EQ(blob[14], 0xff);
227 EXPECT_EQ(blob[15], 0x0f);
228 }
229
230 } // namespace brillo
231