• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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