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