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 FakeAvbOpsDelegateWithDefaults {
     38  public:
     39   AvbSlotVerifyTest() {}
     40 
     41   virtual void SetUp() override {
     42     BaseAvbToolTest::SetUp();
     43     ops_.set_delegate(this);
     44     ops_.set_partition_dir(testdir_);
     45     ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}, {2, 0}, {3, 0}});
     46     ops_.set_stored_is_device_unlocked(false);
     47   }
     48 
     49   void CmdlineWithHashtreeVerification(bool hashtree_verification_on);
     50   void CmdlineWithChainedHashtreeVerification(bool hashtree_verification_on);
     51   void VerificationDisabled(bool use_avbctl,
     52                             bool preload,
     53                             bool has_system_partition);
     54 };
     55 
     56 TEST_F(AvbSlotVerifyTest, Basic) {
     57   GenerateVBMetaImage("vbmeta_a.img",
     58                       "SHA256_RSA2048",
     59                       0,
     60                       base::FilePath("test/data/testkey_rsa2048.pem"),
     61                       "--internal_release_string \"\"");
     62 
     63   ops_.set_expected_public_key(
     64       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
     65 
     66   AvbSlotVerifyData* slot_data = NULL;
     67   const char* requested_partitions[] = {"boot", NULL};
     68   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
     69             avb_slot_verify(ops_.avb_ops(),
     70                             requested_partitions,
     71                             "_a",
     72                             AVB_SLOT_VERIFY_FLAGS_NONE,
     73                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
     74                             &slot_data));
     75   EXPECT_NE(nullptr, slot_data);
     76   EXPECT_EQ(
     77       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
     78       "androidboot.vbmeta.avb_version=1.1 "
     79       "androidboot.vbmeta.device_state=locked "
     80       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
     81       "androidboot.vbmeta.digest="
     82       "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
     83       "androidboot.vbmeta.invalidate_on_error=yes "
     84       "androidboot.veritymode=enforcing",
     85       std::string(slot_data->cmdline));
     86   uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
     87   avb_slot_verify_data_calculate_vbmeta_digest(
     88       slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
     89   EXPECT_EQ("4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
     90             mem_to_hexstring(vbmeta_digest, AVB_SHA256_DIGEST_SIZE));
     91   avb_slot_verify_data_free(slot_data);
     92 
     93   EXPECT_EQ("4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
     94             CalcVBMetaDigest("vbmeta_a.img", "sha256"));
     95 }
     96 
     97 TEST_F(AvbSlotVerifyTest, BasicSha512) {
     98   GenerateVBMetaImage("vbmeta_a.img",
     99                       "SHA512_RSA2048",
    100                       0,
    101                       base::FilePath("test/data/testkey_rsa2048.pem"),
    102                       "--internal_release_string \"\"");
    103 
    104   ops_.set_expected_public_key(
    105       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    106 
    107   AvbSlotVerifyData* slot_data = NULL;
    108   const char* requested_partitions[] = {"boot", NULL};
    109   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    110             avb_slot_verify(ops_.avb_ops(),
    111                             requested_partitions,
    112                             "_a",
    113                             AVB_SLOT_VERIFY_FLAGS_NONE,
    114                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    115                             &slot_data));
    116   EXPECT_NE(nullptr, slot_data);
    117   EXPECT_EQ(
    118       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
    119       "androidboot.vbmeta.avb_version=1.1 "
    120       "androidboot.vbmeta.device_state=locked "
    121       "androidboot.vbmeta.hash_alg=sha512 androidboot.vbmeta.size=1152 "
    122       "androidboot.vbmeta.digest="
    123       "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
    124       "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77 "
    125       "androidboot.vbmeta.invalidate_on_error=yes "
    126       "androidboot.veritymode=enforcing",
    127       std::string(slot_data->cmdline));
    128   uint8_t vbmeta_digest[AVB_SHA512_DIGEST_SIZE];
    129   avb_slot_verify_data_calculate_vbmeta_digest(
    130       slot_data, AVB_DIGEST_TYPE_SHA512, vbmeta_digest);
    131   EXPECT_EQ(
    132       "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
    133       "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77",
    134       mem_to_hexstring(vbmeta_digest, AVB_SHA512_DIGEST_SIZE));
    135   avb_slot_verify_data_free(slot_data);
    136 
    137   EXPECT_EQ(
    138       "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
    139       "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77",
    140       CalcVBMetaDigest("vbmeta_a.img", "sha512"));
    141 }
    142 
    143 TEST_F(AvbSlotVerifyTest, BasicUnlocked) {
    144   GenerateVBMetaImage("vbmeta_a.img",
    145                       "SHA256_RSA2048",
    146                       0,
    147                       base::FilePath("test/data/testkey_rsa2048.pem"),
    148                       "--internal_release_string \"\"");
    149 
    150   ops_.set_expected_public_key(
    151       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    152 
    153   ops_.set_stored_is_device_unlocked(true);
    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                             AVB_SLOT_VERIFY_FLAGS_NONE,
    162                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    163                             &slot_data));
    164   EXPECT_NE(nullptr, slot_data);
    165   EXPECT_EQ(
    166       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
    167       "androidboot.vbmeta.avb_version=1.1 "
    168       "androidboot.vbmeta.device_state=unlocked "
    169       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
    170       "androidboot.vbmeta.digest="
    171       "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
    172       "androidboot.vbmeta.invalidate_on_error=yes "
    173       "androidboot.veritymode=enforcing",
    174       std::string(slot_data->cmdline));
    175   avb_slot_verify_data_free(slot_data);
    176 }
    177 
    178 TEST_F(AvbSlotVerifyTest, PreloadedEnabledButNotUsed) {
    179   GenerateVBMetaImage("vbmeta_a.img",
    180                       "SHA256_RSA2048",
    181                       0,
    182                       base::FilePath("test/data/testkey_rsa2048.pem"),
    183                       "--internal_release_string \"\"");
    184 
    185   ops_.set_expected_public_key(
    186       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    187   ops_.enable_get_preloaded_partition();
    188 
    189   AvbSlotVerifyData* slot_data = NULL;
    190   const char* requested_partitions[] = {"boot", NULL};
    191   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    192             avb_slot_verify(ops_.avb_ops(),
    193                             requested_partitions,
    194                             "_a",
    195                             AVB_SLOT_VERIFY_FLAGS_NONE,
    196                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    197                             &slot_data));
    198   EXPECT_NE(nullptr, slot_data);
    199   avb_slot_verify_data_free(slot_data);
    200 }
    201 
    202 TEST_F(AvbSlotVerifyTest, SlotDataIsCorrect) {
    203   GenerateVBMetaImage("vbmeta_a.img",
    204                       "SHA256_RSA2048",
    205                       0,
    206                       base::FilePath("test/data/testkey_rsa2048.pem"),
    207                       "--internal_release_string \"\"");
    208 
    209   ops_.set_expected_public_key(
    210       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    211 
    212   AvbSlotVerifyData* slot_data = NULL;
    213   const char* requested_partitions[] = {"boot", NULL};
    214   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    215             avb_slot_verify(ops_.avb_ops(),
    216                             requested_partitions,
    217                             "_a",
    218                             AVB_SLOT_VERIFY_FLAGS_NONE,
    219                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    220                             &slot_data));
    221   EXPECT_NE(nullptr, slot_data);
    222   avb_slot_verify_data_free(slot_data);
    223 }
    224 
    225 TEST_F(AvbSlotVerifyTest, WrongPublicKey) {
    226   GenerateVBMetaImage("vbmeta_a.img",
    227                       "SHA256_RSA2048",
    228                       0,
    229                       base::FilePath("test/data/testkey_rsa2048.pem"),
    230                       "--internal_release_string \"\"");
    231 
    232   AvbSlotVerifyData* slot_data = NULL;
    233   const char* requested_partitions[] = {"boot", NULL};
    234   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
    235             avb_slot_verify(ops_.avb_ops(),
    236                             requested_partitions,
    237                             "_a",
    238                             AVB_SLOT_VERIFY_FLAGS_NONE,
    239                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    240                             &slot_data));
    241   EXPECT_EQ(nullptr, slot_data);
    242   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
    243             avb_slot_verify(ops_.avb_ops(),
    244                             requested_partitions,
    245                             "_a",
    246                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
    247                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    248                             &slot_data));
    249   EXPECT_NE(nullptr, slot_data);
    250   avb_slot_verify_data_free(slot_data);
    251 }
    252 
    253 TEST_F(AvbSlotVerifyTest, NoImage) {
    254   const char* requested_partitions[] = {"boot", NULL};
    255   AvbSlotVerifyData* slot_data = NULL;
    256   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
    257             avb_slot_verify(ops_.avb_ops(),
    258                             requested_partitions,
    259                             "_a",
    260                             AVB_SLOT_VERIFY_FLAGS_NONE,
    261                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    262                             &slot_data));
    263   EXPECT_EQ(nullptr, slot_data);
    264 }
    265 
    266 TEST_F(AvbSlotVerifyTest, UnsignedVBMeta) {
    267   GenerateVBMetaImage("vbmeta_a.img",
    268                       "",
    269                       0,
    270                       base::FilePath(""),
    271                       "--internal_release_string \"\"");
    272 
    273   AvbSlotVerifyData* slot_data = NULL;
    274   const char* requested_partitions[] = {"boot", NULL};
    275   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    276             avb_slot_verify(ops_.avb_ops(),
    277                             requested_partitions,
    278                             "_a",
    279                             AVB_SLOT_VERIFY_FLAGS_NONE,
    280                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    281                             &slot_data));
    282   EXPECT_EQ(nullptr, slot_data);
    283   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    284             avb_slot_verify(ops_.avb_ops(),
    285                             requested_partitions,
    286                             "_a",
    287                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
    288                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    289                             &slot_data));
    290   EXPECT_NE(nullptr, slot_data);
    291   avb_slot_verify_data_free(slot_data);
    292 }
    293 
    294 TEST_F(AvbSlotVerifyTest, CorruptedImage) {
    295   GenerateVBMetaImage("vbmeta_a.img",
    296                       "SHA256_RSA2048",
    297                       0,
    298                       base::FilePath("test/data/testkey_rsa2048.pem"),
    299                       "--internal_release_string \"\"");
    300 
    301   // Corrupt four bytes of data in the end of the image. Since the aux
    302   // data is at the end and this data is signed, this will change the
    303   // value of the computed hash.
    304   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
    305   EXPECT_EQ(AVB_IO_RESULT_OK,
    306             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
    307                                                "vbmeta_a",
    308                                                -4,  // offset from end
    309                                                sizeof corrupt_data,
    310                                                corrupt_data));
    311 
    312   AvbSlotVerifyData* slot_data = NULL;
    313   const char* requested_partitions[] = {"boot", NULL};
    314   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    315             avb_slot_verify(ops_.avb_ops(),
    316                             requested_partitions,
    317                             "_a",
    318                             AVB_SLOT_VERIFY_FLAGS_NONE,
    319                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    320                             &slot_data));
    321   EXPECT_EQ(nullptr, slot_data);
    322   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    323             avb_slot_verify(ops_.avb_ops(),
    324                             requested_partitions,
    325                             "_a",
    326                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
    327                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    328                             &slot_data));
    329   EXPECT_NE(nullptr, slot_data);
    330   avb_slot_verify_data_free(slot_data);
    331 }
    332 
    333 TEST_F(AvbSlotVerifyTest, CorruptedMetadata) {
    334   GenerateVBMetaImage("vbmeta_a.img",
    335                       "SHA256_RSA2048",
    336                       0,
    337                       base::FilePath("test/data/testkey_rsa2048.pem"),
    338                       "--internal_release_string \"\"");
    339 
    340   // Corrupt four bytes of data in the beginning of the image. Unlike
    341   // the CorruptedImage test-case above (which is valid metadata) this
    342   // will make the metadata invalid and render the slot unbootable
    343   // even if the device is unlocked. Specifically no AvbSlotVerifyData
    344   // is returned.
    345   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
    346   EXPECT_EQ(AVB_IO_RESULT_OK,
    347             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
    348                                                "vbmeta_a",
    349                                                0,  // offset: beginning
    350                                                sizeof corrupt_data,
    351                                                corrupt_data));
    352 
    353   AvbSlotVerifyData* slot_data = NULL;
    354   const char* requested_partitions[] = {"boot", NULL};
    355   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
    356             avb_slot_verify(ops_.avb_ops(),
    357                             requested_partitions,
    358                             "_a",
    359                             AVB_SLOT_VERIFY_FLAGS_NONE,
    360                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    361                             &slot_data));
    362   EXPECT_EQ(nullptr, slot_data);
    363 }
    364 
    365 TEST_F(AvbSlotVerifyTest, RollbackIndex) {
    366   GenerateVBMetaImage("vbmeta_a.img",
    367                       "SHA256_RSA2048",
    368                       42,
    369                       base::FilePath("test/data/testkey_rsa2048.pem"),
    370                       "--internal_release_string \"\"");
    371 
    372   ops_.set_expected_public_key(
    373       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    374 
    375   AvbSlotVerifyData* slot_data = NULL;
    376   const char* requested_partitions[] = {"boot", NULL};
    377 
    378   // First try with 42 as the stored rollback index - this should
    379   // succeed since the image rollback index is 42 (as set above).
    380   ops_.set_stored_rollback_indexes({{0, 42}});
    381   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    382             avb_slot_verify(ops_.avb_ops(),
    383                             requested_partitions,
    384                             "_a",
    385                             AVB_SLOT_VERIFY_FLAGS_NONE,
    386                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    387                             &slot_data));
    388   EXPECT_NE(nullptr, slot_data);
    389   avb_slot_verify_data_free(slot_data);
    390 
    391   // Then try with 43 for the stored rollback index - this should fail
    392   // because the image has rollback index 42 which is less than 43.
    393   ops_.set_stored_rollback_indexes({{0, 43}});
    394   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
    395             avb_slot_verify(ops_.avb_ops(),
    396                             requested_partitions,
    397                             "_a",
    398                             AVB_SLOT_VERIFY_FLAGS_NONE,
    399                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    400                             &slot_data));
    401   EXPECT_EQ(nullptr, slot_data);
    402   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
    403             avb_slot_verify(ops_.avb_ops(),
    404                             requested_partitions,
    405                             "_a",
    406                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
    407                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    408                             &slot_data));
    409   EXPECT_NE(nullptr, slot_data);
    410   avb_slot_verify_data_free(slot_data);
    411 }
    412 
    413 TEST_F(AvbSlotVerifyTest, LoadEntirePartitionIfAllowingVerificationError) {
    414   const size_t boot_partition_size = 16 * 1024 * 1024;
    415   const size_t boot_image_size = 5 * 1024 * 1024;
    416   const size_t new_boot_image_size = 10 * 1024 * 1024;
    417   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
    418 
    419   // If we're allowing verification errors then check that the whole
    420   // partition is loaded. This is needed because in this mode for
    421   // example the "boot" partition might be flashed with another
    422   // boot.img that is larger than what the HashDescriptor in vbmeta
    423   // says.
    424   EXPECT_COMMAND(
    425       0,
    426       "./avbtool add_hash_footer"
    427       " --image %s"
    428       " --rollback_index 0"
    429       " --partition_name boot"
    430       " --partition_size %zd"
    431       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
    432       " --salt deadbeef"
    433       " --internal_release_string \"\"",
    434       boot_path.value().c_str(),
    435       boot_partition_size);
    436 
    437   GenerateVBMetaImage(
    438       "vbmeta_a.img",
    439       "SHA256_RSA2048",
    440       4,
    441       base::FilePath("test/data/testkey_rsa2048.pem"),
    442       base::StringPrintf(
    443           "--include_descriptors_from_image %s"
    444           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
    445           " --internal_release_string \"\"",
    446           boot_path.value().c_str()));
    447 
    448   // Now replace the boot partition with something bigger and
    449   // different. Because FakeOps's get_size_of_partition() operation
    450   // just returns the file size it means that this is what is returned
    451   // by get_size_of_partition().
    452   //
    453   // Also make sure this image will return a different digest by using
    454   // a non-standard starting byte. This is to force avb_slot_verify()
    455   // to return ERROR_VERIFICATION below.
    456   GenerateImage("boot_a.img", new_boot_image_size, 1 /* start_byte */);
    457 
    458   ops_.set_expected_public_key(
    459       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    460 
    461   AvbSlotVerifyData* slot_data = NULL;
    462   const char* requested_partitions[] = {"boot", NULL};
    463   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    464             avb_slot_verify(ops_.avb_ops(),
    465                             requested_partitions,
    466                             "_a",
    467                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
    468                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    469                             &slot_data));
    470   EXPECT_NE(nullptr, slot_data);
    471 
    472   // Check that the loaded partition is actually
    473   // |new_boot_image_size|.
    474   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
    475   EXPECT_EQ("boot",
    476             std::string(slot_data->loaded_partitions[0].partition_name));
    477   EXPECT_EQ(new_boot_image_size, slot_data->loaded_partitions[0].data_size);
    478   avb_slot_verify_data_free(slot_data);
    479 }
    480 
    481 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMeta) {
    482   const size_t boot_partition_size = 16 * 1024 * 1024;
    483   const size_t boot_image_size = 5 * 1024 * 1024;
    484   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
    485 
    486   EXPECT_COMMAND(
    487       0,
    488       "./avbtool add_hash_footer"
    489       " --image %s"
    490       " --rollback_index 0"
    491       " --partition_name boot"
    492       " --partition_size %zd"
    493       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
    494       " --salt deadbeef"
    495       " --internal_release_string \"\"",
    496       boot_path.value().c_str(),
    497       boot_partition_size);
    498 
    499   GenerateVBMetaImage(
    500       "vbmeta_a.img",
    501       "SHA256_RSA2048",
    502       4,
    503       base::FilePath("test/data/testkey_rsa2048.pem"),
    504       base::StringPrintf(
    505           "--include_descriptors_from_image %s"
    506           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
    507           " --internal_release_string \"\"",
    508           boot_path.value().c_str()));
    509 
    510   EXPECT_EQ(
    511       "Minimum libavb version:   1.0\n"
    512       "Header Block:             256 bytes\n"
    513       "Authentication Block:     320 bytes\n"
    514       "Auxiliary Block:          896 bytes\n"
    515       "Algorithm:                SHA256_RSA2048\n"
    516       "Rollback Index:           4\n"
    517       "Flags:                    0\n"
    518       "Release String:           ''\n"
    519       "Descriptors:\n"
    520       "    Kernel Cmdline descriptor:\n"
    521       "      Flags:                 0\n"
    522       "      Kernel Cmdline:        'cmdline in vbmeta "
    523       "$(ANDROID_BOOT_PARTUUID)'\n"
    524       "    Kernel Cmdline descriptor:\n"
    525       "      Flags:                 0\n"
    526       "      Kernel Cmdline:        'cmdline in hash footer "
    527       "$(ANDROID_SYSTEM_PARTUUID)'\n"
    528       "    Hash descriptor:\n"
    529       "      Image Size:            5242880 bytes\n"
    530       "      Hash Algorithm:        sha256\n"
    531       "      Partition Name:        boot\n"
    532       "      Salt:                  deadbeef\n"
    533       "      Digest:                "
    534       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
    535       "      Flags:                 0\n",
    536       InfoImage(vbmeta_image_path_));
    537 
    538   EXPECT_COMMAND(0,
    539                  "./avbtool erase_footer"
    540                  " --image %s",
    541                  boot_path.value().c_str());
    542 
    543   // With no footer, 'avbtool info_image' should fail (exit status 1).
    544   EXPECT_COMMAND(
    545       1, "./avbtool info_image --image %s", boot_path.value().c_str());
    546 
    547   ops_.set_expected_public_key(
    548       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    549 
    550   AvbSlotVerifyData* slot_data = NULL;
    551   const char* requested_partitions[] = {"boot", NULL};
    552   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    553             avb_slot_verify(ops_.avb_ops(),
    554                             requested_partitions,
    555                             "_a",
    556                             AVB_SLOT_VERIFY_FLAGS_NONE,
    557                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    558                             &slot_data));
    559   EXPECT_NE(nullptr, slot_data);
    560 
    561   // Now verify the slot data. The vbmeta data should match our
    562   // vbmeta_image_ member.
    563   EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
    564   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
    565   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
    566   EXPECT_EQ(0,
    567             memcmp(vbmeta_image_.data(),
    568                    slot_data->vbmeta_images[0].vbmeta_data,
    569                    slot_data->vbmeta_images[0].vbmeta_size));
    570 
    571   // The boot image data should match what is generated above with
    572   // GenerateImage().
    573   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
    574   EXPECT_EQ("boot",
    575             std::string(slot_data->loaded_partitions[0].partition_name));
    576   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
    577   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
    578     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
    579   }
    580 
    581   // This should match the two cmdlines with a space (U+0020) between
    582   // them and the $(ANDROID_SYSTEM_PARTUUID) and
    583   // $(ANDROID_BOOT_PARTUUID) variables replaced.
    584   EXPECT_EQ(
    585       "cmdline in vbmeta 1234-fake-guid-for:boot_a cmdline in hash footer "
    586       "1234-fake-guid-for:system_a "
    587       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
    588       "androidboot.vbmeta.avb_version=1.1 "
    589       "androidboot.vbmeta.device_state=locked "
    590       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
    591       "androidboot.vbmeta.digest="
    592       "99e84e34697a77414f0d7dd7896e98ac4da2d26bdd3756ef59ec79918de2adbe "
    593       "androidboot.vbmeta.invalidate_on_error=yes "
    594       "androidboot.veritymode=enforcing",
    595       std::string(slot_data->cmdline));
    596   EXPECT_EQ(4UL, slot_data->rollback_indexes[0]);
    597   for (size_t n = 1; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
    598     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
    599   }
    600   avb_slot_verify_data_free(slot_data);
    601 }
    602 
    603 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMetaWithPreloadedPartition) {
    604   const size_t boot_partition_size = 16 * 1024 * 1024;
    605   const size_t boot_image_size = 5 * 1024 * 1024;
    606   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
    607 
    608   EXPECT_COMMAND(
    609       0,
    610       "./avbtool add_hash_footer"
    611       " --image %s"
    612       " --rollback_index 0"
    613       " --partition_name boot"
    614       " --partition_size %zd"
    615       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
    616       " --salt deadbeef"
    617       " --internal_release_string \"\"",
    618       boot_path.value().c_str(),
    619       boot_partition_size);
    620 
    621   GenerateVBMetaImage(
    622       "vbmeta_a.img",
    623       "SHA256_RSA2048",
    624       4,
    625       base::FilePath("test/data/testkey_rsa2048.pem"),
    626       base::StringPrintf(
    627           "--include_descriptors_from_image %s"
    628           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
    629           " --internal_release_string \"\"",
    630           boot_path.value().c_str()));
    631 
    632   EXPECT_COMMAND(0,
    633                  "./avbtool erase_footer"
    634                  " --image %s",
    635                  boot_path.value().c_str());
    636 
    637   // With no footer, 'avbtool info_image' should fail (exit status 1).
    638   EXPECT_COMMAND(
    639       1, "./avbtool info_image --image %s", boot_path.value().c_str());
    640 
    641   ops_.set_expected_public_key(
    642       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    643   ops_.enable_get_preloaded_partition();
    644   EXPECT_TRUE(ops_.preload_partition("boot_a", boot_path));
    645 
    646   AvbSlotVerifyData* slot_data = NULL;
    647   const char* requested_partitions[] = {"boot", NULL};
    648   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    649             avb_slot_verify(ops_.avb_ops(),
    650                             requested_partitions,
    651                             "_a",
    652                             AVB_SLOT_VERIFY_FLAGS_NONE,
    653                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    654                             &slot_data));
    655   EXPECT_NE(nullptr, slot_data);
    656 
    657   // Now verify the slot data. The vbmeta data should match our
    658   // vbmeta_image_ member.
    659   EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
    660   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
    661   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
    662   EXPECT_EQ(0,
    663             memcmp(vbmeta_image_.data(),
    664                    slot_data->vbmeta_images[0].vbmeta_data,
    665                    slot_data->vbmeta_images[0].vbmeta_size));
    666 
    667   // The boot image data should match what is generated above with
    668   // GenerateImage().
    669   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
    670   EXPECT_EQ("boot",
    671             std::string(slot_data->loaded_partitions[0].partition_name));
    672   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
    673   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
    674     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
    675   }
    676   EXPECT_TRUE(slot_data->loaded_partitions[0].preloaded);
    677 
    678   avb_slot_verify_data_free(slot_data);
    679 }
    680 
    681 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMetaCorruptBoot) {
    682   size_t boot_partition_size = 16 * 1024 * 1024;
    683   base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
    684   const char* requested_partitions[] = {"boot", NULL};
    685 
    686   EXPECT_COMMAND(0,
    687                  "./avbtool add_hash_footer"
    688                  " --image %s"
    689                  " --rollback_index 0"
    690                  " --partition_name boot"
    691                  " --partition_size %zd"
    692                  " --salt deadbeef"
    693                  " --internal_release_string \"\"",
    694                  boot_path.value().c_str(),
    695                  boot_partition_size);
    696 
    697   GenerateVBMetaImage("vbmeta_a.img",
    698                       "SHA256_RSA2048",
    699                       0,
    700                       base::FilePath("test/data/testkey_rsa2048.pem"),
    701                       base::StringPrintf("--include_descriptors_from_image %s"
    702                                          " --internal_release_string \"\"",
    703                                          boot_path.value().c_str()));
    704 
    705   EXPECT_COMMAND(0,
    706                  "./avbtool erase_footer"
    707                  " --image %s",
    708                  boot_path.value().c_str());
    709 
    710   ops_.set_expected_public_key(
    711       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    712 
    713   // So far, so good.
    714   AvbSlotVerifyData* slot_data = NULL;
    715   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    716             avb_slot_verify(ops_.avb_ops(),
    717                             requested_partitions,
    718                             "_a",
    719                             AVB_SLOT_VERIFY_FLAGS_NONE,
    720                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    721                             &slot_data));
    722   EXPECT_NE(nullptr, slot_data);
    723   avb_slot_verify_data_free(slot_data);
    724 
    725   // Now corrupt boot_a.img and expect verification error.
    726   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
    727   EXPECT_EQ(AVB_IO_RESULT_OK,
    728             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
    729                                                "boot_a",
    730                                                1024 * 1024,  // offset: 1 MiB
    731                                                sizeof corrupt_data,
    732                                                corrupt_data));
    733 
    734   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    735             avb_slot_verify(ops_.avb_ops(),
    736                             requested_partitions,
    737                             "_a",
    738                             AVB_SLOT_VERIFY_FLAGS_NONE,
    739                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    740                             &slot_data));
    741   EXPECT_EQ(nullptr, slot_data);
    742   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
    743             avb_slot_verify(ops_.avb_ops(),
    744                             requested_partitions,
    745                             "_a",
    746                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
    747                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    748                             &slot_data));
    749   EXPECT_NE(nullptr, slot_data);
    750   avb_slot_verify_data_free(slot_data);
    751 }
    752 
    753 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartition) {
    754   size_t boot_partition_size = 16 * 1024 * 1024;
    755   const size_t boot_image_size = 5 * 1024 * 1024;
    756   base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
    757   const char* requested_partitions[] = {"boot", NULL};
    758 
    759   EXPECT_COMMAND(0,
    760                  "./avbtool add_hash_footer"
    761                  " --image %s"
    762                  " --kernel_cmdline 'cmdline2 in hash footer'"
    763                  " --rollback_index 12"
    764                  " --partition_name boot"
    765                  " --partition_size %zd"
    766                  " --algorithm SHA256_RSA4096"
    767                  " --key test/data/testkey_rsa4096.pem"
    768                  " --salt deadbeef"
    769                  " --internal_release_string \"\"",
    770                  boot_path.value().c_str(),
    771                  boot_partition_size);
    772 
    773   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
    774   EXPECT_COMMAND(
    775       0,
    776       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
    777       " --output %s",
    778       pk_path.value().c_str());
    779 
    780   GenerateVBMetaImage(
    781       "vbmeta.img",
    782       "SHA256_RSA2048",
    783       11,
    784       base::FilePath("test/data/testkey_rsa2048.pem"),
    785       base::StringPrintf("--chain_partition boot:1:%s"
    786                          " --kernel_cmdline 'cmdline2 in vbmeta'"
    787                          " --internal_release_string \"\"",
    788                          pk_path.value().c_str()));
    789 
    790   EXPECT_EQ(
    791       "Minimum libavb version:   1.0\n"
    792       "Header Block:             256 bytes\n"
    793       "Authentication Block:     320 bytes\n"
    794       "Auxiliary Block:          1728 bytes\n"
    795       "Algorithm:                SHA256_RSA2048\n"
    796       "Rollback Index:           11\n"
    797       "Flags:                    0\n"
    798       "Release String:           ''\n"
    799       "Descriptors:\n"
    800       "    Chain Partition descriptor:\n"
    801       "      Partition Name:          boot\n"
    802       "      Rollback Index Location: 1\n"
    803       "      Public key (sha1):       "
    804       "2597c218aae470a130f61162feaae70afd97f011\n"
    805       "    Kernel Cmdline descriptor:\n"
    806       "      Flags:                 0\n"
    807       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
    808       InfoImage(vbmeta_image_path_));
    809 
    810   EXPECT_EQ(
    811       "Footer version:           1.0\n"
    812       "Image size:               16777216 bytes\n"
    813       "Original image size:      5242880 bytes\n"
    814       "VBMeta offset:            5242880\n"
    815       "VBMeta size:              2112 bytes\n"
    816       "--\n"
    817       "Minimum libavb version:   1.0\n"
    818       "Header Block:             256 bytes\n"
    819       "Authentication Block:     576 bytes\n"
    820       "Auxiliary Block:          1280 bytes\n"
    821       "Algorithm:                SHA256_RSA4096\n"
    822       "Rollback Index:           12\n"
    823       "Flags:                    0\n"
    824       "Release String:           ''\n"
    825       "Descriptors:\n"
    826       "    Hash descriptor:\n"
    827       "      Image Size:            5242880 bytes\n"
    828       "      Hash Algorithm:        sha256\n"
    829       "      Partition Name:        boot\n"
    830       "      Salt:                  deadbeef\n"
    831       "      Digest:                "
    832       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
    833       "      Flags:                 0\n"
    834       "    Kernel Cmdline descriptor:\n"
    835       "      Flags:                 0\n"
    836       "      Kernel Cmdline:        'cmdline2 in hash footer'\n",
    837       InfoImage(boot_path));
    838 
    839   ops_.set_expected_public_key(
    840       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    841 
    842   AvbSlotVerifyData* slot_data = NULL;
    843   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
    844             avb_slot_verify(ops_.avb_ops(),
    845                             requested_partitions,
    846                             "",
    847                             AVB_SLOT_VERIFY_FLAGS_NONE,
    848                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    849                             &slot_data));
    850   EXPECT_NE(nullptr, slot_data);
    851 
    852   // Now verify the slot data. We should have two vbmeta
    853   // structs. Verify both of them. Note that the A/B suffix isn't
    854   // appended.
    855   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
    856   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
    857   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
    858   EXPECT_EQ(0,
    859             memcmp(vbmeta_image_.data(),
    860                    slot_data->vbmeta_images[0].vbmeta_data,
    861                    slot_data->vbmeta_images[0].vbmeta_size));
    862   // And for the second vbmeta struct we check that the descriptors
    863   // match the info_image output from above.
    864   EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
    865   const AvbDescriptor** descriptors =
    866       avb_descriptor_get_all(slot_data->vbmeta_images[1].vbmeta_data,
    867                              slot_data->vbmeta_images[1].vbmeta_size,
    868                              NULL);
    869   EXPECT_NE(nullptr, descriptors);
    870   AvbHashDescriptor hash_desc;
    871   EXPECT_EQ(true,
    872             avb_hash_descriptor_validate_and_byteswap(
    873                 ((AvbHashDescriptor*)descriptors[0]), &hash_desc));
    874   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
    875                             sizeof(AvbHashDescriptor);
    876   uint64_t o = 0;
    877   EXPECT_EQ("boot",
    878             std::string(reinterpret_cast<const char*>(desc_end + o),
    879                         hash_desc.partition_name_len));
    880   o += hash_desc.partition_name_len;
    881   EXPECT_EQ("deadbeef", mem_to_hexstring(desc_end + o, hash_desc.salt_len));
    882   o += hash_desc.salt_len;
    883   EXPECT_EQ("184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d",
    884             mem_to_hexstring(desc_end + o, hash_desc.digest_len));
    885   AvbKernelCmdlineDescriptor cmdline_desc;
    886   EXPECT_EQ(true,
    887             avb_kernel_cmdline_descriptor_validate_and_byteswap(
    888                 ((AvbKernelCmdlineDescriptor*)descriptors[1]), &cmdline_desc));
    889   desc_end = reinterpret_cast<const uint8_t*>(descriptors[1]) +
    890              sizeof(AvbKernelCmdlineDescriptor);
    891   EXPECT_EQ("cmdline2 in hash footer",
    892             std::string(reinterpret_cast<const char*>(desc_end),
    893                         cmdline_desc.kernel_cmdline_length));
    894   avb_free(descriptors);
    895 
    896   // The boot image data should match what is generated above with
    897   // GenerateImage().
    898   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
    899   EXPECT_EQ("boot",
    900             std::string(slot_data->loaded_partitions[0].partition_name));
    901   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
    902   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
    903     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
    904   }
    905 
    906   // This should match the two cmdlines with a space (U+0020) between them.
    907   EXPECT_EQ(
    908       "cmdline2 in hash footer cmdline2 in vbmeta "
    909       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
    910       "androidboot.vbmeta.avb_version=1.1 "
    911       "androidboot.vbmeta.device_state=locked "
    912       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
    913       "androidboot.vbmeta.digest="
    914       "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4 "
    915       "androidboot.vbmeta.invalidate_on_error=yes "
    916       "androidboot.veritymode=enforcing",
    917       std::string(slot_data->cmdline));
    918   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
    919   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
    920   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
    921     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
    922   }
    923   uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
    924   avb_slot_verify_data_calculate_vbmeta_digest(
    925       slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
    926   EXPECT_EQ("4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
    927             mem_to_hexstring(vbmeta_digest, AVB_SHA256_DIGEST_SIZE));
    928   avb_slot_verify_data_free(slot_data);
    929 
    930   EXPECT_EQ("4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
    931             CalcVBMetaDigest("vbmeta.img", "sha256"));
    932 }
    933 
    934 TEST_F(AvbSlotVerifyTest, HashDescriptorInOtherVBMetaPartition) {
    935   size_t boot_partition_size = 16 * 1024 * 1024;
    936   const size_t boot_image_size = 5 * 1024 * 1024;
    937   base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
    938   base::FilePath other_vbmeta_path = testdir_.Append("vbmeta_google.img");
    939   const char* requested_partitions[] = {"boot", NULL};
    940 
    941   EXPECT_COMMAND(0,
    942                  "./avbtool add_hash_footer"
    943                  " --image %s"
    944                  " --kernel_cmdline 'cmdline2 in hash footer'"
    945                  " --rollback_index 12"
    946                  " --partition_name boot"
    947                  " --partition_size %zd"
    948                  " --algorithm SHA256_RSA4096"
    949                  " --key test/data/testkey_rsa4096.pem"
    950                  " --salt deadbeef"
    951                  " --internal_release_string \"\"",
    952                  boot_path.value().c_str(),
    953                  boot_partition_size);
    954 
    955   // Extract the vbmeta blob from the footer in boot.img, put it into
    956   // vbmeta_google.img, and erase the footer from boot.img
    957   EXPECT_COMMAND(0,
    958                  "./avbtool extract_vbmeta_image"
    959                  " --image %s"
    960                  " --output %s",
    961                  boot_path.value().c_str(),
    962                  other_vbmeta_path.value().c_str());
    963   EXPECT_COMMAND(0,
    964                  "./avbtool erase_footer"
    965                  " --image %s",
    966                  boot_path.value().c_str());
    967 
    968   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
    969   EXPECT_COMMAND(
    970       0,
    971       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
    972       " --output %s",
    973       pk_path.value().c_str());
    974 
    975   GenerateVBMetaImage(
    976       "vbmeta.img",
    977       "SHA256_RSA2048",
    978       11,
    979       base::FilePath("test/data/testkey_rsa2048.pem"),
    980       base::StringPrintf("--chain_partition vbmeta_google:1:%s"
    981                          " --kernel_cmdline 'cmdline2 in vbmeta'"
    982                          " --internal_release_string \"\"",
    983                          pk_path.value().c_str()));
    984 
    985   EXPECT_EQ(
    986       "Minimum libavb version:   1.0\n"
    987       "Header Block:             256 bytes\n"
    988       "Authentication Block:     320 bytes\n"
    989       "Auxiliary Block:          1728 bytes\n"
    990       "Algorithm:                SHA256_RSA2048\n"
    991       "Rollback Index:           11\n"
    992       "Flags:                    0\n"
    993       "Release String:           ''\n"
    994       "Descriptors:\n"
    995       "    Chain Partition descriptor:\n"
    996       "      Partition Name:          vbmeta_google\n"
    997       "      Rollback Index Location: 1\n"
    998       "      Public key (sha1):       "
    999       "2597c218aae470a130f61162feaae70afd97f011\n"
   1000       "    Kernel Cmdline descriptor:\n"
   1001       "      Flags:                 0\n"
   1002       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
   1003       InfoImage(vbmeta_image_path_));
   1004 
   1005   EXPECT_EQ(
   1006       "Minimum libavb version:   1.0\n"
   1007       "Header Block:             256 bytes\n"
   1008       "Authentication Block:     576 bytes\n"
   1009       "Auxiliary Block:          1280 bytes\n"
   1010       "Algorithm:                SHA256_RSA4096\n"
   1011       "Rollback Index:           12\n"
   1012       "Flags:                    0\n"
   1013       "Release String:           ''\n"
   1014       "Descriptors:\n"
   1015       "    Hash descriptor:\n"
   1016       "      Image Size:            5242880 bytes\n"
   1017       "      Hash Algorithm:        sha256\n"
   1018       "      Partition Name:        boot\n"
   1019       "      Salt:                  deadbeef\n"
   1020       "      Digest:                "
   1021       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
   1022       "      Flags:                 0\n"
   1023       "    Kernel Cmdline descriptor:\n"
   1024       "      Flags:                 0\n"
   1025       "      Kernel Cmdline:        'cmdline2 in hash footer'\n",
   1026       InfoImage(other_vbmeta_path));
   1027 
   1028   ops_.set_expected_public_key(
   1029       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1030 
   1031   AvbSlotVerifyData* slot_data = NULL;
   1032   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1033             avb_slot_verify(ops_.avb_ops(),
   1034                             requested_partitions,
   1035                             "",
   1036                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1037                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1038                             &slot_data));
   1039   EXPECT_NE(nullptr, slot_data);
   1040 
   1041   // Now verify the slot data. We should have two vbmeta
   1042   // structs. Verify both of them. Note that the A/B suffix isn't
   1043   // appended.
   1044   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
   1045   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
   1046   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
   1047   EXPECT_EQ(0,
   1048             memcmp(vbmeta_image_.data(),
   1049                    slot_data->vbmeta_images[0].vbmeta_data,
   1050                    slot_data->vbmeta_images[0].vbmeta_size));
   1051   // And for the second vbmeta struct we check that the descriptors
   1052   // match the info_image output from above.
   1053   EXPECT_EQ("vbmeta_google",
   1054             std::string(slot_data->vbmeta_images[1].partition_name));
   1055   const AvbDescriptor** descriptors =
   1056       avb_descriptor_get_all(slot_data->vbmeta_images[1].vbmeta_data,
   1057                              slot_data->vbmeta_images[1].vbmeta_size,
   1058                              NULL);
   1059   EXPECT_NE(nullptr, descriptors);
   1060   AvbHashDescriptor hash_desc;
   1061   EXPECT_EQ(true,
   1062             avb_hash_descriptor_validate_and_byteswap(
   1063                 ((AvbHashDescriptor*)descriptors[0]), &hash_desc));
   1064   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
   1065                             sizeof(AvbHashDescriptor);
   1066   uint64_t o = 0;
   1067   EXPECT_EQ("boot",
   1068             std::string(reinterpret_cast<const char*>(desc_end + o),
   1069                         hash_desc.partition_name_len));
   1070   o += hash_desc.partition_name_len;
   1071   EXPECT_EQ("deadbeef", mem_to_hexstring(desc_end + o, hash_desc.salt_len));
   1072   o += hash_desc.salt_len;
   1073   EXPECT_EQ("184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d",
   1074             mem_to_hexstring(desc_end + o, hash_desc.digest_len));
   1075   AvbKernelCmdlineDescriptor cmdline_desc;
   1076   EXPECT_EQ(true,
   1077             avb_kernel_cmdline_descriptor_validate_and_byteswap(
   1078                 ((AvbKernelCmdlineDescriptor*)descriptors[1]), &cmdline_desc));
   1079   desc_end = reinterpret_cast<const uint8_t*>(descriptors[1]) +
   1080              sizeof(AvbKernelCmdlineDescriptor);
   1081   EXPECT_EQ("cmdline2 in hash footer",
   1082             std::string(reinterpret_cast<const char*>(desc_end),
   1083                         cmdline_desc.kernel_cmdline_length));
   1084   avb_free(descriptors);
   1085 
   1086   // The boot image data should match what is generated above with
   1087   // GenerateImage().
   1088   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
   1089   EXPECT_EQ("boot",
   1090             std::string(slot_data->loaded_partitions[0].partition_name));
   1091   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
   1092   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
   1093     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
   1094   }
   1095 
   1096   // This should match the two cmdlines with a space (U+0020) between them.
   1097   EXPECT_EQ(
   1098       "cmdline2 in hash footer cmdline2 in vbmeta "
   1099       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
   1100       "androidboot.vbmeta.avb_version=1.1 "
   1101       "androidboot.vbmeta.device_state=locked "
   1102       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
   1103       "androidboot.vbmeta.digest="
   1104       "232447e92370ed31c2b6c5fb7328eb5d828a9819b3e6f6c10d96b9ca6fd209a1 "
   1105       "androidboot.vbmeta.invalidate_on_error=yes "
   1106       "androidboot.veritymode=enforcing",
   1107       std::string(slot_data->cmdline));
   1108   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
   1109   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
   1110   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
   1111     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
   1112   }
   1113   uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
   1114   avb_slot_verify_data_calculate_vbmeta_digest(
   1115       slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
   1116   EXPECT_EQ("232447e92370ed31c2b6c5fb7328eb5d828a9819b3e6f6c10d96b9ca6fd209a1",
   1117             mem_to_hexstring(vbmeta_digest, AVB_SHA256_DIGEST_SIZE));
   1118   avb_slot_verify_data_free(slot_data);
   1119 
   1120   EXPECT_EQ("232447e92370ed31c2b6c5fb7328eb5d828a9819b3e6f6c10d96b9ca6fd209a1",
   1121             CalcVBMetaDigest("vbmeta.img", "sha256"));
   1122 }
   1123 
   1124 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionCorruptBoot) {
   1125   size_t boot_partition_size = 16 * 1024 * 1024;
   1126   base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
   1127   const char* requested_partitions[] = {"boot", NULL};
   1128 
   1129   EXPECT_COMMAND(0,
   1130                  "./avbtool add_hash_footer"
   1131                  " --image %s"
   1132                  " --rollback_index 0"
   1133                  " --partition_name boot"
   1134                  " --partition_size %zd"
   1135                  " --algorithm SHA256_RSA4096"
   1136                  " --key test/data/testkey_rsa4096.pem"
   1137                  " --salt deadbeef"
   1138                  " --internal_release_string \"\"",
   1139                  boot_path.value().c_str(),
   1140                  boot_partition_size);
   1141 
   1142   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   1143   EXPECT_COMMAND(
   1144       0,
   1145       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   1146       " --output %s",
   1147       pk_path.value().c_str());
   1148 
   1149   GenerateVBMetaImage("vbmeta_a.img",
   1150                       "SHA256_RSA2048",
   1151                       0,
   1152                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1153                       base::StringPrintf("--chain_partition boot:1:%s"
   1154                                          " --internal_release_string \"\"",
   1155                                          pk_path.value().c_str()));
   1156 
   1157   ops_.set_expected_public_key(
   1158       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1159 
   1160   AvbSlotVerifyData* slot_data = NULL;
   1161   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1162             avb_slot_verify(ops_.avb_ops(),
   1163                             requested_partitions,
   1164                             "_a",
   1165                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1166                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1167                             &slot_data));
   1168   EXPECT_NE(nullptr, slot_data);
   1169   avb_slot_verify_data_free(slot_data);
   1170 
   1171   // Now corrupt boot_a.img and expect verification error.
   1172   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
   1173   EXPECT_EQ(AVB_IO_RESULT_OK,
   1174             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
   1175                                                "boot_a",
   1176                                                1024 * 1024,  // offset: 1 MiB
   1177                                                sizeof corrupt_data,
   1178                                                corrupt_data));
   1179 
   1180   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
   1181             avb_slot_verify(ops_.avb_ops(),
   1182                             requested_partitions,
   1183                             "_a",
   1184                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1185                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1186                             &slot_data));
   1187   EXPECT_EQ(nullptr, slot_data);
   1188   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
   1189             avb_slot_verify(ops_.avb_ops(),
   1190                             requested_partitions,
   1191                             "_a",
   1192                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
   1193                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1194                             &slot_data));
   1195   EXPECT_NE(nullptr, slot_data);
   1196   avb_slot_verify_data_free(slot_data);
   1197 }
   1198 
   1199 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionKeyMismatch) {
   1200   size_t boot_partition_size = 16 * 1024 * 1024;
   1201   base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
   1202   const char* requested_partitions[] = {"boot", NULL};
   1203 
   1204   // Use different key to sign vbmeta in boot_a (we use the 8192 bit
   1205   // key) than what's in the chained partition descriptor (which is
   1206   // the 4096 bit key) and expect
   1207   // AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED.
   1208 
   1209   EXPECT_COMMAND(0,
   1210                  "./avbtool add_hash_footer"
   1211                  " --image %s"
   1212                  " --rollback_index 0"
   1213                  " --partition_name boot"
   1214                  " --partition_size %zd"
   1215                  " --algorithm SHA256_RSA8192"
   1216                  " --key test/data/testkey_rsa8192.pem"
   1217                  " --salt deadbeef"
   1218                  " --internal_release_string \"\"",
   1219                  boot_path.value().c_str(),
   1220                  boot_partition_size);
   1221 
   1222   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   1223   EXPECT_COMMAND(
   1224       0,
   1225       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   1226       " --output %s",
   1227       pk_path.value().c_str());
   1228 
   1229   GenerateVBMetaImage("vbmeta_a.img",
   1230                       "SHA256_RSA2048",
   1231                       0,
   1232                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1233                       base::StringPrintf("--chain_partition boot:1:%s"
   1234                                          " --internal_release_string \"\"",
   1235                                          pk_path.value().c_str()));
   1236 
   1237   ops_.set_expected_public_key(
   1238       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1239 
   1240   AvbSlotVerifyData* slot_data = NULL;
   1241   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
   1242             avb_slot_verify(ops_.avb_ops(),
   1243                             requested_partitions,
   1244                             "_a",
   1245                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1246                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1247                             &slot_data));
   1248   EXPECT_EQ(nullptr, slot_data);
   1249   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
   1250             avb_slot_verify(ops_.avb_ops(),
   1251                             requested_partitions,
   1252                             "_a",
   1253                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
   1254                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1255                             &slot_data));
   1256   EXPECT_NE(nullptr, slot_data);
   1257   avb_slot_verify_data_free(slot_data);
   1258 }
   1259 
   1260 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionRollbackIndexFail) {
   1261   size_t boot_partition_size = 16 * 1024 * 1024;
   1262   base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
   1263   const char* requested_partitions[] = {"boot", NULL};
   1264 
   1265   EXPECT_COMMAND(0,
   1266                  "./avbtool add_hash_footer"
   1267                  " --image %s"
   1268                  " --rollback_index 10"
   1269                  " --partition_name boot"
   1270                  " --partition_size %zd"
   1271                  " --algorithm SHA256_RSA4096"
   1272                  " --key test/data/testkey_rsa4096.pem"
   1273                  " --salt deadbeef"
   1274                  " --internal_release_string \"\"",
   1275                  boot_path.value().c_str(),
   1276                  boot_partition_size);
   1277 
   1278   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   1279   EXPECT_COMMAND(
   1280       0,
   1281       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   1282       " --output %s",
   1283       pk_path.value().c_str());
   1284 
   1285   GenerateVBMetaImage("vbmeta_a.img",
   1286                       "SHA256_RSA2048",
   1287                       110,
   1288                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1289                       base::StringPrintf("--chain_partition boot:1:%s"
   1290                                          " --internal_release_string \"\"",
   1291                                          pk_path.value().c_str()));
   1292 
   1293   ops_.set_expected_public_key(
   1294       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1295 
   1296   AvbSlotVerifyData* slot_data = NULL;
   1297 
   1298   // Both images (vbmeta_a and boot_a) have rollback index 10 and 11
   1299   // so it should work if the stored rollback indexes are 0 and 0.
   1300   ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}});
   1301   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1302             avb_slot_verify(ops_.avb_ops(),
   1303                             requested_partitions,
   1304                             "_a",
   1305                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1306                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1307                             &slot_data));
   1308   EXPECT_NE(nullptr, slot_data);
   1309   avb_slot_verify_data_free(slot_data);
   1310 
   1311   // Check failure if we set the stored rollback index of the chained
   1312   // partition to 20 (see AvbSlotVerifyTest.RollbackIndex above
   1313   // where we test rollback index checks for the vbmeta partition).
   1314   ops_.set_stored_rollback_indexes({{0, 0}, {1, 20}});
   1315   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
   1316             avb_slot_verify(ops_.avb_ops(),
   1317                             requested_partitions,
   1318                             "_a",
   1319                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1320                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1321                             &slot_data));
   1322   EXPECT_EQ(nullptr, slot_data);
   1323   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
   1324             avb_slot_verify(ops_.avb_ops(),
   1325                             requested_partitions,
   1326                             "_a",
   1327                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
   1328                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1329                             &slot_data));
   1330   EXPECT_NE(nullptr, slot_data);
   1331   avb_slot_verify_data_free(slot_data);
   1332 
   1333   // Check failure if there is no rollback index slot 1 - in that case
   1334   // we expect an I/O error since ops->read_rollback_index() will
   1335   // fail.
   1336   ops_.set_stored_rollback_indexes({{0, 0}});
   1337   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
   1338             avb_slot_verify(ops_.avb_ops(),
   1339                             requested_partitions,
   1340                             "_a",
   1341                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1342                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1343                             &slot_data));
   1344   EXPECT_EQ(nullptr, slot_data);
   1345 }
   1346 
   1347 TEST_F(AvbSlotVerifyTest, ChainedPartitionNoSlots) {
   1348   size_t boot_partition_size = 16 * 1024 * 1024;
   1349   const size_t boot_image_size = 5 * 1024 * 1024;
   1350   base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
   1351   const char* requested_partitions[] = {"boot", NULL};
   1352 
   1353   EXPECT_COMMAND(0,
   1354                  "./avbtool add_hash_footer"
   1355                  " --image %s"
   1356                  " --kernel_cmdline 'cmdline2 in hash footer'"
   1357                  " --rollback_index 12"
   1358                  " --partition_name boot"
   1359                  " --partition_size %zd"
   1360                  " --algorithm SHA256_RSA4096"
   1361                  " --key test/data/testkey_rsa4096.pem"
   1362                  " --salt deadbeef"
   1363                  " --internal_release_string \"\"",
   1364                  boot_path.value().c_str(),
   1365                  boot_partition_size);
   1366 
   1367   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   1368   EXPECT_COMMAND(
   1369       0,
   1370       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   1371       " --output %s",
   1372       pk_path.value().c_str());
   1373 
   1374   GenerateVBMetaImage(
   1375       "vbmeta.img",
   1376       "SHA256_RSA2048",
   1377       11,
   1378       base::FilePath("test/data/testkey_rsa2048.pem"),
   1379       base::StringPrintf("--chain_partition boot:1:%s"
   1380                          " --kernel_cmdline 'cmdline2 in vbmeta'"
   1381                          " --internal_release_string \"\"",
   1382                          pk_path.value().c_str()));
   1383 
   1384   EXPECT_EQ(
   1385       "Minimum libavb version:   1.0\n"
   1386       "Header Block:             256 bytes\n"
   1387       "Authentication Block:     320 bytes\n"
   1388       "Auxiliary Block:          1728 bytes\n"
   1389       "Algorithm:                SHA256_RSA2048\n"
   1390       "Rollback Index:           11\n"
   1391       "Flags:                    0\n"
   1392       "Release String:           ''\n"
   1393       "Descriptors:\n"
   1394       "    Chain Partition descriptor:\n"
   1395       "      Partition Name:          boot\n"
   1396       "      Rollback Index Location: 1\n"
   1397       "      Public key (sha1):       "
   1398       "2597c218aae470a130f61162feaae70afd97f011\n"
   1399       "    Kernel Cmdline descriptor:\n"
   1400       "      Flags:                 0\n"
   1401       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
   1402       InfoImage(vbmeta_image_path_));
   1403 
   1404   ops_.set_expected_public_key(
   1405       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1406 
   1407   AvbSlotVerifyData* slot_data = NULL;
   1408   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1409             avb_slot_verify(ops_.avb_ops(),
   1410                             requested_partitions,
   1411                             "",
   1412                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1413                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1414                             &slot_data));
   1415   EXPECT_NE(nullptr, slot_data);
   1416 
   1417   // Now verify the slot data. The first vbmeta data should match our
   1418   // vbmeta_image_ member and the second one should be for the 'boot'
   1419   // partition.
   1420   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
   1421   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
   1422   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
   1423   EXPECT_EQ(0,
   1424             memcmp(vbmeta_image_.data(),
   1425                    slot_data->vbmeta_images[0].vbmeta_data,
   1426                    slot_data->vbmeta_images[0].vbmeta_size));
   1427   EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
   1428 
   1429   // The boot image data should match what is generated above with
   1430   // GenerateImage().
   1431   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
   1432   EXPECT_EQ("boot",
   1433             std::string(slot_data->loaded_partitions[0].partition_name));
   1434   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
   1435   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
   1436     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
   1437   }
   1438 
   1439   // This should match the two cmdlines with a space (U+0020) between
   1440   // them.
   1441   EXPECT_EQ(
   1442       "cmdline2 in hash footer cmdline2 in vbmeta "
   1443       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
   1444       "androidboot.vbmeta.avb_version=1.1 "
   1445       "androidboot.vbmeta.device_state=locked "
   1446       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
   1447       "androidboot.vbmeta.digest="
   1448       "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4 "
   1449       "androidboot.vbmeta.invalidate_on_error=yes "
   1450       "androidboot.veritymode=enforcing",
   1451       std::string(slot_data->cmdline));
   1452   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
   1453   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
   1454   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
   1455     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
   1456   }
   1457   avb_slot_verify_data_free(slot_data);
   1458 }
   1459 
   1460 TEST_F(AvbSlotVerifyTest, PartitionsOtherThanBoot) {
   1461   const size_t foo_partition_size = 16 * 1024 * 1024;
   1462   const size_t bar_partition_size = 32 * 1024 * 1024;
   1463   const size_t foo_image_size = 5 * 1024 * 1024;
   1464   const size_t bar_image_size = 10 * 1024 * 1024;
   1465   base::FilePath foo_path = GenerateImage("foo_a.img", foo_image_size);
   1466   base::FilePath bar_path = GenerateImage("bar_a.img", bar_image_size);
   1467 
   1468   EXPECT_COMMAND(0,
   1469                  "./avbtool add_hash_footer"
   1470                  " --image %s"
   1471                  " --partition_name foo"
   1472                  " --partition_size %zd"
   1473                  " --salt deadbeef"
   1474                  " --internal_release_string \"\"",
   1475                  foo_path.value().c_str(),
   1476                  foo_partition_size);
   1477 
   1478   EXPECT_COMMAND(0,
   1479                  "./avbtool add_hash_footer"
   1480                  " --image %s"
   1481                  " --partition_name bar"
   1482                  " --partition_size %zd"
   1483                  " --salt deadbeef"
   1484                  " --internal_release_string \"\"",
   1485                  bar_path.value().c_str(),
   1486                  bar_partition_size);
   1487 
   1488   GenerateVBMetaImage("vbmeta_a.img",
   1489                       "SHA256_RSA2048",
   1490                       4,
   1491                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1492                       base::StringPrintf("--include_descriptors_from_image %s"
   1493                                          " --include_descriptors_from_image %s"
   1494                                          " --internal_release_string \"\"",
   1495                                          foo_path.value().c_str(),
   1496                                          bar_path.value().c_str()));
   1497 
   1498   EXPECT_EQ(
   1499       "Minimum libavb version:   1.0\n"
   1500       "Header Block:             256 bytes\n"
   1501       "Authentication Block:     320 bytes\n"
   1502       "Auxiliary Block:          896 bytes\n"
   1503       "Algorithm:                SHA256_RSA2048\n"
   1504       "Rollback Index:           4\n"
   1505       "Flags:                    0\n"
   1506       "Release String:           ''\n"
   1507       "Descriptors:\n"
   1508       "    Hash descriptor:\n"
   1509       "      Image Size:            10485760 bytes\n"
   1510       "      Hash Algorithm:        sha256\n"
   1511       "      Partition Name:        bar\n"
   1512       "      Salt:                  deadbeef\n"
   1513       "      Digest:                "
   1514       "baea4bbd261d0edf4d1fe5e6e5a36976c291eeba66b6a46fa81dba691327a727\n"
   1515       "      Flags:                 0\n"
   1516       "    Hash descriptor:\n"
   1517       "      Image Size:            5242880 bytes\n"
   1518       "      Hash Algorithm:        sha256\n"
   1519       "      Partition Name:        foo\n"
   1520       "      Salt:                  deadbeef\n"
   1521       "      Digest:                "
   1522       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
   1523       "      Flags:                 0\n",
   1524       InfoImage(vbmeta_image_path_));
   1525 
   1526   ops_.set_expected_public_key(
   1527       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1528 
   1529   AvbSlotVerifyData* slot_data = NULL;
   1530   const char* requested_partitions[] = {"foo", "bar", NULL};
   1531   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1532             avb_slot_verify(ops_.avb_ops(),
   1533                             requested_partitions,
   1534                             "_a",
   1535                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1536                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1537                             &slot_data));
   1538   EXPECT_NE(nullptr, slot_data);
   1539 
   1540   // Now verify the slot data. The vbmeta data should match our
   1541   // vbmeta_image_ member.
   1542   EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
   1543   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
   1544   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
   1545   EXPECT_EQ(0,
   1546             memcmp(vbmeta_image_.data(),
   1547                    slot_data->vbmeta_images[0].vbmeta_data,
   1548                    slot_data->vbmeta_images[0].vbmeta_size));
   1549 
   1550   // The 'foo' and 'bar' image data should match what is generated
   1551   // above with GenerateImage().
   1552   EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
   1553   EXPECT_EQ("bar", std::string(slot_data->loaded_partitions[0].partition_name));
   1554   EXPECT_EQ(bar_image_size, slot_data->loaded_partitions[0].data_size);
   1555   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
   1556     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
   1557   }
   1558   EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[1].partition_name));
   1559   EXPECT_EQ(foo_image_size, slot_data->loaded_partitions[1].data_size);
   1560   for (size_t n = 0; n < slot_data->loaded_partitions[1].data_size; n++) {
   1561     EXPECT_EQ(slot_data->loaded_partitions[1].data[n], uint8_t(n));
   1562   }
   1563   avb_slot_verify_data_free(slot_data);
   1564 
   1565   // Check that we loaded vbmeta_a, foo_a, and bar_a.
   1566   std::set<std::string> partitions = ops_.get_partition_names_read_from();
   1567   EXPECT_EQ(size_t(3), partitions.size());
   1568   EXPECT_TRUE(partitions.find("vbmeta_a") != partitions.end());
   1569   EXPECT_TRUE(partitions.find("foo_a") != partitions.end());
   1570   EXPECT_TRUE(partitions.find("bar_a") != partitions.end());
   1571 }
   1572 
   1573 TEST_F(AvbSlotVerifyTest, OnlyLoadWhatHasBeenRequested) {
   1574   const size_t foo_partition_size = 16 * 1024 * 1024;
   1575   const size_t bar_partition_size = 32 * 1024 * 1024;
   1576   const size_t foo_image_size = 5 * 1024 * 1024;
   1577   const size_t bar_image_size = 10 * 1024 * 1024;
   1578   base::FilePath foo_path = GenerateImage("foo_a.img", foo_image_size);
   1579   base::FilePath bar_path = GenerateImage("bar_a.img", bar_image_size);
   1580 
   1581   EXPECT_COMMAND(0,
   1582                  "./avbtool add_hash_footer"
   1583                  " --image %s"
   1584                  " --partition_name foo"
   1585                  " --partition_size %zd"
   1586                  " --salt deadbeef"
   1587                  " --internal_release_string \"\"",
   1588                  foo_path.value().c_str(),
   1589                  foo_partition_size);
   1590 
   1591   EXPECT_COMMAND(0,
   1592                  "./avbtool add_hash_footer"
   1593                  " --image %s"
   1594                  " --partition_name bar"
   1595                  " --partition_size %zd"
   1596                  " --salt deadbeef"
   1597                  " --internal_release_string \"\"",
   1598                  bar_path.value().c_str(),
   1599                  bar_partition_size);
   1600 
   1601   GenerateVBMetaImage("vbmeta_a.img",
   1602                       "SHA256_RSA2048",
   1603                       4,
   1604                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1605                       base::StringPrintf("--include_descriptors_from_image %s"
   1606                                          " --include_descriptors_from_image %s"
   1607                                          " --internal_release_string \"\"",
   1608                                          foo_path.value().c_str(),
   1609                                          bar_path.value().c_str()));
   1610 
   1611   EXPECT_EQ(
   1612       "Minimum libavb version:   1.0\n"
   1613       "Header Block:             256 bytes\n"
   1614       "Authentication Block:     320 bytes\n"
   1615       "Auxiliary Block:          896 bytes\n"
   1616       "Algorithm:                SHA256_RSA2048\n"
   1617       "Rollback Index:           4\n"
   1618       "Flags:                    0\n"
   1619       "Release String:           ''\n"
   1620       "Descriptors:\n"
   1621       "    Hash descriptor:\n"
   1622       "      Image Size:            10485760 bytes\n"
   1623       "      Hash Algorithm:        sha256\n"
   1624       "      Partition Name:        bar\n"
   1625       "      Salt:                  deadbeef\n"
   1626       "      Digest:                "
   1627       "baea4bbd261d0edf4d1fe5e6e5a36976c291eeba66b6a46fa81dba691327a727\n"
   1628       "      Flags:                 0\n"
   1629       "    Hash descriptor:\n"
   1630       "      Image Size:            5242880 bytes\n"
   1631       "      Hash Algorithm:        sha256\n"
   1632       "      Partition Name:        foo\n"
   1633       "      Salt:                  deadbeef\n"
   1634       "      Digest:                "
   1635       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
   1636       "      Flags:                 0\n",
   1637       InfoImage(vbmeta_image_path_));
   1638 
   1639   ops_.set_expected_public_key(
   1640       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1641   AvbSlotVerifyData* slot_data = NULL;
   1642   const char* requested_partitions[] = {"foo", NULL};
   1643   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1644             avb_slot_verify(ops_.avb_ops(),
   1645                             requested_partitions,
   1646                             "_a",
   1647                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1648                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1649                             &slot_data));
   1650   EXPECT_NE(nullptr, slot_data);
   1651   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
   1652   EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[0].partition_name));
   1653   avb_slot_verify_data_free(slot_data);
   1654 
   1655   // Check that we loaded vbmeta_a, foo_a but not bar_a.
   1656   std::set<std::string> partitions = ops_.get_partition_names_read_from();
   1657   EXPECT_EQ(size_t(2), partitions.size());
   1658   EXPECT_TRUE(partitions.find("vbmeta_a") != partitions.end());
   1659   EXPECT_TRUE(partitions.find("foo_a") != partitions.end());
   1660   EXPECT_TRUE(partitions.find("bar_a") == partitions.end());
   1661 }
   1662 
   1663 TEST_F(AvbSlotVerifyTest, PublicKeyMetadata) {
   1664   base::FilePath md_path = GenerateImage("md.bin", 1536);
   1665 
   1666   GenerateVBMetaImage("vbmeta_a.img",
   1667                       "SHA256_RSA2048",
   1668                       0,
   1669                       base::FilePath("test/data/testkey_rsa2048.pem"),
   1670                       base::StringPrintf("--public_key_metadata %s"
   1671                                          " --internal_release_string \"\"",
   1672                                          md_path.value().c_str()));
   1673 
   1674   ops_.set_expected_public_key(
   1675       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1676 
   1677   std::string md_data;
   1678   ASSERT_TRUE(base::ReadFileToString(md_path, &md_data));
   1679   ops_.set_expected_public_key_metadata(md_data);
   1680 
   1681   AvbSlotVerifyData* slot_data = NULL;
   1682   const char* requested_partitions[] = {"boot", NULL};
   1683   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1684             avb_slot_verify(ops_.avb_ops(),
   1685                             requested_partitions,
   1686                             "_a",
   1687                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1688                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1689                             &slot_data));
   1690   EXPECT_NE(nullptr, slot_data);
   1691   EXPECT_EQ(
   1692       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   1693       "androidboot.vbmeta.avb_version=1.1 "
   1694       "androidboot.vbmeta.device_state=locked "
   1695       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=2688 "
   1696       "androidboot.vbmeta.digest="
   1697       "5edcaa54f40382ee6a2fc3b86cdf383348b35ed07955e83ea32d84b69a97eaa0 "
   1698       "androidboot.vbmeta.invalidate_on_error=yes "
   1699       "androidboot.veritymode=enforcing",
   1700       std::string(slot_data->cmdline));
   1701   avb_slot_verify_data_free(slot_data);
   1702 }
   1703 
   1704 void AvbSlotVerifyTest::CmdlineWithHashtreeVerification(
   1705     bool hashtree_verification_on) {
   1706   const size_t rootfs_size = 1028 * 1024;
   1707   const size_t partition_size = 1536 * 1024;
   1708 
   1709   // Generate a 1028 KiB file with known content.
   1710   std::vector<uint8_t> rootfs;
   1711   rootfs.resize(rootfs_size);
   1712   for (size_t n = 0; n < rootfs_size; n++)
   1713     rootfs[n] = uint8_t(n);
   1714   base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
   1715   EXPECT_EQ(rootfs_size,
   1716             static_cast<const size_t>(
   1717                 base::WriteFile(rootfs_path,
   1718                                 reinterpret_cast<const char*>(rootfs.data()),
   1719                                 rootfs.size())));
   1720 
   1721   EXPECT_COMMAND(0,
   1722                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   1723                  "--partition_size %d --partition_name foobar "
   1724                  "--algorithm SHA256_RSA2048 "
   1725                  "--key test/data/testkey_rsa2048.pem "
   1726                  "--internal_release_string \"\" "
   1727                  "--do_not_generate_fec",
   1728                  rootfs_path.value().c_str(),
   1729                  (int)partition_size);
   1730 
   1731   // Check that we correctly generate dm-verity kernel cmdline
   1732   // snippets, if requested.
   1733   GenerateVBMetaImage(
   1734       "vbmeta_a.img",
   1735       "SHA256_RSA2048",
   1736       4,
   1737       base::FilePath("test/data/testkey_rsa2048.pem"),
   1738       base::StringPrintf("--setup_rootfs_from_kernel %s "
   1739                          "--kernel_cmdline should_be_in_both=1 "
   1740                          "--algorithm SHA256_RSA2048 "
   1741                          "--flags %d "
   1742                          "--internal_release_string \"\"",
   1743                          rootfs_path.value().c_str(),
   1744                          hashtree_verification_on
   1745                              ? 0
   1746                              : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED));
   1747 
   1748   EXPECT_EQ(
   1749       base::StringPrintf(
   1750           "Minimum libavb version:   1.0\n"
   1751           "Header Block:             256 bytes\n"
   1752           "Authentication Block:     320 bytes\n"
   1753           "Auxiliary Block:          960 bytes\n"
   1754           "Algorithm:                SHA256_RSA2048\n"
   1755           "Rollback Index:           4\n"
   1756           "Flags:                    %d\n"
   1757           "Release String:           ''\n"
   1758           "Descriptors:\n"
   1759           "    Kernel Cmdline descriptor:\n"
   1760           "      Flags:                 1\n"
   1761           "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity "
   1762           "1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
   1763           "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
   1764           "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
   1765           "$(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
   1766           "    Kernel Cmdline descriptor:\n"
   1767           "      Flags:                 2\n"
   1768           "      Kernel Cmdline:        "
   1769           "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
   1770           "    Kernel Cmdline descriptor:\n"
   1771           "      Flags:                 0\n"
   1772           "      Kernel Cmdline:        'should_be_in_both=1'\n",
   1773           hashtree_verification_on ? 0
   1774                                    : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED),
   1775       InfoImage(vbmeta_image_path_));
   1776 
   1777   ops_.set_expected_public_key(
   1778       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1779 
   1780   // Check that avb_slot_verify() picks the cmdline decsriptors based
   1781   // on their flags value.
   1782   AvbSlotVerifyData* slot_data = NULL;
   1783   const char* requested_partitions[] = {"boot", NULL};
   1784   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1785             avb_slot_verify(ops_.avb_ops(),
   1786                             requested_partitions,
   1787                             "_a",
   1788                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1789                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1790                             &slot_data));
   1791   EXPECT_NE(nullptr, slot_data);
   1792   if (hashtree_verification_on) {
   1793     EXPECT_EQ(
   1794         "dm=\"1 vroot none ro 1,0 2056 verity 1 "
   1795         "PARTUUID=1234-fake-guid-for:system_a "
   1796         "PARTUUID=1234-fake-guid-for:system_a 4096 4096 257 257 sha1 "
   1797         "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
   1798         "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
   1799         "should_be_in_both=1 "
   1800         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   1801         "androidboot.vbmeta.avb_version=1.1 "
   1802         "androidboot.vbmeta.device_state=locked "
   1803         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
   1804         "androidboot.vbmeta.digest="
   1805         "946996b4cd78f2c060f6bb062b94054b809cbfbe9bf4425df263a0e55395ceea "
   1806         "androidboot.vbmeta.invalidate_on_error=yes "
   1807         "androidboot.veritymode=enforcing",
   1808         std::string(slot_data->cmdline));
   1809   } else {
   1810     // NOTE: androidboot.veritymode is 'disabled', not 'enforcing' and
   1811     // androidboot.vbmeta.invalidate_on_error isn't set.
   1812     EXPECT_EQ(
   1813         "root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
   1814         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   1815         "androidboot.vbmeta.avb_version=1.1 "
   1816         "androidboot.vbmeta.device_state=locked "
   1817         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
   1818         "androidboot.vbmeta.digest="
   1819         "c74338b2b366f7f774d264abb4ac06c997cbaacbf5edd70a6ef1a552f744076b "
   1820         "androidboot.veritymode=disabled",
   1821         std::string(slot_data->cmdline));
   1822   }
   1823   avb_slot_verify_data_free(slot_data);
   1824 }
   1825 
   1826 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOff) {
   1827   CmdlineWithHashtreeVerification(false);
   1828 }
   1829 
   1830 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOn) {
   1831   CmdlineWithHashtreeVerification(true);
   1832 }
   1833 
   1834 void AvbSlotVerifyTest::CmdlineWithChainedHashtreeVerification(
   1835     bool hashtree_verification_on) {
   1836   const size_t system_size = 1028 * 1024;
   1837   const size_t system_partition_size = 1536 * 1024;
   1838 
   1839   // Generate a 1028 KiB file with known content.
   1840   std::vector<uint8_t> contents;
   1841   contents.resize(system_size);
   1842   for (size_t n = 0; n < system_size; n++)
   1843     contents[n] = uint8_t(n);
   1844   base::FilePath system_path = testdir_.Append("system_a.img");
   1845   EXPECT_EQ(system_size,
   1846             static_cast<const size_t>(
   1847                 base::WriteFile(system_path,
   1848                                 reinterpret_cast<const char*>(contents.data()),
   1849                                 contents.size())));
   1850 
   1851   // Check that we correctly generate dm-verity kernel cmdline
   1852   // snippets, if requested.
   1853   EXPECT_COMMAND(0,
   1854                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   1855                  "--partition_size %d --partition_name foobar "
   1856                  "--algorithm SHA256_RSA2048 "
   1857                  "--key test/data/testkey_rsa2048.pem "
   1858                  "--internal_release_string \"\" "
   1859                  "--do_not_generate_fec "
   1860                  "--setup_as_rootfs_from_kernel",
   1861                  system_path.value().c_str(),
   1862                  (int)system_partition_size);
   1863 
   1864   EXPECT_EQ(
   1865       "Footer version:           1.0\n"
   1866       "Image size:               1572864 bytes\n"
   1867       "Original image size:      1052672 bytes\n"
   1868       "VBMeta offset:            1069056\n"
   1869       "VBMeta size:              1664 bytes\n"
   1870       "--\n"
   1871       "Minimum libavb version:   1.0\n"
   1872       "Header Block:             256 bytes\n"
   1873       "Authentication Block:     320 bytes\n"
   1874       "Auxiliary Block:          1088 bytes\n"
   1875       "Algorithm:                SHA256_RSA2048\n"
   1876       "Rollback Index:           0\n"
   1877       "Flags:                    0\n"
   1878       "Release String:           ''\n"
   1879       "Descriptors:\n"
   1880       "    Hashtree descriptor:\n"
   1881       "      Version of dm-verity:  1\n"
   1882       "      Image Size:            1052672 bytes\n"
   1883       "      Tree Offset:           1052672\n"
   1884       "      Tree Size:             16384 bytes\n"
   1885       "      Data Block Size:       4096 bytes\n"
   1886       "      Hash Block Size:       4096 bytes\n"
   1887       "      FEC num roots:         0\n"
   1888       "      FEC offset:            0\n"
   1889       "      FEC size:              0 bytes\n"
   1890       "      Hash Algorithm:        sha1\n"
   1891       "      Partition Name:        foobar\n"
   1892       "      Salt:                  d00df00d\n"
   1893       "      Root Digest:           e811611467dcd6e8dc4324e45f706c2bdd51db67\n"
   1894       "      Flags:                 0\n"
   1895       "    Kernel Cmdline descriptor:\n"
   1896       "      Flags:                 1\n"
   1897       "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity 1 "
   1898       "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
   1899       "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
   1900       "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
   1901       "    Kernel Cmdline descriptor:\n"
   1902       "      Flags:                 2\n"
   1903       "      Kernel Cmdline:        "
   1904       "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n",
   1905       InfoImage(system_path));
   1906 
   1907   base::FilePath pk_path = testdir_.Append("testkey_rsa2048.avbpubkey");
   1908   EXPECT_COMMAND(
   1909       0,
   1910       "./avbtool extract_public_key --key test/data/testkey_rsa2048.pem"
   1911       " --output %s",
   1912       pk_path.value().c_str());
   1913 
   1914   GenerateVBMetaImage(
   1915       "vbmeta_a.img",
   1916       "SHA256_RSA2048",
   1917       4,
   1918       base::FilePath("test/data/testkey_rsa2048.pem"),
   1919       base::StringPrintf("--kernel_cmdline should_be_in_both=1 "
   1920                          "--algorithm SHA256_RSA2048 "
   1921                          "--flags %d "
   1922                          "--chain_partition system:1:%s "
   1923                          "--internal_release_string \"\"",
   1924                          hashtree_verification_on
   1925                              ? 0
   1926                              : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED,
   1927                          pk_path.value().c_str()));
   1928 
   1929   EXPECT_EQ(
   1930       base::StringPrintf("Minimum libavb version:   1.0\n"
   1931                          "Header Block:             256 bytes\n"
   1932                          "Authentication Block:     320 bytes\n"
   1933                          "Auxiliary Block:          1216 bytes\n"
   1934                          "Algorithm:                SHA256_RSA2048\n"
   1935                          "Rollback Index:           4\n"
   1936                          "Flags:                    %d\n"
   1937                          "Release String:           ''\n"
   1938                          "Descriptors:\n"
   1939                          "    Chain Partition descriptor:\n"
   1940                          "      Partition Name:          system\n"
   1941                          "      Rollback Index Location: 1\n"
   1942                          "      Public key (sha1):       "
   1943                          "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
   1944                          "    Kernel Cmdline descriptor:\n"
   1945                          "      Flags:                 0\n"
   1946                          "      Kernel Cmdline:        'should_be_in_both=1'\n",
   1947                          hashtree_verification_on
   1948                              ? 0
   1949                              : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED),
   1950       InfoImage(vbmeta_image_path_));
   1951 
   1952   ops_.set_expected_public_key(
   1953       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   1954 
   1955   // Check that avb_slot_verify() picks the cmdline descriptors based
   1956   // on their flags value... note that these descriptors are in the
   1957   // 'system' partition.
   1958   AvbSlotVerifyData* slot_data = NULL;
   1959   const char* requested_partitions[] = {"boot", NULL};
   1960   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   1961             avb_slot_verify(ops_.avb_ops(),
   1962                             requested_partitions,
   1963                             "_a",
   1964                             AVB_SLOT_VERIFY_FLAGS_NONE,
   1965                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1966                             &slot_data));
   1967   EXPECT_NE(nullptr, slot_data);
   1968   if (hashtree_verification_on) {
   1969     EXPECT_EQ(
   1970         "dm=\"1 vroot none ro 1,0 2056 verity 1 "
   1971         "PARTUUID=1234-fake-guid-for:system_a "
   1972         "PARTUUID=1234-fake-guid-for:system_a 4096 4096 257 257 sha1 "
   1973         "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
   1974         "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
   1975         "should_be_in_both=1 "
   1976         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   1977         "androidboot.vbmeta.avb_version=1.1 "
   1978         "androidboot.vbmeta.device_state=locked "
   1979         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=3456 "
   1980         "androidboot.vbmeta.digest="
   1981         "5ee1669b112625322657b83ec932c73dad9b0222011b5aa3e8273f4e0ee025dc "
   1982         "androidboot.vbmeta.invalidate_on_error=yes "
   1983         "androidboot.veritymode=enforcing",
   1984         std::string(slot_data->cmdline));
   1985   } else {
   1986     // NOTE: androidboot.veritymode is 'disabled', not 'enforcing' and
   1987     // androidboot.vbmeta.invalidate_on_error isn't set.
   1988     EXPECT_EQ(
   1989         "root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
   1990         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   1991         "androidboot.vbmeta.avb_version=1.1 "
   1992         "androidboot.vbmeta.device_state=locked "
   1993         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=3456 "
   1994         "androidboot.vbmeta.digest="
   1995         "ae792c45a9d898b532ff9625b60043a8d9eae7e6106b9cba31837d50ba40f81c "
   1996         "androidboot.veritymode=disabled",
   1997         std::string(slot_data->cmdline));
   1998   }
   1999   avb_slot_verify_data_free(slot_data);
   2000 }
   2001 
   2002 TEST_F(AvbSlotVerifyTest, CmdlineWithChainedHashtreeVerificationOff) {
   2003   CmdlineWithChainedHashtreeVerification(false);
   2004 }
   2005 
   2006 TEST_F(AvbSlotVerifyTest, CmdlineWithChainedHashtreeVerificationOn) {
   2007   CmdlineWithChainedHashtreeVerification(true);
   2008 }
   2009 
   2010 void AvbSlotVerifyTest::VerificationDisabled(bool use_avbctl,
   2011                                              bool preload_boot,
   2012                                              bool has_system_partition) {
   2013   const size_t boot_part_size = 32 * 1024 * 1024;
   2014   const size_t dtbo_part_size = 4 * 1024 * 1024;
   2015   const size_t rootfs_size = 1028 * 1024;
   2016   const size_t partition_size = 1536 * 1024;
   2017 
   2018   // Generate boot_a.img and dtbo_a.img since avb_slot_verify() will
   2019   // attempt to load them upon encountering the VERIFICATION_DISABLED
   2020   // flag.
   2021   base::FilePath boot_path = GenerateImage("boot_a.img", boot_part_size);
   2022   const size_t DTBO_DATA_OFFSET = 42;
   2023   base::FilePath dtbo_path =
   2024       GenerateImage("dtbo_a.img", dtbo_part_size, DTBO_DATA_OFFSET);
   2025 
   2026   // Generate a 1028 KiB file with known content.
   2027   std::vector<uint8_t> rootfs;
   2028   rootfs.resize(rootfs_size);
   2029   for (size_t n = 0; n < rootfs_size; n++)
   2030     rootfs[n] = uint8_t(n);
   2031   base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
   2032   EXPECT_EQ(rootfs_size,
   2033             static_cast<const size_t>(
   2034                 base::WriteFile(rootfs_path,
   2035                                 reinterpret_cast<const char*>(rootfs.data()),
   2036                                 rootfs.size())));
   2037 
   2038   EXPECT_COMMAND(0,
   2039                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   2040                  "--partition_size %d --partition_name foobar "
   2041                  "--algorithm SHA256_RSA2048 "
   2042                  "--key test/data/testkey_rsa2048.pem "
   2043                  "--internal_release_string \"\" "
   2044                  "--do_not_generate_fec",
   2045                  rootfs_path.value().c_str(),
   2046                  (int)partition_size);
   2047 
   2048   // Check that we correctly generate dm-verity kernel cmdline
   2049   // snippets, if requested.
   2050   GenerateVBMetaImage(
   2051       "vbmeta_a.img",
   2052       "SHA256_RSA2048",
   2053       4,
   2054       base::FilePath("test/data/testkey_rsa2048.pem"),
   2055       base::StringPrintf(
   2056           "--setup_rootfs_from_kernel %s "
   2057           "--kernel_cmdline should_be_in_both=1 "
   2058           "--algorithm SHA256_RSA2048 "
   2059           "--flags %d "
   2060           "--internal_release_string \"\"",
   2061           rootfs_path.value().c_str(),
   2062           use_avbctl ? 0 : AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED));
   2063 
   2064   EXPECT_EQ(
   2065       base::StringPrintf(
   2066           "Minimum libavb version:   1.0\n"
   2067           "Header Block:             256 bytes\n"
   2068           "Authentication Block:     320 bytes\n"
   2069           "Auxiliary Block:          960 bytes\n"
   2070           "Algorithm:                SHA256_RSA2048\n"
   2071           "Rollback Index:           4\n"
   2072           "Flags:                    %d\n"
   2073           "Release String:           ''\n"
   2074           "Descriptors:\n"
   2075           "    Kernel Cmdline descriptor:\n"
   2076           "      Flags:                 1\n"
   2077           "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity "
   2078           "1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
   2079           "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
   2080           "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
   2081           "$(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
   2082           "    Kernel Cmdline descriptor:\n"
   2083           "      Flags:                 2\n"
   2084           "      Kernel Cmdline:        "
   2085           "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
   2086           "    Kernel Cmdline descriptor:\n"
   2087           "      Flags:                 0\n"
   2088           "      Kernel Cmdline:        'should_be_in_both=1'\n",
   2089           use_avbctl ? 0 : AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED),
   2090       InfoImage(vbmeta_image_path_));
   2091 
   2092   ops_.set_expected_public_key(
   2093       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   2094 
   2095   if (!has_system_partition) {
   2096     ops_.set_hidden_partitions({"system", "system_a", "system_b"});
   2097   }
   2098 
   2099   // Manually set the flag the same way 'avbctl disable-verification'
   2100   // would do it.
   2101   if (use_avbctl) {
   2102     uint32_t flags_data;
   2103     flags_data = avb_htobe32(AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
   2104     EXPECT_EQ(AVB_IO_RESULT_OK,
   2105               ops_.avb_ops()->write_to_partition(
   2106                   ops_.avb_ops(),
   2107                   "vbmeta_a",
   2108                   offsetof(AvbVBMetaImageHeader, flags),
   2109                   sizeof flags_data,
   2110                   &flags_data));
   2111   }
   2112 
   2113   if (preload_boot) {
   2114     ops_.enable_get_preloaded_partition();
   2115     EXPECT_TRUE(ops_.preload_partition("boot_a", boot_path));
   2116   }
   2117 
   2118   // Check that avb_slot_verify() doesn't return any of the
   2119   // descriptors and instead return a kernel command-line with
   2120   // root=PARTUUID=<whatever_for_system_a> and none of the
   2121   // androidboot.vbmeta.* options are set. Also ensure all the
   2122   // requested partitions are loaded.
   2123   //
   2124   // Also if we modified via avbctl we should expect
   2125   // ERROR_VERIFICATION instead of OK.
   2126   //
   2127   AvbSlotVerifyResult expected_result = AVB_SLOT_VERIFY_RESULT_OK;
   2128   if (use_avbctl) {
   2129     expected_result = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
   2130   }
   2131   AvbSlotVerifyData* slot_data = NULL;
   2132   const char* requested_partitions[] = {"boot", "dtbo", NULL};
   2133   EXPECT_EQ(expected_result,
   2134             avb_slot_verify(ops_.avb_ops(),
   2135                             requested_partitions,
   2136                             "_a",
   2137                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
   2138                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   2139                             &slot_data));
   2140   EXPECT_NE(nullptr, slot_data);
   2141   if (has_system_partition) {
   2142     EXPECT_EQ("root=PARTUUID=1234-fake-guid-for:system_a",
   2143               std::string(slot_data->cmdline));
   2144   } else {
   2145     EXPECT_EQ("", std::string(slot_data->cmdline));
   2146   }
   2147 
   2148   // Also make sure that it actually loads the boot and dtbo partitions.
   2149   EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
   2150   EXPECT_EQ("boot",
   2151             std::string(slot_data->loaded_partitions[0].partition_name));
   2152   EXPECT_EQ(boot_part_size, slot_data->loaded_partitions[0].data_size);
   2153   for (size_t n = 0; n < boot_part_size; n++) {
   2154     EXPECT_EQ(uint8_t(n), slot_data->loaded_partitions[0].data[n]);
   2155   }
   2156   EXPECT_EQ(preload_boot, slot_data->loaded_partitions[0].preloaded);
   2157 
   2158   EXPECT_EQ("dtbo",
   2159             std::string(slot_data->loaded_partitions[1].partition_name));
   2160   EXPECT_EQ(dtbo_part_size, slot_data->loaded_partitions[1].data_size);
   2161   for (size_t n = 0; n < dtbo_part_size; n++) {
   2162     EXPECT_EQ(uint8_t(n + DTBO_DATA_OFFSET),
   2163               slot_data->loaded_partitions[1].data[n]);
   2164   }
   2165   EXPECT_FALSE(slot_data->loaded_partitions[1].preloaded);
   2166 
   2167   avb_slot_verify_data_free(slot_data);
   2168 }
   2169 
   2170 TEST_F(AvbSlotVerifyTest, VerificationDisabledUnmodified) {
   2171   VerificationDisabled(false,  // use_avbctl
   2172                        false,  // preload_boot
   2173                        true);  // has_system_partition
   2174 }
   2175 
   2176 TEST_F(AvbSlotVerifyTest, VerificationDisabledModified) {
   2177   VerificationDisabled(true,   // use_avbctl
   2178                        false,  // preload_boot
   2179                        true);  // has_system_partition
   2180 }
   2181 
   2182 TEST_F(AvbSlotVerifyTest, VerificationDisabledUnmodifiedPreloadBoot) {
   2183   VerificationDisabled(false,  // use_avbctl
   2184                        true,   // preload_boot
   2185                        true);  // has_system_partition
   2186 }
   2187 
   2188 TEST_F(AvbSlotVerifyTest, VerificationDisabledModifiedPreloadBoot) {
   2189   VerificationDisabled(true,   // use_avbctl
   2190                        true,   // preload_boot
   2191                        true);  // has_system_partition
   2192 }
   2193 
   2194 TEST_F(AvbSlotVerifyTest, VerificationDisabledUnmodifiedNoSystemPartition) {
   2195   VerificationDisabled(false,   // use_avbctl
   2196                        false,   // preload_boot
   2197                        false);  // has_system_partition
   2198 }
   2199 
   2200 TEST_F(AvbSlotVerifyTest, VerificationDisabledModifiedNoSystemPartition) {
   2201   VerificationDisabled(true,    // use_avbctl
   2202                        false,   // preload_boot
   2203                        false);  // has_system_partition
   2204 }
   2205 
   2206 // In the event that there's no vbmeta partition, we treat the vbmeta
   2207 // struct from 'boot' as the top-level partition. Check that this
   2208 // works.
   2209 TEST_F(AvbSlotVerifyTest, NoVBMetaPartition) {
   2210   const size_t MiB = 1024 * 1024;
   2211   const size_t boot_size = 6 * MiB;
   2212   const size_t boot_part_size = 8 * MiB;
   2213   const size_t system_size = 16 * MiB;
   2214   const size_t system_part_size = 32 * MiB;
   2215   const size_t foobar_size = 8 * MiB;
   2216   const size_t foobar_part_size = 16 * MiB;
   2217   const size_t bazboo_size = 4 * MiB;
   2218   const size_t bazboo_part_size = 8 * MiB;
   2219   base::FilePath boot_path = GenerateImage("boot.img", boot_size);
   2220   base::FilePath system_path = GenerateImage("system.img", system_size);
   2221   base::FilePath foobar_path = GenerateImage("foobar.img", foobar_size);
   2222   base::FilePath bazboo_path = GenerateImage("bazboo.img", bazboo_size);
   2223 
   2224   EXPECT_COMMAND(0,
   2225                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   2226                  "--partition_size %d --partition_name system "
   2227                  "--algorithm SHA256_RSA2048 "
   2228                  "--key test/data/testkey_rsa2048.pem "
   2229                  "--internal_release_string \"\" "
   2230                  "--do_not_generate_fec",
   2231                  system_path.value().c_str(),
   2232                  (int)system_part_size);
   2233 
   2234   EXPECT_COMMAND(0,
   2235                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   2236                  "--partition_size %d --partition_name foobar "
   2237                  "--algorithm SHA256_RSA2048 "
   2238                  "--key test/data/testkey_rsa2048.pem "
   2239                  "--internal_release_string \"\" "
   2240                  "--do_not_generate_fec",
   2241                  foobar_path.value().c_str(),
   2242                  (int)foobar_part_size);
   2243 
   2244   EXPECT_COMMAND(0,
   2245                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   2246                  "--partition_size %d --partition_name bazboo "
   2247                  "--algorithm SHA512_RSA4096 "
   2248                  "--key test/data/testkey_rsa4096.pem "
   2249                  "--internal_release_string \"\" "
   2250                  "--do_not_generate_fec",
   2251                  bazboo_path.value().c_str(),
   2252                  (int)bazboo_part_size);
   2253 
   2254   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   2255   EXPECT_COMMAND(
   2256       0,
   2257       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   2258       " --output %s",
   2259       pk_path.value().c_str());
   2260 
   2261   // Explicitly pass "--flags 2147483648" (i.e. 1<<31) to check that
   2262   // boot.img is treated as top-level. Note the corresponding "Flags:"
   2263   // field below in the avbtool info_image output.
   2264   EXPECT_COMMAND(0,
   2265                  "./avbtool add_hash_footer --salt d00df00d "
   2266                  "--hash_algorithm sha256 --image %s "
   2267                  "--partition_size %d --partition_name boot "
   2268                  "--algorithm SHA256_RSA2048 "
   2269                  "--key test/data/testkey_rsa2048.pem "
   2270                  "--internal_release_string \"\" "
   2271                  "--include_descriptors_from_image %s "
   2272                  "--include_descriptors_from_image %s "
   2273                  "--setup_rootfs_from_kernel %s "
   2274                  "--chain_partition bazboo:1:%s "
   2275                  "--flags 2147483648",
   2276                  boot_path.value().c_str(),
   2277                  (int)boot_part_size,
   2278                  system_path.value().c_str(),
   2279                  foobar_path.value().c_str(),
   2280                  system_path.value().c_str(),
   2281                  pk_path.value().c_str());
   2282 
   2283   ASSERT_EQ(
   2284       "Footer version:           1.0\n"
   2285       "Image size:               8388608 bytes\n"
   2286       "Original image size:      6291456 bytes\n"
   2287       "VBMeta offset:            6291456\n"
   2288       "VBMeta size:              3200 bytes\n"
   2289       "--\n"
   2290       "Minimum libavb version:   1.0\n"
   2291       "Header Block:             256 bytes\n"
   2292       "Authentication Block:     320 bytes\n"
   2293       "Auxiliary Block:          2624 bytes\n"
   2294       "Algorithm:                SHA256_RSA2048\n"
   2295       "Rollback Index:           0\n"
   2296       "Flags:                    2147483648\n"
   2297       "Release String:           ''\n"
   2298       "Descriptors:\n"
   2299       "    Hash descriptor:\n"
   2300       "      Image Size:            6291456 bytes\n"
   2301       "      Hash Algorithm:        sha256\n"
   2302       "      Partition Name:        boot\n"
   2303       "      Salt:                  d00df00d\n"
   2304       "      Digest:                "
   2305       "4c109399b20e476bab15363bff55740add83e1c1e97e0b132f5c713ddd8c7868\n"
   2306       "      Flags:                 0\n"
   2307       "    Chain Partition descriptor:\n"
   2308       "      Partition Name:          bazboo\n"
   2309       "      Rollback Index Location: 1\n"
   2310       "      Public key (sha1):       "
   2311       "2597c218aae470a130f61162feaae70afd97f011\n"
   2312       "    Kernel Cmdline descriptor:\n"
   2313       "      Flags:                 1\n"
   2314       "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 32768 verity 1 "
   2315       "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
   2316       "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
   2317       "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
   2318       "    Kernel Cmdline descriptor:\n"
   2319       "      Flags:                 2\n"
   2320       "      Kernel Cmdline:        "
   2321       "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
   2322       "    Hashtree descriptor:\n"
   2323       "      Version of dm-verity:  1\n"
   2324       "      Image Size:            8388608 bytes\n"
   2325       "      Tree Offset:           8388608\n"
   2326       "      Tree Size:             69632 bytes\n"
   2327       "      Data Block Size:       4096 bytes\n"
   2328       "      Hash Block Size:       4096 bytes\n"
   2329       "      FEC num roots:         0\n"
   2330       "      FEC offset:            0\n"
   2331       "      FEC size:              0 bytes\n"
   2332       "      Hash Algorithm:        sha1\n"
   2333       "      Partition Name:        foobar\n"
   2334       "      Salt:                  d00df00d\n"
   2335       "      Root Digest:           d52d93c988d336a79abe1c05240ae9a79a9b7d61\n"
   2336       "      Flags:                 0\n"
   2337       "    Hashtree descriptor:\n"
   2338       "      Version of dm-verity:  1\n"
   2339       "      Image Size:            16777216 bytes\n"
   2340       "      Tree Offset:           16777216\n"
   2341       "      Tree Size:             135168 bytes\n"
   2342       "      Data Block Size:       4096 bytes\n"
   2343       "      Hash Block Size:       4096 bytes\n"
   2344       "      FEC num roots:         0\n"
   2345       "      FEC offset:            0\n"
   2346       "      FEC size:              0 bytes\n"
   2347       "      Hash Algorithm:        sha1\n"
   2348       "      Partition Name:        system\n"
   2349       "      Salt:                  d00df00d\n"
   2350       "      Root Digest:           c9ffc3bfae5000269a55a56621547fd1fcf819df\n"
   2351       "      Flags:                 0\n",
   2352       InfoImage(boot_path));
   2353 
   2354   ops_.set_expected_public_key(
   2355       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   2356 
   2357   // Now check that libavb will fall back to reading from 'boot'
   2358   // instead of 'vbmeta' when encountering
   2359   // AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION on trying to read from
   2360   // 'vbmeta'.
   2361   AvbSlotVerifyData* slot_data = NULL;
   2362   const char* requested_partitions[] = {"boot", NULL};
   2363   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   2364             avb_slot_verify(ops_.avb_ops(),
   2365                             requested_partitions,
   2366                             "",
   2367                             AVB_SLOT_VERIFY_FLAGS_NONE,
   2368                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   2369                             &slot_data));
   2370   EXPECT_NE(nullptr, slot_data);
   2371   // Note 'boot' in the value androidboot.vbmeta.device since we've
   2372   // read from 'boot' and not 'vbmeta'.
   2373   EXPECT_EQ(
   2374       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
   2375       "PARTUUID=1234-fake-guid-for:system PARTUUID=1234-fake-guid-for:system "
   2376       "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
   2377       "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
   2378       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:boot "
   2379       "androidboot.vbmeta.avb_version=1.1 "
   2380       "androidboot.vbmeta.device_state=locked "
   2381       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=5312 "
   2382       "androidboot.vbmeta.digest="
   2383       "b297d90aa92a5d49725d1206ff1301b054c5a0214f1cb2fc12b809b317d943e4 "
   2384       "androidboot.vbmeta.invalidate_on_error=yes "
   2385       "androidboot.veritymode=enforcing",
   2386       std::string(slot_data->cmdline));
   2387   avb_slot_verify_data_free(slot_data);
   2388 }
   2389 
   2390 // Check that non-zero flags in chained partition are caught in
   2391 // avb_slot_verify().
   2392 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceFlagsZero) {
   2393   size_t boot_partition_size = 16 * 1024 * 1024;
   2394   const size_t boot_image_size = 5 * 1024 * 1024;
   2395   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
   2396   const char* requested_partitions[] = {"boot", NULL};
   2397 
   2398   EXPECT_COMMAND(0,
   2399                  "./avbtool add_hash_footer"
   2400                  " --image %s"
   2401                  " --kernel_cmdline 'cmdline2 in hash footer'"
   2402                  " --rollback_index 12"
   2403                  " --partition_name boot"
   2404                  " --partition_size %zd"
   2405                  " --algorithm SHA256_RSA4096"
   2406                  " --key test/data/testkey_rsa4096.pem"
   2407                  " --salt deadbeef"
   2408                  " --flags 1"
   2409                  " --internal_release_string \"\"",
   2410                  boot_path.value().c_str(),
   2411                  boot_partition_size);
   2412 
   2413   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   2414   EXPECT_COMMAND(
   2415       0,
   2416       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   2417       " --output %s",
   2418       pk_path.value().c_str());
   2419 
   2420   GenerateVBMetaImage(
   2421       "vbmeta_a.img",
   2422       "SHA256_RSA2048",
   2423       11,
   2424       base::FilePath("test/data/testkey_rsa2048.pem"),
   2425       base::StringPrintf("--chain_partition boot:1:%s"
   2426                          " --kernel_cmdline 'cmdline2 in vbmeta'"
   2427                          " --internal_release_string \"\"",
   2428                          pk_path.value().c_str()));
   2429 
   2430   ops_.set_expected_public_key(
   2431       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   2432 
   2433   AvbSlotVerifyData* slot_data = NULL;
   2434   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
   2435             avb_slot_verify(ops_.avb_ops(),
   2436                             requested_partitions,
   2437                             "_a",
   2438                             AVB_SLOT_VERIFY_FLAGS_NONE,
   2439                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   2440                             &slot_data));
   2441   EXPECT_EQ(nullptr, slot_data);
   2442 }
   2443 
   2444 // Check that chain descriptors in chained partitions are caught in
   2445 // avb_slot_verify().
   2446 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceNoChainPartitions) {
   2447   size_t boot_partition_size = 16 * 1024 * 1024;
   2448   const size_t boot_image_size = 5 * 1024 * 1024;
   2449   base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
   2450   const char* requested_partitions[] = {"boot", NULL};
   2451 
   2452   base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
   2453   EXPECT_COMMAND(
   2454       0,
   2455       "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
   2456       " --output %s",
   2457       pk_path.value().c_str());
   2458 
   2459   EXPECT_COMMAND(0,
   2460                  "./avbtool add_hash_footer"
   2461                  " --image %s"
   2462                  " --kernel_cmdline 'cmdline2 in hash footer'"
   2463                  " --rollback_index 12"
   2464                  " --partition_name boot"
   2465                  " --partition_size %zd"
   2466                  " --algorithm SHA256_RSA4096"
   2467                  " --key test/data/testkey_rsa4096.pem"
   2468                  " --salt deadbeef"
   2469                  " --chain_partition other:2:%s"
   2470                  " --internal_release_string \"\"",
   2471                  boot_path.value().c_str(),
   2472                  boot_partition_size,
   2473                  pk_path.value().c_str());
   2474 
   2475   GenerateVBMetaImage(
   2476       "vbmeta_a.img",
   2477       "SHA256_RSA2048",
   2478       11,
   2479       base::FilePath("test/data/testkey_rsa2048.pem"),
   2480       base::StringPrintf("--chain_partition boot:1:%s"
   2481                          " --kernel_cmdline 'cmdline2 in vbmeta'"
   2482                          " --internal_release_string \"\"",
   2483                          pk_path.value().c_str()));
   2484 
   2485   ops_.set_expected_public_key(
   2486       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   2487 
   2488   AvbSlotVerifyData* slot_data = NULL;
   2489   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
   2490             avb_slot_verify(ops_.avb_ops(),
   2491                             requested_partitions,
   2492                             "_a",
   2493                             AVB_SLOT_VERIFY_FLAGS_NONE,
   2494                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   2495                             &slot_data));
   2496   EXPECT_EQ(nullptr, slot_data);
   2497 }
   2498 
   2499 TEST_F(AvbSlotVerifyTest, HashtreeErrorModes) {
   2500   const size_t MiB = 1024 * 1024;
   2501   const size_t system_size = 16 * MiB;
   2502   const size_t system_part_size = 32 * MiB;
   2503   base::FilePath system_path = GenerateImage("system.img", system_size);
   2504 
   2505   EXPECT_COMMAND(0,
   2506                  "./avbtool add_hashtree_footer --salt d00df00d --image %s "
   2507                  "--partition_size %d --partition_name system "
   2508                  "--algorithm SHA256_RSA2048 "
   2509                  "--key test/data/testkey_rsa2048.pem "
   2510                  "--internal_release_string \"\" "
   2511                  "--do_not_generate_fec",
   2512                  system_path.value().c_str(),
   2513                  (int)system_part_size);
   2514 
   2515   GenerateVBMetaImage("vbmeta.img",
   2516                       "SHA256_RSA2048",
   2517                       0,
   2518                       base::FilePath("test/data/testkey_rsa2048.pem"),
   2519                       base::StringPrintf("--setup_rootfs_from_kernel %s "
   2520                                          "--include_descriptors_from_image %s"
   2521                                          " --internal_release_string \"\"",
   2522                                          system_path.value().c_str(),
   2523                                          system_path.value().c_str()));
   2524 
   2525   ops_.set_expected_public_key(
   2526       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   2527 
   2528   AvbSlotVerifyData* slot_data = NULL;
   2529   const char* requested_partitions[] = {"boot", NULL};
   2530 
   2531   // For AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE we should get
   2532   // androidboot.vbmeta.invalidate_on_error=yes and
   2533   // androidboot.veritymode=enforcing. We should get
   2534   // 'restart_on_corruption' in the dm="..." string.
   2535   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   2536             avb_slot_verify(ops_.avb_ops(),
   2537                             requested_partitions,
   2538                             "",
   2539                             AVB_SLOT_VERIFY_FLAGS_NONE,
   2540                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   2541                             &slot_data));
   2542   EXPECT_NE(nullptr, slot_data);
   2543   EXPECT_EQ(
   2544       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
   2545       "PARTUUID=1234-fake-guid-for:system "
   2546       "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
   2547       "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
   2548       "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
   2549       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
   2550       "androidboot.vbmeta.avb_version=1.1 "
   2551       "androidboot.vbmeta.device_state=locked "
   2552       "androidboot.vbmeta.hash_alg=sha256 "
   2553       "androidboot.vbmeta.size=1664 "
   2554       "androidboot.vbmeta.digest="
   2555       "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
   2556       "androidboot.vbmeta.invalidate_on_error=yes "
   2557       "androidboot.veritymode=enforcing",
   2558       std::string(slot_data->cmdline));
   2559   avb_slot_verify_data_free(slot_data);
   2560 
   2561   // For AVB_HASHTREE_ERROR_MODE_RESTART we should get
   2562   // androidboot.veritymode=enforcing and
   2563   // androidboot.vbmeta.invalidate_on_error should be unset. We should
   2564   // get 'restart_on_corruption' in the dm="..." string.
   2565   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   2566             avb_slot_verify(ops_.avb_ops(),
   2567                             requested_partitions,
   2568                             "",
   2569                             AVB_SLOT_VERIFY_FLAGS_NONE,
   2570                             AVB_HASHTREE_ERROR_MODE_RESTART,
   2571                             &slot_data));
   2572   EXPECT_NE(nullptr, slot_data);
   2573   EXPECT_EQ(
   2574       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
   2575       "PARTUUID=1234-fake-guid-for:system "
   2576       "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
   2577       "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
   2578       "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
   2579       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
   2580       "androidboot.vbmeta.avb_version=1.1 "
   2581       "androidboot.vbmeta.device_state=locked "
   2582       "androidboot.vbmeta.hash_alg=sha256 "
   2583       "androidboot.vbmeta.size=1664 "
   2584       "androidboot.vbmeta.digest="
   2585       "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
   2586       "androidboot.veritymode=enforcing",
   2587       std::string(slot_data->cmdline));
   2588   avb_slot_verify_data_free(slot_data);
   2589 
   2590   // For AVB_HASHTREE_ERROR_MODE_EIO we should get
   2591   // androidboot.veritymode=eio and
   2592   // androidboot.vbmeta.invalidate_on_error should be unset. We should
   2593   // get 'ignore_zero_blocks' in the dm="..." string.
   2594   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   2595             avb_slot_verify(ops_.avb_ops(),
   2596                             requested_partitions,
   2597                             "",
   2598                             AVB_SLOT_VERIFY_FLAGS_NONE,
   2599                             AVB_HASHTREE_ERROR_MODE_EIO,
   2600                             &slot_data));
   2601   EXPECT_NE(nullptr, slot_data);
   2602   EXPECT_EQ(
   2603       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
   2604       "PARTUUID=1234-fake-guid-for:system "
   2605       "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
   2606       "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
   2607       "ignore_zero_blocks ignore_zero_blocks\" root=/dev/dm-0 "
   2608       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
   2609       "androidboot.vbmeta.avb_version=1.1 "
   2610       "androidboot.vbmeta.device_state=locked "
   2611       "androidboot.vbmeta.hash_alg=sha256 "
   2612       "androidboot.vbmeta.size=1664 "
   2613       "androidboot.vbmeta.digest="
   2614       "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
   2615       "androidboot.veritymode=eio",
   2616       std::string(slot_data->cmdline));
   2617   avb_slot_verify_data_free(slot_data);
   2618 
   2619   // For AVB_HASHTREE_ERROR_MODE_LOGGING we should get
   2620   // androidboot.veritymode=logging and
   2621   // androidboot.vbmeta.invalidate_on_error should be unset. We should
   2622   // get 'ignore_corruption' in the dm="..." string.
   2623   //
   2624   // Check AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT is returned
   2625   // unless we pass AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR.
   2626   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT,
   2627             avb_slot_verify(ops_.avb_ops(),
   2628                             requested_partitions,
   2629                             "",
   2630                             AVB_SLOT_VERIFY_FLAGS_NONE,
   2631                             AVB_HASHTREE_ERROR_MODE_LOGGING,
   2632                             &slot_data));
   2633   EXPECT_EQ(nullptr, slot_data);
   2634   // --
   2635   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   2636             avb_slot_verify(ops_.avb_ops(),
   2637                             requested_partitions,
   2638                             "",
   2639                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
   2640                             AVB_HASHTREE_ERROR_MODE_LOGGING,
   2641                             &slot_data));
   2642   EXPECT_NE(nullptr, slot_data);
   2643   EXPECT_EQ(
   2644       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
   2645       "PARTUUID=1234-fake-guid-for:system "
   2646       "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
   2647       "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
   2648       "ignore_corruption ignore_zero_blocks\" root=/dev/dm-0 "
   2649       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
   2650       "androidboot.vbmeta.avb_version=1.1 "
   2651       "androidboot.vbmeta.device_state=locked "
   2652       "androidboot.vbmeta.hash_alg=sha256 "
   2653       "androidboot.vbmeta.size=1664 "
   2654       "androidboot.vbmeta.digest="
   2655       "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
   2656       "androidboot.veritymode=logging",
   2657       std::string(slot_data->cmdline));
   2658   avb_slot_verify_data_free(slot_data);
   2659 
   2660   // Check we'll get androidboot.veritymode=disabled for any
   2661   // |hashtree_error_mode| if dm-verity is disabled.
   2662   GenerateVBMetaImage("vbmeta.img",
   2663                       "SHA256_RSA2048",
   2664                       0,
   2665                       base::FilePath("test/data/testkey_rsa2048.pem"),
   2666                       base::StringPrintf("--setup_rootfs_from_kernel %s "
   2667                                          "--include_descriptors_from_image %s "
   2668                                          "--set_hashtree_disabled_flag "
   2669                                          "--internal_release_string \"\"",
   2670                                          system_path.value().c_str(),
   2671                                          system_path.value().c_str()));
   2672   for (int n = 0; n < 4; n++) {
   2673     AvbHashtreeErrorMode modes[4] = {
   2674         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   2675         AVB_HASHTREE_ERROR_MODE_RESTART,
   2676         AVB_HASHTREE_ERROR_MODE_EIO,
   2677         AVB_HASHTREE_ERROR_MODE_LOGGING};
   2678     EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   2679               avb_slot_verify(ops_.avb_ops(),
   2680                               requested_partitions,
   2681                               "",
   2682                               AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
   2683                               modes[n],
   2684                               &slot_data));
   2685     EXPECT_NE(nullptr, slot_data);
   2686     EXPECT_EQ(
   2687         "root=PARTUUID=1234-fake-guid-for:system "
   2688         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
   2689         "androidboot.vbmeta.avb_version=1.1 "
   2690         "androidboot.vbmeta.device_state=locked "
   2691         "androidboot.vbmeta.hash_alg=sha256 "
   2692         "androidboot.vbmeta.size=1664 "
   2693         "androidboot.vbmeta.digest="
   2694         "e73a466d63f451dcf5c051ff12a32c006ba282a34b37420c0d563f0282cad703 "
   2695         "androidboot.veritymode=disabled",
   2696         std::string(slot_data->cmdline));
   2697     avb_slot_verify_data_free(slot_data);
   2698   }
   2699 }
   2700 
   2701 class AvbSlotVerifyTestWithPersistentDigest : public AvbSlotVerifyTest {
   2702  protected:
   2703   void SetupWithHashDescriptor(bool do_not_use_ab = true) {
   2704     const size_t factory_partition_size = 16 * 1024 * 1024;
   2705     const size_t factory_image_size = 5 * 1024 * 1024;
   2706     base::FilePath factory_path =
   2707         GenerateImage("factory.img", factory_image_size);
   2708 
   2709     EXPECT_COMMAND(0,
   2710                    "./avbtool add_hash_footer"
   2711                    " --image %s"
   2712                    " --rollback_index 0"
   2713                    " --partition_name factory"
   2714                    " --partition_size %zd"
   2715                    " --internal_release_string \"\""
   2716                    " --use_persistent_digest %s",
   2717                    factory_path.value().c_str(),
   2718                    factory_partition_size,
   2719                    do_not_use_ab ? "--do_not_use_ab" : "");
   2720 
   2721     GenerateVBMetaImage(
   2722         "vbmeta_a.img",
   2723         "SHA256_RSA2048",
   2724         0,
   2725         base::FilePath("test/data/testkey_rsa2048.pem"),
   2726         base::StringPrintf("--internal_release_string \"\" "
   2727                            "--include_descriptors_from_image %s ",
   2728                            factory_path.value().c_str()));
   2729 
   2730     EXPECT_EQ(base::StringPrintf("Minimum libavb version:   1.1\n"
   2731                                  "Header Block:             256 bytes\n"
   2732                                  "Authentication Block:     320 bytes\n"
   2733                                  "Auxiliary Block:          704 bytes\n"
   2734                                  "Algorithm:                SHA256_RSA2048\n"
   2735                                  "Rollback Index:           0\n"
   2736                                  "Flags:                    0\n"
   2737                                  "Release String:           ''\n"
   2738                                  "Descriptors:\n"
   2739                                  "    Hash descriptor:\n"
   2740                                  "      Image Size:            5242880 bytes\n"
   2741                                  "      Hash Algorithm:        sha256\n"
   2742                                  "      Partition Name:        factory\n"
   2743                                  "      Salt:                  \n"
   2744                                  "      Digest:                \n"
   2745                                  "      Flags:                 %d\n",
   2746                                  do_not_use_ab ? 1 : 0),
   2747               InfoImage(vbmeta_image_path_));
   2748 
   2749     ops_.set_expected_public_key(
   2750         PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   2751   }
   2752 
   2753   void SetupWithHashtreeDescriptor(bool do_not_use_ab = true) {
   2754     const size_t factory_partition_size = 16 * 1024 * 1024;
   2755     const size_t factory_image_size = 5 * 1024 * 1024;
   2756     base::FilePath factory_path =
   2757         GenerateImage("factory.img", factory_image_size);
   2758 
   2759     EXPECT_COMMAND(
   2760         0,
   2761         "./avbtool add_hashtree_footer"
   2762         " --image %s"
   2763         " --rollback_index 0"
   2764         " --partition_name factory"
   2765         " --partition_size %zd"
   2766         " --hash_algorithm %s"
   2767         " --internal_release_string \"\""
   2768         " --kernel_cmdline "
   2769         "'androidboot.vbmeta.root_digest.factory=$(AVB_FACTORY_ROOT_DIGEST)'"
   2770         " --use_persistent_digest %s",
   2771         factory_path.value().c_str(),
   2772         factory_partition_size,
   2773         verity_hash_algorithm_.c_str(),
   2774         do_not_use_ab ? "--do_not_use_ab" : "");
   2775 
   2776     GenerateVBMetaImage(
   2777         "vbmeta_a.img",
   2778         "SHA256_RSA2048",
   2779         0,
   2780         base::FilePath("test/data/testkey_rsa2048.pem"),
   2781         base::StringPrintf("--internal_release_string \"\" "
   2782                            "--include_descriptors_from_image %s ",
   2783                            factory_path.value().c_str()));
   2784 
   2785     int expected_tree_size =
   2786         (verity_hash_algorithm_ == "sha512") ? 86016 : 45056;
   2787     int expected_fec_offset =
   2788         (verity_hash_algorithm_ == "sha512") ? 5328896 : 5287936;
   2789     EXPECT_EQ(base::StringPrintf("Minimum libavb version:   1.1\n"
   2790                                  "Header Block:             256 bytes\n"
   2791                                  "Authentication Block:     320 bytes\n"
   2792                                  "Auxiliary Block:          832 bytes\n"
   2793                                  "Algorithm:                SHA256_RSA2048\n"
   2794                                  "Rollback Index:           0\n"
   2795                                  "Flags:                    0\n"
   2796                                  "Release String:           ''\n"
   2797                                  "Descriptors:\n"
   2798                                  "    Kernel Cmdline descriptor:\n"
   2799                                  "      Flags:                 0\n"
   2800                                  "      Kernel Cmdline:        "
   2801                                  "'androidboot.vbmeta.root_digest.factory=$("
   2802                                  "AVB_FACTORY_ROOT_DIGEST)'\n"
   2803                                  "    Hashtree descriptor:\n"
   2804                                  "      Version of dm-verity:  1\n"
   2805                                  "      Image Size:            5242880 bytes\n"
   2806                                  "      Tree Offset:           5242880\n"
   2807                                  "      Tree Size:             %d bytes\n"
   2808                                  "      Data Block Size:       4096 bytes\n"
   2809                                  "      Hash Block Size:       4096 bytes\n"
   2810                                  "      FEC num roots:         2\n"
   2811                                  "      FEC offset:            %d\n"
   2812                                  "      FEC size:              49152 bytes\n"
   2813                                  "      Hash Algorithm:        %s\n"
   2814                                  "      Partition Name:        factory\n"
   2815                                  "      Salt:                  \n"
   2816                                  "      Root Digest:           \n"
   2817                                  "      Flags:                 %d\n",
   2818                                  expected_tree_size,
   2819                                  expected_fec_offset,
   2820                                  verity_hash_algorithm_.c_str(),
   2821                                  do_not_use_ab ? 1 : 0),
   2822               InfoImage(vbmeta_image_path_));
   2823 
   2824     ops_.set_expected_public_key(
   2825         PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   2826   }
   2827 
   2828   void Verify(bool expect_success) {
   2829     AvbSlotVerifyData* slot_data = NULL;
   2830     const char* requested_partitions[] = {"factory", NULL};
   2831     AvbSlotVerifyResult result =
   2832         avb_slot_verify(ops_.avb_ops(),
   2833                         requested_partitions,
   2834                         "_a",
   2835                         AVB_SLOT_VERIFY_FLAGS_NONE,
   2836                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   2837                         &slot_data);
   2838     if (expect_success) {
   2839       ASSERT_EQ(AVB_SLOT_VERIFY_RESULT_OK, result);
   2840       ASSERT_NE(nullptr, slot_data);
   2841       last_cmdline_ = slot_data->cmdline;
   2842       avb_slot_verify_data_free(slot_data);
   2843     } else {
   2844       EXPECT_NE(AVB_SLOT_VERIFY_RESULT_OK, result);
   2845       EXPECT_EQ(nullptr, slot_data);
   2846       if (expected_error_code_ != AVB_SLOT_VERIFY_RESULT_OK) {
   2847         EXPECT_EQ(expected_error_code_, result);
   2848       }
   2849     }
   2850   }
   2851 
   2852   std::string last_cmdline_;
   2853   std::string verity_hash_algorithm_{"sha1"};
   2854   AvbSlotVerifyResult expected_error_code_{AVB_SLOT_VERIFY_RESULT_OK};
   2855 
   2856  public:
   2857   // Persistent digests always use AVB_NPV_PERSISTENT_DIGEST_PREFIX followed by
   2858   // the partition name.
   2859   const char* kPersistentValueName = "avb.persistent_digest.factory";
   2860   // The digest for the hash descriptor which matches the factory contents.
   2861   const uint8_t kDigest[AVB_SHA256_DIGEST_SIZE] = {
   2862       0x2e, 0x7c, 0xab, 0x63, 0x14, 0xe9, 0x61, 0x4b, 0x6f, 0x2d, 0xa1,
   2863       0x26, 0x30, 0x66, 0x1c, 0x30, 0x38, 0xe5, 0x59, 0x20, 0x25, 0xf6,
   2864       0x53, 0x4b, 0xa5, 0x82, 0x3c, 0x3b, 0x34, 0x0a, 0x1c, 0xb6};
   2865 };
   2866 
   2867 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic) {
   2868   SetupWithHashDescriptor();
   2869   // Store the expected image digest as a persistent value.
   2870   ops_.write_persistent_value(
   2871       kPersistentValueName, AVB_SHA256_DIGEST_SIZE, kDigest);
   2872   Verify(true /* expect_success */);
   2873   EXPECT_EQ(
   2874       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   2875       "androidboot.vbmeta.avb_version=1.1 "
   2876       "androidboot.vbmeta.device_state=locked "
   2877       "androidboot.vbmeta.hash_alg=sha256 "
   2878       "androidboot.vbmeta.size=1280 "
   2879       "androidboot.vbmeta.digest="
   2880       "f7a4ce48092379fe0e913ffda10d859cd5fc19fa721c9e81f05f8bfea14b9873 "
   2881       "androidboot.vbmeta.invalidate_on_error=yes "
   2882       "androidboot.veritymode=enforcing",
   2883       last_cmdline_);
   2884 }
   2885 
   2886 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_WithAB) {
   2887   SetupWithHashDescriptor(false /* do_not_use_ab */);
   2888   // Store the expected image digest as a persistent value.
   2889   ops_.write_persistent_value(
   2890       kPersistentValueName, AVB_SHA256_DIGEST_SIZE, kDigest);
   2891   Verify(false /* expect_success */);
   2892 }
   2893 
   2894 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_WithAutoInit) {
   2895   SetupWithHashDescriptor();
   2896   // Explicitly do not write any digest as a persistent value.
   2897   Verify(true /* expect_success */);
   2898 }
   2899 
   2900 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_WithNoAutoInit) {
   2901   SetupWithHashDescriptor();
   2902   // Explicitly do not write any digest as a persistent value.
   2903   // Set device as unlocked so that auto persistent digest initialization does
   2904   // not occur.
   2905   ops_.set_stored_is_device_unlocked(true);
   2906   Verify(false /* expect_success */);
   2907 }
   2908 
   2909 class AvbSlotVerifyTestWithPersistentDigest_InvalidDigestLength
   2910     : public AvbSlotVerifyTestWithPersistentDigest,
   2911       public ::testing::WithParamInterface<size_t> {};
   2912 
   2913 TEST_P(AvbSlotVerifyTestWithPersistentDigest_InvalidDigestLength, Param) {
   2914   SetupWithHashDescriptor();
   2915   // Store a digest value with the given length.
   2916   ops_.write_persistent_value(kPersistentValueName, GetParam(), kDigest);
   2917   expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
   2918   Verify(false /* expect_success */);
   2919 }
   2920 
   2921 // Test a bunch of invalid digest length values.
   2922 INSTANTIATE_TEST_CASE_P(
   2923     P,
   2924     AvbSlotVerifyTestWithPersistentDigest_InvalidDigestLength,
   2925     ::testing::Values(AVB_SHA256_DIGEST_SIZE + 1,
   2926                       AVB_SHA256_DIGEST_SIZE - 1,
   2927                       0,
   2928                       AVB_SHA512_DIGEST_SIZE));
   2929 
   2930 class AvbSlotVerifyTestWithPersistentDigest_InvalidPersistentValueName
   2931     : public AvbSlotVerifyTestWithPersistentDigest,
   2932       public ::testing::WithParamInterface<const char*> {
   2933   // FakeAvbOpsDelegate override.
   2934   AvbIOResult write_persistent_value(const char* name,
   2935                                      size_t value_size,
   2936                                      const uint8_t* value) override {
   2937     // Fail attempted initialization with any name not under test.
   2938     if (std::string(name) != GetParam()) {
   2939       return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
   2940     }
   2941     return ops_.write_persistent_value(name, value_size, value);
   2942   }
   2943 };
   2944 
   2945 TEST_P(AvbSlotVerifyTestWithPersistentDigest_InvalidPersistentValueName,
   2946        Param) {
   2947   SetupWithHashDescriptor();
   2948   ops_.write_persistent_value(GetParam(), AVB_SHA256_DIGEST_SIZE, kDigest);
   2949   Verify(false /* expect_success */);
   2950 }
   2951 
   2952 // Test a bunch of invalid persistent value names.
   2953 INSTANTIATE_TEST_CASE_P(
   2954     P,
   2955     AvbSlotVerifyTestWithPersistentDigest_InvalidPersistentValueName,
   2956     ::testing::Values(
   2957         "",
   2958         "avb.persistent_digest.factory0",
   2959         "avb.persistent_digest.factor",
   2960         "loooooooooooooooooooooooooooooooooooooooooooooongvalue"));
   2961 
   2962 class AvbSlotVerifyTestWithPersistentDigest_ReadDigestFailure
   2963     : public AvbSlotVerifyTestWithPersistentDigest,
   2964       public ::testing::WithParamInterface<AvbIOResult> {
   2965   // FakeAvbOpsDelegate overrides.
   2966   AvbIOResult read_persistent_value(const char* name,
   2967                                     size_t buffer_size,
   2968                                     uint8_t* out_buffer,
   2969                                     size_t* out_num_bytes_read) override {
   2970     return GetParam();
   2971   }
   2972 };
   2973 
   2974 TEST_P(AvbSlotVerifyTestWithPersistentDigest_ReadDigestFailure, Param) {
   2975   SetupWithHashDescriptor();
   2976   // Set device as unlocked so that auto persistent digest initialization does
   2977   // not occur.
   2978   ops_.set_stored_is_device_unlocked(true);
   2979   switch (GetParam()) {
   2980     case AVB_IO_RESULT_ERROR_OOM:
   2981       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
   2982       break;
   2983     case AVB_IO_RESULT_ERROR_IO:
   2984       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
   2985       break;
   2986     case AVB_IO_RESULT_ERROR_NO_SUCH_VALUE:
   2987       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
   2988       break;
   2989     // Fall through.
   2990     case AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE:
   2991     case AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE:
   2992       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
   2993       break;
   2994     default:
   2995       break;
   2996   }
   2997   Verify(false /* expect_success */);
   2998 }
   2999 
   3000 // Test a bunch of error codes.
   3001 INSTANTIATE_TEST_CASE_P(
   3002     P,
   3003     AvbSlotVerifyTestWithPersistentDigest_ReadDigestFailure,
   3004     ::testing::Values(AVB_IO_RESULT_ERROR_OOM,
   3005                       AVB_IO_RESULT_ERROR_IO,
   3006                       AVB_IO_RESULT_ERROR_NO_SUCH_VALUE,
   3007                       AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE,
   3008                       AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE));
   3009 
   3010 class AvbSlotVerifyTestWithPersistentDigest_AutoInitDigestFailure
   3011     : public AvbSlotVerifyTestWithPersistentDigest,
   3012       public ::testing::WithParamInterface<AvbIOResult> {
   3013   // FakeAvbOpsDelegate overrides.
   3014   AvbIOResult read_persistent_value(const char* name,
   3015                                     size_t buffer_size,
   3016                                     uint8_t* out_buffer,
   3017                                     size_t* out_num_bytes_read) override {
   3018     // Auto digest initialization only occurs when read returns NO_SUCH_VALUE
   3019     return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
   3020   }
   3021   AvbIOResult write_persistent_value(const char* name,
   3022                                      size_t value_size,
   3023                                      const uint8_t* value) override {
   3024     return GetParam();
   3025   }
   3026 };
   3027 
   3028 TEST_P(AvbSlotVerifyTestWithPersistentDigest_AutoInitDigestFailure, Param) {
   3029   SetupWithHashDescriptor();
   3030   // Set device as locked so that auto persistent digest initialization occurs.
   3031   ops_.set_stored_is_device_unlocked(false);
   3032   switch (GetParam()) {
   3033     case AVB_IO_RESULT_OK:
   3034       // This tests the case where the write appears to succeed, but the
   3035       // read-back after it still fails.
   3036       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
   3037       break;
   3038     case AVB_IO_RESULT_ERROR_OOM:
   3039       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
   3040       break;
   3041     // Fall through.
   3042     case AVB_IO_RESULT_ERROR_IO:
   3043     case AVB_IO_RESULT_ERROR_NO_SUCH_VALUE:
   3044     case AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE:
   3045     case AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE:
   3046       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
   3047       break;
   3048     default:
   3049       break;
   3050   }
   3051   Verify(false /* expect_success */);
   3052 }
   3053 
   3054 // Test a bunch of error codes.
   3055 INSTANTIATE_TEST_CASE_P(
   3056     P,
   3057     AvbSlotVerifyTestWithPersistentDigest_AutoInitDigestFailure,
   3058     ::testing::Values(AVB_IO_RESULT_OK,
   3059                       AVB_IO_RESULT_ERROR_OOM,
   3060                       AVB_IO_RESULT_ERROR_IO,
   3061                       AVB_IO_RESULT_ERROR_NO_SUCH_VALUE,
   3062                       AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE,
   3063                       AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE));
   3064 
   3065 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_Sha1) {
   3066   verity_hash_algorithm_ = "sha1";
   3067   SetupWithHashtreeDescriptor();
   3068   // Store an arbitrary image digest.
   3069   uint8_t fake_digest[]{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3070                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3071                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
   3072   ops_.write_persistent_value(
   3073       kPersistentValueName, AVB_SHA1_DIGEST_SIZE, fake_digest);
   3074   Verify(true /* expect_success */);
   3075   EXPECT_EQ(
   3076       "androidboot.vbmeta.root_digest.factory="
   3077       // Note: Here appear the bytes used in write_persistent_value above.
   3078       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "
   3079       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   3080       "androidboot.vbmeta.avb_version=1.1 "
   3081       "androidboot.vbmeta.device_state=locked "
   3082       "androidboot.vbmeta.hash_alg=sha256 "
   3083       "androidboot.vbmeta.size=1408 "
   3084       "androidboot.vbmeta.digest="
   3085       "eeaa2fb8deb48b9645f817bb6a6ce05ba3ef92d0d2d9c950c2383853cd4a3064 "
   3086       "androidboot.vbmeta.invalidate_on_error=yes "
   3087       "androidboot.veritymode=enforcing",
   3088       last_cmdline_);
   3089 }
   3090 
   3091 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_Sha256) {
   3092   verity_hash_algorithm_ = "sha256";
   3093   SetupWithHashtreeDescriptor();
   3094   // Store an arbitrary image digest.
   3095   uint8_t fake_digest[]{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3096                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3097                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3098                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
   3099   ops_.write_persistent_value(
   3100       kPersistentValueName, AVB_SHA256_DIGEST_SIZE, fake_digest);
   3101   Verify(true /* expect_success */);
   3102   EXPECT_EQ(
   3103       "androidboot.vbmeta.root_digest.factory="
   3104       // Note: Here appear the bytes used in write_persistent_value above.
   3105       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "
   3106       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   3107       "androidboot.vbmeta.avb_version=1.1 "
   3108       "androidboot.vbmeta.device_state=locked "
   3109       "androidboot.vbmeta.hash_alg=sha256 "
   3110       "androidboot.vbmeta.size=1408 "
   3111       "androidboot.vbmeta.digest="
   3112       "d3f35ef7a0812d8328be7850003b2c5607b673d0aede641656c9c04fa7992d40 "
   3113       "androidboot.vbmeta.invalidate_on_error=yes "
   3114       "androidboot.veritymode=enforcing",
   3115       last_cmdline_);
   3116 }
   3117 
   3118 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_Sha512) {
   3119   verity_hash_algorithm_ = "sha512";
   3120   SetupWithHashtreeDescriptor();
   3121   // Store an arbitrary image digest.
   3122   uint8_t fake_digest[]{
   3123       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3124       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3125       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3126       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3127       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3128       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
   3129   ops_.write_persistent_value(
   3130       kPersistentValueName, AVB_SHA512_DIGEST_SIZE, fake_digest);
   3131   Verify(true /* expect_success */);
   3132   EXPECT_EQ(
   3133       "androidboot.vbmeta.root_digest.factory="
   3134       // Note: Here appear the bytes used in write_persistent_value above.
   3135       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
   3136       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "
   3137       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   3138       "androidboot.vbmeta.avb_version=1.1 "
   3139       "androidboot.vbmeta.device_state=locked "
   3140       "androidboot.vbmeta.hash_alg=sha256 "
   3141       "androidboot.vbmeta.size=1408 "
   3142       "androidboot.vbmeta.digest="
   3143       "d6ea8d50dce5ca6d38ea6e780bb5b5d7ee588b53a92020ad3d1c99018f3e5f52 "
   3144       "androidboot.vbmeta.invalidate_on_error=yes "
   3145       "androidboot.veritymode=enforcing",
   3146       last_cmdline_);
   3147 }
   3148 
   3149 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_WithAB) {
   3150   verity_hash_algorithm_ = "sha1";
   3151   SetupWithHashtreeDescriptor(false /* do_not_use_ab */);
   3152   // Store an arbitrary image digest.
   3153   uint8_t fake_digest[]{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3154                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
   3155                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
   3156   ops_.write_persistent_value(
   3157       kPersistentValueName, AVB_SHA1_DIGEST_SIZE, fake_digest);
   3158   Verify(false /* expect_success */);
   3159 }
   3160 
   3161 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_NoAutoInit) {
   3162   verity_hash_algorithm_ = "sha1";
   3163   SetupWithHashtreeDescriptor();
   3164   // Explicitly do not store any persistent digest.
   3165   Verify(false /* expect_success */);
   3166 }
   3167 
   3168 class AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidDigestLength
   3169     : public AvbSlotVerifyTestWithPersistentDigest,
   3170       public ::testing::WithParamInterface<size_t> {};
   3171 
   3172 TEST_P(AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidDigestLength,
   3173        Param) {
   3174   SetupWithHashtreeDescriptor();
   3175   // Store a digest value with the given length.
   3176   ops_.write_persistent_value(kPersistentValueName, GetParam(), kDigest);
   3177   Verify(false /* expect_success */);
   3178 }
   3179 
   3180 // Test a bunch of invalid digest length values.
   3181 INSTANTIATE_TEST_CASE_P(
   3182     P,
   3183     AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidDigestLength,
   3184     ::testing::Values(AVB_SHA1_DIGEST_SIZE + 1,
   3185                       AVB_SHA1_DIGEST_SIZE - 1,
   3186                       0,
   3187                       AVB_SHA256_DIGEST_SIZE,
   3188                       AVB_SHA512_DIGEST_SIZE));
   3189 
   3190 class AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidPersistentValueName
   3191     : public AvbSlotVerifyTestWithPersistentDigest,
   3192       public ::testing::WithParamInterface<const char*> {};
   3193 
   3194 TEST_P(
   3195     AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidPersistentValueName,
   3196     Param) {
   3197   SetupWithHashtreeDescriptor();
   3198   ops_.write_persistent_value(GetParam(), AVB_SHA256_DIGEST_SIZE, kDigest);
   3199   Verify(false /* expect_success */);
   3200 }
   3201 
   3202 // Test a bunch of invalid persistent value names.
   3203 INSTANTIATE_TEST_CASE_P(
   3204     P,
   3205     AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidPersistentValueName,
   3206     ::testing::Values(
   3207         "",
   3208         "avb.persistent_digest.factory0",
   3209         "avb.persistent_digest.factor",
   3210         "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
   3211         "oooooooooooooooooooooooooooooooooooooooooooooooooooongvalue"));
   3212 
   3213 class AvbSlotVerifyTestWithPersistentDigest_Hashtree_ReadDigestFailure
   3214     : public AvbSlotVerifyTestWithPersistentDigest,
   3215       public ::testing::WithParamInterface<AvbIOResult> {
   3216   // FakeAvbOpsDelegate override.
   3217   AvbIOResult read_persistent_value(const char* name,
   3218                                     size_t buffer_size,
   3219                                     uint8_t* out_buffer,
   3220                                     size_t* out_num_bytes_read) override {
   3221     return GetParam();
   3222   }
   3223 };
   3224 
   3225 TEST_P(AvbSlotVerifyTestWithPersistentDigest_Hashtree_ReadDigestFailure,
   3226        Param) {
   3227   SetupWithHashtreeDescriptor();
   3228   ops_.write_persistent_value(
   3229       kPersistentValueName, AVB_SHA256_DIGEST_SIZE, kDigest);
   3230   switch (GetParam()) {
   3231     case AVB_IO_RESULT_ERROR_OOM:
   3232       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
   3233       break;
   3234     case AVB_IO_RESULT_ERROR_IO:
   3235       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
   3236       break;
   3237     case AVB_IO_RESULT_ERROR_NO_SUCH_VALUE:
   3238       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
   3239       break;
   3240     // Fall through.
   3241     case AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE:
   3242     case AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE:
   3243       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
   3244       break;
   3245     default:
   3246       break;
   3247   }
   3248   Verify(false /* expect_success */);
   3249 }
   3250 
   3251 // Test a bunch of error codes.
   3252 INSTANTIATE_TEST_CASE_P(
   3253     P,
   3254     AvbSlotVerifyTestWithPersistentDigest_Hashtree_ReadDigestFailure,
   3255     ::testing::Values(AVB_IO_RESULT_ERROR_OOM,
   3256                       AVB_IO_RESULT_ERROR_IO,
   3257                       AVB_IO_RESULT_ERROR_NO_SUCH_VALUE,
   3258                       AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE,
   3259                       AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE));
   3260 
   3261 TEST_F(AvbSlotVerifyTest, ManagedVerityMode) {
   3262   GenerateVBMetaImage("vbmeta.img",
   3263                       "SHA256_RSA2048",
   3264                       0,
   3265                       base::FilePath("test/data/testkey_rsa2048.pem"),
   3266                       "--internal_release_string \"\"");
   3267 
   3268   ops_.set_expected_public_key(
   3269       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   3270 
   3271   AvbSlotVerifyData* slot_data = NULL;
   3272   const char* requested_partitions[] = {"boot", NULL};
   3273 
   3274   // run 1: initial boot -> should be in non-'eio' mode
   3275   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3276             avb_slot_verify(ops_.avb_ops(),
   3277                             requested_partitions,
   3278                             "",
   3279                             AVB_SLOT_VERIFY_FLAGS_NONE,
   3280                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
   3281                             &slot_data));
   3282   EXPECT_NE(nullptr, slot_data);
   3283   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_RESTART,
   3284             slot_data->resolved_hashtree_error_mode);
   3285   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=enforcing") !=
   3286               nullptr);
   3287   EXPECT_TRUE(strstr(slot_data->cmdline,
   3288                      "androidboot.veritymode.managed=yes") != nullptr);
   3289   avb_slot_verify_data_free(slot_data);
   3290 
   3291   // run 2: second boot without dm-verity error -> should still be in non-'eio'
   3292   // mode
   3293   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3294             avb_slot_verify(ops_.avb_ops(),
   3295                             requested_partitions,
   3296                             "",
   3297                             AVB_SLOT_VERIFY_FLAGS_NONE,
   3298                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
   3299                             &slot_data));
   3300   EXPECT_NE(nullptr, slot_data);
   3301   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_RESTART,
   3302             slot_data->resolved_hashtree_error_mode);
   3303   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=enforcing") !=
   3304               nullptr);
   3305   EXPECT_TRUE(strstr(slot_data->cmdline,
   3306                      "androidboot.veritymode.managed=yes") != nullptr);
   3307   avb_slot_verify_data_free(slot_data);
   3308 
   3309   // run 3: Reboot after dm-verity error -> should be in 'eio' mode
   3310   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3311             avb_slot_verify(
   3312                 ops_.avb_ops(),
   3313                 requested_partitions,
   3314                 "",
   3315                 AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION,
   3316                 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
   3317                 &slot_data));
   3318   EXPECT_NE(nullptr, slot_data);
   3319   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_EIO,
   3320             slot_data->resolved_hashtree_error_mode);
   3321   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=eio") !=
   3322               nullptr);
   3323   EXPECT_TRUE(strstr(slot_data->cmdline,
   3324                      "androidboot.veritymode.managed=yes") != nullptr);
   3325   avb_slot_verify_data_free(slot_data);
   3326 
   3327   // run 4: Reboot again.. no dm-verity error but check still in 'eio' mode
   3328   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3329             avb_slot_verify(ops_.avb_ops(),
   3330                             requested_partitions,
   3331                             "",
   3332                             AVB_SLOT_VERIFY_FLAGS_NONE,
   3333                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
   3334                             &slot_data));
   3335   EXPECT_NE(nullptr, slot_data);
   3336   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_EIO,
   3337             slot_data->resolved_hashtree_error_mode);
   3338   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=eio") !=
   3339               nullptr);
   3340   EXPECT_TRUE(strstr(slot_data->cmdline,
   3341                      "androidboot.veritymode.managed=yes") != nullptr);
   3342   avb_slot_verify_data_free(slot_data);
   3343 
   3344   // run 5: Reboot again.. with dm-verity error, check still in 'eio' mode
   3345   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3346             avb_slot_verify(
   3347                 ops_.avb_ops(),
   3348                 requested_partitions,
   3349                 "",
   3350                 AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION,
   3351                 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
   3352                 &slot_data));
   3353   EXPECT_NE(nullptr, slot_data);
   3354   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_EIO,
   3355             slot_data->resolved_hashtree_error_mode);
   3356   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=eio") !=
   3357               nullptr);
   3358   EXPECT_TRUE(strstr(slot_data->cmdline,
   3359                      "androidboot.veritymode.managed=yes") != nullptr);
   3360   avb_slot_verify_data_free(slot_data);
   3361 
   3362   // run 6: Reboot again.. no dm-verity error but check still in 'eio' mode
   3363   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3364             avb_slot_verify(ops_.avb_ops(),
   3365                             requested_partitions,
   3366                             "",
   3367                             AVB_SLOT_VERIFY_FLAGS_NONE,
   3368                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
   3369                             &slot_data));
   3370   EXPECT_NE(nullptr, slot_data);
   3371   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_EIO,
   3372             slot_data->resolved_hashtree_error_mode);
   3373   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=eio") !=
   3374               nullptr);
   3375   EXPECT_TRUE(strstr(slot_data->cmdline,
   3376                      "androidboot.veritymode.managed=yes") != nullptr);
   3377   avb_slot_verify_data_free(slot_data);
   3378 
   3379   // This simulates changing the OS underneath!
   3380   GenerateVBMetaImage("vbmeta.img",
   3381                       "SHA256_RSA2048",
   3382                       0,
   3383                       base::FilePath("test/data/testkey_rsa2048.pem"),
   3384                       "--internal_release_string \"\" --prop key:value");
   3385 
   3386   // run 7: Reboot again, but this time the OS changed underneath.. check
   3387   // that we go back to non-'eio' mode.
   3388   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3389             avb_slot_verify(ops_.avb_ops(),
   3390                             requested_partitions,
   3391                             "",
   3392                             AVB_SLOT_VERIFY_FLAGS_NONE,
   3393                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
   3394                             &slot_data));
   3395   EXPECT_NE(nullptr, slot_data);
   3396   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_RESTART,
   3397             slot_data->resolved_hashtree_error_mode);
   3398   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=enforcing") !=
   3399               nullptr);
   3400   EXPECT_TRUE(strstr(slot_data->cmdline,
   3401                      "androidboot.veritymode.managed=yes") != nullptr);
   3402   avb_slot_verify_data_free(slot_data);
   3403 
   3404   // run 8: subsequent boot without dm-verity error -> should still be in
   3405   // non-'eio' mode
   3406   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3407             avb_slot_verify(ops_.avb_ops(),
   3408                             requested_partitions,
   3409                             "",
   3410                             AVB_SLOT_VERIFY_FLAGS_NONE,
   3411                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
   3412                             &slot_data));
   3413   EXPECT_NE(nullptr, slot_data);
   3414   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_RESTART,
   3415             slot_data->resolved_hashtree_error_mode);
   3416   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=enforcing") !=
   3417               nullptr);
   3418   EXPECT_TRUE(strstr(slot_data->cmdline,
   3419                      "androidboot.veritymode.managed=yes") != nullptr);
   3420   avb_slot_verify_data_free(slot_data);
   3421 }
   3422 
   3423 TEST_F(AvbSlotVerifyTest, NoSystemPartition) {
   3424   GenerateVBMetaImage("vbmeta_a.img",
   3425                       "SHA256_RSA2048",
   3426                       0,
   3427                       base::FilePath("test/data/testkey_rsa2048.pem"),
   3428                       "--internal_release_string \"\"");
   3429 
   3430   ops_.set_expected_public_key(
   3431       PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
   3432   ops_.set_hidden_partitions({"system_a"});
   3433 
   3434   AvbSlotVerifyData* slot_data = NULL;
   3435   const char* requested_partitions[] = {"boot", NULL};
   3436   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
   3437             avb_slot_verify(ops_.avb_ops(),
   3438                             requested_partitions,
   3439                             "_a",
   3440                             AVB_SLOT_VERIFY_FLAGS_NONE,
   3441                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   3442                             &slot_data));
   3443   EXPECT_NE(nullptr, slot_data);
   3444   EXPECT_EQ(
   3445       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
   3446       "androidboot.vbmeta.avb_version=1.1 "
   3447       "androidboot.vbmeta.device_state=locked "
   3448       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
   3449       "androidboot.vbmeta.digest="
   3450       "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
   3451       "androidboot.vbmeta.invalidate_on_error=yes "
   3452       "androidboot.veritymode=enforcing",
   3453       std::string(slot_data->cmdline));
   3454 
   3455   avb_slot_verify_data_free(slot_data);
   3456 }
   3457 
   3458 }  // namespace avb
   3459