xref: /aosp_15_r20/external/avb/test/avb_slot_verify_unittest.cc (revision d289c2ba6de359471b23d594623b906876bc48a0)
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include <android-base/file.h>
26 #include <android-base/stringprintf.h>
27 #include <base/files/file_util.h>
28 
29 #include <iostream>
30 
31 #include "avb_unittest_util.h"
32 #include "fake_avb_ops.h"
33 
34 namespace avb {
35 
36 class AvbSlotVerifyTest : public BaseAvbToolTest,
37                           public FakeAvbOpsDelegateWithDefaults {
38  public:
AvbSlotVerifyTest()39   AvbSlotVerifyTest() {}
40 
SetUp()41   virtual void SetUp() override {
42     BaseAvbToolTest::SetUp();
43     ops_.set_delegate(this);
44     ops_.set_partition_dir(testdir_);
45     ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}, {2, 0}, {3, 0}});
46     ops_.set_stored_is_device_unlocked(false);
47   }
48 
49   void CmdlineWithHashtreeVerification(bool hashtree_verification_on);
50   void CmdlineWithChainedHashtreeVerification(bool hashtree_verification_on);
51   void VerificationDisabled(bool use_avbctl,
52                             bool preload,
53                             bool has_system_partition);
54 };
55 
TEST_F(AvbSlotVerifyTest,Basic)56 TEST_F(AvbSlotVerifyTest, Basic) {
57   GenerateVBMetaImage("vbmeta_a.img",
58                       "SHA256_RSA2048",
59                       0,
60                       "test/data/testkey_rsa2048.pem",
61                       "--internal_release_string \"\"");
62 
63   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
64 
65   AvbSlotVerifyData* slot_data = NULL;
66   const char* requested_partitions[] = {"boot", NULL};
67   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
68             avb_slot_verify(ops_.avb_ops(),
69                             requested_partitions,
70                             "_a",
71                             AVB_SLOT_VERIFY_FLAGS_NONE,
72                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
73                             &slot_data));
74   EXPECT_NE(nullptr, slot_data);
75   EXPECT_EQ(
76       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
77       "androidboot.vbmeta.avb_version=1.3 "
78       "androidboot.vbmeta.device_state=locked "
79       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
80       "androidboot.vbmeta.digest="
81       "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
82       "androidboot.vbmeta.invalidate_on_error=yes "
83       "androidboot.veritymode=enforcing",
84       std::string(slot_data->cmdline));
85   uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
86   avb_slot_verify_data_calculate_vbmeta_digest(
87       slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
88   EXPECT_EQ("4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
89             mem_to_hexstring(vbmeta_digest, AVB_SHA256_DIGEST_SIZE));
90   avb_slot_verify_data_free(slot_data);
91 
92   EXPECT_EQ("4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
93             CalcVBMetaDigest("vbmeta_a.img", "sha256"));
94 }
95 
TEST_F(AvbSlotVerifyTest,BasicSha512)96 TEST_F(AvbSlotVerifyTest, BasicSha512) {
97   GenerateVBMetaImage("vbmeta_a.img",
98                       "SHA512_RSA2048",
99                       0,
100                       "test/data/testkey_rsa2048.pem",
101                       "--internal_release_string \"\"");
102 
103   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
104 
105   AvbSlotVerifyData* slot_data = NULL;
106   const char* requested_partitions[] = {"boot", NULL};
107   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
108             avb_slot_verify(ops_.avb_ops(),
109                             requested_partitions,
110                             "_a",
111                             AVB_SLOT_VERIFY_FLAGS_NONE,
112                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
113                             &slot_data));
114   EXPECT_NE(nullptr, slot_data);
115   EXPECT_EQ(
116       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
117       "androidboot.vbmeta.avb_version=1.3 "
118       "androidboot.vbmeta.device_state=locked "
119       "androidboot.vbmeta.hash_alg=sha512 androidboot.vbmeta.size=1152 "
120       "androidboot.vbmeta.digest="
121       "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
122       "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77 "
123       "androidboot.vbmeta.invalidate_on_error=yes "
124       "androidboot.veritymode=enforcing",
125       std::string(slot_data->cmdline));
126   uint8_t vbmeta_digest[AVB_SHA512_DIGEST_SIZE];
127   avb_slot_verify_data_calculate_vbmeta_digest(
128       slot_data, AVB_DIGEST_TYPE_SHA512, vbmeta_digest);
129   EXPECT_EQ(
130       "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
131       "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77",
132       mem_to_hexstring(vbmeta_digest, AVB_SHA512_DIGEST_SIZE));
133   avb_slot_verify_data_free(slot_data);
134 
135   EXPECT_EQ(
136       "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
137       "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77",
138       CalcVBMetaDigest("vbmeta_a.img", "sha512"));
139 }
140 
TEST_F(AvbSlotVerifyTest,BasicUnlocked)141 TEST_F(AvbSlotVerifyTest, BasicUnlocked) {
142   GenerateVBMetaImage("vbmeta_a.img",
143                       "SHA256_RSA2048",
144                       0,
145                       "test/data/testkey_rsa2048.pem",
146                       "--internal_release_string \"\"");
147 
148   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
149 
150   ops_.set_stored_is_device_unlocked(true);
151 
152   AvbSlotVerifyData* slot_data = NULL;
153   const char* requested_partitions[] = {"boot", NULL};
154   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
155             avb_slot_verify(ops_.avb_ops(),
156                             requested_partitions,
157                             "_a",
158                             AVB_SLOT_VERIFY_FLAGS_NONE,
159                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
160                             &slot_data));
161   EXPECT_NE(nullptr, slot_data);
162   EXPECT_EQ(
163       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
164       "androidboot.vbmeta.avb_version=1.3 "
165       "androidboot.vbmeta.device_state=unlocked "
166       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
167       "androidboot.vbmeta.digest="
168       "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
169       "androidboot.vbmeta.invalidate_on_error=yes "
170       "androidboot.veritymode=enforcing",
171       std::string(slot_data->cmdline));
172   avb_slot_verify_data_free(slot_data);
173 }
174 
TEST_F(AvbSlotVerifyTest,PreloadedEnabledButNotUsed)175 TEST_F(AvbSlotVerifyTest, PreloadedEnabledButNotUsed) {
176   GenerateVBMetaImage("vbmeta_a.img",
177                       "SHA256_RSA2048",
178                       0,
179                       "test/data/testkey_rsa2048.pem",
180                       "--internal_release_string \"\"");
181 
182   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
183   ops_.enable_get_preloaded_partition();
184 
185   AvbSlotVerifyData* slot_data = NULL;
186   const char* requested_partitions[] = {"boot", NULL};
187   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
188             avb_slot_verify(ops_.avb_ops(),
189                             requested_partitions,
190                             "_a",
191                             AVB_SLOT_VERIFY_FLAGS_NONE,
192                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
193                             &slot_data));
194   EXPECT_NE(nullptr, slot_data);
195   avb_slot_verify_data_free(slot_data);
196 }
197 
TEST_F(AvbSlotVerifyTest,SlotDataIsCorrect)198 TEST_F(AvbSlotVerifyTest, SlotDataIsCorrect) {
199   GenerateVBMetaImage("vbmeta_a.img",
200                       "SHA256_RSA2048",
201                       0,
202                       "test/data/testkey_rsa2048.pem",
203                       "--internal_release_string \"\"");
204 
205   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
206 
207   AvbSlotVerifyData* slot_data = NULL;
208   const char* requested_partitions[] = {"boot", NULL};
209   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
210             avb_slot_verify(ops_.avb_ops(),
211                             requested_partitions,
212                             "_a",
213                             AVB_SLOT_VERIFY_FLAGS_NONE,
214                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
215                             &slot_data));
216   EXPECT_NE(nullptr, slot_data);
217   avb_slot_verify_data_free(slot_data);
218 }
219 
TEST_F(AvbSlotVerifyTest,WrongPublicKey)220 TEST_F(AvbSlotVerifyTest, WrongPublicKey) {
221   GenerateVBMetaImage("vbmeta_a.img",
222                       "SHA256_RSA2048",
223                       0,
224                       "test/data/testkey_rsa2048.pem",
225                       "--internal_release_string \"\"");
226 
227   AvbSlotVerifyData* slot_data = NULL;
228   const char* requested_partitions[] = {"boot", NULL};
229   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
230             avb_slot_verify(ops_.avb_ops(),
231                             requested_partitions,
232                             "_a",
233                             AVB_SLOT_VERIFY_FLAGS_NONE,
234                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
235                             &slot_data));
236   EXPECT_EQ(nullptr, slot_data);
237   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
238             avb_slot_verify(ops_.avb_ops(),
239                             requested_partitions,
240                             "_a",
241                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
242                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
243                             &slot_data));
244   EXPECT_NE(nullptr, slot_data);
245   avb_slot_verify_data_free(slot_data);
246 }
247 
TEST_F(AvbSlotVerifyTest,NoImage)248 TEST_F(AvbSlotVerifyTest, NoImage) {
249   const char* requested_partitions[] = {"boot", NULL};
250   AvbSlotVerifyData* slot_data = NULL;
251   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
252             avb_slot_verify(ops_.avb_ops(),
253                             requested_partitions,
254                             "_a",
255                             AVB_SLOT_VERIFY_FLAGS_NONE,
256                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
257                             &slot_data));
258   EXPECT_EQ(nullptr, slot_data);
259 }
260 
TEST_F(AvbSlotVerifyTest,UnsignedVBMeta)261 TEST_F(AvbSlotVerifyTest, UnsignedVBMeta) {
262   GenerateVBMetaImage(
263       "vbmeta_a.img", "", 0, "", "--internal_release_string \"\"");
264 
265   AvbSlotVerifyData* slot_data = NULL;
266   const char* requested_partitions[] = {"boot", NULL};
267   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
268             avb_slot_verify(ops_.avb_ops(),
269                             requested_partitions,
270                             "_a",
271                             AVB_SLOT_VERIFY_FLAGS_NONE,
272                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
273                             &slot_data));
274   EXPECT_EQ(nullptr, slot_data);
275   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
276             avb_slot_verify(ops_.avb_ops(),
277                             requested_partitions,
278                             "_a",
279                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
280                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
281                             &slot_data));
282   EXPECT_NE(nullptr, slot_data);
283   avb_slot_verify_data_free(slot_data);
284 }
285 
TEST_F(AvbSlotVerifyTest,CorruptedImage)286 TEST_F(AvbSlotVerifyTest, CorruptedImage) {
287   GenerateVBMetaImage("vbmeta_a.img",
288                       "SHA256_RSA2048",
289                       0,
290                       "test/data/testkey_rsa2048.pem",
291                       "--internal_release_string \"\"");
292 
293   // Corrupt four bytes of data in the end of the image. Since the aux
294   // data is at the end and this data is signed, this will change the
295   // value of the computed hash.
296   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
297   EXPECT_EQ(AVB_IO_RESULT_OK,
298             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
299                                                "vbmeta_a",
300                                                -4,  // offset from end
301                                                sizeof corrupt_data,
302                                                corrupt_data));
303 
304   AvbSlotVerifyData* slot_data = NULL;
305   const char* requested_partitions[] = {"boot", NULL};
306   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
307             avb_slot_verify(ops_.avb_ops(),
308                             requested_partitions,
309                             "_a",
310                             AVB_SLOT_VERIFY_FLAGS_NONE,
311                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
312                             &slot_data));
313   EXPECT_EQ(nullptr, slot_data);
314   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
315             avb_slot_verify(ops_.avb_ops(),
316                             requested_partitions,
317                             "_a",
318                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
319                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
320                             &slot_data));
321   EXPECT_NE(nullptr, slot_data);
322   avb_slot_verify_data_free(slot_data);
323 }
324 
TEST_F(AvbSlotVerifyTest,CorruptedMetadata)325 TEST_F(AvbSlotVerifyTest, CorruptedMetadata) {
326   GenerateVBMetaImage("vbmeta_a.img",
327                       "SHA256_RSA2048",
328                       0,
329                       "test/data/testkey_rsa2048.pem",
330                       "--internal_release_string \"\"");
331 
332   // Corrupt four bytes of data in the beginning of the image. Unlike
333   // the CorruptedImage test-case above (which is valid metadata) this
334   // will make the metadata invalid and render the slot unbootable
335   // even if the device is unlocked. Specifically no AvbSlotVerifyData
336   // is returned.
337   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
338   EXPECT_EQ(AVB_IO_RESULT_OK,
339             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
340                                                "vbmeta_a",
341                                                0,  // offset: beginning
342                                                sizeof corrupt_data,
343                                                corrupt_data));
344 
345   AvbSlotVerifyData* slot_data = NULL;
346   const char* requested_partitions[] = {"boot", NULL};
347   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
348             avb_slot_verify(ops_.avb_ops(),
349                             requested_partitions,
350                             "_a",
351                             AVB_SLOT_VERIFY_FLAGS_NONE,
352                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
353                             &slot_data));
354   EXPECT_EQ(nullptr, slot_data);
355 }
356 
TEST_F(AvbSlotVerifyTest,RollbackIndex)357 TEST_F(AvbSlotVerifyTest, RollbackIndex) {
358   GenerateVBMetaImage("vbmeta_a.img",
359                       "SHA256_RSA2048",
360                       42,
361                       "test/data/testkey_rsa2048.pem",
362                       "--internal_release_string \"\"");
363 
364   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
365 
366   AvbSlotVerifyData* slot_data = NULL;
367   const char* requested_partitions[] = {"boot", NULL};
368 
369   // First try with 42 as the stored rollback index - this should
370   // succeed since the image rollback index is 42 (as set above).
371   ops_.set_stored_rollback_indexes({{0, 42}});
372   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
373             avb_slot_verify(ops_.avb_ops(),
374                             requested_partitions,
375                             "_a",
376                             AVB_SLOT_VERIFY_FLAGS_NONE,
377                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
378                             &slot_data));
379   EXPECT_NE(nullptr, slot_data);
380   avb_slot_verify_data_free(slot_data);
381 
382   // Then try with 43 for the stored rollback index - this should fail
383   // because the image has rollback index 42 which is less than 43.
384   ops_.set_stored_rollback_indexes({{0, 43}});
385   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
386             avb_slot_verify(ops_.avb_ops(),
387                             requested_partitions,
388                             "_a",
389                             AVB_SLOT_VERIFY_FLAGS_NONE,
390                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
391                             &slot_data));
392   EXPECT_EQ(nullptr, slot_data);
393   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
394             avb_slot_verify(ops_.avb_ops(),
395                             requested_partitions,
396                             "_a",
397                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
398                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
399                             &slot_data));
400   EXPECT_NE(nullptr, slot_data);
401   avb_slot_verify_data_free(slot_data);
402 }
403 
TEST_F(AvbSlotVerifyTest,RollbackIndexLocationSpecified)404 TEST_F(AvbSlotVerifyTest, RollbackIndexLocationSpecified) {
405   GenerateVBMetaImage("vbmeta_a.img",
406                       "SHA256_RSA2048",
407                       42,
408                       "test/data/testkey_rsa2048.pem",
409                       "--rollback_index_location 15");
410 
411   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
412 
413   AvbSlotVerifyData* slot_data = NULL;
414   const char* requested_partitions[] = {"boot", NULL};
415 
416   // First try with 42 as the stored rollback index - this should
417   // succeed since the image rollback index is 42 (as set above).
418   // The rollback index at location 0 should not be checked because
419   // the rollback index location is set to 15.
420   ops_.set_stored_rollback_indexes({{15, 42}});
421   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
422             avb_slot_verify(ops_.avb_ops(),
423                             requested_partitions,
424                             "_a",
425                             AVB_SLOT_VERIFY_FLAGS_NONE,
426                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
427                             &slot_data));
428   EXPECT_NE(nullptr, slot_data);
429 
430   for (size_t n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
431     uint64_t expected_rollback = 0;
432     if (n == 15) expected_rollback = 42;
433 
434     EXPECT_EQ(expected_rollback, slot_data->rollback_indexes[n]);
435   }
436 
437   avb_slot_verify_data_free(slot_data);
438 
439   // Then try with 43 for the stored rollback index - this should fail
440   // because the image has rollback index 42 which is less than 43.
441   ops_.set_stored_rollback_indexes({{0, 41}, {15, 43}});
442   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
443             avb_slot_verify(ops_.avb_ops(),
444                             requested_partitions,
445                             "_a",
446                             AVB_SLOT_VERIFY_FLAGS_NONE,
447                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
448                             &slot_data));
449   EXPECT_EQ(nullptr, slot_data);
450   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
451             avb_slot_verify(ops_.avb_ops(),
452                             requested_partitions,
453                             "_a",
454                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
455                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
456                             &slot_data));
457   EXPECT_NE(nullptr, slot_data);
458   avb_slot_verify_data_free(slot_data);
459 }
460 
TEST_F(AvbSlotVerifyTest,RollbackIndexLocationInvalid)461 TEST_F(AvbSlotVerifyTest, RollbackIndexLocationInvalid) {
462   uint32_t rollback_index_location = AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS;
463   GenerateVBMetaImage(
464       "vbmeta_a.img",
465       "SHA256_RSA2048",
466       42,
467       "test/data/testkey_rsa2048.pem",
468       android::base::StringPrintf("--rollback_index_location %d",
469                                   rollback_index_location));
470 
471   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
472 
473   AvbSlotVerifyData* slot_data = NULL;
474   const char* requested_partitions[] = {"boot", NULL};
475 
476   EXPECT_NE(AVB_SLOT_VERIFY_RESULT_OK,
477             avb_slot_verify(ops_.avb_ops(),
478                             requested_partitions,
479                             "_a",
480                             AVB_SLOT_VERIFY_FLAGS_NONE,
481                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
482                             &slot_data));
483   EXPECT_EQ(nullptr, slot_data);
484 }
485 
TEST_F(AvbSlotVerifyTest,LoadEntirePartitionIfAllowingVerificationError)486 TEST_F(AvbSlotVerifyTest, LoadEntirePartitionIfAllowingVerificationError) {
487   const size_t boot_partition_size = 16 * 1024 * 1024;
488   const size_t boot_image_size = 5 * 1024 * 1024;
489   const size_t new_boot_image_size = 10 * 1024 * 1024;
490   std::string boot_path = GenerateImage("boot_a.img", boot_image_size);
491 
492   // If we're allowing verification errors then check that the whole
493   // partition is loaded. This is needed because in this mode for
494   // example the "boot" partition might be flashed with another
495   // boot.img that is larger than what the HashDescriptor in vbmeta
496   // says.
497   EXPECT_COMMAND(
498       0,
499       "./avbtool.py add_hash_footer"
500       " --image %s"
501       " --rollback_index 0"
502       " --partition_name boot"
503       " --partition_size %zd"
504       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
505       " --salt deadbeef"
506       " --internal_release_string \"\"",
507       boot_path.c_str(),
508       boot_partition_size);
509 
510   GenerateVBMetaImage(
511       "vbmeta_a.img",
512       "SHA256_RSA2048",
513       4,
514       "test/data/testkey_rsa2048.pem",
515       android::base::StringPrintf(
516           "--include_descriptors_from_image %s"
517           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
518           " --internal_release_string \"\"",
519           boot_path.c_str()));
520 
521   // Now replace the boot partition with something bigger and
522   // different. Because FakeOps's get_size_of_partition() operation
523   // just returns the file size it means that this is what is returned
524   // by get_size_of_partition().
525   //
526   // Also make sure this image will return a different digest by using
527   // a non-standard starting byte. This is to force avb_slot_verify()
528   // to return ERROR_VERIFICATION below.
529   GenerateImage("boot_a.img", new_boot_image_size, 1 /* start_byte */);
530 
531   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
532 
533   AvbSlotVerifyData* slot_data = NULL;
534   const char* requested_partitions[] = {"boot", NULL};
535   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
536             avb_slot_verify(ops_.avb_ops(),
537                             requested_partitions,
538                             "_a",
539                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
540                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
541                             &slot_data));
542   EXPECT_NE(nullptr, slot_data);
543 
544   // Check that the loaded partition is actually
545   // |new_boot_image_size|.
546   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
547   EXPECT_EQ("boot",
548             std::string(slot_data->loaded_partitions[0].partition_name));
549   EXPECT_EQ(new_boot_image_size, slot_data->loaded_partitions[0].data_size);
550   avb_slot_verify_data_free(slot_data);
551 }
552 
TEST_F(AvbSlotVerifyTest,LoadSmallerPartitionIfAllowingVerificationError)553 TEST_F(AvbSlotVerifyTest, LoadSmallerPartitionIfAllowingVerificationError) {
554   const size_t boot_partition_size = 16 * 1024 * 1024;
555   const size_t boot_image_size = 5 * 1024 * 1024;
556   const size_t new_boot_image_size = 1 * 1024 * 1024;
557   std::string boot_path = GenerateImage("boot_a.img", boot_image_size);
558 
559   // If we're allowing verification errors then check that the whole
560   // partition is loaded. This is needed because in this mode for
561   // example the "boot" partition might be flashed with another
562   // boot.img that is larger than what the HashDescriptor in vbmeta
563   // says.
564   EXPECT_COMMAND(
565       0,
566       "./avbtool.py add_hash_footer"
567       " --image %s"
568       " --rollback_index 0"
569       " --partition_name boot"
570       " --partition_size %zd"
571       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
572       " --salt deadbeef"
573       " --internal_release_string \"\"",
574       boot_path.c_str(),
575       boot_partition_size);
576 
577   GenerateVBMetaImage(
578       "vbmeta_a.img",
579       "SHA256_RSA2048",
580       4,
581       "test/data/testkey_rsa2048.pem",
582       android::base::StringPrintf(
583           "--include_descriptors_from_image %s"
584           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
585           " --internal_release_string \"\"",
586           boot_path.c_str()));
587 
588   // Now replace the boot partition with something bigger and
589   // different. Because FakeOps's get_size_of_partition() operation
590   // just returns the file size it means that this is what is returned
591   // by get_size_of_partition().
592   //
593   // Also make sure this image will return a different digest by using
594   // a non-standard starting byte. This is to force avb_slot_verify()
595   // to return ERROR_VERIFICATION below.
596   GenerateImage("boot_a.img", new_boot_image_size, 1 /* start_byte */);
597 
598   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
599 
600   AvbSlotVerifyData* slot_data = NULL;
601   const char* requested_partitions[] = {"boot", NULL};
602   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
603             avb_slot_verify(ops_.avb_ops(),
604                             requested_partitions,
605                             "_a",
606                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
607                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
608                             &slot_data));
609   EXPECT_NE(nullptr, slot_data);
610 
611   // Check that the loaded partition is actually
612   // |new_boot_image_size|.
613   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
614   EXPECT_EQ("boot",
615             std::string(slot_data->loaded_partitions[0].partition_name));
616   EXPECT_EQ(new_boot_image_size, slot_data->loaded_partitions[0].data_size);
617   avb_slot_verify_data_free(slot_data);
618 }
619 
TEST_F(AvbSlotVerifyTest,HashDescriptorInVBMeta)620 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMeta) {
621   const size_t boot_partition_size = 16 * 1024 * 1024;
622   const size_t boot_image_size = 5 * 1024 * 1024;
623   std::string boot_path = GenerateImage("boot_a.img", boot_image_size);
624 
625   EXPECT_COMMAND(
626       0,
627       "./avbtool.py add_hash_footer"
628       " --image %s"
629       " --rollback_index 0"
630       " --partition_name boot"
631       " --partition_size %zd"
632       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
633       " --salt deadbeef"
634       " --internal_release_string \"\"",
635       boot_path.c_str(),
636       boot_partition_size);
637 
638   GenerateVBMetaImage(
639       "vbmeta_a.img",
640       "SHA256_RSA2048",
641       4,
642       "test/data/testkey_rsa2048.pem",
643       android::base::StringPrintf(
644           "--include_descriptors_from_image %s"
645           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
646           " --internal_release_string \"\"",
647           boot_path.c_str()));
648 
649   EXPECT_EQ(
650       "Minimum libavb version:   1.0\n"
651       "Header Block:             256 bytes\n"
652       "Authentication Block:     320 bytes\n"
653       "Auxiliary Block:          896 bytes\n"
654       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
655       "Algorithm:                SHA256_RSA2048\n"
656       "Rollback Index:           4\n"
657       "Flags:                    0\n"
658       "Rollback Index Location:  0\n"
659       "Release String:           ''\n"
660       "Descriptors:\n"
661       "    Kernel Cmdline descriptor:\n"
662       "      Flags:                 0\n"
663       "      Kernel Cmdline:        'cmdline in vbmeta "
664       "$(ANDROID_BOOT_PARTUUID)'\n"
665       "    Kernel Cmdline descriptor:\n"
666       "      Flags:                 0\n"
667       "      Kernel Cmdline:        'cmdline in hash footer "
668       "$(ANDROID_SYSTEM_PARTUUID)'\n"
669       "    Hash descriptor:\n"
670       "      Image Size:            5242880 bytes\n"
671       "      Hash Algorithm:        sha256\n"
672       "      Partition Name:        boot\n"
673       "      Salt:                  deadbeef\n"
674       "      Digest:                "
675       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
676       "      Flags:                 0\n",
677       InfoImage(vbmeta_image_path_.string()));
678 
679   EXPECT_COMMAND(0,
680                  "./avbtool.py erase_footer"
681                  " --image %s",
682                  boot_path.c_str());
683 
684   // With no footer, 'avbtool info_image' should fail (exit status 1).
685   EXPECT_COMMAND(1, "./avbtool.py info_image --image %s", boot_path.c_str());
686 
687   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
688 
689   AvbSlotVerifyData* slot_data = NULL;
690   const char* requested_partitions[] = {"boot", NULL};
691   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
692             avb_slot_verify(ops_.avb_ops(),
693                             requested_partitions,
694                             "_a",
695                             AVB_SLOT_VERIFY_FLAGS_NONE,
696                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
697                             &slot_data));
698   EXPECT_NE(nullptr, slot_data);
699 
700   // Now verify the slot data. The vbmeta data should match our
701   // vbmeta_image_ member.
702   EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
703   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
704   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
705   EXPECT_EQ(0,
706             memcmp(vbmeta_image_.data(),
707                    slot_data->vbmeta_images[0].vbmeta_data,
708                    slot_data->vbmeta_images[0].vbmeta_size));
709 
710   // The boot image data should match what is generated above with
711   // GenerateImage().
712   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
713   EXPECT_EQ("boot",
714             std::string(slot_data->loaded_partitions[0].partition_name));
715   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
716   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
717     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
718   }
719 
720   // This should match the two cmdlines with a space (U+0020) between
721   // them and the $(ANDROID_SYSTEM_PARTUUID) and
722   // $(ANDROID_BOOT_PARTUUID) variables replaced.
723   EXPECT_EQ(
724       "cmdline in vbmeta 1234-fake-guid-for:boot_a cmdline in hash footer "
725       "1234-fake-guid-for:system_a "
726       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
727       "androidboot.vbmeta.avb_version=1.3 "
728       "androidboot.vbmeta.device_state=locked "
729       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
730       "androidboot.vbmeta.digest="
731       "99e84e34697a77414f0d7dd7896e98ac4da2d26bdd3756ef59ec79918de2adbe "
732       "androidboot.vbmeta.invalidate_on_error=yes "
733       "androidboot.veritymode=enforcing",
734       std::string(slot_data->cmdline));
735   EXPECT_EQ(4UL, slot_data->rollback_indexes[0]);
736   for (size_t n = 1; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
737     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
738   }
739   avb_slot_verify_data_free(slot_data);
740 }
741 
TEST_F(AvbSlotVerifyTest,HashDescriptorInVBMetaWithPreloadedPartition)742 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMetaWithPreloadedPartition) {
743   const size_t boot_partition_size = 16 * 1024 * 1024;
744   const size_t boot_image_size = 5 * 1024 * 1024;
745   std::string boot_path = GenerateImage("boot_a.img", boot_image_size);
746 
747   EXPECT_COMMAND(
748       0,
749       "./avbtool.py add_hash_footer"
750       " --image %s"
751       " --rollback_index 0"
752       " --partition_name boot"
753       " --partition_size %zd"
754       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
755       " --salt deadbeef"
756       " --internal_release_string \"\"",
757       boot_path.c_str(),
758       boot_partition_size);
759 
760   GenerateVBMetaImage(
761       "vbmeta_a.img",
762       "SHA256_RSA2048",
763       4,
764       "test/data/testkey_rsa2048.pem",
765       android::base::StringPrintf(
766           "--include_descriptors_from_image %s"
767           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
768           " --internal_release_string \"\"",
769           boot_path.c_str()));
770 
771   EXPECT_COMMAND(0,
772                  "./avbtool.py erase_footer"
773                  " --image %s",
774                  boot_path.c_str());
775 
776   // With no footer, 'avbtool info_image' should fail (exit status 1).
777   EXPECT_COMMAND(1, "./avbtool.py info_image --image %s", boot_path.c_str());
778 
779   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
780   ops_.enable_get_preloaded_partition();
781   EXPECT_TRUE(ops_.preload_partition("boot_a", base::FilePath(boot_path)));
782 
783   AvbSlotVerifyData* slot_data = NULL;
784   const char* requested_partitions[] = {"boot", NULL};
785   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
786             avb_slot_verify(ops_.avb_ops(),
787                             requested_partitions,
788                             "_a",
789                             AVB_SLOT_VERIFY_FLAGS_NONE,
790                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
791                             &slot_data));
792   EXPECT_NE(nullptr, slot_data);
793 
794   // Now verify the slot data. The vbmeta data should match our
795   // vbmeta_image_ member.
796   EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
797   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
798   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
799   EXPECT_EQ(0,
800             memcmp(vbmeta_image_.data(),
801                    slot_data->vbmeta_images[0].vbmeta_data,
802                    slot_data->vbmeta_images[0].vbmeta_size));
803 
804   // The boot image data should match what is generated above with
805   // GenerateImage().
806   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
807   EXPECT_EQ("boot",
808             std::string(slot_data->loaded_partitions[0].partition_name));
809   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
810   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
811     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
812   }
813   EXPECT_TRUE(slot_data->loaded_partitions[0].preloaded);
814 
815   avb_slot_verify_data_free(slot_data);
816 }
817 
TEST_F(AvbSlotVerifyTest,SmallPreallocatedPreloadedPartitionFailGracefully)818 TEST_F(AvbSlotVerifyTest, SmallPreallocatedPreloadedPartitionFailGracefully) {
819   const size_t boot_partition_size = 16 * 1024 * 1024;
820   const size_t boot_image_size = 5 * 1024 * 1024;
821   // Generate vbmeta based on this boot image.
822   std::string boot_path = GenerateImage("boot_a.img", boot_image_size);
823 
824   // Preload smaller image than expected on the stack
825   // libavb should not attempt to free this buffer.
826   const size_t fake_preload_image_size = 1024;
827   uint8_t fake_preload_buf[fake_preload_image_size];
828 
829   EXPECT_COMMAND(
830       0,
831       "./avbtool.py add_hash_footer"
832       " --image %s"
833       " --rollback_index 0"
834       " --partition_name boot"
835       " --partition_size %zd"
836       " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
837       " --salt deadbeef"
838       " --internal_release_string \"\"",
839       boot_path.c_str(),
840       boot_partition_size);
841 
842   GenerateVBMetaImage(
843       "vbmeta_a.img",
844       "SHA256_RSA2048",
845       4,
846       "test/data/testkey_rsa2048.pem",
847       android::base::StringPrintf(
848           "--include_descriptors_from_image %s"
849           " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
850           " --internal_release_string \"\"",
851           boot_path.c_str()));
852 
853   EXPECT_COMMAND(0,
854                  "./avbtool.py erase_footer"
855                  " --image %s",
856                  boot_path.c_str());
857 
858   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
859   ops_.enable_get_preloaded_partition();
860   EXPECT_TRUE(ops_.preload_preallocated_partition(
861       "boot_a", fake_preload_buf, fake_preload_image_size));
862 
863   AvbSlotVerifyData* slot_data = NULL;
864   const char* requested_partitions[] = {"boot", NULL};
865   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
866             avb_slot_verify(ops_.avb_ops(),
867                             requested_partitions,
868                             "_a",
869                             AVB_SLOT_VERIFY_FLAGS_NONE,
870                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
871                             &slot_data));
872   EXPECT_EQ(nullptr, slot_data);
873 }
874 
TEST_F(AvbSlotVerifyTest,HashDescriptorInVBMetaCorruptBoot)875 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMetaCorruptBoot) {
876   size_t boot_partition_size = 16 * 1024 * 1024;
877   std::string boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
878   const char* requested_partitions[] = {"boot", NULL};
879 
880   EXPECT_COMMAND(0,
881                  "./avbtool.py add_hash_footer"
882                  " --image %s"
883                  " --rollback_index 0"
884                  " --partition_name boot"
885                  " --partition_size %zd"
886                  " --salt deadbeef"
887                  " --internal_release_string \"\"",
888                  boot_path.c_str(),
889                  boot_partition_size);
890 
891   GenerateVBMetaImage(
892       "vbmeta_a.img",
893       "SHA256_RSA2048",
894       0,
895       "test/data/testkey_rsa2048.pem",
896       android::base::StringPrintf("--include_descriptors_from_image %s"
897                                   " --internal_release_string \"\"",
898                                   boot_path.c_str()));
899 
900   EXPECT_COMMAND(0,
901                  "./avbtool.py erase_footer"
902                  " --image %s",
903                  boot_path.c_str());
904 
905   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
906 
907   // So far, so good.
908   AvbSlotVerifyData* slot_data = NULL;
909   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
910             avb_slot_verify(ops_.avb_ops(),
911                             requested_partitions,
912                             "_a",
913                             AVB_SLOT_VERIFY_FLAGS_NONE,
914                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
915                             &slot_data));
916   EXPECT_NE(nullptr, slot_data);
917   avb_slot_verify_data_free(slot_data);
918 
919   // Now corrupt boot_a.img and expect verification error.
920   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
921   EXPECT_EQ(AVB_IO_RESULT_OK,
922             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
923                                                "boot_a",
924                                                1024 * 1024,  // offset: 1 MiB
925                                                sizeof corrupt_data,
926                                                corrupt_data));
927 
928   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
929             avb_slot_verify(ops_.avb_ops(),
930                             requested_partitions,
931                             "_a",
932                             AVB_SLOT_VERIFY_FLAGS_NONE,
933                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
934                             &slot_data));
935   EXPECT_EQ(nullptr, slot_data);
936   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
937             avb_slot_verify(ops_.avb_ops(),
938                             requested_partitions,
939                             "_a",
940                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
941                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
942                             &slot_data));
943   EXPECT_NE(nullptr, slot_data);
944   avb_slot_verify_data_free(slot_data);
945 }
946 
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartition)947 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartition) {
948   size_t boot_partition_size = 16 * 1024 * 1024;
949   const size_t boot_image_size = 5 * 1024 * 1024;
950   std::string boot_path = GenerateImage("boot.img", boot_image_size);
951   const char* requested_partitions[] = {"boot", NULL};
952 
953   EXPECT_COMMAND(0,
954                  "./avbtool.py add_hash_footer"
955                  " --image %s"
956                  " --kernel_cmdline 'cmdline2 in hash footer'"
957                  " --rollback_index 12"
958                  " --partition_name boot"
959                  " --partition_size %zd"
960                  " --algorithm SHA256_RSA4096"
961                  " --key test/data/testkey_rsa4096.pem"
962                  " --salt deadbeef"
963                  " --internal_release_string \"\"",
964                  boot_path.c_str(),
965                  boot_partition_size);
966 
967   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
968   EXPECT_COMMAND(
969       0,
970       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
971       " --output %s",
972       pk_path.c_str());
973 
974   GenerateVBMetaImage(
975       "vbmeta.img",
976       "SHA256_RSA2048",
977       11,
978       "test/data/testkey_rsa2048.pem",
979       android::base::StringPrintf("--chain_partition boot:1:%s"
980                                   " --kernel_cmdline 'cmdline2 in vbmeta'"
981                                   " --internal_release_string \"\"",
982                                   pk_path.c_str()));
983 
984   EXPECT_EQ(
985       "Minimum libavb version:   1.0\n"
986       "Header Block:             256 bytes\n"
987       "Authentication Block:     320 bytes\n"
988       "Auxiliary Block:          1728 bytes\n"
989       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
990       "Algorithm:                SHA256_RSA2048\n"
991       "Rollback Index:           11\n"
992       "Flags:                    0\n"
993       "Rollback Index Location:  0\n"
994       "Release String:           ''\n"
995       "Descriptors:\n"
996       "    Chain Partition descriptor:\n"
997       "      Partition Name:          boot\n"
998       "      Rollback Index Location: 1\n"
999       "      Public key (sha1):       "
1000       "2597c218aae470a130f61162feaae70afd97f011\n"
1001       "      Flags:                   0\n"
1002       "    Kernel Cmdline descriptor:\n"
1003       "      Flags:                 0\n"
1004       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
1005       InfoImage(vbmeta_image_path_.string()));
1006 
1007   EXPECT_EQ(
1008       "Footer version:           1.0\n"
1009       "Image size:               16777216 bytes\n"
1010       "Original image size:      5242880 bytes\n"
1011       "VBMeta offset:            5242880\n"
1012       "VBMeta size:              2112 bytes\n"
1013       "--\n"
1014       "Minimum libavb version:   1.0\n"
1015       "Header Block:             256 bytes\n"
1016       "Authentication Block:     576 bytes\n"
1017       "Auxiliary Block:          1280 bytes\n"
1018       "Public key (sha1):        2597c218aae470a130f61162feaae70afd97f011\n"
1019       "Algorithm:                SHA256_RSA4096\n"
1020       "Rollback Index:           12\n"
1021       "Flags:                    0\n"
1022       "Rollback Index Location:  0\n"
1023       "Release String:           ''\n"
1024       "Descriptors:\n"
1025       "    Hash descriptor:\n"
1026       "      Image Size:            5242880 bytes\n"
1027       "      Hash Algorithm:        sha256\n"
1028       "      Partition Name:        boot\n"
1029       "      Salt:                  deadbeef\n"
1030       "      Digest:                "
1031       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
1032       "      Flags:                 0\n"
1033       "    Kernel Cmdline descriptor:\n"
1034       "      Flags:                 0\n"
1035       "      Kernel Cmdline:        'cmdline2 in hash footer'\n",
1036       InfoImage(boot_path));
1037 
1038   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
1039 
1040   AvbSlotVerifyData* slot_data = NULL;
1041   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1042             avb_slot_verify(ops_.avb_ops(),
1043                             requested_partitions,
1044                             "",
1045                             AVB_SLOT_VERIFY_FLAGS_NONE,
1046                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1047                             &slot_data));
1048   EXPECT_NE(nullptr, slot_data);
1049 
1050   // Now verify the slot data. We should have two vbmeta
1051   // structs. Verify both of them. Note that the A/B suffix isn't
1052   // appended.
1053   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
1054   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
1055   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
1056   EXPECT_EQ(0,
1057             memcmp(vbmeta_image_.data(),
1058                    slot_data->vbmeta_images[0].vbmeta_data,
1059                    slot_data->vbmeta_images[0].vbmeta_size));
1060   // And for the second vbmeta struct we check that the descriptors
1061   // match the info_image output from above.
1062   EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
1063   const AvbDescriptor** descriptors =
1064       avb_descriptor_get_all(slot_data->vbmeta_images[1].vbmeta_data,
1065                              slot_data->vbmeta_images[1].vbmeta_size,
1066                              NULL);
1067   EXPECT_NE(nullptr, descriptors);
1068   AvbHashDescriptor hash_desc;
1069   EXPECT_EQ(true,
1070             avb_hash_descriptor_validate_and_byteswap(
1071                 ((AvbHashDescriptor*)descriptors[0]), &hash_desc));
1072   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
1073                             sizeof(AvbHashDescriptor);
1074   uint64_t o = 0;
1075   EXPECT_EQ("boot",
1076             std::string(reinterpret_cast<const char*>(desc_end + o),
1077                         hash_desc.partition_name_len));
1078   o += hash_desc.partition_name_len;
1079   EXPECT_EQ("deadbeef", mem_to_hexstring(desc_end + o, hash_desc.salt_len));
1080   o += hash_desc.salt_len;
1081   EXPECT_EQ("184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d",
1082             mem_to_hexstring(desc_end + o, hash_desc.digest_len));
1083   AvbKernelCmdlineDescriptor cmdline_desc;
1084   EXPECT_EQ(true,
1085             avb_kernel_cmdline_descriptor_validate_and_byteswap(
1086                 ((AvbKernelCmdlineDescriptor*)descriptors[1]), &cmdline_desc));
1087   desc_end = reinterpret_cast<const uint8_t*>(descriptors[1]) +
1088              sizeof(AvbKernelCmdlineDescriptor);
1089   EXPECT_EQ("cmdline2 in hash footer",
1090             std::string(reinterpret_cast<const char*>(desc_end),
1091                         cmdline_desc.kernel_cmdline_length));
1092   avb_free(descriptors);
1093 
1094   // The boot image data should match what is generated above with
1095   // GenerateImage().
1096   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
1097   EXPECT_EQ("boot",
1098             std::string(slot_data->loaded_partitions[0].partition_name));
1099   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
1100   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
1101     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
1102   }
1103 
1104   // This should match the two cmdlines with a space (U+0020) between them.
1105   EXPECT_EQ(
1106       "cmdline2 in hash footer cmdline2 in vbmeta "
1107       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
1108       "androidboot.vbmeta.avb_version=1.3 "
1109       "androidboot.vbmeta.device_state=locked "
1110       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
1111       "androidboot.vbmeta.digest="
1112       "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4 "
1113       "androidboot.vbmeta.invalidate_on_error=yes "
1114       "androidboot.veritymode=enforcing",
1115       std::string(slot_data->cmdline));
1116   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
1117   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
1118   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
1119     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
1120   }
1121   uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
1122   avb_slot_verify_data_calculate_vbmeta_digest(
1123       slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
1124   EXPECT_EQ("4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
1125             mem_to_hexstring(vbmeta_digest, AVB_SHA256_DIGEST_SIZE));
1126   avb_slot_verify_data_free(slot_data);
1127 
1128   EXPECT_EQ("4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
1129             CalcVBMetaDigest("vbmeta.img", "sha256"));
1130 }
1131 
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionNoAB)1132 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionNoAB) {
1133   size_t boot_partition_size = 16 * 1024 * 1024;
1134   const size_t boot_image_size = 5 * 1024 * 1024;
1135   std::string boot_path = GenerateImage("boot.img", boot_image_size);
1136   EXPECT_COMMAND(
1137       0,
1138       "./avbtool.py add_hash_footer"
1139       " --image %s"
1140       " --rollback_index 12"
1141       " --partition_name boot"
1142       " --partition_size %zd"
1143       " --algorithm SHA256_RSA4096"
1144       " --key test/data/testkey_rsa4096.pem"
1145       " --salt d70fd60d0f7d9c3b4587b9782c0dd2012ba01bfb3598a47ca8dce88d6afb9415"
1146       " --internal_release_string \"\""
1147       " --do_not_use_ab",
1148       boot_path.c_str(),
1149       boot_partition_size);
1150 
1151   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
1152   EXPECT_COMMAND(
1153       0,
1154       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
1155       " --output %s",
1156       pk_path.c_str());
1157 
1158   GenerateVBMetaImage(
1159       "vbmeta_a.img",
1160       "SHA256_RSA2048",
1161       11,
1162       "test/data/testkey_rsa2048.pem",
1163       android::base::StringPrintf("--chain_partition_do_not_use_ab boot:1:%s"
1164                                   " --internal_release_string \"\"",
1165                                   pk_path.c_str()));
1166 
1167   EXPECT_EQ(
1168       "Minimum libavb version:   1.3\n"
1169       "Header Block:             256 bytes\n"
1170       "Authentication Block:     320 bytes\n"
1171       "Auxiliary Block:          1664 bytes\n"
1172       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1173       "Algorithm:                SHA256_RSA2048\n"
1174       "Rollback Index:           11\n"
1175       "Flags:                    0\n"
1176       "Rollback Index Location:  0\n"
1177       "Release String:           ''\n"
1178       "Descriptors:\n"
1179       "    Chain Partition descriptor:\n"
1180       "      Partition Name:          boot\n"
1181       "      Rollback Index Location: 1\n"
1182       "      Public key (sha1):       "
1183       "2597c218aae470a130f61162feaae70afd97f011\n"
1184       "      Flags:                   1\n",
1185       InfoImage(vbmeta_image_path_.string()));
1186 
1187   EXPECT_EQ(
1188       "Footer version:           1.0\n"
1189       "Image size:               16777216 bytes\n"
1190       "Original image size:      5242880 bytes\n"
1191       "VBMeta offset:            5242880\n"
1192       "VBMeta size:              2112 bytes\n"
1193       "--\n"
1194       "Minimum libavb version:   1.1\n"
1195       "Header Block:             256 bytes\n"
1196       "Authentication Block:     576 bytes\n"
1197       "Auxiliary Block:          1280 bytes\n"
1198       "Public key (sha1):        2597c218aae470a130f61162feaae70afd97f011\n"
1199       "Algorithm:                SHA256_RSA4096\n"
1200       "Rollback Index:           12\n"
1201       "Flags:                    0\n"
1202       "Rollback Index Location:  0\n"
1203       "Release String:           ''\n"
1204       "Descriptors:\n"
1205       "    Hash descriptor:\n"
1206       "      Image Size:            5242880 bytes\n"
1207       "      Hash Algorithm:        sha256\n"
1208       "      Partition Name:        boot\n"
1209       "      Salt:                  "
1210       "d70fd60d0f7d9c3b4587b9782c0dd2012ba01bfb3598a47ca8dce88d6afb9415\n"
1211       "      Digest:                "
1212       "e54d3d497d1cb01bd9b0a2ebda4a305b12b4f5ba084c9cc588690d33ae1e9940\n"
1213       "      Flags:                 1\n",
1214       InfoImage(boot_path));
1215 
1216   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
1217 
1218   AvbSlotVerifyData* slot_data = NULL;
1219   const char* requested_partitions[] = {"boot", NULL};
1220   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1221             avb_slot_verify(ops_.avb_ops(),
1222                             requested_partitions,
1223                             "_a",
1224                             AVB_SLOT_VERIFY_FLAGS_NONE,
1225                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1226                             &slot_data));
1227   EXPECT_NE(nullptr, slot_data);
1228 
1229   // Now verify the slot data. The vbmeta data should match our
1230   // vbmeta_image_ member.
1231   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
1232   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
1233   EXPECT_EQ(0,
1234             memcmp(vbmeta_image_.data(),
1235                    slot_data->vbmeta_images[0].vbmeta_data,
1236                    slot_data->vbmeta_images[0].vbmeta_size));
1237 
1238   // And for the second vbmeta struct we check that the descriptors
1239   // match the info_image output from above.
1240   EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
1241   const AvbDescriptor** descriptors =
1242       avb_descriptor_get_all(slot_data->vbmeta_images[1].vbmeta_data,
1243                              slot_data->vbmeta_images[1].vbmeta_size,
1244                              NULL);
1245   EXPECT_NE(nullptr, descriptors);
1246   AvbHashDescriptor hash_desc;
1247   EXPECT_EQ(true,
1248             avb_hash_descriptor_validate_and_byteswap(
1249                 ((AvbHashDescriptor*)descriptors[0]), &hash_desc));
1250   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
1251                             sizeof(AvbHashDescriptor);
1252   uint64_t o = 0;
1253   EXPECT_EQ("boot",
1254             std::string(reinterpret_cast<const char*>(desc_end + o),
1255                         hash_desc.partition_name_len));
1256   o += hash_desc.partition_name_len;
1257   EXPECT_EQ("d70fd60d0f7d9c3b4587b9782c0dd2012ba01bfb3598a47ca8dce88d6afb9415",
1258             mem_to_hexstring(desc_end + o, hash_desc.salt_len));
1259   o += hash_desc.salt_len;
1260   EXPECT_EQ("e54d3d497d1cb01bd9b0a2ebda4a305b12b4f5ba084c9cc588690d33ae1e9940",
1261             mem_to_hexstring(desc_end + o, hash_desc.digest_len));
1262   avb_free(descriptors);
1263 
1264   // The boot image data should match what is generated above with
1265   // GenerateImage().
1266   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
1267   EXPECT_EQ("boot",
1268             std::string(slot_data->loaded_partitions[0].partition_name));
1269   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
1270   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
1271     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
1272   }
1273 
1274   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
1275   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
1276   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
1277     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
1278   }
1279 
1280   uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
1281   avb_slot_verify_data_calculate_vbmeta_digest(
1282       slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
1283   EXPECT_EQ("40adb9e4d7a21cbba5c48ce540c370405e83af3355588aa108db5347b8459d71",
1284             mem_to_hexstring(vbmeta_digest, AVB_SHA256_DIGEST_SIZE));
1285 
1286   EXPECT_EQ("40adb9e4d7a21cbba5c48ce540c370405e83af3355588aa108db5347b8459d71",
1287             CalcVBMetaDigest("vbmeta_a.img", "sha256"));
1288 
1289   avb_slot_verify_data_free(slot_data);
1290 }
1291 
TEST_F(AvbSlotVerifyTest,RollbackIndexLocationInChainedPartition)1292 TEST_F(AvbSlotVerifyTest, RollbackIndexLocationInChainedPartition) {
1293   size_t boot_partition_size = 16 * 1024 * 1024;
1294   const size_t boot_image_size = 5 * 1024 * 1024;
1295   std::string boot_path = GenerateImage("boot.img", boot_image_size);
1296   const char* requested_partitions[] = {"boot", NULL};
1297 
1298   EXPECT_COMMAND(0,
1299                  "./avbtool.py add_hash_footer"
1300                  " --image %s"
1301                  " --kernel_cmdline 'cmdline2 in hash footer'"
1302                  " --rollback_index 12"
1303                  " --rollback_index_location 3"
1304                  " --partition_name boot"
1305                  " --partition_size %zd"
1306                  " --algorithm SHA256_RSA4096"
1307                  " --key test/data/testkey_rsa4096.pem"
1308                  " --salt deadbeef"
1309                  " --internal_release_string \"\"",
1310                  boot_path.c_str(),
1311                  boot_partition_size);
1312 
1313   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
1314   EXPECT_COMMAND(
1315       0,
1316       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
1317       " --output %s",
1318       pk_path.c_str());
1319 
1320   GenerateVBMetaImage(
1321       "vbmeta.img",
1322       "SHA256_RSA2048",
1323       11,
1324       "test/data/testkey_rsa2048.pem",
1325       android::base::StringPrintf("--chain_partition boot:2:%s"
1326                                   " --kernel_cmdline 'cmdline2 in vbmeta'"
1327                                   " --rollback_index_location 1"
1328                                   " --internal_release_string \"\"",
1329                                   pk_path.c_str()));
1330 
1331   EXPECT_EQ(
1332       "Minimum libavb version:   1.2\n"
1333       "Header Block:             256 bytes\n"
1334       "Authentication Block:     320 bytes\n"
1335       "Auxiliary Block:          1728 bytes\n"
1336       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1337       "Algorithm:                SHA256_RSA2048\n"
1338       "Rollback Index:           11\n"
1339       "Flags:                    0\n"
1340       "Rollback Index Location:  1\n"
1341       "Release String:           ''\n"
1342       "Descriptors:\n"
1343       "    Chain Partition descriptor:\n"
1344       "      Partition Name:          boot\n"
1345       "      Rollback Index Location: 2\n"
1346       "      Public key (sha1):       "
1347       "2597c218aae470a130f61162feaae70afd97f011\n"
1348       "      Flags:                   0\n"
1349       "    Kernel Cmdline descriptor:\n"
1350       "      Flags:                 0\n"
1351       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
1352       InfoImage(vbmeta_image_path_.string()));
1353 
1354   EXPECT_EQ(
1355       "Footer version:           1.0\n"
1356       "Image size:               16777216 bytes\n"
1357       "Original image size:      5242880 bytes\n"
1358       "VBMeta offset:            5242880\n"
1359       "VBMeta size:              2112 bytes\n"
1360       "--\n"
1361       "Minimum libavb version:   1.2\n"
1362       "Header Block:             256 bytes\n"
1363       "Authentication Block:     576 bytes\n"
1364       "Auxiliary Block:          1280 bytes\n"
1365       "Public key (sha1):        2597c218aae470a130f61162feaae70afd97f011\n"
1366       "Algorithm:                SHA256_RSA4096\n"
1367       "Rollback Index:           12\n"
1368       "Flags:                    0\n"
1369       "Rollback Index Location:  3\n"
1370       "Release String:           ''\n"
1371       "Descriptors:\n"
1372       "    Hash descriptor:\n"
1373       "      Image Size:            5242880 bytes\n"
1374       "      Hash Algorithm:        sha256\n"
1375       "      Partition Name:        boot\n"
1376       "      Salt:                  deadbeef\n"
1377       "      Digest:                "
1378       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
1379       "      Flags:                 0\n"
1380       "    Kernel Cmdline descriptor:\n"
1381       "      Flags:                 0\n"
1382       "      Kernel Cmdline:        'cmdline2 in hash footer'\n",
1383       InfoImage(boot_path));
1384 
1385   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
1386 
1387   // Verify that the rollback index location in the chained partition is ignored
1388   ops_.set_stored_rollback_indexes({{1, 11}, {2, 12}, {3, 20}});
1389 
1390   AvbSlotVerifyData* slot_data = NULL;
1391   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1392             avb_slot_verify(ops_.avb_ops(),
1393                             requested_partitions,
1394                             "",
1395                             AVB_SLOT_VERIFY_FLAGS_NONE,
1396                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1397                             &slot_data));
1398   EXPECT_NE(nullptr, slot_data);
1399 
1400   EXPECT_EQ(0UL, slot_data->rollback_indexes[0]);
1401   EXPECT_EQ(11UL, slot_data->rollback_indexes[1]);
1402   EXPECT_EQ(12UL, slot_data->rollback_indexes[2]);
1403   for (size_t n = 3; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
1404     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
1405   }
1406   avb_slot_verify_data_free(slot_data);
1407 }
1408 
TEST_F(AvbSlotVerifyTest,HashDescriptorInOtherVBMetaPartition)1409 TEST_F(AvbSlotVerifyTest, HashDescriptorInOtherVBMetaPartition) {
1410   size_t boot_partition_size = 16 * 1024 * 1024;
1411   const size_t boot_image_size = 5 * 1024 * 1024;
1412   std::string boot_path = GenerateImage("boot.img", boot_image_size);
1413   std::filesystem::path other_vbmeta_path = testdir_ / "vbmeta_google.img";
1414   const char* requested_partitions[] = {"boot", NULL};
1415 
1416   EXPECT_COMMAND(0,
1417                  "./avbtool.py add_hash_footer"
1418                  " --image %s"
1419                  " --kernel_cmdline 'cmdline2 in hash footer'"
1420                  " --rollback_index 12"
1421                  " --partition_name boot"
1422                  " --partition_size %zd"
1423                  " --algorithm SHA256_RSA4096"
1424                  " --key test/data/testkey_rsa4096.pem"
1425                  " --salt deadbeef"
1426                  " --internal_release_string \"\"",
1427                  boot_path.c_str(),
1428                  boot_partition_size);
1429 
1430   // Extract the vbmeta blob from the footer in boot.img, put it into
1431   // vbmeta_google.img, and erase the footer from boot.img
1432   EXPECT_COMMAND(0,
1433                  "./avbtool.py extract_vbmeta_image"
1434                  " --image %s"
1435                  " --output %s",
1436                  boot_path.c_str(),
1437                  other_vbmeta_path.c_str());
1438   EXPECT_COMMAND(0,
1439                  "./avbtool.py erase_footer"
1440                  " --image %s",
1441                  boot_path.c_str());
1442 
1443   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
1444   EXPECT_COMMAND(
1445       0,
1446       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
1447       " --output %s",
1448       pk_path.c_str());
1449 
1450   GenerateVBMetaImage(
1451       "vbmeta.img",
1452       "SHA256_RSA2048",
1453       11,
1454       "test/data/testkey_rsa2048.pem",
1455       android::base::StringPrintf("--chain_partition vbmeta_google:1:%s"
1456                                   " --kernel_cmdline 'cmdline2 in vbmeta'"
1457                                   " --internal_release_string \"\"",
1458                                   pk_path.c_str()));
1459 
1460   EXPECT_EQ(
1461       "Minimum libavb version:   1.0\n"
1462       "Header Block:             256 bytes\n"
1463       "Authentication Block:     320 bytes\n"
1464       "Auxiliary Block:          1728 bytes\n"
1465       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1466       "Algorithm:                SHA256_RSA2048\n"
1467       "Rollback Index:           11\n"
1468       "Flags:                    0\n"
1469       "Rollback Index Location:  0\n"
1470       "Release String:           ''\n"
1471       "Descriptors:\n"
1472       "    Chain Partition descriptor:\n"
1473       "      Partition Name:          vbmeta_google\n"
1474       "      Rollback Index Location: 1\n"
1475       "      Public key (sha1):       "
1476       "2597c218aae470a130f61162feaae70afd97f011\n"
1477       "      Flags:                   0\n"
1478       "    Kernel Cmdline descriptor:\n"
1479       "      Flags:                 0\n"
1480       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
1481       InfoImage(vbmeta_image_path_.string()));
1482 
1483   EXPECT_EQ(
1484       "Minimum libavb version:   1.0\n"
1485       "Header Block:             256 bytes\n"
1486       "Authentication Block:     576 bytes\n"
1487       "Auxiliary Block:          1280 bytes\n"
1488       "Public key (sha1):        2597c218aae470a130f61162feaae70afd97f011\n"
1489       "Algorithm:                SHA256_RSA4096\n"
1490       "Rollback Index:           12\n"
1491       "Flags:                    0\n"
1492       "Rollback Index Location:  0\n"
1493       "Release String:           ''\n"
1494       "Descriptors:\n"
1495       "    Hash descriptor:\n"
1496       "      Image Size:            5242880 bytes\n"
1497       "      Hash Algorithm:        sha256\n"
1498       "      Partition Name:        boot\n"
1499       "      Salt:                  deadbeef\n"
1500       "      Digest:                "
1501       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
1502       "      Flags:                 0\n"
1503       "    Kernel Cmdline descriptor:\n"
1504       "      Flags:                 0\n"
1505       "      Kernel Cmdline:        'cmdline2 in hash footer'\n",
1506       InfoImage(other_vbmeta_path.string()));
1507 
1508   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
1509 
1510   AvbSlotVerifyData* slot_data = NULL;
1511   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1512             avb_slot_verify(ops_.avb_ops(),
1513                             requested_partitions,
1514                             "",
1515                             AVB_SLOT_VERIFY_FLAGS_NONE,
1516                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1517                             &slot_data));
1518   EXPECT_NE(nullptr, slot_data);
1519 
1520   // Now verify the slot data. We should have two vbmeta
1521   // structs. Verify both of them. Note that the A/B suffix isn't
1522   // appended.
1523   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
1524   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
1525   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
1526   EXPECT_EQ(0,
1527             memcmp(vbmeta_image_.data(),
1528                    slot_data->vbmeta_images[0].vbmeta_data,
1529                    slot_data->vbmeta_images[0].vbmeta_size));
1530   // And for the second vbmeta struct we check that the descriptors
1531   // match the info_image output from above.
1532   EXPECT_EQ("vbmeta_google",
1533             std::string(slot_data->vbmeta_images[1].partition_name));
1534   const AvbDescriptor** descriptors =
1535       avb_descriptor_get_all(slot_data->vbmeta_images[1].vbmeta_data,
1536                              slot_data->vbmeta_images[1].vbmeta_size,
1537                              NULL);
1538   EXPECT_NE(nullptr, descriptors);
1539   AvbHashDescriptor hash_desc;
1540   EXPECT_EQ(true,
1541             avb_hash_descriptor_validate_and_byteswap(
1542                 ((AvbHashDescriptor*)descriptors[0]), &hash_desc));
1543   const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
1544                             sizeof(AvbHashDescriptor);
1545   uint64_t o = 0;
1546   EXPECT_EQ("boot",
1547             std::string(reinterpret_cast<const char*>(desc_end + o),
1548                         hash_desc.partition_name_len));
1549   o += hash_desc.partition_name_len;
1550   EXPECT_EQ("deadbeef", mem_to_hexstring(desc_end + o, hash_desc.salt_len));
1551   o += hash_desc.salt_len;
1552   EXPECT_EQ("184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d",
1553             mem_to_hexstring(desc_end + o, hash_desc.digest_len));
1554   AvbKernelCmdlineDescriptor cmdline_desc;
1555   EXPECT_EQ(true,
1556             avb_kernel_cmdline_descriptor_validate_and_byteswap(
1557                 ((AvbKernelCmdlineDescriptor*)descriptors[1]), &cmdline_desc));
1558   desc_end = reinterpret_cast<const uint8_t*>(descriptors[1]) +
1559              sizeof(AvbKernelCmdlineDescriptor);
1560   EXPECT_EQ("cmdline2 in hash footer",
1561             std::string(reinterpret_cast<const char*>(desc_end),
1562                         cmdline_desc.kernel_cmdline_length));
1563   avb_free(descriptors);
1564 
1565   // The boot image data should match what is generated above with
1566   // GenerateImage().
1567   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
1568   EXPECT_EQ("boot",
1569             std::string(slot_data->loaded_partitions[0].partition_name));
1570   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
1571   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
1572     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
1573   }
1574 
1575   // This should match the two cmdlines with a space (U+0020) between them.
1576   EXPECT_EQ(
1577       "cmdline2 in hash footer cmdline2 in vbmeta "
1578       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
1579       "androidboot.vbmeta.avb_version=1.3 "
1580       "androidboot.vbmeta.device_state=locked "
1581       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
1582       "androidboot.vbmeta.digest="
1583       "232447e92370ed31c2b6c5fb7328eb5d828a9819b3e6f6c10d96b9ca6fd209a1 "
1584       "androidboot.vbmeta.invalidate_on_error=yes "
1585       "androidboot.veritymode=enforcing",
1586       std::string(slot_data->cmdline));
1587   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
1588   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
1589   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
1590     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
1591   }
1592   uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
1593   avb_slot_verify_data_calculate_vbmeta_digest(
1594       slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
1595   EXPECT_EQ("232447e92370ed31c2b6c5fb7328eb5d828a9819b3e6f6c10d96b9ca6fd209a1",
1596             mem_to_hexstring(vbmeta_digest, AVB_SHA256_DIGEST_SIZE));
1597   avb_slot_verify_data_free(slot_data);
1598 
1599   EXPECT_EQ("232447e92370ed31c2b6c5fb7328eb5d828a9819b3e6f6c10d96b9ca6fd209a1",
1600             CalcVBMetaDigest("vbmeta.img", "sha256"));
1601 }
1602 
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionCorruptBoot)1603 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionCorruptBoot) {
1604   size_t boot_partition_size = 16 * 1024 * 1024;
1605   std::string boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
1606   const char* requested_partitions[] = {"boot", NULL};
1607 
1608   EXPECT_COMMAND(0,
1609                  "./avbtool.py add_hash_footer"
1610                  " --image %s"
1611                  " --rollback_index 0"
1612                  " --partition_name boot"
1613                  " --partition_size %zd"
1614                  " --algorithm SHA256_RSA4096"
1615                  " --key test/data/testkey_rsa4096.pem"
1616                  " --salt deadbeef"
1617                  " --internal_release_string \"\"",
1618                  boot_path.c_str(),
1619                  boot_partition_size);
1620 
1621   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
1622   EXPECT_COMMAND(
1623       0,
1624       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
1625       " --output %s",
1626       pk_path.c_str());
1627 
1628   GenerateVBMetaImage(
1629       "vbmeta_a.img",
1630       "SHA256_RSA2048",
1631       0,
1632       "test/data/testkey_rsa2048.pem",
1633       android::base::StringPrintf("--chain_partition boot:1:%s"
1634                                   " --internal_release_string \"\"",
1635                                   pk_path.c_str()));
1636 
1637   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
1638 
1639   AvbSlotVerifyData* slot_data = NULL;
1640   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1641             avb_slot_verify(ops_.avb_ops(),
1642                             requested_partitions,
1643                             "_a",
1644                             AVB_SLOT_VERIFY_FLAGS_NONE,
1645                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1646                             &slot_data));
1647   EXPECT_NE(nullptr, slot_data);
1648   avb_slot_verify_data_free(slot_data);
1649 
1650   // Now corrupt boot_a.img and expect verification error.
1651   uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
1652   EXPECT_EQ(AVB_IO_RESULT_OK,
1653             ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
1654                                                "boot_a",
1655                                                1024 * 1024,  // offset: 1 MiB
1656                                                sizeof corrupt_data,
1657                                                corrupt_data));
1658 
1659   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
1660             avb_slot_verify(ops_.avb_ops(),
1661                             requested_partitions,
1662                             "_a",
1663                             AVB_SLOT_VERIFY_FLAGS_NONE,
1664                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1665                             &slot_data));
1666   EXPECT_EQ(nullptr, slot_data);
1667   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
1668             avb_slot_verify(ops_.avb_ops(),
1669                             requested_partitions,
1670                             "_a",
1671                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
1672                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1673                             &slot_data));
1674   EXPECT_NE(nullptr, slot_data);
1675   avb_slot_verify_data_free(slot_data);
1676 }
1677 
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionKeyMismatch)1678 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionKeyMismatch) {
1679   size_t boot_partition_size = 16 * 1024 * 1024;
1680   std::string boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
1681   const char* requested_partitions[] = {"boot", NULL};
1682 
1683   // Use different key to sign vbmeta in boot_a (we use the 8192 bit
1684   // key) than what's in the chained partition descriptor (which is
1685   // the 4096 bit key) and expect
1686   // AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED.
1687 
1688   EXPECT_COMMAND(0,
1689                  "./avbtool.py add_hash_footer"
1690                  " --image %s"
1691                  " --rollback_index 0"
1692                  " --partition_name boot"
1693                  " --partition_size %zd"
1694                  " --algorithm SHA256_RSA8192"
1695                  " --key test/data/testkey_rsa8192.pem"
1696                  " --salt deadbeef"
1697                  " --internal_release_string \"\"",
1698                  boot_path.c_str(),
1699                  boot_partition_size);
1700 
1701   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
1702   EXPECT_COMMAND(
1703       0,
1704       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
1705       " --output %s",
1706       pk_path.c_str());
1707 
1708   GenerateVBMetaImage(
1709       "vbmeta_a.img",
1710       "SHA256_RSA2048",
1711       0,
1712       "test/data/testkey_rsa2048.pem",
1713       android::base::StringPrintf("--chain_partition boot:1:%s"
1714                                   " --internal_release_string \"\"",
1715                                   pk_path.c_str()));
1716 
1717   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
1718 
1719   AvbSlotVerifyData* slot_data = NULL;
1720   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
1721             avb_slot_verify(ops_.avb_ops(),
1722                             requested_partitions,
1723                             "_a",
1724                             AVB_SLOT_VERIFY_FLAGS_NONE,
1725                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1726                             &slot_data));
1727   EXPECT_EQ(nullptr, slot_data);
1728   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
1729             avb_slot_verify(ops_.avb_ops(),
1730                             requested_partitions,
1731                             "_a",
1732                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
1733                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1734                             &slot_data));
1735   EXPECT_NE(nullptr, slot_data);
1736   avb_slot_verify_data_free(slot_data);
1737 }
1738 
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionRollbackIndexFail)1739 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionRollbackIndexFail) {
1740   size_t boot_partition_size = 16 * 1024 * 1024;
1741   std::string boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
1742   const char* requested_partitions[] = {"boot", NULL};
1743 
1744   EXPECT_COMMAND(0,
1745                  "./avbtool.py add_hash_footer"
1746                  " --image %s"
1747                  " --rollback_index 10"
1748                  " --partition_name boot"
1749                  " --partition_size %zd"
1750                  " --algorithm SHA256_RSA4096"
1751                  " --key test/data/testkey_rsa4096.pem"
1752                  " --salt deadbeef"
1753                  " --internal_release_string \"\"",
1754                  boot_path.c_str(),
1755                  boot_partition_size);
1756 
1757   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
1758   EXPECT_COMMAND(
1759       0,
1760       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
1761       " --output %s",
1762       pk_path.c_str());
1763 
1764   GenerateVBMetaImage(
1765       "vbmeta_a.img",
1766       "SHA256_RSA2048",
1767       110,
1768       "test/data/testkey_rsa2048.pem",
1769       android::base::StringPrintf("--chain_partition boot:1:%s"
1770                                   " --internal_release_string \"\"",
1771                                   pk_path.c_str()));
1772 
1773   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
1774 
1775   AvbSlotVerifyData* slot_data = NULL;
1776 
1777   // Both images (vbmeta_a and boot_a) have rollback index 10 and 11
1778   // so it should work if the stored rollback indexes are 0 and 0.
1779   ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}});
1780   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1781             avb_slot_verify(ops_.avb_ops(),
1782                             requested_partitions,
1783                             "_a",
1784                             AVB_SLOT_VERIFY_FLAGS_NONE,
1785                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1786                             &slot_data));
1787   EXPECT_NE(nullptr, slot_data);
1788   avb_slot_verify_data_free(slot_data);
1789 
1790   // Check failure if we set the stored rollback index of the chained
1791   // partition to 20 (see AvbSlotVerifyTest.RollbackIndex above
1792   // where we test rollback index checks for the vbmeta partition).
1793   ops_.set_stored_rollback_indexes({{0, 0}, {1, 20}});
1794   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
1795             avb_slot_verify(ops_.avb_ops(),
1796                             requested_partitions,
1797                             "_a",
1798                             AVB_SLOT_VERIFY_FLAGS_NONE,
1799                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1800                             &slot_data));
1801   EXPECT_EQ(nullptr, slot_data);
1802   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
1803             avb_slot_verify(ops_.avb_ops(),
1804                             requested_partitions,
1805                             "_a",
1806                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
1807                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1808                             &slot_data));
1809   EXPECT_NE(nullptr, slot_data);
1810   avb_slot_verify_data_free(slot_data);
1811 
1812   // Check failure if there is no rollback index slot 1 - in that case
1813   // we expect an I/O error since ops->read_rollback_index() will
1814   // fail.
1815   ops_.set_stored_rollback_indexes({{0, 0}});
1816   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
1817             avb_slot_verify(ops_.avb_ops(),
1818                             requested_partitions,
1819                             "_a",
1820                             AVB_SLOT_VERIFY_FLAGS_NONE,
1821                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1822                             &slot_data));
1823   EXPECT_EQ(nullptr, slot_data);
1824 }
1825 
TEST_F(AvbSlotVerifyTest,ChainedPartitionNoSlots)1826 TEST_F(AvbSlotVerifyTest, ChainedPartitionNoSlots) {
1827   size_t boot_partition_size = 16 * 1024 * 1024;
1828   const size_t boot_image_size = 5 * 1024 * 1024;
1829   std::string boot_path = GenerateImage("boot.img", boot_image_size);
1830   const char* requested_partitions[] = {"boot", NULL};
1831 
1832   EXPECT_COMMAND(0,
1833                  "./avbtool.py add_hash_footer"
1834                  " --image %s"
1835                  " --kernel_cmdline 'cmdline2 in hash footer'"
1836                  " --rollback_index 12"
1837                  " --partition_name boot"
1838                  " --partition_size %zd"
1839                  " --algorithm SHA256_RSA4096"
1840                  " --key test/data/testkey_rsa4096.pem"
1841                  " --salt deadbeef"
1842                  " --internal_release_string \"\"",
1843                  boot_path.c_str(),
1844                  boot_partition_size);
1845 
1846   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
1847   EXPECT_COMMAND(
1848       0,
1849       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
1850       " --output %s",
1851       pk_path.c_str());
1852 
1853   GenerateVBMetaImage(
1854       "vbmeta.img",
1855       "SHA256_RSA2048",
1856       11,
1857       "test/data/testkey_rsa2048.pem",
1858       android::base::StringPrintf("--chain_partition boot:1:%s"
1859                                   " --kernel_cmdline 'cmdline2 in vbmeta'"
1860                                   " --internal_release_string \"\"",
1861                                   pk_path.c_str()));
1862 
1863   EXPECT_EQ(
1864       "Minimum libavb version:   1.0\n"
1865       "Header Block:             256 bytes\n"
1866       "Authentication Block:     320 bytes\n"
1867       "Auxiliary Block:          1728 bytes\n"
1868       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1869       "Algorithm:                SHA256_RSA2048\n"
1870       "Rollback Index:           11\n"
1871       "Flags:                    0\n"
1872       "Rollback Index Location:  0\n"
1873       "Release String:           ''\n"
1874       "Descriptors:\n"
1875       "    Chain Partition descriptor:\n"
1876       "      Partition Name:          boot\n"
1877       "      Rollback Index Location: 1\n"
1878       "      Public key (sha1):       "
1879       "2597c218aae470a130f61162feaae70afd97f011\n"
1880       "      Flags:                   0\n"
1881       "    Kernel Cmdline descriptor:\n"
1882       "      Flags:                 0\n"
1883       "      Kernel Cmdline:        'cmdline2 in vbmeta'\n",
1884       InfoImage(vbmeta_image_path_.string()));
1885 
1886   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
1887 
1888   AvbSlotVerifyData* slot_data = NULL;
1889   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1890             avb_slot_verify(ops_.avb_ops(),
1891                             requested_partitions,
1892                             "",
1893                             AVB_SLOT_VERIFY_FLAGS_NONE,
1894                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1895                             &slot_data));
1896   EXPECT_NE(nullptr, slot_data);
1897 
1898   // Now verify the slot data. The first vbmeta data should match our
1899   // vbmeta_image_ member and the second one should be for the 'boot'
1900   // partition.
1901   EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
1902   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
1903   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
1904   EXPECT_EQ(0,
1905             memcmp(vbmeta_image_.data(),
1906                    slot_data->vbmeta_images[0].vbmeta_data,
1907                    slot_data->vbmeta_images[0].vbmeta_size));
1908   EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
1909 
1910   // The boot image data should match what is generated above with
1911   // GenerateImage().
1912   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
1913   EXPECT_EQ("boot",
1914             std::string(slot_data->loaded_partitions[0].partition_name));
1915   EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
1916   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
1917     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
1918   }
1919 
1920   // This should match the two cmdlines with a space (U+0020) between
1921   // them.
1922   EXPECT_EQ(
1923       "cmdline2 in hash footer cmdline2 in vbmeta "
1924       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
1925       "androidboot.vbmeta.avb_version=1.3 "
1926       "androidboot.vbmeta.device_state=locked "
1927       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
1928       "androidboot.vbmeta.digest="
1929       "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4 "
1930       "androidboot.vbmeta.invalidate_on_error=yes "
1931       "androidboot.veritymode=enforcing",
1932       std::string(slot_data->cmdline));
1933   EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
1934   EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
1935   for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
1936     EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
1937   }
1938   avb_slot_verify_data_free(slot_data);
1939 }
1940 
TEST_F(AvbSlotVerifyTest,PartitionsOtherThanBoot)1941 TEST_F(AvbSlotVerifyTest, PartitionsOtherThanBoot) {
1942   const size_t foo_partition_size = 16 * 1024 * 1024;
1943   const size_t bar_partition_size = 32 * 1024 * 1024;
1944   const size_t foo_image_size = 5 * 1024 * 1024;
1945   const size_t bar_image_size = 10 * 1024 * 1024;
1946   std::string foo_path = GenerateImage("foo_a.img", foo_image_size);
1947   std::string bar_path = GenerateImage("bar_a.img", bar_image_size);
1948 
1949   EXPECT_COMMAND(0,
1950                  "./avbtool.py add_hash_footer"
1951                  " --image %s"
1952                  " --partition_name foo"
1953                  " --partition_size %zd"
1954                  " --salt deadbeef"
1955                  " --internal_release_string \"\"",
1956                  foo_path.c_str(),
1957                  foo_partition_size);
1958 
1959   EXPECT_COMMAND(0,
1960                  "./avbtool.py add_hash_footer"
1961                  " --image %s"
1962                  " --partition_name bar"
1963                  " --partition_size %zd"
1964                  " --salt deadbeef"
1965                  " --internal_release_string \"\"",
1966                  bar_path.c_str(),
1967                  bar_partition_size);
1968 
1969   GenerateVBMetaImage(
1970       "vbmeta_a.img",
1971       "SHA256_RSA2048",
1972       4,
1973       "test/data/testkey_rsa2048.pem",
1974       android::base::StringPrintf("--include_descriptors_from_image %s"
1975                                   " --include_descriptors_from_image %s"
1976                                   " --internal_release_string \"\"",
1977                                   foo_path.c_str(),
1978                                   bar_path.c_str()));
1979 
1980   EXPECT_EQ(
1981       "Minimum libavb version:   1.0\n"
1982       "Header Block:             256 bytes\n"
1983       "Authentication Block:     320 bytes\n"
1984       "Auxiliary Block:          896 bytes\n"
1985       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1986       "Algorithm:                SHA256_RSA2048\n"
1987       "Rollback Index:           4\n"
1988       "Flags:                    0\n"
1989       "Rollback Index Location:  0\n"
1990       "Release String:           ''\n"
1991       "Descriptors:\n"
1992       "    Hash descriptor:\n"
1993       "      Image Size:            10485760 bytes\n"
1994       "      Hash Algorithm:        sha256\n"
1995       "      Partition Name:        bar\n"
1996       "      Salt:                  deadbeef\n"
1997       "      Digest:                "
1998       "baea4bbd261d0edf4d1fe5e6e5a36976c291eeba66b6a46fa81dba691327a727\n"
1999       "      Flags:                 0\n"
2000       "    Hash descriptor:\n"
2001       "      Image Size:            5242880 bytes\n"
2002       "      Hash Algorithm:        sha256\n"
2003       "      Partition Name:        foo\n"
2004       "      Salt:                  deadbeef\n"
2005       "      Digest:                "
2006       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
2007       "      Flags:                 0\n",
2008       InfoImage(vbmeta_image_path_.string()));
2009 
2010   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
2011 
2012   AvbSlotVerifyData* slot_data = NULL;
2013   const char* requested_partitions[] = {"foo", "bar", NULL};
2014   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2015             avb_slot_verify(ops_.avb_ops(),
2016                             requested_partitions,
2017                             "_a",
2018                             AVB_SLOT_VERIFY_FLAGS_NONE,
2019                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2020                             &slot_data));
2021   EXPECT_NE(nullptr, slot_data);
2022 
2023   // Now verify the slot data. The vbmeta data should match our
2024   // vbmeta_image_ member.
2025   EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
2026   EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
2027   EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
2028   EXPECT_EQ(0,
2029             memcmp(vbmeta_image_.data(),
2030                    slot_data->vbmeta_images[0].vbmeta_data,
2031                    slot_data->vbmeta_images[0].vbmeta_size));
2032 
2033   // The 'foo' and 'bar' image data should match what is generated
2034   // above with GenerateImage().
2035   EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
2036   EXPECT_EQ("bar", std::string(slot_data->loaded_partitions[0].partition_name));
2037   EXPECT_EQ(bar_image_size, slot_data->loaded_partitions[0].data_size);
2038   for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
2039     EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
2040   }
2041   EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[1].partition_name));
2042   EXPECT_EQ(foo_image_size, slot_data->loaded_partitions[1].data_size);
2043   for (size_t n = 0; n < slot_data->loaded_partitions[1].data_size; n++) {
2044     EXPECT_EQ(slot_data->loaded_partitions[1].data[n], uint8_t(n));
2045   }
2046   avb_slot_verify_data_free(slot_data);
2047 
2048   // Check that we loaded vbmeta_a, foo_a, and bar_a.
2049   std::set<std::string> partitions = ops_.get_partition_names_read_from();
2050   EXPECT_EQ(size_t(3), partitions.size());
2051   EXPECT_TRUE(partitions.find("vbmeta_a") != partitions.end());
2052   EXPECT_TRUE(partitions.find("foo_a") != partitions.end());
2053   EXPECT_TRUE(partitions.find("bar_a") != partitions.end());
2054 }
2055 
TEST_F(AvbSlotVerifyTest,OnlyLoadWhatHasBeenRequested)2056 TEST_F(AvbSlotVerifyTest, OnlyLoadWhatHasBeenRequested) {
2057   const size_t foo_partition_size = 16 * 1024 * 1024;
2058   const size_t bar_partition_size = 32 * 1024 * 1024;
2059   const size_t foo_image_size = 5 * 1024 * 1024;
2060   const size_t bar_image_size = 10 * 1024 * 1024;
2061   std::string foo_path = GenerateImage("foo_a.img", foo_image_size);
2062   std::string bar_path = GenerateImage("bar_a.img", bar_image_size);
2063 
2064   EXPECT_COMMAND(0,
2065                  "./avbtool.py add_hash_footer"
2066                  " --image %s"
2067                  " --partition_name foo"
2068                  " --partition_size %zd"
2069                  " --salt deadbeef"
2070                  " --internal_release_string \"\"",
2071                  foo_path.c_str(),
2072                  foo_partition_size);
2073 
2074   EXPECT_COMMAND(0,
2075                  "./avbtool.py add_hash_footer"
2076                  " --image %s"
2077                  " --partition_name bar"
2078                  " --partition_size %zd"
2079                  " --salt deadbeef"
2080                  " --internal_release_string \"\"",
2081                  bar_path.c_str(),
2082                  bar_partition_size);
2083 
2084   GenerateVBMetaImage(
2085       "vbmeta_a.img",
2086       "SHA256_RSA2048",
2087       4,
2088       "test/data/testkey_rsa2048.pem",
2089       android::base::StringPrintf("--include_descriptors_from_image %s"
2090                                   " --include_descriptors_from_image %s"
2091                                   " --internal_release_string \"\"",
2092                                   foo_path.c_str(),
2093                                   bar_path.c_str()));
2094 
2095   EXPECT_EQ(
2096       "Minimum libavb version:   1.0\n"
2097       "Header Block:             256 bytes\n"
2098       "Authentication Block:     320 bytes\n"
2099       "Auxiliary Block:          896 bytes\n"
2100       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2101       "Algorithm:                SHA256_RSA2048\n"
2102       "Rollback Index:           4\n"
2103       "Flags:                    0\n"
2104       "Rollback Index Location:  0\n"
2105       "Release String:           ''\n"
2106       "Descriptors:\n"
2107       "    Hash descriptor:\n"
2108       "      Image Size:            10485760 bytes\n"
2109       "      Hash Algorithm:        sha256\n"
2110       "      Partition Name:        bar\n"
2111       "      Salt:                  deadbeef\n"
2112       "      Digest:                "
2113       "baea4bbd261d0edf4d1fe5e6e5a36976c291eeba66b6a46fa81dba691327a727\n"
2114       "      Flags:                 0\n"
2115       "    Hash descriptor:\n"
2116       "      Image Size:            5242880 bytes\n"
2117       "      Hash Algorithm:        sha256\n"
2118       "      Partition Name:        foo\n"
2119       "      Salt:                  deadbeef\n"
2120       "      Digest:                "
2121       "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
2122       "      Flags:                 0\n",
2123       InfoImage(vbmeta_image_path_.string()));
2124 
2125   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
2126   AvbSlotVerifyData* slot_data = NULL;
2127   const char* requested_partitions[] = {"foo", NULL};
2128   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2129             avb_slot_verify(ops_.avb_ops(),
2130                             requested_partitions,
2131                             "_a",
2132                             AVB_SLOT_VERIFY_FLAGS_NONE,
2133                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2134                             &slot_data));
2135   EXPECT_NE(nullptr, slot_data);
2136   EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
2137   EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[0].partition_name));
2138   avb_slot_verify_data_free(slot_data);
2139 
2140   // Check that we loaded vbmeta_a, foo_a but not bar_a.
2141   std::set<std::string> partitions = ops_.get_partition_names_read_from();
2142   EXPECT_EQ(size_t(2), partitions.size());
2143   EXPECT_TRUE(partitions.find("vbmeta_a") != partitions.end());
2144   EXPECT_TRUE(partitions.find("foo_a") != partitions.end());
2145   EXPECT_TRUE(partitions.find("bar_a") == partitions.end());
2146 }
2147 
TEST_F(AvbSlotVerifyTest,NoVBMetaPartitionFlag)2148 TEST_F(AvbSlotVerifyTest, NoVBMetaPartitionFlag) {
2149   const size_t foo_partition_size = 16 * 1024 * 1024;
2150   const size_t bar_partition_size = 32 * 1024 * 1024;
2151   const size_t foo_image_size = 5 * 1024 * 1024;
2152   const size_t bar_image_size = 10 * 1024 * 1024;
2153   std::string foo_path = GenerateImage("foo_a.img", foo_image_size);
2154   std::string bar_path = GenerateImage("bar_a.img", bar_image_size);
2155 
2156   EXPECT_COMMAND(0,
2157                  "./avbtool.py add_hash_footer"
2158                  " --image %s"
2159                  " --kernel_cmdline 'this is=5 from foo=42'"
2160                  " --partition_name foo"
2161                  " --partition_size %zd"
2162                  " --salt deadbeef"
2163                  " --internal_release_string \"\""
2164                  " --algorithm SHA256_RSA4096"
2165                  " --salt deadbeef"
2166                  " --key test/data/testkey_rsa4096.pem"
2167                  " --rollback_index 42",
2168                  foo_path.c_str(),
2169                  foo_partition_size);
2170 
2171   EXPECT_COMMAND(0,
2172                  "./avbtool.py add_hash_footer"
2173                  " --image %s"
2174                  " --kernel_cmdline 'and=43 from bar'"
2175                  " --partition_name bar"
2176                  " --partition_size %zd"
2177                  " --salt deadbeef"
2178                  " --internal_release_string \"\""
2179                  " --algorithm SHA256_RSA2048"
2180                  " --salt deadbeef"
2181                  " --key test/data/testkey_rsa2048.pem"
2182                  " --rollback_index 43",
2183                  bar_path.c_str(),
2184                  bar_partition_size);
2185 
2186   ops_.set_expected_public_key_for_partition(
2187       "foo_a", PublicKeyAVB("test/data/testkey_rsa4096.pem"), 1);
2188   ops_.set_expected_public_key_for_partition(
2189       "bar_a", PublicKeyAVB("test/data/testkey_rsa2048.pem"), 2);
2190   ops_.set_stored_rollback_indexes({{0, 1000}, {1, 10}, {2, 11}});
2191   AvbSlotVerifyData* slot_data = NULL;
2192   const char* requested_partitions[] = {"foo", "bar", NULL};
2193 
2194   // Without AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION, this should fail because
2195   // vbmeta_a (or boot_a) cannot not be found.
2196   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
2197             avb_slot_verify(ops_.avb_ops(),
2198                             requested_partitions,
2199                             "_a",
2200                             AVB_SLOT_VERIFY_FLAGS_NONE,
2201                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2202                             &slot_data));
2203 
2204   // However, with this flag it should succeed (note that rollback indexes in
2205   // the images exceed the stored rollback indexes)
2206   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2207             avb_slot_verify(ops_.avb_ops(),
2208                             requested_partitions,
2209                             "_a",
2210                             AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
2211                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2212                             &slot_data));
2213   EXPECT_NE(nullptr, slot_data);
2214   EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
2215   EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[0].partition_name));
2216   EXPECT_EQ("bar", std::string(slot_data->loaded_partitions[1].partition_name));
2217   // Note the absence of 'androidboot.vbmeta.device'
2218   EXPECT_EQ(
2219       "this is=5 from foo=42 and=43 from bar "
2220       "androidboot.vbmeta.avb_version=1.3 "
2221       "androidboot.vbmeta.device_state=locked "
2222       "androidboot.vbmeta.hash_alg=sha256 "
2223       "androidboot.vbmeta.size=3456 "
2224       "androidboot.vbmeta.digest="
2225       "b5dbfb1743073f9a4cb45f94d1d849f89ca9777d158a2a06d09517c79ffd86cd "
2226       "androidboot.vbmeta.invalidate_on_error=yes "
2227       "androidboot.veritymode=enforcing",
2228       std::string(slot_data->cmdline));
2229   avb_slot_verify_data_free(slot_data);
2230 
2231   // Check that rollback protection works if we increase the stored rollback
2232   // indexes to exceed that of the image... do a check for each location.
2233   ops_.set_stored_rollback_indexes({{0, 1000}, {1, 10}, {2, 100}});
2234   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
2235             avb_slot_verify(ops_.avb_ops(),
2236                             requested_partitions,
2237                             "_a",
2238                             AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
2239                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2240                             &slot_data));
2241   EXPECT_EQ(nullptr, slot_data);
2242   ops_.set_stored_rollback_indexes({{0, 1000}, {1, 100}, {2, 10}});
2243   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
2244             avb_slot_verify(ops_.avb_ops(),
2245                             requested_partitions,
2246                             "_a",
2247                             AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION,
2248                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2249                             &slot_data));
2250   EXPECT_EQ(nullptr, slot_data);
2251 }
2252 
TEST_F(AvbSlotVerifyTest,PublicKeyMetadata)2253 TEST_F(AvbSlotVerifyTest, PublicKeyMetadata) {
2254   std::string md_path = GenerateImage("md.bin", 1536);
2255 
2256   GenerateVBMetaImage(
2257       "vbmeta_a.img",
2258       "SHA256_RSA2048",
2259       0,
2260       "test/data/testkey_rsa2048.pem",
2261       android::base::StringPrintf("--public_key_metadata %s"
2262                                   " --internal_release_string \"\"",
2263                                   md_path.c_str()));
2264 
2265   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
2266 
2267   std::string md_data;
2268   ASSERT_TRUE(android::base::ReadFileToString(md_path, &md_data));
2269   ops_.set_expected_public_key_metadata(md_data);
2270 
2271   AvbSlotVerifyData* slot_data = NULL;
2272   const char* requested_partitions[] = {"boot", NULL};
2273   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2274             avb_slot_verify(ops_.avb_ops(),
2275                             requested_partitions,
2276                             "_a",
2277                             AVB_SLOT_VERIFY_FLAGS_NONE,
2278                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2279                             &slot_data));
2280   EXPECT_NE(nullptr, slot_data);
2281   EXPECT_EQ(
2282       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
2283       "androidboot.vbmeta.avb_version=1.3 "
2284       "androidboot.vbmeta.device_state=locked "
2285       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=2688 "
2286       "androidboot.vbmeta.digest="
2287       "5edcaa54f40382ee6a2fc3b86cdf383348b35ed07955e83ea32d84b69a97eaa0 "
2288       "androidboot.vbmeta.invalidate_on_error=yes "
2289       "androidboot.veritymode=enforcing",
2290       std::string(slot_data->cmdline));
2291   avb_slot_verify_data_free(slot_data);
2292 }
2293 
CmdlineWithHashtreeVerification(bool hashtree_verification_on)2294 void AvbSlotVerifyTest::CmdlineWithHashtreeVerification(
2295     bool hashtree_verification_on) {
2296   const size_t rootfs_size = 1028 * 1024;
2297   const size_t partition_size = 1536 * 1024;
2298 
2299   // Generate a 1028 KiB file with known content.
2300   std::vector<uint8_t> rootfs;
2301   rootfs.resize(rootfs_size);
2302   for (size_t n = 0; n < rootfs_size; n++)
2303     rootfs[n] = uint8_t(n);
2304   std::filesystem::path rootfs_path = testdir_ / "rootfs.bin";
2305   EXPECT_EQ(rootfs_size,
2306             static_cast<const size_t>(
2307                 base::WriteFile(base::FilePath(rootfs_path.c_str()),
2308                                 reinterpret_cast<const char*>(rootfs.data()),
2309                                 rootfs.size())));
2310 
2311   EXPECT_COMMAND(0,
2312                  "./avbtool.py add_hashtree_footer --salt d00df00d --image %s "
2313                  "--partition_size %d --partition_name foobar "
2314                  "--algorithm SHA256_RSA2048 "
2315                  "--key test/data/testkey_rsa2048.pem "
2316                  "--internal_release_string \"\" "
2317                  "--do_not_generate_fec",
2318                  rootfs_path.c_str(),
2319                  (int)partition_size);
2320 
2321   // Check that we correctly generate dm-verity kernel cmdline
2322   // snippets, if requested.
2323   GenerateVBMetaImage(
2324       "vbmeta_a.img",
2325       "SHA256_RSA2048",
2326       4,
2327       "test/data/testkey_rsa2048.pem",
2328       android::base::StringPrintf(
2329           "--setup_rootfs_from_kernel %s "
2330           "--kernel_cmdline should_be_in_both=1 "
2331           "--algorithm SHA256_RSA2048 "
2332           "--flags %d "
2333           "--internal_release_string \"\"",
2334           rootfs_path.c_str(),
2335           hashtree_verification_on ? 0
2336                                    : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED));
2337 
2338   EXPECT_EQ(
2339       android::base::StringPrintf(
2340           "Minimum libavb version:   1.0\n"
2341           "Header Block:             256 bytes\n"
2342           "Authentication Block:     320 bytes\n"
2343           "Auxiliary Block:          960 bytes\n"
2344           "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2345           "Algorithm:                SHA256_RSA2048\n"
2346           "Rollback Index:           4\n"
2347           "Flags:                    %d\n"
2348           "Rollback Index Location:  0\n"
2349           "Release String:           ''\n"
2350           "Descriptors:\n"
2351           "    Kernel Cmdline descriptor:\n"
2352           "      Flags:                 1\n"
2353           "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity "
2354           "1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
2355           "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
2356           "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
2357           "$(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
2358           "    Kernel Cmdline descriptor:\n"
2359           "      Flags:                 2\n"
2360           "      Kernel Cmdline:        "
2361           "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
2362           "    Kernel Cmdline descriptor:\n"
2363           "      Flags:                 0\n"
2364           "      Kernel Cmdline:        'should_be_in_both=1'\n",
2365           hashtree_verification_on ? 0
2366                                    : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED),
2367       InfoImage(vbmeta_image_path_.string()));
2368 
2369   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
2370 
2371   // Check that avb_slot_verify() picks the cmdline decsriptors based
2372   // on their flags value.
2373   AvbSlotVerifyData* slot_data = NULL;
2374   const char* requested_partitions[] = {"boot", NULL};
2375   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2376             avb_slot_verify(ops_.avb_ops(),
2377                             requested_partitions,
2378                             "_a",
2379                             AVB_SLOT_VERIFY_FLAGS_NONE,
2380                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2381                             &slot_data));
2382   EXPECT_NE(nullptr, slot_data);
2383   if (hashtree_verification_on) {
2384     EXPECT_EQ(
2385         "dm=\"1 vroot none ro 1,0 2056 verity 1 "
2386         "PARTUUID=1234-fake-guid-for:system_a "
2387         "PARTUUID=1234-fake-guid-for:system_a 4096 4096 257 257 sha1 "
2388         "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
2389         "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
2390         "should_be_in_both=1 "
2391         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
2392         "androidboot.vbmeta.avb_version=1.3 "
2393         "androidboot.vbmeta.device_state=locked "
2394         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
2395         "androidboot.vbmeta.digest="
2396         "946996b4cd78f2c060f6bb062b94054b809cbfbe9bf4425df263a0e55395ceea "
2397         "androidboot.vbmeta.invalidate_on_error=yes "
2398         "androidboot.veritymode=enforcing",
2399         std::string(slot_data->cmdline));
2400   } else {
2401     // NOTE: androidboot.veritymode is 'disabled', not 'enforcing' and
2402     // androidboot.vbmeta.invalidate_on_error isn't set.
2403     EXPECT_EQ(
2404         "root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
2405         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
2406         "androidboot.vbmeta.avb_version=1.3 "
2407         "androidboot.vbmeta.device_state=locked "
2408         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
2409         "androidboot.vbmeta.digest="
2410         "c74338b2b366f7f774d264abb4ac06c997cbaacbf5edd70a6ef1a552f744076b "
2411         "androidboot.veritymode=disabled",
2412         std::string(slot_data->cmdline));
2413   }
2414   avb_slot_verify_data_free(slot_data);
2415 }
2416 
TEST_F(AvbSlotVerifyTest,CmdlineWithHashtreeVerificationOff)2417 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOff) {
2418   CmdlineWithHashtreeVerification(false);
2419 }
2420 
TEST_F(AvbSlotVerifyTest,CmdlineWithHashtreeVerificationOn)2421 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOn) {
2422   CmdlineWithHashtreeVerification(true);
2423 }
2424 
CmdlineWithChainedHashtreeVerification(bool hashtree_verification_on)2425 void AvbSlotVerifyTest::CmdlineWithChainedHashtreeVerification(
2426     bool hashtree_verification_on) {
2427   const size_t system_size = 1028 * 1024;
2428   const size_t system_partition_size = 1536 * 1024;
2429 
2430   // Generate a 1028 KiB file with known content.
2431   std::vector<uint8_t> contents;
2432   contents.resize(system_size);
2433   for (size_t n = 0; n < system_size; n++)
2434     contents[n] = uint8_t(n);
2435   std::filesystem::path system_path = testdir_ / "system_a.img";
2436   EXPECT_EQ(system_size,
2437             static_cast<const size_t>(
2438                 base::WriteFile(base::FilePath(system_path.c_str()),
2439                                 reinterpret_cast<const char*>(contents.data()),
2440                                 contents.size())));
2441 
2442   // Check that we correctly generate dm-verity kernel cmdline
2443   // snippets, if requested.
2444   EXPECT_COMMAND(0,
2445                  "./avbtool.py add_hashtree_footer --salt d00df00d --image %s "
2446                  "--partition_size %d --partition_name foobar "
2447                  "--algorithm SHA256_RSA2048 "
2448                  "--key test/data/testkey_rsa2048.pem "
2449                  "--internal_release_string \"\" "
2450                  "--do_not_generate_fec "
2451                  "--setup_as_rootfs_from_kernel",
2452                  system_path.c_str(),
2453                  (int)system_partition_size);
2454 
2455   EXPECT_EQ(
2456       "Footer version:           1.0\n"
2457       "Image size:               1572864 bytes\n"
2458       "Original image size:      1052672 bytes\n"
2459       "VBMeta offset:            1069056\n"
2460       "VBMeta size:              1664 bytes\n"
2461       "--\n"
2462       "Minimum libavb version:   1.0\n"
2463       "Header Block:             256 bytes\n"
2464       "Authentication Block:     320 bytes\n"
2465       "Auxiliary Block:          1088 bytes\n"
2466       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2467       "Algorithm:                SHA256_RSA2048\n"
2468       "Rollback Index:           0\n"
2469       "Flags:                    0\n"
2470       "Rollback Index Location:  0\n"
2471       "Release String:           ''\n"
2472       "Descriptors:\n"
2473       "    Hashtree descriptor:\n"
2474       "      Version of dm-verity:  1\n"
2475       "      Image Size:            1052672 bytes\n"
2476       "      Tree Offset:           1052672\n"
2477       "      Tree Size:             16384 bytes\n"
2478       "      Data Block Size:       4096 bytes\n"
2479       "      Hash Block Size:       4096 bytes\n"
2480       "      FEC num roots:         0\n"
2481       "      FEC offset:            0\n"
2482       "      FEC size:              0 bytes\n"
2483       "      Hash Algorithm:        sha1\n"
2484       "      Partition Name:        foobar\n"
2485       "      Salt:                  d00df00d\n"
2486       "      Root Digest:           e811611467dcd6e8dc4324e45f706c2bdd51db67\n"
2487       "      Flags:                 0\n"
2488       "    Kernel Cmdline descriptor:\n"
2489       "      Flags:                 1\n"
2490       "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity 1 "
2491       "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
2492       "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
2493       "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
2494       "    Kernel Cmdline descriptor:\n"
2495       "      Flags:                 2\n"
2496       "      Kernel Cmdline:        "
2497       "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n",
2498       InfoImage(system_path.string()));
2499 
2500   std::filesystem::path pk_path = testdir_ / "testkey_rsa2048.avbpubkey";
2501   EXPECT_COMMAND(
2502       0,
2503       "./avbtool.py extract_public_key --key test/data/testkey_rsa2048.pem"
2504       " --output %s",
2505       pk_path.c_str());
2506 
2507   GenerateVBMetaImage(
2508       "vbmeta_a.img",
2509       "SHA256_RSA2048",
2510       4,
2511       "test/data/testkey_rsa2048.pem",
2512       android::base::StringPrintf(
2513           "--kernel_cmdline should_be_in_both=1 "
2514           "--algorithm SHA256_RSA2048 "
2515           "--flags %d "
2516           "--chain_partition system:1:%s "
2517           "--internal_release_string \"\"",
2518           hashtree_verification_on ? 0
2519                                    : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED,
2520           pk_path.c_str()));
2521 
2522   EXPECT_EQ(
2523       android::base::StringPrintf(
2524           "Minimum libavb version:   1.0\n"
2525           "Header Block:             256 bytes\n"
2526           "Authentication Block:     320 bytes\n"
2527           "Auxiliary Block:          1216 bytes\n"
2528           "Public key (sha1):        "
2529           "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2530           "Algorithm:                SHA256_RSA2048\n"
2531           "Rollback Index:           4\n"
2532           "Flags:                    %d\n"
2533           "Rollback Index Location:  0\n"
2534           "Release String:           ''\n"
2535           "Descriptors:\n"
2536           "    Chain Partition descriptor:\n"
2537           "      Partition Name:          system\n"
2538           "      Rollback Index Location: 1\n"
2539           "      Public key (sha1):       "
2540           "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2541           "      Flags:                   0\n"
2542           "    Kernel Cmdline descriptor:\n"
2543           "      Flags:                 0\n"
2544           "      Kernel Cmdline:        'should_be_in_both=1'\n",
2545           hashtree_verification_on ? 0
2546                                    : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED),
2547       InfoImage(vbmeta_image_path_.string()));
2548 
2549   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
2550 
2551   // Check that avb_slot_verify() picks the cmdline descriptors based
2552   // on their flags value... note that these descriptors are in the
2553   // 'system' partition.
2554   AvbSlotVerifyData* slot_data = NULL;
2555   const char* requested_partitions[] = {"boot", NULL};
2556   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2557             avb_slot_verify(ops_.avb_ops(),
2558                             requested_partitions,
2559                             "_a",
2560                             AVB_SLOT_VERIFY_FLAGS_NONE,
2561                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2562                             &slot_data));
2563   EXPECT_NE(nullptr, slot_data);
2564   if (hashtree_verification_on) {
2565     EXPECT_EQ(
2566         "dm=\"1 vroot none ro 1,0 2056 verity 1 "
2567         "PARTUUID=1234-fake-guid-for:system_a "
2568         "PARTUUID=1234-fake-guid-for:system_a 4096 4096 257 257 sha1 "
2569         "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
2570         "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
2571         "should_be_in_both=1 "
2572         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
2573         "androidboot.vbmeta.avb_version=1.3 "
2574         "androidboot.vbmeta.device_state=locked "
2575         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=3456 "
2576         "androidboot.vbmeta.digest="
2577         "5ee1669b112625322657b83ec932c73dad9b0222011b5aa3e8273f4e0ee025dc "
2578         "androidboot.vbmeta.invalidate_on_error=yes "
2579         "androidboot.veritymode=enforcing",
2580         std::string(slot_data->cmdline));
2581   } else {
2582     // NOTE: androidboot.veritymode is 'disabled', not 'enforcing' and
2583     // androidboot.vbmeta.invalidate_on_error isn't set.
2584     EXPECT_EQ(
2585         "root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
2586         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
2587         "androidboot.vbmeta.avb_version=1.3 "
2588         "androidboot.vbmeta.device_state=locked "
2589         "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=3456 "
2590         "androidboot.vbmeta.digest="
2591         "ae792c45a9d898b532ff9625b60043a8d9eae7e6106b9cba31837d50ba40f81c "
2592         "androidboot.veritymode=disabled",
2593         std::string(slot_data->cmdline));
2594   }
2595   avb_slot_verify_data_free(slot_data);
2596 }
2597 
TEST_F(AvbSlotVerifyTest,CmdlineWithChainedHashtreeVerificationOff)2598 TEST_F(AvbSlotVerifyTest, CmdlineWithChainedHashtreeVerificationOff) {
2599   CmdlineWithChainedHashtreeVerification(false);
2600 }
2601 
TEST_F(AvbSlotVerifyTest,CmdlineWithChainedHashtreeVerificationOn)2602 TEST_F(AvbSlotVerifyTest, CmdlineWithChainedHashtreeVerificationOn) {
2603   CmdlineWithChainedHashtreeVerification(true);
2604 }
2605 
VerificationDisabled(bool use_avbctl,bool preload_boot,bool has_system_partition)2606 void AvbSlotVerifyTest::VerificationDisabled(bool use_avbctl,
2607                                              bool preload_boot,
2608                                              bool has_system_partition) {
2609   const size_t boot_part_size = 32 * 1024 * 1024;
2610   const size_t dtbo_part_size = 4 * 1024 * 1024;
2611   const size_t rootfs_size = 1028 * 1024;
2612   const size_t partition_size = 1536 * 1024;
2613 
2614   // Generate boot_a.img and dtbo_a.img since avb_slot_verify() will
2615   // attempt to load them upon encountering the VERIFICATION_DISABLED
2616   // flag.
2617   std::string boot_path = GenerateImage("boot_a.img", boot_part_size);
2618   const size_t DTBO_DATA_OFFSET = 42;
2619   std::string dtbo_path =
2620       GenerateImage("dtbo_a.img", dtbo_part_size, DTBO_DATA_OFFSET);
2621 
2622   // Generate a 1028 KiB file with known content.
2623   std::vector<uint8_t> rootfs;
2624   rootfs.resize(rootfs_size);
2625   for (size_t n = 0; n < rootfs_size; n++)
2626     rootfs[n] = uint8_t(n);
2627   std::filesystem::path rootfs_path = testdir_ / "rootfs.bin";
2628   EXPECT_EQ(rootfs_size,
2629             static_cast<const size_t>(
2630                 base::WriteFile(base::FilePath(rootfs_path.c_str()),
2631                                 reinterpret_cast<const char*>(rootfs.data()),
2632                                 rootfs.size())));
2633 
2634   EXPECT_COMMAND(0,
2635                  "./avbtool.py add_hashtree_footer --salt d00df00d --image %s "
2636                  "--partition_size %d --partition_name foobar "
2637                  "--algorithm SHA256_RSA2048 "
2638                  "--key test/data/testkey_rsa2048.pem "
2639                  "--internal_release_string \"\" "
2640                  "--do_not_generate_fec",
2641                  rootfs_path.c_str(),
2642                  (int)partition_size);
2643 
2644   // Check that we correctly generate dm-verity kernel cmdline
2645   // snippets, if requested.
2646   GenerateVBMetaImage(
2647       "vbmeta_a.img",
2648       "SHA256_RSA2048",
2649       4,
2650       "test/data/testkey_rsa2048.pem",
2651       android::base::StringPrintf(
2652           "--setup_rootfs_from_kernel %s "
2653           "--kernel_cmdline should_be_in_both=1 "
2654           "--algorithm SHA256_RSA2048 "
2655           "--flags %d "
2656           "--internal_release_string \"\"",
2657           rootfs_path.c_str(),
2658           use_avbctl ? 0 : AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED));
2659 
2660   EXPECT_EQ(
2661       android::base::StringPrintf(
2662           "Minimum libavb version:   1.0\n"
2663           "Header Block:             256 bytes\n"
2664           "Authentication Block:     320 bytes\n"
2665           "Auxiliary Block:          960 bytes\n"
2666           "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2667           "Algorithm:                SHA256_RSA2048\n"
2668           "Rollback Index:           4\n"
2669           "Flags:                    %d\n"
2670           "Rollback Index Location:  0\n"
2671           "Release String:           ''\n"
2672           "Descriptors:\n"
2673           "    Kernel Cmdline descriptor:\n"
2674           "      Flags:                 1\n"
2675           "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 2056 verity "
2676           "1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
2677           "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
2678           "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
2679           "$(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
2680           "    Kernel Cmdline descriptor:\n"
2681           "      Flags:                 2\n"
2682           "      Kernel Cmdline:        "
2683           "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
2684           "    Kernel Cmdline descriptor:\n"
2685           "      Flags:                 0\n"
2686           "      Kernel Cmdline:        'should_be_in_both=1'\n",
2687           use_avbctl ? 0 : AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED),
2688       InfoImage(vbmeta_image_path_.string()));
2689 
2690   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
2691 
2692   if (!has_system_partition) {
2693     ops_.set_hidden_partitions({"system", "system_a", "system_b"});
2694   }
2695 
2696   // Manually set the flag the same way 'avbctl disable-verification'
2697   // would do it.
2698   if (use_avbctl) {
2699     uint32_t flags_data;
2700     flags_data = avb_htobe32(AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
2701     EXPECT_EQ(AVB_IO_RESULT_OK,
2702               ops_.avb_ops()->write_to_partition(
2703                   ops_.avb_ops(),
2704                   "vbmeta_a",
2705                   offsetof(AvbVBMetaImageHeader, flags),
2706                   sizeof flags_data,
2707                   &flags_data));
2708   }
2709 
2710   if (preload_boot) {
2711     ops_.enable_get_preloaded_partition();
2712     EXPECT_TRUE(ops_.preload_partition("boot_a", base::FilePath(boot_path)));
2713   }
2714 
2715   // Check that avb_slot_verify() doesn't return any of the
2716   // descriptors and instead return a kernel command-line with
2717   // root=PARTUUID=<whatever_for_system_a> and none of the
2718   // androidboot.vbmeta.* options are set. Also ensure all the
2719   // requested partitions are loaded.
2720   //
2721   // Also if we modified via avbctl we should expect
2722   // ERROR_VERIFICATION instead of OK.
2723   //
2724   AvbSlotVerifyResult expected_result = AVB_SLOT_VERIFY_RESULT_OK;
2725   if (use_avbctl) {
2726     expected_result = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
2727   }
2728   AvbSlotVerifyData* slot_data = NULL;
2729   const char* requested_partitions[] = {"boot", "dtbo", NULL};
2730   EXPECT_EQ(expected_result,
2731             avb_slot_verify(ops_.avb_ops(),
2732                             requested_partitions,
2733                             "_a",
2734                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
2735                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2736                             &slot_data));
2737   EXPECT_NE(nullptr, slot_data);
2738   if (has_system_partition) {
2739     EXPECT_EQ("root=PARTUUID=1234-fake-guid-for:system_a",
2740               std::string(slot_data->cmdline));
2741   } else {
2742     EXPECT_EQ("", std::string(slot_data->cmdline));
2743   }
2744 
2745   // Also make sure that it actually loads the boot and dtbo partitions.
2746   EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
2747   EXPECT_EQ("boot",
2748             std::string(slot_data->loaded_partitions[0].partition_name));
2749   EXPECT_EQ(boot_part_size, slot_data->loaded_partitions[0].data_size);
2750   for (size_t n = 0; n < boot_part_size; n++) {
2751     EXPECT_EQ(uint8_t(n), slot_data->loaded_partitions[0].data[n]);
2752   }
2753   EXPECT_EQ(preload_boot, slot_data->loaded_partitions[0].preloaded);
2754 
2755   EXPECT_EQ("dtbo",
2756             std::string(slot_data->loaded_partitions[1].partition_name));
2757   EXPECT_EQ(dtbo_part_size, slot_data->loaded_partitions[1].data_size);
2758   for (size_t n = 0; n < dtbo_part_size; n++) {
2759     EXPECT_EQ(uint8_t(n + DTBO_DATA_OFFSET),
2760               slot_data->loaded_partitions[1].data[n]);
2761   }
2762   EXPECT_FALSE(slot_data->loaded_partitions[1].preloaded);
2763 
2764   avb_slot_verify_data_free(slot_data);
2765 }
2766 
TEST_F(AvbSlotVerifyTest,VerificationDisabledUnmodified)2767 TEST_F(AvbSlotVerifyTest, VerificationDisabledUnmodified) {
2768   VerificationDisabled(false,  // use_avbctl
2769                        false,  // preload_boot
2770                        true);  // has_system_partition
2771 }
2772 
TEST_F(AvbSlotVerifyTest,VerificationDisabledModified)2773 TEST_F(AvbSlotVerifyTest, VerificationDisabledModified) {
2774   VerificationDisabled(true,   // use_avbctl
2775                        false,  // preload_boot
2776                        true);  // has_system_partition
2777 }
2778 
TEST_F(AvbSlotVerifyTest,VerificationDisabledUnmodifiedPreloadBoot)2779 TEST_F(AvbSlotVerifyTest, VerificationDisabledUnmodifiedPreloadBoot) {
2780   VerificationDisabled(false,  // use_avbctl
2781                        true,   // preload_boot
2782                        true);  // has_system_partition
2783 }
2784 
TEST_F(AvbSlotVerifyTest,VerificationDisabledModifiedPreloadBoot)2785 TEST_F(AvbSlotVerifyTest, VerificationDisabledModifiedPreloadBoot) {
2786   VerificationDisabled(true,   // use_avbctl
2787                        true,   // preload_boot
2788                        true);  // has_system_partition
2789 }
2790 
TEST_F(AvbSlotVerifyTest,VerificationDisabledUnmodifiedNoSystemPartition)2791 TEST_F(AvbSlotVerifyTest, VerificationDisabledUnmodifiedNoSystemPartition) {
2792   VerificationDisabled(false,   // use_avbctl
2793                        false,   // preload_boot
2794                        false);  // has_system_partition
2795 }
2796 
TEST_F(AvbSlotVerifyTest,VerificationDisabledModifiedNoSystemPartition)2797 TEST_F(AvbSlotVerifyTest, VerificationDisabledModifiedNoSystemPartition) {
2798   VerificationDisabled(true,    // use_avbctl
2799                        false,   // preload_boot
2800                        false);  // has_system_partition
2801 }
2802 
2803 // In the event that there's no vbmeta partition, we treat the vbmeta
2804 // struct from 'boot' as the top-level partition. Check that this
2805 // works.
TEST_F(AvbSlotVerifyTest,NoVBMetaPartition)2806 TEST_F(AvbSlotVerifyTest, NoVBMetaPartition) {
2807   const size_t MiB = 1024 * 1024;
2808   const size_t boot_size = 6 * MiB;
2809   const size_t boot_part_size = 8 * MiB;
2810   const size_t system_size = 16 * MiB;
2811   const size_t system_part_size = 32 * MiB;
2812   const size_t foobar_size = 8 * MiB;
2813   const size_t foobar_part_size = 16 * MiB;
2814   const size_t bazboo_size = 4 * MiB;
2815   const size_t bazboo_part_size = 8 * MiB;
2816   std::string boot_path = GenerateImage("boot.img", boot_size);
2817   std::string system_path = GenerateImage("system.img", system_size);
2818   std::string foobar_path = GenerateImage("foobar.img", foobar_size);
2819   std::string bazboo_path = GenerateImage("bazboo.img", bazboo_size);
2820 
2821   EXPECT_COMMAND(0,
2822                  "./avbtool.py add_hashtree_footer --salt d00df00d --image %s "
2823                  "--partition_size %d --partition_name system "
2824                  "--algorithm SHA256_RSA2048 "
2825                  "--key test/data/testkey_rsa2048.pem "
2826                  "--internal_release_string \"\" "
2827                  "--do_not_generate_fec",
2828                  system_path.c_str(),
2829                  (int)system_part_size);
2830 
2831   EXPECT_COMMAND(0,
2832                  "./avbtool.py add_hashtree_footer --salt d00df00d --image %s "
2833                  "--partition_size %d --partition_name foobar "
2834                  "--algorithm SHA256_RSA2048 "
2835                  "--key test/data/testkey_rsa2048.pem "
2836                  "--internal_release_string \"\" "
2837                  "--do_not_generate_fec",
2838                  foobar_path.c_str(),
2839                  (int)foobar_part_size);
2840 
2841   EXPECT_COMMAND(0,
2842                  "./avbtool.py add_hashtree_footer --salt d00df00d --image %s "
2843                  "--partition_size %d --partition_name bazboo "
2844                  "--algorithm SHA512_RSA4096 "
2845                  "--key test/data/testkey_rsa4096.pem "
2846                  "--internal_release_string \"\" "
2847                  "--do_not_generate_fec",
2848                  bazboo_path.c_str(),
2849                  (int)bazboo_part_size);
2850 
2851   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
2852   EXPECT_COMMAND(
2853       0,
2854       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
2855       " --output %s",
2856       pk_path.c_str());
2857 
2858   // Explicitly pass "--flags 2147483648" (i.e. 1<<31) to check that
2859   // boot.img is treated as top-level. Note the corresponding "Flags:"
2860   // field below in the avbtool info_image output.
2861   EXPECT_COMMAND(0,
2862                  "./avbtool.py add_hash_footer --salt d00df00d "
2863                  "--hash_algorithm sha256 --image %s "
2864                  "--partition_size %d --partition_name boot "
2865                  "--algorithm SHA256_RSA2048 "
2866                  "--key test/data/testkey_rsa2048.pem "
2867                  "--internal_release_string \"\" "
2868                  "--include_descriptors_from_image %s "
2869                  "--include_descriptors_from_image %s "
2870                  "--setup_rootfs_from_kernel %s "
2871                  "--chain_partition bazboo:1:%s "
2872                  "--flags 2147483648",
2873                  boot_path.c_str(),
2874                  (int)boot_part_size,
2875                  system_path.c_str(),
2876                  foobar_path.c_str(),
2877                  system_path.c_str(),
2878                  pk_path.c_str());
2879 
2880   ASSERT_EQ(
2881       "Footer version:           1.0\n"
2882       "Image size:               8388608 bytes\n"
2883       "Original image size:      6291456 bytes\n"
2884       "VBMeta offset:            6291456\n"
2885       "VBMeta size:              3200 bytes\n"
2886       "--\n"
2887       "Minimum libavb version:   1.0\n"
2888       "Header Block:             256 bytes\n"
2889       "Authentication Block:     320 bytes\n"
2890       "Auxiliary Block:          2624 bytes\n"
2891       "Public key (sha1):        cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
2892       "Algorithm:                SHA256_RSA2048\n"
2893       "Rollback Index:           0\n"
2894       "Flags:                    2147483648\n"
2895       "Rollback Index Location:  0\n"
2896       "Release String:           ''\n"
2897       "Descriptors:\n"
2898       "    Hash descriptor:\n"
2899       "      Image Size:            6291456 bytes\n"
2900       "      Hash Algorithm:        sha256\n"
2901       "      Partition Name:        boot\n"
2902       "      Salt:                  d00df00d\n"
2903       "      Digest:                "
2904       "4c109399b20e476bab15363bff55740add83e1c1e97e0b132f5c713ddd8c7868\n"
2905       "      Flags:                 0\n"
2906       "    Chain Partition descriptor:\n"
2907       "      Partition Name:          bazboo\n"
2908       "      Rollback Index Location: 1\n"
2909       "      Public key (sha1):       "
2910       "2597c218aae470a130f61162feaae70afd97f011\n"
2911       "      Flags:                   0\n"
2912       "    Kernel Cmdline descriptor:\n"
2913       "      Flags:                 1\n"
2914       "      Kernel Cmdline:        'dm=\"1 vroot none ro 1,0 32768 verity 1 "
2915       "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
2916       "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
2917       "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
2918       "    Kernel Cmdline descriptor:\n"
2919       "      Flags:                 2\n"
2920       "      Kernel Cmdline:        "
2921       "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
2922       "    Hashtree descriptor:\n"
2923       "      Version of dm-verity:  1\n"
2924       "      Image Size:            8388608 bytes\n"
2925       "      Tree Offset:           8388608\n"
2926       "      Tree Size:             69632 bytes\n"
2927       "      Data Block Size:       4096 bytes\n"
2928       "      Hash Block Size:       4096 bytes\n"
2929       "      FEC num roots:         0\n"
2930       "      FEC offset:            0\n"
2931       "      FEC size:              0 bytes\n"
2932       "      Hash Algorithm:        sha1\n"
2933       "      Partition Name:        foobar\n"
2934       "      Salt:                  d00df00d\n"
2935       "      Root Digest:           d52d93c988d336a79abe1c05240ae9a79a9b7d61\n"
2936       "      Flags:                 0\n"
2937       "    Hashtree descriptor:\n"
2938       "      Version of dm-verity:  1\n"
2939       "      Image Size:            16777216 bytes\n"
2940       "      Tree Offset:           16777216\n"
2941       "      Tree Size:             135168 bytes\n"
2942       "      Data Block Size:       4096 bytes\n"
2943       "      Hash Block Size:       4096 bytes\n"
2944       "      FEC num roots:         0\n"
2945       "      FEC offset:            0\n"
2946       "      FEC size:              0 bytes\n"
2947       "      Hash Algorithm:        sha1\n"
2948       "      Partition Name:        system\n"
2949       "      Salt:                  d00df00d\n"
2950       "      Root Digest:           c9ffc3bfae5000269a55a56621547fd1fcf819df\n"
2951       "      Flags:                 0\n",
2952       InfoImage(boot_path));
2953 
2954   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
2955 
2956   // Now check that libavb will fall back to reading from 'boot'
2957   // instead of 'vbmeta' when encountering
2958   // AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION on trying to read from
2959   // 'vbmeta'.
2960   AvbSlotVerifyData* slot_data = NULL;
2961   const char* requested_partitions[] = {"boot", NULL};
2962   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2963             avb_slot_verify(ops_.avb_ops(),
2964                             requested_partitions,
2965                             "",
2966                             AVB_SLOT_VERIFY_FLAGS_NONE,
2967                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2968                             &slot_data));
2969   EXPECT_NE(nullptr, slot_data);
2970   // Note 'boot' in the value androidboot.vbmeta.device since we've
2971   // read from 'boot' and not 'vbmeta'.
2972   EXPECT_EQ(
2973       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
2974       "PARTUUID=1234-fake-guid-for:system PARTUUID=1234-fake-guid-for:system "
2975       "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
2976       "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
2977       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:boot "
2978       "androidboot.vbmeta.avb_version=1.3 "
2979       "androidboot.vbmeta.device_state=locked "
2980       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=5312 "
2981       "androidboot.vbmeta.digest="
2982       "b297d90aa92a5d49725d1206ff1301b054c5a0214f1cb2fc12b809b317d943e4 "
2983       "androidboot.vbmeta.invalidate_on_error=yes "
2984       "androidboot.veritymode=enforcing",
2985       std::string(slot_data->cmdline));
2986   avb_slot_verify_data_free(slot_data);
2987 }
2988 
2989 // Check that non-zero flags in chained partition are caught in
2990 // avb_slot_verify().
TEST_F(AvbSlotVerifyTest,ChainedPartitionEnforceFlagsZero)2991 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceFlagsZero) {
2992   size_t boot_partition_size = 16 * 1024 * 1024;
2993   const size_t boot_image_size = 5 * 1024 * 1024;
2994   std::string boot_path = GenerateImage("boot_a.img", boot_image_size);
2995   const char* requested_partitions[] = {"boot", NULL};
2996 
2997   EXPECT_COMMAND(0,
2998                  "./avbtool.py add_hash_footer"
2999                  " --image %s"
3000                  " --kernel_cmdline 'cmdline2 in hash footer'"
3001                  " --rollback_index 12"
3002                  " --partition_name boot"
3003                  " --partition_size %zd"
3004                  " --algorithm SHA256_RSA4096"
3005                  " --key test/data/testkey_rsa4096.pem"
3006                  " --salt deadbeef"
3007                  " --flags 1"
3008                  " --internal_release_string \"\"",
3009                  boot_path.c_str(),
3010                  boot_partition_size);
3011 
3012   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
3013   EXPECT_COMMAND(
3014       0,
3015       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
3016       " --output %s",
3017       pk_path.c_str());
3018 
3019   GenerateVBMetaImage(
3020       "vbmeta_a.img",
3021       "SHA256_RSA2048",
3022       11,
3023       "test/data/testkey_rsa2048.pem",
3024       android::base::StringPrintf("--chain_partition boot:1:%s"
3025                                   " --kernel_cmdline 'cmdline2 in vbmeta'"
3026                                   " --internal_release_string \"\"",
3027                                   pk_path.c_str()));
3028 
3029   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
3030 
3031   AvbSlotVerifyData* slot_data = NULL;
3032   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
3033             avb_slot_verify(ops_.avb_ops(),
3034                             requested_partitions,
3035                             "_a",
3036                             AVB_SLOT_VERIFY_FLAGS_NONE,
3037                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
3038                             &slot_data));
3039   EXPECT_EQ(nullptr, slot_data);
3040 }
3041 
3042 // Check that chain descriptors in chained partitions are caught in
3043 // avb_slot_verify().
TEST_F(AvbSlotVerifyTest,ChainedPartitionEnforceNoChainPartitions)3044 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceNoChainPartitions) {
3045   size_t boot_partition_size = 16 * 1024 * 1024;
3046   const size_t boot_image_size = 5 * 1024 * 1024;
3047   std::string boot_path = GenerateImage("boot_a.img", boot_image_size);
3048   const char* requested_partitions[] = {"boot", NULL};
3049 
3050   std::filesystem::path pk_path = testdir_ / "testkey_rsa4096.avbpubkey";
3051   EXPECT_COMMAND(
3052       0,
3053       "./avbtool.py extract_public_key --key test/data/testkey_rsa4096.pem"
3054       " --output %s",
3055       pk_path.c_str());
3056 
3057   EXPECT_COMMAND(0,
3058                  "./avbtool.py add_hash_footer"
3059                  " --image %s"
3060                  " --kernel_cmdline 'cmdline2 in hash footer'"
3061                  " --rollback_index 12"
3062                  " --partition_name boot"
3063                  " --partition_size %zd"
3064                  " --algorithm SHA256_RSA4096"
3065                  " --key test/data/testkey_rsa4096.pem"
3066                  " --salt deadbeef"
3067                  " --chain_partition other:2:%s"
3068                  " --internal_release_string \"\"",
3069                  boot_path.c_str(),
3070                  boot_partition_size,
3071                  pk_path.c_str());
3072 
3073   GenerateVBMetaImage(
3074       "vbmeta_a.img",
3075       "SHA256_RSA2048",
3076       11,
3077       "test/data/testkey_rsa2048.pem",
3078       android::base::StringPrintf("--chain_partition boot:1:%s"
3079                                   " --kernel_cmdline 'cmdline2 in vbmeta'"
3080                                   " --internal_release_string \"\"",
3081                                   pk_path.c_str()));
3082 
3083   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
3084 
3085   AvbSlotVerifyData* slot_data = NULL;
3086   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
3087             avb_slot_verify(ops_.avb_ops(),
3088                             requested_partitions,
3089                             "_a",
3090                             AVB_SLOT_VERIFY_FLAGS_NONE,
3091                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
3092                             &slot_data));
3093   EXPECT_EQ(nullptr, slot_data);
3094 }
3095 
TEST_F(AvbSlotVerifyTest,HashtreeErrorModes)3096 TEST_F(AvbSlotVerifyTest, HashtreeErrorModes) {
3097   const size_t MiB = 1024 * 1024;
3098   const size_t system_size = 16 * MiB;
3099   const size_t system_part_size = 32 * MiB;
3100   std::string system_path = GenerateImage("system.img", system_size);
3101 
3102   EXPECT_COMMAND(0,
3103                  "./avbtool.py add_hashtree_footer --salt d00df00d --image %s "
3104                  "--partition_size %d --partition_name system "
3105                  "--algorithm SHA256_RSA2048 "
3106                  "--key test/data/testkey_rsa2048.pem "
3107                  "--internal_release_string \"\" "
3108                  "--do_not_generate_fec",
3109                  system_path.c_str(),
3110                  (int)system_part_size);
3111 
3112   GenerateVBMetaImage(
3113       "vbmeta.img",
3114       "SHA256_RSA2048",
3115       0,
3116       "test/data/testkey_rsa2048.pem",
3117       android::base::StringPrintf("--setup_rootfs_from_kernel %s "
3118                                   "--include_descriptors_from_image %s"
3119                                   " --internal_release_string \"\"",
3120                                   system_path.c_str(),
3121                                   system_path.c_str()));
3122 
3123   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
3124 
3125   AvbSlotVerifyData* slot_data = NULL;
3126   const char* requested_partitions[] = {"boot", NULL};
3127 
3128   // For AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE we should get
3129   // androidboot.vbmeta.invalidate_on_error=yes and
3130   // androidboot.veritymode=enforcing. We should get
3131   // 'restart_on_corruption' in the dm="..." string.
3132   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3133             avb_slot_verify(ops_.avb_ops(),
3134                             requested_partitions,
3135                             "",
3136                             AVB_SLOT_VERIFY_FLAGS_NONE,
3137                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
3138                             &slot_data));
3139   EXPECT_NE(nullptr, slot_data);
3140   EXPECT_EQ(
3141       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
3142       "PARTUUID=1234-fake-guid-for:system "
3143       "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
3144       "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
3145       "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
3146       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
3147       "androidboot.vbmeta.avb_version=1.3 "
3148       "androidboot.vbmeta.device_state=locked "
3149       "androidboot.vbmeta.hash_alg=sha256 "
3150       "androidboot.vbmeta.size=1664 "
3151       "androidboot.vbmeta.digest="
3152       "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
3153       "androidboot.vbmeta.invalidate_on_error=yes "
3154       "androidboot.veritymode=enforcing",
3155       std::string(slot_data->cmdline));
3156   avb_slot_verify_data_free(slot_data);
3157 
3158   // For AVB_HASHTREE_ERROR_MODE_RESTART we should get
3159   // androidboot.veritymode=enforcing and
3160   // androidboot.vbmeta.invalidate_on_error should be unset. We should
3161   // get 'restart_on_corruption' in the dm="..." string.
3162   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3163             avb_slot_verify(ops_.avb_ops(),
3164                             requested_partitions,
3165                             "",
3166                             AVB_SLOT_VERIFY_FLAGS_NONE,
3167                             AVB_HASHTREE_ERROR_MODE_RESTART,
3168                             &slot_data));
3169   EXPECT_NE(nullptr, slot_data);
3170   EXPECT_EQ(
3171       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
3172       "PARTUUID=1234-fake-guid-for:system "
3173       "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
3174       "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
3175       "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
3176       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
3177       "androidboot.vbmeta.avb_version=1.3 "
3178       "androidboot.vbmeta.device_state=locked "
3179       "androidboot.vbmeta.hash_alg=sha256 "
3180       "androidboot.vbmeta.size=1664 "
3181       "androidboot.vbmeta.digest="
3182       "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
3183       "androidboot.veritymode=enforcing",
3184       std::string(slot_data->cmdline));
3185   avb_slot_verify_data_free(slot_data);
3186 
3187   // For AVB_HASHTREE_ERROR_MODE_EIO we should get
3188   // androidboot.veritymode=eio and
3189   // androidboot.vbmeta.invalidate_on_error should be unset. We should
3190   // get 'ignore_zero_blocks' in the dm="..." string.
3191   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3192             avb_slot_verify(ops_.avb_ops(),
3193                             requested_partitions,
3194                             "",
3195                             AVB_SLOT_VERIFY_FLAGS_NONE,
3196                             AVB_HASHTREE_ERROR_MODE_EIO,
3197                             &slot_data));
3198   EXPECT_NE(nullptr, slot_data);
3199   EXPECT_EQ(
3200       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
3201       "PARTUUID=1234-fake-guid-for:system "
3202       "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
3203       "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
3204       "ignore_zero_blocks ignore_zero_blocks\" root=/dev/dm-0 "
3205       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
3206       "androidboot.vbmeta.avb_version=1.3 "
3207       "androidboot.vbmeta.device_state=locked "
3208       "androidboot.vbmeta.hash_alg=sha256 "
3209       "androidboot.vbmeta.size=1664 "
3210       "androidboot.vbmeta.digest="
3211       "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
3212       "androidboot.veritymode=eio",
3213       std::string(slot_data->cmdline));
3214   avb_slot_verify_data_free(slot_data);
3215 
3216   // For AVB_HASHTREE_ERROR_MODE_LOGGING we should get
3217   // androidboot.veritymode=logging and
3218   // androidboot.vbmeta.invalidate_on_error should be unset. We should
3219   // get 'ignore_corruption' in the dm="..." string.
3220   //
3221   // Check AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT is returned
3222   // unless we pass AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR.
3223   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT,
3224             avb_slot_verify(ops_.avb_ops(),
3225                             requested_partitions,
3226                             "",
3227                             AVB_SLOT_VERIFY_FLAGS_NONE,
3228                             AVB_HASHTREE_ERROR_MODE_LOGGING,
3229                             &slot_data));
3230   EXPECT_EQ(nullptr, slot_data);
3231   // --
3232   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3233             avb_slot_verify(ops_.avb_ops(),
3234                             requested_partitions,
3235                             "",
3236                             AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
3237                             AVB_HASHTREE_ERROR_MODE_LOGGING,
3238                             &slot_data));
3239   EXPECT_NE(nullptr, slot_data);
3240   EXPECT_EQ(
3241       "dm=\"1 vroot none ro 1,0 32768 verity 1 "
3242       "PARTUUID=1234-fake-guid-for:system "
3243       "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
3244       "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
3245       "ignore_corruption ignore_zero_blocks\" root=/dev/dm-0 "
3246       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
3247       "androidboot.vbmeta.avb_version=1.3 "
3248       "androidboot.vbmeta.device_state=locked "
3249       "androidboot.vbmeta.hash_alg=sha256 "
3250       "androidboot.vbmeta.size=1664 "
3251       "androidboot.vbmeta.digest="
3252       "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
3253       "androidboot.veritymode=logging",
3254       std::string(slot_data->cmdline));
3255   avb_slot_verify_data_free(slot_data);
3256 
3257   // Check we'll get androidboot.veritymode=disabled for any
3258   // |hashtree_error_mode| if dm-verity is disabled.
3259   GenerateVBMetaImage(
3260       "vbmeta.img",
3261       "SHA256_RSA2048",
3262       0,
3263       "test/data/testkey_rsa2048.pem",
3264       android::base::StringPrintf("--setup_rootfs_from_kernel %s "
3265                                   "--include_descriptors_from_image %s "
3266                                   "--set_hashtree_disabled_flag "
3267                                   "--internal_release_string \"\"",
3268                                   system_path.c_str(),
3269                                   system_path.c_str()));
3270   for (int n = 0; n < 4; n++) {
3271     AvbHashtreeErrorMode modes[4] = {
3272         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
3273         AVB_HASHTREE_ERROR_MODE_RESTART,
3274         AVB_HASHTREE_ERROR_MODE_EIO,
3275         AVB_HASHTREE_ERROR_MODE_LOGGING};
3276     EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3277               avb_slot_verify(ops_.avb_ops(),
3278                               requested_partitions,
3279                               "",
3280                               AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
3281                               modes[n],
3282                               &slot_data));
3283     EXPECT_NE(nullptr, slot_data);
3284     EXPECT_EQ(
3285         "root=PARTUUID=1234-fake-guid-for:system "
3286         "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
3287         "androidboot.vbmeta.avb_version=1.3 "
3288         "androidboot.vbmeta.device_state=locked "
3289         "androidboot.vbmeta.hash_alg=sha256 "
3290         "androidboot.vbmeta.size=1664 "
3291         "androidboot.vbmeta.digest="
3292         "e73a466d63f451dcf5c051ff12a32c006ba282a34b37420c0d563f0282cad703 "
3293         "androidboot.veritymode=disabled",
3294         std::string(slot_data->cmdline));
3295     avb_slot_verify_data_free(slot_data);
3296   }
3297 }
3298 
3299 class AvbSlotVerifyTestWithPersistentDigest : public AvbSlotVerifyTest {
3300  protected:
SetupWithHashDescriptor(bool do_not_use_ab=true)3301   void SetupWithHashDescriptor(bool do_not_use_ab = true) {
3302     const size_t factory_partition_size = 16 * 1024 * 1024;
3303     const size_t factory_image_size = 5 * 1024 * 1024;
3304     std::string factory_path = GenerateImage("factory.img", factory_image_size);
3305 
3306     EXPECT_COMMAND(0,
3307                    "./avbtool.py add_hash_footer"
3308                    " --image %s"
3309                    " --rollback_index 0"
3310                    " --partition_name factory"
3311                    " --partition_size %zd"
3312                    " --internal_release_string \"\""
3313                    " --use_persistent_digest %s",
3314                    factory_path.c_str(),
3315                    factory_partition_size,
3316                    do_not_use_ab ? "--do_not_use_ab" : "");
3317 
3318     GenerateVBMetaImage(
3319         "vbmeta_a.img",
3320         "SHA256_RSA2048",
3321         0,
3322         "test/data/testkey_rsa2048.pem",
3323         android::base::StringPrintf("--internal_release_string \"\" "
3324                                     "--include_descriptors_from_image %s ",
3325                                     factory_path.c_str()));
3326 
3327     EXPECT_EQ(android::base::StringPrintf(
3328                   "Minimum libavb version:   1.1\n"
3329                   "Header Block:             256 bytes\n"
3330                   "Authentication Block:     320 bytes\n"
3331                   "Auxiliary Block:          704 bytes\n"
3332                   "Public key (sha1):        "
3333                   "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
3334                   "Algorithm:                SHA256_RSA2048\n"
3335                   "Rollback Index:           0\n"
3336                   "Flags:                    0\n"
3337                   "Rollback Index Location:  0\n"
3338                   "Release String:           ''\n"
3339                   "Descriptors:\n"
3340                   "    Hash descriptor:\n"
3341                   "      Image Size:            5242880 bytes\n"
3342                   "      Hash Algorithm:        sha256\n"
3343                   "      Partition Name:        factory\n"
3344                   "      Salt:                  \n"
3345                   "      Digest:                \n"
3346                   "      Flags:                 %d\n",
3347                   do_not_use_ab ? 1 : 0),
3348               InfoImage(vbmeta_image_path_.string()));
3349 
3350     ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
3351   }
3352 
SetupWithHashtreeDescriptor(bool do_not_use_ab=true)3353   void SetupWithHashtreeDescriptor(bool do_not_use_ab = true) {
3354     const size_t factory_partition_size = 16 * 1024 * 1024;
3355     const size_t factory_image_size = 5 * 1024 * 1024;
3356     std::string factory_path = GenerateImage("factory.img", factory_image_size);
3357 
3358     EXPECT_COMMAND(
3359         0,
3360         "./avbtool.py add_hashtree_footer"
3361         " --image %s"
3362         " --rollback_index 0"
3363         " --partition_name factory"
3364         " --partition_size %zd"
3365         " --hash_algorithm %s"
3366         " --internal_release_string \"\""
3367         " --kernel_cmdline "
3368         "'androidboot.vbmeta.root_digest.factory=$(AVB_FACTORY_ROOT_DIGEST)'"
3369         " --use_persistent_digest %s",
3370         factory_path.c_str(),
3371         factory_partition_size,
3372         verity_hash_algorithm_.c_str(),
3373         do_not_use_ab ? "--do_not_use_ab" : "");
3374 
3375     GenerateVBMetaImage(
3376         "vbmeta_a.img",
3377         "SHA256_RSA2048",
3378         0,
3379         "test/data/testkey_rsa2048.pem",
3380         android::base::StringPrintf("--internal_release_string \"\" "
3381                                     "--include_descriptors_from_image %s ",
3382                                     factory_path.c_str()));
3383 
3384     int expected_tree_size =
3385         (verity_hash_algorithm_ == "sha512") ? 86016 : 45056;
3386     int expected_fec_offset =
3387         (verity_hash_algorithm_ == "sha512") ? 5328896 : 5287936;
3388     EXPECT_EQ(android::base::StringPrintf(
3389                   "Minimum libavb version:   1.1\n"
3390                   "Header Block:             256 bytes\n"
3391                   "Authentication Block:     320 bytes\n"
3392                   "Auxiliary Block:          832 bytes\n"
3393                   "Public key (sha1):        "
3394                   "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
3395                   "Algorithm:                SHA256_RSA2048\n"
3396                   "Rollback Index:           0\n"
3397                   "Flags:                    0\n"
3398                   "Rollback Index Location:  0\n"
3399                   "Release String:           ''\n"
3400                   "Descriptors:\n"
3401                   "    Kernel Cmdline descriptor:\n"
3402                   "      Flags:                 0\n"
3403                   "      Kernel Cmdline:        "
3404                   "'androidboot.vbmeta.root_digest.factory=$("
3405                   "AVB_FACTORY_ROOT_DIGEST)'\n"
3406                   "    Hashtree descriptor:\n"
3407                   "      Version of dm-verity:  1\n"
3408                   "      Image Size:            5242880 bytes\n"
3409                   "      Tree Offset:           5242880\n"
3410                   "      Tree Size:             %d bytes\n"
3411                   "      Data Block Size:       4096 bytes\n"
3412                   "      Hash Block Size:       4096 bytes\n"
3413                   "      FEC num roots:         2\n"
3414                   "      FEC offset:            %d\n"
3415                   "      FEC size:              49152 bytes\n"
3416                   "      Hash Algorithm:        %s\n"
3417                   "      Partition Name:        factory\n"
3418                   "      Salt:                  \n"
3419                   "      Root Digest:           \n"
3420                   "      Flags:                 %d\n",
3421                   expected_tree_size,
3422                   expected_fec_offset,
3423                   verity_hash_algorithm_.c_str(),
3424                   do_not_use_ab ? 1 : 0),
3425               InfoImage(vbmeta_image_path_.string()));
3426 
3427     ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
3428   }
3429 
Verify(bool expect_success)3430   void Verify(bool expect_success) {
3431     AvbSlotVerifyData* slot_data = NULL;
3432     const char* requested_partitions[] = {"factory", NULL};
3433     AvbSlotVerifyResult result =
3434         avb_slot_verify(ops_.avb_ops(),
3435                         requested_partitions,
3436                         "_a",
3437                         AVB_SLOT_VERIFY_FLAGS_NONE,
3438                         AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
3439                         &slot_data);
3440     if (expect_success) {
3441       ASSERT_EQ(AVB_SLOT_VERIFY_RESULT_OK, result);
3442       ASSERT_NE(nullptr, slot_data);
3443       last_cmdline_ = slot_data->cmdline;
3444       avb_slot_verify_data_free(slot_data);
3445     } else {
3446       EXPECT_NE(AVB_SLOT_VERIFY_RESULT_OK, result);
3447       EXPECT_EQ(nullptr, slot_data);
3448       if (expected_error_code_ != AVB_SLOT_VERIFY_RESULT_OK) {
3449         EXPECT_EQ(expected_error_code_, result);
3450       }
3451     }
3452   }
3453 
3454   std::string last_cmdline_;
3455   std::string verity_hash_algorithm_{"sha1"};
3456   AvbSlotVerifyResult expected_error_code_{AVB_SLOT_VERIFY_RESULT_OK};
3457 
3458  public:
3459   // Persistent digests always use AVB_NPV_PERSISTENT_DIGEST_PREFIX followed by
3460   // the partition name.
3461   const char* kPersistentValueName = "avb.persistent_digest.factory";
3462   // The digest for the hash descriptor which matches the factory contents.
3463   const uint8_t kDigest[AVB_SHA256_DIGEST_SIZE] = {
3464       0x2e, 0x7c, 0xab, 0x63, 0x14, 0xe9, 0x61, 0x4b, 0x6f, 0x2d, 0xa1,
3465       0x26, 0x30, 0x66, 0x1c, 0x30, 0x38, 0xe5, 0x59, 0x20, 0x25, 0xf6,
3466       0x53, 0x4b, 0xa5, 0x82, 0x3c, 0x3b, 0x34, 0x0a, 0x1c, 0xb6};
3467 };
3468 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic)3469 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic) {
3470   SetupWithHashDescriptor();
3471   // Store the expected image digest as a persistent value.
3472   ops_.write_persistent_value(
3473       kPersistentValueName, AVB_SHA256_DIGEST_SIZE, kDigest);
3474   Verify(true /* expect_success */);
3475   EXPECT_EQ(
3476       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
3477       "androidboot.vbmeta.avb_version=1.3 "
3478       "androidboot.vbmeta.device_state=locked "
3479       "androidboot.vbmeta.hash_alg=sha256 "
3480       "androidboot.vbmeta.size=1280 "
3481       "androidboot.vbmeta.digest="
3482       "f7a4ce48092379fe0e913ffda10d859cd5fc19fa721c9e81f05f8bfea14b9873 "
3483       "androidboot.vbmeta.invalidate_on_error=yes "
3484       "androidboot.veritymode=enforcing",
3485       last_cmdline_);
3486 }
3487 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic_WithAB)3488 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_WithAB) {
3489   SetupWithHashDescriptor(false /* do_not_use_ab */);
3490   // Store the expected image digest as a persistent value.
3491   ops_.write_persistent_value(
3492       kPersistentValueName, AVB_SHA256_DIGEST_SIZE, kDigest);
3493   Verify(false /* expect_success */);
3494 }
3495 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic_WithAutoInit)3496 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_WithAutoInit) {
3497   SetupWithHashDescriptor();
3498   // Explicitly do not write any digest as a persistent value.
3499   Verify(true /* expect_success */);
3500 }
3501 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic_WithNoAutoInit)3502 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_WithNoAutoInit) {
3503   SetupWithHashDescriptor();
3504   // Explicitly do not write any digest as a persistent value.
3505   // Set device as unlocked so that auto persistent digest initialization does
3506   // not occur.
3507   ops_.set_stored_is_device_unlocked(true);
3508   Verify(false /* expect_success */);
3509 }
3510 
3511 class AvbSlotVerifyTestWithPersistentDigest_InvalidDigestLength
3512     : public AvbSlotVerifyTestWithPersistentDigest,
3513       public ::testing::WithParamInterface<size_t> {};
3514 
TEST_P(AvbSlotVerifyTestWithPersistentDigest_InvalidDigestLength,Param)3515 TEST_P(AvbSlotVerifyTestWithPersistentDigest_InvalidDigestLength, Param) {
3516   SetupWithHashDescriptor();
3517   // Store a digest value with the given length.
3518   ops_.write_persistent_value(kPersistentValueName, GetParam(), kDigest);
3519   expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
3520   Verify(false /* expect_success */);
3521 }
3522 
3523 // Test a bunch of invalid digest length values.
3524 INSTANTIATE_TEST_CASE_P(
3525     P,
3526     AvbSlotVerifyTestWithPersistentDigest_InvalidDigestLength,
3527     ::testing::Values(AVB_SHA256_DIGEST_SIZE + 1,
3528                       AVB_SHA256_DIGEST_SIZE - 1,
3529                       0,
3530                       AVB_SHA512_DIGEST_SIZE));
3531 
3532 class AvbSlotVerifyTestWithPersistentDigest_InvalidPersistentValueName
3533     : public AvbSlotVerifyTestWithPersistentDigest,
3534       public ::testing::WithParamInterface<const char*> {
3535   // FakeAvbOpsDelegate override.
write_persistent_value(const char * name,size_t value_size,const uint8_t * value)3536   AvbIOResult write_persistent_value(const char* name,
3537                                      size_t value_size,
3538                                      const uint8_t* value) override {
3539     // Fail attempted initialization with any name not under test.
3540     if (std::string(name) != GetParam()) {
3541       return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
3542     }
3543     return ops_.write_persistent_value(name, value_size, value);
3544   }
3545 };
3546 
TEST_P(AvbSlotVerifyTestWithPersistentDigest_InvalidPersistentValueName,Param)3547 TEST_P(AvbSlotVerifyTestWithPersistentDigest_InvalidPersistentValueName,
3548        Param) {
3549   SetupWithHashDescriptor();
3550   ops_.write_persistent_value(GetParam(), AVB_SHA256_DIGEST_SIZE, kDigest);
3551   Verify(false /* expect_success */);
3552 }
3553 
3554 // Test a bunch of invalid persistent value names.
3555 INSTANTIATE_TEST_CASE_P(
3556     P,
3557     AvbSlotVerifyTestWithPersistentDigest_InvalidPersistentValueName,
3558     ::testing::Values(
3559         "",
3560         "avb.persistent_digest.factory0",
3561         "avb.persistent_digest.factor",
3562         "loooooooooooooooooooooooooooooooooooooooooooooongvalue"));
3563 
3564 class AvbSlotVerifyTestWithPersistentDigest_ReadDigestFailure
3565     : public AvbSlotVerifyTestWithPersistentDigest,
3566       public ::testing::WithParamInterface<AvbIOResult> {
3567   // FakeAvbOpsDelegate overrides.
read_persistent_value(const char * name,size_t buffer_size,uint8_t * out_buffer,size_t * out_num_bytes_read)3568   AvbIOResult read_persistent_value(const char* name,
3569                                     size_t buffer_size,
3570                                     uint8_t* out_buffer,
3571                                     size_t* out_num_bytes_read) override {
3572     return GetParam();
3573   }
3574 };
3575 
TEST_P(AvbSlotVerifyTestWithPersistentDigest_ReadDigestFailure,Param)3576 TEST_P(AvbSlotVerifyTestWithPersistentDigest_ReadDigestFailure, Param) {
3577   SetupWithHashDescriptor();
3578   // Set device as unlocked so that auto persistent digest initialization does
3579   // not occur.
3580   ops_.set_stored_is_device_unlocked(true);
3581   switch (GetParam()) {
3582     case AVB_IO_RESULT_ERROR_OOM:
3583       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
3584       break;
3585     case AVB_IO_RESULT_ERROR_IO:
3586       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
3587       break;
3588     case AVB_IO_RESULT_ERROR_NO_SUCH_VALUE:
3589       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
3590       break;
3591     // Fall through.
3592     case AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE:
3593     case AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE:
3594       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
3595       break;
3596     default:
3597       break;
3598   }
3599   Verify(false /* expect_success */);
3600 }
3601 
3602 // Test a bunch of error codes.
3603 INSTANTIATE_TEST_CASE_P(
3604     P,
3605     AvbSlotVerifyTestWithPersistentDigest_ReadDigestFailure,
3606     ::testing::Values(AVB_IO_RESULT_ERROR_OOM,
3607                       AVB_IO_RESULT_ERROR_IO,
3608                       AVB_IO_RESULT_ERROR_NO_SUCH_VALUE,
3609                       AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE,
3610                       AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE));
3611 
3612 class AvbSlotVerifyTestWithPersistentDigest_AutoInitDigestFailure
3613     : public AvbSlotVerifyTestWithPersistentDigest,
3614       public ::testing::WithParamInterface<AvbIOResult> {
3615   // FakeAvbOpsDelegate overrides.
read_persistent_value(const char * name,size_t buffer_size,uint8_t * out_buffer,size_t * out_num_bytes_read)3616   AvbIOResult read_persistent_value(const char* name,
3617                                     size_t buffer_size,
3618                                     uint8_t* out_buffer,
3619                                     size_t* out_num_bytes_read) override {
3620     // Auto digest initialization only occurs when read returns NO_SUCH_VALUE
3621     return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE;
3622   }
write_persistent_value(const char * name,size_t value_size,const uint8_t * value)3623   AvbIOResult write_persistent_value(const char* name,
3624                                      size_t value_size,
3625                                      const uint8_t* value) override {
3626     return GetParam();
3627   }
3628 };
3629 
TEST_P(AvbSlotVerifyTestWithPersistentDigest_AutoInitDigestFailure,Param)3630 TEST_P(AvbSlotVerifyTestWithPersistentDigest_AutoInitDigestFailure, Param) {
3631   SetupWithHashDescriptor();
3632   // Set device as locked so that auto persistent digest initialization occurs.
3633   ops_.set_stored_is_device_unlocked(false);
3634   switch (GetParam()) {
3635     case AVB_IO_RESULT_OK:
3636       // This tests the case where the write appears to succeed, but the
3637       // read-back after it still fails.
3638       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
3639       break;
3640     case AVB_IO_RESULT_ERROR_OOM:
3641       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
3642       break;
3643     // Fall through.
3644     case AVB_IO_RESULT_ERROR_IO:
3645     case AVB_IO_RESULT_ERROR_NO_SUCH_VALUE:
3646     case AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE:
3647     case AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE:
3648       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
3649       break;
3650     default:
3651       break;
3652   }
3653   Verify(false /* expect_success */);
3654 }
3655 
3656 // Test a bunch of error codes.
3657 INSTANTIATE_TEST_CASE_P(
3658     P,
3659     AvbSlotVerifyTestWithPersistentDigest_AutoInitDigestFailure,
3660     ::testing::Values(AVB_IO_RESULT_OK,
3661                       AVB_IO_RESULT_ERROR_OOM,
3662                       AVB_IO_RESULT_ERROR_IO,
3663                       AVB_IO_RESULT_ERROR_NO_SUCH_VALUE,
3664                       AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE,
3665                       AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE));
3666 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic_Hashtree_Sha1)3667 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_Sha1) {
3668   verity_hash_algorithm_ = "sha1";
3669   SetupWithHashtreeDescriptor();
3670   // Store an arbitrary image digest.
3671   uint8_t fake_digest[]{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3672                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3673                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
3674   ops_.write_persistent_value(
3675       kPersistentValueName, AVB_SHA1_DIGEST_SIZE, fake_digest);
3676   Verify(true /* expect_success */);
3677   EXPECT_EQ(
3678       "androidboot.vbmeta.root_digest.factory="
3679       // Note: Here appear the bytes used in write_persistent_value above.
3680       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "
3681       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
3682       "androidboot.vbmeta.avb_version=1.3 "
3683       "androidboot.vbmeta.device_state=locked "
3684       "androidboot.vbmeta.hash_alg=sha256 "
3685       "androidboot.vbmeta.size=1408 "
3686       "androidboot.vbmeta.digest="
3687       "eeaa2fb8deb48b9645f817bb6a6ce05ba3ef92d0d2d9c950c2383853cd4a3064 "
3688       "androidboot.vbmeta.invalidate_on_error=yes "
3689       "androidboot.veritymode=enforcing",
3690       last_cmdline_);
3691 }
3692 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic_Hashtree_Sha256)3693 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_Sha256) {
3694   verity_hash_algorithm_ = "sha256";
3695   SetupWithHashtreeDescriptor();
3696   // Store an arbitrary image digest.
3697   uint8_t fake_digest[]{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3698                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3699                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3700                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
3701   ops_.write_persistent_value(
3702       kPersistentValueName, AVB_SHA256_DIGEST_SIZE, fake_digest);
3703   Verify(true /* expect_success */);
3704   EXPECT_EQ(
3705       "androidboot.vbmeta.root_digest.factory="
3706       // Note: Here appear the bytes used in write_persistent_value above.
3707       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "
3708       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
3709       "androidboot.vbmeta.avb_version=1.3 "
3710       "androidboot.vbmeta.device_state=locked "
3711       "androidboot.vbmeta.hash_alg=sha256 "
3712       "androidboot.vbmeta.size=1408 "
3713       "androidboot.vbmeta.digest="
3714       "d3f35ef7a0812d8328be7850003b2c5607b673d0aede641656c9c04fa7992d40 "
3715       "androidboot.vbmeta.invalidate_on_error=yes "
3716       "androidboot.veritymode=enforcing",
3717       last_cmdline_);
3718 }
3719 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic_Hashtree_Sha512)3720 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_Sha512) {
3721   verity_hash_algorithm_ = "sha512";
3722   SetupWithHashtreeDescriptor();
3723   // Store an arbitrary image digest.
3724   uint8_t fake_digest[]{
3725       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3726       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3727       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3728       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3729       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3730       0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
3731   ops_.write_persistent_value(
3732       kPersistentValueName, AVB_SHA512_DIGEST_SIZE, fake_digest);
3733   Verify(true /* expect_success */);
3734   EXPECT_EQ(
3735       "androidboot.vbmeta.root_digest.factory="
3736       // Note: Here appear the bytes used in write_persistent_value above.
3737       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
3738       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "
3739       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
3740       "androidboot.vbmeta.avb_version=1.3 "
3741       "androidboot.vbmeta.device_state=locked "
3742       "androidboot.vbmeta.hash_alg=sha256 "
3743       "androidboot.vbmeta.size=1408 "
3744       "androidboot.vbmeta.digest="
3745       "d6ea8d50dce5ca6d38ea6e780bb5b5d7ee588b53a92020ad3d1c99018f3e5f52 "
3746       "androidboot.vbmeta.invalidate_on_error=yes "
3747       "androidboot.veritymode=enforcing",
3748       last_cmdline_);
3749 }
3750 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic_Hashtree_WithAB)3751 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_WithAB) {
3752   verity_hash_algorithm_ = "sha1";
3753   SetupWithHashtreeDescriptor(false /* do_not_use_ab */);
3754   // Store an arbitrary image digest.
3755   uint8_t fake_digest[]{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3756                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
3757                         0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
3758   ops_.write_persistent_value(
3759       kPersistentValueName, AVB_SHA1_DIGEST_SIZE, fake_digest);
3760   Verify(false /* expect_success */);
3761 }
3762 
TEST_F(AvbSlotVerifyTestWithPersistentDigest,Basic_Hashtree_NoAutoInit)3763 TEST_F(AvbSlotVerifyTestWithPersistentDigest, Basic_Hashtree_NoAutoInit) {
3764   verity_hash_algorithm_ = "sha1";
3765   SetupWithHashtreeDescriptor();
3766   // Explicitly do not store any persistent digest.
3767   Verify(false /* expect_success */);
3768 }
3769 
3770 class AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidDigestLength
3771     : public AvbSlotVerifyTestWithPersistentDigest,
3772       public ::testing::WithParamInterface<size_t> {};
3773 
TEST_P(AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidDigestLength,Param)3774 TEST_P(AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidDigestLength,
3775        Param) {
3776   SetupWithHashtreeDescriptor();
3777   // Store a digest value with the given length.
3778   ops_.write_persistent_value(kPersistentValueName, GetParam(), kDigest);
3779   Verify(false /* expect_success */);
3780 }
3781 
3782 // Test a bunch of invalid digest length values.
3783 INSTANTIATE_TEST_CASE_P(
3784     P,
3785     AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidDigestLength,
3786     ::testing::Values(AVB_SHA1_DIGEST_SIZE + 1,
3787                       AVB_SHA1_DIGEST_SIZE - 1,
3788                       0,
3789                       AVB_SHA256_DIGEST_SIZE,
3790                       AVB_SHA512_DIGEST_SIZE));
3791 
3792 class AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidPersistentValueName
3793     : public AvbSlotVerifyTestWithPersistentDigest,
3794       public ::testing::WithParamInterface<const char*> {};
3795 
TEST_P(AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidPersistentValueName,Param)3796 TEST_P(
3797     AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidPersistentValueName,
3798     Param) {
3799   SetupWithHashtreeDescriptor();
3800   ops_.write_persistent_value(GetParam(), AVB_SHA256_DIGEST_SIZE, kDigest);
3801   Verify(false /* expect_success */);
3802 }
3803 
3804 // Test a bunch of invalid persistent value names.
3805 INSTANTIATE_TEST_CASE_P(
3806     P,
3807     AvbSlotVerifyTestWithPersistentDigest_Hashtree_InvalidPersistentValueName,
3808     ::testing::Values(
3809         "",
3810         "avb.persistent_digest.factory0",
3811         "avb.persistent_digest.factor",
3812         "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
3813         "oooooooooooooooooooooooooooooooooooooooooooooooooooongvalue"));
3814 
3815 class AvbSlotVerifyTestWithPersistentDigest_Hashtree_ReadDigestFailure
3816     : public AvbSlotVerifyTestWithPersistentDigest,
3817       public ::testing::WithParamInterface<AvbIOResult> {
3818   // FakeAvbOpsDelegate override.
read_persistent_value(const char * name,size_t buffer_size,uint8_t * out_buffer,size_t * out_num_bytes_read)3819   AvbIOResult read_persistent_value(const char* name,
3820                                     size_t buffer_size,
3821                                     uint8_t* out_buffer,
3822                                     size_t* out_num_bytes_read) override {
3823     return GetParam();
3824   }
3825 };
3826 
TEST_P(AvbSlotVerifyTestWithPersistentDigest_Hashtree_ReadDigestFailure,Param)3827 TEST_P(AvbSlotVerifyTestWithPersistentDigest_Hashtree_ReadDigestFailure,
3828        Param) {
3829   SetupWithHashtreeDescriptor();
3830   ops_.write_persistent_value(
3831       kPersistentValueName, AVB_SHA256_DIGEST_SIZE, kDigest);
3832   switch (GetParam()) {
3833     case AVB_IO_RESULT_ERROR_OOM:
3834       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
3835       break;
3836     case AVB_IO_RESULT_ERROR_IO:
3837       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
3838       break;
3839     case AVB_IO_RESULT_ERROR_NO_SUCH_VALUE:
3840       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
3841       break;
3842     // Fall through.
3843     case AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE:
3844     case AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE:
3845       expected_error_code_ = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA;
3846       break;
3847     default:
3848       break;
3849   }
3850   Verify(false /* expect_success */);
3851 }
3852 
3853 // Test a bunch of error codes.
3854 INSTANTIATE_TEST_CASE_P(
3855     P,
3856     AvbSlotVerifyTestWithPersistentDigest_Hashtree_ReadDigestFailure,
3857     ::testing::Values(AVB_IO_RESULT_ERROR_OOM,
3858                       AVB_IO_RESULT_ERROR_IO,
3859                       AVB_IO_RESULT_ERROR_NO_SUCH_VALUE,
3860                       AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE,
3861                       AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE));
3862 
TEST_F(AvbSlotVerifyTest,ManagedVerityMode)3863 TEST_F(AvbSlotVerifyTest, ManagedVerityMode) {
3864   GenerateVBMetaImage("vbmeta.img",
3865                       "SHA256_RSA2048",
3866                       0,
3867                       "test/data/testkey_rsa2048.pem",
3868                       "--internal_release_string \"\"");
3869 
3870   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
3871 
3872   AvbSlotVerifyData* slot_data = NULL;
3873   const char* requested_partitions[] = {"boot", NULL};
3874 
3875   // run 1: initial boot -> should be in non-'eio' mode
3876   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3877             avb_slot_verify(ops_.avb_ops(),
3878                             requested_partitions,
3879                             "",
3880                             AVB_SLOT_VERIFY_FLAGS_NONE,
3881                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
3882                             &slot_data));
3883   EXPECT_NE(nullptr, slot_data);
3884   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_RESTART,
3885             slot_data->resolved_hashtree_error_mode);
3886   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=enforcing") !=
3887               nullptr);
3888   EXPECT_TRUE(strstr(slot_data->cmdline,
3889                      "androidboot.veritymode.managed=yes") != nullptr);
3890   avb_slot_verify_data_free(slot_data);
3891 
3892   // run 2: second boot without dm-verity error -> should still be in non-'eio'
3893   // mode
3894   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3895             avb_slot_verify(ops_.avb_ops(),
3896                             requested_partitions,
3897                             "",
3898                             AVB_SLOT_VERIFY_FLAGS_NONE,
3899                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
3900                             &slot_data));
3901   EXPECT_NE(nullptr, slot_data);
3902   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_RESTART,
3903             slot_data->resolved_hashtree_error_mode);
3904   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=enforcing") !=
3905               nullptr);
3906   EXPECT_TRUE(strstr(slot_data->cmdline,
3907                      "androidboot.veritymode.managed=yes") != nullptr);
3908   avb_slot_verify_data_free(slot_data);
3909 
3910   // run 3: Reboot after dm-verity error -> should be in 'eio' mode
3911   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3912             avb_slot_verify(
3913                 ops_.avb_ops(),
3914                 requested_partitions,
3915                 "",
3916                 AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION,
3917                 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
3918                 &slot_data));
3919   EXPECT_NE(nullptr, slot_data);
3920   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_EIO,
3921             slot_data->resolved_hashtree_error_mode);
3922   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=eio") !=
3923               nullptr);
3924   EXPECT_TRUE(strstr(slot_data->cmdline,
3925                      "androidboot.veritymode.managed=yes") != nullptr);
3926   avb_slot_verify_data_free(slot_data);
3927 
3928   // run 4: Reboot again.. no dm-verity error but check still in 'eio' mode
3929   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3930             avb_slot_verify(ops_.avb_ops(),
3931                             requested_partitions,
3932                             "",
3933                             AVB_SLOT_VERIFY_FLAGS_NONE,
3934                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
3935                             &slot_data));
3936   EXPECT_NE(nullptr, slot_data);
3937   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_EIO,
3938             slot_data->resolved_hashtree_error_mode);
3939   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=eio") !=
3940               nullptr);
3941   EXPECT_TRUE(strstr(slot_data->cmdline,
3942                      "androidboot.veritymode.managed=yes") != nullptr);
3943   avb_slot_verify_data_free(slot_data);
3944 
3945   // run 5: Reboot again.. with dm-verity error, check still in 'eio' mode
3946   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3947             avb_slot_verify(
3948                 ops_.avb_ops(),
3949                 requested_partitions,
3950                 "",
3951                 AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION,
3952                 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
3953                 &slot_data));
3954   EXPECT_NE(nullptr, slot_data);
3955   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_EIO,
3956             slot_data->resolved_hashtree_error_mode);
3957   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=eio") !=
3958               nullptr);
3959   EXPECT_TRUE(strstr(slot_data->cmdline,
3960                      "androidboot.veritymode.managed=yes") != nullptr);
3961   avb_slot_verify_data_free(slot_data);
3962 
3963   // run 6: Reboot again.. no dm-verity error but check still in 'eio' mode
3964   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3965             avb_slot_verify(ops_.avb_ops(),
3966                             requested_partitions,
3967                             "",
3968                             AVB_SLOT_VERIFY_FLAGS_NONE,
3969                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
3970                             &slot_data));
3971   EXPECT_NE(nullptr, slot_data);
3972   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_EIO,
3973             slot_data->resolved_hashtree_error_mode);
3974   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=eio") !=
3975               nullptr);
3976   EXPECT_TRUE(strstr(slot_data->cmdline,
3977                      "androidboot.veritymode.managed=yes") != nullptr);
3978   avb_slot_verify_data_free(slot_data);
3979 
3980   // This simulates changing the OS underneath!
3981   GenerateVBMetaImage("vbmeta.img",
3982                       "SHA256_RSA2048",
3983                       0,
3984                       "test/data/testkey_rsa2048.pem",
3985                       "--internal_release_string \"\" --prop key:value");
3986 
3987   // run 7: Reboot again, but this time the OS changed underneath.. check
3988   // that we go back to non-'eio' mode.
3989   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
3990             avb_slot_verify(ops_.avb_ops(),
3991                             requested_partitions,
3992                             "",
3993                             AVB_SLOT_VERIFY_FLAGS_NONE,
3994                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
3995                             &slot_data));
3996   EXPECT_NE(nullptr, slot_data);
3997   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_RESTART,
3998             slot_data->resolved_hashtree_error_mode);
3999   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=enforcing") !=
4000               nullptr);
4001   EXPECT_TRUE(strstr(slot_data->cmdline,
4002                      "androidboot.veritymode.managed=yes") != nullptr);
4003   avb_slot_verify_data_free(slot_data);
4004 
4005   // run 8: subsequent boot without dm-verity error -> should still be in
4006   // non-'eio' mode
4007   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
4008             avb_slot_verify(ops_.avb_ops(),
4009                             requested_partitions,
4010                             "",
4011                             AVB_SLOT_VERIFY_FLAGS_NONE,
4012                             AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
4013                             &slot_data));
4014   EXPECT_NE(nullptr, slot_data);
4015   EXPECT_EQ(AVB_HASHTREE_ERROR_MODE_RESTART,
4016             slot_data->resolved_hashtree_error_mode);
4017   EXPECT_TRUE(strstr(slot_data->cmdline, "androidboot.veritymode=enforcing") !=
4018               nullptr);
4019   EXPECT_TRUE(strstr(slot_data->cmdline,
4020                      "androidboot.veritymode.managed=yes") != nullptr);
4021   avb_slot_verify_data_free(slot_data);
4022 }
4023 
TEST_F(AvbSlotVerifyTest,NoSystemPartition)4024 TEST_F(AvbSlotVerifyTest, NoSystemPartition) {
4025   GenerateVBMetaImage("vbmeta_a.img",
4026                       "SHA256_RSA2048",
4027                       0,
4028                       "test/data/testkey_rsa2048.pem",
4029                       "--internal_release_string \"\"");
4030 
4031   ops_.set_expected_public_key(PublicKeyAVB("test/data/testkey_rsa2048.pem"));
4032   ops_.set_hidden_partitions({"system_a"});
4033 
4034   AvbSlotVerifyData* slot_data = NULL;
4035   const char* requested_partitions[] = {"boot", NULL};
4036   EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
4037             avb_slot_verify(ops_.avb_ops(),
4038                             requested_partitions,
4039                             "_a",
4040                             AVB_SLOT_VERIFY_FLAGS_NONE,
4041                             AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
4042                             &slot_data));
4043   EXPECT_NE(nullptr, slot_data);
4044   EXPECT_EQ(
4045       "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
4046       "androidboot.vbmeta.avb_version=1.3 "
4047       "androidboot.vbmeta.device_state=locked "
4048       "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
4049       "androidboot.vbmeta.digest="
4050       "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
4051       "androidboot.vbmeta.invalidate_on_error=yes "
4052       "androidboot.veritymode=enforcing",
4053       std::string(slot_data->cmdline));
4054 
4055   avb_slot_verify_data_free(slot_data);
4056 }
4057 
4058 }  // namespace avb
4059