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