OLD | NEW |
1 // Copyright (C) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (C) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by the GPL v2 license that can | 2 // Use of this source code is governed by the GPL v2 license that can |
3 // be found in the LICENSE file. | 3 // be found in the LICENSE file. |
4 // | 4 // |
5 // Basic unittesting of dm-bht using google-gtest. | 5 // Basic unittesting of dm-bht using google-gtest. |
6 | 6 |
7 #include <base/basictypes.h> | 7 #include <base/basictypes.h> |
8 #include <base/logging.h> | 8 #include <base/logging.h> |
9 #include <base/scoped_ptr.h> | 9 #include <base/scoped_ptr.h> |
10 #include <gtest/gtest.h> | 10 #include <gtest/gtest.h> |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 hash_data_.reset(new u8[to_bytes(sectors_)]); | 100 hash_data_.reset(new u8[to_bytes(sectors_)]); |
101 } | 101 } |
102 dm_bht_set_write_cb(bht_.get(), MemoryBhtTest::WriteCallback); | 102 dm_bht_set_write_cb(bht_.get(), MemoryBhtTest::WriteCallback); |
103 dm_bht_set_read_cb(bht_.get(), MemoryBhtTest::ReadCallback); | 103 dm_bht_set_read_cb(bht_.get(), MemoryBhtTest::ReadCallback); |
104 } | 104 } |
105 void SetupBht(const unsigned int depth, | 105 void SetupBht(const unsigned int depth, |
106 const unsigned int total_blocks, | 106 const unsigned int total_blocks, |
107 const char *digest_algorithm) { | 107 const char *digest_algorithm) { |
108 NewBht(depth, total_blocks, digest_algorithm); | 108 NewBht(depth, total_blocks, digest_algorithm); |
109 | 109 |
110 u8 data[PAGE_SIZE]; | 110 u8 data[PAGE_SIZE] = { 0 }; |
111 // Store all the block hashes of blocks of 0. | |
112 memset(reinterpret_cast<void *>(data), 0, sizeof(data)); | |
113 unsigned int blocks = total_blocks; | 111 unsigned int blocks = total_blocks; |
114 do { | 112 do { |
115 EXPECT_EQ(dm_bht_store_block(bht_.get(), blocks - 1, data), 0); | 113 EXPECT_EQ(dm_bht_store_block(bht_.get(), blocks - 1, data), 0); |
116 } while (--blocks > 0); | 114 } while (--blocks > 0); |
117 | 115 |
118 dm_bht_set_read_cb(bht_.get(), dm_bht_zeroread_callback); | 116 dm_bht_set_read_cb(bht_.get(), dm_bht_zeroread_callback); |
119 EXPECT_EQ(0, dm_bht_compute(bht_.get(), NULL)); | 117 EXPECT_EQ(0, dm_bht_compute(bht_.get(), NULL)); |
120 EXPECT_EQ(0, dm_bht_sync(bht_.get(), reinterpret_cast<void *>(this))); | 118 EXPECT_EQ(0, dm_bht_sync(bht_.get(), reinterpret_cast<void *>(this))); |
121 u8 digest[1024]; | 119 u8 digest[1024]; |
122 dm_bht_root_hexdigest(bht_.get(), digest, sizeof(digest)); | 120 dm_bht_root_hexdigest(bht_.get(), digest, sizeof(digest)); |
(...skipping 21 matching lines...) Expand all Loading... |
144 scoped_ptr<struct dm_bht> bht_; | 142 scoped_ptr<struct dm_bht> bht_; |
145 scoped_array<u8> hash_data_; | 143 scoped_array<u8> hash_data_; |
146 sector_t sectors_; | 144 sector_t sectors_; |
147 }; | 145 }; |
148 | 146 |
149 TEST_F(MemoryBhtTest, CreateThenVerifyOk) { | 147 TEST_F(MemoryBhtTest, CreateThenVerifyOk) { |
150 static const unsigned int total_blocks = 16384; | 148 static const unsigned int total_blocks = 16384; |
151 // Set the root hash for a 0-filled image | 149 // Set the root hash for a 0-filled image |
152 static const char kRootDigest[] = | 150 static const char kRootDigest[] = |
153 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; | 151 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; |
154 // This should match what dm_bht_store_block computed earlier. | 152 // A page of all zeros |
155 static const char kZeroDigest[] = | 153 static const char kZeroPage[PAGE_SIZE] = { 0 }; |
156 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | |
157 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | |
158 // TODO(wad) write a test for hex_to_bin and bin_to_hex | |
159 unsigned int digest_size = strlen(kZeroDigest) >> 1; | |
160 | |
161 dm_bht_hex_to_bin(digest, | |
162 reinterpret_cast<const u8 *>(kZeroDigest), | |
163 digest_size); | |
164 | 154 |
165 SetupBht(2, total_blocks, "sha256"); | 155 SetupBht(2, total_blocks, "sha256"); |
166 dm_bht_set_root_hexdigest(bht_.get(), | 156 dm_bht_set_root_hexdigest(bht_.get(), |
167 reinterpret_cast<const u8 *>(kRootDigest)); | 157 reinterpret_cast<const u8 *>(kRootDigest)); |
168 | 158 |
169 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { | 159 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { |
170 DLOG(INFO) << "verifying block: " << blocks; | 160 DLOG(INFO) << "verifying block: " << blocks; |
171 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); | 161 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, kZeroPage)); |
172 } | 162 } |
173 | 163 |
174 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 164 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
175 } | 165 } |
176 | 166 |
177 TEST_F(MemoryBhtTest, CreateThenVerifyMultipleLevels) { | 167 TEST_F(MemoryBhtTest, CreateThenVerifyMultipleLevels) { |
178 static const unsigned int total_blocks = 16384; | 168 static const unsigned int total_blocks = 16384; |
179 // Set the root hash for a 0-filled image | 169 // Set the root hash for a 0-filled image |
180 static const char kRootDigest[] = | 170 static const char kRootDigest[] = |
181 "c86619624d3456f711dbb94d4ad79a4b029f6fd3b5a4a90b155c856bf5b3409b"; | 171 "c86619624d3456f711dbb94d4ad79a4b029f6fd3b5a4a90b155c856bf5b3409b"; |
182 // This should match what dm_bht_store_block computed earlier. | 172 // A page of all zeros |
183 static const char kZeroDigest[] = | 173 static const char kZeroPage[PAGE_SIZE] = { 0 }; |
184 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | |
185 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | |
186 // TODO(wad) write a test for hex_to_bin and bin_to_hex | |
187 unsigned int digest_size = strlen(kZeroDigest) >> 1; | |
188 | |
189 dm_bht_hex_to_bin(digest, | |
190 reinterpret_cast<const u8 *>(kZeroDigest), | |
191 digest_size); | |
192 | 174 |
193 SetupBht(4, total_blocks, "sha256"); | 175 SetupBht(4, total_blocks, "sha256"); |
194 dm_bht_set_root_hexdigest(bht_.get(), | 176 dm_bht_set_root_hexdigest(bht_.get(), |
195 reinterpret_cast<const u8 *>(kRootDigest)); | 177 reinterpret_cast<const u8 *>(kRootDigest)); |
196 | 178 |
197 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { | 179 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { |
198 DLOG(INFO) << "verifying block: " << blocks; | 180 DLOG(INFO) << "verifying block: " << blocks; |
199 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); | 181 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, kZeroPage)); |
200 } | 182 } |
201 | 183 |
202 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 184 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
203 } | 185 } |
204 | 186 |
205 TEST_F(MemoryBhtTest, CreateThenVerifyOddCount) { | 187 TEST_F(MemoryBhtTest, CreateThenVerifyOddCount) { |
206 static const unsigned int total_blocks = 16383; | 188 static const unsigned int total_blocks = 16383; |
207 // Set the root hash for a 0-filled image | 189 // Set the root hash for a 0-filled image |
208 static const char kRootDigest[] = | 190 static const char kRootDigest[] = |
209 "c78d187c430465bd7831fe4908247b6ab5107e3a826d933b71e85aa9a932e03c"; | 191 "c78d187c430465bd7831fe4908247b6ab5107e3a826d933b71e85aa9a932e03c"; |
210 // This should match what dm_bht_store_block computed earlier. | 192 // A page of all zeros |
211 static const char kZeroDigest[] = | 193 static const char kZeroPage[PAGE_SIZE] = { 0 }; |
212 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | |
213 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | |
214 // TODO(wad) write a test for hex_to_bin and bin_to_hex | |
215 unsigned int digest_size = strlen(kZeroDigest) >> 1; | |
216 | |
217 dm_bht_hex_to_bin(digest, | |
218 reinterpret_cast<const u8 *>(kZeroDigest), | |
219 digest_size); | |
220 | 194 |
221 SetupBht(4, total_blocks, "sha256"); | 195 SetupBht(4, total_blocks, "sha256"); |
222 dm_bht_set_root_hexdigest(bht_.get(), | 196 dm_bht_set_root_hexdigest(bht_.get(), |
223 reinterpret_cast<const u8 *>(kRootDigest)); | 197 reinterpret_cast<const u8 *>(kRootDigest)); |
224 | 198 |
225 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { | 199 for (unsigned int blocks = 0; blocks < total_blocks; ++blocks) { |
226 DLOG(INFO) << "verifying block: " << blocks; | 200 DLOG(INFO) << "verifying block: " << blocks; |
227 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, digest, digest_size)); | 201 EXPECT_EQ(0, dm_bht_verify_block(bht_.get(), blocks, kZeroPage)); |
228 } | 202 } |
229 | 203 |
230 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 204 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
231 } | 205 } |
232 | 206 |
233 TEST_F(MemoryBhtTest, CreateThenVerifyBad) { | 207 TEST_F(MemoryBhtTest, CreateThenVerifyBadHashBlock) { |
234 static const unsigned int total_blocks = 16384; | 208 static const unsigned int total_blocks = 16384; |
235 SetupBht(2, total_blocks, "sha256"); | 209 SetupBht(2, total_blocks, "sha256"); |
| 210 // A page of all zeros |
| 211 static const char kZeroPage[PAGE_SIZE] = { 0 }; |
236 // Set the root hash for a 0-filled image | 212 // Set the root hash for a 0-filled image |
237 static const char kRootDigest[] = | 213 static const char kRootDigest[] = |
238 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; | 214 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; |
239 dm_bht_set_root_hexdigest(bht_.get(), | 215 dm_bht_set_root_hexdigest(bht_.get(), |
240 reinterpret_cast<const u8 *>(kRootDigest)); | 216 reinterpret_cast<const u8 *>(kRootDigest)); |
241 | 217 |
242 // TODO(wad) add tests for partial tree validity/verification | 218 // TODO(wad) add tests for partial tree validity/verification |
243 | 219 |
244 // Corrupt one block value | 220 // Corrupt one has hblock |
245 static const unsigned int kBadBlock = 256; | 221 static const unsigned int kBadBlock = 256; |
246 u8 data[PAGE_SIZE]; | 222 u8 data[PAGE_SIZE]; |
247 memset(reinterpret_cast<void *>(data), 'A', sizeof(data)); | 223 memset(reinterpret_cast<void *>(data), 'A', sizeof(data)); |
248 EXPECT_EQ(dm_bht_store_block(bht_.get(), kBadBlock, data), 0); | 224 EXPECT_EQ(dm_bht_store_block(bht_.get(), kBadBlock, data), 0); |
249 | 225 |
250 // This should match what dm_bht_store_block computed earlier. | 226 // Attempt to verify both the bad block and all the neighbors. |
251 static const char kZeroDigest[] = | 227 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + 1, kZeroPage), 0); |
252 "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"; | |
253 u8 digest[(sizeof(kZeroDigest) - 1) >> 1]; | |
254 // TODO(wad) write a test for hex_to_bin and bin_to_hex | |
255 unsigned int digest_size = strlen(kZeroDigest) >> 1; | |
256 dm_bht_hex_to_bin(digest, | |
257 reinterpret_cast<const u8 *>(kZeroDigest), | |
258 digest_size); | |
259 | 228 |
260 // Attempt to verify both the bad block and all the neighbors. | 229 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + 2, kZeroPage), 0); |
261 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + 1, digest, digest_size), | 230 |
| 231 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + (bht_->node_count / 2), |
| 232 kZeroPage), |
262 0); | 233 0); |
263 | 234 |
264 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + 2, digest, digest_size), | 235 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock, kZeroPage), 0); |
265 0); | |
266 | |
267 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock + (bht_->node_count / 2), | |
268 digest, digest_size), | |
269 0); | |
270 | |
271 EXPECT_LT(dm_bht_verify_block(bht_.get(), kBadBlock, digest, digest_size), 0); | |
272 | 236 |
273 // Verify that the prior entry is untouched and still safe | 237 // Verify that the prior entry is untouched and still safe |
274 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock - 1, digest, digest_size), | 238 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock - 1, kZeroPage), 0); |
275 0); | |
276 | 239 |
277 // Same for the next entry | 240 // Same for the next entry |
278 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock + bht_->node_count, | 241 EXPECT_EQ(dm_bht_verify_block(bht_.get(), kBadBlock + bht_->node_count, |
279 digest, digest_size), | 242 kZeroPage), |
280 0); | 243 0); |
281 | 244 |
282 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); | 245 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
283 } | 246 } |
| 247 |
| 248 TEST_F(MemoryBhtTest, CreateThenVerifyBadDataBlock) { |
| 249 static const unsigned int total_blocks = 384; |
| 250 SetupBht(2, total_blocks, "sha256"); |
| 251 // Set the root hash for a 0-filled image |
| 252 static const char kRootDigest[] = |
| 253 "45d65d6f9e5a962f4d80b5f1bd7a918152251c27bdad8c5f52b590c129833372"; |
| 254 dm_bht_set_root_hexdigest(bht_.get(), |
| 255 reinterpret_cast<const u8 *>(kRootDigest)); |
| 256 // A corrupt page |
| 257 static const u8 kBadPage[PAGE_SIZE] = { 'A' }; |
| 258 |
| 259 EXPECT_LT(dm_bht_verify_block(bht_.get(), 0, kBadPage), 0); |
| 260 EXPECT_LT(dm_bht_verify_block(bht_.get(), 127, kBadPage), 0); |
| 261 EXPECT_LT(dm_bht_verify_block(bht_.get(), 128, kBadPage), 0); |
| 262 EXPECT_LT(dm_bht_verify_block(bht_.get(), 255, kBadPage), 0); |
| 263 EXPECT_LT(dm_bht_verify_block(bht_.get(), 256, kBadPage), 0); |
| 264 EXPECT_LT(dm_bht_verify_block(bht_.get(), 383, kBadPage), 0); |
| 265 |
| 266 EXPECT_EQ(0, dm_bht_destroy(bht_.get())); |
| 267 } |
OLD | NEW |