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