1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 #include <iostream>
26
27 #include <endian.h>
28 #include <inttypes.h>
29 #include <string.h>
30
31 #include <base/files/file_util.h>
32 #include <base/strings/string_split.h>
33 #include <base/strings/string_util.h>
34 #include <base/strings/stringprintf.h>
35
36 #include <libavb/avb_sha.h>
37 #include <libavb/libavb.h>
38
39 #include "avb_unittest_util.h"
40 #include "fake_avb_ops.h"
41
42 namespace avb {
43
44 class AvbToolTest : public BaseAvbToolTest {
45 public:
AvbToolTest()46 AvbToolTest() {}
47
SetUp()48 virtual void SetUp() override {
49 BaseAvbToolTest::SetUp();
50 ops_.set_partition_dir(testdir_);
51 ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}, {2, 0}, {3, 0}});
52 ops_.set_stored_is_device_unlocked(false);
53 }
54
55 void AddHashFooterTest(bool sparse_image);
56 void AddHashtreeFooterTest(bool sparse_image);
57 void AddHashtreeFooterFECTest(bool sparse_image);
58
59 void GenerateImageWithHashAndHashtreeSetup();
60
61 FakeAvbOps ops_;
62 };
63
64 // This test ensure that the version is increased in both
65 // avb_boot_image.h and the avb tool.
TEST_F(AvbToolTest,AvbVersionInSync)66 TEST_F(AvbToolTest, AvbVersionInSync) {
67 base::FilePath path = testdir_.Append("version.txt");
68 EXPECT_COMMAND(0, "./avbtool version > %s", path.value().c_str());
69 std::string printed_version;
70 ASSERT_TRUE(base::ReadFileToString(path, &printed_version));
71 base::TrimWhitespaceASCII(printed_version, base::TRIM_ALL, &printed_version);
72 // See comments in libavb/avb_version.c and avbtool's get_release_string()
73 // about being in sync.
74 EXPECT_EQ(printed_version,
75 std::string("avbtool ") + std::string(avb_version_string()));
76 }
77
TEST_F(AvbToolTest,DefaultReleaseString)78 TEST_F(AvbToolTest, DefaultReleaseString) {
79 GenerateVBMetaImage("vbmeta.img",
80 "SHA256_RSA2048",
81 0,
82 base::FilePath("test/data/testkey_rsa2048.pem"));
83
84 // Default release string is "avbtool " + avb_version_string().
85 AvbVBMetaImageHeader h;
86 avb_vbmeta_image_header_to_host_byte_order(
87 reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
88 EXPECT_EQ(std::string("avbtool ") + std::string(avb_version_string()),
89 std::string((const char*)h.release_string));
90 }
91
TEST_F(AvbToolTest,ReleaseStringAppend)92 TEST_F(AvbToolTest, ReleaseStringAppend) {
93 GenerateVBMetaImage("vbmeta.img",
94 "SHA256_RSA2048",
95 0,
96 base::FilePath("test/data/testkey_rsa2048.pem"),
97 "--append_to_release_string \"Woot XYZ\"");
98
99 // Note that avbtool inserts the space by itself.
100 std::string expected_str =
101 std::string("avbtool ") + std::string(avb_version_string()) + " Woot XYZ";
102
103 AvbVBMetaImageHeader h;
104 avb_vbmeta_image_header_to_host_byte_order(
105 reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
106 EXPECT_EQ(expected_str, std::string((const char*)h.release_string));
107 }
108
TEST_F(AvbToolTest,ReleaseStringAppendTruncated)109 TEST_F(AvbToolTest, ReleaseStringAppendTruncated) {
110 // Append enough text that truncation is sure to happen.
111 std::string append_str = "0123456789abcdef0123456789abcdef0123456789abcdef";
112 std::string expected_str = std::string("avbtool ") +
113 std::string(avb_version_string()) + " " +
114 append_str;
115 EXPECT_GT(expected_str.size(), (size_t)(AVB_RELEASE_STRING_SIZE - 1));
116 expected_str.resize(AVB_RELEASE_STRING_SIZE - 1);
117
118 GenerateVBMetaImage(
119 "vbmeta.img",
120 "SHA256_RSA2048",
121 0,
122 base::FilePath("test/data/testkey_rsa2048.pem"),
123 std::string("--append_to_release_string \"") + append_str + "\"");
124
125 // This checks that it ends with a NUL byte.
126 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
127 avb_vbmeta_image_verify(
128 vbmeta_image_.data(), vbmeta_image_.size(), nullptr, nullptr));
129
130 // For good measure we also check here.
131 AvbVBMetaImageHeader h;
132 avb_vbmeta_image_header_to_host_byte_order(
133 reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
134 EXPECT_EQ(expected_str, std::string((const char*)h.release_string));
135 }
136
TEST_F(AvbToolTest,ExtractPublicKey)137 TEST_F(AvbToolTest, ExtractPublicKey) {
138 GenerateVBMetaImage("vbmeta.img",
139 "SHA256_RSA2048",
140 0,
141 base::FilePath("test/data/testkey_rsa2048.pem"),
142 "--internal_release_string \"\"");
143
144 std::string key_data =
145 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem"));
146
147 AvbVBMetaImageHeader h;
148 avb_vbmeta_image_header_to_host_byte_order(
149 reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
150 uint8_t* d = reinterpret_cast<uint8_t*>(vbmeta_image_.data());
151 size_t auxiliary_data_block_offset =
152 sizeof(AvbVBMetaImageHeader) + h.authentication_data_block_size;
153 EXPECT_GT(h.auxiliary_data_block_size, key_data.size());
154 EXPECT_EQ(0,
155 memcmp(key_data.data(),
156 d + auxiliary_data_block_offset + h.public_key_offset,
157 key_data.size()));
158 }
159
TEST_F(AvbToolTest,CheckDescriptors)160 TEST_F(AvbToolTest, CheckDescriptors) {
161 GenerateVBMetaImage("vbmeta.img",
162 "SHA256_RSA2048",
163 0,
164 base::FilePath("test/data/testkey_rsa2048.pem"),
165 "--prop foo:brillo "
166 "--prop bar:chromeos "
167 "--prop prisoner:24601 "
168 "--prop hexnumber:0xcafe "
169 "--prop hexnumber_capital:0xCAFE "
170 "--prop large_hexnumber:0xfedcba9876543210 "
171 "--prop larger_than_uint64:0xfedcba98765432101 "
172 "--prop almost_a_number:423x "
173 "--prop_from_file blob:test/data/small_blob.bin "
174 "--internal_release_string \"\"");
175
176 AvbVBMetaImageHeader h;
177 avb_vbmeta_image_header_to_host_byte_order(
178 reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
179
180 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
181 avb_vbmeta_image_verify(
182 vbmeta_image_.data(), vbmeta_image_.size(), nullptr, nullptr));
183
184 const char* s;
185 size_t len;
186 uint64_t val;
187
188 // Basic.
189 s = avb_property_lookup(
190 vbmeta_image_.data(), vbmeta_image_.size(), "foo", 0, &len);
191 EXPECT_EQ(0, strcmp(s, "brillo"));
192 EXPECT_EQ(6U, len);
193 s = avb_property_lookup(
194 vbmeta_image_.data(), vbmeta_image_.size(), "bar", 0, &len);
195 EXPECT_EQ(0, strcmp(s, "chromeos"));
196 EXPECT_EQ(8U, len);
197 s = avb_property_lookup(
198 vbmeta_image_.data(), vbmeta_image_.size(), "non-existant", 0, &len);
199 EXPECT_EQ(0U, len);
200 EXPECT_EQ(NULL, s);
201
202 // Numbers.
203 EXPECT_NE(
204 0,
205 avb_property_lookup_uint64(
206 vbmeta_image_.data(), vbmeta_image_.size(), "prisoner", 0, &val));
207 EXPECT_EQ(24601U, val);
208
209 EXPECT_NE(
210 0,
211 avb_property_lookup_uint64(
212 vbmeta_image_.data(), vbmeta_image_.size(), "hexnumber", 0, &val));
213 EXPECT_EQ(0xcafeU, val);
214
215 EXPECT_NE(0,
216 avb_property_lookup_uint64(vbmeta_image_.data(),
217 vbmeta_image_.size(),
218 "hexnumber_capital",
219 0,
220 &val));
221 EXPECT_EQ(0xcafeU, val);
222
223 EXPECT_NE(0,
224 avb_property_lookup_uint64(vbmeta_image_.data(),
225 vbmeta_image_.size(),
226 "large_hexnumber",
227 0,
228 &val));
229 EXPECT_EQ(0xfedcba9876543210U, val);
230
231 // We could catch overflows and return an error ... but we currently don't.
232 EXPECT_NE(0,
233 avb_property_lookup_uint64(vbmeta_image_.data(),
234 vbmeta_image_.size(),
235 "larger_than_uint64",
236 0,
237 &val));
238 EXPECT_EQ(0xedcba98765432101U, val);
239
240 // Number-parsing failures.
241 EXPECT_EQ(0,
242 avb_property_lookup_uint64(
243 vbmeta_image_.data(), vbmeta_image_.size(), "foo", 0, &val));
244
245 EXPECT_EQ(0,
246 avb_property_lookup_uint64(vbmeta_image_.data(),
247 vbmeta_image_.size(),
248 "almost_a_number",
249 0,
250 &val));
251
252 // Blobs.
253 //
254 // test/data/small_blob.bin is 21 byte file full of NUL-bytes except
255 // for the string "brillo ftw!" at index 2 and '\n' at the last
256 // byte.
257 s = avb_property_lookup(
258 vbmeta_image_.data(), vbmeta_image_.size(), "blob", 0, &len);
259 EXPECT_EQ(21U, len);
260 EXPECT_EQ(0, memcmp(s, "\0\0", 2));
261 EXPECT_EQ(0, memcmp(s + 2, "brillo ftw!", 11));
262 EXPECT_EQ(0, memcmp(s + 13, "\0\0\0\0\0\0\0", 7));
263 EXPECT_EQ('\n', s[20]);
264 }
265
TEST_F(AvbToolTest,Padding)266 TEST_F(AvbToolTest, Padding) {
267 GenerateVBMetaImage("vbmeta.img",
268 "SHA256_RSA2048",
269 0,
270 base::FilePath("test/data/testkey_rsa2048.pem"),
271 "--internal_release_string \"\"");
272
273 GenerateVBMetaImage("vbmeta_padded.img",
274 "SHA256_RSA2048",
275 0,
276 base::FilePath("test/data/testkey_rsa2048.pem"),
277 "--internal_release_string \"\" --padding_size 4096");
278
279 base::FilePath vbmeta_path = testdir_.Append("vbmeta.img");
280 base::FilePath vbmeta_padded_path = testdir_.Append("vbmeta_padded.img");
281 int64_t vbmeta_size, vbmeta_padded_size;
282 ASSERT_TRUE(base::GetFileSize(vbmeta_path, &vbmeta_size));
283 ASSERT_TRUE(base::GetFileSize(vbmeta_padded_path, &vbmeta_padded_size));
284
285 EXPECT_NE(vbmeta_size, vbmeta_padded_size);
286
287 // The padded size should be a multiple of 4096.
288 EXPECT_EQ(vbmeta_padded_size % 4096, 0);
289
290 // When rounded up the unpadded size should equal the padded size.
291 int64_t vbmeta_size_rounded_up = ((vbmeta_size + 4095) / 4096) * 4096;
292 EXPECT_EQ(vbmeta_size_rounded_up, vbmeta_padded_size);
293 }
294
TEST_F(AvbToolTest,CheckRollbackIndex)295 TEST_F(AvbToolTest, CheckRollbackIndex) {
296 uint64_t rollback_index = 42;
297 GenerateVBMetaImage("vbmeta.img",
298 "SHA256_RSA2048",
299 rollback_index,
300 base::FilePath("test/data/testkey_rsa2048.pem"),
301 "--internal_release_string \"\"");
302
303 AvbVBMetaImageHeader h;
304 avb_vbmeta_image_header_to_host_byte_order(
305 reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
306
307 EXPECT_EQ(rollback_index, h.rollback_index);
308 }
309
TEST_F(AvbToolTest,CheckPubkeyReturned)310 TEST_F(AvbToolTest, CheckPubkeyReturned) {
311 GenerateVBMetaImage("vbmeta.img",
312 "SHA256_RSA2048",
313 0,
314 base::FilePath("test/data/testkey_rsa2048.pem"),
315 "--internal_release_string \"\"");
316
317 const uint8_t* pubkey = NULL;
318 size_t pubkey_length = 0;
319
320 EXPECT_EQ(
321 AVB_VBMETA_VERIFY_RESULT_OK,
322 avb_vbmeta_image_verify(
323 vbmeta_image_.data(), vbmeta_image_.size(), &pubkey, &pubkey_length));
324
325 AvbVBMetaImageHeader h;
326 avb_vbmeta_image_header_to_host_byte_order(
327 reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
328
329 EXPECT_EQ(pubkey_length, h.public_key_size);
330
331 const uint8_t* expected_pubkey =
332 vbmeta_image_.data() + sizeof(AvbVBMetaImageHeader) +
333 h.authentication_data_block_size + h.public_key_offset;
334 EXPECT_EQ(pubkey, expected_pubkey);
335 }
336
TEST_F(AvbToolTest,Info)337 TEST_F(AvbToolTest, Info) {
338 GenerateVBMetaImage("vbmeta.img",
339 "SHA256_RSA2048",
340 0,
341 base::FilePath("test/data/testkey_rsa2048.pem"),
342 "--prop foo:brillo "
343 "--prop bar:chromeos "
344 "--prop prisoner:24601 "
345 "--prop hexnumber:0xcafe "
346 "--prop hexnumber_capital:0xCAFE "
347 "--prop large_hexnumber:0xfedcba9876543210 "
348 "--prop larger_than_uint64:0xfedcba98765432101 "
349 "--prop almost_a_number:423x "
350 "--prop_from_file blob:test/data/small_blob.bin "
351 "--prop_from_file large_blob:test/data/large_blob.bin "
352 "--internal_release_string \"\"");
353
354 ASSERT_EQ(
355 "Minimum libavb version: 1.0\n"
356 "Header Block: 256 bytes\n"
357 "Authentication Block: 320 bytes\n"
358 "Auxiliary Block: 3200 bytes\n"
359 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
360 "Algorithm: SHA256_RSA2048\n"
361 "Rollback Index: 0\n"
362 "Flags: 0\n"
363 "Release String: ''\n"
364 "Descriptors:\n"
365 " Prop: foo -> 'brillo'\n"
366 " Prop: bar -> 'chromeos'\n"
367 " Prop: prisoner -> '24601'\n"
368 " Prop: hexnumber -> '0xcafe'\n"
369 " Prop: hexnumber_capital -> '0xCAFE'\n"
370 " Prop: large_hexnumber -> '0xfedcba9876543210'\n"
371 " Prop: larger_than_uint64 -> '0xfedcba98765432101'\n"
372 " Prop: almost_a_number -> '423x'\n"
373 " Prop: blob -> '\\x00\\x00brillo "
374 "ftw!\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\n'\n"
375 " Prop: large_blob -> (2048 bytes)\n",
376 InfoImage(vbmeta_image_path_));
377 }
378
collect_descriptors(const AvbDescriptor * descriptor,void * user_data)379 static bool collect_descriptors(const AvbDescriptor* descriptor,
380 void* user_data) {
381 std::vector<const AvbDescriptor*>* descriptors =
382 reinterpret_cast<std::vector<const AvbDescriptor*>*>(user_data);
383 descriptors->push_back(descriptor);
384 return true; // Keep iterating.
385 }
386
AddHashFooterGetExpectedVBMetaInfo(const bool sparse_image,const uint64_t partition_size)387 static std::string AddHashFooterGetExpectedVBMetaInfo(
388 const bool sparse_image, const uint64_t partition_size) {
389 return base::StringPrintf(
390 "Footer version: 1.0\n"
391 "Image size: %" PRIu64
392 " bytes\n"
393 "Original image size: 1052672 bytes\n"
394 "VBMeta offset: 1052672\n"
395 "VBMeta size: 1280 bytes\n"
396 "--\n"
397 "Minimum libavb version: 1.0%s\n"
398 "Header Block: 256 bytes\n"
399 "Authentication Block: 320 bytes\n"
400 "Auxiliary Block: 704 bytes\n"
401 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
402 "Algorithm: SHA256_RSA2048\n"
403 "Rollback Index: 0\n"
404 "Flags: 0\n"
405 "Release String: ''\n"
406 "Descriptors:\n"
407 " Hash descriptor:\n"
408 " Image Size: 1052672 bytes\n"
409 " Hash Algorithm: sha256\n"
410 " Partition Name: foobar\n"
411 " Salt: d00df00d\n"
412 " Digest: "
413 "9a58cc996d405e08a1e00f96dbfe9104fedf41cb83b1f"
414 "5e4ed357fbcf58d88d9\n"
415 " Flags: 0\n",
416 partition_size,
417 sparse_image ? " (Sparse)" : "");
418 }
419
AddHashFooterTest(bool sparse_image)420 void AvbToolTest::AddHashFooterTest(bool sparse_image) {
421 const size_t rootfs_size = 1028 * 1024;
422 const size_t partition_size = 1536 * 1024;
423 const size_t resized_partition_size = 1280 * 1024;
424
425 // Generate a 1028 KiB file with known content. Some content have
426 // been arranged to ensure FILL_DATA segments in the sparse file.
427 std::vector<uint8_t> rootfs;
428 rootfs.resize(rootfs_size);
429 for (size_t n = 0; n < rootfs_size; n++) {
430 if ((n >= 5 * 1000 && n < 105 * 1000) ||
431 (n >= 205 * 1000 && n < 305 * 1000) ||
432 (n >= 505 * 1000 && n < 605 * 1000)) {
433 rootfs[n] = uint8_t(n) & 0x03;
434 } else {
435 rootfs[n] = uint8_t(n);
436 }
437 }
438 base::FilePath external_vbmeta_path = testdir_.Append("external_vbmeta.bin");
439 base::FilePath extracted_vbmeta_path =
440 testdir_.Append("extracted_vbmeta.bin");
441 base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
442 EXPECT_EQ(rootfs_size,
443 static_cast<const size_t>(
444 base::WriteFile(rootfs_path,
445 reinterpret_cast<const char*>(rootfs.data()),
446 rootfs.size())));
447
448 if (sparse_image) {
449 EXPECT_COMMAND(0,
450 "mv %s %s.unsparse",
451 rootfs_path.value().c_str(),
452 rootfs_path.value().c_str());
453 EXPECT_COMMAND(0,
454 "img2simg %s.unsparse %s",
455 rootfs_path.value().c_str(),
456 rootfs_path.value().c_str());
457 EXPECT_COMMAND(0, "rm -f %s.unsparse", rootfs_path.value().c_str());
458 }
459
460 /* Do this twice to check that 'add_hash_footer' is idempotent. */
461 for (int n = 0; n < 2; n++) {
462 EXPECT_COMMAND(0,
463 "./avbtool add_hash_footer --salt d00df00d "
464 "--hash_algorithm sha256 --image %s "
465 "--partition_size %d --partition_name foobar "
466 "--algorithm SHA256_RSA2048 "
467 "--key test/data/testkey_rsa2048.pem "
468 "--output_vbmeta %s "
469 "--internal_release_string \"\"",
470 rootfs_path.value().c_str(),
471 (int)partition_size,
472 external_vbmeta_path.value().c_str());
473
474 ASSERT_EQ(AddHashFooterGetExpectedVBMetaInfo(sparse_image, partition_size),
475 InfoImage(rootfs_path));
476
477 ASSERT_EQ(
478 "Minimum libavb version: 1.0\n"
479 "Header Block: 256 bytes\n"
480 "Authentication Block: 320 bytes\n"
481 "Auxiliary Block: 704 bytes\n"
482 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
483 "Algorithm: SHA256_RSA2048\n"
484 "Rollback Index: 0\n"
485 "Flags: 0\n"
486 "Release String: ''\n"
487 "Descriptors:\n"
488 " Hash descriptor:\n"
489 " Image Size: 1052672 bytes\n"
490 " Hash Algorithm: sha256\n"
491 " Partition Name: foobar\n"
492 " Salt: d00df00d\n"
493 " Digest: "
494 "9a58cc996d405e08a1e00f96dbfe9104fedf41cb83b1f"
495 "5e4ed357fbcf58d88d9\n"
496 " Flags: 0\n",
497 InfoImage(external_vbmeta_path));
498
499 // Check that the extracted vbmeta matches the externally generally one.
500 EXPECT_COMMAND(0,
501 "./avbtool extract_vbmeta_image --image %s "
502 "--output %s",
503 rootfs_path.value().c_str(),
504 extracted_vbmeta_path.value().c_str());
505 EXPECT_COMMAND(0,
506 "diff %s %s",
507 external_vbmeta_path.value().c_str(),
508 extracted_vbmeta_path.value().c_str());
509 }
510
511 // Resize the image and check that the only thing that has changed
512 // is where the footer is. First check that resizing to a smaller
513 // size than the original rootfs fails. Then resize to something
514 // larger than the original rootfs but smaller than the current
515 // partition size.
516 EXPECT_COMMAND(1,
517 "./avbtool resize_image --image %s "
518 "--partition_size %d",
519 rootfs_path.value().c_str(),
520 (int)(rootfs_size - 16 * 1024));
521 EXPECT_COMMAND(0,
522 "./avbtool resize_image --image %s "
523 "--partition_size %d",
524 rootfs_path.value().c_str(),
525 (int)resized_partition_size);
526 ASSERT_EQ(
527 AddHashFooterGetExpectedVBMetaInfo(sparse_image, resized_partition_size),
528 InfoImage(rootfs_path));
529
530 if (sparse_image) {
531 EXPECT_COMMAND(0,
532 "mv %s %s.sparse",
533 rootfs_path.value().c_str(),
534 rootfs_path.value().c_str());
535 EXPECT_COMMAND(0,
536 "simg2img %s.sparse %s",
537 rootfs_path.value().c_str(),
538 rootfs_path.value().c_str());
539 EXPECT_COMMAND(0, "rm -f %s.sparse", rootfs_path.value().c_str());
540 }
541
542 // Manually calculate the hash to check that it agrees with avbtool.
543 AvbSHA256Ctx hasher_ctx;
544 const uint8_t hasher_salt[4] = {0xd0, 0x0d, 0xf0, 0x0d};
545 avb_sha256_init(&hasher_ctx);
546 avb_sha256_update(&hasher_ctx, hasher_salt, 4);
547 avb_sha256_update(&hasher_ctx, rootfs.data(), rootfs_size);
548 uint8_t* hasher_digest = avb_sha256_final(&hasher_ctx);
549 EXPECT_EQ("9a58cc996d405e08a1e00f96dbfe9104fedf41cb83b1f5e4ed357fbcf58d88d9",
550 mem_to_hexstring(hasher_digest, AVB_SHA256_DIGEST_SIZE));
551
552 // Now check that we can find the VBMeta block again from the footer.
553 std::string part_data;
554 ASSERT_TRUE(base::ReadFileToString(rootfs_path, &part_data));
555
556 // Check footer contains correct data.
557 AvbFooter f;
558 EXPECT_NE(0,
559 avb_footer_validate_and_byteswap(
560 reinterpret_cast<const AvbFooter*>(
561 part_data.data() + part_data.size() - AVB_FOOTER_SIZE),
562 &f));
563 EXPECT_EQ(
564 std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
565 AVB_FOOTER_MAGIC);
566 EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
567 EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
568 EXPECT_EQ(1052672UL, f.original_image_size);
569 EXPECT_EQ(1052672UL, f.vbmeta_offset);
570 EXPECT_EQ(1280UL, f.vbmeta_size);
571
572 // Check that the vbmeta image at |f.vbmeta_offset| checks out.
573 const uint8_t* vbmeta_data =
574 reinterpret_cast<const uint8_t*>(part_data.data() + f.vbmeta_offset);
575 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
576 avb_vbmeta_image_verify(vbmeta_data, f.vbmeta_size, NULL, NULL));
577
578 // Collect all descriptors.
579 std::vector<const AvbDescriptor*> descriptors;
580 avb_descriptor_foreach(
581 vbmeta_data, f.vbmeta_size, collect_descriptors, &descriptors);
582
583 // We should only have a single descriptor and it should be a
584 // hash descriptor.
585 EXPECT_EQ(1UL, descriptors.size());
586 EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASH, avb_be64toh(descriptors[0]->tag));
587 AvbHashDescriptor d;
588 EXPECT_NE(
589 0,
590 avb_hash_descriptor_validate_and_byteswap(
591 reinterpret_cast<const AvbHashDescriptor*>(descriptors[0]), &d));
592 EXPECT_EQ(1052672UL, d.image_size);
593 EXPECT_EQ(6UL, d.partition_name_len);
594 EXPECT_EQ(4UL, d.salt_len);
595 EXPECT_EQ(32UL, d.digest_len);
596 const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
597 sizeof(AvbHashDescriptor);
598 uint64_t o = 0;
599 EXPECT_EQ("foobar",
600 std::string(reinterpret_cast<const char*>(desc_end + o),
601 d.partition_name_len));
602 o += d.partition_name_len;
603 EXPECT_EQ("d00df00d", mem_to_hexstring(desc_end + o, d.salt_len));
604 o += d.salt_len;
605 EXPECT_EQ("9a58cc996d405e08a1e00f96dbfe9104fedf41cb83b1f5e4ed357fbcf58d88d9",
606 mem_to_hexstring(desc_end + o, d.digest_len));
607
608 // Check that the footer is correctly erased.
609 EXPECT_COMMAND(
610 0, "./avbtool erase_footer --image %s", rootfs_path.value().c_str());
611 int64_t erased_footer_file_size;
612 ASSERT_TRUE(base::GetFileSize(rootfs_path, &erased_footer_file_size));
613 EXPECT_EQ(static_cast<size_t>(erased_footer_file_size), rootfs_size);
614
615 // Check that --do_not_append_vbmeta_image works as intended.
616 EXPECT_COMMAND(0,
617 "./avbtool add_hash_footer --salt d00df00d "
618 "--hash_algorithm sha256 --image %s "
619 "--partition_size %d --partition_name foobar "
620 "--algorithm SHA256_RSA2048 "
621 "--key test/data/testkey_rsa2048.pem "
622 "--output_vbmeta %s_2nd_run --do_not_append_vbmeta_image "
623 "--internal_release_string \"\"",
624 rootfs_path.value().c_str(),
625 (int)partition_size,
626 external_vbmeta_path.value().c_str());
627 int64_t file_size;
628 ASSERT_TRUE(base::GetFileSize(rootfs_path, &file_size));
629 EXPECT_EQ(static_cast<size_t>(file_size), rootfs_size);
630 EXPECT_COMMAND(0,
631 "diff %s %s_2nd_run",
632 external_vbmeta_path.value().c_str(),
633 external_vbmeta_path.value().c_str());
634 }
635
TEST_F(AvbToolTest,AddHashFooter)636 TEST_F(AvbToolTest, AddHashFooter) {
637 AddHashFooterTest(false);
638 }
639
TEST_F(AvbToolTest,AddHashFooterSparse)640 TEST_F(AvbToolTest, AddHashFooterSparse) {
641 AddHashFooterTest(true);
642 }
643
RemoveLinesStartingWith(const std::string & str,const std::string & prefix)644 static std::string RemoveLinesStartingWith(const std::string& str,
645 const std::string& prefix) {
646 std::vector<std::string> lines;
647 std::string ret;
648
649 lines = base::SplitString(
650 str, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
651 for (const std::string& line : lines) {
652 if (!base::StartsWith(line, prefix, base::CompareCase::SENSITIVE)) {
653 ret += line;
654 ret += '\n';
655 }
656 }
657 return ret;
658 }
659
660 // NOTE: make_ext4fs was removed and there is no replacement for how we use
661 // it... so this is currently disabled..
TEST_F(AvbToolTest,DISABLED_AddHashFooterSparseWithHoleAtTheEnd)662 TEST_F(AvbToolTest, DISABLED_AddHashFooterSparseWithHoleAtTheEnd) {
663 const size_t partition_size = 10 * 1024 * 1024;
664 const size_t metadata_size = 128 * 1024;
665
666 // It's not enough to run img2simg on a file with a lot of zeroes at
667 // the end since that will turn up as "Fill with value (for value =
668 // 0x00000000)" and not "Don't care". Instead, use make_ext4fs for
669 // this since it will put a big hole (e.g. "Don't care" chunk) at
670 // the end.
671 base::FilePath partition_path = testdir_.Append("partition.bin");
672 EXPECT_COMMAND(0,
673 "make_ext4fs -s -L test -l %zd %s",
674 partition_size - metadata_size,
675 partition_path.value().c_str());
676
677 EXPECT_COMMAND(0,
678 "./avbtool add_hash_footer --salt d00df00d "
679 "--hash_algorithm sha256 --image %s "
680 "--partition_size %d --partition_name foobar "
681 "--algorithm SHA256_RSA2048 "
682 "--key test/data/testkey_rsa2048.pem "
683 "--internal_release_string \"\"",
684 partition_path.value().c_str(),
685 (int)partition_size);
686
687 // Since we may be using an arbritary version of make_ext4fs
688 // (because of different branches) the contents of the resulting
689 // disk image may slightly change. It's enough to just remove the
690 // "Digest:" line from the output to work around this.
691 std::string info =
692 RemoveLinesStartingWith(InfoImage(partition_path), " Digest:");
693 ASSERT_EQ(
694 "Footer version: 1.0\n"
695 "Image size: 10485760 bytes\n"
696 "Original image size: 10354688 bytes\n"
697 "VBMeta offset: 10354688\n"
698 "VBMeta size: 1280 bytes\n"
699 "--\n"
700 "Minimum libavb version: 1.0 (Sparse)\n"
701 "Header Block: 256 bytes\n"
702 "Authentication Block: 320 bytes\n"
703 "Auxiliary Block: 704 bytes\n"
704 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
705 "Algorithm: SHA256_RSA2048\n"
706 "Rollback Index: 0\n"
707 "Flags: 0\n"
708 "Release String: ''\n"
709 "Descriptors:\n"
710 " Hash descriptor:\n"
711 " Image Size: 10354688 bytes\n"
712 " Hash Algorithm: sha256\n"
713 " Partition Name: foobar\n"
714 " Salt: d00df00d\n"
715 " Flags: 0\n",
716 info);
717
718 EXPECT_COMMAND(0,
719 "mv %s %s.sparse",
720 partition_path.value().c_str(),
721 partition_path.value().c_str());
722 EXPECT_COMMAND(0,
723 "simg2img %s.sparse %s",
724 partition_path.value().c_str(),
725 partition_path.value().c_str());
726 EXPECT_COMMAND(0, "rm -f %s.sparse", partition_path.value().c_str());
727 }
728
TEST_F(AvbToolTest,AddHashFooterCalcMaxImageSize)729 TEST_F(AvbToolTest, AddHashFooterCalcMaxImageSize) {
730 const size_t partition_size = 10 * 1024 * 1024;
731 base::FilePath output_path = testdir_.Append("max_size.txt");
732
733 EXPECT_COMMAND(0,
734 "./avbtool add_hash_footer "
735 "--partition_size %zd "
736 "--calc_max_image_size > %s",
737 partition_size,
738 output_path.value().c_str());
739 std::string max_image_size_data;
740 EXPECT_TRUE(base::ReadFileToString(output_path, &max_image_size_data));
741 EXPECT_EQ("10416128\n", max_image_size_data);
742 size_t max_image_size = atoll(max_image_size_data.c_str());
743
744 // Metadata takes up 68 KiB.
745 EXPECT_EQ(68 * 1024ULL, partition_size - max_image_size);
746
747 // Check that we can add a hash footer for an image this size for
748 // such a partition size.
749 base::FilePath boot_path = GenerateImage("boot", max_image_size);
750 EXPECT_COMMAND(0,
751 "./avbtool add_hash_footer"
752 " --image %s"
753 " --partition_name boot"
754 " --partition_size %zd"
755 " --salt deadbeef"
756 " --algorithm SHA512_RSA4096 "
757 " --key test/data/testkey_rsa4096.pem"
758 " --internal_release_string \"\"",
759 boot_path.value().c_str(),
760 partition_size);
761 }
762
TEST_F(AvbToolTest,AddHashFooterWithPersistentDigest)763 TEST_F(AvbToolTest, AddHashFooterWithPersistentDigest) {
764 size_t partition_size = 1024 * 1024;
765 base::FilePath path = GenerateImage("digest_location", 1024);
766 EXPECT_COMMAND(0,
767 "./avbtool add_hash_footer "
768 "--hash_algorithm sha256 --image %s "
769 "--partition_size %d --partition_name foobar "
770 "--algorithm SHA256_RSA2048 "
771 "--key test/data/testkey_rsa2048.pem "
772 "--internal_release_string \"\" "
773 "--use_persistent_digest",
774 path.value().c_str(),
775 (int)partition_size);
776 // There are two important bits specific to these flags:
777 // Minimum libavb version = 1.1
778 // Hash descriptor -> Digest = (empty)
779 ASSERT_EQ(
780 "Footer version: 1.0\n"
781 "Image size: 1048576 bytes\n"
782 "Original image size: 1024 bytes\n"
783 "VBMeta offset: 4096\n"
784 "VBMeta size: 1280 bytes\n"
785 "--\n"
786 "Minimum libavb version: 1.1\n"
787 "Header Block: 256 bytes\n"
788 "Authentication Block: 320 bytes\n"
789 "Auxiliary Block: 704 bytes\n"
790 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
791 "Algorithm: SHA256_RSA2048\n"
792 "Rollback Index: 0\n"
793 "Flags: 0\n"
794 "Release String: ''\n"
795 "Descriptors:\n"
796 " Hash descriptor:\n"
797 " Image Size: 1024 bytes\n"
798 " Hash Algorithm: sha256\n"
799 " Partition Name: foobar\n"
800 " Salt: \n"
801 " Digest: \n"
802 " Flags: 0\n",
803 InfoImage(path));
804 }
805
TEST_F(AvbToolTest,AddHashFooterWithNoAB)806 TEST_F(AvbToolTest, AddHashFooterWithNoAB) {
807 size_t partition_size = 1024 * 1024;
808 base::FilePath path = GenerateImage("digest_location", 1024);
809 EXPECT_COMMAND(0,
810 "./avbtool add_hash_footer --salt d00df00d "
811 "--hash_algorithm sha256 --image %s "
812 "--partition_size %d --partition_name foobar "
813 "--algorithm SHA256_RSA2048 "
814 "--key test/data/testkey_rsa2048.pem "
815 "--internal_release_string \"\" "
816 "--do_not_use_ab",
817 path.value().c_str(),
818 (int)partition_size);
819 // There are two important bits specific to these flags:
820 // Minimum libavb version = 1.1
821 // Hash descriptor -> Flags = 1
822 ASSERT_EQ(
823 "Footer version: 1.0\n"
824 "Image size: 1048576 bytes\n"
825 "Original image size: 1024 bytes\n"
826 "VBMeta offset: 4096\n"
827 "VBMeta size: 1280 bytes\n"
828 "--\n"
829 "Minimum libavb version: 1.1\n"
830 "Header Block: 256 bytes\n"
831 "Authentication Block: 320 bytes\n"
832 "Auxiliary Block: 704 bytes\n"
833 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
834 "Algorithm: SHA256_RSA2048\n"
835 "Rollback Index: 0\n"
836 "Flags: 0\n"
837 "Release String: ''\n"
838 "Descriptors:\n"
839 " Hash descriptor:\n"
840 " Image Size: 1024 bytes\n"
841 " Hash Algorithm: sha256\n"
842 " Partition Name: foobar\n"
843 " Salt: d00df00d\n"
844 " Digest: "
845 "91386fea3e251ad0c2cb6859e4f4772f37fdb69f17d46636ddc9e7fbfd3bf3d0\n"
846 " Flags: 1\n",
847 InfoImage(path));
848 }
849
TEST_F(AvbToolTest,AddHashFooterWithPersistentDigestAndNoAB)850 TEST_F(AvbToolTest, AddHashFooterWithPersistentDigestAndNoAB) {
851 size_t partition_size = 1024 * 1024;
852 base::FilePath path = GenerateImage("digest_location", 1024);
853 EXPECT_COMMAND(0,
854 "./avbtool add_hash_footer "
855 "--hash_algorithm sha256 --image %s "
856 "--partition_size %d --partition_name foobar "
857 "--algorithm SHA256_RSA2048 "
858 "--key test/data/testkey_rsa2048.pem "
859 "--internal_release_string \"\" "
860 "--use_persistent_digest --do_not_use_ab",
861 path.value().c_str(),
862 (int)partition_size);
863 // There are three important bits specific to these flags:
864 // Minimum libavb version = 1.1
865 // Hash descriptor -> Digest = (empty)
866 // Hash descriptor -> Flags = 1
867 ASSERT_EQ(
868 "Footer version: 1.0\n"
869 "Image size: 1048576 bytes\n"
870 "Original image size: 1024 bytes\n"
871 "VBMeta offset: 4096\n"
872 "VBMeta size: 1280 bytes\n"
873 "--\n"
874 "Minimum libavb version: 1.1\n"
875 "Header Block: 256 bytes\n"
876 "Authentication Block: 320 bytes\n"
877 "Auxiliary Block: 704 bytes\n"
878 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
879 "Algorithm: SHA256_RSA2048\n"
880 "Rollback Index: 0\n"
881 "Flags: 0\n"
882 "Release String: ''\n"
883 "Descriptors:\n"
884 " Hash descriptor:\n"
885 " Image Size: 1024 bytes\n"
886 " Hash Algorithm: sha256\n"
887 " Partition Name: foobar\n"
888 " Salt: \n"
889 " Digest: \n"
890 " Flags: 1\n",
891 InfoImage(path));
892 }
893
AddHashtreeFooterTest(bool sparse_image)894 void AvbToolTest::AddHashtreeFooterTest(bool sparse_image) {
895 const size_t rootfs_size = 1028 * 1024;
896 const size_t partition_size = 1536 * 1024;
897
898 // Generate a 1028 KiB file with known content.
899 std::vector<uint8_t> rootfs;
900 rootfs.resize(rootfs_size);
901 for (size_t n = 0; n < rootfs_size; n++)
902 rootfs[n] = uint8_t(n);
903 base::FilePath external_vbmeta_path = testdir_.Append("external_vbmeta.bin");
904 base::FilePath extracted_vbmeta_path =
905 testdir_.Append("extracted_vbmeta.bin");
906 base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
907 EXPECT_EQ(rootfs_size,
908 static_cast<const size_t>(
909 base::WriteFile(rootfs_path,
910 reinterpret_cast<const char*>(rootfs.data()),
911 rootfs.size())));
912
913 if (sparse_image) {
914 EXPECT_COMMAND(0,
915 "mv %s %s.unsparse",
916 rootfs_path.value().c_str(),
917 rootfs_path.value().c_str());
918 EXPECT_COMMAND(0,
919 "img2simg %s.unsparse %s",
920 rootfs_path.value().c_str(),
921 rootfs_path.value().c_str());
922 EXPECT_COMMAND(0, "rm -f %s.unsparse", rootfs_path.value().c_str());
923 }
924
925 /* Do this twice to check that 'add_hashtree_footer' is idempotent. */
926 for (int n = 0; n < 2; n++) {
927 EXPECT_COMMAND(0,
928 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
929 "--partition_size %d --partition_name foobar "
930 "--algorithm SHA256_RSA2048 "
931 "--key test/data/testkey_rsa2048.pem "
932 "--output_vbmeta_image %s "
933 "--internal_release_string \"\" "
934 "--do_not_generate_fec",
935 rootfs_path.value().c_str(),
936 (int)partition_size,
937 external_vbmeta_path.value().c_str());
938
939 ASSERT_EQ(base::StringPrintf("Footer version: 1.0\n"
940 "Image size: 1572864 bytes\n"
941 "Original image size: 1052672 bytes\n"
942 "VBMeta offset: 1069056\n"
943 "VBMeta size: 1344 bytes\n"
944 "--\n"
945 "Minimum libavb version: 1.0%s\n"
946 "Header Block: 256 bytes\n"
947 "Authentication Block: 320 bytes\n"
948 "Auxiliary Block: 768 bytes\n"
949 "Public key (sha1): "
950 "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
951 "Algorithm: SHA256_RSA2048\n"
952 "Rollback Index: 0\n"
953 "Flags: 0\n"
954 "Release String: ''\n"
955 "Descriptors:\n"
956 " Hashtree descriptor:\n"
957 " Version of dm-verity: 1\n"
958 " Image Size: 1052672 bytes\n"
959 " Tree Offset: 1052672\n"
960 " Tree Size: 16384 bytes\n"
961 " Data Block Size: 4096 bytes\n"
962 " Hash Block Size: 4096 bytes\n"
963 " FEC num roots: 0\n"
964 " FEC offset: 0\n"
965 " FEC size: 0 bytes\n"
966 " Hash Algorithm: sha1\n"
967 " Partition Name: foobar\n"
968 " Salt: d00df00d\n"
969 " Root Digest: "
970 "e811611467dcd6e8dc4324e45f706c2bdd51db67\n"
971 " Flags: 0\n",
972 sparse_image ? " (Sparse)" : ""),
973 InfoImage(rootfs_path));
974
975 ASSERT_EQ(
976 "Minimum libavb version: 1.0\n"
977 "Header Block: 256 bytes\n"
978 "Authentication Block: 320 bytes\n"
979 "Auxiliary Block: 768 bytes\n"
980 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
981 "Algorithm: SHA256_RSA2048\n"
982 "Rollback Index: 0\n"
983 "Flags: 0\n"
984 "Release String: ''\n"
985 "Descriptors:\n"
986 " Hashtree descriptor:\n"
987 " Version of dm-verity: 1\n"
988 " Image Size: 1052672 bytes\n"
989 " Tree Offset: 1052672\n"
990 " Tree Size: 16384 bytes\n"
991 " Data Block Size: 4096 bytes\n"
992 " Hash Block Size: 4096 bytes\n"
993 " FEC num roots: 0\n"
994 " FEC offset: 0\n"
995 " FEC size: 0 bytes\n"
996 " Hash Algorithm: sha1\n"
997 " Partition Name: foobar\n"
998 " Salt: d00df00d\n"
999 " Root Digest: "
1000 "e811611467dcd6e8dc4324e45f706c2bdd51db67\n"
1001 " Flags: 0\n",
1002 InfoImage(external_vbmeta_path));
1003
1004 // Check that the extracted vbmeta matches the externally generally one.
1005 EXPECT_COMMAND(0,
1006 "./avbtool extract_vbmeta_image --image %s "
1007 "--output %s",
1008 rootfs_path.value().c_str(),
1009 extracted_vbmeta_path.value().c_str());
1010 EXPECT_COMMAND(0,
1011 "diff %s %s",
1012 external_vbmeta_path.value().c_str(),
1013 extracted_vbmeta_path.value().c_str());
1014 }
1015
1016 /* Zero the hashtree on a copy of the image. */
1017 EXPECT_COMMAND(0,
1018 "cp %s %s.zht",
1019 rootfs_path.value().c_str(),
1020 rootfs_path.value().c_str());
1021 EXPECT_COMMAND(0,
1022 "./avbtool zero_hashtree --image %s.zht ",
1023 rootfs_path.value().c_str());
1024
1025 if (sparse_image) {
1026 EXPECT_COMMAND(0,
1027 "mv %s %s.sparse",
1028 rootfs_path.value().c_str(),
1029 rootfs_path.value().c_str());
1030 EXPECT_COMMAND(0,
1031 "simg2img %s.sparse %s",
1032 rootfs_path.value().c_str(),
1033 rootfs_path.value().c_str());
1034 EXPECT_COMMAND(0, "rm -f %s.sparse", rootfs_path.value().c_str());
1035
1036 EXPECT_COMMAND(0,
1037 "mv %s.zht %s.zht.sparse",
1038 rootfs_path.value().c_str(),
1039 rootfs_path.value().c_str());
1040 EXPECT_COMMAND(0,
1041 "simg2img %s.zht.sparse %s.zht",
1042 rootfs_path.value().c_str(),
1043 rootfs_path.value().c_str());
1044 EXPECT_COMMAND(0, "rm -f %s.zht.sparse", rootfs_path.value().c_str());
1045 }
1046
1047 // To check that we generate the correct hashtree we can use
1048 // veritysetup(1) - another codebase for working with dm-verity
1049 // hashtrees - to verify it.
1050 //
1051 // If we don't want to impose the requirement of having the
1052 // veritysetup(1) command available on builders we can comment this
1053 // out.
1054 EXPECT_COMMAND(0,
1055 "veritysetup --no-superblock --format=1 --hash=sha1 "
1056 "--data-block-size=4096 --hash-block-size=4096 "
1057 "--salt=d00df00d "
1058 "--data-blocks=257 "
1059 "--hash-offset=1052672 "
1060 "verify "
1061 "%s %s "
1062 "e811611467dcd6e8dc4324e45f706c2bdd51db67",
1063 rootfs_path.value().c_str(),
1064 rootfs_path.value().c_str());
1065
1066 // Now check that we can find the VBMeta block again from the footer.
1067 std::string part_data;
1068 ASSERT_TRUE(base::ReadFileToString(rootfs_path, &part_data));
1069
1070 // Also read the zeroed hash-tree version.
1071 std::string zht_part_data;
1072 ASSERT_TRUE(base::ReadFileToString(
1073 base::FilePath(rootfs_path.value() + ".zht"), &zht_part_data));
1074
1075 // Check footer contains correct data.
1076 AvbFooter f;
1077 EXPECT_NE(0,
1078 avb_footer_validate_and_byteswap(
1079 reinterpret_cast<const AvbFooter*>(
1080 part_data.data() + part_data.size() - AVB_FOOTER_SIZE),
1081 &f));
1082 EXPECT_EQ(
1083 std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
1084 AVB_FOOTER_MAGIC);
1085 EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
1086 EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
1087 EXPECT_EQ(1052672UL, f.original_image_size);
1088 EXPECT_EQ(1069056UL, f.vbmeta_offset);
1089 EXPECT_EQ(1344UL, f.vbmeta_size);
1090
1091 // Check that the vbmeta image at |f.vbmeta_offset| checks out.
1092 const uint8_t* vbmeta_data =
1093 reinterpret_cast<const uint8_t*>(part_data.data() + f.vbmeta_offset);
1094 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
1095 avb_vbmeta_image_verify(vbmeta_data, f.vbmeta_size, NULL, NULL));
1096
1097 // Collect all descriptors.
1098 std::vector<const AvbDescriptor*> descriptors;
1099 avb_descriptor_foreach(
1100 vbmeta_data, f.vbmeta_size, collect_descriptors, &descriptors);
1101
1102 // We should only have a single descriptor and it should be a
1103 // hashtree descriptor.
1104 EXPECT_EQ(1UL, descriptors.size());
1105 EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASHTREE, avb_be64toh(descriptors[0]->tag));
1106 AvbHashtreeDescriptor d;
1107 EXPECT_NE(
1108 0,
1109 avb_hashtree_descriptor_validate_and_byteswap(
1110 reinterpret_cast<const AvbHashtreeDescriptor*>(descriptors[0]), &d));
1111 EXPECT_EQ(1UL, d.dm_verity_version);
1112 EXPECT_EQ(1052672UL, d.image_size);
1113 EXPECT_EQ(1052672UL, d.tree_offset);
1114 EXPECT_EQ(16384UL, d.tree_size);
1115 EXPECT_EQ(4096UL, d.data_block_size);
1116 EXPECT_EQ(4096UL, d.hash_block_size);
1117 EXPECT_EQ(6UL, d.partition_name_len);
1118 EXPECT_EQ(4UL, d.salt_len);
1119 EXPECT_EQ(20UL, d.root_digest_len);
1120 const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
1121 sizeof(AvbHashtreeDescriptor);
1122 uint64_t o = 0;
1123 EXPECT_EQ("foobar",
1124 std::string(reinterpret_cast<const char*>(desc_end + o),
1125 d.partition_name_len));
1126 o += d.partition_name_len;
1127 EXPECT_EQ("d00df00d", mem_to_hexstring(desc_end + o, d.salt_len));
1128 o += d.salt_len;
1129 EXPECT_EQ("e811611467dcd6e8dc4324e45f706c2bdd51db67",
1130 mem_to_hexstring(desc_end + o, d.root_digest_len));
1131
1132 // Check that the zeroed hashtree version differ only by the hashtree + fec
1133 // being zeroed out.
1134 EXPECT_EQ(part_data.size(), zht_part_data.size());
1135 size_t zht_ht_begin = d.tree_offset;
1136 size_t zht_ht_end = zht_ht_begin + d.tree_size;
1137 size_t zht_fec_begin = zht_ht_end;
1138 size_t zht_fec_end = zht_fec_begin + d.fec_size;
1139 EXPECT_EQ(0, memcmp(part_data.data(), zht_part_data.data(), zht_ht_begin));
1140 EXPECT_NE(0,
1141 memcmp(part_data.data() + zht_ht_begin,
1142 zht_part_data.data() + zht_ht_begin,
1143 zht_fec_end - zht_ht_begin));
1144 EXPECT_EQ(0,
1145 memcmp(part_data.data() + zht_fec_end,
1146 zht_part_data.data() + zht_fec_end,
1147 zht_part_data.size() - zht_fec_end));
1148 EXPECT_EQ(0, strncmp(zht_part_data.data() + zht_ht_begin, "ZeRoHaSH", 8));
1149 for (size_t n = zht_ht_begin + 8; n < zht_ht_end; n++) {
1150 EXPECT_EQ(0, zht_part_data.data()[n]);
1151 }
1152 if (d.fec_size > 0) {
1153 EXPECT_EQ(0, strncmp(zht_part_data.data() + zht_fec_begin, "ZeRoHaSH", 8));
1154 for (size_t n = zht_fec_begin + 8; n < zht_fec_end; n++) {
1155 EXPECT_EQ(0, zht_part_data.data()[n]);
1156 }
1157 }
1158
1159 // Check that we correctly generate dm-verity kernel cmdline
1160 // snippets, if requested.
1161 base::FilePath vbmeta_dmv_path = testdir_.Append("vbmeta_dm_verity_desc.bin");
1162 EXPECT_COMMAND(0,
1163 "./avbtool make_vbmeta_image "
1164 "--output %s "
1165 "--setup_rootfs_from_kernel %s "
1166 "--algorithm SHA256_RSA2048 "
1167 "--key test/data/testkey_rsa2048.pem "
1168 "--internal_release_string \"\"",
1169 vbmeta_dmv_path.value().c_str(),
1170 rootfs_path.value().c_str());
1171
1172 ASSERT_EQ(
1173 "Minimum libavb version: 1.0\n"
1174 "Header Block: 256 bytes\n"
1175 "Authentication Block: 320 bytes\n"
1176 "Auxiliary Block: 896 bytes\n"
1177 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1178 "Algorithm: SHA256_RSA2048\n"
1179 "Rollback Index: 0\n"
1180 "Flags: 0\n"
1181 "Release String: ''\n"
1182 "Descriptors:\n"
1183 " Kernel Cmdline descriptor:\n"
1184 " Flags: 1\n"
1185 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity 1 "
1186 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
1187 "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
1188 "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
1189 " Kernel Cmdline descriptor:\n"
1190 " Flags: 2\n"
1191 " Kernel Cmdline: "
1192 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n",
1193 InfoImage(vbmeta_dmv_path));
1194
1195 // Check that the footer is correctly erased and the hashtree
1196 // remains - see above for why the constant 1069056 is used.
1197 EXPECT_COMMAND(0,
1198 "./avbtool erase_footer --image %s --keep_hashtree",
1199 rootfs_path.value().c_str());
1200 int64_t erased_footer_file_size;
1201 ASSERT_TRUE(base::GetFileSize(rootfs_path, &erased_footer_file_size));
1202 EXPECT_EQ(static_cast<size_t>(erased_footer_file_size), 1069056UL);
1203
1204 // Check that --do_not_append_vbmeta_image works as intended.
1205 //
1206 // For this we need to reset the size of the image to the original
1207 // size because it's not possible to identify the existing hashtree.
1208 EXPECT_COMMAND(
1209 0, "truncate -s %d %s", (int)rootfs_size, rootfs_path.value().c_str());
1210 EXPECT_COMMAND(0,
1211 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1212 "--partition_size %d --partition_name foobar "
1213 "--algorithm SHA256_RSA2048 "
1214 "--key test/data/testkey_rsa2048.pem "
1215 "--output_vbmeta %s_2nd_run --do_not_append_vbmeta_image "
1216 "--internal_release_string \"\" "
1217 "--do_not_generate_fec",
1218 rootfs_path.value().c_str(),
1219 (int)partition_size,
1220 external_vbmeta_path.value().c_str());
1221 int64_t file_size;
1222 ASSERT_TRUE(base::GetFileSize(rootfs_path, &file_size));
1223 EXPECT_EQ(static_cast<size_t>(file_size), 1069056UL);
1224 EXPECT_COMMAND(0,
1225 "diff %s %s_2nd_run",
1226 external_vbmeta_path.value().c_str(),
1227 external_vbmeta_path.value().c_str());
1228 }
1229
TEST_F(AvbToolTest,AddHashtreeFooter)1230 TEST_F(AvbToolTest, AddHashtreeFooter) {
1231 AddHashtreeFooterTest(false);
1232 }
1233
TEST_F(AvbToolTest,AddHashtreeFooterSparse)1234 TEST_F(AvbToolTest, AddHashtreeFooterSparse) {
1235 AddHashtreeFooterTest(true);
1236 }
1237
AddHashtreeFooterFECTest(bool sparse_image)1238 void AvbToolTest::AddHashtreeFooterFECTest(bool sparse_image) {
1239 const size_t rootfs_size = 1028 * 1024;
1240 const size_t partition_size = 1536 * 1024;
1241
1242 // Generate a 1028 KiB file with known content.
1243 std::vector<uint8_t> rootfs;
1244 rootfs.resize(rootfs_size);
1245 for (size_t n = 0; n < rootfs_size; n++)
1246 rootfs[n] = uint8_t(n);
1247 base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
1248 EXPECT_EQ(rootfs_size,
1249 static_cast<const size_t>(
1250 base::WriteFile(rootfs_path,
1251 reinterpret_cast<const char*>(rootfs.data()),
1252 rootfs.size())));
1253
1254 if (sparse_image) {
1255 EXPECT_COMMAND(0,
1256 "mv %s %s.unsparse",
1257 rootfs_path.value().c_str(),
1258 rootfs_path.value().c_str());
1259 EXPECT_COMMAND(0,
1260 "img2simg %s.unsparse %s",
1261 rootfs_path.value().c_str(),
1262 rootfs_path.value().c_str());
1263 EXPECT_COMMAND(0, "rm -f %s.unsparse", rootfs_path.value().c_str());
1264 }
1265
1266 /* Do this twice to check that 'add_hashtree_footer' is idempotent. */
1267 for (int n = 0; n < 2; n++) {
1268 EXPECT_COMMAND(0,
1269 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1270 "--partition_size %d --partition_name foobar "
1271 "--algorithm SHA256_RSA2048 "
1272 "--key test/data/testkey_rsa2048.pem "
1273 "--internal_release_string \"\"",
1274 rootfs_path.value().c_str(),
1275 (int)partition_size);
1276
1277 ASSERT_EQ(base::StringPrintf("Footer version: 1.0\n"
1278 "Image size: 1572864 bytes\n"
1279 "Original image size: 1052672 bytes\n"
1280 "VBMeta offset: 1085440\n"
1281 "VBMeta size: 1344 bytes\n"
1282 "--\n"
1283 "Minimum libavb version: 1.0%s\n"
1284 "Header Block: 256 bytes\n"
1285 "Authentication Block: 320 bytes\n"
1286 "Auxiliary Block: 768 bytes\n"
1287 "Public key (sha1): "
1288 "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1289 "Algorithm: SHA256_RSA2048\n"
1290 "Rollback Index: 0\n"
1291 "Flags: 0\n"
1292 "Release String: ''\n"
1293 "Descriptors:\n"
1294 " Hashtree descriptor:\n"
1295 " Version of dm-verity: 1\n"
1296 " Image Size: 1052672 bytes\n"
1297 " Tree Offset: 1052672\n"
1298 " Tree Size: 16384 bytes\n"
1299 " Data Block Size: 4096 bytes\n"
1300 " Hash Block Size: 4096 bytes\n"
1301 " FEC num roots: 2\n"
1302 " FEC offset: 1069056\n"
1303 " FEC size: 16384 bytes\n"
1304 " Hash Algorithm: sha1\n"
1305 " Partition Name: foobar\n"
1306 " Salt: d00df00d\n"
1307 " Root Digest: "
1308 "e811611467dcd6e8dc4324e45f706c2bdd51db67\n"
1309 " Flags: 0\n",
1310 sparse_image ? " (Sparse)" : ""),
1311 InfoImage(rootfs_path));
1312 }
1313
1314 /* Zero the hashtree and FEC on a copy of the image. */
1315 EXPECT_COMMAND(0,
1316 "cp %s %s.zht",
1317 rootfs_path.value().c_str(),
1318 rootfs_path.value().c_str());
1319 EXPECT_COMMAND(0,
1320 "./avbtool zero_hashtree --image %s.zht ",
1321 rootfs_path.value().c_str());
1322
1323 if (sparse_image) {
1324 EXPECT_COMMAND(0,
1325 "mv %s %s.sparse",
1326 rootfs_path.value().c_str(),
1327 rootfs_path.value().c_str());
1328 EXPECT_COMMAND(0,
1329 "simg2img %s.sparse %s",
1330 rootfs_path.value().c_str(),
1331 rootfs_path.value().c_str());
1332 EXPECT_COMMAND(0, "rm -f %s.sparse", rootfs_path.value().c_str());
1333
1334 EXPECT_COMMAND(0,
1335 "mv %s.zht %s.zht.sparse",
1336 rootfs_path.value().c_str(),
1337 rootfs_path.value().c_str());
1338 EXPECT_COMMAND(0,
1339 "simg2img %s.zht.sparse %s.zht",
1340 rootfs_path.value().c_str(),
1341 rootfs_path.value().c_str());
1342 EXPECT_COMMAND(0, "rm -f %s.zht.sparse", rootfs_path.value().c_str());
1343 }
1344
1345 /* TODO: would be nice to verify that the FEC data is correct. */
1346
1347 // Now check that we can find the VBMeta block again from the footer.
1348 std::string part_data;
1349 ASSERT_TRUE(base::ReadFileToString(rootfs_path, &part_data));
1350
1351 // Also read the zeroed hash-tree version.
1352 std::string zht_part_data;
1353 ASSERT_TRUE(base::ReadFileToString(
1354 base::FilePath(rootfs_path.value() + ".zht"), &zht_part_data));
1355
1356 // Check footer contains correct data.
1357 AvbFooter f;
1358 EXPECT_NE(0,
1359 avb_footer_validate_and_byteswap(
1360 reinterpret_cast<const AvbFooter*>(
1361 part_data.data() + part_data.size() - AVB_FOOTER_SIZE),
1362 &f));
1363 EXPECT_EQ(
1364 std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
1365 AVB_FOOTER_MAGIC);
1366 EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
1367 EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
1368 EXPECT_EQ(1052672UL, f.original_image_size);
1369 EXPECT_EQ(1085440UL, f.vbmeta_offset);
1370 EXPECT_EQ(1344UL, f.vbmeta_size);
1371
1372 // Check that the vbmeta image at |f.vbmeta_offset| checks out.
1373 const uint8_t* vbmeta_data =
1374 reinterpret_cast<const uint8_t*>(part_data.data() + f.vbmeta_offset);
1375 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
1376 avb_vbmeta_image_verify(vbmeta_data, f.vbmeta_size, NULL, NULL));
1377
1378 // Collect all descriptors.
1379 std::vector<const AvbDescriptor*> descriptors;
1380 avb_descriptor_foreach(
1381 vbmeta_data, f.vbmeta_size, collect_descriptors, &descriptors);
1382
1383 // We should only have a single descriptor and it should be a
1384 // hashtree descriptor.
1385 EXPECT_EQ(1UL, descriptors.size());
1386 EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASHTREE, avb_be64toh(descriptors[0]->tag));
1387 AvbHashtreeDescriptor d;
1388 EXPECT_NE(
1389 0,
1390 avb_hashtree_descriptor_validate_and_byteswap(
1391 reinterpret_cast<const AvbHashtreeDescriptor*>(descriptors[0]), &d));
1392 EXPECT_EQ(1UL, d.dm_verity_version);
1393 EXPECT_EQ(1052672UL, d.image_size);
1394 EXPECT_EQ(1052672UL, d.tree_offset);
1395 EXPECT_EQ(16384UL, d.tree_size);
1396 EXPECT_EQ(4096UL, d.data_block_size);
1397 EXPECT_EQ(2UL, d.fec_num_roots);
1398 EXPECT_EQ(1069056UL, d.fec_offset);
1399 EXPECT_EQ(16384UL, d.fec_size);
1400 EXPECT_EQ(6UL, d.partition_name_len);
1401 EXPECT_EQ(4UL, d.salt_len);
1402 EXPECT_EQ(20UL, d.root_digest_len);
1403 const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
1404 sizeof(AvbHashtreeDescriptor);
1405 uint64_t o = 0;
1406 EXPECT_EQ("foobar",
1407 std::string(reinterpret_cast<const char*>(desc_end + o),
1408 d.partition_name_len));
1409 o += d.partition_name_len;
1410 EXPECT_EQ("d00df00d", mem_to_hexstring(desc_end + o, d.salt_len));
1411 o += d.salt_len;
1412 EXPECT_EQ("e811611467dcd6e8dc4324e45f706c2bdd51db67",
1413 mem_to_hexstring(desc_end + o, d.root_digest_len));
1414
1415 // Check that the zeroed hashtree version differ only by the hashtree + fec
1416 // being zeroed out.
1417 EXPECT_EQ(part_data.size(), zht_part_data.size());
1418 size_t zht_ht_begin = d.tree_offset;
1419 size_t zht_ht_end = zht_ht_begin + d.tree_size;
1420 size_t zht_fec_begin = zht_ht_end;
1421 size_t zht_fec_end = zht_fec_begin + d.fec_size;
1422 EXPECT_EQ(0, memcmp(part_data.data(), zht_part_data.data(), zht_ht_begin));
1423 EXPECT_NE(0,
1424 memcmp(part_data.data() + zht_ht_begin,
1425 zht_part_data.data() + zht_ht_begin,
1426 zht_fec_end - zht_ht_begin));
1427 EXPECT_EQ(0,
1428 memcmp(part_data.data() + zht_fec_end,
1429 zht_part_data.data() + zht_fec_end,
1430 zht_part_data.size() - zht_fec_end));
1431 EXPECT_EQ(0, strncmp(zht_part_data.data() + zht_ht_begin, "ZeRoHaSH", 8));
1432 for (size_t n = zht_ht_begin + 8; n < zht_ht_end; n++) {
1433 EXPECT_EQ(0, zht_part_data.data()[n]);
1434 }
1435 if (d.fec_size > 0) {
1436 EXPECT_EQ(0, strncmp(zht_part_data.data() + zht_fec_begin, "ZeRoHaSH", 8));
1437 for (size_t n = zht_fec_begin + 8; n < zht_fec_end; n++) {
1438 EXPECT_EQ(0, zht_part_data.data()[n]);
1439 }
1440 }
1441
1442 // Check that we correctly generate dm-verity kernel cmdline
1443 // snippets, if requested.
1444 base::FilePath vbmeta_dmv_path = testdir_.Append("vbmeta_dm_verity_desc.bin");
1445 EXPECT_COMMAND(0,
1446 "./avbtool make_vbmeta_image "
1447 "--output %s "
1448 "--setup_rootfs_from_kernel %s "
1449 "--algorithm SHA256_RSA2048 "
1450 "--key test/data/testkey_rsa2048.pem "
1451 "--internal_release_string \"\"",
1452 vbmeta_dmv_path.value().c_str(),
1453 rootfs_path.value().c_str());
1454
1455 ASSERT_EQ(
1456 "Minimum libavb version: 1.0\n"
1457 "Header Block: 256 bytes\n"
1458 "Authentication Block: 320 bytes\n"
1459 "Auxiliary Block: 960 bytes\n"
1460 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1461 "Algorithm: SHA256_RSA2048\n"
1462 "Rollback Index: 0\n"
1463 "Flags: 0\n"
1464 "Release String: ''\n"
1465 "Descriptors:\n"
1466 " Kernel Cmdline descriptor:\n"
1467 " Flags: 1\n"
1468 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity 1 "
1469 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
1470 "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
1471 "d00df00d 10 $(ANDROID_VERITY_MODE) ignore_zero_blocks "
1472 "use_fec_from_device "
1473 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) fec_roots 2 fec_blocks 261 "
1474 "fec_start 261\" root=/dev/dm-0'\n"
1475 " Kernel Cmdline descriptor:\n"
1476 " Flags: 2\n"
1477 " Kernel Cmdline: "
1478 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n",
1479 InfoImage(vbmeta_dmv_path));
1480
1481 // Check that the footer is correctly erased and the hashtree and
1482 // FEC data remains. The constant 1085440 is used because it's where
1483 // the FEC data ends (it's at offset 1069056 and size 16384).
1484 EXPECT_COMMAND(0,
1485 "./avbtool erase_footer --image %s --keep_hashtree",
1486 rootfs_path.value().c_str());
1487 int64_t erased_footer_file_size;
1488 ASSERT_TRUE(base::GetFileSize(rootfs_path, &erased_footer_file_size));
1489 EXPECT_EQ(static_cast<size_t>(erased_footer_file_size), 1085440UL);
1490 }
1491
TEST_F(AvbToolTest,AddHashtreeFooterFEC)1492 TEST_F(AvbToolTest, AddHashtreeFooterFEC) {
1493 AddHashtreeFooterFECTest(false);
1494 }
1495
TEST_F(AvbToolTest,AddHashtreeFooterFECSparse)1496 TEST_F(AvbToolTest, AddHashtreeFooterFECSparse) {
1497 AddHashtreeFooterFECTest(true);
1498 }
1499
TEST_F(AvbToolTest,AddHashtreeFooterCalcMaxImageSize)1500 TEST_F(AvbToolTest, AddHashtreeFooterCalcMaxImageSize) {
1501 const size_t partition_size = 10 * 1024 * 1024;
1502 base::FilePath output_path = testdir_.Append("max_size.txt");
1503
1504 EXPECT_COMMAND(0,
1505 "./avbtool add_hashtree_footer "
1506 "--partition_size %zd --calc_max_image_size "
1507 "--do_not_generate_fec > %s",
1508 partition_size,
1509 output_path.value().c_str());
1510 std::string max_image_size_data;
1511 EXPECT_TRUE(base::ReadFileToString(output_path, &max_image_size_data));
1512 EXPECT_EQ("10330112\n", max_image_size_data);
1513 size_t max_image_size = atoll(max_image_size_data.c_str());
1514
1515 // Hashtree and metadata takes up 152 KiB - compare to below with
1516 // FEC which is 244 KiB.
1517 EXPECT_EQ(152 * 1024ULL, partition_size - max_image_size);
1518
1519 // Check that we can add a hashtree with an image this size for such
1520 // a partition size.
1521 base::FilePath system_path = GenerateImage("system", max_image_size);
1522 EXPECT_COMMAND(0,
1523 "./avbtool add_hashtree_footer"
1524 " --image %s"
1525 " --partition_name system"
1526 " --partition_size %zd"
1527 " --salt deadbeef"
1528 " --algorithm SHA512_RSA4096 "
1529 " --key test/data/testkey_rsa4096.pem"
1530 " --internal_release_string \"\" "
1531 "--do_not_generate_fec",
1532 system_path.value().c_str(),
1533 partition_size);
1534 }
1535
TEST_F(AvbToolTest,AddHashtreeFooterCalcMaxImageSizeWithFEC)1536 TEST_F(AvbToolTest, AddHashtreeFooterCalcMaxImageSizeWithFEC) {
1537 const size_t partition_size = 10 * 1024 * 1024;
1538 base::FilePath output_path = testdir_.Append("max_size.txt");
1539
1540 EXPECT_COMMAND(0,
1541 "./avbtool add_hashtree_footer "
1542 "--partition_size %zd --calc_max_image_size > %s",
1543 partition_size,
1544 output_path.value().c_str());
1545 std::string max_image_size_data;
1546 EXPECT_TRUE(base::ReadFileToString(output_path, &max_image_size_data));
1547 EXPECT_EQ("10235904\n", max_image_size_data);
1548 size_t max_image_size = atoll(max_image_size_data.c_str());
1549
1550 // Hashtree, FEC codes, and metadata takes up 244 KiB - compare to
1551 // above wihtout FEC which is 152 KiB.
1552 EXPECT_EQ(244 * 1024ULL, partition_size - max_image_size);
1553
1554 // Check that we can add a hashtree with an image this size for such
1555 // a partition size.
1556 base::FilePath system_path = GenerateImage("system", max_image_size);
1557 EXPECT_COMMAND(0,
1558 "./avbtool add_hashtree_footer"
1559 " --image %s"
1560 " --partition_name system"
1561 " --partition_size %zd"
1562 " --salt deadbeef"
1563 " --algorithm SHA512_RSA4096 "
1564 " --key test/data/testkey_rsa4096.pem"
1565 " --internal_release_string \"\"",
1566 system_path.value().c_str(),
1567 partition_size);
1568 }
1569
TEST_F(AvbToolTest,AddHashtreeFooterCalcMaxImageSizeWithNoHashtree)1570 TEST_F(AvbToolTest, AddHashtreeFooterCalcMaxImageSizeWithNoHashtree) {
1571 const size_t partition_size = 10 * 1024 * 1024;
1572 base::FilePath output_path = testdir_.Append("max_size.txt");
1573
1574 EXPECT_COMMAND(0,
1575 "./avbtool add_hashtree_footer "
1576 "--no_hashtree "
1577 "--partition_size %zd --calc_max_image_size > %s",
1578 partition_size,
1579 output_path.value().c_str());
1580 std::string max_image_size_data;
1581 EXPECT_TRUE(base::ReadFileToString(output_path, &max_image_size_data));
1582 EXPECT_EQ("10416128\n", max_image_size_data);
1583 size_t max_image_size = atoll(max_image_size_data.c_str());
1584
1585 // vbmeta(64) + footer(4) takes up 68 KiB
1586 EXPECT_EQ(68 * 1024ULL, partition_size - max_image_size);
1587
1588 // Check that we can add a hashtree with an image this size for such
1589 // a partition size.
1590 base::FilePath system_path = GenerateImage("system", max_image_size);
1591 EXPECT_COMMAND(0,
1592 "./avbtool add_hashtree_footer"
1593 " --image %s"
1594 " --no_hashtree"
1595 " --partition_name system"
1596 " --partition_size %zd"
1597 " --salt deadbeef"
1598 " --algorithm SHA512_RSA4096 "
1599 " --key test/data/testkey_rsa4096.pem"
1600 " --internal_release_string \"\"",
1601 system_path.value().c_str(),
1602 partition_size);
1603 // with --no_hashtree, Tree/FEC sizes are 0 bytes
1604 ASSERT_EQ(
1605 "Footer version: 1.0\n"
1606 "Image size: 10485760 bytes\n"
1607 "Original image size: 10416128 bytes\n"
1608 "VBMeta offset: 10416128\n"
1609 "VBMeta size: 2112 bytes\n"
1610 "--\n"
1611 "Minimum libavb version: 1.0\n"
1612 "Header Block: 256 bytes\n"
1613 "Authentication Block: 576 bytes\n"
1614 "Auxiliary Block: 1280 bytes\n"
1615 "Public key (sha1): 2597c218aae470a130f61162feaae70afd97f011\n"
1616 "Algorithm: SHA512_RSA4096\n"
1617 "Rollback Index: 0\n"
1618 "Flags: 0\n"
1619 "Release String: ''\n"
1620 "Descriptors:\n"
1621 " Hashtree descriptor:\n"
1622 " Version of dm-verity: 1\n"
1623 " Image Size: 10416128 bytes\n"
1624 " Tree Offset: 10416128\n"
1625 " Tree Size: 0 bytes\n"
1626 " Data Block Size: 4096 bytes\n"
1627 " Hash Block Size: 4096 bytes\n"
1628 " FEC num roots: 2\n"
1629 " FEC offset: 10416128\n"
1630 " FEC size: 0 bytes\n"
1631 " Hash Algorithm: sha1\n"
1632 " Partition Name: system\n"
1633 " Salt: deadbeef\n"
1634 " Root Digest: 4215bd42bcc99636f42956ce3d2c7884d6a8093b\n"
1635 " Flags: 0\n",
1636 InfoImage(system_path));
1637 }
1638
TEST_F(AvbToolTest,AddHashtreeFooterWithPersistentDigest)1639 TEST_F(AvbToolTest, AddHashtreeFooterWithPersistentDigest) {
1640 size_t partition_size = 10 * 1024 * 1024;
1641 base::FilePath path = GenerateImage("digest_location", partition_size / 2);
1642 EXPECT_COMMAND(0,
1643 "./avbtool add_hashtree_footer "
1644 "--hash_algorithm sha256 --image %s "
1645 "--partition_size %d --partition_name foobar "
1646 "--algorithm SHA256_RSA2048 "
1647 "--key test/data/testkey_rsa2048.pem "
1648 "--internal_release_string \"\" "
1649 "--use_persistent_digest",
1650 path.value().c_str(),
1651 (int)partition_size);
1652 // There are two important bits here specific to --use_persistent_digest:
1653 // Minimum libavb version = 1.1
1654 // Hashtree descriptor -> Root Digest = (empty)
1655 ASSERT_EQ(
1656 "Footer version: 1.0\n"
1657 "Image size: 10485760 bytes\n"
1658 "Original image size: 5242880 bytes\n"
1659 "VBMeta offset: 5337088\n"
1660 "VBMeta size: 1344 bytes\n"
1661 "--\n"
1662 "Minimum libavb version: 1.1\n"
1663 "Header Block: 256 bytes\n"
1664 "Authentication Block: 320 bytes\n"
1665 "Auxiliary Block: 768 bytes\n"
1666 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1667 "Algorithm: SHA256_RSA2048\n"
1668 "Rollback Index: 0\n"
1669 "Flags: 0\n"
1670 "Release String: ''\n"
1671 "Descriptors:\n"
1672 " Hashtree descriptor:\n"
1673 " Version of dm-verity: 1\n"
1674 " Image Size: 5242880 bytes\n"
1675 " Tree Offset: 5242880\n"
1676 " Tree Size: 45056 bytes\n"
1677 " Data Block Size: 4096 bytes\n"
1678 " Hash Block Size: 4096 bytes\n"
1679 " FEC num roots: 2\n"
1680 " FEC offset: 5287936\n"
1681 " FEC size: 49152 bytes\n"
1682 " Hash Algorithm: sha256\n"
1683 " Partition Name: foobar\n"
1684 " Salt: \n"
1685 " Root Digest: \n"
1686 " Flags: 0\n",
1687 InfoImage(path));
1688 }
1689
TEST_F(AvbToolTest,AddHashtreeFooterWithNoAB)1690 TEST_F(AvbToolTest, AddHashtreeFooterWithNoAB) {
1691 size_t partition_size = 10 * 1024 * 1024;
1692 base::FilePath path = GenerateImage("digest_location", partition_size / 2);
1693 EXPECT_COMMAND(0,
1694 "./avbtool add_hashtree_footer --salt d00df00d "
1695 "--hash_algorithm sha256 --image %s "
1696 "--partition_size %d --partition_name foobar "
1697 "--algorithm SHA256_RSA2048 "
1698 "--key test/data/testkey_rsa2048.pem "
1699 "--internal_release_string \"\" "
1700 "--do_not_use_ab",
1701 path.value().c_str(),
1702 (int)partition_size);
1703 // There are two important bits here we're expecting with --do_not_use_ab:
1704 // Minimum libavb version = 1.1
1705 // Hashtree descriptor -> Flags = 1
1706 ASSERT_EQ(
1707 "Footer version: 1.0\n"
1708 "Image size: 10485760 bytes\n"
1709 "Original image size: 5242880 bytes\n"
1710 "VBMeta offset: 5337088\n"
1711 "VBMeta size: 1344 bytes\n"
1712 "--\n"
1713 "Minimum libavb version: 1.1\n"
1714 "Header Block: 256 bytes\n"
1715 "Authentication Block: 320 bytes\n"
1716 "Auxiliary Block: 768 bytes\n"
1717 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1718 "Algorithm: SHA256_RSA2048\n"
1719 "Rollback Index: 0\n"
1720 "Flags: 0\n"
1721 "Release String: ''\n"
1722 "Descriptors:\n"
1723 " Hashtree descriptor:\n"
1724 " Version of dm-verity: 1\n"
1725 " Image Size: 5242880 bytes\n"
1726 " Tree Offset: 5242880\n"
1727 " Tree Size: 45056 bytes\n"
1728 " Data Block Size: 4096 bytes\n"
1729 " Hash Block Size: 4096 bytes\n"
1730 " FEC num roots: 2\n"
1731 " FEC offset: 5287936\n"
1732 " FEC size: 49152 bytes\n"
1733 " Hash Algorithm: sha256\n"
1734 " Partition Name: foobar\n"
1735 " Salt: d00df00d\n"
1736 " Root Digest: "
1737 "d0e31526f5a3f8e3f59acf726bd31ae7861ee78f9baa9195356bf479c6f9119d\n"
1738 " Flags: 1\n",
1739 InfoImage(path));
1740 }
1741
TEST_F(AvbToolTest,AddHashtreeFooterWithPersistentDigestAndNoAB)1742 TEST_F(AvbToolTest, AddHashtreeFooterWithPersistentDigestAndNoAB) {
1743 size_t partition_size = 10 * 1024 * 1024;
1744 base::FilePath path = GenerateImage("digest_location", partition_size / 2);
1745 EXPECT_COMMAND(0,
1746 "./avbtool add_hashtree_footer "
1747 "--hash_algorithm sha256 --image %s "
1748 "--partition_size %d --partition_name foobar "
1749 "--algorithm SHA256_RSA2048 "
1750 "--key test/data/testkey_rsa2048.pem "
1751 "--internal_release_string \"\" "
1752 "--use_persistent_digest --do_not_use_ab",
1753 path.value().c_str(),
1754 (int)partition_size);
1755 // There are three important bits specific to these flags:
1756 // Minimum libavb version = 1.1
1757 // Hashtree descriptor -> Root Digest = (empty)
1758 // Hashtree descriptor -> Flags = 1
1759 ASSERT_EQ(
1760 "Footer version: 1.0\n"
1761 "Image size: 10485760 bytes\n"
1762 "Original image size: 5242880 bytes\n"
1763 "VBMeta offset: 5337088\n"
1764 "VBMeta size: 1344 bytes\n"
1765 "--\n"
1766 "Minimum libavb version: 1.1\n"
1767 "Header Block: 256 bytes\n"
1768 "Authentication Block: 320 bytes\n"
1769 "Auxiliary Block: 768 bytes\n"
1770 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1771 "Algorithm: SHA256_RSA2048\n"
1772 "Rollback Index: 0\n"
1773 "Flags: 0\n"
1774 "Release String: ''\n"
1775 "Descriptors:\n"
1776 " Hashtree descriptor:\n"
1777 " Version of dm-verity: 1\n"
1778 " Image Size: 5242880 bytes\n"
1779 " Tree Offset: 5242880\n"
1780 " Tree Size: 45056 bytes\n"
1781 " Data Block Size: 4096 bytes\n"
1782 " Hash Block Size: 4096 bytes\n"
1783 " FEC num roots: 2\n"
1784 " FEC offset: 5287936\n"
1785 " FEC size: 49152 bytes\n"
1786 " Hash Algorithm: sha256\n"
1787 " Partition Name: foobar\n"
1788 " Salt: \n"
1789 " Root Digest: \n"
1790 " Flags: 1\n",
1791 InfoImage(path));
1792 }
1793
TEST_F(AvbToolTest,AddHashtreeFooterNoSizeOrName)1794 TEST_F(AvbToolTest, AddHashtreeFooterNoSizeOrName) {
1795 // Size must be a multiple of block size (4096 bytes)
1796 size_t file_size = 72 * 1024;
1797 base::FilePath path = GenerateImage("data.bin", file_size);
1798
1799 // Note how there is no --partition_size or --partition_name here.
1800 EXPECT_COMMAND(0,
1801 "./avbtool add_hashtree_footer --salt d00df00d "
1802 "--image %s "
1803 "--algorithm SHA256_RSA2048 "
1804 "--key test/data/testkey_rsa2048.pem "
1805 "--internal_release_string \"\" ",
1806 path.value().c_str());
1807
1808 ASSERT_EQ(
1809 "Footer version: 1.0\n"
1810 "Image size: 94208 bytes\n"
1811 "Original image size: 73728 bytes\n"
1812 "VBMeta offset: 86016\n"
1813 "VBMeta size: 1344 bytes\n"
1814 "--\n"
1815 "Minimum libavb version: 1.0\n"
1816 "Header Block: 256 bytes\n"
1817 "Authentication Block: 320 bytes\n"
1818 "Auxiliary Block: 768 bytes\n"
1819 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1820 "Algorithm: SHA256_RSA2048\n"
1821 "Rollback Index: 0\n"
1822 "Flags: 0\n"
1823 "Release String: ''\n"
1824 "Descriptors:\n"
1825 " Hashtree descriptor:\n"
1826 " Version of dm-verity: 1\n"
1827 " Image Size: 73728 bytes\n"
1828 " Tree Offset: 73728\n"
1829 " Tree Size: 4096 bytes\n"
1830 " Data Block Size: 4096 bytes\n"
1831 " Hash Block Size: 4096 bytes\n"
1832 " FEC num roots: 2\n"
1833 " FEC offset: 77824\n"
1834 " FEC size: 8192 bytes\n"
1835 " Hash Algorithm: sha1\n"
1836 " Partition Name: \n"
1837 " Salt: d00df00d\n"
1838 " Root Digest: 2f73fb340e982794643e1121d82d5195677c2b31\n"
1839 " Flags: 0\n",
1840 InfoImage(path));
1841
1842 // Check that at least avbtool can verify the image and hashtree.
1843 EXPECT_COMMAND(0,
1844 "./avbtool verify_image "
1845 "--image %s ",
1846 path.value().c_str());
1847 }
1848
TEST_F(AvbToolTest,AddHashtreeFooterNoSizeWrongSize)1849 TEST_F(AvbToolTest, AddHashtreeFooterNoSizeWrongSize) {
1850 // Size must be a multiple of block size (4096 bytes) and this one isn't...
1851 size_t file_size = 70 * 1024;
1852 base::FilePath path = GenerateImage("data.bin", file_size);
1853
1854 // ... so we expect this command to fail.
1855 EXPECT_COMMAND(1,
1856 "./avbtool add_hashtree_footer --salt d00df00d "
1857 "--image %s "
1858 "--algorithm SHA256_RSA2048 "
1859 "--key test/data/testkey_rsa2048.pem "
1860 "--internal_release_string \"\" ",
1861 path.value().c_str());
1862 }
1863
TEST_F(AvbToolTest,KernelCmdlineDescriptor)1864 TEST_F(AvbToolTest, KernelCmdlineDescriptor) {
1865 base::FilePath vbmeta_path =
1866 testdir_.Append("vbmeta_kernel_cmdline_desc.bin");
1867
1868 EXPECT_COMMAND(0,
1869 "./avbtool make_vbmeta_image "
1870 "--output %s "
1871 "--kernel_cmdline 'foo bar baz' "
1872 "--kernel_cmdline 'second cmdline' "
1873 "--algorithm SHA256_RSA2048 "
1874 "--key test/data/testkey_rsa2048.pem "
1875 "--internal_release_string \"\"",
1876 vbmeta_path.value().c_str());
1877
1878 ASSERT_EQ(
1879 "Minimum libavb version: 1.0\n"
1880 "Header Block: 256 bytes\n"
1881 "Authentication Block: 320 bytes\n"
1882 "Auxiliary Block: 640 bytes\n"
1883 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1884 "Algorithm: SHA256_RSA2048\n"
1885 "Rollback Index: 0\n"
1886 "Flags: 0\n"
1887 "Release String: ''\n"
1888 "Descriptors:\n"
1889 " Kernel Cmdline descriptor:\n"
1890 " Flags: 0\n"
1891 " Kernel Cmdline: 'foo bar baz'\n"
1892 " Kernel Cmdline descriptor:\n"
1893 " Flags: 0\n"
1894 " Kernel Cmdline: 'second cmdline'\n",
1895 InfoImage(vbmeta_path));
1896
1897 // Now check the VBMeta image.
1898 std::string image_data;
1899 ASSERT_TRUE(base::ReadFileToString(vbmeta_path, &image_data));
1900
1901 const uint8_t* vbmeta_data =
1902 reinterpret_cast<const uint8_t*>(image_data.data());
1903 const size_t vbmeta_size = image_data.length();
1904 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
1905 avb_vbmeta_image_verify(vbmeta_data, vbmeta_size, NULL, NULL));
1906
1907 // Collect all descriptors.
1908 std::vector<const AvbDescriptor*> descriptors;
1909 avb_descriptor_foreach(
1910 vbmeta_data, vbmeta_size, collect_descriptors, &descriptors);
1911
1912 // We should have two descriptors - check them.
1913 EXPECT_EQ(2UL, descriptors.size());
1914 AvbKernelCmdlineDescriptor d;
1915 EXPECT_EQ(AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE,
1916 avb_be64toh(descriptors[0]->tag));
1917 EXPECT_NE(
1918 0,
1919 avb_kernel_cmdline_descriptor_validate_and_byteswap(
1920 reinterpret_cast<const AvbKernelCmdlineDescriptor*>(descriptors[0]),
1921 &d));
1922 EXPECT_EQ("foo bar baz",
1923 std::string(reinterpret_cast<const char*>(descriptors[0]) +
1924 sizeof(AvbKernelCmdlineDescriptor),
1925 d.kernel_cmdline_length));
1926 EXPECT_EQ(AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE,
1927 avb_be64toh(descriptors[1]->tag));
1928 EXPECT_NE(
1929 0,
1930 avb_kernel_cmdline_descriptor_validate_and_byteswap(
1931 reinterpret_cast<const AvbKernelCmdlineDescriptor*>(descriptors[1]),
1932 &d));
1933 EXPECT_EQ("second cmdline",
1934 std::string(reinterpret_cast<const char*>(descriptors[1]) +
1935 sizeof(AvbKernelCmdlineDescriptor),
1936 d.kernel_cmdline_length));
1937 }
1938
TEST_F(AvbToolTest,CalculateKernelCmdline)1939 TEST_F(AvbToolTest, CalculateKernelCmdline) {
1940 base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
1941 EXPECT_COMMAND(0,
1942 "./avbtool make_vbmeta_image "
1943 "--output %s "
1944 "--kernel_cmdline 'foo bar baz' "
1945 "--kernel_cmdline 'second cmdline' "
1946 "--algorithm SHA256_RSA2048 "
1947 "--key test/data/testkey_rsa2048.pem "
1948 "--internal_release_string \"\"",
1949 vbmeta_path.value().c_str());
1950
1951 base::FilePath out_path = testdir_.Append("out.txt");
1952 std::string out;
1953 EXPECT_COMMAND(0,
1954 "./avbtool calculate_kernel_cmdline --image %s > %s",
1955 vbmeta_path.value().c_str(),
1956 out_path.value().c_str());
1957 ASSERT_TRUE(base::ReadFileToString(out_path, &out));
1958 EXPECT_EQ(out, "foo bar baz second cmdline");
1959 }
1960
TEST_F(AvbToolTest,CalculateKernelCmdlineChainedAndWithFlags)1961 TEST_F(AvbToolTest, CalculateKernelCmdlineChainedAndWithFlags) {
1962 const size_t rootfs_size = 1028 * 1024;
1963 const size_t partition_size = 1536 * 1024;
1964
1965 base::FilePath pk_path = testdir_.Append("testkey_rsa2048.avbpubkey");
1966
1967 // Generate a 1028 KiB file with known content, add a hashtree, and cmdline
1968 // descriptors for setting up this hashtree. Notably this will create *two*
1969 // cmdline descriptors so we can test calculate_kernel_cmdline's
1970 // --hashtree_disabled option.
1971 std::vector<uint8_t> rootfs;
1972 rootfs.resize(rootfs_size);
1973 for (size_t n = 0; n < rootfs_size; n++)
1974 rootfs[n] = uint8_t(n);
1975 base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
1976 EXPECT_EQ(rootfs_size,
1977 static_cast<const size_t>(
1978 base::WriteFile(rootfs_path,
1979 reinterpret_cast<const char*>(rootfs.data()),
1980 rootfs.size())));
1981
1982 EXPECT_COMMAND(
1983 0,
1984 "./avbtool extract_public_key --key test/data/testkey_rsa2048.pem"
1985 " --output %s",
1986 pk_path.value().c_str());
1987
1988 EXPECT_COMMAND(0,
1989 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1990 "--partition_size %d --partition_name rootfs "
1991 "--algorithm SHA256_RSA2048 "
1992 "--key test/data/testkey_rsa2048.pem "
1993 "--internal_release_string \"\" "
1994 "--setup_as_rootfs_from_kernel",
1995 rootfs_path.value().c_str(),
1996 (int)partition_size);
1997 EXPECT_EQ(
1998 "Footer version: 1.0\n"
1999 "Image size: 1572864 bytes\n"
2000 "Original image size: 1052672 bytes\n"
2001 "VBMeta offset: 1085440\n"
2002 "VBMeta size: 1792 bytes\n"
2003 "--\n"
2004 "Minimum libavb version: 1.0\n"
2005 "Header Block: 256 bytes\n"
2006 "Authentication Block: 320 bytes\n"
2007 "Auxiliary Block: 1216 bytes\n"
2008 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2009 "Algorithm: SHA256_RSA2048\n"
2010 "Rollback Index: 0\n"
2011 "Flags: 0\n"
2012 "Release String: ''\n"
2013 "Descriptors:\n"
2014 " Hashtree descriptor:\n"
2015 " Version of dm-verity: 1\n"
2016 " Image Size: 1052672 bytes\n"
2017 " Tree Offset: 1052672\n"
2018 " Tree Size: 16384 bytes\n"
2019 " Data Block Size: 4096 bytes\n"
2020 " Hash Block Size: 4096 bytes\n"
2021 " FEC num roots: 2\n"
2022 " FEC offset: 1069056\n"
2023 " FEC size: 16384 bytes\n"
2024 " Hash Algorithm: sha1\n"
2025 " Partition Name: rootfs\n"
2026 " Salt: d00df00d\n"
2027 " Root Digest: e811611467dcd6e8dc4324e45f706c2bdd51db67\n"
2028 " Flags: 0\n"
2029 " Kernel Cmdline descriptor:\n"
2030 " Flags: 1\n"
2031 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity 1 "
2032 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
2033 "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
2034 "d00df00d 10 $(ANDROID_VERITY_MODE) ignore_zero_blocks "
2035 "use_fec_from_device PARTUUID=$(ANDROID_SYSTEM_PARTUUID) fec_roots 2 "
2036 "fec_blocks 261 fec_start 261\" root=/dev/dm-0'\n"
2037 " Kernel Cmdline descriptor:\n"
2038 " Flags: 2\n"
2039 " Kernel Cmdline: "
2040 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n",
2041 InfoImage(rootfs_path));
2042
2043 // Chain to the rootfs.img and include two cmdline descriptors.
2044 base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
2045 EXPECT_COMMAND(0,
2046 "./avbtool make_vbmeta_image "
2047 "--output %s "
2048 "--kernel_cmdline 'foo bar baz' "
2049 "--kernel_cmdline 'second cmdline' "
2050 "--chain_partition rootfs:1:%s "
2051 "--algorithm SHA256_RSA2048 "
2052 "--key test/data/testkey_rsa2048.pem "
2053 "--internal_release_string \"\"",
2054 vbmeta_path.value().c_str(),
2055 pk_path.value().c_str());
2056 EXPECT_EQ(
2057 "Minimum libavb version: 1.0\n"
2058 "Header Block: 256 bytes\n"
2059 "Authentication Block: 320 bytes\n"
2060 "Auxiliary Block: 1280 bytes\n"
2061 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2062 "Algorithm: SHA256_RSA2048\n"
2063 "Rollback Index: 0\n"
2064 "Flags: 0\n"
2065 "Release String: ''\n"
2066 "Descriptors:\n"
2067 " Chain Partition descriptor:\n"
2068 " Partition Name: rootfs\n"
2069 " Rollback Index Location: 1\n"
2070 " Public key (sha1): "
2071 "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2072 " Kernel Cmdline descriptor:\n"
2073 " Flags: 0\n"
2074 " Kernel Cmdline: 'foo bar baz'\n"
2075 " Kernel Cmdline descriptor:\n"
2076 " Flags: 0\n"
2077 " Kernel Cmdline: 'second cmdline'\n",
2078 InfoImage(vbmeta_path));
2079
2080 base::FilePath out_path = testdir_.Append("out.txt");
2081 std::string out;
2082
2083 // First check the kernel cmdline without --hashtree_disabled - compare with
2084 // above info_image output.
2085 EXPECT_COMMAND(0,
2086 "./avbtool calculate_kernel_cmdline --image %s > %s",
2087 vbmeta_path.value().c_str(),
2088 out_path.value().c_str());
2089 ASSERT_TRUE(base::ReadFileToString(out_path, &out));
2090 EXPECT_EQ(
2091 "dm=\"1 vroot none ro 1,0 2056 verity 1 "
2092 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
2093 "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
2094 "d00df00d 10 $(ANDROID_VERITY_MODE) ignore_zero_blocks "
2095 "use_fec_from_device PARTUUID=$(ANDROID_SYSTEM_PARTUUID) fec_roots 2 "
2096 "fec_blocks 261 fec_start 261\" root=/dev/dm-0 foo bar baz second "
2097 "cmdline",
2098 out);
2099
2100 // Then check the kernel cmdline with --hashtree_disabled - compare with above
2101 // info_image output.
2102 EXPECT_COMMAND(
2103 0,
2104 "./avbtool calculate_kernel_cmdline --image %s --hashtree_disabled > %s",
2105 vbmeta_path.value().c_str(),
2106 out_path.value().c_str());
2107 ASSERT_TRUE(base::ReadFileToString(out_path, &out));
2108 EXPECT_EQ(
2109 "root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID) foo bar baz second cmdline",
2110 out);
2111 }
2112
TEST_F(AvbToolTest,AddHashFooterSmallImageWithExternalVbmeta)2113 TEST_F(AvbToolTest, AddHashFooterSmallImageWithExternalVbmeta) {
2114 const size_t image_size = 37;
2115 const size_t partition_size = 20 * 4096;
2116
2117 std::vector<uint8_t> image(image_size, 0);
2118 for (size_t n = 0; n < image_size; n++) {
2119 image[n] = uint8_t(n);
2120 }
2121
2122 base::FilePath ext_vbmeta_path = testdir_.Append("ext_vbmeta.bin");
2123 base::FilePath image_path = testdir_.Append("kernel.bin");
2124 EXPECT_EQ(image_size,
2125 static_cast<const size_t>(
2126 base::WriteFile(image_path,
2127 reinterpret_cast<const char*>(image.data()),
2128 image.size())));
2129 EXPECT_COMMAND(0,
2130 "./avbtool add_hash_footer --salt d00df00d "
2131 "--hash_algorithm sha256 --image %s "
2132 "--partition_size %zu --partition_name kernel "
2133 "--algorithm SHA256_RSA2048 "
2134 "--key test/data/testkey_rsa2048.pem "
2135 "--output_vbmeta %s "
2136 "--do_not_append_vbmeta_image "
2137 "--internal_release_string \"\"",
2138 image_path.value().c_str(),
2139 partition_size,
2140 ext_vbmeta_path.value().c_str());
2141
2142 // It is not this unit test's job to check the vbmeta content.
2143
2144 int64_t file_size;
2145 ASSERT_TRUE(base::GetFileSize(image_path, &file_size));
2146 EXPECT_EQ(static_cast<size_t>(file_size), image_size);
2147 }
2148
TEST_F(AvbToolTest,IncludeDescriptor)2149 TEST_F(AvbToolTest, IncludeDescriptor) {
2150 base::FilePath vbmeta1_path = testdir_.Append("vbmeta_id1.bin");
2151 base::FilePath vbmeta2_path = testdir_.Append("vbmeta_id2.bin");
2152 base::FilePath vbmeta3_path = testdir_.Append("vbmeta_id3.bin");
2153
2154 EXPECT_COMMAND(0,
2155 "./avbtool make_vbmeta_image "
2156 "--output %s "
2157 "--kernel_cmdline 'something' "
2158 "--prop name:value "
2159 "--internal_release_string \"\"",
2160 vbmeta1_path.value().c_str());
2161
2162 EXPECT_COMMAND(0,
2163 "./avbtool make_vbmeta_image "
2164 "--output %s "
2165 "--prop name2:value2 "
2166 "--prop name3:value3 "
2167 "--internal_release_string \"\"",
2168 vbmeta2_path.value().c_str());
2169
2170 EXPECT_COMMAND(0,
2171 "./avbtool make_vbmeta_image "
2172 "--output %s "
2173 "--prop name4:value4 "
2174 "--include_descriptors_from_image %s "
2175 "--include_descriptors_from_image %s "
2176 "--internal_release_string \"\"",
2177 vbmeta3_path.value().c_str(),
2178 vbmeta1_path.value().c_str(),
2179 vbmeta2_path.value().c_str());
2180
2181 ASSERT_EQ(
2182 "Minimum libavb version: 1.0\n"
2183 "Header Block: 256 bytes\n"
2184 "Authentication Block: 0 bytes\n"
2185 "Auxiliary Block: 256 bytes\n"
2186 "Algorithm: NONE\n"
2187 "Rollback Index: 0\n"
2188 "Flags: 0\n"
2189 "Release String: ''\n"
2190 "Descriptors:\n"
2191 " Prop: name4 -> 'value4'\n"
2192 " Prop: name -> 'value'\n"
2193 " Kernel Cmdline descriptor:\n"
2194 " Flags: 0\n"
2195 " Kernel Cmdline: 'something'\n"
2196 " Prop: name2 -> 'value2'\n"
2197 " Prop: name3 -> 'value3'\n",
2198 InfoImage(vbmeta3_path));
2199 }
2200
TEST_F(AvbToolTest,ChainedPartition)2201 TEST_F(AvbToolTest, ChainedPartition) {
2202 base::FilePath vbmeta_path = testdir_.Append("vbmeta_cp.bin");
2203
2204 base::FilePath pk_path = testdir_.Append("testkey_rsa2048.avbpubkey");
2205
2206 EXPECT_COMMAND(
2207 0,
2208 "./avbtool extract_public_key --key test/data/testkey_rsa2048.pem"
2209 " --output %s",
2210 pk_path.value().c_str());
2211
2212 EXPECT_COMMAND(
2213 0,
2214 "./avbtool make_vbmeta_image "
2215 "--output %s "
2216 "--chain_partition system:1:%s "
2217 "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
2218 "--internal_release_string \"\"",
2219 vbmeta_path.value().c_str(),
2220 pk_path.value().c_str());
2221
2222 ASSERT_EQ(
2223 "Minimum libavb version: 1.0\n"
2224 "Header Block: 256 bytes\n"
2225 "Authentication Block: 320 bytes\n"
2226 "Auxiliary Block: 1152 bytes\n"
2227 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2228 "Algorithm: SHA256_RSA2048\n"
2229 "Rollback Index: 0\n"
2230 "Flags: 0\n"
2231 "Release String: ''\n"
2232 "Descriptors:\n"
2233 " Chain Partition descriptor:\n"
2234 " Partition Name: system\n"
2235 " Rollback Index Location: 1\n"
2236 " Public key (sha1): "
2237 "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n",
2238 InfoImage(vbmeta_path));
2239
2240 // Now check the VBMeta image.
2241 std::string image_data;
2242 ASSERT_TRUE(base::ReadFileToString(vbmeta_path, &image_data));
2243
2244 const uint8_t* vbmeta_data =
2245 reinterpret_cast<const uint8_t*>(image_data.data());
2246 const size_t vbmeta_size = image_data.length();
2247 EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
2248 avb_vbmeta_image_verify(vbmeta_data, vbmeta_size, NULL, NULL));
2249
2250 // Collect all descriptors.
2251 std::vector<const AvbDescriptor*> descriptors;
2252 avb_descriptor_foreach(
2253 vbmeta_data, vbmeta_size, collect_descriptors, &descriptors);
2254
2255 // We should have one descriptor - check it.
2256 EXPECT_EQ(1UL, descriptors.size());
2257
2258 std::string pk_data;
2259 ASSERT_TRUE(base::ReadFileToString(pk_path, &pk_data));
2260
2261 AvbChainPartitionDescriptor d;
2262 EXPECT_EQ(AVB_DESCRIPTOR_TAG_CHAIN_PARTITION,
2263 avb_be64toh(descriptors[0]->tag));
2264 EXPECT_NE(
2265 0,
2266 avb_chain_partition_descriptor_validate_and_byteswap(
2267 reinterpret_cast<const AvbChainPartitionDescriptor*>(descriptors[0]),
2268 &d));
2269 const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
2270 sizeof(AvbChainPartitionDescriptor);
2271 uint64_t o = 0;
2272 EXPECT_EQ("system",
2273 std::string(reinterpret_cast<const char*>(desc_end + o),
2274 d.partition_name_len));
2275 o += d.partition_name_len;
2276 EXPECT_EQ(pk_data,
2277 std::string(reinterpret_cast<const char*>(descriptors[0]) +
2278 sizeof(AvbChainPartitionDescriptor) + o,
2279 d.public_key_len));
2280 }
2281
TEST_F(AvbToolTest,ChainedPartitionNoLocationCollision)2282 TEST_F(AvbToolTest, ChainedPartitionNoLocationCollision) {
2283 base::FilePath vbmeta_path = testdir_.Append("vbmeta_cp.bin");
2284
2285 base::FilePath pk_path = testdir_.Append("testkey_rsa2048.avbpubkey");
2286
2287 EXPECT_COMMAND(
2288 0,
2289 "./avbtool extract_public_key --key test/data/testkey_rsa2048.pem"
2290 " --output %s",
2291 pk_path.value().c_str());
2292
2293 // Check that avbtool bails if the same Rollback Index Location is
2294 // used for multiple chained partitions.
2295 EXPECT_COMMAND(
2296 1,
2297 "./avbtool make_vbmeta_image "
2298 "--output %s "
2299 "--chain_partition system:1:%s "
2300 "--chain_partition other:1:%s "
2301 "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
2302 "--internal_release_string \"\"",
2303 vbmeta_path.value().c_str(),
2304 pk_path.value().c_str(),
2305 pk_path.value().c_str());
2306 }
2307
TEST_F(AvbToolTest,AppendVBMetaImage)2308 TEST_F(AvbToolTest, AppendVBMetaImage) {
2309 size_t boot_size = 5 * 1024 * 1024;
2310 size_t boot_partition_size = 32 * 1024 * 1024;
2311 base::FilePath boot_path = GenerateImage("boot", boot_size);
2312
2313 GenerateVBMetaImage("vbmeta.img",
2314 "SHA256_RSA2048",
2315 0,
2316 base::FilePath("test/data/testkey_rsa2048.pem"),
2317 std::string("--append_to_release_string \"\" "
2318 "--kernel_cmdline foo"));
2319
2320 EXPECT_COMMAND(0,
2321 "./avbtool append_vbmeta_image "
2322 "--image %s "
2323 "--partition_size %d "
2324 "--vbmeta_image %s ",
2325 boot_path.value().c_str(),
2326 (int)boot_partition_size,
2327 vbmeta_image_path_.value().c_str());
2328
2329 std::string vbmeta_contents = InfoImage(vbmeta_image_path_);
2330 std::string boot_contents = InfoImage(boot_path);
2331
2332 // Check that boot.img has the same vbmeta blob as from vbmeta.img -
2333 // we do this by inspecting 'avbtool info_image' output combined
2334 // with the known footer location given boot.img has 5 MiB known
2335 // content and the partition size is 32 MiB.
2336 ASSERT_EQ(
2337 "Minimum libavb version: 1.0\n"
2338 "Header Block: 256 bytes\n"
2339 "Authentication Block: 320 bytes\n"
2340 "Auxiliary Block: 576 bytes\n"
2341 "Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2342 "Algorithm: SHA256_RSA2048\n"
2343 "Rollback Index: 0\n"
2344 "Flags: 0\n"
2345 "Release String: 'avbtool 1.1.0 '\n"
2346 "Descriptors:\n"
2347 " Kernel Cmdline descriptor:\n"
2348 " Flags: 0\n"
2349 " Kernel Cmdline: 'foo'\n",
2350 vbmeta_contents);
2351 std::string known_footer =
2352 "Footer version: 1.0\n"
2353 "Image size: 33554432 bytes\n"
2354 "Original image size: 5242880 bytes\n"
2355 "VBMeta offset: 5242880\n"
2356 "VBMeta size: 1152 bytes\n"
2357 "--\n";
2358 ASSERT_EQ(known_footer + vbmeta_contents, boot_contents);
2359
2360 // Also verify that the blobs are the same, bit for bit.
2361 base::File f =
2362 base::File(boot_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
2363 std::vector<uint8_t> loaded_vbmeta;
2364 loaded_vbmeta.resize(1152);
2365 EXPECT_EQ(
2366 f.Read(
2367 5 * 1024 * 1024, reinterpret_cast<char*>(loaded_vbmeta.data()), 1152),
2368 1152);
2369 EXPECT_EQ(vbmeta_image_, loaded_vbmeta);
2370 }
2371
TEST_F(AvbToolTest,SigningHelperBasic)2372 TEST_F(AvbToolTest, SigningHelperBasic) {
2373 base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
2374 base::FilePath signing_helper_test_path =
2375 testdir_.Append("signing_helper_test");
2376 EXPECT_COMMAND(
2377 0,
2378 "SIGNING_HELPER_TEST=\"%s\" ./avbtool make_vbmeta_image "
2379 "--output %s "
2380 "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
2381 "--signing_helper test/avbtool_signing_helper_test.py "
2382 "--internal_release_string \"\"",
2383 signing_helper_test_path.value().c_str(),
2384 vbmeta_path.value().c_str());
2385
2386 // Now check the value in test file.
2387 std::string value;
2388 ASSERT_TRUE(base::ReadFileToString(signing_helper_test_path, &value));
2389 EXPECT_EQ("DONE", value);
2390 }
2391
TEST_F(AvbToolTest,SigningHelperWithFilesBasic)2392 TEST_F(AvbToolTest, SigningHelperWithFilesBasic) {
2393 base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
2394 base::FilePath signing_helper_test_path =
2395 testdir_.Append("signing_helper_test");
2396 EXPECT_COMMAND(
2397 0,
2398 "SIGNING_HELPER_TEST=\"%s\" ./avbtool make_vbmeta_image "
2399 "--output %s "
2400 "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
2401 "--signing_helper_with_files "
2402 "test/avbtool_signing_helper_with_files_test.py "
2403 "--internal_release_string \"\"",
2404 signing_helper_test_path.value().c_str(),
2405 vbmeta_path.value().c_str());
2406
2407 // Now check the value in test file.
2408 std::string value;
2409 ASSERT_TRUE(base::ReadFileToString(signing_helper_test_path, &value));
2410 EXPECT_EQ("DONE", value);
2411 }
2412
TEST_F(AvbToolTest,SigningHelperReturnError)2413 TEST_F(AvbToolTest, SigningHelperReturnError) {
2414 base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
2415 EXPECT_COMMAND(
2416 1,
2417 "./avbtool make_vbmeta_image "
2418 "--output %s "
2419 "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
2420 "--signing_helper test/avbtool_signing_helper_test.py "
2421 "--internal_release_string \"\"",
2422 vbmeta_path.value().c_str());
2423 }
2424
TEST_F(AvbToolTest,SigningHelperWithFilesReturnError)2425 TEST_F(AvbToolTest, SigningHelperWithFilesReturnError) {
2426 base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
2427 EXPECT_COMMAND(
2428 1,
2429 "./avbtool make_vbmeta_image "
2430 "--output %s "
2431 "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
2432 "--signing_helper_with_files "
2433 "test/avbtool_signing_helper_with_files_test.py "
2434 "--internal_release_string \"\"",
2435 vbmeta_path.value().c_str());
2436 }
2437
TEST_F(AvbToolTest,VerifyImageNoSignature)2438 TEST_F(AvbToolTest, VerifyImageNoSignature) {
2439 GenerateVBMetaImage("vbmeta.img",
2440 "", // NONE
2441 0,
2442 base::FilePath());
2443
2444 EXPECT_COMMAND(0,
2445 "./avbtool verify_image "
2446 "--image %s ",
2447 vbmeta_image_path_.value().c_str());
2448 }
2449
TEST_F(AvbToolTest,VerifyImageValidSignature)2450 TEST_F(AvbToolTest, VerifyImageValidSignature) {
2451 GenerateVBMetaImage("vbmeta.img",
2452 "SHA256_RSA2048",
2453 0,
2454 base::FilePath("test/data/testkey_rsa2048.pem"));
2455
2456 EXPECT_COMMAND(0,
2457 "./avbtool verify_image "
2458 "--image %s ",
2459 vbmeta_image_path_.value().c_str());
2460 }
2461
TEST_F(AvbToolTest,VerifyImageCorruptedVBMeta)2462 TEST_F(AvbToolTest, VerifyImageCorruptedVBMeta) {
2463 GenerateVBMetaImage("vbmeta.img",
2464 "SHA256_RSA2048",
2465 0,
2466 base::FilePath("test/data/testkey_rsa2048.pem"));
2467
2468 // Corrupt four bytes of data in the end of the image. Since the aux
2469 // data is at the end and this data is signed, this will change the
2470 // value of the computed hash.
2471 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
2472 EXPECT_EQ(AVB_IO_RESULT_OK,
2473 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
2474 "vbmeta",
2475 -4, // offset from end
2476 sizeof corrupt_data,
2477 corrupt_data));
2478
2479 EXPECT_COMMAND(1,
2480 "./avbtool verify_image "
2481 "--image %s ",
2482 vbmeta_image_path_.value().c_str());
2483 }
2484
TEST_F(AvbToolTest,VerifyImageOtherKeyMatching)2485 TEST_F(AvbToolTest, VerifyImageOtherKeyMatching) {
2486 GenerateVBMetaImage("vbmeta.img",
2487 "SHA256_RSA2048",
2488 0,
2489 base::FilePath("test/data/testkey_rsa2048.pem"));
2490
2491 EXPECT_COMMAND(0,
2492 "./avbtool verify_image "
2493 "--image %s --key test/data/testkey_rsa2048.pem",
2494 vbmeta_image_path_.value().c_str());
2495 }
2496
TEST_F(AvbToolTest,VerifyImageOtherKeyNotMatching)2497 TEST_F(AvbToolTest, VerifyImageOtherKeyNotMatching) {
2498 GenerateVBMetaImage("vbmeta.img",
2499 "SHA256_RSA2048",
2500 0,
2501 base::FilePath("test/data/testkey_rsa2048.pem"));
2502
2503 EXPECT_COMMAND(1,
2504 "./avbtool verify_image "
2505 "--image %s --key test/data/testkey_rsa4096.pem",
2506 vbmeta_image_path_.value().c_str());
2507 }
2508
TEST_F(AvbToolTest,VerifyImageBrokenSignature)2509 TEST_F(AvbToolTest, VerifyImageBrokenSignature) {
2510 base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
2511 base::FilePath signing_helper_test_path =
2512 testdir_.Append("signing_helper_test");
2513
2514 // Intentionally make the signer generate a wrong signature.
2515 EXPECT_COMMAND(
2516 0,
2517 "SIGNING_HELPER_GENERATE_WRONG_SIGNATURE=1 ./avbtool make_vbmeta_image "
2518 "--output %s "
2519 "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
2520 "--signing_helper test/avbtool_signing_helper_test.py "
2521 "--internal_release_string \"\"",
2522 vbmeta_path.value().c_str());
2523
2524 EXPECT_COMMAND(1,
2525 "./avbtool verify_image "
2526 "--image %s ",
2527 vbmeta_path.value().c_str());
2528 }
2529
2530 // Helper to generate boot.img, unsparse system.img, and vbmeta.img.
GenerateImageWithHashAndHashtreeSetup()2531 void AvbToolTest::GenerateImageWithHashAndHashtreeSetup() {
2532 const size_t boot_partition_size = 16 * 1024 * 1024;
2533 const size_t boot_image_size = 5 * 1024 * 1024;
2534 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
2535 EXPECT_COMMAND(0,
2536 "./avbtool add_hash_footer"
2537 " --image %s"
2538 " --rollback_index 0"
2539 " --partition_name boot"
2540 " --partition_size %zd"
2541 " --salt deadbeef"
2542 " --internal_release_string \"\"",
2543 boot_path.value().c_str(),
2544 boot_partition_size);
2545
2546 const size_t system_partition_size = 10 * 1024 * 1024;
2547 const size_t system_image_size = 8 * 1024 * 1024;
2548 base::FilePath system_path = GenerateImage("system.img", system_image_size);
2549 EXPECT_COMMAND(0,
2550 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
2551 "--partition_size %zd --partition_name system "
2552 "--internal_release_string \"\" ",
2553 system_path.value().c_str(),
2554 system_partition_size);
2555
2556 GenerateVBMetaImage("vbmeta.img",
2557 "SHA256_RSA2048",
2558 0,
2559 base::FilePath("test/data/testkey_rsa2048.pem"),
2560 base::StringPrintf("--include_descriptors_from_image %s "
2561 "--include_descriptors_from_image %s",
2562 boot_path.value().c_str(),
2563 system_path.value().c_str()));
2564 }
2565
TEST_F(AvbToolTest,VerifyImageWithHashAndHashtree)2566 TEST_F(AvbToolTest, VerifyImageWithHashAndHashtree) {
2567 GenerateImageWithHashAndHashtreeSetup();
2568
2569 // Do two checks - one for system.img not sparse, and one where it
2570 // is sparse.
2571 for (int n = 0; n < 2; n++) {
2572 EXPECT_COMMAND(0,
2573 "./avbtool verify_image "
2574 "--image %s ",
2575 vbmeta_image_path_.value().c_str());
2576 if (n == 0) {
2577 EXPECT_COMMAND(0,
2578 "img2simg %s %s.sparse",
2579 testdir_.Append("system.img").value().c_str(),
2580 testdir_.Append("system.img").value().c_str());
2581 EXPECT_COMMAND(0,
2582 "mv %s.sparse %s",
2583 testdir_.Append("system.img").value().c_str(),
2584 testdir_.Append("system.img").value().c_str());
2585 }
2586 }
2587 }
2588
TEST_F(AvbToolTest,VerifyImageWithHashAndZeroedHashtree)2589 TEST_F(AvbToolTest, VerifyImageWithHashAndZeroedHashtree) {
2590 const size_t system_partition_size = 10 * 1024 * 1024;
2591 const size_t system_image_size = 8 * 1024 * 1024;
2592 base::FilePath system_path = GenerateImage("system.img", system_image_size);
2593 EXPECT_COMMAND(0,
2594 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
2595 "--partition_size %zd --partition_name system "
2596 "--internal_release_string \"\" ",
2597 system_path.value().c_str(),
2598 system_partition_size);
2599
2600 GenerateVBMetaImage("vbmeta.img",
2601 "SHA256_RSA2048",
2602 0,
2603 base::FilePath("test/data/testkey_rsa2048.pem"),
2604 base::StringPrintf("--include_descriptors_from_image %s ",
2605 system_path.value().c_str()));
2606
2607 EXPECT_COMMAND(0,
2608 "./avbtool verify_image --image %s --accept_zeroed_hashtree",
2609 vbmeta_image_path_.value().c_str());
2610
2611 EXPECT_COMMAND(
2612 0, "./avbtool zero_hashtree --image %s", system_path.value().c_str());
2613
2614 EXPECT_COMMAND(1,
2615 "./avbtool verify_image --image %s",
2616 vbmeta_image_path_.value().c_str());
2617
2618 EXPECT_COMMAND(0,
2619 "./avbtool verify_image --image %s --accept_zeroed_hashtree",
2620 vbmeta_image_path_.value().c_str());
2621 }
2622
TEST_F(AvbToolTest,VerifyImageWithNoHashtree)2623 TEST_F(AvbToolTest, VerifyImageWithNoHashtree) {
2624 const size_t system_partition_size = 10 * 1024 * 1024;
2625 const size_t system_image_size = 8 * 1024 * 1024;
2626 base::FilePath system_path = GenerateImage("system.img", system_image_size);
2627 EXPECT_COMMAND(0,
2628 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
2629 "--partition_size %zd --partition_name system "
2630 "--no_hashtree "
2631 "--internal_release_string \"\" ",
2632 system_path.value().c_str(),
2633 system_partition_size);
2634
2635 GenerateVBMetaImage("vbmeta.img",
2636 "SHA256_RSA2048",
2637 0,
2638 base::FilePath("test/data/testkey_rsa2048.pem"),
2639 base::StringPrintf("--include_descriptors_from_image %s ",
2640 system_path.value().c_str()));
2641
2642 EXPECT_COMMAND(1,
2643 "./avbtool verify_image --image %s",
2644 vbmeta_image_path_.value().c_str());
2645
2646 EXPECT_COMMAND(0,
2647 "./avbtool verify_image --image %s --accept_zeroed_hashtree",
2648 vbmeta_image_path_.value().c_str());
2649 }
2650
TEST_F(AvbToolTest,VerifyImageWithHashAndHashtreeCorruptHash)2651 TEST_F(AvbToolTest, VerifyImageWithHashAndHashtreeCorruptHash) {
2652 GenerateImageWithHashAndHashtreeSetup();
2653
2654 // Corrupt four bytes of data in the middle of boot.img.
2655 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
2656 EXPECT_EQ(AVB_IO_RESULT_OK,
2657 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
2658 "boot",
2659 105 * 1024, // offset from start
2660 sizeof corrupt_data,
2661 corrupt_data));
2662
2663 EXPECT_COMMAND(1,
2664 "./avbtool verify_image "
2665 "--image %s ",
2666 vbmeta_image_path_.value().c_str());
2667 }
2668
TEST_F(AvbToolTest,VerifyImageWithHashAndHashtreeCorruptHashtree)2669 TEST_F(AvbToolTest, VerifyImageWithHashAndHashtreeCorruptHashtree) {
2670 GenerateImageWithHashAndHashtreeSetup();
2671
2672 // Corrupt four bytes of data in the middle of system.img.
2673 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
2674 EXPECT_EQ(AVB_IO_RESULT_OK,
2675 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
2676 "system",
2677 123 * 1024, // offset from start
2678 sizeof corrupt_data,
2679 corrupt_data));
2680
2681 // Do two checks - one for system.img not sparse, and one where it
2682 // is sparse.
2683 for (int n = 0; n < 2; n++) {
2684 EXPECT_COMMAND(1,
2685 "./avbtool verify_image "
2686 "--image %s ",
2687 vbmeta_image_path_.value().c_str());
2688 if (n == 0) {
2689 EXPECT_COMMAND(0,
2690 "img2simg %s %s.sparse",
2691 testdir_.Append("system.img").value().c_str(),
2692 testdir_.Append("system.img").value().c_str());
2693 EXPECT_COMMAND(0,
2694 "mv %s.sparse %s",
2695 testdir_.Append("system.img").value().c_str(),
2696 testdir_.Append("system.img").value().c_str());
2697 }
2698 }
2699 }
2700
TEST_F(AvbToolTest,VerifyImageChainPartition)2701 TEST_F(AvbToolTest, VerifyImageChainPartition) {
2702 base::FilePath pk4096_path = testdir_.Append("testkey_rsa4096.avbpubkey");
2703 EXPECT_COMMAND(
2704 0,
2705 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
2706 " --output %s",
2707 pk4096_path.value().c_str());
2708
2709 base::FilePath pk8192_path = testdir_.Append("testkey_rsa8192.avbpubkey");
2710 EXPECT_COMMAND(
2711 0,
2712 "./avbtool extract_public_key --key test/data/testkey_rsa8192.pem"
2713 " --output %s",
2714 pk8192_path.value().c_str());
2715
2716 GenerateVBMetaImage("vbmeta.img",
2717 "SHA256_RSA2048",
2718 0,
2719 base::FilePath("test/data/testkey_rsa2048.pem"),
2720 base::StringPrintf("--chain_partition system:1:%s ",
2721 pk4096_path.value().c_str()));
2722
2723 // Should not fail (name, rollback_index, contents all correct).
2724 EXPECT_COMMAND(0,
2725 "./avbtool verify_image "
2726 "--image %s "
2727 "--expected_chain_partition system:1:%s",
2728 vbmeta_image_path_.value().c_str(),
2729 pk4096_path.value().c_str());
2730
2731 // Should fail because we didn't use --expected_chain_partition.
2732 EXPECT_COMMAND(1,
2733 "./avbtool verify_image "
2734 "--image %s ",
2735 vbmeta_image_path_.value().c_str());
2736
2737 // Should fail because partition name is wrong.
2738 EXPECT_COMMAND(1,
2739 "./avbtool verify_image "
2740 "--image %s "
2741 "--expected_chain_partition xyz:1:%s",
2742 vbmeta_image_path_.value().c_str(),
2743 pk4096_path.value().c_str());
2744
2745 // Should fail because rollback index location is wrong.
2746 EXPECT_COMMAND(1,
2747 "./avbtool verify_image "
2748 "--image %s "
2749 "--expected_chain_partition system:2:%s",
2750 vbmeta_image_path_.value().c_str(),
2751 pk4096_path.value().c_str());
2752
2753 // Should fail because public key blob is wrong.
2754 EXPECT_COMMAND(1,
2755 "./avbtool verify_image "
2756 "--image %s "
2757 "--expected_chain_partition system:1:%s",
2758 vbmeta_image_path_.value().c_str(),
2759 pk8192_path.value().c_str());
2760 }
2761
TEST_F(AvbToolTest,VerifyImageChainPartitionWithFollow)2762 TEST_F(AvbToolTest, VerifyImageChainPartitionWithFollow) {
2763 base::FilePath pk4096_path = testdir_.Append("testkey_rsa4096.avbpubkey");
2764 EXPECT_COMMAND(
2765 0,
2766 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
2767 " --output %s",
2768 pk4096_path.value().c_str());
2769
2770 GenerateVBMetaImage("vbmeta.img",
2771 "SHA256_RSA2048",
2772 0,
2773 base::FilePath("test/data/testkey_rsa2048.pem"),
2774 base::StringPrintf("--chain_partition system:1:%s ",
2775 pk4096_path.value().c_str()));
2776
2777 const size_t system_partition_size = 10 * 1024 * 1024;
2778 const size_t system_image_size = 8 * 1024 * 1024;
2779 base::FilePath system_path = GenerateImage("system.img", system_image_size);
2780 EXPECT_COMMAND(0,
2781 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
2782 "--partition_size %zd --partition_name system "
2783 "--algorithm SHA256_RSA4096 "
2784 "--key test/data/testkey_rsa4096.pem "
2785 "--internal_release_string \"\" ",
2786 system_path.value().c_str(),
2787 system_partition_size);
2788
2789 // Even without --expected_chain_partition this shouldn't fail because we use
2790 // --follow_chain_partitions and system.img exists... to avoid unstable paths
2791 // (e.g. /tmp/libavb.12345) in the output we need to run this from the test
2792 // directory itself. It's a little ugly but it works.
2793 char cwdbuf[PATH_MAX];
2794 ASSERT_NE(nullptr, getcwd(cwdbuf, sizeof cwdbuf));
2795 EXPECT_COMMAND(0,
2796 "cd %s && (%s/avbtool verify_image "
2797 "--image vbmeta.img --follow_chain_partitions > out.txt)",
2798 testdir_.value().c_str(),
2799 cwdbuf);
2800 base::FilePath out_path = testdir_.Append("out.txt");
2801 std::string out;
2802 ASSERT_TRUE(base::ReadFileToString(out_path, &out));
2803 EXPECT_EQ(
2804 "Verifying image vbmeta.img using embedded public key\n"
2805 "vbmeta: Successfully verified SHA256_RSA2048 vbmeta struct in "
2806 "vbmeta.img\n"
2807 "system: Chained but ROLLBACK_SLOT (which is 1) and KEY (which has sha1 "
2808 "2597c218aae470a130f61162feaae70afd97f011) not specified\n"
2809 "--\n"
2810 "Verifying image system.img using embedded public key\n"
2811 "vbmeta: Successfully verified footer and SHA256_RSA4096 vbmeta struct "
2812 "in system.img\n"
2813 "system: Successfully verified sha1 hashtree of system.img for image of "
2814 "8388608 bytes\n",
2815 out);
2816
2817 // Make sure we also follow partitions *even* when specifying
2818 // --expect_chain_partition. The output is slightly different from above.
2819 EXPECT_COMMAND(0,
2820 "cd %s && (%s/avbtool verify_image "
2821 "--image vbmeta.img --expected_chain_partition system:1:%s "
2822 "--follow_chain_partitions > out.txt)",
2823 testdir_.value().c_str(),
2824 cwdbuf,
2825 pk4096_path.value().c_str());
2826 ASSERT_TRUE(base::ReadFileToString(out_path, &out));
2827 EXPECT_EQ(
2828 "Verifying image vbmeta.img using embedded public key\n"
2829 "vbmeta: Successfully verified SHA256_RSA2048 vbmeta struct in "
2830 "vbmeta.img\n"
2831 "system: Successfully verified chain partition descriptor matches "
2832 "expected data\n"
2833 "--\n"
2834 "Verifying image system.img using embedded public key\n"
2835 "vbmeta: Successfully verified footer and SHA256_RSA4096 vbmeta struct "
2836 "in system.img\n"
2837 "system: Successfully verified sha1 hashtree of system.img for image of "
2838 "8388608 bytes\n",
2839 out);
2840 }
2841
TEST_F(AvbToolTest,VerifyImageChainPartitionOtherVBMeta)2842 TEST_F(AvbToolTest, VerifyImageChainPartitionOtherVBMeta) {
2843 base::FilePath pk4096_path = testdir_.Append("testkey_rsa4096.avbpubkey");
2844 EXPECT_COMMAND(
2845 0,
2846 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
2847 " --output %s",
2848 pk4096_path.value().c_str());
2849
2850 const size_t system_partition_size = 10 * 1024 * 1024;
2851 const size_t system_image_size = 8 * 1024 * 1024;
2852 base::FilePath system_path = GenerateImage("system.img", system_image_size);
2853 EXPECT_COMMAND(0,
2854 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
2855 "--partition_size %zd --partition_name system "
2856 "--internal_release_string \"\" "
2857 "--algorithm SHA256_RSA4096 "
2858 "--key test/data/testkey_rsa4096.pem ",
2859 system_path.value().c_str(),
2860 system_partition_size,
2861 pk4096_path.value().c_str());
2862
2863 GenerateVBMetaImage(
2864 "vbmeta.img",
2865 "SHA256_RSA2048",
2866 0,
2867 base::FilePath("test/data/testkey_rsa2048.pem"),
2868 base::StringPrintf("--chain_partition vbmeta_google:1:%s ",
2869 pk4096_path.value().c_str()));
2870
2871 // Should not fail (name, rollback_index, contents all correct).
2872 EXPECT_COMMAND(0,
2873 "./avbtool verify_image "
2874 "--image %s "
2875 "--expected_chain_partition vbmeta_google:1:%s",
2876 vbmeta_image_path_.value().c_str(),
2877 pk4096_path.value().c_str());
2878
2879 // Should not fail (looks in system.img image).
2880 EXPECT_COMMAND(0,
2881 "./avbtool verify_image "
2882 "--image %s ",
2883 system_path.value().c_str());
2884
2885 // Extract the vbmeta blob from the footer in system.img, put it into
2886 // vbmeta_google.img, and erase the footer from system.img (but keep
2887 // the hash tree in system.img)
2888 base::FilePath vbmeta_google_path = GenerateImage("vbmeta_google.img", 0);
2889 EXPECT_COMMAND(0,
2890 "./avbtool extract_vbmeta_image"
2891 " --image %s"
2892 " --output %s",
2893 system_path.value().c_str(),
2894 vbmeta_google_path.value().c_str());
2895 EXPECT_COMMAND(0,
2896 "./avbtool erase_footer"
2897 " --image %s --keep_hashtree",
2898 system_path.value().c_str());
2899
2900 // Should not fail - looks in system.img's detached vbmeta (vbmeta_google.img)
2901 // for vbmeta blob and system.img for the actual hashtree.
2902 EXPECT_COMMAND(0,
2903 "./avbtool verify_image "
2904 "--image %s ",
2905 vbmeta_google_path.value().c_str());
2906 }
2907
2908 class AvbToolTest_PrintRequiredVersion : public AvbToolTest {
2909 protected:
2910 const char* kOutputFile = "versions.txt";
2911
PrintWithAddHashFooter(int target_required_minor_version)2912 void PrintWithAddHashFooter(int target_required_minor_version) {
2913 std::string extra_args;
2914 if (target_required_minor_version == 1) {
2915 // The --do_not_use_ab option will require 1.1.
2916 extra_args = "--do_not_use_ab";
2917 }
2918 const size_t boot_partition_size = 16 * 1024 * 1024;
2919 base::FilePath output_path = testdir_.Append(kOutputFile);
2920 EXPECT_COMMAND(0,
2921 "./avbtool add_hash_footer"
2922 " --rollback_index 0"
2923 " --partition_name boot"
2924 " --partition_size %zd"
2925 " --salt deadbeef"
2926 " --internal_release_string \"\""
2927 " %s"
2928 " --print_required_libavb_version > %s",
2929 boot_partition_size,
2930 extra_args.c_str(),
2931 output_path.value().c_str());
2932 CheckVersion(target_required_minor_version);
2933 }
2934
PrintWithAddHashtreeFooter(int target_required_minor_version)2935 void PrintWithAddHashtreeFooter(int target_required_minor_version) {
2936 std::string extra_args;
2937 if (target_required_minor_version == 1) {
2938 // The --do_not_use_ab option will require 1.1.
2939 extra_args = "--do_not_use_ab";
2940 }
2941 const size_t system_partition_size = 10 * 1024 * 1024;
2942 base::FilePath output_path = testdir_.Append(kOutputFile);
2943 EXPECT_COMMAND(0,
2944 "./avbtool add_hashtree_footer --salt d00df00d "
2945 "--partition_size %zd --partition_name system "
2946 "--internal_release_string \"\""
2947 " %s"
2948 " --print_required_libavb_version > %s",
2949 system_partition_size,
2950 extra_args.c_str(),
2951 output_path.value().c_str());
2952 CheckVersion(target_required_minor_version);
2953 }
2954
PrintWithMakeVbmetaImage(int target_required_minor_version)2955 void PrintWithMakeVbmetaImage(int target_required_minor_version) {
2956 std::string extra_args;
2957 if (target_required_minor_version == 1) {
2958 // An included descriptor that requires 1.1 will require 1.1 for vbmeta.
2959 const size_t boot_partition_size = 16 * 1024 * 1024;
2960 base::FilePath image_path = GenerateImage("test_print_version", 1024);
2961 EXPECT_COMMAND(0,
2962 "./avbtool add_hash_footer --salt d00df00d "
2963 "--hash_algorithm sha256 --image %s "
2964 "--partition_size %d --partition_name foobar "
2965 "--algorithm SHA256_RSA2048 "
2966 "--key test/data/testkey_rsa2048.pem "
2967 "--internal_release_string \"\" "
2968 "--do_not_use_ab",
2969 image_path.value().c_str(),
2970 (int)boot_partition_size);
2971 extra_args = base::StringPrintf("--include_descriptors_from_image %s",
2972 image_path.value().c_str());
2973 }
2974 base::FilePath output_path = testdir_.Append(kOutputFile);
2975 EXPECT_COMMAND(0,
2976 "./avbtool make_vbmeta_image "
2977 "--algorithm SHA256_RSA2048 "
2978 "--key test/data/testkey_rsa2048.pem "
2979 "--internal_release_string \"\""
2980 " %s"
2981 " --print_required_libavb_version > %s",
2982 extra_args.c_str(),
2983 output_path.value().c_str());
2984 CheckVersion(target_required_minor_version);
2985 }
2986
CheckVersion(int expected_required_minor_version)2987 void CheckVersion(int expected_required_minor_version) {
2988 base::FilePath output_path = testdir_.Append(kOutputFile);
2989 std::string output;
2990 ASSERT_TRUE(base::ReadFileToString(output_path, &output));
2991 EXPECT_EQ(output,
2992 base::StringPrintf("1.%d\n", expected_required_minor_version));
2993 }
2994 };
2995
TEST_F(AvbToolTest_PrintRequiredVersion,HashFooter_1_0)2996 TEST_F(AvbToolTest_PrintRequiredVersion, HashFooter_1_0) {
2997 PrintWithAddHashFooter(0);
2998 }
2999
TEST_F(AvbToolTest_PrintRequiredVersion,HashFooter_1_1)3000 TEST_F(AvbToolTest_PrintRequiredVersion, HashFooter_1_1) {
3001 PrintWithAddHashFooter(1);
3002 }
3003
TEST_F(AvbToolTest_PrintRequiredVersion,HashtreeFooter_1_0)3004 TEST_F(AvbToolTest_PrintRequiredVersion, HashtreeFooter_1_0) {
3005 PrintWithAddHashtreeFooter(0);
3006 }
3007
TEST_F(AvbToolTest_PrintRequiredVersion,HashtreeFooter_1_1)3008 TEST_F(AvbToolTest_PrintRequiredVersion, HashtreeFooter_1_1) {
3009 PrintWithAddHashtreeFooter(1);
3010 }
3011
TEST_F(AvbToolTest_PrintRequiredVersion,Vbmeta_1_0)3012 TEST_F(AvbToolTest_PrintRequiredVersion, Vbmeta_1_0) {
3013 PrintWithMakeVbmetaImage(0);
3014 }
3015
TEST_F(AvbToolTest_PrintRequiredVersion,Vbmeta_1_1)3016 TEST_F(AvbToolTest_PrintRequiredVersion, Vbmeta_1_1) {
3017 PrintWithMakeVbmetaImage(1);
3018 }
3019
TEST_F(AvbToolTest,MakeAtxPikCertificate)3020 TEST_F(AvbToolTest, MakeAtxPikCertificate) {
3021 base::FilePath subject_path = testdir_.Append("tmp_subject");
3022 ASSERT_TRUE(base::WriteFile(subject_path, "fake PIK subject", 16));
3023 base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
3024 EXPECT_COMMAND(
3025 0,
3026 "openssl pkey -pubout -in test/data/testkey_atx_pik.pem -out %s",
3027 pubkey_path.value().c_str());
3028
3029 base::FilePath output_path = testdir_.Append("tmp_certificate.bin");
3030 EXPECT_COMMAND(0,
3031 "./avbtool make_atx_certificate"
3032 " --subject %s"
3033 " --subject_key %s"
3034 " --subject_key_version 42"
3035 " --subject_is_intermediate_authority"
3036 " --authority_key test/data/testkey_atx_prk.pem"
3037 " --output %s",
3038 subject_path.value().c_str(),
3039 pubkey_path.value().c_str(),
3040 output_path.value().c_str());
3041
3042 EXPECT_COMMAND(0,
3043 "diff test/data/atx_pik_certificate.bin %s",
3044 output_path.value().c_str());
3045 }
3046
TEST_F(AvbToolTest,MakeAtxPskCertificate)3047 TEST_F(AvbToolTest, MakeAtxPskCertificate) {
3048 base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
3049 EXPECT_COMMAND(
3050 0,
3051 "openssl pkey -pubout -in test/data/testkey_atx_psk.pem -out %s",
3052 pubkey_path.value().c_str());
3053
3054 base::FilePath output_path = testdir_.Append("tmp_certificate.bin");
3055 EXPECT_COMMAND(0,
3056 "./avbtool make_atx_certificate"
3057 " --subject test/data/atx_product_id.bin"
3058 " --subject_key %s"
3059 " --subject_key_version 42"
3060 " --authority_key test/data/testkey_atx_pik.pem"
3061 " --output %s",
3062 pubkey_path.value().c_str(),
3063 output_path.value().c_str());
3064
3065 EXPECT_COMMAND(0,
3066 "diff test/data/atx_psk_certificate.bin %s",
3067 output_path.value().c_str());
3068 }
3069
TEST_F(AvbToolTest,MakeAtxPukCertificate)3070 TEST_F(AvbToolTest, MakeAtxPukCertificate) {
3071 base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
3072 EXPECT_COMMAND(
3073 0,
3074 "openssl pkey -pubout -in test/data/testkey_atx_puk.pem -out %s",
3075 pubkey_path.value().c_str());
3076
3077 base::FilePath output_path = testdir_.Append("tmp_certificate.bin");
3078 EXPECT_COMMAND(0,
3079 "./avbtool make_atx_certificate"
3080 " --subject test/data/atx_product_id.bin"
3081 " --subject_key %s"
3082 " --subject_key_version 42"
3083 " --usage com.google.android.things.vboot.unlock"
3084 " --authority_key test/data/testkey_atx_pik.pem"
3085 " --output %s",
3086 pubkey_path.value().c_str(),
3087 output_path.value().c_str());
3088
3089 EXPECT_COMMAND(0,
3090 "diff test/data/atx_puk_certificate.bin %s",
3091 output_path.value().c_str());
3092 }
3093
TEST_F(AvbToolTest,MakeAtxPermanentAttributes)3094 TEST_F(AvbToolTest, MakeAtxPermanentAttributes) {
3095 base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
3096 EXPECT_COMMAND(
3097 0,
3098 "openssl pkey -pubout -in test/data/testkey_atx_prk.pem -out %s",
3099 pubkey_path.value().c_str());
3100
3101 base::FilePath output_path = testdir_.Append("tmp_attributes.bin");
3102 EXPECT_COMMAND(0,
3103 "./avbtool make_atx_permanent_attributes"
3104 " --root_authority_key %s"
3105 " --product_id test/data/atx_product_id.bin"
3106 " --output %s",
3107 pubkey_path.value().c_str(),
3108 output_path.value().c_str());
3109
3110 EXPECT_COMMAND(0,
3111 "diff test/data/atx_permanent_attributes.bin %s",
3112 output_path.value().c_str());
3113 }
3114
TEST_F(AvbToolTest,MakeAtxMetadata)3115 TEST_F(AvbToolTest, MakeAtxMetadata) {
3116 base::FilePath output_path = testdir_.Append("tmp_metadata.bin");
3117
3118 EXPECT_COMMAND(
3119 0,
3120 "./avbtool make_atx_metadata"
3121 " --intermediate_key_certificate test/data/atx_pik_certificate.bin"
3122 " --product_key_certificate test/data/atx_psk_certificate.bin"
3123 " --output %s",
3124 output_path.value().c_str());
3125
3126 EXPECT_COMMAND(
3127 0, "diff test/data/atx_metadata.bin %s", output_path.value().c_str());
3128 }
3129
TEST_F(AvbToolTest,MakeAtxUnlockCredential)3130 TEST_F(AvbToolTest, MakeAtxUnlockCredential) {
3131 base::FilePath output_path = testdir_.Append("tmp_credential.bin");
3132
3133 EXPECT_COMMAND(
3134 0,
3135 "./avbtool make_atx_unlock_credential"
3136 " --intermediate_key_certificate test/data/atx_pik_certificate.bin"
3137 " --unlock_key_certificate test/data/atx_puk_certificate.bin"
3138 " --challenge test/data/atx_unlock_challenge.bin"
3139 " --unlock_key test/data/testkey_atx_puk.pem"
3140 " --output %s",
3141 output_path.value().c_str());
3142
3143 EXPECT_COMMAND(0,
3144 "diff test/data/atx_unlock_credential.bin %s",
3145 output_path.value().c_str());
3146 }
3147
3148 } // namespace avb
3149