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