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