Home | History | Annotate | Download | only in test
      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:
     46   AvbToolTest() {}
     47 
     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.
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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       "Algorithm:                SHA256_RSA2048\n"
    360       "Rollback Index:           0\n"
    361       "Flags:                    0\n"
    362       "Release String:           ''\n"
    363       "Descriptors:\n"
    364       "    Prop: foo -> 'brillo'\n"
    365       "    Prop: bar -> 'chromeos'\n"
    366       "    Prop: prisoner -> '24601'\n"
    367       "    Prop: hexnumber -> '0xcafe'\n"
    368       "    Prop: hexnumber_capital -> '0xCAFE'\n"
    369       "    Prop: large_hexnumber -> '0xfedcba9876543210'\n"
    370       "    Prop: larger_than_uint64 -> '0xfedcba98765432101'\n"
    371       "    Prop: almost_a_number -> '423x'\n"
    372       "    Prop: blob -> '\\x00\\x00brillo "
    373       "ftw!\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\n'\n"
    374       "    Prop: large_blob -> (2048 bytes)\n",
    375       InfoImage(vbmeta_image_path_));
    376 }
    377 
    378 static bool collect_descriptors(const AvbDescriptor* descriptor,
    379                                 void* user_data) {
    380   std::vector<const AvbDescriptor*>* descriptors =
    381       reinterpret_cast<std::vector<const AvbDescriptor*>*>(user_data);
    382   descriptors->push_back(descriptor);
    383   return true;  // Keep iterating.
    384 }
    385 
    386 static std::string AddHashFooterGetExpectedVBMetaInfo(
    387     const bool sparse_image, const uint64_t partition_size) {
    388   return base::StringPrintf(
    389       "Footer version:           1.0\n"
    390       "Image size:               %" PRIu64
    391       " bytes\n"
    392       "Original image size:      1052672 bytes\n"
    393       "VBMeta offset:            1052672\n"
    394       "VBMeta size:              1280 bytes\n"
    395       "--\n"
    396       "Minimum libavb version:   1.0%s\n"
    397       "Header Block:             256 bytes\n"
    398       "Authentication Block:     320 bytes\n"
    399       "Auxiliary Block:          704 bytes\n"
    400       "Algorithm:                SHA256_RSA2048\n"
    401       "Rollback Index:           0\n"
    402       "Flags:                    0\n"
    403       "Release String:           ''\n"
    404       "Descriptors:\n"
    405       "    Hash descriptor:\n"
    406       "      Image Size:            1052672 bytes\n"
    407       "      Hash Algorithm:        sha256\n"
    408       "      Partition Name:        foobar\n"
    409       "      Salt:                  d00df00d\n"
    410       "      Digest:                "
    411       "9a58cc996d405e08a1e00f96dbfe9104fedf41cb83b1f"
    412       "5e4ed357fbcf58d88d9\n",
    413       partition_size,
    414       sparse_image ? " (Sparse)" : "");
    415 }
    416 
    417 void AvbToolTest::AddHashFooterTest(bool sparse_image) {
    418   const size_t rootfs_size = 1028 * 1024;
    419   const size_t partition_size = 1536 * 1024;
    420   const size_t resized_partition_size = 1280 * 1024;
    421 
    422   // Generate a 1028 KiB file with known content. Some content have
    423   // been arranged to ensure FILL_DATA segments in the sparse file.
    424   std::vector<uint8_t> rootfs;
    425   rootfs.resize(rootfs_size);
    426   for (size_t n = 0; n < rootfs_size; n++) {
    427     if ((n >= 5 * 1000 && n < 105 * 1000) ||
    428         (n >= 205 * 1000 && n < 305 * 1000) ||
    429         (n >= 505 * 1000 && n < 605 * 1000)) {
    430       rootfs[n] = uint8_t(n) & 0x03;
    431     } else {
    432       rootfs[n] = uint8_t(n);
    433     }
    434   }
    435   base::FilePath ext_vbmeta_path = testdir_.Append("ext_vbmeta.bin");
    436   base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
    437   EXPECT_EQ(rootfs_size,
    438             static_cast<const size_t>(
    439                 base::WriteFile(rootfs_path,
    440                                 reinterpret_cast<const char*>(rootfs.data()),
    441                                 rootfs.size())));
    442 
    443   if (sparse_image) {
    444     EXPECT_COMMAND(0,
    445                    "mv %s %s.unsparse",
    446                    rootfs_path.value().c_str(),
    447                    rootfs_path.value().c_str());
    448     EXPECT_COMMAND(0,
    449                    "img2simg %s.unsparse %s",
    450                    rootfs_path.value().c_str(),
    451                    rootfs_path.value().c_str());
    452     EXPECT_COMMAND(0, "rm -f %s.unsparse", rootfs_path.value().c_str());
    453   }
    454 
    455   /* Do this twice to check that 'add_hash_footer' is idempotent. */
    456   for (int n = 0; n < 2; n++) {
    457     EXPECT_COMMAND(0,
    458                    "./avbtool add_hash_footer --salt d00df00d "
    459                    "--hash_algorithm sha256 --image %s "
    460                    "--partition_size %d --partition_name foobar "
    461                    "--algorithm SHA256_RSA2048 "
    462                    "--key test/data/testkey_rsa2048.pem "
    463                    "--output_vbmeta %s "
    464                    "--internal_release_string \"\"",
    465                    rootfs_path.value().c_str(),
    466                    (int)partition_size,
    467                    ext_vbmeta_path.value().c_str());
    468 
    469     ASSERT_EQ(AddHashFooterGetExpectedVBMetaInfo(sparse_image, partition_size),
    470               InfoImage(rootfs_path));
    471 
    472     ASSERT_EQ(
    473         "Minimum libavb version:   1.0\n"
    474         "Header Block:             256 bytes\n"
    475         "Authentication Block:     320 bytes\n"
    476         "Auxiliary Block:          704 bytes\n"
    477         "Algorithm:                SHA256_RSA2048\n"
    478         "Rollback Index:           0\n"
    479         "Flags:                    0\n"
    480         "Release String:           ''\n"
    481         "Descriptors:\n"
    482         "    Hash descriptor:\n"
    483         "      Image Size:            1052672 bytes\n"
    484         "      Hash Algorithm:        sha256\n"
    485         "      Partition Name:        foobar\n"
    486         "      Salt:                  d00df00d\n"
    487         "      Digest:                "
    488         "9a58cc996d405e08a1e00f96dbfe9104fedf41cb83b1f"
    489         "5e4ed357fbcf58d88d9\n",
    490         InfoImage(ext_vbmeta_path));
    491   }
    492 
    493   // Resize the image and check that the only thing that has changed
    494   // is where the footer is. First check that resizing to a smaller
    495   // size than the original rootfs fails. Then resize to something
    496   // larger than the original rootfs but smaller than the current
    497   // partition size.
    498   EXPECT_COMMAND(1,
    499                  "./avbtool resize_image --image %s "
    500                  "--partition_size %d",
    501                  rootfs_path.value().c_str(),
    502                  (int)(rootfs_size - 16 * 1024));
    503   EXPECT_COMMAND(0,
    504                  "./avbtool resize_image --image %s "
    505                  "--partition_size %d",
    506                  rootfs_path.value().c_str(),
    507                  (int)resized_partition_size);
    508   ASSERT_EQ(
    509       AddHashFooterGetExpectedVBMetaInfo(sparse_image, resized_partition_size),
    510       InfoImage(rootfs_path));
    511 
    512   if (sparse_image) {
    513     EXPECT_COMMAND(0,
    514                    "mv %s %s.sparse",
    515                    rootfs_path.value().c_str(),
    516                    rootfs_path.value().c_str());
    517     EXPECT_COMMAND(0,
    518                    "simg2img %s.sparse %s",
    519                    rootfs_path.value().c_str(),
    520                    rootfs_path.value().c_str());
    521     EXPECT_COMMAND(0, "rm -f %s.sparse", rootfs_path.value().c_str());
    522   }
    523 
    524   // Manually calculate the hash to check that it agrees with avbtool.
    525   AvbSHA256Ctx hasher_ctx;
    526   const uint8_t hasher_salt[4] = {0xd0, 0x0d, 0xf0, 0x0d};
    527   avb_sha256_init(&hasher_ctx);
    528   avb_sha256_update(&hasher_ctx, hasher_salt, 4);
    529   avb_sha256_update(&hasher_ctx, rootfs.data(), rootfs_size);
    530   uint8_t* hasher_digest = avb_sha256_final(&hasher_ctx);
    531   EXPECT_EQ("9a58cc996d405e08a1e00f96dbfe9104fedf41cb83b1f5e4ed357fbcf58d88d9",
    532             mem_to_hexstring(hasher_digest, AVB_SHA256_DIGEST_SIZE));
    533 
    534   // Now check that we can find the VBMeta block again from the footer.
    535   std::string part_data;
    536   ASSERT_TRUE(base::ReadFileToString(rootfs_path, &part_data));
    537 
    538   // Check footer contains correct data.
    539   AvbFooter f;
    540   EXPECT_NE(0,
    541             avb_footer_validate_and_byteswap(
    542                 reinterpret_cast<const AvbFooter*>(
    543                     part_data.data() + part_data.size() - AVB_FOOTER_SIZE),
    544                 &f));
    545   EXPECT_EQ(
    546       std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
    547       AVB_FOOTER_MAGIC);
    548   EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
    549   EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
    550   EXPECT_EQ(1052672UL, f.original_image_size);
    551   EXPECT_EQ(1052672UL, f.vbmeta_offset);
    552   EXPECT_EQ(1280UL, f.vbmeta_size);
    553 
    554   // Check that the vbmeta image at |f.vbmeta_offset| checks out.
    555   const uint8_t* vbmeta_data =
    556       reinterpret_cast<const uint8_t*>(part_data.data() + f.vbmeta_offset);
    557   EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
    558             avb_vbmeta_image_verify(vbmeta_data, f.vbmeta_size, NULL, NULL));
    559 
    560   // Collect all descriptors.
    561   std::vector<const AvbDescriptor*> descriptors;
    562   avb_descriptor_foreach(
    563       vbmeta_data, f.vbmeta_size, collect_descriptors, &descriptors);
    564 
    565   // We should only have a single descriptor and it should be a
    566   // hash descriptor.
    567   EXPECT_EQ(1UL, descriptors.size());
    568   EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASH, avb_be64toh(descriptors[0]->tag));
    569   AvbHashDescriptor d;
    570   EXPECT_NE(
    571       0,
    572       avb_hash_descriptor_validate_and_byteswap(
    573           reinterpret_cast<const AvbHashDescriptor*>(descriptors[0]), &d));
    574   EXPECT_EQ(1052672UL, d.image_size);
    575   EXPECT_EQ(6UL, d.partition_name_len);
    576   EXPECT_EQ(4UL, d.salt_len);
    577   EXPECT_EQ(32UL, d.digest_len);
    578   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
    579                             sizeof(AvbHashDescriptor);
    580   uint64_t o = 0;
    581   EXPECT_EQ("foobar",
    582             std::string(reinterpret_cast<const char*>(desc_end + o),
    583                         d.partition_name_len));
    584   o += d.partition_name_len;
    585   EXPECT_EQ("d00df00d", mem_to_hexstring(desc_end + o, d.salt_len));
    586   o += d.salt_len;
    587   EXPECT_EQ("9a58cc996d405e08a1e00f96dbfe9104fedf41cb83b1f5e4ed357fbcf58d88d9",
    588             mem_to_hexstring(desc_end + o, d.digest_len));
    589 
    590   // Check that the footer is correctly erased.
    591   EXPECT_COMMAND(
    592       0, "./avbtool erase_footer --image %s", rootfs_path.value().c_str());
    593   int64_t erased_footer_file_size;
    594   ASSERT_TRUE(base::GetFileSize(rootfs_path, &erased_footer_file_size));
    595   EXPECT_EQ(static_cast<size_t>(erased_footer_file_size), rootfs_size);
    596 
    597   // Check that --do_not_append_vbmeta_image works as intended.
    598   EXPECT_COMMAND(0,
    599                  "./avbtool add_hash_footer --salt d00df00d "
    600                  "--hash_algorithm sha256 --image %s "
    601                  "--partition_size %d --partition_name foobar "
    602                  "--algorithm SHA256_RSA2048 "
    603                  "--key test/data/testkey_rsa2048.pem "
    604                  "--output_vbmeta %s_2nd_run --do_not_append_vbmeta_image "
    605                  "--internal_release_string \"\"",
    606                  rootfs_path.value().c_str(),
    607                  (int)partition_size,
    608                  ext_vbmeta_path.value().c_str());
    609   int64_t file_size;
    610   ASSERT_TRUE(base::GetFileSize(rootfs_path, &file_size));
    611   EXPECT_EQ(static_cast<size_t>(file_size), rootfs_size);
    612   EXPECT_COMMAND(0,
    613                  "diff %s %s_2nd_run",
    614                  ext_vbmeta_path.value().c_str(),
    615                  ext_vbmeta_path.value().c_str());
    616 }
    617 
    618 TEST_F(AvbToolTest, AddHashFooter) {
    619   AddHashFooterTest(false);
    620 }
    621 
    622 TEST_F(AvbToolTest, AddHashFooterSparse) {
    623   AddHashFooterTest(true);
    624 }
    625 
    626 static std::string RemoveLinesStartingWith(const std::string& str,
    627                                            const std::string& prefix) {
    628   std::vector<std::string> lines;
    629   std::string ret;
    630 
    631   lines = base::SplitString(
    632       str, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    633   for (const std::string& line : lines) {
    634     if (!base::StartsWith(line, prefix, base::CompareCase::SENSITIVE)) {
    635       ret += line;
    636       ret += '\n';
    637     }
    638   }
    639   return ret;
    640 }
    641 
    642 TEST_F(AvbToolTest, AddHashFooterSparseWithHoleAtTheEnd) {
    643   const size_t partition_size = 10 * 1024 * 1024;
    644   const size_t metadata_size = 128 * 1024;
    645 
    646   // It's not enough to run img2simg on a file with a lot of zeroes at
    647   // the end since that will turn up as "Fill with value (for value =
    648   // 0x00000000)" and not "Don't care". Instead, use make_ext4fs for
    649   // this since it will put a big hole (e.g. "Don't care" chunk) at
    650   // the end.
    651   base::FilePath partition_path = testdir_.Append("partition.bin");
    652   EXPECT_COMMAND(0,
    653                  "make_ext4fs -s -L test -l %zd %s",
    654                  partition_size - metadata_size,
    655                  partition_path.value().c_str());
    656 
    657   EXPECT_COMMAND(0,
    658                  "./avbtool add_hash_footer --salt d00df00d "
    659                  "--hash_algorithm sha256 --image %s "
    660                  "--partition_size %d --partition_name foobar "
    661                  "--algorithm SHA256_RSA2048 "
    662                  "--key test/data/testkey_rsa2048.pem "
    663                  "--internal_release_string \"\"",
    664                  partition_path.value().c_str(),
    665                  (int)partition_size);
    666 
    667   // Since we may be using an arbritary version of make_ext4fs
    668   // (because of different branches) the contents of the resulting
    669   // disk image may slightly change. It's enough to just remove the
    670   // "Digest:" line from the output to work around this.
    671   std::string info =
    672       RemoveLinesStartingWith(InfoImage(partition_path), "      Digest:");
    673   ASSERT_EQ(
    674       "Footer version:           1.0\n"
    675       "Image size:               10485760 bytes\n"
    676       "Original image size:      10354688 bytes\n"
    677       "VBMeta offset:            10354688\n"
    678       "VBMeta size:              1280 bytes\n"
    679       "--\n"
    680       "Minimum libavb version:   1.0 (Sparse)\n"
    681       "Header Block:             256 bytes\n"
    682       "Authentication Block:     320 bytes\n"
    683       "Auxiliary Block:          704 bytes\n"
    684       "Algorithm:                SHA256_RSA2048\n"
    685       "Rollback Index:           0\n"
    686       "Flags:                    0\n"
    687       "Release String:           ''\n"
    688       "Descriptors:\n"
    689       "    Hash descriptor:\n"
    690       "      Image Size:            10354688 bytes\n"
    691       "      Hash Algorithm:        sha256\n"
    692       "      Partition Name:        foobar\n"
    693       "      Salt:                  d00df00d\n",
    694       info);
    695 
    696   EXPECT_COMMAND(0,
    697                  "mv %s %s.sparse",
    698                  partition_path.value().c_str(),
    699                  partition_path.value().c_str());
    700   EXPECT_COMMAND(0,
    701                  "simg2img %s.sparse %s",
    702                  partition_path.value().c_str(),
    703                  partition_path.value().c_str());
    704   EXPECT_COMMAND(0, "rm -f %s.sparse", partition_path.value().c_str());
    705 }
    706 
    707 TEST_F(AvbToolTest, AddHashFooterCalcMaxImageSize) {
    708   const size_t partition_size = 10 * 1024 * 1024;
    709   base::FilePath output_path = testdir_.Append("max_size.txt");
    710 
    711   EXPECT_COMMAND(0,
    712                  "./avbtool add_hash_footer "
    713                  "--partition_size %zd "
    714                  "--calc_max_image_size > %s",
    715                  partition_size,
    716                  output_path.value().c_str());
    717   std::string max_image_size_data;
    718   EXPECT_TRUE(base::ReadFileToString(output_path, &max_image_size_data));
    719   EXPECT_EQ("10416128\n", max_image_size_data);
    720   size_t max_image_size = atoll(max_image_size_data.c_str());
    721 
    722   // Metadata takes up 68 KiB.
    723   EXPECT_EQ(68 * 1024ULL, partition_size - max_image_size);
    724 
    725   // Check that we can add a hash footer for an image this size for
    726   // such a partition size.
    727   base::FilePath boot_path = GenerateImage("boot", max_image_size);
    728   EXPECT_COMMAND(0,
    729                  "./avbtool add_hash_footer"
    730                  " --image %s"
    731                  " --partition_name boot"
    732                  " --partition_size %zd"
    733                  " --salt deadbeef"
    734                  " --algorithm SHA512_RSA4096 "
    735                  " --key test/data/testkey_rsa4096.pem"
    736                  " --internal_release_string \"\"",
    737                  boot_path.value().c_str(),
    738                  partition_size);
    739 }
    740 
    741 void AvbToolTest::AddHashtreeFooterTest(bool sparse_image) {
    742   const size_t rootfs_size = 1028 * 1024;
    743   const size_t partition_size = 1536 * 1024;
    744 
    745   // Generate a 1028 KiB file with known content.
    746   std::vector<uint8_t> rootfs;
    747   rootfs.resize(rootfs_size);
    748   for (size_t n = 0; n < rootfs_size; n++)
    749     rootfs[n] = uint8_t(n);
    750   base::FilePath ext_vbmeta_path = testdir_.Append("ext_vbmeta.bin");
    751   base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
    752   EXPECT_EQ(rootfs_size,
    753             static_cast<const size_t>(
    754                 base::WriteFile(rootfs_path,
    755                                 reinterpret_cast<const char*>(rootfs.data()),
    756                                 rootfs.size())));
    757 
    758   if (sparse_image) {
    759     EXPECT_COMMAND(0,
    760                    "mv %s %s.unsparse",
    761                    rootfs_path.value().c_str(),
    762                    rootfs_path.value().c_str());
    763     EXPECT_COMMAND(0,
    764                    "img2simg %s.unsparse %s",
    765                    rootfs_path.value().c_str(),
    766                    rootfs_path.value().c_str());
    767     EXPECT_COMMAND(0, "rm -f %s.unsparse", rootfs_path.value().c_str());
    768   }
    769 
    770   /* Do this twice to check that 'add_hashtree_footer' is idempotent. */
    771   for (int n = 0; n < 2; n++) {
    772     EXPECT_COMMAND(0,
    773                    "./avbtool add_hashtree_footer --salt d00df00d --image %s "
    774                    "--partition_size %d --partition_name foobar "
    775                    "--algorithm SHA256_RSA2048 "
    776                    "--key test/data/testkey_rsa2048.pem "
    777                    "--output_vbmeta_image %s "
    778                    "--internal_release_string \"\" "
    779                    "--do_not_generate_fec",
    780                    rootfs_path.value().c_str(),
    781                    (int)partition_size,
    782                    ext_vbmeta_path.value().c_str());
    783 
    784     ASSERT_EQ(base::StringPrintf("Footer version:           1.0\n"
    785                                  "Image size:               1572864 bytes\n"
    786                                  "Original image size:      1052672 bytes\n"
    787                                  "VBMeta offset:            1069056\n"
    788                                  "VBMeta size:              1344 bytes\n"
    789                                  "--\n"
    790                                  "Minimum libavb version:   1.0%s\n"
    791                                  "Header Block:             256 bytes\n"
    792                                  "Authentication Block:     320 bytes\n"
    793                                  "Auxiliary Block:          768 bytes\n"
    794                                  "Algorithm:                SHA256_RSA2048\n"
    795                                  "Rollback Index:           0\n"
    796                                  "Flags:                    0\n"
    797                                  "Release String:           ''\n"
    798                                  "Descriptors:\n"
    799                                  "    Hashtree descriptor:\n"
    800                                  "      Version of dm-verity:  1\n"
    801                                  "      Image Size:            1052672 bytes\n"
    802                                  "      Tree Offset:           1052672\n"
    803                                  "      Tree Size:             16384 bytes\n"
    804                                  "      Data Block Size:       4096 bytes\n"
    805                                  "      Hash Block Size:       4096 bytes\n"
    806                                  "      FEC num roots:         0\n"
    807                                  "      FEC offset:            0\n"
    808                                  "      FEC size:              0 bytes\n"
    809                                  "      Hash Algorithm:        sha1\n"
    810                                  "      Partition Name:        foobar\n"
    811                                  "      Salt:                  d00df00d\n"
    812                                  "      Root Digest:           "
    813                                  "e811611467dcd6e8dc4324e45f706c2bdd51db67\n",
    814                                  sparse_image ? " (Sparse)" : ""),
    815               InfoImage(rootfs_path));
    816 
    817     ASSERT_EQ(
    818         "Minimum libavb version:   1.0\n"
    819         "Header Block:             256 bytes\n"
    820         "Authentication Block:     320 bytes\n"
    821         "Auxiliary Block:          768 bytes\n"
    822         "Algorithm:                SHA256_RSA2048\n"
    823         "Rollback Index:           0\n"
    824         "Flags:                    0\n"
    825         "Release String:           ''\n"
    826         "Descriptors:\n"
    827         "    Hashtree descriptor:\n"
    828         "      Version of dm-verity:  1\n"
    829         "      Image Size:            1052672 bytes\n"
    830         "      Tree Offset:           1052672\n"
    831         "      Tree Size:             16384 bytes\n"
    832         "      Data Block Size:       4096 bytes\n"
    833         "      Hash Block Size:       4096 bytes\n"
    834         "      FEC num roots:         0\n"
    835         "      FEC offset:            0\n"
    836         "      FEC size:              0 bytes\n"
    837         "      Hash Algorithm:        sha1\n"
    838         "      Partition Name:        foobar\n"
    839         "      Salt:                  d00df00d\n"
    840         "      Root Digest:           "
    841         "e811611467dcd6e8dc4324e45f706c2bdd51db67\n",
    842         InfoImage(ext_vbmeta_path));
    843   }
    844 
    845   if (sparse_image) {
    846     EXPECT_COMMAND(0,
    847                    "mv %s %s.sparse",
    848                    rootfs_path.value().c_str(),
    849                    rootfs_path.value().c_str());
    850     EXPECT_COMMAND(0,
    851                    "simg2img %s.sparse %s",
    852                    rootfs_path.value().c_str(),
    853                    rootfs_path.value().c_str());
    854     EXPECT_COMMAND(0, "rm -f %s.sparse", rootfs_path.value().c_str());
    855   }
    856 
    857   // To check that we generate the correct hashtree we can use
    858   // veritysetup(1) - another codebase for working with dm-verity
    859   // hashtrees - to verify it.
    860   //
    861   // If we don't want to impose the requirement of having the
    862   // veritysetup(1) command available on builders we can comment this
    863   // out.
    864   EXPECT_COMMAND(0,
    865                  "veritysetup --no-superblock --format=1 --hash=sha1 "
    866                  "--data-block-size=4096 --hash-block-size=4096 "
    867                  "--salt=d00df00d "
    868                  "--data-blocks=257 "
    869                  "--hash-offset=1052672 "
    870                  "verify "
    871                  "%s %s "
    872                  "e811611467dcd6e8dc4324e45f706c2bdd51db67",
    873                  rootfs_path.value().c_str(),
    874                  rootfs_path.value().c_str());
    875 
    876   // Now check that we can find the VBMeta block again from the footer.
    877   std::string part_data;
    878   ASSERT_TRUE(base::ReadFileToString(rootfs_path, &part_data));
    879 
    880   // Check footer contains correct data.
    881   AvbFooter f;
    882   EXPECT_NE(0,
    883             avb_footer_validate_and_byteswap(
    884                 reinterpret_cast<const AvbFooter*>(
    885                     part_data.data() + part_data.size() - AVB_FOOTER_SIZE),
    886                 &f));
    887   EXPECT_EQ(
    888       std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
    889       AVB_FOOTER_MAGIC);
    890   EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
    891   EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
    892   EXPECT_EQ(1052672UL, f.original_image_size);
    893   EXPECT_EQ(1069056UL, f.vbmeta_offset);
    894   EXPECT_EQ(1344UL, f.vbmeta_size);
    895 
    896   // Check that the vbmeta image at |f.vbmeta_offset| checks out.
    897   const uint8_t* vbmeta_data =
    898       reinterpret_cast<const uint8_t*>(part_data.data() + f.vbmeta_offset);
    899   EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
    900             avb_vbmeta_image_verify(vbmeta_data, f.vbmeta_size, NULL, NULL));
    901 
    902   // Collect all descriptors.
    903   std::vector<const AvbDescriptor*> descriptors;
    904   avb_descriptor_foreach(
    905       vbmeta_data, f.vbmeta_size, collect_descriptors, &descriptors);
    906 
    907   // We should only have a single descriptor and it should be a
    908   // hashtree descriptor.
    909   EXPECT_EQ(1UL, descriptors.size());
    910   EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASHTREE, avb_be64toh(descriptors[0]->tag));
    911   AvbHashtreeDescriptor d;
    912   EXPECT_NE(
    913       0,
    914       avb_hashtree_descriptor_validate_and_byteswap(
    915           reinterpret_cast<const AvbHashtreeDescriptor*>(descriptors[0]), &d));
    916   EXPECT_EQ(1UL, d.dm_verity_version);
    917   EXPECT_EQ(1052672UL, d.image_size);
    918   EXPECT_EQ(1052672UL, d.tree_offset);
    919   EXPECT_EQ(16384UL, d.tree_size);
    920   EXPECT_EQ(4096UL, d.data_block_size);
    921   EXPECT_EQ(4096UL, d.hash_block_size);
    922   EXPECT_EQ(6UL, d.partition_name_len);
    923   EXPECT_EQ(4UL, d.salt_len);
    924   EXPECT_EQ(20UL, d.root_digest_len);
    925   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
    926                             sizeof(AvbHashtreeDescriptor);
    927   uint64_t o = 0;
    928   EXPECT_EQ("foobar",
    929             std::string(reinterpret_cast<const char*>(desc_end + o),
    930                         d.partition_name_len));
    931   o += d.partition_name_len;
    932   EXPECT_EQ("d00df00d", mem_to_hexstring(desc_end + o, d.salt_len));
    933   o += d.salt_len;
    934   EXPECT_EQ("e811611467dcd6e8dc4324e45f706c2bdd51db67",
    935             mem_to_hexstring(desc_end + o, d.root_digest_len));
    936 
    937   // Check that we correctly generate dm-verity kernel cmdline
    938   // snippets, if requested.
    939   base::FilePath vbmeta_dmv_path = testdir_.Append("vbmeta_dm_verity_desc.bin");
    940   EXPECT_COMMAND(0,
    941                  "./avbtool make_vbmeta_image "
    942                  "--output %s "
    943                  "--setup_rootfs_from_kernel %s "
    944                  "--algorithm SHA256_RSA2048 "
    945                  "--key test/data/testkey_rsa2048.pem "
    946                  "--internal_release_string \"\"",
    947                  vbmeta_dmv_path.value().c_str(),
    948                  rootfs_path.value().c_str());
    949 
    950   ASSERT_EQ(
    951       "Minimum libavb version:   1.0\n"
    952       "Header Block:             256 bytes\n"
    953       "Authentication Block:     320 bytes\n"
    954       "Auxiliary Block:          896 bytes\n"
    955       "Algorithm:                SHA256_RSA2048\n"
    956       "Rollback Index:           0\n"
    957       "Flags:                    0\n"
    958       "Release String:           ''\n"
    959       "Descriptors:\n"
    960       "    Kernel Cmdline descriptor:\n"
    961       "      Flags:                 1\n"
    962       "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity 1 "
    963       "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
    964       "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
    965       "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
    966       "    Kernel Cmdline descriptor:\n"
    967       "      Flags:                 2\n"
    968       "      Kernel Cmdline:        "
    969       "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n",
    970       InfoImage(vbmeta_dmv_path));
    971 
    972   // Check that the footer is correctly erased and the hashtree
    973   // remains - see above for why the constant 1069056 is used.
    974   EXPECT_COMMAND(0,
    975                  "./avbtool erase_footer --image %s --keep_hashtree",
    976                  rootfs_path.value().c_str());
    977   int64_t erased_footer_file_size;
    978   ASSERT_TRUE(base::GetFileSize(rootfs_path, &erased_footer_file_size));
    979   EXPECT_EQ(static_cast<size_t>(erased_footer_file_size), 1069056UL);
    980 
    981   // Check that --do_not_append_vbmeta_image works as intended.
    982   //
    983   // For this we need to reset the size of the image to the original
    984   // size because it's not possible to identify the existing hashtree.
    985   EXPECT_COMMAND(
    986       0, "truncate -s %d %s", (int)rootfs_size, rootfs_path.value().c_str());
    987   EXPECT_COMMAND(0,
    988                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
    989                  "--partition_size %d --partition_name foobar "
    990                  "--algorithm SHA256_RSA2048 "
    991                  "--key test/data/testkey_rsa2048.pem "
    992                  "--output_vbmeta %s_2nd_run --do_not_append_vbmeta_image "
    993                  "--internal_release_string \"\" "
    994                  "--do_not_generate_fec",
    995                  rootfs_path.value().c_str(),
    996                  (int)partition_size,
    997                  ext_vbmeta_path.value().c_str());
    998   int64_t file_size;
    999   ASSERT_TRUE(base::GetFileSize(rootfs_path, &file_size));
   1000   EXPECT_EQ(static_cast<size_t>(file_size), 1069056UL);
   1001   EXPECT_COMMAND(0,
   1002                  "diff %s %s_2nd_run",
   1003                  ext_vbmeta_path.value().c_str(),
   1004                  ext_vbmeta_path.value().c_str());
   1005 }
   1006 
   1007 TEST_F(AvbToolTest, AddHashtreeFooter) {
   1008   AddHashtreeFooterTest(false);
   1009 }
   1010 
   1011 TEST_F(AvbToolTest, AddHashtreeFooterSparse) {
   1012   AddHashtreeFooterTest(true);
   1013 }
   1014 
   1015 void AvbToolTest::AddHashtreeFooterFECTest(bool sparse_image) {
   1016   const size_t rootfs_size = 1028 * 1024;
   1017   const size_t partition_size = 1536 * 1024;
   1018 
   1019   // Generate a 1028 KiB file with known content.
   1020   std::vector<uint8_t> rootfs;
   1021   rootfs.resize(rootfs_size);
   1022   for (size_t n = 0; n < rootfs_size; n++)
   1023     rootfs[n] = uint8_t(n);
   1024   base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
   1025   EXPECT_EQ(rootfs_size,
   1026             static_cast<const size_t>(
   1027                 base::WriteFile(rootfs_path,
   1028                                 reinterpret_cast<const char*>(rootfs.data()),
   1029                                 rootfs.size())));
   1030 
   1031   if (sparse_image) {
   1032     EXPECT_COMMAND(0,
   1033                    "mv %s %s.unsparse",
   1034                    rootfs_path.value().c_str(),
   1035                    rootfs_path.value().c_str());
   1036     EXPECT_COMMAND(0,
   1037                    "img2simg %s.unsparse %s",
   1038                    rootfs_path.value().c_str(),
   1039                    rootfs_path.value().c_str());
   1040     EXPECT_COMMAND(0, "rm -f %s.unsparse", rootfs_path.value().c_str());
   1041   }
   1042 
   1043   /* Do this twice to check that 'add_hashtree_footer' is idempotent. */
   1044   for (int n = 0; n < 2; n++) {
   1045     EXPECT_COMMAND(0,
   1046                    "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   1047                    "--partition_size %d --partition_name foobar "
   1048                    "--algorithm SHA256_RSA2048 "
   1049                    "--key test/data/testkey_rsa2048.pem "
   1050                    "--internal_release_string \"\"",
   1051                    rootfs_path.value().c_str(),
   1052                    (int)partition_size);
   1053 
   1054     ASSERT_EQ(base::StringPrintf("Footer version:           1.0\n"
   1055                                  "Image size:               1572864 bytes\n"
   1056                                  "Original image size:      1052672 bytes\n"
   1057                                  "VBMeta offset:            1085440\n"
   1058                                  "VBMeta size:              1344 bytes\n"
   1059                                  "--\n"
   1060                                  "Minimum libavb version:   1.0%s\n"
   1061                                  "Header Block:             256 bytes\n"
   1062                                  "Authentication Block:     320 bytes\n"
   1063                                  "Auxiliary Block:          768 bytes\n"
   1064                                  "Algorithm:                SHA256_RSA2048\n"
   1065                                  "Rollback Index:           0\n"
   1066                                  "Flags:                    0\n"
   1067                                  "Release String:           ''\n"
   1068                                  "Descriptors:\n"
   1069                                  "    Hashtree descriptor:\n"
   1070                                  "      Version of dm-verity:  1\n"
   1071                                  "      Image Size:            1052672 bytes\n"
   1072                                  "      Tree Offset:           1052672\n"
   1073                                  "      Tree Size:             16384 bytes\n"
   1074                                  "      Data Block Size:       4096 bytes\n"
   1075                                  "      Hash Block Size:       4096 bytes\n"
   1076                                  "      FEC num roots:         2\n"
   1077                                  "      FEC offset:            1069056\n"
   1078                                  "      FEC size:              16384 bytes\n"
   1079                                  "      Hash Algorithm:        sha1\n"
   1080                                  "      Partition Name:        foobar\n"
   1081                                  "      Salt:                  d00df00d\n"
   1082                                  "      Root Digest:           "
   1083                                  "e811611467dcd6e8dc4324e45f706c2bdd51db67\n",
   1084                                  sparse_image ? " (Sparse)" : ""),
   1085               InfoImage(rootfs_path));
   1086   }
   1087 
   1088   if (sparse_image) {
   1089     EXPECT_COMMAND(0,
   1090                    "mv %s %s.sparse",
   1091                    rootfs_path.value().c_str(),
   1092                    rootfs_path.value().c_str());
   1093     EXPECT_COMMAND(0,
   1094                    "simg2img %s.sparse %s",
   1095                    rootfs_path.value().c_str(),
   1096                    rootfs_path.value().c_str());
   1097     EXPECT_COMMAND(0, "rm -f %s.sparse", rootfs_path.value().c_str());
   1098   }
   1099 
   1100   /* TODO: would be nice to verify that the FEC data is correct. */
   1101 
   1102   // Now check that we can find the VBMeta block again from the footer.
   1103   std::string part_data;
   1104   ASSERT_TRUE(base::ReadFileToString(rootfs_path, &part_data));
   1105 
   1106   // Check footer contains correct data.
   1107   AvbFooter f;
   1108   EXPECT_NE(0,
   1109             avb_footer_validate_and_byteswap(
   1110                 reinterpret_cast<const AvbFooter*>(
   1111                     part_data.data() + part_data.size() - AVB_FOOTER_SIZE),
   1112                 &f));
   1113   EXPECT_EQ(
   1114       std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
   1115       AVB_FOOTER_MAGIC);
   1116   EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
   1117   EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
   1118   EXPECT_EQ(1052672UL, f.original_image_size);
   1119   EXPECT_EQ(1085440UL, f.vbmeta_offset);
   1120   EXPECT_EQ(1344UL, f.vbmeta_size);
   1121 
   1122   // Check that the vbmeta image at |f.vbmeta_offset| checks out.
   1123   const uint8_t* vbmeta_data =
   1124       reinterpret_cast<const uint8_t*>(part_data.data() + f.vbmeta_offset);
   1125   EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
   1126             avb_vbmeta_image_verify(vbmeta_data, f.vbmeta_size, NULL, NULL));
   1127 
   1128   // Collect all descriptors.
   1129   std::vector<const AvbDescriptor*> descriptors;
   1130   avb_descriptor_foreach(
   1131       vbmeta_data, f.vbmeta_size, collect_descriptors, &descriptors);
   1132 
   1133   // We should only have a single descriptor and it should be a
   1134   // hashtree descriptor.
   1135   EXPECT_EQ(1UL, descriptors.size());
   1136   EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASHTREE, avb_be64toh(descriptors[0]->tag));
   1137   AvbHashtreeDescriptor d;
   1138   EXPECT_NE(
   1139       0,
   1140       avb_hashtree_descriptor_validate_and_byteswap(
   1141           reinterpret_cast<const AvbHashtreeDescriptor*>(descriptors[0]), &d));
   1142   EXPECT_EQ(1UL, d.dm_verity_version);
   1143   EXPECT_EQ(1052672UL, d.image_size);
   1144   EXPECT_EQ(1052672UL, d.tree_offset);
   1145   EXPECT_EQ(16384UL, d.tree_size);
   1146   EXPECT_EQ(4096UL, d.data_block_size);
   1147   EXPECT_EQ(2UL, d.fec_num_roots);
   1148   EXPECT_EQ(1069056UL, d.fec_offset);
   1149   EXPECT_EQ(16384UL, d.fec_size);
   1150   EXPECT_EQ(6UL, d.partition_name_len);
   1151   EXPECT_EQ(4UL, d.salt_len);
   1152   EXPECT_EQ(20UL, d.root_digest_len);
   1153   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
   1154                             sizeof(AvbHashtreeDescriptor);
   1155   uint64_t o = 0;
   1156   EXPECT_EQ("foobar",
   1157             std::string(reinterpret_cast<const char*>(desc_end + o),
   1158                         d.partition_name_len));
   1159   o += d.partition_name_len;
   1160   EXPECT_EQ("d00df00d", mem_to_hexstring(desc_end + o, d.salt_len));
   1161   o += d.salt_len;
   1162   EXPECT_EQ("e811611467dcd6e8dc4324e45f706c2bdd51db67",
   1163             mem_to_hexstring(desc_end + o, d.root_digest_len));
   1164 
   1165   // Check that we correctly generate dm-verity kernel cmdline
   1166   // snippets, if requested.
   1167   base::FilePath vbmeta_dmv_path = testdir_.Append("vbmeta_dm_verity_desc.bin");
   1168   EXPECT_COMMAND(0,
   1169                  "./avbtool make_vbmeta_image "
   1170                  "--output %s "
   1171                  "--setup_rootfs_from_kernel %s "
   1172                  "--algorithm SHA256_RSA2048 "
   1173                  "--key test/data/testkey_rsa2048.pem "
   1174                  "--internal_release_string \"\"",
   1175                  vbmeta_dmv_path.value().c_str(),
   1176                  rootfs_path.value().c_str());
   1177 
   1178   ASSERT_EQ(
   1179       "Minimum libavb version:   1.0\n"
   1180       "Header Block:             256 bytes\n"
   1181       "Authentication Block:     320 bytes\n"
   1182       "Auxiliary Block:          960 bytes\n"
   1183       "Algorithm:                SHA256_RSA2048\n"
   1184       "Rollback Index:           0\n"
   1185       "Flags:                    0\n"
   1186       "Release String:           ''\n"
   1187       "Descriptors:\n"
   1188       "    Kernel Cmdline descriptor:\n"
   1189       "      Flags:                 1\n"
   1190       "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity 1 "
   1191       "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
   1192       "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
   1193       "d00df00d 10 $(ANDROID_VERITY_MODE) ignore_zero_blocks "
   1194       "use_fec_from_device "
   1195       "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) fec_roots 2 fec_blocks 261 "
   1196       "fec_start 261\" root=/dev/dm-0'\n"
   1197       "    Kernel Cmdline descriptor:\n"
   1198       "      Flags:                 2\n"
   1199       "      Kernel Cmdline:        "
   1200       "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n",
   1201       InfoImage(vbmeta_dmv_path));
   1202 
   1203   // Check that the footer is correctly erased and the hashtree and
   1204   // FEC data remains. The constant 1085440 is used because it's where
   1205   // the FEC data ends (it's at offset 1069056 and size 16384).
   1206   EXPECT_COMMAND(0,
   1207                  "./avbtool erase_footer --image %s --keep_hashtree",
   1208                  rootfs_path.value().c_str());
   1209   int64_t erased_footer_file_size;
   1210   ASSERT_TRUE(base::GetFileSize(rootfs_path, &erased_footer_file_size));
   1211   EXPECT_EQ(static_cast<size_t>(erased_footer_file_size), 1085440UL);
   1212 }
   1213 
   1214 TEST_F(AvbToolTest, AddHashtreeFooterFEC) {
   1215   AddHashtreeFooterFECTest(false);
   1216 }
   1217 
   1218 TEST_F(AvbToolTest, AddHashtreeFooterFECSparse) {
   1219   AddHashtreeFooterFECTest(true);
   1220 }
   1221 
   1222 TEST_F(AvbToolTest, AddHashtreeFooterCalcMaxImageSize) {
   1223   const size_t partition_size = 10 * 1024 * 1024;
   1224   base::FilePath output_path = testdir_.Append("max_size.txt");
   1225 
   1226   EXPECT_COMMAND(0,
   1227                  "./avbtool add_hashtree_footer "
   1228                  "--partition_size %zd --calc_max_image_size "
   1229                  "--do_not_generate_fec > %s",
   1230                  partition_size,
   1231                  output_path.value().c_str());
   1232   std::string max_image_size_data;
   1233   EXPECT_TRUE(base::ReadFileToString(output_path, &max_image_size_data));
   1234   EXPECT_EQ("10330112\n", max_image_size_data);
   1235   size_t max_image_size = atoll(max_image_size_data.c_str());
   1236 
   1237   // Hashtree and metadata takes up 152 KiB - compare to below with
   1238   // FEC which is 244 KiB.
   1239   EXPECT_EQ(152 * 1024ULL, partition_size - max_image_size);
   1240 
   1241   // Check that we can add a hashtree with an image this size for such
   1242   // a partition size.
   1243   base::FilePath system_path = GenerateImage("system", max_image_size);
   1244   EXPECT_COMMAND(0,
   1245                  "./avbtool add_hashtree_footer"
   1246                  " --image %s"
   1247                  " --partition_name system"
   1248                  " --partition_size %zd"
   1249                  " --salt deadbeef"
   1250                  " --algorithm SHA512_RSA4096 "
   1251                  " --key test/data/testkey_rsa4096.pem"
   1252                  " --internal_release_string \"\" "
   1253                  "--do_not_generate_fec",
   1254                  system_path.value().c_str(),
   1255                  partition_size);
   1256 }
   1257 
   1258 TEST_F(AvbToolTest, AddHashtreeFooterCalcMaxImageSizeWithFEC) {
   1259   const size_t partition_size = 10 * 1024 * 1024;
   1260   base::FilePath output_path = testdir_.Append("max_size.txt");
   1261 
   1262   EXPECT_COMMAND(0,
   1263                  "./avbtool add_hashtree_footer "
   1264                  "--partition_size %zd --calc_max_image_size > %s",
   1265                  partition_size,
   1266                  output_path.value().c_str());
   1267   std::string max_image_size_data;
   1268   EXPECT_TRUE(base::ReadFileToString(output_path, &max_image_size_data));
   1269   EXPECT_EQ("10235904\n", max_image_size_data);
   1270   size_t max_image_size = atoll(max_image_size_data.c_str());
   1271 
   1272   // Hashtree, FEC codes, and metadata takes up 244 KiB - compare to
   1273   // above wihtout FEC which is 152 KiB.
   1274   EXPECT_EQ(244 * 1024ULL, partition_size - max_image_size);
   1275 
   1276   // Check that we can add a hashtree with an image this size for such
   1277   // a partition size.
   1278   base::FilePath system_path = GenerateImage("system", max_image_size);
   1279   EXPECT_COMMAND(0,
   1280                  "./avbtool add_hashtree_footer"
   1281                  " --image %s"
   1282                  " --partition_name system"
   1283                  " --partition_size %zd"
   1284                  " --salt deadbeef"
   1285                  " --algorithm SHA512_RSA4096 "
   1286                  " --key test/data/testkey_rsa4096.pem"
   1287                  " --internal_release_string \"\"",
   1288                  system_path.value().c_str(),
   1289                  partition_size);
   1290 }
   1291 
   1292 TEST_F(AvbToolTest, KernelCmdlineDescriptor) {
   1293   base::FilePath vbmeta_path =
   1294       testdir_.Append("vbmeta_kernel_cmdline_desc.bin");
   1295 
   1296   EXPECT_COMMAND(0,
   1297                  "./avbtool make_vbmeta_image "
   1298                  "--output %s "
   1299                  "--kernel_cmdline 'foo bar baz' "
   1300                  "--kernel_cmdline 'second cmdline' "
   1301                  "--algorithm SHA256_RSA2048 "
   1302                  "--key test/data/testkey_rsa2048.pem "
   1303                  "--internal_release_string \"\"",
   1304                  vbmeta_path.value().c_str());
   1305 
   1306   ASSERT_EQ(
   1307       "Minimum libavb version:   1.0\n"
   1308       "Header Block:             256 bytes\n"
   1309       "Authentication Block:     320 bytes\n"
   1310       "Auxiliary Block:          640 bytes\n"
   1311       "Algorithm:                SHA256_RSA2048\n"
   1312       "Rollback Index:           0\n"
   1313       "Flags:                    0\n"
   1314       "Release String:           ''\n"
   1315       "Descriptors:\n"
   1316       "    Kernel Cmdline descriptor:\n"
   1317       "      Flags:                 0\n"
   1318       "      Kernel Cmdline:        'foo bar baz'\n"
   1319       "    Kernel Cmdline descriptor:\n"
   1320       "      Flags:                 0\n"
   1321       "      Kernel Cmdline:        'second cmdline'\n",
   1322       InfoImage(vbmeta_path));
   1323 
   1324   // Now check the VBMeta image.
   1325   std::string image_data;
   1326   ASSERT_TRUE(base::ReadFileToString(vbmeta_path, &image_data));
   1327 
   1328   const uint8_t* vbmeta_data =
   1329       reinterpret_cast<const uint8_t*>(image_data.data());
   1330   const size_t vbmeta_size = image_data.length();
   1331   EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
   1332             avb_vbmeta_image_verify(vbmeta_data, vbmeta_size, NULL, NULL));
   1333 
   1334   // Collect all descriptors.
   1335   std::vector<const AvbDescriptor*> descriptors;
   1336   avb_descriptor_foreach(
   1337       vbmeta_data, vbmeta_size, collect_descriptors, &descriptors);
   1338 
   1339   // We should have two descriptors - check them.
   1340   EXPECT_EQ(2UL, descriptors.size());
   1341   AvbKernelCmdlineDescriptor d;
   1342   EXPECT_EQ(AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE,
   1343             avb_be64toh(descriptors[0]->tag));
   1344   EXPECT_NE(
   1345       0,
   1346       avb_kernel_cmdline_descriptor_validate_and_byteswap(
   1347           reinterpret_cast<const AvbKernelCmdlineDescriptor*>(descriptors[0]),
   1348           &d));
   1349   EXPECT_EQ("foo bar baz",
   1350             std::string(reinterpret_cast<const char*>(descriptors[0]) +
   1351                             sizeof(AvbKernelCmdlineDescriptor),
   1352                         d.kernel_cmdline_length));
   1353   EXPECT_EQ(AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE,
   1354             avb_be64toh(descriptors[1]->tag));
   1355   EXPECT_NE(
   1356       0,
   1357       avb_kernel_cmdline_descriptor_validate_and_byteswap(
   1358           reinterpret_cast<const AvbKernelCmdlineDescriptor*>(descriptors[1]),
   1359           &d));
   1360   EXPECT_EQ("second cmdline",
   1361             std::string(reinterpret_cast<const char*>(descriptors[1]) +
   1362                             sizeof(AvbKernelCmdlineDescriptor),
   1363                         d.kernel_cmdline_length));
   1364 }
   1365 
   1366 TEST_F(AvbToolTest, IncludeDescriptor) {
   1367   base::FilePath vbmeta1_path = testdir_.Append("vbmeta_id1.bin");
   1368   base::FilePath vbmeta2_path = testdir_.Append("vbmeta_id2.bin");
   1369   base::FilePath vbmeta3_path = testdir_.Append("vbmeta_id3.bin");
   1370 
   1371   EXPECT_COMMAND(0,
   1372                  "./avbtool make_vbmeta_image "
   1373                  "--output %s "
   1374                  "--kernel_cmdline 'something' "
   1375                  "--prop name:value "
   1376                  "--internal_release_string \"\"",
   1377                  vbmeta1_path.value().c_str());
   1378 
   1379   EXPECT_COMMAND(0,
   1380                  "./avbtool make_vbmeta_image "
   1381                  "--output %s "
   1382                  "--prop name2:value2 "
   1383                  "--prop name3:value3 "
   1384                  "--internal_release_string \"\"",
   1385                  vbmeta2_path.value().c_str());
   1386 
   1387   EXPECT_COMMAND(0,
   1388                  "./avbtool make_vbmeta_image "
   1389                  "--output %s "
   1390                  "--prop name4:value4 "
   1391                  "--include_descriptors_from_image %s "
   1392                  "--include_descriptors_from_image %s "
   1393                  "--internal_release_string \"\"",
   1394                  vbmeta3_path.value().c_str(),
   1395                  vbmeta1_path.value().c_str(),
   1396                  vbmeta2_path.value().c_str());
   1397 
   1398   ASSERT_EQ(
   1399       "Minimum libavb version:   1.0\n"
   1400       "Header Block:             256 bytes\n"
   1401       "Authentication Block:     0 bytes\n"
   1402       "Auxiliary Block:          256 bytes\n"
   1403       "Algorithm:                NONE\n"
   1404       "Rollback Index:           0\n"
   1405       "Flags:                    0\n"
   1406       "Release String:           ''\n"
   1407       "Descriptors:\n"
   1408       "    Prop: name4 -> 'value4'\n"
   1409       "    Prop: name -> 'value'\n"
   1410       "    Kernel Cmdline descriptor:\n"
   1411       "      Flags:                 0\n"
   1412       "      Kernel Cmdline:        'something'\n"
   1413       "    Prop: name2 -> 'value2'\n"
   1414       "    Prop: name3 -> 'value3'\n",
   1415       InfoImage(vbmeta3_path));
   1416 }
   1417 
   1418 TEST_F(AvbToolTest, ChainedPartition) {
   1419   base::FilePath vbmeta_path = testdir_.Append("vbmeta_cp.bin");
   1420 
   1421   base::FilePath pk_path = testdir_.Append("testkey_rsa2048.avbpubkey");
   1422 
   1423   EXPECT_COMMAND(
   1424       0,
   1425       "./avbtool extract_public_key --key test/data/testkey_rsa2048.pem"
   1426       " --output %s",
   1427       pk_path.value().c_str());
   1428 
   1429   EXPECT_COMMAND(
   1430       0,
   1431       "./avbtool make_vbmeta_image "
   1432       "--output %s "
   1433       "--chain_partition system:1:%s "
   1434       "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
   1435       "--internal_release_string \"\"",
   1436       vbmeta_path.value().c_str(),
   1437       pk_path.value().c_str());
   1438 
   1439   ASSERT_EQ(
   1440       "Minimum libavb version:   1.0\n"
   1441       "Header Block:             256 bytes\n"
   1442       "Authentication Block:     320 bytes\n"
   1443       "Auxiliary Block:          1152 bytes\n"
   1444       "Algorithm:                SHA256_RSA2048\n"
   1445       "Rollback Index:           0\n"
   1446       "Flags:                    0\n"
   1447       "Release String:           ''\n"
   1448       "Descriptors:\n"
   1449       "    Chain Partition descriptor:\n"
   1450       "      Partition Name:          system\n"
   1451       "      Rollback Index Location: 1\n"
   1452       "      Public key (sha1):       "
   1453       "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n",
   1454       InfoImage(vbmeta_path));
   1455 
   1456   // Now check the VBMeta image.
   1457   std::string image_data;
   1458   ASSERT_TRUE(base::ReadFileToString(vbmeta_path, &image_data));
   1459 
   1460   const uint8_t* vbmeta_data =
   1461       reinterpret_cast<const uint8_t*>(image_data.data());
   1462   const size_t vbmeta_size = image_data.length();
   1463   EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
   1464             avb_vbmeta_image_verify(vbmeta_data, vbmeta_size, NULL, NULL));
   1465 
   1466   // Collect all descriptors.
   1467   std::vector<const AvbDescriptor*> descriptors;
   1468   avb_descriptor_foreach(
   1469       vbmeta_data, vbmeta_size, collect_descriptors, &descriptors);
   1470 
   1471   // We should have one descriptor - check it.
   1472   EXPECT_EQ(1UL, descriptors.size());
   1473 
   1474   std::string pk_data;
   1475   ASSERT_TRUE(base::ReadFileToString(pk_path, &pk_data));
   1476 
   1477   AvbChainPartitionDescriptor d;
   1478   EXPECT_EQ(AVB_DESCRIPTOR_TAG_CHAIN_PARTITION,
   1479             avb_be64toh(descriptors[0]->tag));
   1480   EXPECT_NE(
   1481       0,
   1482       avb_chain_partition_descriptor_validate_and_byteswap(
   1483           reinterpret_cast<const AvbChainPartitionDescriptor*>(descriptors[0]),
   1484           &d));
   1485   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
   1486                             sizeof(AvbChainPartitionDescriptor);
   1487   uint64_t o = 0;
   1488   EXPECT_EQ("system",
   1489             std::string(reinterpret_cast<const char*>(desc_end + o),
   1490                         d.partition_name_len));
   1491   o += d.partition_name_len;
   1492   EXPECT_EQ(pk_data,
   1493             std::string(reinterpret_cast<const char*>(descriptors[0]) +
   1494                             sizeof(AvbChainPartitionDescriptor) + o,
   1495                         d.public_key_len));
   1496 }
   1497 
   1498 TEST_F(AvbToolTest, ChainedPartitionNoLocationCollision) {
   1499   base::FilePath vbmeta_path = testdir_.Append("vbmeta_cp.bin");
   1500 
   1501   base::FilePath pk_path = testdir_.Append("testkey_rsa2048.avbpubkey");
   1502 
   1503   EXPECT_COMMAND(
   1504       0,
   1505       "./avbtool extract_public_key --key test/data/testkey_rsa2048.pem"
   1506       " --output %s",
   1507       pk_path.value().c_str());
   1508 
   1509   // Check that avbtool bails if the same Rollback Index Location is
   1510   // used for multiple chained partitions.
   1511   EXPECT_COMMAND(
   1512       1,
   1513       "./avbtool make_vbmeta_image "
   1514       "--output %s "
   1515       "--chain_partition system:1:%s "
   1516       "--chain_partition other:1:%s "
   1517       "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
   1518       "--internal_release_string \"\"",
   1519       vbmeta_path.value().c_str(),
   1520       pk_path.value().c_str(),
   1521       pk_path.value().c_str());
   1522 }
   1523 
   1524 TEST_F(AvbToolTest, AppendVBMetaImage) {
   1525   size_t boot_size = 5 * 1024 * 1024;
   1526   size_t boot_partition_size = 32 * 1024 * 1024;
   1527   base::FilePath boot_path = GenerateImage("boot", boot_size);
   1528 
   1529   GenerateVBMetaImage("vbmeta.img",
   1530                       "SHA256_RSA2048",
   1531                       0,
   1532                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1533                       std::string("--append_to_release_string \"\" "
   1534                                   "--kernel_cmdline foo"));
   1535 
   1536   EXPECT_COMMAND(0,
   1537                  "./avbtool append_vbmeta_image "
   1538                  "--image %s "
   1539                  "--partition_size %d "
   1540                  "--vbmeta_image %s ",
   1541                  boot_path.value().c_str(),
   1542                  (int)boot_partition_size,
   1543                  vbmeta_image_path_.value().c_str());
   1544 
   1545   std::string vbmeta_contents = InfoImage(vbmeta_image_path_);
   1546   std::string boot_contents = InfoImage(boot_path);
   1547 
   1548   // Check that boot.img has the same vbmeta blob as from vbmeta.img -
   1549   // we do this by inspecting 'avbtool info_image' output combined
   1550   // with the known footer location given boot.img has 5 MiB known
   1551   // content and the partition size is 32 MiB.
   1552   ASSERT_EQ(
   1553       "Minimum libavb version:   1.0\n"
   1554       "Header Block:             256 bytes\n"
   1555       "Authentication Block:     320 bytes\n"
   1556       "Auxiliary Block:          576 bytes\n"
   1557       "Algorithm:                SHA256_RSA2048\n"
   1558       "Rollback Index:           0\n"
   1559       "Flags:                    0\n"
   1560       "Release String:           'avbtool 1.0.0 '\n"
   1561       "Descriptors:\n"
   1562       "    Kernel Cmdline descriptor:\n"
   1563       "      Flags:                 0\n"
   1564       "      Kernel Cmdline:        'foo'\n",
   1565       vbmeta_contents);
   1566   std::string known_footer =
   1567       "Footer version:           1.0\n"
   1568       "Image size:               33554432 bytes\n"
   1569       "Original image size:      5242880 bytes\n"
   1570       "VBMeta offset:            5242880\n"
   1571       "VBMeta size:              1152 bytes\n"
   1572       "--\n";
   1573   ASSERT_EQ(known_footer + vbmeta_contents, boot_contents);
   1574 
   1575   // Also verify that the blobs are the same, bit for bit.
   1576   base::File f =
   1577       base::File(boot_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
   1578   std::vector<uint8_t> loaded_vbmeta;
   1579   loaded_vbmeta.resize(1152);
   1580   EXPECT_EQ(
   1581       f.Read(
   1582           5 * 1024 * 1024, reinterpret_cast<char*>(loaded_vbmeta.data()), 1152),
   1583       1152);
   1584   EXPECT_EQ(vbmeta_image_, loaded_vbmeta);
   1585 }
   1586 
   1587 TEST_F(AvbToolTest, SigningHelperBasic) {
   1588   base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
   1589   base::FilePath signing_helper_test_path =
   1590       testdir_.Append("signing_helper_test");
   1591   EXPECT_COMMAND(
   1592       0,
   1593       "SIGNING_HELPER_TEST=\"%s\" ./avbtool make_vbmeta_image "
   1594       "--output %s "
   1595       "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
   1596       "--signing_helper test/avbtool_signing_helper_test.py "
   1597       "--internal_release_string \"\"",
   1598       signing_helper_test_path.value().c_str(),
   1599       vbmeta_path.value().c_str());
   1600 
   1601   // Now check the value in test file.
   1602   std::string value;
   1603   ASSERT_TRUE(base::ReadFileToString(signing_helper_test_path, &value));
   1604   EXPECT_EQ("DONE", value);
   1605 }
   1606 
   1607 TEST_F(AvbToolTest, SigningHelperWithFilesBasic) {
   1608   base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
   1609   base::FilePath signing_helper_test_path =
   1610       testdir_.Append("signing_helper_test");
   1611   EXPECT_COMMAND(
   1612       0,
   1613       "SIGNING_HELPER_TEST=\"%s\" ./avbtool make_vbmeta_image "
   1614       "--output %s "
   1615       "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
   1616       "--signing_helper_with_files "
   1617       "test/avbtool_signing_helper_with_files_test.py "
   1618       "--internal_release_string \"\"",
   1619       signing_helper_test_path.value().c_str(),
   1620       vbmeta_path.value().c_str());
   1621 
   1622   // Now check the value in test file.
   1623   std::string value;
   1624   ASSERT_TRUE(base::ReadFileToString(signing_helper_test_path, &value));
   1625   EXPECT_EQ("DONE", value);
   1626 }
   1627 
   1628 TEST_F(AvbToolTest, SigningHelperReturnError) {
   1629   base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
   1630   EXPECT_COMMAND(
   1631       1,
   1632       "./avbtool make_vbmeta_image "
   1633       "--output %s "
   1634       "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
   1635       "--signing_helper test/avbtool_signing_helper_test.py "
   1636       "--internal_release_string \"\"",
   1637       vbmeta_path.value().c_str());
   1638 }
   1639 
   1640 TEST_F(AvbToolTest, SigningHelperWithFilesReturnError) {
   1641   base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
   1642   EXPECT_COMMAND(
   1643       1,
   1644       "./avbtool make_vbmeta_image "
   1645       "--output %s "
   1646       "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
   1647       "--signing_helper_with_files "
   1648       "test/avbtool_signing_helper_with_files_test.py "
   1649       "--internal_release_string \"\"",
   1650       vbmeta_path.value().c_str());
   1651 }
   1652 
   1653 TEST_F(AvbToolTest, VerifyImageNoSignature) {
   1654   GenerateVBMetaImage("vbmeta.img",
   1655                       "",  // NONE
   1656                       0,
   1657                       base::FilePath());
   1658 
   1659   EXPECT_COMMAND(0,
   1660                  "./avbtool verify_image "
   1661                  "--image %s ",
   1662                  vbmeta_image_path_.value().c_str());
   1663 }
   1664 
   1665 TEST_F(AvbToolTest, VerifyImageValidSignature) {
   1666   GenerateVBMetaImage("vbmeta.img",
   1667                       "SHA256_RSA2048",
   1668                       0,
   1669                       base::FilePath("test/data/testkey_rsa2048.pem"));
   1670 
   1671   EXPECT_COMMAND(0,
   1672                  "./avbtool verify_image "
   1673                  "--image %s ",
   1674                  vbmeta_image_path_.value().c_str());
   1675 }
   1676 
   1677 TEST_F(AvbToolTest, VerifyImageCorruptedVBMeta) {
   1678   GenerateVBMetaImage("vbmeta.img",
   1679                       "SHA256_RSA2048",
   1680                       0,
   1681                       base::FilePath("test/data/testkey_rsa2048.pem"));
   1682 
   1683   // Corrupt four bytes of data in the end of the image. Since the aux
   1684   // data is at the end and this data is signed, this will change the
   1685   // value of the computed hash.
   1686   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
   1687   EXPECT_EQ(AVB_IO_RESULT_OK,
   1688             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
   1689                                                "vbmeta",
   1690                                                -4,  // offset from end
   1691                                                sizeof corrupt_data,
   1692                                                corrupt_data));
   1693 
   1694   EXPECT_COMMAND(1,
   1695                  "./avbtool verify_image "
   1696                  "--image %s ",
   1697                  vbmeta_image_path_.value().c_str());
   1698 }
   1699 
   1700 TEST_F(AvbToolTest, VerifyImageOtherKeyMatching) {
   1701   GenerateVBMetaImage("vbmeta.img",
   1702                       "SHA256_RSA2048",
   1703                       0,
   1704                       base::FilePath("test/data/testkey_rsa2048.pem"));
   1705 
   1706   EXPECT_COMMAND(0,
   1707                  "./avbtool verify_image "
   1708                  "--image %s --key test/data/testkey_rsa2048.pem",
   1709                  vbmeta_image_path_.value().c_str());
   1710 }
   1711 
   1712 TEST_F(AvbToolTest, VerifyImageOtherKeyNotMatching) {
   1713   GenerateVBMetaImage("vbmeta.img",
   1714                       "SHA256_RSA2048",
   1715                       0,
   1716                       base::FilePath("test/data/testkey_rsa2048.pem"));
   1717 
   1718   EXPECT_COMMAND(1,
   1719                  "./avbtool verify_image "
   1720                  "--image %s --key test/data/testkey_rsa4096.pem",
   1721                  vbmeta_image_path_.value().c_str());
   1722 }
   1723 
   1724 TEST_F(AvbToolTest, VerifyImageBrokenSignature) {
   1725   base::FilePath vbmeta_path = testdir_.Append("vbmeta.bin");
   1726   base::FilePath signing_helper_test_path =
   1727       testdir_.Append("signing_helper_test");
   1728 
   1729   // Intentionally make the signer generate a wrong signature.
   1730   EXPECT_COMMAND(
   1731       0,
   1732       "SIGNING_HELPER_GENERATE_WRONG_SIGNATURE=1 ./avbtool make_vbmeta_image "
   1733       "--output %s "
   1734       "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
   1735       "--signing_helper test/avbtool_signing_helper_test.py "
   1736       "--internal_release_string \"\"",
   1737       vbmeta_path.value().c_str());
   1738 
   1739   EXPECT_COMMAND(1,
   1740                  "./avbtool verify_image "
   1741                  "--image %s ",
   1742                  vbmeta_path.value().c_str());
   1743 }
   1744 
   1745 // Helper to generate boot.img, unsparse system.img, and vbmeta.img.
   1746 void AvbToolTest::GenerateImageWithHashAndHashtreeSetup() {
   1747   const size_t boot_partition_size = 16 * 1024 * 1024;
   1748   const size_t boot_image_size = 5 * 1024 * 1024;
   1749   base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
   1750   EXPECT_COMMAND(0,
   1751                  "./avbtool add_hash_footer"
   1752                  " --image %s"
   1753                  " --rollback_index 0"
   1754                  " --partition_name boot"
   1755                  " --partition_size %zd"
   1756                  " --salt deadbeef"
   1757                  " --internal_release_string \"\"",
   1758                  boot_path.value().c_str(),
   1759                  boot_partition_size);
   1760 
   1761   const size_t system_partition_size = 10 * 1024 * 1024;
   1762   const size_t system_image_size = 8 * 1024 * 1024;
   1763   base::FilePath system_path = GenerateImage("system.img", system_image_size);
   1764   EXPECT_COMMAND(0,
   1765                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   1766                  "--partition_size %zd --partition_name system "
   1767                  "--internal_release_string \"\" ",
   1768                  system_path.value().c_str(),
   1769                  system_partition_size);
   1770 
   1771   GenerateVBMetaImage("vbmeta.img",
   1772                       "SHA256_RSA2048",
   1773                       0,
   1774                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1775                       base::StringPrintf("--include_descriptors_from_image %s "
   1776                                          "--include_descriptors_from_image %s",
   1777                                          boot_path.value().c_str(),
   1778                                          system_path.value().c_str()));
   1779 }
   1780 
   1781 TEST_F(AvbToolTest, VerifyImageWithHashAndHashtree) {
   1782   GenerateImageWithHashAndHashtreeSetup();
   1783 
   1784   // Do two checks - one for system.img not sparse, and one where it
   1785   // is sparse.
   1786   for (int n = 0; n < 2; n++) {
   1787     EXPECT_COMMAND(0,
   1788                    "./avbtool verify_image "
   1789                    "--image %s ",
   1790                    vbmeta_image_path_.value().c_str());
   1791     if (n == 0) {
   1792       EXPECT_COMMAND(0,
   1793                      "img2simg %s %s.sparse",
   1794                      testdir_.Append("system.img").value().c_str(),
   1795                      testdir_.Append("system.img").value().c_str());
   1796       EXPECT_COMMAND(0,
   1797                      "mv %s.sparse %s",
   1798                      testdir_.Append("system.img").value().c_str(),
   1799                      testdir_.Append("system.img").value().c_str());
   1800     }
   1801   }
   1802 }
   1803 
   1804 TEST_F(AvbToolTest, VerifyImageWithHashAndHashtreeCorruptHash) {
   1805   GenerateImageWithHashAndHashtreeSetup();
   1806 
   1807   // Corrupt four bytes of data in the middle of boot.img.
   1808   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
   1809   EXPECT_EQ(AVB_IO_RESULT_OK,
   1810             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
   1811                                                "boot",
   1812                                                105 * 1024,  // offset from start
   1813                                                sizeof corrupt_data,
   1814                                                corrupt_data));
   1815 
   1816   EXPECT_COMMAND(1,
   1817                  "./avbtool verify_image "
   1818                  "--image %s ",
   1819                  vbmeta_image_path_.value().c_str());
   1820 }
   1821 
   1822 TEST_F(AvbToolTest, VerifyImageWithHashAndHashtreeCorruptHashtree) {
   1823   GenerateImageWithHashAndHashtreeSetup();
   1824 
   1825   // Corrupt four bytes of data in the middle of system.img.
   1826   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
   1827   EXPECT_EQ(AVB_IO_RESULT_OK,
   1828             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
   1829                                                "system",
   1830                                                123 * 1024,  // offset from start
   1831                                                sizeof corrupt_data,
   1832                                                corrupt_data));
   1833 
   1834   // Do two checks - one for system.img not sparse, and one where it
   1835   // is sparse.
   1836   for (int n = 0; n < 2; n++) {
   1837     EXPECT_COMMAND(1,
   1838                    "./avbtool verify_image "
   1839                    "--image %s ",
   1840                    vbmeta_image_path_.value().c_str());
   1841     if (n == 0) {
   1842       EXPECT_COMMAND(0,
   1843                      "img2simg %s %s.sparse",
   1844                      testdir_.Append("system.img").value().c_str(),
   1845                      testdir_.Append("system.img").value().c_str());
   1846       EXPECT_COMMAND(0,
   1847                      "mv %s.sparse %s",
   1848                      testdir_.Append("system.img").value().c_str(),
   1849                      testdir_.Append("system.img").value().c_str());
   1850     }
   1851   }
   1852 }
   1853 
   1854 TEST_F(AvbToolTest, VerifyImageChainPartition) {
   1855   base::FilePath pk4096_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   1856   EXPECT_COMMAND(
   1857       0,
   1858       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   1859       " --output %s",
   1860       pk4096_path.value().c_str());
   1861 
   1862   base::FilePath pk8192_path = testdir_.Append("testkey_rsa8192.avbpubkey");
   1863   EXPECT_COMMAND(
   1864       0,
   1865       "./avbtool extract_public_key --key test/data/testkey_rsa8192.pem"
   1866       " --output %s",
   1867       pk8192_path.value().c_str());
   1868 
   1869   GenerateVBMetaImage("vbmeta.img",
   1870                       "SHA256_RSA2048",
   1871                       0,
   1872                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1873                       base::StringPrintf("--chain_partition system:1:%s ",
   1874                                          pk4096_path.value().c_str()));
   1875 
   1876   // Should not fail (name, rollback_index, contents all correct).
   1877   EXPECT_COMMAND(0,
   1878                  "./avbtool verify_image "
   1879                  "--image %s "
   1880                  "--expected_chain_partition system:1:%s",
   1881                  vbmeta_image_path_.value().c_str(),
   1882                  pk4096_path.value().c_str());
   1883 
   1884   // Should fail because we didn't use --expected_chain_partition.
   1885   EXPECT_COMMAND(1,
   1886                  "./avbtool verify_image "
   1887                  "--image %s ",
   1888                  vbmeta_image_path_.value().c_str());
   1889 
   1890   // Should fail because partition name is wrong.
   1891   EXPECT_COMMAND(1,
   1892                  "./avbtool verify_image "
   1893                  "--image %s "
   1894                  "--expected_chain_partition xyz:1:%s",
   1895                  vbmeta_image_path_.value().c_str(),
   1896                  pk4096_path.value().c_str());
   1897 
   1898   // Should fail because rollback index location is wrong.
   1899   EXPECT_COMMAND(1,
   1900                  "./avbtool verify_image "
   1901                  "--image %s "
   1902                  "--expected_chain_partition system:2:%s",
   1903                  vbmeta_image_path_.value().c_str(),
   1904                  pk4096_path.value().c_str());
   1905 
   1906   // Should fail because public key blob is wrong.
   1907   EXPECT_COMMAND(1,
   1908                  "./avbtool verify_image "
   1909                  "--image %s "
   1910                  "--expected_chain_partition system:1:%s",
   1911                  vbmeta_image_path_.value().c_str(),
   1912                  pk8192_path.value().c_str());
   1913 }
   1914 
   1915 TEST_F(AvbToolTest, PrintRequiredLibavbVersion) {
   1916   base::FilePath output_path = testdir_.Append("versions.txt");
   1917 
   1918   const size_t boot_partition_size = 16 * 1024 * 1024;
   1919   EXPECT_COMMAND(0,
   1920                  "./avbtool add_hash_footer"
   1921                  " --rollback_index 0"
   1922                  " --partition_name boot"
   1923                  " --partition_size %zd"
   1924                  " --salt deadbeef"
   1925                  " --internal_release_string \"\""
   1926                  " --print_required_libavb_version >> %s",
   1927                  boot_partition_size,
   1928                  output_path.value().c_str());
   1929 
   1930   const size_t system_partition_size = 10 * 1024 * 1024;
   1931   EXPECT_COMMAND(0,
   1932                  "./avbtool add_hashtree_footer --salt d00df00d "
   1933                  "--partition_size %zd --partition_name system "
   1934                  "--internal_release_string \"\""
   1935                  " --print_required_libavb_version >> %s",
   1936                  system_partition_size,
   1937                  output_path.value().c_str());
   1938 
   1939   EXPECT_COMMAND(0,
   1940                  "./avbtool make_vbmeta_image "
   1941                  "--algorithm SHA256_RSA2048 "
   1942                  "--key test/data/testkey_rsa2048.pem "
   1943                  "--internal_release_string \"\""
   1944                  " --print_required_libavb_version >> %s",
   1945                  output_path.value().c_str());
   1946 
   1947   // Check that "1.0\n" was printed for all three invocations.
   1948   std::string versions;
   1949   ASSERT_TRUE(base::ReadFileToString(output_path, &versions));
   1950   EXPECT_EQ(versions, std::string("1.0\n1.0\n1.0\n"));
   1951 }
   1952 
   1953 TEST_F(AvbToolTest, MakeAtxPikCertificate) {
   1954   base::FilePath subject_path = testdir_.Append("tmp_subject");
   1955   ASSERT_TRUE(base::WriteFile(subject_path, "fake PIK subject", 16));
   1956   base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
   1957   EXPECT_COMMAND(
   1958       0,
   1959       "openssl pkey -pubout -in test/data/testkey_atx_pik.pem -out %s",
   1960       pubkey_path.value().c_str());
   1961 
   1962   base::FilePath output_path = testdir_.Append("tmp_certificate.bin");
   1963   EXPECT_COMMAND(0,
   1964                  "./avbtool make_atx_certificate"
   1965                  " --subject %s"
   1966                  " --subject_key %s"
   1967                  " --subject_key_version 42"
   1968                  " --subject_is_intermediate_authority"
   1969                  " --authority_key test/data/testkey_atx_prk.pem"
   1970                  " --output %s",
   1971                  subject_path.value().c_str(),
   1972                  pubkey_path.value().c_str(),
   1973                  output_path.value().c_str());
   1974 
   1975   EXPECT_COMMAND(0,
   1976                  "diff test/data/atx_pik_certificate.bin %s",
   1977                  output_path.value().c_str());
   1978 }
   1979 
   1980 TEST_F(AvbToolTest, MakeAtxPskCertificate) {
   1981   base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
   1982   EXPECT_COMMAND(
   1983       0,
   1984       "openssl pkey -pubout -in test/data/testkey_atx_psk.pem -out %s",
   1985       pubkey_path.value().c_str());
   1986 
   1987   base::FilePath output_path = testdir_.Append("tmp_certificate.bin");
   1988   EXPECT_COMMAND(0,
   1989                  "./avbtool make_atx_certificate"
   1990                  " --subject test/data/atx_product_id.bin"
   1991                  " --subject_key %s"
   1992                  " --subject_key_version 42"
   1993                  " --authority_key test/data/testkey_atx_pik.pem"
   1994                  " --output %s",
   1995                  pubkey_path.value().c_str(),
   1996                  output_path.value().c_str());
   1997 
   1998   EXPECT_COMMAND(0,
   1999                  "diff test/data/atx_psk_certificate.bin %s",
   2000                  output_path.value().c_str());
   2001 }
   2002 
   2003 TEST_F(AvbToolTest, MakeAtxPermanentAttributes) {
   2004   base::FilePath pubkey_path = testdir_.Append("tmp_pubkey.pem");
   2005   EXPECT_COMMAND(
   2006       0,
   2007       "openssl pkey -pubout -in test/data/testkey_atx_prk.pem -out %s",
   2008       pubkey_path.value().c_str());
   2009 
   2010   base::FilePath output_path = testdir_.Append("tmp_attributes.bin");
   2011   EXPECT_COMMAND(0,
   2012                  "./avbtool make_atx_permanent_attributes"
   2013                  " --root_authority_key %s"
   2014                  " --product_id test/data/atx_product_id.bin"
   2015                  " --output %s",
   2016                  pubkey_path.value().c_str(),
   2017                  output_path.value().c_str());
   2018 
   2019   EXPECT_COMMAND(0,
   2020                  "diff test/data/atx_permanent_attributes.bin %s",
   2021                  output_path.value().c_str());
   2022 }
   2023 
   2024 TEST_F(AvbToolTest, MakeAtxMetadata) {
   2025   base::FilePath output_path = testdir_.Append("tmp_metadata.bin");
   2026 
   2027   EXPECT_COMMAND(
   2028       0,
   2029       "./avbtool make_atx_metadata"
   2030       " --intermediate_key_certificate test/data/atx_pik_certificate.bin"
   2031       " --product_key_certificate test/data/atx_psk_certificate.bin"
   2032       " --output %s",
   2033       output_path.value().c_str());
   2034 
   2035   EXPECT_COMMAND(
   2036       0, "diff test/data/atx_metadata.bin %s", output_path.value().c_str());
   2037 }
   2038 
   2039 }  // namespace avb
   2040