Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 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 | |
Manoj Gupta | 91944f2 | 2018-02-01 19:23:22 -0800 | [diff] [blame] | 7 | #include "brillo/asan.h" |
Alex Vakulenko | 9ed0cab | 2015-10-12 15:21:28 -0700 | [diff] [blame] | 8 | #include "brillo/secure_blob.h" |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 9 | |
Utkarsh Sanghi | c411f7f | 2014-09-08 15:01:31 -0700 | [diff] [blame] | 10 | #include <algorithm> |
| 11 | #include <iterator> |
Maksim Ivanov | 30b3a16 | 2018-05-29 20:48:26 +0200 | [diff] [blame] | 12 | #include <limits> |
Utkarsh Sanghi | c411f7f | 2014-09-08 15:01:31 -0700 | [diff] [blame] | 13 | #include <numeric> |
| 14 | |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 15 | #include <base/logging.h> |
| 16 | #include <gtest/gtest.h> |
| 17 | |
Alex Vakulenko | 9ed0cab | 2015-10-12 15:21:28 -0700 | [diff] [blame] | 18 | namespace brillo { |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 19 | using std::string; |
| 20 | |
Maksim Ivanov | 30b3a16 | 2018-05-29 20:48:26 +0200 | [diff] [blame] | 21 | // Tests BlobToString() and BlobFromString(). |
| 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 | |
Maksim Ivanov | aeb7bb4 | 2018-06-07 00:01:08 +0200 | [diff] [blame] | 33 | // Tests 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 | |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 48 | class SecureBlobTest : public ::testing::Test { |
| 49 | public: |
Alex Vakulenko | 05d2904 | 2015-01-13 09:39:25 -0800 | [diff] [blame] | 50 | SecureBlobTest() {} |
| 51 | virtual ~SecureBlobTest() {} |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 52 | |
Jorge Lucangeli Obes | c251402 | 2018-06-21 11:33:16 -0400 | [diff] [blame] | 53 | static bool FindBlobInBlob(const brillo::SecureBlob& haystack, |
| 54 | const brillo::SecureBlob& needle) { |
Alex Vakulenko | 05d2904 | 2015-01-13 09:39:25 -0800 | [diff] [blame] | 55 | auto pos = std::search( |
| 56 | haystack.begin(), haystack.end(), needle.begin(), needle.end()); |
Utkarsh Sanghi | c411f7f | 2014-09-08 15:01:31 -0700 | [diff] [blame] | 57 | return (pos != haystack.end()); |
| 58 | } |
| 59 | |
Jorge Lucangeli Obes | c251402 | 2018-06-21 11:33:16 -0400 | [diff] [blame] | 60 | static int FindBlobIndexInBlob(const brillo::SecureBlob& haystack, |
| 61 | const brillo::SecureBlob& needle) { |
Alex Vakulenko | 05d2904 | 2015-01-13 09:39:25 -0800 | [diff] [blame] | 62 | auto pos = std::search( |
| 63 | haystack.begin(), haystack.end(), needle.begin(), needle.end()); |
Utkarsh Sanghi | c411f7f | 2014-09-08 15:01:31 -0700 | [diff] [blame] | 64 | if (pos == haystack.end()) { |
| 65 | return -1; |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 66 | } |
Utkarsh Sanghi | c411f7f | 2014-09-08 15:01:31 -0700 | [diff] [blame] | 67 | return std::distance(haystack.begin(), pos); |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | private: |
| 71 | DISALLOW_COPY_AND_ASSIGN(SecureBlobTest); |
| 72 | }; |
| 73 | |
| 74 | TEST_F(SecureBlobTest, AllocationSizeTest) { |
Jorge Lucangeli Obes | c251402 | 2018-06-21 11:33:16 -0400 | [diff] [blame] | 75 | // Checks that allocating a SecureBlob of a specified size works. |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 76 | SecureBlob blob(32); |
| 77 | |
| 78 | EXPECT_EQ(32, blob.size()); |
| 79 | } |
| 80 | |
Jorge Lucangeli Obes | c251402 | 2018-06-21 11:33:16 -0400 | [diff] [blame] | 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 | |
| 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 | |
| 99 | TEST_F(SecureBlobTest, ConstructorIteratorTest) { |
| 100 | // Checks that constructing a SecureBlob with an iterator works. |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 101 | unsigned char from_data[32]; |
Alex Vakulenko | c3c53ee | 2015-03-25 16:21:34 -0700 | [diff] [blame] | 102 | std::iota(std::begin(from_data), std::end(from_data), 0); |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 103 | |
Alex Vakulenko | c3c53ee | 2015-03-25 16:21:34 -0700 | [diff] [blame] | 104 | SecureBlob blob(std::begin(from_data), std::end(from_data)); |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 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 | |
Jorge Lucangeli Obes | c251402 | 2018-06-21 11:33:16 -0400 | [diff] [blame] | 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())); |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 120 | } |
| 121 | |
Jorge Lucangeli Obes | c251402 | 2018-06-21 11:33:16 -0400 | [diff] [blame] | 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 | |
| 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. |
Manoj Gupta | cd5ebb2 | 2018-01-26 12:13:31 -0800 | [diff] [blame] | 161 | // https://crbug.com/806013 |
Manoj Gupta | 91944f2 | 2018-02-01 19:23:22 -0800 | [diff] [blame] | 162 | #ifndef BRILLO_ASAN_BUILD |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 163 | TEST_F(SecureBlobTest, ResizeTest) { |
Jorge Lucangeli Obes | c251402 | 2018-06-21 11:33:16 -0400 | [diff] [blame] | 164 | // Check that resizing a SecureBlob wipes the excess memory. The test assumes |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 165 | // that resize() down by one will not re-allocate the memory, so the last byte |
Jorge Lucangeli Obes | c251402 | 2018-06-21 11:33:16 -0400 | [diff] [blame] | 166 | // will still be part of the SecureBlob's allocation. |
Alex Vakulenko | c3c53ee | 2015-03-25 16:21:34 -0700 | [diff] [blame] | 167 | size_t length = 1024; |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 168 | SecureBlob blob(length); |
| 169 | void* original_data = blob.data(); |
Alex Vakulenko | c3c53ee | 2015-03-25 16:21:34 -0700 | [diff] [blame] | 170 | for (size_t i = 0; i < length; i++) { |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 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()); |
Alex Vakulenko | c3c53ee | 2015-03-25 16:21:34 -0700 | [diff] [blame] | 178 | EXPECT_EQ(0, blob.data()[length - 1]); |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 179 | } |
Manoj Gupta | cd5ebb2 | 2018-01-26 12:13:31 -0800 | [diff] [blame] | 180 | #endif |
Darren Krahn | fcb4e19 | 2012-06-08 14:52:47 -0700 | [diff] [blame] | 181 | |
Utkarsh Sanghi | c411f7f | 2014-09-08 15:01:31 -0700 | [diff] [blame] | 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 | |
| 197 | TEST_F(SecureBlobTest, BlobToStringTest) { |
| 198 | std::string test_string("Test String"); |
Alex Vakulenko | c3c53ee | 2015-03-25 16:21:34 -0700 | [diff] [blame] | 199 | SecureBlob blob = SecureBlob(test_string.begin(), test_string.end()); |
Utkarsh Sanghi | c411f7f | 2014-09-08 15:01:31 -0700 | [diff] [blame] | 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 | |
Jorge Lucangeli Obes | 4f500da | 2018-06-26 10:31:32 -0400 | [diff] [blame] | 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 | |
Alex Vakulenko | 9ed0cab | 2015-10-12 15:21:28 -0700 | [diff] [blame] | 230 | } // namespace brillo |