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