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