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 <base/files/file_util.h>
     28 #include <base/strings/string_util.h>
     29 #include <base/strings/stringprintf.h>
     30 
     31 #include "avb_unittest_util.h"
     32 #include "fake_avb_ops.h"
     33 
     34 namespace avb {
     35 
     36 class AvbSlotVerifyTest : public BaseAvbToolTest {
     37  public:
     38   AvbSlotVerifyTest() {}
     39 
     40   virtual void SetUp() override {
     41     BaseAvbToolTest::SetUp();
     42     ops_.set_partition_dir(testdir_);
     43     ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}, {2, 0}, {3, 0}});
     44     ops_.set_stored_is_device_unlocked(false);
     45   }
     46 
     47   void CmdlineWithHashtreeVerification(bool hashtree_verification_on);
     48 
     49   FakeAvbOps ops_;
     50 };
     51 
     52 TEST_F(AvbSlotVerifyTest, Basic) {
     53   GenerateVBMetaImage("vbmeta_a.img",
     54                       "SHA256_RSA2048",
     55                       0,
     56                       base::FilePath("test/data/testkey_rsa2048.pem"),
     57                       "--internal_release_string \"\"");
     58 
     59   ops_.set_expected_public_key(
     60       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
     61 
     62   AvbSlotVerifyData* slot_data = NULL;
     63   const char* requested_partitions[] = {"boot", NULL};
     64   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
     65             avb_slot_verify(ops_.avb_ops(),
     66                             requested_partitions,
     67                             "_a",
     68                             false /* allow_verification_error */,
     69                             &slot_data));
     70   EXPECT_NE(nullptr, slot_data);
     71   EXPECT_EQ(
     72       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
     73       "androidboot.vbmeta.avb_version=1.0 "
     74       "androidboot.vbmeta.device_state=locked "
     75       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
     76       "androidboot.vbmeta.digest="
     77       "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
     78       std::string(slot_data->cmdline));
     79   avb_slot_verify_data_free(slot_data);
     80 }
     81 
     82 TEST_F(AvbSlotVerifyTest, BasicSha512) {
     83   GenerateVBMetaImage("vbmeta_a.img",
     84                       "SHA512_RSA2048",
     85                       0,
     86                       base::FilePath("test/data/testkey_rsa2048.pem"),
     87                       "--internal_release_string \"\"");
     88 
     89   ops_.set_expected_public_key(
     90       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
     91 
     92   AvbSlotVerifyData* slot_data = NULL;
     93   const char* requested_partitions[] = {"boot", NULL};
     94   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
     95             avb_slot_verify(ops_.avb_ops(),
     96                             requested_partitions,
     97                             "_a",
     98                             false /* allow_verification_error */,
     99                             &slot_data));
    100   EXPECT_NE(nullptr, slot_data);
    101   EXPECT_EQ(
    102       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
    103       "androidboot.vbmeta.avb_version=1.0 "
    104       "androidboot.vbmeta.device_state=locked "
    105       "androidboot.vbmeta.hash_alg=sha512 androidboot.vbmeta.size=1152 "
    106       "androidboot.vbmeta.digest="
    107       "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
    108       "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77",
    109       std::string(slot_data->cmdline));
    110   avb_slot_verify_data_free(slot_data);
    111 }
    112 
    113 TEST_F(AvbSlotVerifyTest, BasicUnlocked) {
    114   GenerateVBMetaImage("vbmeta_a.img",
    115                       "SHA256_RSA2048",
    116                       0,
    117                       base::FilePath("test/data/testkey_rsa2048.pem"),
    118                       "--internal_release_string \"\"");
    119 
    120   ops_.set_expected_public_key(
    121       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    122 
    123   ops_.set_stored_is_device_unlocked(true);
    124 
    125   AvbSlotVerifyData* slot_data = NULL;
    126   const char* requested_partitions[] = {"boot", NULL};
    127   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    128             avb_slot_verify(ops_.avb_ops(),
    129                             requested_partitions,
    130                             "_a",
    131                             false /* allow_verification_error */,
    132                             &slot_data));
    133   EXPECT_NE(nullptr, slot_data);
    134   EXPECT_EQ(
    135       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
    136       "androidboot.vbmeta.avb_version=1.0 "
    137       "androidboot.vbmeta.device_state=unlocked "
    138       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
    139       "androidboot.vbmeta.digest="
    140       "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
    141       std::string(slot_data->cmdline));
    142   avb_slot_verify_data_free(slot_data);
    143 }
    144 
    145 TEST_F(AvbSlotVerifyTest, SlotDataIsCorrect) {
    146   GenerateVBMetaImage("vbmeta_a.img",
    147                       "SHA256_RSA2048",
    148                       0,
    149                       base::FilePath("test/data/testkey_rsa2048.pem"),
    150                       "--internal_release_string \"\"");
    151 
    152   ops_.set_expected_public_key(
    153       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    154 
    155   AvbSlotVerifyData* slot_data = NULL;
    156   const char* requested_partitions[] = {"boot", NULL};
    157   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    158             avb_slot_verify(ops_.avb_ops(),
    159                             requested_partitions,
    160                             "_a",
    161                             false /* allow_verification_error */,
    162                             &slot_data));
    163   EXPECT_NE(nullptr, slot_data);
    164   avb_slot_verify_data_free(slot_data);
    165 }
    166 
    167 TEST_F(AvbSlotVerifyTest, WrongPublicKey) {
    168   GenerateVBMetaImage("vbmeta_a.img",
    169                       "SHA256_RSA2048",
    170                       0,
    171                       base::FilePath("test/data/testkey_rsa2048.pem"),
    172                       "--internal_release_string \"\"");
    173 
    174   AvbSlotVerifyData* slot_data = NULL;
    175   const char* requested_partitions[] = {"boot", NULL};
    176   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
    177             avb_slot_verify(ops_.avb_ops(),
    178                             requested_partitions,
    179                             "_a",
    180                             false /* allow_verification_error */,
    181                             &slot_data));
    182   EXPECT_EQ(nullptr, slot_data);
    183   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
    184             avb_slot_verify(ops_.avb_ops(),
    185                             requested_partitions,
    186                             "_a",
    187                             true /* allow_verification_error */,
    188                             &slot_data));
    189   EXPECT_NE(nullptr, slot_data);
    190   avb_slot_verify_data_free(slot_data);
    191 }
    192 
    193 TEST_F(AvbSlotVerifyTest, NoImage) {
    194   const char* requested_partitions[] = {"boot", NULL};
    195   AvbSlotVerifyData* slot_data = NULL;
    196   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
    197             avb_slot_verify(ops_.avb_ops(),
    198                             requested_partitions,
    199                             "_a",
    200                             false /* allow_verification_error */,
    201                             &slot_data));
    202   EXPECT_EQ(nullptr, slot_data);
    203 }
    204 
    205 TEST_F(AvbSlotVerifyTest, UnsignedVBMeta) {
    206   GenerateVBMetaImage("vbmeta_a.img",
    207                       "",
    208                       0,
    209                       base::FilePath(""),
    210                       "--internal_release_string \"\"");
    211 
    212   AvbSlotVerifyData* slot_data = NULL;
    213   const char* requested_partitions[] = {"boot", NULL};
    214   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    215             avb_slot_verify(ops_.avb_ops(),
    216                             requested_partitions,
    217                             "_a",
    218                             false /* allow_verification_error */,
    219                             &slot_data));
    220   EXPECT_EQ(nullptr, slot_data);
    221   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    222             avb_slot_verify(ops_.avb_ops(),
    223                             requested_partitions,
    224                             "_a",
    225                             true /* allow_verification_error */,
    226                             &slot_data));
    227   EXPECT_NE(nullptr, slot_data);
    228   avb_slot_verify_data_free(slot_data);
    229 }
    230 
    231 TEST_F(AvbSlotVerifyTest, CorruptedImage) {
    232   GenerateVBMetaImage("vbmeta_a.img",
    233                       "SHA256_RSA2048",
    234                       0,
    235                       base::FilePath("test/data/testkey_rsa2048.pem"),
    236                       "--internal_release_string \"\"");
    237 
    238   // Corrupt four bytes of data in the end of the image. Since the aux
    239   // data is at the end and this data is signed, this will change the
    240   // value of the computed hash.
    241   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
    242   EXPECT_EQ(AVB_IO_RESULT_OK,
    243             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
    244                                                "vbmeta_a",
    245                                                -4,  // offset from end
    246                                                sizeof corrupt_data,
    247                                                corrupt_data));
    248 
    249   AvbSlotVerifyData* slot_data = NULL;
    250   const char* requested_partitions[] = {"boot", NULL};
    251   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    252             avb_slot_verify(ops_.avb_ops(),
    253                             requested_partitions,
    254                             "_a",
    255                             false /* allow_verification_error */,
    256                             &slot_data));
    257   EXPECT_EQ(nullptr, slot_data);
    258   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    259             avb_slot_verify(ops_.avb_ops(),
    260                             requested_partitions,
    261                             "_a",
    262                             true /* allow_verification_error */,
    263                             &slot_data));
    264   EXPECT_NE(nullptr, slot_data);
    265   avb_slot_verify_data_free(slot_data);
    266 }
    267 
    268 TEST_F(AvbSlotVerifyTest, CorruptedMetadata) {
    269   GenerateVBMetaImage("vbmeta_a.img",
    270                       "SHA256_RSA2048",
    271                       0,
    272                       base::FilePath("test/data/testkey_rsa2048.pem"),
    273                       "--internal_release_string \"\"");
    274 
    275   // Corrupt four bytes of data in the beginning of the image. Unlike
    276   // the CorruptedImage test-case above (which is valid metadata) this
    277   // will make the metadata invalid and render the slot unbootable
    278   // even if the device is unlocked. Specifically no AvbSlotVerifyData
    279   // is returned.
    280   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
    281   EXPECT_EQ(AVB_IO_RESULT_OK,
    282             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
    283                                                "vbmeta_a",
    284                                                0,  // offset: beginning
    285                                                sizeof corrupt_data,
    286                                                corrupt_data));
    287 
    288   AvbSlotVerifyData* slot_data = NULL;
    289   const char* requested_partitions[] = {"boot", NULL};
    290   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
    291             avb_slot_verify(ops_.avb_ops(),
    292                             requested_partitions,
    293                             "_a",
    294                             false /* allow_verification_error */,
    295                             &slot_data));
    296   EXPECT_EQ(nullptr, slot_data);
    297 }
    298 
    299 TEST_F(AvbSlotVerifyTest, RollbackIndex) {
    300   GenerateVBMetaImage("vbmeta_a.img",
    301                       "SHA256_RSA2048",
    302                       42,
    303                       base::FilePath("test/data/testkey_rsa2048.pem"),
    304                       "--internal_release_string \"\"");
    305 
    306   ops_.set_expected_public_key(
    307       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    308 
    309   AvbSlotVerifyData* slot_data = NULL;
    310   const char* requested_partitions[] = {"boot", NULL};
    311 
    312   // First try with 42 as the stored rollback index - this should
    313   // succeed since the image rollback index is 42 (as set above).
    314   ops_.set_stored_rollback_indexes({{0, 42}});
    315   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    316             avb_slot_verify(ops_.avb_ops(),
    317                             requested_partitions,
    318                             "_a",
    319                             false /* allow_verification_error */,
    320                             &slot_data));
    321   EXPECT_NE(nullptr, slot_data);
    322   avb_slot_verify_data_free(slot_data);
    323 
    324   // Then try with 43 for the stored rollback index - this should fail
    325   // because the image has rollback index 42 which is less than 43.
    326   ops_.set_stored_rollback_indexes({{0, 43}});
    327   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
    328             avb_slot_verify(ops_.avb_ops(),
    329                             requested_partitions,
    330                             "_a",
    331                             false /* allow_verification_error */,
    332                             &slot_data));
    333   EXPECT_EQ(nullptr, slot_data);
    334   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
    335             avb_slot_verify(ops_.avb_ops(),
    336                             requested_partitions,
    337                             "_a",
    338                             true /* allow_verification_error */,
    339                             &slot_data));
    340   EXPECT_NE(nullptr, slot_data);
    341   avb_slot_verify_data_free(slot_data);
    342 }
    343 
    344 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMeta) {
    345   const size_t boot_partition_size = 16 * 1024 * 1024;
    346   const size_t boot_image_size = 5 * 1024 * 1024;
    347   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
    348 
    349   EXPECT_COMMAND(
    350       0,
    351       "./avbtool add_hash_footer"
    352       " --image %s"
    353       " --rollback_index 0"
    354       " --partition_name boot"
    355       " --partition_size %zd"
    356       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
    357       " --salt deadbeef"
    358       " --internal_release_string \"\"",
    359       boot_path.value().c_str(),
    360       boot_partition_size);
    361 
    362   GenerateVBMetaImage(
    363       "vbmeta_a.img",
    364       "SHA256_RSA2048",
    365       4,
    366       base::FilePath("test/data/testkey_rsa2048.pem"),
    367       base::StringPrintf(
    368           "--include_descriptors_from_image %s"
    369           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
    370           " --internal_release_string \"\"",
    371           boot_path.value().c_str()));
    372 
    373   EXPECT_EQ(
    374       "Minimum libavb version:   1.0\n"
    375       "Header Block:             256 bytes\n"
    376       "Authentication Block:     320 bytes\n"
    377       "Auxiliary Block:          896 bytes\n"
    378       "Algorithm:                SHA256_RSA2048\n"
    379       "Rollback Index:           4\n"
    380       "Flags:                    0\n"
    381       "Release String:           ''\n"
    382       "Descriptors:\n"
    383       "    Kernel Cmdline descriptor:\n"
    384       "      Flags:                 0\n"
    385       "      Kernel Cmdline:        'cmdline in vbmeta "
    386       "$(ANDROID_BOOT_PARTUUID)'\n"
    387       "    Hash descriptor:\n"
    388       "      Image Size:            5242880 bytes\n"
    389       "      Hash Algorithm:        sha256\n"
    390       "      Partition Name:        boot\n"
    391       "      Salt:                  deadbeef\n"
    392       "      Digest:                "
    393       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
    394       "    Kernel Cmdline descriptor:\n"
    395       "      Flags:                 0\n"
    396       "      Kernel Cmdline:        'cmdline in hash footer "
    397       "$(ANDROID_SYSTEM_PARTUUID)'\n",
    398       InfoImage(vbmeta_image_path_));
    399 
    400   EXPECT_COMMAND(0,
    401                  "./avbtool erase_footer"
    402                  " --image %s",
    403                  boot_path.value().c_str());
    404 
    405   // With no footer, 'avbtool info_image' should fail (exit status 1).
    406   EXPECT_COMMAND(
    407       1, "./avbtool info_image --image %s", boot_path.value().c_str());
    408 
    409   ops_.set_expected_public_key(
    410       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    411 
    412   AvbSlotVerifyData* slot_data = NULL;
    413   const char* requested_partitions[] = {"boot", NULL};
    414   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    415             avb_slot_verify(ops_.avb_ops(),
    416                             requested_partitions,
    417                             "_a",
    418                             false /* allow_verification_error */,
    419                             &slot_data));
    420   EXPECT_NE(nullptr, slot_data);
    421 
    422   // Now verify the slot data. The vbmeta data should match our
    423   // vbmeta_image_ member.
    424   EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
    425   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
    426   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
    427   EXPECT_EQ(0,
    428             memcmp(vbmeta_image_.data(),
    429                    slot_data->vbmeta_images[0].vbmeta_data,
    430                    slot_data->vbmeta_images[0].vbmeta_size));
    431 
    432   // The boot image data should match what is generated above with
    433   // GenerateImage().
    434   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
    435   EXPECT_EQ("boot",
    436             std::string(slot_data->loaded_partitions[0].partition_name));
    437   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
    438   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
    439     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
    440   }
    441 
    442   // This should match the two cmdlines with a space (U+0020) between
    443   // them and the $(ANDROID_SYSTEM_PARTUUID) and
    444   // $(ANDROID_BOOT_PARTUUID) variables replaced.
    445   EXPECT_EQ(
    446       "cmdline in vbmeta 1234-fake-guid-for:boot_a cmdline in hash footer "
    447       "1234-fake-guid-for:system_a "
    448       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
    449       "androidboot.vbmeta.avb_version=1.0 "
    450       "androidboot.vbmeta.device_state=locked "
    451       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
    452       "androidboot.vbmeta.digest="
    453       "34cdb59b955aa35d4da97701f304fabf7392eecca8c50ff1a0b7b6e1c9aaa1b8",
    454       std::string(slot_data->cmdline));
    455   EXPECT_EQ(4UL, slot_data->rollback_indexes[0]);
    456   for (size_t n = 1; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
    457     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
    458   }
    459   avb_slot_verify_data_free(slot_data);
    460 }
    461 
    462 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMetaCorruptBoot) {
    463   size_t boot_partition_size = 16 * 1024 * 1024;
    464   base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
    465   const char* requested_partitions[] = {"boot", NULL};
    466 
    467   EXPECT_COMMAND(0,
    468                  "./avbtool add_hash_footer"
    469                  " --image %s"
    470                  " --rollback_index 0"
    471                  " --partition_name boot"
    472                  " --partition_size %zd"
    473                  " --salt deadbeef"
    474                  " --internal_release_string \"\"",
    475                  boot_path.value().c_str(),
    476                  boot_partition_size);
    477 
    478   GenerateVBMetaImage("vbmeta_a.img",
    479                       "SHA256_RSA2048",
    480                       0,
    481                       base::FilePath("test/data/testkey_rsa2048.pem"),
    482                       base::StringPrintf("--include_descriptors_from_image %s"
    483                                          " --internal_release_string \"\"",
    484                                          boot_path.value().c_str()));
    485 
    486   EXPECT_COMMAND(0,
    487                  "./avbtool erase_footer"
    488                  " --image %s",
    489                  boot_path.value().c_str());
    490 
    491   ops_.set_expected_public_key(
    492       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    493 
    494   // So far, so good.
    495   AvbSlotVerifyData* slot_data = NULL;
    496   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    497             avb_slot_verify(ops_.avb_ops(),
    498                             requested_partitions,
    499                             "_a",
    500                             false /* allow_verification_error */,
    501                             &slot_data));
    502   EXPECT_NE(nullptr, slot_data);
    503   avb_slot_verify_data_free(slot_data);
    504 
    505   // Now corrupt boot_a.img and expect verification error.
    506   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
    507   EXPECT_EQ(AVB_IO_RESULT_OK,
    508             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
    509                                                "boot_a",
    510                                                1024 * 1024,  // offset: 1 MiB
    511                                                sizeof corrupt_data,
    512                                                corrupt_data));
    513 
    514   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    515             avb_slot_verify(ops_.avb_ops(),
    516                             requested_partitions,
    517                             "_a",
    518                             false /* allow_verification_error */,
    519                             &slot_data));
    520   EXPECT_EQ(nullptr, slot_data);
    521   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    522             avb_slot_verify(ops_.avb_ops(),
    523                             requested_partitions,
    524                             "_a",
    525                             true /* allow_verification_error */,
    526                             &slot_data));
    527   EXPECT_NE(nullptr, slot_data);
    528   avb_slot_verify_data_free(slot_data);
    529 }
    530 
    531 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartition) {
    532   size_t boot_partition_size = 16 * 1024 * 1024;
    533   const size_t boot_image_size = 5 * 1024 * 1024;
    534   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
    535   const char* requested_partitions[] = {"boot", NULL};
    536 
    537   EXPECT_COMMAND(0,
    538                  "./avbtool add_hash_footer"
    539                  " --image %s"
    540                  " --kernel_cmdline 'cmdline2 in hash footer'"
    541                  " --rollback_index 12"
    542                  " --partition_name boot"
    543                  " --partition_size %zd"
    544                  " --algorithm SHA256_RSA4096"
    545                  " --key test/data/testkey_rsa4096.pem"
    546                  " --salt deadbeef"
    547                  " --internal_release_string \"\"",
    548                  boot_path.value().c_str(),
    549                  boot_partition_size);
    550 
    551   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
    552   EXPECT_COMMAND(
    553       0,
    554       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
    555       " --output %s",
    556       pk_path.value().c_str());
    557 
    558   GenerateVBMetaImage(
    559       "vbmeta_a.img",
    560       "SHA256_RSA2048",
    561       11,
    562       base::FilePath("test/data/testkey_rsa2048.pem"),
    563       base::StringPrintf("--chain_partition boot:1:%s"
    564                          " --kernel_cmdline 'cmdline2 in vbmeta'"
    565                          " --internal_release_string \"\"",
    566                          pk_path.value().c_str()));
    567 
    568   EXPECT_EQ(
    569       "Minimum libavb version:   1.0\n"
    570       "Header Block:             256 bytes\n"
    571       "Authentication Block:     320 bytes\n"
    572       "Auxiliary Block:          1728 bytes\n"
    573       "Algorithm:                SHA256_RSA2048\n"
    574       "Rollback Index:           11\n"
    575       "Flags:                    0\n"
    576       "Release String:           ''\n"
    577       "Descriptors:\n"
    578       "    Chain Partition descriptor:\n"
    579       "      Partition Name:          boot\n"
    580       "      Rollback Index Location: 1\n"
    581       "      Public key (sha1):       "
    582       "2597c218aae470a130f61162feaae70afd97f011\n"
    583       "    Kernel Cmdline descriptor:\n"
    584       "      Flags:                 0\n"
    585       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
    586       InfoImage(vbmeta_image_path_));
    587 
    588   EXPECT_EQ(
    589       "Footer version:           1.0\n"
    590       "Image size:               16777216 bytes\n"
    591       "Original image size:      5242880 bytes\n"
    592       "VBMeta offset:            5242880\n"
    593       "VBMeta size:              2112 bytes\n"
    594       "--\n"
    595       "Minimum libavb version:   1.0\n"
    596       "Header Block:             256 bytes\n"
    597       "Authentication Block:     576 bytes\n"
    598       "Auxiliary Block:          1280 bytes\n"
    599       "Algorithm:                SHA256_RSA4096\n"
    600       "Rollback Index:           12\n"
    601       "Flags:                    0\n"
    602       "Release String:           ''\n"
    603       "Descriptors:\n"
    604       "    Hash descriptor:\n"
    605       "      Image Size:            5242880 bytes\n"
    606       "      Hash Algorithm:        sha256\n"
    607       "      Partition Name:        boot\n"
    608       "      Salt:                  deadbeef\n"
    609       "      Digest:                "
    610       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
    611       "    Kernel Cmdline descriptor:\n"
    612       "      Flags:                 0\n"
    613       "      Kernel Cmdline:        'cmdline2 in hash footer'\n",
    614       InfoImage(boot_path));
    615 
    616   ops_.set_expected_public_key(
    617       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    618 
    619   AvbSlotVerifyData* slot_data = NULL;
    620   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    621             avb_slot_verify(ops_.avb_ops(),
    622                             requested_partitions,
    623                             "_a",
    624                             false /* allow_verification_error */,
    625                             &slot_data));
    626   EXPECT_NE(nullptr, slot_data);
    627 
    628   // Now verify the slot data. We should have two vbmeta
    629   // structs. Verify both of them. Note that the A/B suffix isn't
    630   // appended.
    631   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
    632   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
    633   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
    634   EXPECT_EQ(0,
    635             memcmp(vbmeta_image_.data(),
    636                    slot_data->vbmeta_images[0].vbmeta_data,
    637                    slot_data->vbmeta_images[0].vbmeta_size));
    638   // And for the second vbmeta struct we check that the descriptors
    639   // match the info_image output from above.
    640   EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
    641   const AvbDescriptor** descriptors =
    642       avb_descriptor_get_all(slot_data->vbmeta_images[1].vbmeta_data,
    643                              slot_data->vbmeta_images[1].vbmeta_size,
    644                              NULL);
    645   EXPECT_NE(nullptr, descriptors);
    646   AvbHashDescriptor hash_desc;
    647   EXPECT_EQ(true,
    648             avb_hash_descriptor_validate_and_byteswap(
    649                 ((AvbHashDescriptor*)descriptors[0]), &hash_desc));
    650   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
    651                             sizeof(AvbHashDescriptor);
    652   uint64_t o = 0;
    653   EXPECT_EQ("boot",
    654             std::string(reinterpret_cast<const char*>(desc_end + o),
    655                         hash_desc.partition_name_len));
    656   o += hash_desc.partition_name_len;
    657   EXPECT_EQ("deadbeef", mem_to_hexstring(desc_end + o, hash_desc.salt_len));
    658   o += hash_desc.salt_len;
    659   EXPECT_EQ("184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d",
    660             mem_to_hexstring(desc_end + o, hash_desc.digest_len));
    661   AvbKernelCmdlineDescriptor cmdline_desc;
    662   EXPECT_EQ(true,
    663             avb_kernel_cmdline_descriptor_validate_and_byteswap(
    664                 ((AvbKernelCmdlineDescriptor*)descriptors[1]), &cmdline_desc));
    665   desc_end = reinterpret_cast<const uint8_t*>(descriptors[1]) +
    666              sizeof(AvbKernelCmdlineDescriptor);
    667   EXPECT_EQ("cmdline2 in hash footer",
    668             std::string(reinterpret_cast<const char*>(desc_end),
    669                         cmdline_desc.kernel_cmdline_length));
    670   avb_free(descriptors);
    671 
    672   // The boot image data should match what is generated above with
    673   // GenerateImage().
    674   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
    675   EXPECT_EQ("boot",
    676             std::string(slot_data->loaded_partitions[0].partition_name));
    677   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
    678   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
    679     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
    680   }
    681 
    682   // This should match the two cmdlines with a space (U+0020) between them.
    683   EXPECT_EQ(
    684       "cmdline2 in hash footer cmdline2 in vbmeta "
    685       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
    686       "androidboot.vbmeta.avb_version=1.0 "
    687       "androidboot.vbmeta.device_state=locked "
    688       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
    689       "androidboot.vbmeta.digest="
    690       "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
    691       std::string(slot_data->cmdline));
    692   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
    693   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
    694   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
    695     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
    696   }
    697   avb_slot_verify_data_free(slot_data);
    698 }
    699 
    700 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionCorruptBoot) {
    701   size_t boot_partition_size = 16 * 1024 * 1024;
    702   base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
    703   const char* requested_partitions[] = {"boot", NULL};
    704 
    705   EXPECT_COMMAND(0,
    706                  "./avbtool add_hash_footer"
    707                  " --image %s"
    708                  " --rollback_index 0"
    709                  " --partition_name boot"
    710                  " --partition_size %zd"
    711                  " --algorithm SHA256_RSA4096"
    712                  " --key test/data/testkey_rsa4096.pem"
    713                  " --salt deadbeef"
    714                  " --internal_release_string \"\"",
    715                  boot_path.value().c_str(),
    716                  boot_partition_size);
    717 
    718   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
    719   EXPECT_COMMAND(
    720       0,
    721       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
    722       " --output %s",
    723       pk_path.value().c_str());
    724 
    725   GenerateVBMetaImage("vbmeta_a.img",
    726                       "SHA256_RSA2048",
    727                       0,
    728                       base::FilePath("test/data/testkey_rsa2048.pem"),
    729                       base::StringPrintf("--chain_partition boot:1:%s"
    730                                          " --internal_release_string \"\"",
    731                                          pk_path.value().c_str()));
    732 
    733   ops_.set_expected_public_key(
    734       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    735 
    736   AvbSlotVerifyData* slot_data = NULL;
    737   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    738             avb_slot_verify(ops_.avb_ops(),
    739                             requested_partitions,
    740                             "_a",
    741                             false /* allow_verification_error */,
    742                             &slot_data));
    743   EXPECT_NE(nullptr, slot_data);
    744   avb_slot_verify_data_free(slot_data);
    745 
    746   // Now corrupt boot_a.img and expect verification error.
    747   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
    748   EXPECT_EQ(AVB_IO_RESULT_OK,
    749             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
    750                                                "boot_a",
    751                                                1024 * 1024,  // offset: 1 MiB
    752                                                sizeof corrupt_data,
    753                                                corrupt_data));
    754 
    755   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    756             avb_slot_verify(ops_.avb_ops(),
    757                             requested_partitions,
    758                             "_a",
    759                             false /* allow_verification_error */,
    760                             &slot_data));
    761   EXPECT_EQ(nullptr, slot_data);
    762   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    763             avb_slot_verify(ops_.avb_ops(),
    764                             requested_partitions,
    765                             "_a",
    766                             true /* allow_verification_error */,
    767                             &slot_data));
    768   EXPECT_NE(nullptr, slot_data);
    769   avb_slot_verify_data_free(slot_data);
    770 }
    771 
    772 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionKeyMismatch) {
    773   size_t boot_partition_size = 16 * 1024 * 1024;
    774   base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
    775   const char* requested_partitions[] = {"boot", NULL};
    776 
    777   // Use different key to sign vbmeta in boot_a (we use the 8192 bit
    778   // key) than what's in the chained partition descriptor (which is
    779   // the 4096 bit key) and expect
    780   // AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED.
    781 
    782   EXPECT_COMMAND(0,
    783                  "./avbtool add_hash_footer"
    784                  " --image %s"
    785                  " --rollback_index 0"
    786                  " --partition_name boot"
    787                  " --partition_size %zd"
    788                  " --algorithm SHA256_RSA8192"
    789                  " --key test/data/testkey_rsa8192.pem"
    790                  " --salt deadbeef"
    791                  " --internal_release_string \"\"",
    792                  boot_path.value().c_str(),
    793                  boot_partition_size);
    794 
    795   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
    796   EXPECT_COMMAND(
    797       0,
    798       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
    799       " --output %s",
    800       pk_path.value().c_str());
    801 
    802   GenerateVBMetaImage("vbmeta_a.img",
    803                       "SHA256_RSA2048",
    804                       0,
    805                       base::FilePath("test/data/testkey_rsa2048.pem"),
    806                       base::StringPrintf("--chain_partition boot:1:%s"
    807                                          " --internal_release_string \"\"",
    808                                          pk_path.value().c_str()));
    809 
    810   ops_.set_expected_public_key(
    811       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    812 
    813   AvbSlotVerifyData* slot_data = NULL;
    814   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
    815             avb_slot_verify(ops_.avb_ops(),
    816                             requested_partitions,
    817                             "_a",
    818                             false /* allow_verification_error */,
    819                             &slot_data));
    820   EXPECT_EQ(nullptr, slot_data);
    821   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
    822             avb_slot_verify(ops_.avb_ops(),
    823                             requested_partitions,
    824                             "_a",
    825                             true /* allow_verification_error */,
    826                             &slot_data));
    827   EXPECT_NE(nullptr, slot_data);
    828   avb_slot_verify_data_free(slot_data);
    829 }
    830 
    831 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionRollbackIndexFail) {
    832   size_t boot_partition_size = 16 * 1024 * 1024;
    833   base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
    834   const char* requested_partitions[] = {"boot", NULL};
    835 
    836   EXPECT_COMMAND(0,
    837                  "./avbtool add_hash_footer"
    838                  " --image %s"
    839                  " --rollback_index 10"
    840                  " --partition_name boot"
    841                  " --partition_size %zd"
    842                  " --algorithm SHA256_RSA4096"
    843                  " --key test/data/testkey_rsa4096.pem"
    844                  " --salt deadbeef"
    845                  " --internal_release_string \"\"",
    846                  boot_path.value().c_str(),
    847                  boot_partition_size);
    848 
    849   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
    850   EXPECT_COMMAND(
    851       0,
    852       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
    853       " --output %s",
    854       pk_path.value().c_str());
    855 
    856   GenerateVBMetaImage("vbmeta_a.img",
    857                       "SHA256_RSA2048",
    858                       110,
    859                       base::FilePath("test/data/testkey_rsa2048.pem"),
    860                       base::StringPrintf("--chain_partition boot:1:%s"
    861                                          " --internal_release_string \"\"",
    862                                          pk_path.value().c_str()));
    863 
    864   ops_.set_expected_public_key(
    865       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    866 
    867   AvbSlotVerifyData* slot_data = NULL;
    868 
    869   // Both images (vbmeta_a and boot_a) have rollback index 10 and 11
    870   // so it should work if the stored rollback indexes are 0 and 0.
    871   ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}});
    872   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    873             avb_slot_verify(ops_.avb_ops(),
    874                             requested_partitions,
    875                             "_a",
    876                             false /* allow_verification_error */,
    877                             &slot_data));
    878   EXPECT_NE(nullptr, slot_data);
    879   avb_slot_verify_data_free(slot_data);
    880 
    881   // Check failure if we set the stored rollback index of the chained
    882   // partition to 20 (see AvbSlotVerifyTest.RollbackIndex above
    883   // where we test rollback index checks for the vbmeta partition).
    884   ops_.set_stored_rollback_indexes({{0, 0}, {1, 20}});
    885   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
    886             avb_slot_verify(ops_.avb_ops(),
    887                             requested_partitions,
    888                             "_a",
    889                             false /* allow_verification_error */,
    890                             &slot_data));
    891   EXPECT_EQ(nullptr, slot_data);
    892   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
    893             avb_slot_verify(ops_.avb_ops(),
    894                             requested_partitions,
    895                             "_a",
    896                             true /* allow_verification_error */,
    897                             &slot_data));
    898   EXPECT_NE(nullptr, slot_data);
    899   avb_slot_verify_data_free(slot_data);
    900 
    901   // Check failure if there is no rollback index slot 1 - in that case
    902   // we expect an I/O error since ops->read_rollback_index() will
    903   // fail.
    904   ops_.set_stored_rollback_indexes({{0, 0}});
    905   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
    906             avb_slot_verify(ops_.avb_ops(),
    907                             requested_partitions,
    908                             "_a",
    909                             false /* allow_verification_error */,
    910                             &slot_data));
    911   EXPECT_EQ(nullptr, slot_data);
    912 }
    913 
    914 TEST_F(AvbSlotVerifyTest, ChainedPartitionNoSlots) {
    915   size_t boot_partition_size = 16 * 1024 * 1024;
    916   const size_t boot_image_size = 5 * 1024 * 1024;
    917   base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
    918   const char* requested_partitions[] = {"boot", NULL};
    919 
    920   EXPECT_COMMAND(0,
    921                  "./avbtool add_hash_footer"
    922                  " --image %s"
    923                  " --kernel_cmdline 'cmdline2 in hash footer'"
    924                  " --rollback_index 12"
    925                  " --partition_name boot"
    926                  " --partition_size %zd"
    927                  " --algorithm SHA256_RSA4096"
    928                  " --key test/data/testkey_rsa4096.pem"
    929                  " --salt deadbeef"
    930                  " --internal_release_string \"\"",
    931                  boot_path.value().c_str(),
    932                  boot_partition_size);
    933 
    934   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
    935   EXPECT_COMMAND(
    936       0,
    937       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
    938       " --output %s",
    939       pk_path.value().c_str());
    940 
    941   GenerateVBMetaImage(
    942       "vbmeta.img",
    943       "SHA256_RSA2048",
    944       11,
    945       base::FilePath("test/data/testkey_rsa2048.pem"),
    946       base::StringPrintf("--chain_partition boot:1:%s"
    947                          " --kernel_cmdline 'cmdline2 in vbmeta'"
    948                          " --internal_release_string \"\"",
    949                          pk_path.value().c_str()));
    950 
    951   EXPECT_EQ(
    952       "Minimum libavb version:   1.0\n"
    953       "Header Block:             256 bytes\n"
    954       "Authentication Block:     320 bytes\n"
    955       "Auxiliary Block:          1728 bytes\n"
    956       "Algorithm:                SHA256_RSA2048\n"
    957       "Rollback Index:           11\n"
    958       "Flags:                    0\n"
    959       "Release String:           ''\n"
    960       "Descriptors:\n"
    961       "    Chain Partition descriptor:\n"
    962       "      Partition Name:          boot\n"
    963       "      Rollback Index Location: 1\n"
    964       "      Public key (sha1):       "
    965       "2597c218aae470a130f61162feaae70afd97f011\n"
    966       "    Kernel Cmdline descriptor:\n"
    967       "      Flags:                 0\n"
    968       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
    969       InfoImage(vbmeta_image_path_));
    970 
    971   ops_.set_expected_public_key(
    972       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    973 
    974   AvbSlotVerifyData* slot_data = NULL;
    975   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    976             avb_slot_verify(ops_.avb_ops(),
    977                             requested_partitions,
    978                             "",
    979                             false /* allow_verification_error */,
    980                             &slot_data));
    981   EXPECT_NE(nullptr, slot_data);
    982 
    983   // Now verify the slot data. The first vbmeta data should match our
    984   // vbmeta_image_ member and the second one should be for the 'boot'
    985   // partition.
    986   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
    987   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
    988   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
    989   EXPECT_EQ(0,
    990             memcmp(vbmeta_image_.data(),
    991                    slot_data->vbmeta_images[0].vbmeta_data,
    992                    slot_data->vbmeta_images[0].vbmeta_size));
    993   EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
    994 
    995   // The boot image data should match what is generated above with
    996   // GenerateImage().
    997   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
    998   EXPECT_EQ("boot",
    999             std::string(slot_data->loaded_partitions[0].partition_name));
   1000   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
   1001   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
   1002     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
   1003   }
   1004 
   1005   // This should match the two cmdlines with a space (U+0020) between
   1006   // them.
   1007   EXPECT_EQ(
   1008       "cmdline2 in hash footer cmdline2 in vbmeta "
   1009       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
   1010       "androidboot.vbmeta.avb_version=1.0 "
   1011       "androidboot.vbmeta.device_state=locked "
   1012       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
   1013       "androidboot.vbmeta.digest="
   1014       "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
   1015       std::string(slot_data->cmdline));
   1016   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
   1017   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
   1018   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
   1019     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
   1020   }
   1021   avb_slot_verify_data_free(slot_data);
   1022 }
   1023 
   1024 TEST_F(AvbSlotVerifyTest, PartitionsOtherThanBoot) {
   1025   const size_t foo_partition_size = 16 * 1024 * 1024;
   1026   const size_t bar_partition_size = 32 * 1024 * 1024;
   1027   const size_t foo_image_size = 5 * 1024 * 1024;
   1028   const size_t bar_image_size = 10 * 1024 * 1024;
   1029   base::FilePath foo_path = GenerateImage("foo_a.img", foo_image_size);
   1030   base::FilePath bar_path = GenerateImage("bar_a.img", bar_image_size);
   1031 
   1032   EXPECT_COMMAND(0,
   1033                  "./avbtool add_hash_footer"
   1034                  " --image %s"
   1035                  " --partition_name foo"
   1036                  " --partition_size %zd"
   1037                  " --salt deadbeef"
   1038                  " --internal_release_string \"\"",
   1039                  foo_path.value().c_str(),
   1040                  foo_partition_size);
   1041 
   1042   EXPECT_COMMAND(0,
   1043                  "./avbtool add_hash_footer"
   1044                  " --image %s"
   1045                  " --partition_name bar"
   1046                  " --partition_size %zd"
   1047                  " --salt deadbeef"
   1048                  " --internal_release_string \"\"",
   1049                  bar_path.value().c_str(),
   1050                  bar_partition_size);
   1051 
   1052   GenerateVBMetaImage("vbmeta_a.img",
   1053                       "SHA256_RSA2048",
   1054                       4,
   1055                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1056                       base::StringPrintf("--include_descriptors_from_image %s"
   1057                                          " --include_descriptors_from_image %s"
   1058                                          " --internal_release_string \"\"",
   1059                                          foo_path.value().c_str(),
   1060                                          bar_path.value().c_str()));
   1061 
   1062   EXPECT_EQ(
   1063       "Minimum libavb version:   1.0\n"
   1064       "Header Block:             256 bytes\n"
   1065       "Authentication Block:     320 bytes\n"
   1066       "Auxiliary Block:          896 bytes\n"
   1067       "Algorithm:                SHA256_RSA2048\n"
   1068       "Rollback Index:           4\n"
   1069       "Flags:                    0\n"
   1070       "Release String:           ''\n"
   1071       "Descriptors:\n"
   1072       "    Hash descriptor:\n"
   1073       "      Image Size:            5242880 bytes\n"
   1074       "      Hash Algorithm:        sha256\n"
   1075       "      Partition Name:        foo\n"
   1076       "      Salt:                  deadbeef\n"
   1077       "      Digest:                "
   1078       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
   1079       "    Hash descriptor:\n"
   1080       "      Image Size:            10485760 bytes\n"
   1081       "      Hash Algorithm:        sha256\n"
   1082       "      Partition Name:        bar\n"
   1083       "      Salt:                  deadbeef\n"
   1084       "      Digest:                "
   1085       "baea4bbd261d0edf4d1fe5e6e5a36976c291eeba66b6a46fa81dba691327a727\n",
   1086       InfoImage(vbmeta_image_path_));
   1087 
   1088   ops_.set_expected_public_key(
   1089       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1090 
   1091   AvbSlotVerifyData* slot_data = NULL;
   1092   const char* requested_partitions[] = {"foo", "bar", NULL};
   1093   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1094             avb_slot_verify(ops_.avb_ops(),
   1095                             requested_partitions,
   1096                             "_a",
   1097                             false /* allow_verification_error */,
   1098                             &slot_data));
   1099   EXPECT_NE(nullptr, slot_data);
   1100 
   1101   // Now verify the slot data. The vbmeta data should match our
   1102   // vbmeta_image_ member.
   1103   EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
   1104   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
   1105   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
   1106   EXPECT_EQ(0,
   1107             memcmp(vbmeta_image_.data(),
   1108                    slot_data->vbmeta_images[0].vbmeta_data,
   1109                    slot_data->vbmeta_images[0].vbmeta_size));
   1110 
   1111   // The 'foo' and 'bar' image data should match what is generated
   1112   // above with GenerateImage().
   1113   EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
   1114   EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[0].partition_name));
   1115   EXPECT_EQ(foo_image_size, slot_data->loaded_partitions[0].data_size);
   1116   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
   1117     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
   1118   }
   1119   EXPECT_EQ("bar", std::string(slot_data->loaded_partitions[1].partition_name));
   1120   EXPECT_EQ(bar_image_size, slot_data->loaded_partitions[1].data_size);
   1121   for (size_t n = 0; n < slot_data->loaded_partitions[1].data_size; n++) {
   1122     EXPECT_EQ(slot_data->loaded_partitions[1].data[n], uint8_t(n));
   1123   }
   1124 
   1125   avb_slot_verify_data_free(slot_data);
   1126 }
   1127 
   1128 TEST_F(AvbSlotVerifyTest, PublicKeyMetadata) {
   1129   base::FilePath md_path = GenerateImage("md.bin", 1536);
   1130 
   1131   GenerateVBMetaImage("vbmeta_a.img",
   1132                       "SHA256_RSA2048",
   1133                       0,
   1134                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1135                       base::StringPrintf("--public_key_metadata %s"
   1136                                          " --internal_release_string \"\"",
   1137                                          md_path.value().c_str()));
   1138 
   1139   ops_.set_expected_public_key(
   1140       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1141 
   1142   std::string md_data;
   1143   ASSERT_TRUE(base::ReadFileToString(md_path, &md_data));
   1144   ops_.set_expected_public_key_metadata(md_data);
   1145 
   1146   AvbSlotVerifyData* slot_data = NULL;
   1147   const char* requested_partitions[] = {"boot", NULL};
   1148   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1149             avb_slot_verify(ops_.avb_ops(),
   1150                             requested_partitions,
   1151                             "_a",
   1152                             false /* allow_verification_error */,
   1153                             &slot_data));
   1154   EXPECT_NE(nullptr, slot_data);
   1155   EXPECT_EQ(
   1156       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   1157       "androidboot.vbmeta.avb_version=1.0 "
   1158       "androidboot.vbmeta.device_state=locked "
   1159       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=2688 "
   1160       "androidboot.vbmeta.digest="
   1161       "5edcaa54f40382ee6a2fc3b86cdf383348b35ed07955e83ea32d84b69a97eaa0",
   1162       std::string(slot_data->cmdline));
   1163   avb_slot_verify_data_free(slot_data);
   1164 }
   1165 
   1166 void AvbSlotVerifyTest::CmdlineWithHashtreeVerification(
   1167     bool hashtree_verification_on) {
   1168   const size_t rootfs_size = 1028 * 1024;
   1169   const size_t partition_size = 1536 * 1024;
   1170 
   1171   // Generate a 1028 KiB file with known content.
   1172   std::vector<uint8_t> rootfs;
   1173   rootfs.resize(rootfs_size);
   1174   for (size_t n = 0; n < rootfs_size; n++)
   1175     rootfs[n] = uint8_t(n);
   1176   base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
   1177   EXPECT_EQ(rootfs_size,
   1178             static_cast<const size_t>(
   1179                 base::WriteFile(rootfs_path,
   1180                                 reinterpret_cast<const char*>(rootfs.data()),
   1181                                 rootfs.size())));
   1182 
   1183   EXPECT_COMMAND(0,
   1184                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   1185                  "--partition_size %d --partition_name foobar "
   1186                  "--algorithm SHA256_RSA2048 "
   1187                  "--key test/data/testkey_rsa2048.pem "
   1188                  "--internal_release_string \"\"",
   1189                  rootfs_path.value().c_str(),
   1190                  (int)partition_size);
   1191 
   1192   // Check that we correctly generate dm-verity kernel cmdline
   1193   // snippets, if requested.
   1194   GenerateVBMetaImage(
   1195       "vbmeta_a.img",
   1196       "SHA256_RSA2048",
   1197       4,
   1198       base::FilePath("test/data/testkey_rsa2048.pem"),
   1199       base::StringPrintf("--setup_rootfs_from_kernel %s "
   1200                          "--kernel_cmdline should_be_in_both=1 "
   1201                          "--algorithm SHA256_RSA2048 "
   1202                          "--flags %d "
   1203                          "--internal_release_string \"\"",
   1204                          rootfs_path.value().c_str(),
   1205                          hashtree_verification_on
   1206                              ? 0
   1207                              : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED));
   1208 
   1209   EXPECT_EQ(
   1210       base::StringPrintf(
   1211           "Minimum libavb version:   1.0\n"
   1212           "Header Block:             256 bytes\n"
   1213           "Authentication Block:     320 bytes\n"
   1214           "Auxiliary Block:          960 bytes\n"
   1215           "Algorithm:                SHA256_RSA2048\n"
   1216           "Rollback Index:           4\n"
   1217           "Flags:                    %d\n"
   1218           "Release String:           ''\n"
   1219           "Descriptors:\n"
   1220           "    Kernel Cmdline descriptor:\n"
   1221           "      Flags:                 1\n"
   1222           "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity "
   1223           "1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
   1224           "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
   1225           "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
   1226           "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0'\n"
   1227           "    Kernel Cmdline descriptor:\n"
   1228           "      Flags:                 2\n"
   1229           "      Kernel Cmdline:        "
   1230           "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
   1231           "    Kernel Cmdline descriptor:\n"
   1232           "      Flags:                 0\n"
   1233           "      Kernel Cmdline:        'should_be_in_both=1'\n",
   1234           hashtree_verification_on ? 0
   1235                                    : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED),
   1236       InfoImage(vbmeta_image_path_));
   1237 
   1238   ops_.set_expected_public_key(
   1239       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1240 
   1241   // Check that avb_slot_verify() picks the cmdline decsriptors based
   1242   // on their flags value.
   1243   AvbSlotVerifyData* slot_data = NULL;
   1244   const char* requested_partitions[] = {"boot", NULL};
   1245   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1246             avb_slot_verify(ops_.avb_ops(),
   1247                             requested_partitions,
   1248                             "_a",
   1249                             false /* allow_verification_error */,
   1250                             &slot_data));
   1251   EXPECT_NE(nullptr, slot_data);
   1252   if (hashtree_verification_on) {
   1253     EXPECT_EQ(
   1254         "dm=\"1 vroot none ro 1,0 2056 verity 1 "
   1255         "PARTUUID=1234-fake-guid-for:system_a "
   1256         "PARTUUID=1234-fake-guid-for:system_a 4096 4096 257 257 sha1 "
   1257         "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
   1258         "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
   1259         "should_be_in_both=1 "
   1260         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   1261         "androidboot.vbmeta.avb_version=1.0 "
   1262         "androidboot.vbmeta.device_state=locked "
   1263         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
   1264         "androidboot.vbmeta.digest="
   1265         "51ea1638d8cc19a7a15b2bade22d155fb5150a6e376171ea1a89b7d6c89d6f17",
   1266         std::string(slot_data->cmdline));
   1267   } else {
   1268     EXPECT_EQ(
   1269         "root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
   1270         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   1271         "androidboot.vbmeta.avb_version=1.0 "
   1272         "androidboot.vbmeta.device_state=locked "
   1273         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
   1274         "androidboot.vbmeta.digest="
   1275         "877daa21c04df1d9e1776bc6169c98de947ce44b1b34b545021bb3f34e287da6",
   1276         std::string(slot_data->cmdline));
   1277   }
   1278   avb_slot_verify_data_free(slot_data);
   1279 }
   1280 
   1281 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOff) {
   1282   CmdlineWithHashtreeVerification(false);
   1283 }
   1284 
   1285 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOn) {
   1286   CmdlineWithHashtreeVerification(true);
   1287 }
   1288 
   1289 // In the event that there's no vbmeta partition, we treat the vbmeta
   1290 // struct from 'boot' as the top-level partition. Check that this
   1291 // works.
   1292 TEST_F(AvbSlotVerifyTest, NoVBMetaPartition) {
   1293   const size_t MiB = 1024 * 1024;
   1294   const size_t boot_size = 6 * MiB;
   1295   const size_t boot_part_size = 8 * MiB;
   1296   const size_t system_size = 16 * MiB;
   1297   const size_t system_part_size = 32 * MiB;
   1298   const size_t foobar_size = 8 * MiB;
   1299   const size_t foobar_part_size = 16 * MiB;
   1300   const size_t bazboo_size = 4 * MiB;
   1301   const size_t bazboo_part_size = 8 * MiB;
   1302   base::FilePath boot_path = GenerateImage("boot.img", boot_size);
   1303   base::FilePath system_path = GenerateImage("system.img", system_size);
   1304   base::FilePath foobar_path = GenerateImage("foobar.img", foobar_size);
   1305   base::FilePath bazboo_path = GenerateImage("bazboo.img", bazboo_size);
   1306 
   1307   EXPECT_COMMAND(0,
   1308                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   1309                  "--partition_size %d --partition_name system "
   1310                  "--algorithm SHA256_RSA2048 "
   1311                  "--key test/data/testkey_rsa2048.pem "
   1312                  "--internal_release_string \"\"",
   1313                  system_path.value().c_str(),
   1314                  (int)system_part_size);
   1315 
   1316   EXPECT_COMMAND(0,
   1317                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   1318                  "--partition_size %d --partition_name foobar "
   1319                  "--algorithm SHA256_RSA2048 "
   1320                  "--key test/data/testkey_rsa2048.pem "
   1321                  "--internal_release_string \"\"",
   1322                  foobar_path.value().c_str(),
   1323                  (int)foobar_part_size);
   1324 
   1325   EXPECT_COMMAND(0,
   1326                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   1327                  "--partition_size %d --partition_name bazboo "
   1328                  "--algorithm SHA512_RSA4096 "
   1329                  "--key test/data/testkey_rsa4096.pem "
   1330                  "--internal_release_string \"\"",
   1331                  bazboo_path.value().c_str(),
   1332                  (int)bazboo_part_size);
   1333 
   1334   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   1335   EXPECT_COMMAND(
   1336       0,
   1337       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   1338       " --output %s",
   1339       pk_path.value().c_str());
   1340 
   1341   // Explicitly pass "--flags 2147483648" (i.e. 1<<31) to check that
   1342   // boot.img is treated as top-level. Note the corresponding "Flags:"
   1343   // field below in the avbtool info_image output.
   1344   EXPECT_COMMAND(0,
   1345                  "./avbtool add_hash_footer --salt d00df00d "
   1346                  "--hash_algorithm sha256 --image %s "
   1347                  "--partition_size %d --partition_name boot "
   1348                  "--algorithm SHA256_RSA2048 "
   1349                  "--key test/data/testkey_rsa2048.pem "
   1350                  "--internal_release_string \"\" "
   1351                  "--include_descriptors_from_image %s "
   1352                  "--include_descriptors_from_image %s "
   1353                  "--setup_rootfs_from_kernel %s "
   1354                  "--chain_partition bazboo:1:%s "
   1355                  "--flags 2147483648",
   1356                  boot_path.value().c_str(),
   1357                  (int)boot_part_size,
   1358                  system_path.value().c_str(),
   1359                  foobar_path.value().c_str(),
   1360                  system_path.value().c_str(),
   1361                  pk_path.value().c_str());
   1362 
   1363   ASSERT_EQ(
   1364       "Footer version:           1.0\n"
   1365       "Image size:               8388608 bytes\n"
   1366       "Original image size:      6291456 bytes\n"
   1367       "VBMeta offset:            6291456\n"
   1368       "VBMeta size:              3200 bytes\n"
   1369       "--\n"
   1370       "Minimum libavb version:   1.0\n"
   1371       "Header Block:             256 bytes\n"
   1372       "Authentication Block:     320 bytes\n"
   1373       "Auxiliary Block:          2624 bytes\n"
   1374       "Algorithm:                SHA256_RSA2048\n"
   1375       "Rollback Index:           0\n"
   1376       "Flags:                    2147483648\n"
   1377       "Release String:           ''\n"
   1378       "Descriptors:\n"
   1379       "    Hash descriptor:\n"
   1380       "      Image Size:            6291456 bytes\n"
   1381       "      Hash Algorithm:        sha256\n"
   1382       "      Partition Name:        boot\n"
   1383       "      Salt:                  d00df00d\n"
   1384       "      Digest:                "
   1385       "4c109399b20e476bab15363bff55740add83e1c1e97e0b132f5c713ddd8c7868\n"
   1386       "    Chain Partition descriptor:\n"
   1387       "      Partition Name:          bazboo\n"
   1388       "      Rollback Index Location: 1\n"
   1389       "      Public key (sha1):       "
   1390       "2597c218aae470a130f61162feaae70afd97f011\n"
   1391       "    Kernel Cmdline descriptor:\n"
   1392       "      Flags:                 1\n"
   1393       "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 32768 verity 1 "
   1394       "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
   1395       "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
   1396       "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0'\n"
   1397       "    Kernel Cmdline descriptor:\n"
   1398       "      Flags:                 2\n"
   1399       "      Kernel Cmdline:        "
   1400       "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
   1401       "    Hashtree descriptor:\n"
   1402       "      Version of dm-verity:  1\n"
   1403       "      Image Size:            16777216 bytes\n"
   1404       "      Tree Offset:           16777216\n"
   1405       "      Tree Size:             135168 bytes\n"
   1406       "      Data Block Size:       4096 bytes\n"
   1407       "      Hash Block Size:       4096 bytes\n"
   1408       "      FEC num roots:         0\n"
   1409       "      FEC offset:            0\n"
   1410       "      FEC size:              0 bytes\n"
   1411       "      Hash Algorithm:        sha1\n"
   1412       "      Partition Name:        system\n"
   1413       "      Salt:                  d00df00d\n"
   1414       "      Root Digest:           c9ffc3bfae5000269a55a56621547fd1fcf819df\n"
   1415       "    Hashtree descriptor:\n"
   1416       "      Version of dm-verity:  1\n"
   1417       "      Image Size:            8388608 bytes\n"
   1418       "      Tree Offset:           8388608\n"
   1419       "      Tree Size:             69632 bytes\n"
   1420       "      Data Block Size:       4096 bytes\n"
   1421       "      Hash Block Size:       4096 bytes\n"
   1422       "      FEC num roots:         0\n"
   1423       "      FEC offset:            0\n"
   1424       "      FEC size:              0 bytes\n"
   1425       "      Hash Algorithm:        sha1\n"
   1426       "      Partition Name:        foobar\n"
   1427       "      Salt:                  d00df00d\n"
   1428       "      Root Digest:           d52d93c988d336a79abe1c05240ae9a79a9b7d61\n",
   1429       InfoImage(boot_path));
   1430 
   1431   ops_.set_expected_public_key(
   1432       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1433 
   1434   // Now check that libavb will fall back to reading from 'boot'
   1435   // instead of 'vbmeta' when encountering
   1436   // AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION on trying to read from
   1437   // 'vbmeta'.
   1438   AvbSlotVerifyData* slot_data = NULL;
   1439   const char* requested_partitions[] = {"boot", NULL};
   1440   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1441             avb_slot_verify(ops_.avb_ops(),
   1442                             requested_partitions,
   1443                             "",
   1444                             false /* allow_verification_error */,
   1445                             &slot_data));
   1446   EXPECT_NE(nullptr, slot_data);
   1447   // Note 'boot' in the value androidboot.vbmeta.device since we've
   1448   // read from 'boot' and not 'vbmeta'.
   1449   EXPECT_EQ(
   1450       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
   1451       "PARTUUID=1234-fake-guid-for:system PARTUUID=1234-fake-guid-for:system "
   1452       "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
   1453       "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
   1454       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:boot "
   1455       "androidboot.vbmeta.avb_version=1.0 "
   1456       "androidboot.vbmeta.device_state=locked "
   1457       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=5312 "
   1458       "androidboot.vbmeta.digest="
   1459       "87bf39949a560f93d54aa0a5e9d158439110141246e40fb103f131633a3ca456",
   1460       std::string(slot_data->cmdline));
   1461   avb_slot_verify_data_free(slot_data);
   1462 }
   1463 
   1464 // Check that non-zero flags in chained partition are caught in
   1465 // avb_slot_verify().
   1466 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceFlagsZero) {
   1467   size_t boot_partition_size = 16 * 1024 * 1024;
   1468   const size_t boot_image_size = 5 * 1024 * 1024;
   1469   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
   1470   const char* requested_partitions[] = {"boot", NULL};
   1471 
   1472   EXPECT_COMMAND(0,
   1473                  "./avbtool add_hash_footer"
   1474                  " --image %s"
   1475                  " --kernel_cmdline 'cmdline2 in hash footer'"
   1476                  " --rollback_index 12"
   1477                  " --partition_name boot"
   1478                  " --partition_size %zd"
   1479                  " --algorithm SHA256_RSA4096"
   1480                  " --key test/data/testkey_rsa4096.pem"
   1481                  " --salt deadbeef"
   1482                  " --flags 1"
   1483                  " --internal_release_string \"\"",
   1484                  boot_path.value().c_str(),
   1485                  boot_partition_size);
   1486 
   1487   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   1488   EXPECT_COMMAND(
   1489       0,
   1490       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   1491       " --output %s",
   1492       pk_path.value().c_str());
   1493 
   1494   GenerateVBMetaImage(
   1495       "vbmeta_a.img",
   1496       "SHA256_RSA2048",
   1497       11,
   1498       base::FilePath("test/data/testkey_rsa2048.pem"),
   1499       base::StringPrintf("--chain_partition boot:1:%s"
   1500                          " --kernel_cmdline 'cmdline2 in vbmeta'"
   1501                          " --internal_release_string \"\"",
   1502                          pk_path.value().c_str()));
   1503 
   1504   ops_.set_expected_public_key(
   1505       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1506 
   1507   AvbSlotVerifyData* slot_data = NULL;
   1508   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
   1509             avb_slot_verify(ops_.avb_ops(),
   1510                             requested_partitions,
   1511                             "_a",
   1512                             false /* allow_verification_error */,
   1513                             &slot_data));
   1514   EXPECT_EQ(nullptr, slot_data);
   1515 }
   1516 
   1517 // Check that chain descriptors in chained partitions are caught in
   1518 // avb_slot_verify().
   1519 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceNoChainPartitions) {
   1520   size_t boot_partition_size = 16 * 1024 * 1024;
   1521   const size_t boot_image_size = 5 * 1024 * 1024;
   1522   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
   1523   const char* requested_partitions[] = {"boot", NULL};
   1524 
   1525   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   1526   EXPECT_COMMAND(
   1527       0,
   1528       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   1529       " --output %s",
   1530       pk_path.value().c_str());
   1531 
   1532   EXPECT_COMMAND(0,
   1533                  "./avbtool add_hash_footer"
   1534                  " --image %s"
   1535                  " --kernel_cmdline 'cmdline2 in hash footer'"
   1536                  " --rollback_index 12"
   1537                  " --partition_name boot"
   1538                  " --partition_size %zd"
   1539                  " --algorithm SHA256_RSA4096"
   1540                  " --key test/data/testkey_rsa4096.pem"
   1541                  " --salt deadbeef"
   1542                  " --chain_partition other:2:%s"
   1543                  " --internal_release_string \"\"",
   1544                  boot_path.value().c_str(),
   1545                  boot_partition_size,
   1546                  pk_path.value().c_str());
   1547 
   1548   GenerateVBMetaImage(
   1549       "vbmeta_a.img",
   1550       "SHA256_RSA2048",
   1551       11,
   1552       base::FilePath("test/data/testkey_rsa2048.pem"),
   1553       base::StringPrintf("--chain_partition boot:1:%s"
   1554                          " --kernel_cmdline 'cmdline2 in vbmeta'"
   1555                          " --internal_release_string \"\"",
   1556                          pk_path.value().c_str()));
   1557 
   1558   ops_.set_expected_public_key(
   1559       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1560 
   1561   AvbSlotVerifyData* slot_data = NULL;
   1562   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
   1563             avb_slot_verify(ops_.avb_ops(),
   1564                             requested_partitions,
   1565                             "_a",
   1566                             false /* allow_verification_error */,
   1567                             &slot_data));
   1568   EXPECT_EQ(nullptr, slot_data);
   1569 }
   1570 
   1571 }  // namespace avb
   1572