blob: ff95d0f7372d6a1e00abb30e6c6b48d0227b7228 [file] [log] [blame]
Darren Krahnfcb4e192012-06-08 14:52:47 -07001// 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
Manoj Gupta91944f22018-02-01 19:23:22 -08007#include "brillo/asan.h"
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -07008#include "brillo/secure_blob.h"
Darren Krahnfcb4e192012-06-08 14:52:47 -07009
Utkarsh Sanghic411f7f2014-09-08 15:01:31 -070010#include <algorithm>
11#include <iterator>
Maksim Ivanov30b3a162018-05-29 20:48:26 +020012#include <limits>
Utkarsh Sanghic411f7f2014-09-08 15:01:31 -070013#include <numeric>
14
Darren Krahnfcb4e192012-06-08 14:52:47 -070015#include <base/logging.h>
16#include <gtest/gtest.h>
17
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070018namespace brillo {
Darren Krahnfcb4e192012-06-08 14:52:47 -070019using std::string;
20
Maksim Ivanov30b3a162018-05-29 20:48:26 +020021// Tests BlobToString() and BlobFromString().
22TEST(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
Maksim Ivanovaeb7bb42018-06-07 00:01:08 +020033// Tests CombineBlobs().
34TEST(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
Darren Krahnfcb4e192012-06-08 14:52:47 -070048class SecureBlobTest : public ::testing::Test {
49 public:
Alex Vakulenko05d29042015-01-13 09:39:25 -080050 SecureBlobTest() {}
51 virtual ~SecureBlobTest() {}
Darren Krahnfcb4e192012-06-08 14:52:47 -070052
Jorge Lucangeli Obesc2514022018-06-21 11:33:16 -040053 static bool FindBlobInBlob(const brillo::SecureBlob& haystack,
54 const brillo::SecureBlob& needle) {
Alex Vakulenko05d29042015-01-13 09:39:25 -080055 auto pos = std::search(
56 haystack.begin(), haystack.end(), needle.begin(), needle.end());
Utkarsh Sanghic411f7f2014-09-08 15:01:31 -070057 return (pos != haystack.end());
58 }
59
Jorge Lucangeli Obesc2514022018-06-21 11:33:16 -040060 static int FindBlobIndexInBlob(const brillo::SecureBlob& haystack,
61 const brillo::SecureBlob& needle) {
Alex Vakulenko05d29042015-01-13 09:39:25 -080062 auto pos = std::search(
63 haystack.begin(), haystack.end(), needle.begin(), needle.end());
Utkarsh Sanghic411f7f2014-09-08 15:01:31 -070064 if (pos == haystack.end()) {
65 return -1;
Darren Krahnfcb4e192012-06-08 14:52:47 -070066 }
Utkarsh Sanghic411f7f2014-09-08 15:01:31 -070067 return std::distance(haystack.begin(), pos);
Darren Krahnfcb4e192012-06-08 14:52:47 -070068 }
69
70 private:
71 DISALLOW_COPY_AND_ASSIGN(SecureBlobTest);
72};
73
74TEST_F(SecureBlobTest, AllocationSizeTest) {
Jorge Lucangeli Obesc2514022018-06-21 11:33:16 -040075 // Checks that allocating a SecureBlob of a specified size works.
Darren Krahnfcb4e192012-06-08 14:52:47 -070076 SecureBlob blob(32);
77
78 EXPECT_EQ(32, blob.size());
79}
80
Jorge Lucangeli Obesc2514022018-06-21 11:33:16 -040081TEST_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
90TEST_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
99TEST_F(SecureBlobTest, ConstructorIteratorTest) {
100 // Checks that constructing a SecureBlob with an iterator works.
Darren Krahnfcb4e192012-06-08 14:52:47 -0700101 unsigned char from_data[32];
Alex Vakulenkoc3c53ee2015-03-25 16:21:34 -0700102 std::iota(std::begin(from_data), std::end(from_data), 0);
Darren Krahnfcb4e192012-06-08 14:52:47 -0700103
Alex Vakulenkoc3c53ee2015-03-25 16:21:34 -0700104 SecureBlob blob(std::begin(from_data), std::end(from_data));
Darren Krahnfcb4e192012-06-08 14:52:47 -0700105
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
Jorge Lucangeli Obesc2514022018-06-21 11:33:16 -0400113TEST_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()));
Darren Krahnfcb4e192012-06-08 14:52:47 -0700120}
121
Jorge Lucangeli Obesc2514022018-06-21 11:33:16 -0400122TEST_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
138TEST_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.
Manoj Guptacd5ebb22018-01-26 12:13:31 -0800161// https://crbug.com/806013
Manoj Gupta91944f22018-02-01 19:23:22 -0800162#ifndef BRILLO_ASAN_BUILD
Darren Krahnfcb4e192012-06-08 14:52:47 -0700163TEST_F(SecureBlobTest, ResizeTest) {
Jorge Lucangeli Obesc2514022018-06-21 11:33:16 -0400164 // Check that resizing a SecureBlob wipes the excess memory. The test assumes
Darren Krahnfcb4e192012-06-08 14:52:47 -0700165 // that resize() down by one will not re-allocate the memory, so the last byte
Jorge Lucangeli Obesc2514022018-06-21 11:33:16 -0400166 // will still be part of the SecureBlob's allocation.
Alex Vakulenkoc3c53ee2015-03-25 16:21:34 -0700167 size_t length = 1024;
Darren Krahnfcb4e192012-06-08 14:52:47 -0700168 SecureBlob blob(length);
169 void* original_data = blob.data();
Alex Vakulenkoc3c53ee2015-03-25 16:21:34 -0700170 for (size_t i = 0; i < length; i++) {
Darren Krahnfcb4e192012-06-08 14:52:47 -0700171 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());
Alex Vakulenkoc3c53ee2015-03-25 16:21:34 -0700178 EXPECT_EQ(0, blob.data()[length - 1]);
Darren Krahnfcb4e192012-06-08 14:52:47 -0700179}
Manoj Guptacd5ebb22018-01-26 12:13:31 -0800180#endif
Darren Krahnfcb4e192012-06-08 14:52:47 -0700181
Utkarsh Sanghic411f7f2014-09-08 15:01:31 -0700182TEST_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
197TEST_F(SecureBlobTest, BlobToStringTest) {
198 std::string test_string("Test String");
Alex Vakulenkoc3c53ee2015-03-25 16:21:34 -0700199 SecureBlob blob = SecureBlob(test_string.begin(), test_string.end());
Utkarsh Sanghic411f7f2014-09-08 15:01:31 -0700200 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
Jorge Lucangeli Obes4f500da2018-06-26 10:31:32 -0400205TEST_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
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -0700230} // namespace brillo