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:
ABTest()48   ABTest() {}
49 };
50 
TEST_F(ABTest,InitData)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 
TEST_F(ABTest,DataSerialization)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 
TEST_F(ABTest,CatchBadCRC)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 
TEST_F(ABTest,CatchUnsupportedMajorVersion)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 
TEST_F(ABTest,SupportSameMajorFutureMinorVersion)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:
AvbABFlowTest()133   AvbABFlowTest() {}
134 
SetUp()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 
GenerateSlot(unsigned int slot_number,SlotValidity slot_validity,uint64_t rollback_boot,uint64_t rollback_odm)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                    odm_path.value().c_str(),
206                    rollback_odm,
207                    odm_partition_size);
208 
209     base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
210     EXPECT_COMMAND(
211         0,
212         "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
213         " --output %s",
214         pk_path.value().c_str());
215 
216     // If requested to make the image unverified, just use another key
217     // in the chain_partition descriptor since this will cause
218     // avb_slot_verify() to return ERROR_PUBLIC_KEY_REJECTED.
219     if (slot_validity == SV_UNV) {
220       pk_path = GenerateImage("dummy.avbpubkey", 32);
221     }
222 
223     GenerateVBMetaImage(vbmeta_name,
224                         "SHA256_RSA2048",
225                         rollback_boot,
226                         base::FilePath("test/data/testkey_rsa2048.pem"),
227                         base::StringPrintf("--include_descriptors_from_image %s"
228                                            " --chain_partition odm:1:%s",
229                                            boot_path.value().c_str(),
230                                            pk_path.value().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                         false /* allow_verification_error */,
335                         &data));
336   ExpMD(14,
337         0,
338         1,  // A: pri, tries, successful
339         15,
340         0,
341         1,                           // B: pri, tries, successful
342         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
343   ASSERT_NE(nullptr, data);
344   EXPECT_EQ("_b", std::string(data->ab_suffix));
345   avb_slot_verify_data_free(data);
346 
347   // Also check the other slot.
348   SetMD(15,
349         0,
350         1,
351         SV_OK,
352         0,
353         0,  // A: pri, tries, success, slot_validity, RIs
354         14,
355         0,
356         1,
357         SV_OK,
358         0,
359         0,  // B: pri, tries, success, slot_validity, RIs
360         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
361   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
362             avb_ab_flow(ops_.avb_ab_ops(),
363                         requested_partitions,
364                         false /* allow_verification_error */,
365                         &data));
366   ExpMD(15,
367         0,
368         1,  // A: pri, tries, successful
369         14,
370         0,
371         1,                           // B: pri, tries, successful
372         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
373   ASSERT_NE(nullptr, data);
374   EXPECT_EQ("_a", std::string(data->ab_suffix));
375   avb_slot_verify_data_free(data);
376 }
377 
TEST_F(AvbABFlowTest,NoBootableSlots)378 TEST_F(AvbABFlowTest, NoBootableSlots) {
379   AvbSlotVerifyData* data;
380   const char* requested_partitions[] = {"boot", NULL};
381 
382   SetMD(0,
383         0,
384         0,
385         SV_OK,
386         0,
387         0,  // A: pri, tries, success, slot_validity, RIs
388         0,
389         0,
390         0,
391         SV_OK,
392         0,
393         0,  // B: pri, tries, success, slot_validity, RIs
394         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
395   EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
396             avb_ab_flow(ops_.avb_ab_ops(),
397                         requested_partitions,
398                         false /* allow_verification_error */,
399                         &data));
400   ExpMD(0,
401         0,
402         0,  // A: pri, tries, successful
403         0,
404         0,
405         0,                           // B: pri, tries, successful
406         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
407   ASSERT_EQ(nullptr, data);
408 }
409 
TEST_F(AvbABFlowTest,TriesRemainingDecreasing)410 TEST_F(AvbABFlowTest, TriesRemainingDecreasing) {
411   AvbSlotVerifyData* data;
412   const char* requested_partitions[] = {"boot", NULL};
413 
414   SetMD(15,
415         3,
416         0,
417         SV_OK,
418         0,
419         0,  // A: pri, tries, success, slot_validity, RIs
420         0,
421         0,
422         0,
423         SV_OK,
424         0,
425         0,  // B: pri, tries, success, slot_validity, RIs
426         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
427 
428   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
429             avb_ab_flow(ops_.avb_ab_ops(),
430                         requested_partitions,
431                         false /* allow_verification_error */,
432                         &data));
433   ExpMD(15,
434         2,
435         0,  // A: pri, tries, successful
436         0,
437         0,
438         0,                           // B: pri, tries, successful
439         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
440   ASSERT_NE(nullptr, data);
441   EXPECT_EQ("_a", std::string(data->ab_suffix));
442   avb_slot_verify_data_free(data);
443 
444   // Keep counting down...
445   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
446             avb_ab_flow(ops_.avb_ab_ops(),
447                         requested_partitions,
448                         false /* allow_verification_error */,
449                         &data));
450   ExpMD(15,
451         1,
452         0,  // A: pri, tries, successful
453         0,
454         0,
455         0,                           // B: pri, tries, successful
456         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
457   ASSERT_NE(nullptr, data);
458   EXPECT_EQ("_a", std::string(data->ab_suffix));
459   avb_slot_verify_data_free(data);
460 
461   // Last try...
462   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
463             avb_ab_flow(ops_.avb_ab_ops(),
464                         requested_partitions,
465                         false /* allow_verification_error */,
466                         &data));
467   ExpMD(15,
468         0,
469         0,  // A: pri, tries, successful
470         0,
471         0,
472         0,                           // B: pri, tries, successful
473         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
474   ASSERT_NE(nullptr, data);
475   EXPECT_EQ("_a", std::string(data->ab_suffix));
476   avb_slot_verify_data_free(data);
477 
478   // And we're out of tries. At this point, (15, 0, 0) is normalized
479   // to (0, 0, 0) so expect that.
480   EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
481             avb_ab_flow(ops_.avb_ab_ops(),
482                         requested_partitions,
483                         false /* allow_verification_error */,
484                         &data));
485   ExpMD(0,
486         0,
487         0,  // A: pri, tries, successful
488         0,
489         0,
490         0,                           // B: pri, tries, successful
491         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
492   ASSERT_EQ(nullptr, data);
493 }
494 
TEST_F(AvbABFlowTest,TryingThenFallback)495 TEST_F(AvbABFlowTest, TryingThenFallback) {
496   AvbSlotVerifyData* data;
497   const char* requested_partitions[] = {"boot", NULL};
498 
499   SetMD(15,
500         2,
501         0,
502         SV_OK,
503         0,
504         0,  // A: pri, tries, success, slot_validity, RIs
505         14,
506         0,
507         1,
508         SV_OK,
509         0,
510         0,  // B: pri, tries, success, slot_validity, RIs
511         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
512   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
513             avb_ab_flow(ops_.avb_ab_ops(),
514                         requested_partitions,
515                         false /* allow_verification_error */,
516                         &data));
517   ExpMD(15,
518         1,
519         0,  // A: pri, tries, successful
520         14,
521         0,
522         1,                           // B: pri, tries, successful
523         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
524   ASSERT_NE(nullptr, data);
525   EXPECT_EQ("_a", std::string(data->ab_suffix));
526   avb_slot_verify_data_free(data);
527 
528   // Last try...
529   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
530             avb_ab_flow(ops_.avb_ab_ops(),
531                         requested_partitions,
532                         false /* allow_verification_error */,
533                         &data));
534   ExpMD(15,
535         0,
536         0,  // A: pri, tries, successful
537         14,
538         0,
539         1,                           // B: pri, tries, successful
540         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
541   ASSERT_NE(nullptr, data);
542   EXPECT_EQ("_a", std::string(data->ab_suffix));
543   avb_slot_verify_data_free(data);
544 
545   // And we're out of tries. Check we fall back to slot B.
546   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
547             avb_ab_flow(ops_.avb_ab_ops(),
548                         requested_partitions,
549                         false /* allow_verification_error */,
550                         &data));
551   ExpMD(0,
552         0,
553         0,  // A: pri, tries, successful
554         14,
555         0,
556         1,                           // B: pri, tries, successful
557         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
558   ASSERT_NE(nullptr, data);
559   EXPECT_EQ("_b", std::string(data->ab_suffix));
560   avb_slot_verify_data_free(data);
561 }
562 
TEST_F(AvbABFlowTest,TriesRemainingNotDecreasingIfNotPriority)563 TEST_F(AvbABFlowTest, TriesRemainingNotDecreasingIfNotPriority) {
564   AvbSlotVerifyData* data;
565   const char* requested_partitions[] = {"boot", NULL};
566 
567   SetMD(15,
568         0,
569         1,
570         SV_OK,
571         0,
572         0,  // A: pri, tries, success, slot_validity, RIs
573         14,
574         7,
575         0,
576         SV_OK,
577         0,
578         0,  // B: pri, tries, success, slot_validity, RIs
579         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
580   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
581             avb_ab_flow(ops_.avb_ab_ops(),
582                         requested_partitions,
583                         false /* allow_verification_error */,
584                         &data));
585   ExpMD(15,
586         0,
587         1,  // A: pri, tries, successful
588         14,
589         7,
590         0,                           // B: pri, tries, successful
591         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
592   ASSERT_NE(nullptr, data);
593   EXPECT_EQ("_a", std::string(data->ab_suffix));
594   avb_slot_verify_data_free(data);
595 }
596 
TEST_F(AvbABFlowTest,InvalidSlotIsMarkedAsSuch)597 TEST_F(AvbABFlowTest, InvalidSlotIsMarkedAsSuch) {
598   AvbSlotVerifyData* data;
599   const char* requested_partitions[] = {"boot", NULL};
600 
601   // Slot A is invalid.
602   SetMD(15,
603         0,
604         1,
605         SV_INV,
606         0,
607         0,  // A: pri, tries, success, slot_validity, RIs
608         14,
609         0,
610         1,
611         SV_OK,
612         0,
613         0,  // B: pri, tries, success, slot_validity, RIs
614         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
615   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
616             avb_ab_flow(ops_.avb_ab_ops(),
617                         requested_partitions,
618                         false /* allow_verification_error */,
619                         &data));
620   ExpMD(0,
621         0,
622         0,  // A: pri, tries, successful
623         14,
624         0,
625         1,                           // B: pri, tries, successful
626         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
627   ASSERT_NE(nullptr, data);
628   EXPECT_EQ("_b", std::string(data->ab_suffix));
629   avb_slot_verify_data_free(data);
630 
631   // Slot B is invalid.
632   SetMD(15,
633         0,
634         1,
635         SV_OK,
636         0,
637         0,  // A: pri, tries, success, slot_validity, RIs
638         14,
639         0,
640         1,
641         SV_INV,
642         0,
643         0,  // B: pri, tries, success, slot_validity, RIs
644         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
645   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
646             avb_ab_flow(ops_.avb_ab_ops(),
647                         requested_partitions,
648                         false /* allow_verification_error */,
649                         &data));
650   ExpMD(15,
651         0,
652         1,  // A: pri, tries, successful
653         0,
654         0,
655         0,                           // B: pri, tries, successful
656         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
657   ASSERT_NE(nullptr, data);
658   EXPECT_EQ("_a", std::string(data->ab_suffix));
659   avb_slot_verify_data_free(data);
660 
661   // Both slots are invalid.
662   SetMD(15,
663         0,
664         1,
665         SV_INV,
666         0,
667         0,  // A: pri, tries, success, slot_validity, RIs
668         14,
669         0,
670         1,
671         SV_INV,
672         0,
673         0,  // B: pri, tries, success, slot_validity, RIs
674         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
675   EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
676             avb_ab_flow(ops_.avb_ab_ops(),
677                         requested_partitions,
678                         false /* allow_verification_error */,
679                         &data));
680   ExpMD(0,
681         0,
682         0,  // A: pri, tries, successful
683         0,
684         0,
685         0,                           // B: pri, tries, successful
686         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
687   ASSERT_EQ(nullptr, data);
688 }
689 
TEST_F(AvbABFlowTest,UnverifiedSlotIsMarkedAsSuch)690 TEST_F(AvbABFlowTest, UnverifiedSlotIsMarkedAsSuch) {
691   AvbSlotVerifyData* data;
692   const char* requested_partitions[] = {"boot", NULL};
693 
694   // Slot A fails verification.
695   SetMD(15,
696         0,
697         1,
698         SV_UNV,
699         0,
700         0,  // A: pri, tries, success, slot_validity, RIs
701         14,
702         0,
703         1,
704         SV_OK,
705         0,
706         0,  // B: pri, tries, success, slot_validity, RIs
707         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
708   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
709             avb_ab_flow(ops_.avb_ab_ops(),
710                         requested_partitions,
711                         false /* allow_verification_error */,
712                         &data));
713   ExpMD(0,
714         0,
715         0,  // A: pri, tries, successful
716         14,
717         0,
718         1,                           // B: pri, tries, successful
719         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
720   ASSERT_NE(nullptr, data);
721   EXPECT_EQ("_b", std::string(data->ab_suffix));
722   avb_slot_verify_data_free(data);
723 
724   // Slot B fails verification.
725   SetMD(15,
726         0,
727         1,
728         SV_OK,
729         0,
730         0,  // A: pri, tries, success, slot_validity, RIs
731         14,
732         0,
733         1,
734         SV_UNV,
735         0,
736         0,  // B: pri, tries, success, slot_validity, RIs
737         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
738   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
739             avb_ab_flow(ops_.avb_ab_ops(),
740                         requested_partitions,
741                         false /* allow_verification_error */,
742                         &data));
743   ExpMD(15,
744         0,
745         1,  // A: pri, tries, successful
746         0,
747         0,
748         0,                           // B: pri, tries, successful
749         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
750   ASSERT_NE(nullptr, data);
751   EXPECT_EQ("_a", std::string(data->ab_suffix));
752   avb_slot_verify_data_free(data);
753 
754   // Both slots fail verification.
755   SetMD(15,
756         0,
757         1,
758         SV_UNV,
759         0,
760         0,  // A: pri, tries, success, slot_validity, RIs
761         14,
762         0,
763         1,
764         SV_UNV,
765         0,
766         0,  // B: pri, tries, success, slot_validity, RIs
767         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
768   EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS,
769             avb_ab_flow(ops_.avb_ab_ops(),
770                         requested_partitions,
771                         false /* allow_verification_error */,
772                         &data));
773   ExpMD(0,
774         0,
775         0,  // A: pri, tries, successful
776         0,
777         0,
778         0,                           // B: pri, tries, successful
779         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
780   ASSERT_EQ(nullptr, data);
781 }
782 
TEST_F(AvbABFlowTest,RollbackIndexFailures)783 TEST_F(AvbABFlowTest, RollbackIndexFailures) {
784   AvbSlotVerifyData* data;
785   const char* requested_partitions[] = {"boot", NULL};
786 
787   // Slot A rollback index failure for 'boot'.
788   SetMD(15,
789         0,
790         1,
791         SV_OK,
792         0,
793         2,  // A: pri, tries, success, slot_validity, RIs
794         14,
795         0,
796         1,
797         SV_OK,
798         2,
799         2,  // B: pri, tries, success, slot_validity, RIs
800         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
801   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
802             avb_ab_flow(ops_.avb_ab_ops(),
803                         requested_partitions,
804                         false /* allow_verification_error */,
805                         &data));
806   ExpMD(0,
807         0,
808         0,  // A: pri, tries, successful
809         14,
810         0,
811         1,                           // B: pri, tries, successful
812         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
813   ASSERT_NE(nullptr, data);
814   EXPECT_EQ("_b", std::string(data->ab_suffix));
815   avb_slot_verify_data_free(data);
816 
817   // Slot A rollback index failure for 'odm'.
818   SetMD(15,
819         0,
820         1,
821         SV_OK,
822         2,
823         0,  // A: pri, tries, success, slot_validity, RIs
824         14,
825         0,
826         1,
827         SV_OK,
828         2,
829         2,  // B: pri, tries, success, slot_validity, RIs
830         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
831   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
832             avb_ab_flow(ops_.avb_ab_ops(),
833                         requested_partitions,
834                         false /* allow_verification_error */,
835                         &data));
836   ExpMD(0,
837         0,
838         0,  // A: pri, tries, successful
839         14,
840         0,
841         1,                           // B: pri, tries, successful
842         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
843   ASSERT_NE(nullptr, data);
844   EXPECT_EQ("_b", std::string(data->ab_suffix));
845   avb_slot_verify_data_free(data);
846 }
847 
TEST_F(AvbABFlowTest,StoredRollbackIndexBumped)848 TEST_F(AvbABFlowTest, StoredRollbackIndexBumped) {
849   AvbSlotVerifyData* data;
850   const char* requested_partitions[] = {"boot", NULL};
851 
852   SetMD(15,
853         0,
854         1,
855         SV_OK,
856         3,
857         3,  // A: pri, tries, success, slot_validity, RIs
858         14,
859         0,
860         1,
861         SV_OK,
862         3,
863         3,  // B: pri, tries, success, slot_validity, RIs
864         MakeRollbackIndexes(2, 2));  // stored_rollback_indexes
865   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
866             avb_ab_flow(ops_.avb_ab_ops(),
867                         requested_partitions,
868                         false /* allow_verification_error */,
869                         &data));
870   ExpMD(15,
871         0,
872         1,  // A: pri, tries, successful
873         14,
874         0,
875         1,                           // B: pri, tries, successful
876         MakeRollbackIndexes(3, 3));  // stored_rollback_indexes
877   ASSERT_NE(nullptr, data);
878   EXPECT_EQ("_a", std::string(data->ab_suffix));
879   avb_slot_verify_data_free(data);
880 
881   // The case where different partitions have different rollback
882   // index values.
883   SetMD(15,
884         0,
885         1,
886         SV_OK,
887         4,
888         9,  // A: pri, tries, success, slot_validity, RIs
889         14,
890         0,
891         1,
892         SV_OK,
893         5,
894         7,  // B: pri, tries, success, slot_validity, RIs
895         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
896   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
897             avb_ab_flow(ops_.avb_ab_ops(),
898                         requested_partitions,
899                         false /* allow_verification_error */,
900                         &data));
901   ExpMD(15,
902         0,
903         1,  // A: pri, tries, successful
904         14,
905         0,
906         1,                           // B: pri, tries, successful
907         MakeRollbackIndexes(4, 7));  // stored_rollback_indexes
908   ASSERT_NE(nullptr, data);
909   EXPECT_EQ("_a", std::string(data->ab_suffix));
910   avb_slot_verify_data_free(data);
911 
912   // If the slot with the low RI fails verification (or is invalid),
913   // check that these low Rollback Indexs are not taken into account
914   // after marking it as unbootable.
915   SetMD(15,
916         0,
917         1,
918         SV_INV,
919         4,
920         9,  // A: pri, tries, success, slot_validity, RIs
921         14,
922         0,
923         1,
924         SV_OK,
925         5,
926         7,  // B: pri, tries, success, slot_validity, RIs
927         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
928   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
929             avb_ab_flow(ops_.avb_ab_ops(),
930                         requested_partitions,
931                         false /* allow_verification_error */,
932                         &data));
933   ExpMD(0,
934         0,
935         0,  // A: pri, tries, successful
936         14,
937         0,
938         1,                           // B: pri, tries, successful
939         MakeRollbackIndexes(5, 7));  // stored_rollback_indexes
940   ASSERT_NE(nullptr, data);
941   EXPECT_EQ("_b", std::string(data->ab_suffix));
942   avb_slot_verify_data_free(data);
943 }
944 
TEST_F(AvbABFlowTest,MarkSlotActive)945 TEST_F(AvbABFlowTest, MarkSlotActive) {
946   SetMD(15,
947         0,
948         1,
949         SV_INV,
950         0,
951         0,  // A: pri, tries, success, slot_validity, RIs
952         11,
953         0,
954         1,
955         SV_OK,
956         0,
957         0,  // B: pri, tries, success, slot_validity, RIs
958         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
959   EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_mark_slot_active(ops_.avb_ab_ops(), 0));
960   ExpMD(15,
961         7,
962         0,  // A: pri, tries, successful
963         11,
964         0,
965         1,                           // B: pri, tries, successful
966         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
967 
968   // Note how priority of slot A is altered to make room for newly
969   // activated slot.
970   SetMD(15,
971         0,
972         1,
973         SV_INV,
974         0,
975         0,  // A: pri, tries, success, slot_validity, RIs
976         14,
977         0,
978         1,
979         SV_OK,
980         0,
981         0,  // B: pri, tries, success, slot_validity, RIs
982         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
983   EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_mark_slot_active(ops_.avb_ab_ops(), 1));
984   ExpMD(14,
985         0,
986         1,  // A: pri, tries, successful
987         15,
988         7,
989         0,                           // B: pri, tries, successful
990         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
991 }
992 
TEST_F(AvbABFlowTest,MarkSlotUnbootable)993 TEST_F(AvbABFlowTest, MarkSlotUnbootable) {
994   SetMD(15,
995         0,
996         1,
997         SV_INV,
998         0,
999         0,  // A: pri, tries, success, slot_validity, RIs
1000         11,
1001         0,
1002         1,
1003         SV_OK,
1004         0,
1005         0,  // B: pri, tries, success, slot_validity, RIs
1006         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1007   EXPECT_EQ(AVB_IO_RESULT_OK,
1008             avb_ab_mark_slot_unbootable(ops_.avb_ab_ops(), 0));
1009   ExpMD(0,
1010         0,
1011         0,  // A: pri, tries, successful
1012         11,
1013         0,
1014         1,                           // B: pri, tries, successful
1015         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1016 
1017   SetMD(15,
1018         0,
1019         1,
1020         SV_INV,
1021         0,
1022         0,  // A: pri, tries, success, slot_validity, RIs
1023         14,
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(), 1));
1032   ExpMD(15,
1033         0,
1034         1,  // A: pri, tries, successful
1035         0,
1036         0,
1037         0,                           // B: pri, tries, successful
1038         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1039 }
1040 
TEST_F(AvbABFlowTest,MarkSlotSuccessful)1041 TEST_F(AvbABFlowTest, MarkSlotSuccessful) {
1042   SetMD(15,
1043         5,
1044         0,
1045         SV_INV,
1046         0,
1047         0,  // A: pri, tries, success, slot_validity, RIs
1048         11,
1049         3,
1050         0,
1051         SV_OK,
1052         0,
1053         0,  // B: pri, tries, success, slot_validity, RIs
1054         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1055   EXPECT_EQ(AVB_IO_RESULT_OK,
1056             avb_ab_mark_slot_successful(ops_.avb_ab_ops(), 0));
1057   ExpMD(15,
1058         0,
1059         1,  // A: pri, tries, successful
1060         11,
1061         3,
1062         0,                           // B: pri, tries, successful
1063         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1064 
1065   SetMD(15,
1066         5,
1067         0,
1068         SV_INV,
1069         0,
1070         0,  // A: pri, tries, success, slot_validity, RIs
1071         14,
1072         0,
1073         1,
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(), 1));
1080   ExpMD(15,
1081         5,
1082         0,  // A: pri, tries, successful
1083         14,
1084         0,
1085         1,                           // B: pri, tries, successful
1086         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1087 
1088   // Marking an unbootable slot (A) as successful won't work (it's a
1089   // programmer error to do so)... notice however that the unbootable
1090   // slot is normalized in the process.
1091   SetMD(0,
1092         3,
1093         2,
1094         SV_INV,
1095         0,
1096         0,  // A: pri, tries, success, slot_validity, RIs
1097         14,
1098         0,
1099         1,
1100         SV_OK,
1101         0,
1102         0,  // B: pri, tries, success, slot_validity, RIs
1103         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1104   EXPECT_EQ(AVB_IO_RESULT_OK,
1105             avb_ab_mark_slot_successful(ops_.avb_ab_ops(), 0));
1106   ExpMD(0,
1107         0,
1108         0,  // A: pri, tries, successful
1109         14,
1110         0,
1111         1,                           // B: pri, tries, successful
1112         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1113 }
1114 
1115 static AvbABData my_serialized_data;
1116 
my_write_ab_metadata(AvbABOps * ops,const struct AvbABData * data)1117 static AvbIOResult my_write_ab_metadata(AvbABOps* ops,
1118                                         const struct AvbABData* data) {
1119   avb_ab_data_update_crc_and_byteswap(data, &my_serialized_data);
1120   return AVB_IO_RESULT_OK;
1121 }
1122 
my_read_ab_metadata(AvbABOps * ops,struct AvbABData * data)1123 static AvbIOResult my_read_ab_metadata(AvbABOps* ops, struct AvbABData* data) {
1124   if (!avb_ab_data_verify_and_byteswap(&my_serialized_data, data)) {
1125     avb_error(
1126         "Error validating A/B metadata from persistent storage. "
1127         "Resetting and writing new A/B metadata to persistent storage.\n");
1128     avb_ab_data_init(data);
1129     return my_write_ab_metadata(ops, data);
1130   }
1131   return AVB_IO_RESULT_OK;
1132 }
1133 
TEST_F(AvbABFlowTest,OtherMetadataStorage)1134 TEST_F(AvbABFlowTest, OtherMetadataStorage) {
1135   AvbSlotVerifyData* data;
1136   const char* requested_partitions[] = {"boot", NULL};
1137 
1138   // Use our own A/B storage routines (see above).
1139   ops_.avb_ab_ops()->read_ab_metadata = my_read_ab_metadata;
1140   ops_.avb_ab_ops()->write_ab_metadata = my_write_ab_metadata;
1141 
1142   SetMD(14,
1143         0,
1144         1,
1145         SV_OK,
1146         0,
1147         0,  // A: pri, tries, success, slot_validity, RIs
1148         15,
1149         0,
1150         1,
1151         SV_OK,
1152         0,
1153         0,  // B: pri, tries, success, slot_validity, RIs
1154         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1155   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
1156             avb_ab_flow(ops_.avb_ab_ops(),
1157                         requested_partitions,
1158                         false /* allow_verification_error */,
1159                         &data));
1160   ExpMD(14,
1161         0,
1162         1,  // A: pri, tries, successful
1163         15,
1164         0,
1165         1,                           // B: pri, tries, successful
1166         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1167   ASSERT_NE(nullptr, data);
1168   EXPECT_EQ("_b", std::string(data->ab_suffix));
1169   avb_slot_verify_data_free(data);
1170 
1171   // Also check the other slot.
1172   SetMD(15,
1173         0,
1174         1,
1175         SV_OK,
1176         0,
1177         0,  // A: pri, tries, success, slot_validity, RIs
1178         14,
1179         0,
1180         1,
1181         SV_OK,
1182         0,
1183         0,  // B: pri, tries, success, slot_validity, RIs
1184         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1185   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK,
1186             avb_ab_flow(ops_.avb_ab_ops(),
1187                         requested_partitions,
1188                         false /* allow_verification_error */,
1189                         &data));
1190   ExpMD(15,
1191         0,
1192         1,  // A: pri, tries, successful
1193         14,
1194         0,
1195         1,                           // B: pri, tries, successful
1196         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1197   ASSERT_NE(nullptr, data);
1198   EXPECT_EQ("_a", std::string(data->ab_suffix));
1199   avb_slot_verify_data_free(data);
1200 
1201   // Check that 'misc' hasn't been written to at all.
1202   std::string misc_data;
1203   base::FilePath misc_path = testdir_.Append("misc.img");
1204   ASSERT_TRUE(base::ReadFileToString(misc_path, &misc_data));
1205   EXPECT_EQ(size_t(MISC_PART_SIZE), misc_data.size());
1206   for (size_t n = 0; n < misc_data.size(); n++) {
1207     ASSERT_EQ(uint8_t(misc_data[n]), 0);
1208   }
1209 }
1210 
TEST_F(AvbABFlowTest,UnlockedUnverifiedSlot)1211 TEST_F(AvbABFlowTest, UnlockedUnverifiedSlot) {
1212   AvbSlotVerifyData* data;
1213   const char* requested_partitions[] = {"boot", NULL};
1214 
1215   SetMD(14,
1216         0,
1217         1,
1218         SV_OK,
1219         0,
1220         0,  // A: pri, tries, success, slot_validity, RIs
1221         15,
1222         0,
1223         1,
1224         SV_UNV,
1225         0,
1226         0,  // B: pri, tries, success, slot_validity, RIs
1227         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1228   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
1229             avb_ab_flow(ops_.avb_ab_ops(),
1230                         requested_partitions,
1231                         true /* allow_verification_error */,
1232                         &data));
1233   ExpMD(14,
1234         0,
1235         1,  // A: pri, tries, successful
1236         15,
1237         0,
1238         1,                           // B: pri, tries, successful
1239         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1240   ASSERT_NE(nullptr, data);
1241   EXPECT_EQ("_b", std::string(data->ab_suffix));
1242   avb_slot_verify_data_free(data);
1243 
1244   // Also check the other slot.
1245   SetMD(15,
1246         0,
1247         1,
1248         SV_UNV,
1249         0,
1250         0,  // A: pri, tries, success, slot_validity, RIs
1251         14,
1252         0,
1253         1,
1254         SV_OK,
1255         0,
1256         0,  // B: pri, tries, success, slot_validity, RIs
1257         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1258   EXPECT_EQ(AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR,
1259             avb_ab_flow(ops_.avb_ab_ops(),
1260                         requested_partitions,
1261                         true /* allow_verification_error */,
1262                         &data));
1263   ExpMD(15,
1264         0,
1265         1,  // A: pri, tries, successful
1266         14,
1267         0,
1268         1,                           // B: pri, tries, successful
1269         MakeRollbackIndexes(0, 0));  // stored_rollback_indexes
1270   ASSERT_NE(nullptr, data);
1271   EXPECT_EQ("_a", std::string(data->ab_suffix));
1272   avb_slot_verify_data_free(data);
1273 }
1274 
TEST_F(AvbABFlowTest,AvbtoolMetadataGeneratorEmptyFile)1275 TEST_F(AvbABFlowTest, AvbtoolMetadataGeneratorEmptyFile) {
1276   AvbABData data;
1277 
1278   base::FilePath misc_path = testdir_.Append("misc.img");
1279   EXPECT_COMMAND(0,
1280                  "./avbtool set_ab_metadata"
1281                  " --misc_image %s"
1282                  " --slot_data 13:3:0:11:2:1",
1283                  misc_path.value().c_str());
1284 
1285   EXPECT_EQ(AVB_IO_RESULT_OK,
1286             ops_.avb_ab_ops()->read_ab_metadata(ops_.avb_ab_ops(), &data));
1287   EXPECT_EQ(13, data.slots[0].priority);
1288   EXPECT_EQ(3, data.slots[0].tries_remaining);
1289   EXPECT_EQ(0, data.slots[0].successful_boot);
1290   EXPECT_EQ(11, data.slots[1].priority);
1291   EXPECT_EQ(2, data.slots[1].tries_remaining);
1292   EXPECT_EQ(1, data.slots[1].successful_boot);
1293 }
1294 
TEST_F(AvbABFlowTest,AvbtoolMetadataGeneratorExistingFile)1295 TEST_F(AvbABFlowTest, AvbtoolMetadataGeneratorExistingFile) {
1296   AvbABData data;
1297   size_t n;
1298 
1299   size_t misc_size = 1024 * 1024;
1300   base::FilePath misc_path = GenerateImage("misc.img", misc_size);
1301   EXPECT_COMMAND(0,
1302                  "./avbtool set_ab_metadata"
1303                  " --misc_image %s"
1304                  " --slot_data 12:2:1:10:5:0",
1305                  misc_path.value().c_str());
1306 
1307   EXPECT_EQ(AVB_IO_RESULT_OK,
1308             ops_.avb_ab_ops()->read_ab_metadata(ops_.avb_ab_ops(), &data));
1309   EXPECT_EQ(12, data.slots[0].priority);
1310   EXPECT_EQ(2, data.slots[0].tries_remaining);
1311   EXPECT_EQ(1, data.slots[0].successful_boot);
1312   EXPECT_EQ(10, data.slots[1].priority);
1313   EXPECT_EQ(5, data.slots[1].tries_remaining);
1314   EXPECT_EQ(0, data.slots[1].successful_boot);
1315 
1316   std::string misc_data;
1317   ASSERT_TRUE(base::ReadFileToString(misc_path, &misc_data));
1318   EXPECT_EQ(misc_size, misc_data.size());
1319   for (n = 0; n < 2048; n++) {
1320     ASSERT_EQ(uint8_t(misc_data[n]), uint8_t(n));
1321   }
1322   for (n = 2048 + 32; n < misc_data.size(); n++) {
1323     ASSERT_EQ(uint8_t(misc_data[n]), uint8_t(n));
1324   }
1325 }
1326 
1327 }  // namespace avb
1328