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 <string.h>
     26 
     27 #include <map>
     28 #include <vector>
     29 
     30 #include <gtest/gtest.h>
     31 
     32 #include <libavb_ab/libavb_ab.h>
     33 
     34 #include "avb_unittest_util.h"
     35 #include "fake_avb_ops.h"
     36 
     37 namespace avb {
     38 
     39 static_assert(sizeof(AvbABSlotData) == 4, "AvbABSlotData has wrong size");
     40 static_assert(sizeof(AvbABData) == AVB_AB_DATA_SIZE,
     41               "AvbABData has wrong size");
     42 static_assert(offsetof(AvbABData, slots) % 8 == 0,
     43               "AvbABData slots member has wrong offset");
     44 
     45 // Subclass BaseAvbToolTest to check for memory leaks.
     46 class ABTest : public BaseAvbToolTest {
     47  public:
     48   ABTest() {}
     49 };
     50 
     51 TEST_F(ABTest, InitData) {
     52   AvbABData data;
     53   avb_ab_data_init(&data);
     54   EXPECT_EQ(0,
     55             strncmp(reinterpret_cast<const char*>(data.magic),
     56                     AVB_AB_MAGIC,
     57                     AVB_AB_MAGIC_LEN));
     58   EXPECT_EQ(AVB_AB_MAX_PRIORITY, data.slots[0].priority);
     59   EXPECT_EQ(AVB_AB_MAX_TRIES_REMAINING, data.slots[0].tries_remaining);
     60   EXPECT_EQ(0, data.slots[0].successful_boot);
     61   EXPECT_EQ(AVB_AB_MAX_PRIORITY - 1, data.slots[1].priority);
     62   EXPECT_EQ(AVB_AB_MAX_TRIES_REMAINING, data.slots[1].tries_remaining);
     63   EXPECT_EQ(0, data.slots[1].successful_boot);
     64   EXPECT_EQ(uint32_t(0), data.crc32);
     65 }
     66 
     67 TEST_F(ABTest, DataSerialization) {
     68   AvbABData data;
     69   AvbABData serialized;
     70   AvbABData restored;
     71 
     72   avb_ab_data_init(&data);
     73   EXPECT_EQ(uint32_t(0), data.crc32);
     74   avb_ab_data_update_crc_and_byteswap(&data, &serialized);
     75   EXPECT_NE(uint32_t(0), serialized.crc32);
     76   EXPECT_TRUE(avb_ab_data_verify_and_byteswap(&serialized, &restored));
     77   EXPECT_EQ(std::string(reinterpret_cast<const char*>(data.magic), 4),
     78             std::string(reinterpret_cast<const char*>(restored.magic), 4));
     79   EXPECT_EQ(data.version_major, restored.version_major);
     80   EXPECT_EQ(data.version_minor, restored.version_minor);
     81   EXPECT_EQ(0,
     82             memcmp(reinterpret_cast<void*>(data.slots),
     83                    reinterpret_cast<void*>(restored.slots),
     84                    sizeof(AvbABSlotData) * 2));
     85 }
     86 
     87 TEST_F(ABTest, CatchBadCRC) {
     88   AvbABData data;
     89   AvbABData serialized;
     90   AvbABData restored;
     91 
     92   avb_ab_data_init(&data);
     93   avb_ab_data_update_crc_and_byteswap(&data, &serialized);
     94   serialized.crc32 += 1;
     95   EXPECT_FALSE(avb_ab_data_verify_and_byteswap(&serialized, &restored));
     96 }
     97 
     98 TEST_F(ABTest, CatchUnsupportedMajorVersion) {
     99   AvbABData data;
    100   AvbABData serialized;
    101   AvbABData restored;
    102 
    103   avb_ab_data_init(&data);
    104   data.version_major += 1;
    105   avb_ab_data_update_crc_and_byteswap(&data, &serialized);
    106   EXPECT_FALSE(avb_ab_data_verify_and_byteswap(&serialized, &restored));
    107 }
    108 
    109 TEST_F(ABTest, SupportSameMajorFutureMinorVersion) {
    110   AvbABData data;
    111   AvbABData serialized;
    112   AvbABData restored;
    113 
    114   avb_ab_data_init(&data);
    115   data.version_minor += 1;
    116   avb_ab_data_update_crc_and_byteswap(&data, &serialized);
    117   EXPECT_TRUE(avb_ab_data_verify_and_byteswap(&serialized, &restored));
    118 }
    119 
    120 #define MISC_PART_SIZE 8 * 1024
    121 
    122 // These values are kept short since they are used in SetMD() and it's
    123 // helpful if the information for a slot fits in one 80-character
    124 // line.
    125 enum SlotValidity {
    126   SV_OK,   // Slot is valid and verified.
    127   SV_INV,  // Slot is invalid.
    128   SV_UNV,  // Slot is valid but unverified.
    129 };
    130 
    131 class AvbABFlowTest : public BaseAvbToolTest {
    132  public:
    133   AvbABFlowTest() {}
    134 
    135   virtual void SetUp() override {
    136     BaseAvbToolTest::SetUp();
    137     ops_.set_partition_dir(testdir_);
    138     ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}, {2, 0}, {3, 0}});
    139     ops_.set_stored_is_device_unlocked(false);
    140 
    141     // Create large enough 'misc' partition and initialize it with
    142     // zeroes.
    143     std::vector<uint8_t> misc;
    144     misc.resize(MISC_PART_SIZE);
    145     base::FilePath misc_path = testdir_.Append("misc.img");
    146     EXPECT_EQ(misc.size(),
    147               static_cast<const size_t>(
    148                   base::WriteFile(misc_path,
    149                                   reinterpret_cast<const char*>(misc.data()),
    150                                   misc.size())));
    151 
    152     // We're going to use this key for all images.
    153     ops_.set_expected_public_key(
    154         PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
    155   }
    156 
    157   void GenerateSlot(unsigned int slot_number,
    158                     SlotValidity slot_validity,
    159                     uint64_t rollback_boot,
    160                     uint64_t rollback_odm) {
    161     std::string boot_name = "boot_a.img";
    162     std::string vbmeta_name = "vbmeta_a.img";
    163     std::string odm_name = "odm_a.img";
    164     if (slot_number > 0) {
    165       boot_name = "boot_b.img";
    166       vbmeta_name = "vbmeta_b.img";
    167       odm_name = "odm_b.img";
    168     }
    169 
    170     // If asked to make an invalid slot, just generate 1MiB garbage
    171     // for each the three images in the slot.
    172     if (slot_validity == SV_INV) {
    173       GenerateImage(boot_name, 1024 * 1024);
    174       GenerateImage(vbmeta_name, 1024 * 1024);
    175       GenerateImage(odm_name, 1024 * 1024);
    176       return;
    177     }
    178 
    179     const size_t boot_partition_size = 16 * 1024 * 1024;
    180     const size_t boot_image_size = 5 * 1024 * 1024;
    181     base::FilePath boot_path = GenerateImage(boot_name, boot_image_size);
    182     EXPECT_COMMAND(0,
    183                    "./avbtool add_hash_footer"
    184                    " --image %s"
    185                    " --rollback_index %" PRIu64
    186                    " --partition_name boot"
    187                    " --partition_size %zd"
    188                    " --salt deadbeef",
    189                    boot_path.value().c_str(),
    190                    rollback_boot,
    191                    boot_partition_size);
    192 
    193     const size_t odm_partition_size = 512 * 1024;
    194     const size_t odm_image_size = 80 * 1024;
    195     base::FilePath odm_path = GenerateImage(odm_name, odm_image_size);
    196     EXPECT_COMMAND(0,
    197                    "./avbtool add_hashtree_footer"
    198                    " --image %s"
    199                    " --rollback_index %" PRIu64
    200                    " --partition_name odm"
    201                    " --partition_size %zd"
    202                    " --salt deadbeef"
    203                    " --algorithm SHA512_RSA4096 "
    204                    " --key test/data/testkey_rsa4096.pem"
    205                    " --do_not_generate_fec",
    206                    odm_path.value().c_str(),
    207                    rollback_odm,
    208                    odm_partition_size);
    209 
    210     base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
    211     EXPECT_COMMAND(
    212         0,
    213         "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
    214         " --output %s",
    215         pk_path.value().c_str());
    216 
    217     // If requested to make the image unverified, just use another key
    218     // in the chain_partition descriptor since this will cause
    219     // avb_slot_verify() to return ERROR_PUBLIC_KEY_REJECTED.
    220     if (slot_validity == SV_UNV) {
    221       pk_path = GenerateImage("dummy.avbpubkey", 32);
    222     }
    223 
    224     GenerateVBMetaImage(vbmeta_name,
    225                         "SHA256_RSA2048",
    226                         rollback_boot,
    227                         base::FilePath("test/data/testkey_rsa2048.pem"),
    228                         base::StringPrintf("--include_descriptors_from_image %s"
    229                                            " --chain_partition odm:1:%s",
    230                                            boot_path.value().c_str(),
    231                                            pk_path.value().c_str()));
    232   }
    233 
    234   void SetMD(int a_pri,
    235              int a_tries,
    236              bool a_success,
    237              SlotValidity a_slot_validity,
    238              uint64_t a_rollback_boot,
    239              uint64_t a_rollback_odm,
    240              int b_pri,
    241              int b_tries,
    242              bool b_success,
    243              SlotValidity b_slot_validity,
    244              uint64_t b_rollback_boot,
    245              uint64_t b_rollback_odm,
    246              const std::map<size_t, uint64_t>& stored_rollback_indexes) {
    247     AvbABData data;
    248     avb_ab_data_init(&data);
    249     data.slots[0].priority = a_pri;
    250     data.slots[0].tries_remaining = a_tries;
    251     data.slots[0].successful_boot = (a_success ? 1 : 0);
    252     data.slots[1].priority = b_pri;
    253     data.slots[1].tries_remaining = b_tries;
    254     data.slots[1].successful_boot = (b_success ? 1 : 0);
    255     EXPECT_EQ(AVB_IO_RESULT_OK,
    256               ops_.avb_ab_ops()->write_ab_metadata(ops_.avb_ab_ops(), &data));
    257     GenerateSlot(0, a_slot_validity, a_rollback_boot, a_rollback_odm);
    258     GenerateSlot(1, b_slot_validity, b_rollback_boot, b_rollback_odm);
    259     ops_.set_stored_rollback_indexes(stored_rollback_indexes);
    260   }
    261 
    262   std::map<size_t, uint64_t> MakeRollbackIndexes(uint64_t slot_0_value,
    263                                                  uint64_t slot_1_value) {
    264     return std::map<size_t, uint64_t>{{0, slot_0_value}, {1, slot_1_value}};
    265   }
    266 
    267   FakeAvbOps ops_;
    268 };
    269 
    270 #define ExpMD(a_pri,                                                          \
    271               a_tries,                                                        \
    272               a_success,                                                      \
    273               b_pri,                                                          \
    274               b_tries,                                                        \
    275               b_success,                                                      \
    276               stored_rollback_indexes)                                        \
    277   do {                                                                        \
    278     AvbABData data;                                                           \
    279     EXPECT_EQ(AVB_IO_RESULT_OK,                                               \
    280               ops_.avb_ab_ops()->read_ab_metadata(ops_.avb_ab_ops(), &data)); \
    281     EXPECT_EQ(a_pri, data.slots[0].priority);                                 \
    282     EXPECT_EQ(a_tries, data.slots[0].tries_remaining);                        \
    283     EXPECT_EQ(a_success ? 1 : 0, data.slots[0].successful_boot);              \
    284     EXPECT_EQ(b_pri, data.slots[1].priority);                                 \
    285     EXPECT_EQ(b_tries, data.slots[1].tries_remaining);                        \
    286     EXPECT_EQ(b_success ? 1 : 0, data.slots[1].successful_boot);              \
    287     EXPECT_EQ(stored_rollback_indexes, ops_.get_stored_rollback_indexes());   \
    288   } while (0);
    289 
    290 TEST_F(AvbABFlowTest, MetadataReadAndWrite) {
    291   AvbABData data;
    292   AvbABData loaded;
    293 
    294   // First load from an uninitialized 'misc' partition. This should
    295   // not fail and just returned initialized data.
    296   EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_data_read(ops_.avb_ab_ops(), &loaded));
    297   EXPECT_EQ(AVB_AB_MAX_PRIORITY, loaded.slots[0].priority);
    298   EXPECT_EQ(AVB_AB_MAX_TRIES_REMAINING, loaded.slots[0].tries_remaining);
    299   EXPECT_EQ(0, loaded.slots[0].successful_boot);
    300   EXPECT_EQ(AVB_AB_MAX_PRIORITY - 1, loaded.slots[1].priority);
    301   EXPECT_EQ(AVB_AB_MAX_TRIES_REMAINING, loaded.slots[1].tries_remaining);
    302   EXPECT_EQ(0, loaded.slots[1].successful_boot);
    303 
    304   // Then initialize and save well-known A/B metadata and check we
    305   // read back the same thing.
    306   avb_ab_data_init(&data);
    307   data.slots[0].priority = 2;
    308   data.slots[0].tries_remaining = 3;
    309   EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_data_write(ops_.avb_ab_ops(), &data));
    310   EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_data_read(ops_.avb_ab_ops(), &loaded));
    311   EXPECT_EQ(2, loaded.slots[0].priority);
    312   EXPECT_EQ(3, loaded.slots[0].tries_remaining);
    313 }
    314 
    315 TEST_F(AvbABFlowTest, EverythingIsValid) {
    316   AvbSlotVerifyData* data;
    317   const char* requested_partitions[] = {"boot", NULL};
    318 
    319   SetMD(14,
    320         0,
    321         1,
    322         SV_OK,
    323         0,
    324         0,  // A: pri, tries, success, slot_validity, RIs
    325         15,
    326         0,
    327         1,
    328         SV_OK,
    329         0,
    330         0,  // B: pri, tries, success, slot_validity, RIs
    331         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    332   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    333             avb_ab_flow(ops_.avb_ab_ops(),
    334                         requested_partitions,
    335                         AVB_SLOT_VERIFY_FLAGS_NONE,
    336                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    337                         &data));
    338   ExpMD(14,
    339         0,
    340         1,  // A: pri, tries, successful
    341         15,
    342         0,
    343         1,                           // B: pri, tries, successful
    344         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    345   ASSERT_NE(nullptr, data);
    346   EXPECT_EQ("_b", std::string(data->ab_suffix));
    347   avb_slot_verify_data_free(data);
    348 
    349   // Also check the other slot.
    350   SetMD(15,
    351         0,
    352         1,
    353         SV_OK,
    354         0,
    355         0,  // A: pri, tries, success, slot_validity, RIs
    356         14,
    357         0,
    358         1,
    359         SV_OK,
    360         0,
    361         0,  // B: pri, tries, success, slot_validity, RIs
    362         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    363   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    364             avb_ab_flow(ops_.avb_ab_ops(),
    365                         requested_partitions,
    366                         AVB_SLOT_VERIFY_FLAGS_NONE,
    367                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    368                         &data));
    369   ExpMD(15,
    370         0,
    371         1,  // A: pri, tries, successful
    372         14,
    373         0,
    374         1,                           // B: pri, tries, successful
    375         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    376   ASSERT_NE(nullptr, data);
    377   EXPECT_EQ("_a", std::string(data->ab_suffix));
    378   avb_slot_verify_data_free(data);
    379 }
    380 
    381 TEST_F(AvbABFlowTest, NoBootableSlots) {
    382   AvbSlotVerifyData* data;
    383   const char* requested_partitions[] = {"boot", NULL};
    384 
    385   SetMD(0,
    386         0,
    387         0,
    388         SV_OK,
    389         0,
    390         0,  // A: pri, tries, success, slot_validity, RIs
    391         0,
    392         0,
    393         0,
    394         SV_OK,
    395         0,
    396         0,  // B: pri, tries, success, slot_validity, RIs
    397         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    398   EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
    399             avb_ab_flow(ops_.avb_ab_ops(),
    400                         requested_partitions,
    401                         AVB_SLOT_VERIFY_FLAGS_NONE,
    402                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    403                         &data));
    404   ExpMD(0,
    405         0,
    406         0,  // A: pri, tries, successful
    407         0,
    408         0,
    409         0,                           // B: pri, tries, successful
    410         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    411   ASSERT_EQ(nullptr, data);
    412 }
    413 
    414 TEST_F(AvbABFlowTest, TriesRemainingDecreasing) {
    415   AvbSlotVerifyData* data;
    416   const char* requested_partitions[] = {"boot", NULL};
    417 
    418   SetMD(15,
    419         3,
    420         0,
    421         SV_OK,
    422         0,
    423         0,  // A: pri, tries, success, slot_validity, RIs
    424         0,
    425         0,
    426         0,
    427         SV_OK,
    428         0,
    429         0,  // B: pri, tries, success, slot_validity, RIs
    430         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    431 
    432   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    433             avb_ab_flow(ops_.avb_ab_ops(),
    434                         requested_partitions,
    435                         AVB_SLOT_VERIFY_FLAGS_NONE,
    436                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    437                         &data));
    438   ExpMD(15,
    439         2,
    440         0,  // A: pri, tries, successful
    441         0,
    442         0,
    443         0,                           // B: pri, tries, successful
    444         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    445   ASSERT_NE(nullptr, data);
    446   EXPECT_EQ("_a", std::string(data->ab_suffix));
    447   avb_slot_verify_data_free(data);
    448 
    449   // Keep counting down...
    450   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    451             avb_ab_flow(ops_.avb_ab_ops(),
    452                         requested_partitions,
    453                         AVB_SLOT_VERIFY_FLAGS_NONE,
    454                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    455                         &data));
    456   ExpMD(15,
    457         1,
    458         0,  // A: pri, tries, successful
    459         0,
    460         0,
    461         0,                           // B: pri, tries, successful
    462         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    463   ASSERT_NE(nullptr, data);
    464   EXPECT_EQ("_a", std::string(data->ab_suffix));
    465   avb_slot_verify_data_free(data);
    466 
    467   // Last try...
    468   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    469             avb_ab_flow(ops_.avb_ab_ops(),
    470                         requested_partitions,
    471                         AVB_SLOT_VERIFY_FLAGS_NONE,
    472                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    473                         &data));
    474   ExpMD(15,
    475         0,
    476         0,  // A: pri, tries, successful
    477         0,
    478         0,
    479         0,                           // B: pri, tries, successful
    480         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    481   ASSERT_NE(nullptr, data);
    482   EXPECT_EQ("_a", std::string(data->ab_suffix));
    483   avb_slot_verify_data_free(data);
    484 
    485   // And we're out of tries. At this point, (15, 0, 0) is normalized
    486   // to (0, 0, 0) so expect that.
    487   EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
    488             avb_ab_flow(ops_.avb_ab_ops(),
    489                         requested_partitions,
    490                         AVB_SLOT_VERIFY_FLAGS_NONE,
    491                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    492                         &data));
    493   ExpMD(0,
    494         0,
    495         0,  // A: pri, tries, successful
    496         0,
    497         0,
    498         0,                           // B: pri, tries, successful
    499         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    500   ASSERT_EQ(nullptr, data);
    501 }
    502 
    503 TEST_F(AvbABFlowTest, TryingThenFallback) {
    504   AvbSlotVerifyData* data;
    505   const char* requested_partitions[] = {"boot", NULL};
    506 
    507   SetMD(15,
    508         2,
    509         0,
    510         SV_OK,
    511         0,
    512         0,  // A: pri, tries, success, slot_validity, RIs
    513         14,
    514         0,
    515         1,
    516         SV_OK,
    517         0,
    518         0,  // B: pri, tries, success, slot_validity, RIs
    519         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    520   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    521             avb_ab_flow(ops_.avb_ab_ops(),
    522                         requested_partitions,
    523                         AVB_SLOT_VERIFY_FLAGS_NONE,
    524                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    525                         &data));
    526   ExpMD(15,
    527         1,
    528         0,  // A: pri, tries, successful
    529         14,
    530         0,
    531         1,                           // B: pri, tries, successful
    532         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    533   ASSERT_NE(nullptr, data);
    534   EXPECT_EQ("_a", std::string(data->ab_suffix));
    535   avb_slot_verify_data_free(data);
    536 
    537   // Last try...
    538   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    539             avb_ab_flow(ops_.avb_ab_ops(),
    540                         requested_partitions,
    541                         AVB_SLOT_VERIFY_FLAGS_NONE,
    542                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    543                         &data));
    544   ExpMD(15,
    545         0,
    546         0,  // A: pri, tries, successful
    547         14,
    548         0,
    549         1,                           // B: pri, tries, successful
    550         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    551   ASSERT_NE(nullptr, data);
    552   EXPECT_EQ("_a", std::string(data->ab_suffix));
    553   avb_slot_verify_data_free(data);
    554 
    555   // And we're out of tries. Check we fall back to slot B.
    556   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    557             avb_ab_flow(ops_.avb_ab_ops(),
    558                         requested_partitions,
    559                         AVB_SLOT_VERIFY_FLAGS_NONE,
    560                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    561                         &data));
    562   ExpMD(0,
    563         0,
    564         0,  // A: pri, tries, successful
    565         14,
    566         0,
    567         1,                           // B: pri, tries, successful
    568         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    569   ASSERT_NE(nullptr, data);
    570   EXPECT_EQ("_b", std::string(data->ab_suffix));
    571   avb_slot_verify_data_free(data);
    572 }
    573 
    574 TEST_F(AvbABFlowTest, TriesRemainingNotDecreasingIfNotPriority) {
    575   AvbSlotVerifyData* data;
    576   const char* requested_partitions[] = {"boot", NULL};
    577 
    578   SetMD(15,
    579         0,
    580         1,
    581         SV_OK,
    582         0,
    583         0,  // A: pri, tries, success, slot_validity, RIs
    584         14,
    585         7,
    586         0,
    587         SV_OK,
    588         0,
    589         0,  // B: pri, tries, success, slot_validity, RIs
    590         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    591   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    592             avb_ab_flow(ops_.avb_ab_ops(),
    593                         requested_partitions,
    594                         AVB_SLOT_VERIFY_FLAGS_NONE,
    595                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    596                         &data));
    597   ExpMD(15,
    598         0,
    599         1,  // A: pri, tries, successful
    600         14,
    601         7,
    602         0,                           // B: pri, tries, successful
    603         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    604   ASSERT_NE(nullptr, data);
    605   EXPECT_EQ("_a", std::string(data->ab_suffix));
    606   avb_slot_verify_data_free(data);
    607 }
    608 
    609 TEST_F(AvbABFlowTest, InvalidSlotIsMarkedAsSuch) {
    610   AvbSlotVerifyData* data;
    611   const char* requested_partitions[] = {"boot", NULL};
    612 
    613   // Slot A is invalid.
    614   SetMD(15,
    615         0,
    616         1,
    617         SV_INV,
    618         0,
    619         0,  // A: pri, tries, success, slot_validity, RIs
    620         14,
    621         0,
    622         1,
    623         SV_OK,
    624         0,
    625         0,  // B: pri, tries, success, slot_validity, RIs
    626         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    627   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    628             avb_ab_flow(ops_.avb_ab_ops(),
    629                         requested_partitions,
    630                         AVB_SLOT_VERIFY_FLAGS_NONE,
    631                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    632                         &data));
    633   ExpMD(0,
    634         0,
    635         0,  // A: pri, tries, successful
    636         14,
    637         0,
    638         1,                           // B: pri, tries, successful
    639         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    640   ASSERT_NE(nullptr, data);
    641   EXPECT_EQ("_b", std::string(data->ab_suffix));
    642   avb_slot_verify_data_free(data);
    643 
    644   // Slot B is invalid.
    645   SetMD(15,
    646         0,
    647         1,
    648         SV_OK,
    649         0,
    650         0,  // A: pri, tries, success, slot_validity, RIs
    651         14,
    652         0,
    653         1,
    654         SV_INV,
    655         0,
    656         0,  // B: pri, tries, success, slot_validity, RIs
    657         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    658   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    659             avb_ab_flow(ops_.avb_ab_ops(),
    660                         requested_partitions,
    661                         AVB_SLOT_VERIFY_FLAGS_NONE,
    662                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    663                         &data));
    664   ExpMD(15,
    665         0,
    666         1,  // A: pri, tries, successful
    667         0,
    668         0,
    669         0,                           // B: pri, tries, successful
    670         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    671   ASSERT_NE(nullptr, data);
    672   EXPECT_EQ("_a", std::string(data->ab_suffix));
    673   avb_slot_verify_data_free(data);
    674 
    675   // Both slots are invalid.
    676   SetMD(15,
    677         0,
    678         1,
    679         SV_INV,
    680         0,
    681         0,  // A: pri, tries, success, slot_validity, RIs
    682         14,
    683         0,
    684         1,
    685         SV_INV,
    686         0,
    687         0,  // B: pri, tries, success, slot_validity, RIs
    688         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    689   EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
    690             avb_ab_flow(ops_.avb_ab_ops(),
    691                         requested_partitions,
    692                         AVB_SLOT_VERIFY_FLAGS_NONE,
    693                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    694                         &data));
    695   ExpMD(0,
    696         0,
    697         0,  // A: pri, tries, successful
    698         0,
    699         0,
    700         0,                           // B: pri, tries, successful
    701         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    702   ASSERT_EQ(nullptr, data);
    703 }
    704 
    705 TEST_F(AvbABFlowTest, UnverifiedSlotIsMarkedAsSuch) {
    706   AvbSlotVerifyData* data;
    707   const char* requested_partitions[] = {"boot", NULL};
    708 
    709   // Slot A fails verification.
    710   SetMD(15,
    711         0,
    712         1,
    713         SV_UNV,
    714         0,
    715         0,  // A: pri, tries, success, slot_validity, RIs
    716         14,
    717         0,
    718         1,
    719         SV_OK,
    720         0,
    721         0,  // B: pri, tries, success, slot_validity, RIs
    722         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    723   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    724             avb_ab_flow(ops_.avb_ab_ops(),
    725                         requested_partitions,
    726                         AVB_SLOT_VERIFY_FLAGS_NONE,
    727                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    728                         &data));
    729   ExpMD(0,
    730         0,
    731         0,  // A: pri, tries, successful
    732         14,
    733         0,
    734         1,                           // B: pri, tries, successful
    735         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    736   ASSERT_NE(nullptr, data);
    737   EXPECT_EQ("_b", std::string(data->ab_suffix));
    738   avb_slot_verify_data_free(data);
    739 
    740   // Slot B fails verification.
    741   SetMD(15,
    742         0,
    743         1,
    744         SV_OK,
    745         0,
    746         0,  // A: pri, tries, success, slot_validity, RIs
    747         14,
    748         0,
    749         1,
    750         SV_UNV,
    751         0,
    752         0,  // B: pri, tries, success, slot_validity, RIs
    753         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    754   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    755             avb_ab_flow(ops_.avb_ab_ops(),
    756                         requested_partitions,
    757                         AVB_SLOT_VERIFY_FLAGS_NONE,
    758                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    759                         &data));
    760   ExpMD(15,
    761         0,
    762         1,  // A: pri, tries, successful
    763         0,
    764         0,
    765         0,                           // B: pri, tries, successful
    766         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    767   ASSERT_NE(nullptr, data);
    768   EXPECT_EQ("_a", std::string(data->ab_suffix));
    769   avb_slot_verify_data_free(data);
    770 
    771   // Both slots fail verification.
    772   SetMD(15,
    773         0,
    774         1,
    775         SV_UNV,
    776         0,
    777         0,  // A: pri, tries, success, slot_validity, RIs
    778         14,
    779         0,
    780         1,
    781         SV_UNV,
    782         0,
    783         0,  // B: pri, tries, success, slot_validity, RIs
    784         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    785   EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
    786             avb_ab_flow(ops_.avb_ab_ops(),
    787                         requested_partitions,
    788                         AVB_SLOT_VERIFY_FLAGS_NONE,
    789                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    790                         &data));
    791   ExpMD(0,
    792         0,
    793         0,  // A: pri, tries, successful
    794         0,
    795         0,
    796         0,                           // B: pri, tries, successful
    797         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    798   ASSERT_EQ(nullptr, data);
    799 }
    800 
    801 TEST_F(AvbABFlowTest, RollbackIndexFailures) {
    802   AvbSlotVerifyData* data;
    803   const char* requested_partitions[] = {"boot", NULL};
    804 
    805   // Slot A rollback index failure for 'boot'.
    806   SetMD(15,
    807         0,
    808         1,
    809         SV_OK,
    810         0,
    811         2,  // A: pri, tries, success, slot_validity, RIs
    812         14,
    813         0,
    814         1,
    815         SV_OK,
    816         2,
    817         2,  // B: pri, tries, success, slot_validity, RIs
    818         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
    819   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    820             avb_ab_flow(ops_.avb_ab_ops(),
    821                         requested_partitions,
    822                         AVB_SLOT_VERIFY_FLAGS_NONE,
    823                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    824                         &data));
    825   ExpMD(0,
    826         0,
    827         0,  // A: pri, tries, successful
    828         14,
    829         0,
    830         1,                           // B: pri, tries, successful
    831         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
    832   ASSERT_NE(nullptr, data);
    833   EXPECT_EQ("_b", std::string(data->ab_suffix));
    834   avb_slot_verify_data_free(data);
    835 
    836   // Slot A rollback index failure for 'odm'.
    837   SetMD(15,
    838         0,
    839         1,
    840         SV_OK,
    841         2,
    842         0,  // A: pri, tries, success, slot_validity, RIs
    843         14,
    844         0,
    845         1,
    846         SV_OK,
    847         2,
    848         2,  // B: pri, tries, success, slot_validity, RIs
    849         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
    850   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    851             avb_ab_flow(ops_.avb_ab_ops(),
    852                         requested_partitions,
    853                         AVB_SLOT_VERIFY_FLAGS_NONE,
    854                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    855                         &data));
    856   ExpMD(0,
    857         0,
    858         0,  // A: pri, tries, successful
    859         14,
    860         0,
    861         1,                           // B: pri, tries, successful
    862         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
    863   ASSERT_NE(nullptr, data);
    864   EXPECT_EQ("_b", std::string(data->ab_suffix));
    865   avb_slot_verify_data_free(data);
    866 }
    867 
    868 TEST_F(AvbABFlowTest, StoredRollbackIndexBumped) {
    869   AvbSlotVerifyData* data;
    870   const char* requested_partitions[] = {"boot", NULL};
    871 
    872   SetMD(15,
    873         0,
    874         1,
    875         SV_OK,
    876         3,
    877         3,  // A: pri, tries, success, slot_validity, RIs
    878         14,
    879         0,
    880         1,
    881         SV_OK,
    882         3,
    883         3,  // B: pri, tries, success, slot_validity, RIs
    884         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
    885   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    886             avb_ab_flow(ops_.avb_ab_ops(),
    887                         requested_partitions,
    888                         AVB_SLOT_VERIFY_FLAGS_NONE,
    889                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    890                         &data));
    891   ExpMD(15,
    892         0,
    893         1,  // A: pri, tries, successful
    894         14,
    895         0,
    896         1,                           // B: pri, tries, successful
    897         MakeRollbackIndexes(3, 3));  // stored_rollback_indexes
    898   ASSERT_NE(nullptr, data);
    899   EXPECT_EQ("_a", std::string(data->ab_suffix));
    900   avb_slot_verify_data_free(data);
    901 
    902   // The case where different partitions have different rollback
    903   // index values.
    904   SetMD(15,
    905         0,
    906         1,
    907         SV_OK,
    908         4,
    909         9,  // A: pri, tries, success, slot_validity, RIs
    910         14,
    911         0,
    912         1,
    913         SV_OK,
    914         5,
    915         7,  // B: pri, tries, success, slot_validity, RIs
    916         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    917   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    918             avb_ab_flow(ops_.avb_ab_ops(),
    919                         requested_partitions,
    920                         AVB_SLOT_VERIFY_FLAGS_NONE,
    921                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    922                         &data));
    923   ExpMD(15,
    924         0,
    925         1,  // A: pri, tries, successful
    926         14,
    927         0,
    928         1,                           // B: pri, tries, successful
    929         MakeRollbackIndexes(4, 7));  // stored_rollback_indexes
    930   ASSERT_NE(nullptr, data);
    931   EXPECT_EQ("_a", std::string(data->ab_suffix));
    932   avb_slot_verify_data_free(data);
    933 
    934   // If the slot with the low RI fails verification (or is invalid),
    935   // check that these low Rollback Indexs are not taken into account
    936   // after marking it as unbootable.
    937   SetMD(15,
    938         0,
    939         1,
    940         SV_INV,
    941         4,
    942         9,  // A: pri, tries, success, slot_validity, RIs
    943         14,
    944         0,
    945         1,
    946         SV_OK,
    947         5,
    948         7,  // B: pri, tries, success, slot_validity, RIs
    949         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    950   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
    951             avb_ab_flow(ops_.avb_ab_ops(),
    952                         requested_partitions,
    953                         AVB_SLOT_VERIFY_FLAGS_NONE,
    954                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
    955                         &data));
    956   ExpMD(0,
    957         0,
    958         0,  // A: pri, tries, successful
    959         14,
    960         0,
    961         1,                           // B: pri, tries, successful
    962         MakeRollbackIndexes(5, 7));  // stored_rollback_indexes
    963   ASSERT_NE(nullptr, data);
    964   EXPECT_EQ("_b", std::string(data->ab_suffix));
    965   avb_slot_verify_data_free(data);
    966 }
    967 
    968 TEST_F(AvbABFlowTest, MarkSlotActive) {
    969   SetMD(15,
    970         0,
    971         1,
    972         SV_INV,
    973         0,
    974         0,  // A: pri, tries, success, slot_validity, RIs
    975         11,
    976         0,
    977         1,
    978         SV_OK,
    979         0,
    980         0,  // B: pri, tries, success, slot_validity, RIs
    981         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    982   EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_mark_slot_active(ops_.avb_ab_ops(), 0));
    983   ExpMD(15,
    984         7,
    985         0,  // A: pri, tries, successful
    986         11,
    987         0,
    988         1,                           // B: pri, tries, successful
    989         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
    990 
    991   // Note how priority of slot A is altered to make room for newly
    992   // activated slot.
    993   SetMD(15,
    994         0,
    995         1,
    996         SV_INV,
    997         0,
    998         0,  // A: pri, tries, success, slot_validity, RIs
    999         14,
   1000         0,
   1001         1,
   1002         SV_OK,
   1003         0,
   1004         0,  // B: pri, tries, success, slot_validity, RIs
   1005         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1006   EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_mark_slot_active(ops_.avb_ab_ops(), 1));
   1007   ExpMD(14,
   1008         0,
   1009         1,  // A: pri, tries, successful
   1010         15,
   1011         7,
   1012         0,                           // B: pri, tries, successful
   1013         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1014 }
   1015 
   1016 TEST_F(AvbABFlowTest, MarkSlotUnbootable) {
   1017   SetMD(15,
   1018         0,
   1019         1,
   1020         SV_INV,
   1021         0,
   1022         0,  // A: pri, tries, success, slot_validity, RIs
   1023         11,
   1024         0,
   1025         1,
   1026         SV_OK,
   1027         0,
   1028         0,  // B: pri, tries, success, slot_validity, RIs
   1029         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1030   EXPECT_EQ(AVB_IO_RESULT_OK,
   1031             avb_ab_mark_slot_unbootable(ops_.avb_ab_ops(), 0));
   1032   ExpMD(0,
   1033         0,
   1034         0,  // A: pri, tries, successful
   1035         11,
   1036         0,
   1037         1,                           // B: pri, tries, successful
   1038         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1039 
   1040   SetMD(15,
   1041         0,
   1042         1,
   1043         SV_INV,
   1044         0,
   1045         0,  // A: pri, tries, success, slot_validity, RIs
   1046         14,
   1047         0,
   1048         1,
   1049         SV_OK,
   1050         0,
   1051         0,  // B: pri, tries, success, slot_validity, RIs
   1052         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1053   EXPECT_EQ(AVB_IO_RESULT_OK,
   1054             avb_ab_mark_slot_unbootable(ops_.avb_ab_ops(), 1));
   1055   ExpMD(15,
   1056         0,
   1057         1,  // A: pri, tries, successful
   1058         0,
   1059         0,
   1060         0,                           // B: pri, tries, successful
   1061         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1062 }
   1063 
   1064 TEST_F(AvbABFlowTest, MarkSlotSuccessful) {
   1065   SetMD(15,
   1066         5,
   1067         0,
   1068         SV_INV,
   1069         0,
   1070         0,  // A: pri, tries, success, slot_validity, RIs
   1071         11,
   1072         3,
   1073         0,
   1074         SV_OK,
   1075         0,
   1076         0,  // B: pri, tries, success, slot_validity, RIs
   1077         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1078   EXPECT_EQ(AVB_IO_RESULT_OK,
   1079             avb_ab_mark_slot_successful(ops_.avb_ab_ops(), 0));
   1080   ExpMD(15,
   1081         0,
   1082         1,  // A: pri, tries, successful
   1083         11,
   1084         3,
   1085         0,                           // B: pri, tries, successful
   1086         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1087 
   1088   SetMD(15,
   1089         5,
   1090         0,
   1091         SV_INV,
   1092         0,
   1093         0,  // A: pri, tries, success, slot_validity, RIs
   1094         14,
   1095         0,
   1096         1,
   1097         SV_OK,
   1098         0,
   1099         0,  // B: pri, tries, success, slot_validity, RIs
   1100         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1101   EXPECT_EQ(AVB_IO_RESULT_OK,
   1102             avb_ab_mark_slot_successful(ops_.avb_ab_ops(), 1));
   1103   ExpMD(15,
   1104         5,
   1105         0,  // A: pri, tries, successful
   1106         14,
   1107         0,
   1108         1,                           // B: pri, tries, successful
   1109         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1110 
   1111   // Marking an unbootable slot (A) as successful won't work (it's a
   1112   // programmer error to do so)... notice however that the unbootable
   1113   // slot is normalized in the process.
   1114   SetMD(0,
   1115         3,
   1116         2,
   1117         SV_INV,
   1118         0,
   1119         0,  // A: pri, tries, success, slot_validity, RIs
   1120         14,
   1121         0,
   1122         1,
   1123         SV_OK,
   1124         0,
   1125         0,  // B: pri, tries, success, slot_validity, RIs
   1126         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1127   EXPECT_EQ(AVB_IO_RESULT_OK,
   1128             avb_ab_mark_slot_successful(ops_.avb_ab_ops(), 0));
   1129   ExpMD(0,
   1130         0,
   1131         0,  // A: pri, tries, successful
   1132         14,
   1133         0,
   1134         1,                           // B: pri, tries, successful
   1135         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1136 }
   1137 
   1138 static AvbABData my_serialized_data;
   1139 
   1140 static AvbIOResult my_write_ab_metadata(AvbABOps* ops,
   1141                                         const struct AvbABData* data) {
   1142   avb_ab_data_update_crc_and_byteswap(data, &my_serialized_data);
   1143   return AVB_IO_RESULT_OK;
   1144 }
   1145 
   1146 static AvbIOResult my_read_ab_metadata(AvbABOps* ops, struct AvbABData* data) {
   1147   if (!avb_ab_data_verify_and_byteswap(&my_serialized_data, data)) {
   1148     avb_error(
   1149         "Error validating A/B metadata from persistent storage. "
   1150         "Resetting and writing new A/B metadata to persistent storage.\n");
   1151     avb_ab_data_init(data);
   1152     return my_write_ab_metadata(ops, data);
   1153   }
   1154   return AVB_IO_RESULT_OK;
   1155 }
   1156 
   1157 TEST_F(AvbABFlowTest, OtherMetadataStorage) {
   1158   AvbSlotVerifyData* data;
   1159   const char* requested_partitions[] = {"boot", NULL};
   1160 
   1161   // Use our own A/B storage routines (see above).
   1162   ops_.avb_ab_ops()->read_ab_metadata = my_read_ab_metadata;
   1163   ops_.avb_ab_ops()->write_ab_metadata = my_write_ab_metadata;
   1164 
   1165   SetMD(14,
   1166         0,
   1167         1,
   1168         SV_OK,
   1169         0,
   1170         0,  // A: pri, tries, success, slot_validity, RIs
   1171         15,
   1172         0,
   1173         1,
   1174         SV_OK,
   1175         0,
   1176         0,  // B: pri, tries, success, slot_validity, RIs
   1177         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1178   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
   1179             avb_ab_flow(ops_.avb_ab_ops(),
   1180                         requested_partitions,
   1181                         AVB_SLOT_VERIFY_FLAGS_NONE,
   1182                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1183                         &data));
   1184   ExpMD(14,
   1185         0,
   1186         1,  // A: pri, tries, successful
   1187         15,
   1188         0,
   1189         1,                           // B: pri, tries, successful
   1190         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1191   ASSERT_NE(nullptr, data);
   1192   EXPECT_EQ("_b", std::string(data->ab_suffix));
   1193   avb_slot_verify_data_free(data);
   1194 
   1195   // Also check the other slot.
   1196   SetMD(15,
   1197         0,
   1198         1,
   1199         SV_OK,
   1200         0,
   1201         0,  // A: pri, tries, success, slot_validity, RIs
   1202         14,
   1203         0,
   1204         1,
   1205         SV_OK,
   1206         0,
   1207         0,  // B: pri, tries, success, slot_validity, RIs
   1208         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1209   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
   1210             avb_ab_flow(ops_.avb_ab_ops(),
   1211                         requested_partitions,
   1212                         AVB_SLOT_VERIFY_FLAGS_NONE,
   1213                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1214                         &data));
   1215   ExpMD(15,
   1216         0,
   1217         1,  // A: pri, tries, successful
   1218         14,
   1219         0,
   1220         1,                           // B: pri, tries, successful
   1221         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1222   ASSERT_NE(nullptr, data);
   1223   EXPECT_EQ("_a", std::string(data->ab_suffix));
   1224   avb_slot_verify_data_free(data);
   1225 
   1226   // Check that 'misc' hasn't been written to at all.
   1227   std::string misc_data;
   1228   base::FilePath misc_path = testdir_.Append("misc.img");
   1229   ASSERT_TRUE(base::ReadFileToString(misc_path, &misc_data));
   1230   EXPECT_EQ(size_t(MISC_PART_SIZE), misc_data.size());
   1231   for (size_t n = 0; n < misc_data.size(); n++) {
   1232     ASSERT_EQ(uint8_t(misc_data[n]), 0);
   1233   }
   1234 }
   1235 
   1236 TEST_F(AvbABFlowTest, UnlockedUnverifiedSlot) {
   1237   AvbSlotVerifyData* data;
   1238   const char* requested_partitions[] = {"boot", NULL};
   1239 
   1240   SetMD(14,
   1241         0,
   1242         1,
   1243         SV_OK,
   1244         0,
   1245         0,  // A: pri, tries, success, slot_validity, RIs
   1246         15,
   1247         0,
   1248         1,
   1249         SV_UNV,
   1250         0,
   1251         0,  // B: pri, tries, success, slot_validity, RIs
   1252         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1253   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
   1254             avb_ab_flow(ops_.avb_ab_ops(),
   1255                         requested_partitions,
   1256                         AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
   1257                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1258                         &data));
   1259   ExpMD(14,
   1260         0,
   1261         1,  // A: pri, tries, successful
   1262         15,
   1263         0,
   1264         1,                           // B: pri, tries, successful
   1265         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1266   ASSERT_NE(nullptr, data);
   1267   EXPECT_EQ("_b", std::string(data->ab_suffix));
   1268   avb_slot_verify_data_free(data);
   1269 
   1270   // Also check the other slot.
   1271   SetMD(15,
   1272         0,
   1273         1,
   1274         SV_UNV,
   1275         0,
   1276         0,  // A: pri, tries, success, slot_validity, RIs
   1277         14,
   1278         0,
   1279         1,
   1280         SV_OK,
   1281         0,
   1282         0,  // B: pri, tries, success, slot_validity, RIs
   1283         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1284   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
   1285             avb_ab_flow(ops_.avb_ab_ops(),
   1286                         requested_partitions,
   1287                         AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
   1288                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
   1289                         &data));
   1290   ExpMD(15,
   1291         0,
   1292         1,  // A: pri, tries, successful
   1293         14,
   1294         0,
   1295         1,                           // B: pri, tries, successful
   1296         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
   1297   ASSERT_NE(nullptr, data);
   1298   EXPECT_EQ("_a", std::string(data->ab_suffix));
   1299   avb_slot_verify_data_free(data);
   1300 }
   1301 
   1302 TEST_F(AvbABFlowTest, AvbtoolMetadataGeneratorEmptyFile) {
   1303   AvbABData data;
   1304 
   1305   base::FilePath misc_path = testdir_.Append("misc.img");
   1306   EXPECT_COMMAND(0,
   1307                  "./avbtool set_ab_metadata"
   1308                  " --misc_image %s"
   1309                  " --slot_data 13:3:0:11:2:1",
   1310                  misc_path.value().c_str());
   1311 
   1312   EXPECT_EQ(AVB_IO_RESULT_OK,
   1313             ops_.avb_ab_ops()->read_ab_metadata(ops_.avb_ab_ops(), &data));
   1314   EXPECT_EQ(13, data.slots[0].priority);
   1315   EXPECT_EQ(3, data.slots[0].tries_remaining);
   1316   EXPECT_EQ(0, data.slots[0].successful_boot);
   1317   EXPECT_EQ(11, data.slots[1].priority);
   1318   EXPECT_EQ(2, data.slots[1].tries_remaining);
   1319   EXPECT_EQ(1, data.slots[1].successful_boot);
   1320 }
   1321 
   1322 TEST_F(AvbABFlowTest, AvbtoolMetadataGeneratorExistingFile) {
   1323   AvbABData data;
   1324   size_t n;
   1325 
   1326   size_t misc_size = 1024 * 1024;
   1327   base::FilePath misc_path = GenerateImage("misc.img", misc_size);
   1328   EXPECT_COMMAND(0,
   1329                  "./avbtool set_ab_metadata"
   1330                  " --misc_image %s"
   1331                  " --slot_data 12:2:1:10:5:0",
   1332                  misc_path.value().c_str());
   1333 
   1334   EXPECT_EQ(AVB_IO_RESULT_OK,
   1335             ops_.avb_ab_ops()->read_ab_metadata(ops_.avb_ab_ops(), &data));
   1336   EXPECT_EQ(12, data.slots[0].priority);
   1337   EXPECT_EQ(2, data.slots[0].tries_remaining);
   1338   EXPECT_EQ(1, data.slots[0].successful_boot);
   1339   EXPECT_EQ(10, data.slots[1].priority);
   1340   EXPECT_EQ(5, data.slots[1].tries_remaining);
   1341   EXPECT_EQ(0, data.slots[1].successful_boot);
   1342 
   1343   std::string misc_data;
   1344   ASSERT_TRUE(base::ReadFileToString(misc_path, &misc_data));
   1345   EXPECT_EQ(misc_size, misc_data.size());
   1346   for (n = 0; n < 2048; n++) {
   1347     ASSERT_EQ(uint8_t(misc_data[n]), uint8_t(n));
   1348   }
   1349   for (n = 2048 + 32; n < misc_data.size(); n++) {
   1350     ASSERT_EQ(uint8_t(misc_data[n]), uint8_t(n));
   1351   }
   1352 }
   1353 
   1354 }  // namespace avb
   1355