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:
AvbSlotVerifyTest()38 AvbSlotVerifyTest() {}
39
SetUp()40 virtual void SetUp() override {
41 BaseAvbToolTest::SetUp();
42 ops_.set_partition_dir(testdir_);
43 ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}, {2, 0}, {3, 0}});
44 ops_.set_stored_is_device_unlocked(false);
45 }
46
47 void CmdlineWithHashtreeVerification(bool hashtree_verification_on);
48 void CmdlineWithChainedHashtreeVerification(bool hashtree_verification_on);
49 void VerificationDisabled(bool use_avbctl);
50
51 FakeAvbOps ops_;
52 };
53
TEST_F(AvbSlotVerifyTest,Basic)54 TEST_F(AvbSlotVerifyTest, Basic) {
55 GenerateVBMetaImage("vbmeta_a.img",
56 "SHA256_RSA2048",
57 0,
58 base::FilePath("test/data/testkey_rsa2048.pem"),
59 "--internal_release_string \"\"");
60
61 ops_.set_expected_public_key(
62 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
63
64 AvbSlotVerifyData* slot_data = NULL;
65 const char* requested_partitions[] = {"boot", NULL};
66 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
67 avb_slot_verify(ops_.avb_ops(),
68 requested_partitions,
69 "_a",
70 AVB_SLOT_VERIFY_FLAGS_NONE,
71 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
72 &slot_data));
73 EXPECT_NE(nullptr, slot_data);
74 EXPECT_EQ(
75 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
76 "androidboot.vbmeta.avb_version=1.0 "
77 "androidboot.vbmeta.device_state=locked "
78 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
79 "androidboot.vbmeta.digest="
80 "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
81 "androidboot.vbmeta.invalidate_on_error=yes "
82 "androidboot.veritymode=enforcing",
83 std::string(slot_data->cmdline));
84 avb_slot_verify_data_free(slot_data);
85 }
86
TEST_F(AvbSlotVerifyTest,BasicSha512)87 TEST_F(AvbSlotVerifyTest, BasicSha512) {
88 GenerateVBMetaImage("vbmeta_a.img",
89 "SHA512_RSA2048",
90 0,
91 base::FilePath("test/data/testkey_rsa2048.pem"),
92 "--internal_release_string \"\"");
93
94 ops_.set_expected_public_key(
95 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
96
97 AvbSlotVerifyData* slot_data = NULL;
98 const char* requested_partitions[] = {"boot", NULL};
99 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
100 avb_slot_verify(ops_.avb_ops(),
101 requested_partitions,
102 "_a",
103 AVB_SLOT_VERIFY_FLAGS_NONE,
104 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
105 &slot_data));
106 EXPECT_NE(nullptr, slot_data);
107 EXPECT_EQ(
108 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
109 "androidboot.vbmeta.avb_version=1.0 "
110 "androidboot.vbmeta.device_state=locked "
111 "androidboot.vbmeta.hash_alg=sha512 androidboot.vbmeta.size=1152 "
112 "androidboot.vbmeta.digest="
113 "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
114 "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77 "
115 "androidboot.vbmeta.invalidate_on_error=yes "
116 "androidboot.veritymode=enforcing",
117 std::string(slot_data->cmdline));
118 avb_slot_verify_data_free(slot_data);
119 }
120
TEST_F(AvbSlotVerifyTest,BasicUnlocked)121 TEST_F(AvbSlotVerifyTest, BasicUnlocked) {
122 GenerateVBMetaImage("vbmeta_a.img",
123 "SHA256_RSA2048",
124 0,
125 base::FilePath("test/data/testkey_rsa2048.pem"),
126 "--internal_release_string \"\"");
127
128 ops_.set_expected_public_key(
129 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
130
131 ops_.set_stored_is_device_unlocked(true);
132
133 AvbSlotVerifyData* slot_data = NULL;
134 const char* requested_partitions[] = {"boot", NULL};
135 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
136 avb_slot_verify(ops_.avb_ops(),
137 requested_partitions,
138 "_a",
139 AVB_SLOT_VERIFY_FLAGS_NONE,
140 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
141 &slot_data));
142 EXPECT_NE(nullptr, slot_data);
143 EXPECT_EQ(
144 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
145 "androidboot.vbmeta.avb_version=1.0 "
146 "androidboot.vbmeta.device_state=unlocked "
147 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
148 "androidboot.vbmeta.digest="
149 "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d "
150 "androidboot.vbmeta.invalidate_on_error=yes "
151 "androidboot.veritymode=enforcing",
152 std::string(slot_data->cmdline));
153 avb_slot_verify_data_free(slot_data);
154 }
155
TEST_F(AvbSlotVerifyTest,SlotDataIsCorrect)156 TEST_F(AvbSlotVerifyTest, SlotDataIsCorrect) {
157 GenerateVBMetaImage("vbmeta_a.img",
158 "SHA256_RSA2048",
159 0,
160 base::FilePath("test/data/testkey_rsa2048.pem"),
161 "--internal_release_string \"\"");
162
163 ops_.set_expected_public_key(
164 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
165
166 AvbSlotVerifyData* slot_data = NULL;
167 const char* requested_partitions[] = {"boot", NULL};
168 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
169 avb_slot_verify(ops_.avb_ops(),
170 requested_partitions,
171 "_a",
172 AVB_SLOT_VERIFY_FLAGS_NONE,
173 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
174 &slot_data));
175 EXPECT_NE(nullptr, slot_data);
176 avb_slot_verify_data_free(slot_data);
177 }
178
TEST_F(AvbSlotVerifyTest,WrongPublicKey)179 TEST_F(AvbSlotVerifyTest, WrongPublicKey) {
180 GenerateVBMetaImage("vbmeta_a.img",
181 "SHA256_RSA2048",
182 0,
183 base::FilePath("test/data/testkey_rsa2048.pem"),
184 "--internal_release_string \"\"");
185
186 AvbSlotVerifyData* slot_data = NULL;
187 const char* requested_partitions[] = {"boot", NULL};
188 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
189 avb_slot_verify(ops_.avb_ops(),
190 requested_partitions,
191 "_a",
192 AVB_SLOT_VERIFY_FLAGS_NONE,
193 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
194 &slot_data));
195 EXPECT_EQ(nullptr, slot_data);
196 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
197 avb_slot_verify(ops_.avb_ops(),
198 requested_partitions,
199 "_a",
200 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
201 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
202 &slot_data));
203 EXPECT_NE(nullptr, slot_data);
204 avb_slot_verify_data_free(slot_data);
205 }
206
TEST_F(AvbSlotVerifyTest,NoImage)207 TEST_F(AvbSlotVerifyTest, NoImage) {
208 const char* requested_partitions[] = {"boot", NULL};
209 AvbSlotVerifyData* slot_data = NULL;
210 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
211 avb_slot_verify(ops_.avb_ops(),
212 requested_partitions,
213 "_a",
214 AVB_SLOT_VERIFY_FLAGS_NONE,
215 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
216 &slot_data));
217 EXPECT_EQ(nullptr, slot_data);
218 }
219
TEST_F(AvbSlotVerifyTest,UnsignedVBMeta)220 TEST_F(AvbSlotVerifyTest, UnsignedVBMeta) {
221 GenerateVBMetaImage("vbmeta_a.img",
222 "",
223 0,
224 base::FilePath(""),
225 "--internal_release_string \"\"");
226
227 AvbSlotVerifyData* slot_data = NULL;
228 const char* requested_partitions[] = {"boot", NULL};
229 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
230 avb_slot_verify(ops_.avb_ops(),
231 requested_partitions,
232 "_a",
233 AVB_SLOT_VERIFY_FLAGS_NONE,
234 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
235 &slot_data));
236 EXPECT_EQ(nullptr, slot_data);
237 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
238 avb_slot_verify(ops_.avb_ops(),
239 requested_partitions,
240 "_a",
241 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
242 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
243 &slot_data));
244 EXPECT_NE(nullptr, slot_data);
245 avb_slot_verify_data_free(slot_data);
246 }
247
TEST_F(AvbSlotVerifyTest,CorruptedImage)248 TEST_F(AvbSlotVerifyTest, CorruptedImage) {
249 GenerateVBMetaImage("vbmeta_a.img",
250 "SHA256_RSA2048",
251 0,
252 base::FilePath("test/data/testkey_rsa2048.pem"),
253 "--internal_release_string \"\"");
254
255 // Corrupt four bytes of data in the end of the image. Since the aux
256 // data is at the end and this data is signed, this will change the
257 // value of the computed hash.
258 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
259 EXPECT_EQ(AVB_IO_RESULT_OK,
260 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
261 "vbmeta_a",
262 -4, // offset from end
263 sizeof corrupt_data,
264 corrupt_data));
265
266 AvbSlotVerifyData* slot_data = NULL;
267 const char* requested_partitions[] = {"boot", NULL};
268 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
269 avb_slot_verify(ops_.avb_ops(),
270 requested_partitions,
271 "_a",
272 AVB_SLOT_VERIFY_FLAGS_NONE,
273 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
274 &slot_data));
275 EXPECT_EQ(nullptr, slot_data);
276 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
277 avb_slot_verify(ops_.avb_ops(),
278 requested_partitions,
279 "_a",
280 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
281 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
282 &slot_data));
283 EXPECT_NE(nullptr, slot_data);
284 avb_slot_verify_data_free(slot_data);
285 }
286
TEST_F(AvbSlotVerifyTest,CorruptedMetadata)287 TEST_F(AvbSlotVerifyTest, CorruptedMetadata) {
288 GenerateVBMetaImage("vbmeta_a.img",
289 "SHA256_RSA2048",
290 0,
291 base::FilePath("test/data/testkey_rsa2048.pem"),
292 "--internal_release_string \"\"");
293
294 // Corrupt four bytes of data in the beginning of the image. Unlike
295 // the CorruptedImage test-case above (which is valid metadata) this
296 // will make the metadata invalid and render the slot unbootable
297 // even if the device is unlocked. Specifically no AvbSlotVerifyData
298 // is returned.
299 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
300 EXPECT_EQ(AVB_IO_RESULT_OK,
301 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
302 "vbmeta_a",
303 0, // offset: beginning
304 sizeof corrupt_data,
305 corrupt_data));
306
307 AvbSlotVerifyData* slot_data = NULL;
308 const char* requested_partitions[] = {"boot", NULL};
309 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
310 avb_slot_verify(ops_.avb_ops(),
311 requested_partitions,
312 "_a",
313 AVB_SLOT_VERIFY_FLAGS_NONE,
314 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
315 &slot_data));
316 EXPECT_EQ(nullptr, slot_data);
317 }
318
TEST_F(AvbSlotVerifyTest,RollbackIndex)319 TEST_F(AvbSlotVerifyTest, RollbackIndex) {
320 GenerateVBMetaImage("vbmeta_a.img",
321 "SHA256_RSA2048",
322 42,
323 base::FilePath("test/data/testkey_rsa2048.pem"),
324 "--internal_release_string \"\"");
325
326 ops_.set_expected_public_key(
327 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
328
329 AvbSlotVerifyData* slot_data = NULL;
330 const char* requested_partitions[] = {"boot", NULL};
331
332 // First try with 42 as the stored rollback index - this should
333 // succeed since the image rollback index is 42 (as set above).
334 ops_.set_stored_rollback_indexes({{0, 42}});
335 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
336 avb_slot_verify(ops_.avb_ops(),
337 requested_partitions,
338 "_a",
339 AVB_SLOT_VERIFY_FLAGS_NONE,
340 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
341 &slot_data));
342 EXPECT_NE(nullptr, slot_data);
343 avb_slot_verify_data_free(slot_data);
344
345 // Then try with 43 for the stored rollback index - this should fail
346 // because the image has rollback index 42 which is less than 43.
347 ops_.set_stored_rollback_indexes({{0, 43}});
348 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
349 avb_slot_verify(ops_.avb_ops(),
350 requested_partitions,
351 "_a",
352 AVB_SLOT_VERIFY_FLAGS_NONE,
353 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
354 &slot_data));
355 EXPECT_EQ(nullptr, slot_data);
356 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
357 avb_slot_verify(ops_.avb_ops(),
358 requested_partitions,
359 "_a",
360 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
361 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
362 &slot_data));
363 EXPECT_NE(nullptr, slot_data);
364 avb_slot_verify_data_free(slot_data);
365 }
366
TEST_F(AvbSlotVerifyTest,LoadEntirePartitionIfAllowingVerificationError)367 TEST_F(AvbSlotVerifyTest, LoadEntirePartitionIfAllowingVerificationError) {
368 const size_t boot_partition_size = 16 * 1024 * 1024;
369 const size_t boot_image_size = 5 * 1024 * 1024;
370 const size_t new_boot_image_size = 10 * 1024 * 1024;
371 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
372
373 // If we're allowing verification errors then check that the whole
374 // partition is loaded. This is needed because in this mode for
375 // example the "boot" partition might be flashed with another
376 // boot.img that is larger than what the HashDescriptor in vbmeta
377 // says.
378 EXPECT_COMMAND(
379 0,
380 "./avbtool add_hash_footer"
381 " --image %s"
382 " --rollback_index 0"
383 " --partition_name boot"
384 " --partition_size %zd"
385 " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
386 " --salt deadbeef"
387 " --internal_release_string \"\"",
388 boot_path.value().c_str(),
389 boot_partition_size);
390
391 GenerateVBMetaImage(
392 "vbmeta_a.img",
393 "SHA256_RSA2048",
394 4,
395 base::FilePath("test/data/testkey_rsa2048.pem"),
396 base::StringPrintf(
397 "--include_descriptors_from_image %s"
398 " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
399 " --internal_release_string \"\"",
400 boot_path.value().c_str()));
401
402 // Now replace the boot partition with something bigger and
403 // different. Because FakeOps's get_size_of_partition() operation
404 // just returns the file size it means that this is what is returned
405 // by get_size_of_partition().
406 //
407 // Also make sure this image will return a different digest by using
408 // a non-standard starting byte. This is to force avb_slot_verify()
409 // to return ERROR_VERIFICATION below.
410 GenerateImage("boot_a.img", new_boot_image_size, 1 /* start_byte */);
411
412 ops_.set_expected_public_key(
413 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
414
415 AvbSlotVerifyData* slot_data = NULL;
416 const char* requested_partitions[] = {"boot", NULL};
417 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
418 avb_slot_verify(ops_.avb_ops(),
419 requested_partitions,
420 "_a",
421 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
422 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
423 &slot_data));
424 EXPECT_NE(nullptr, slot_data);
425
426 // Check that the loaded partition is actually
427 // |new_boot_image_size|.
428 EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
429 EXPECT_EQ("boot",
430 std::string(slot_data->loaded_partitions[0].partition_name));
431 EXPECT_EQ(new_boot_image_size, slot_data->loaded_partitions[0].data_size);
432 avb_slot_verify_data_free(slot_data);
433 }
434
TEST_F(AvbSlotVerifyTest,HashDescriptorInVBMeta)435 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMeta) {
436 const size_t boot_partition_size = 16 * 1024 * 1024;
437 const size_t boot_image_size = 5 * 1024 * 1024;
438 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
439
440 EXPECT_COMMAND(
441 0,
442 "./avbtool add_hash_footer"
443 " --image %s"
444 " --rollback_index 0"
445 " --partition_name boot"
446 " --partition_size %zd"
447 " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
448 " --salt deadbeef"
449 " --internal_release_string \"\"",
450 boot_path.value().c_str(),
451 boot_partition_size);
452
453 GenerateVBMetaImage(
454 "vbmeta_a.img",
455 "SHA256_RSA2048",
456 4,
457 base::FilePath("test/data/testkey_rsa2048.pem"),
458 base::StringPrintf(
459 "--include_descriptors_from_image %s"
460 " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
461 " --internal_release_string \"\"",
462 boot_path.value().c_str()));
463
464 EXPECT_EQ(
465 "Minimum libavb version: 1.0\n"
466 "Header Block: 256 bytes\n"
467 "Authentication Block: 320 bytes\n"
468 "Auxiliary Block: 896 bytes\n"
469 "Algorithm: SHA256_RSA2048\n"
470 "Rollback Index: 4\n"
471 "Flags: 0\n"
472 "Release String: ''\n"
473 "Descriptors:\n"
474 " Kernel Cmdline descriptor:\n"
475 " Flags: 0\n"
476 " Kernel Cmdline: 'cmdline in vbmeta "
477 "$(ANDROID_BOOT_PARTUUID)'\n"
478 " Hash descriptor:\n"
479 " Image Size: 5242880 bytes\n"
480 " Hash Algorithm: sha256\n"
481 " Partition Name: boot\n"
482 " Salt: deadbeef\n"
483 " Digest: "
484 "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
485 " Kernel Cmdline descriptor:\n"
486 " Flags: 0\n"
487 " Kernel Cmdline: 'cmdline in hash footer "
488 "$(ANDROID_SYSTEM_PARTUUID)'\n",
489 InfoImage(vbmeta_image_path_));
490
491 EXPECT_COMMAND(0,
492 "./avbtool erase_footer"
493 " --image %s",
494 boot_path.value().c_str());
495
496 // With no footer, 'avbtool info_image' should fail (exit status 1).
497 EXPECT_COMMAND(
498 1, "./avbtool info_image --image %s", boot_path.value().c_str());
499
500 ops_.set_expected_public_key(
501 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
502
503 AvbSlotVerifyData* slot_data = NULL;
504 const char* requested_partitions[] = {"boot", NULL};
505 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
506 avb_slot_verify(ops_.avb_ops(),
507 requested_partitions,
508 "_a",
509 AVB_SLOT_VERIFY_FLAGS_NONE,
510 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
511 &slot_data));
512 EXPECT_NE(nullptr, slot_data);
513
514 // Now verify the slot data. The vbmeta data should match our
515 // vbmeta_image_ member.
516 EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
517 EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
518 EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
519 EXPECT_EQ(0,
520 memcmp(vbmeta_image_.data(),
521 slot_data->vbmeta_images[0].vbmeta_data,
522 slot_data->vbmeta_images[0].vbmeta_size));
523
524 // The boot image data should match what is generated above with
525 // GenerateImage().
526 EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
527 EXPECT_EQ("boot",
528 std::string(slot_data->loaded_partitions[0].partition_name));
529 EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
530 for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
531 EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
532 }
533
534 // This should match the two cmdlines with a space (U+0020) between
535 // them and the $(ANDROID_SYSTEM_PARTUUID) and
536 // $(ANDROID_BOOT_PARTUUID) variables replaced.
537 EXPECT_EQ(
538 "cmdline in vbmeta 1234-fake-guid-for:boot_a cmdline in hash footer "
539 "1234-fake-guid-for:system_a "
540 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
541 "androidboot.vbmeta.avb_version=1.0 "
542 "androidboot.vbmeta.device_state=locked "
543 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
544 "androidboot.vbmeta.digest="
545 "34cdb59b955aa35d4da97701f304fabf7392eecca8c50ff1a0b7b6e1c9aaa1b8 "
546 "androidboot.vbmeta.invalidate_on_error=yes "
547 "androidboot.veritymode=enforcing",
548 std::string(slot_data->cmdline));
549 EXPECT_EQ(4UL, slot_data->rollback_indexes[0]);
550 for (size_t n = 1; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
551 EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
552 }
553 avb_slot_verify_data_free(slot_data);
554 }
555
TEST_F(AvbSlotVerifyTest,HashDescriptorInVBMetaCorruptBoot)556 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMetaCorruptBoot) {
557 size_t boot_partition_size = 16 * 1024 * 1024;
558 base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
559 const char* requested_partitions[] = {"boot", NULL};
560
561 EXPECT_COMMAND(0,
562 "./avbtool add_hash_footer"
563 " --image %s"
564 " --rollback_index 0"
565 " --partition_name boot"
566 " --partition_size %zd"
567 " --salt deadbeef"
568 " --internal_release_string \"\"",
569 boot_path.value().c_str(),
570 boot_partition_size);
571
572 GenerateVBMetaImage("vbmeta_a.img",
573 "SHA256_RSA2048",
574 0,
575 base::FilePath("test/data/testkey_rsa2048.pem"),
576 base::StringPrintf("--include_descriptors_from_image %s"
577 " --internal_release_string \"\"",
578 boot_path.value().c_str()));
579
580 EXPECT_COMMAND(0,
581 "./avbtool erase_footer"
582 " --image %s",
583 boot_path.value().c_str());
584
585 ops_.set_expected_public_key(
586 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
587
588 // So far, so good.
589 AvbSlotVerifyData* slot_data = NULL;
590 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
591 avb_slot_verify(ops_.avb_ops(),
592 requested_partitions,
593 "_a",
594 AVB_SLOT_VERIFY_FLAGS_NONE,
595 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
596 &slot_data));
597 EXPECT_NE(nullptr, slot_data);
598 avb_slot_verify_data_free(slot_data);
599
600 // Now corrupt boot_a.img and expect verification error.
601 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
602 EXPECT_EQ(AVB_IO_RESULT_OK,
603 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
604 "boot_a",
605 1024 * 1024, // offset: 1 MiB
606 sizeof corrupt_data,
607 corrupt_data));
608
609 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
610 avb_slot_verify(ops_.avb_ops(),
611 requested_partitions,
612 "_a",
613 AVB_SLOT_VERIFY_FLAGS_NONE,
614 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
615 &slot_data));
616 EXPECT_EQ(nullptr, slot_data);
617 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
618 avb_slot_verify(ops_.avb_ops(),
619 requested_partitions,
620 "_a",
621 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
622 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
623 &slot_data));
624 EXPECT_NE(nullptr, slot_data);
625 avb_slot_verify_data_free(slot_data);
626 }
627
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartition)628 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartition) {
629 size_t boot_partition_size = 16 * 1024 * 1024;
630 const size_t boot_image_size = 5 * 1024 * 1024;
631 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
632 const char* requested_partitions[] = {"boot", NULL};
633
634 EXPECT_COMMAND(0,
635 "./avbtool add_hash_footer"
636 " --image %s"
637 " --kernel_cmdline 'cmdline2 in hash footer'"
638 " --rollback_index 12"
639 " --partition_name boot"
640 " --partition_size %zd"
641 " --algorithm SHA256_RSA4096"
642 " --key test/data/testkey_rsa4096.pem"
643 " --salt deadbeef"
644 " --internal_release_string \"\"",
645 boot_path.value().c_str(),
646 boot_partition_size);
647
648 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
649 EXPECT_COMMAND(
650 0,
651 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
652 " --output %s",
653 pk_path.value().c_str());
654
655 GenerateVBMetaImage(
656 "vbmeta_a.img",
657 "SHA256_RSA2048",
658 11,
659 base::FilePath("test/data/testkey_rsa2048.pem"),
660 base::StringPrintf("--chain_partition boot:1:%s"
661 " --kernel_cmdline 'cmdline2 in vbmeta'"
662 " --internal_release_string \"\"",
663 pk_path.value().c_str()));
664
665 EXPECT_EQ(
666 "Minimum libavb version: 1.0\n"
667 "Header Block: 256 bytes\n"
668 "Authentication Block: 320 bytes\n"
669 "Auxiliary Block: 1728 bytes\n"
670 "Algorithm: SHA256_RSA2048\n"
671 "Rollback Index: 11\n"
672 "Flags: 0\n"
673 "Release String: ''\n"
674 "Descriptors:\n"
675 " Chain Partition descriptor:\n"
676 " Partition Name: boot\n"
677 " Rollback Index Location: 1\n"
678 " Public key (sha1): "
679 "2597c218aae470a130f61162feaae70afd97f011\n"
680 " Kernel Cmdline descriptor:\n"
681 " Flags: 0\n"
682 " Kernel Cmdline: 'cmdline2 in vbmeta'\n",
683 InfoImage(vbmeta_image_path_));
684
685 EXPECT_EQ(
686 "Footer version: 1.0\n"
687 "Image size: 16777216 bytes\n"
688 "Original image size: 5242880 bytes\n"
689 "VBMeta offset: 5242880\n"
690 "VBMeta size: 2112 bytes\n"
691 "--\n"
692 "Minimum libavb version: 1.0\n"
693 "Header Block: 256 bytes\n"
694 "Authentication Block: 576 bytes\n"
695 "Auxiliary Block: 1280 bytes\n"
696 "Algorithm: SHA256_RSA4096\n"
697 "Rollback Index: 12\n"
698 "Flags: 0\n"
699 "Release String: ''\n"
700 "Descriptors:\n"
701 " Hash descriptor:\n"
702 " Image Size: 5242880 bytes\n"
703 " Hash Algorithm: sha256\n"
704 " Partition Name: boot\n"
705 " Salt: deadbeef\n"
706 " Digest: "
707 "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
708 " Kernel Cmdline descriptor:\n"
709 " Flags: 0\n"
710 " Kernel Cmdline: 'cmdline2 in hash footer'\n",
711 InfoImage(boot_path));
712
713 ops_.set_expected_public_key(
714 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
715
716 AvbSlotVerifyData* slot_data = NULL;
717 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
718 avb_slot_verify(ops_.avb_ops(),
719 requested_partitions,
720 "_a",
721 AVB_SLOT_VERIFY_FLAGS_NONE,
722 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
723 &slot_data));
724 EXPECT_NE(nullptr, slot_data);
725
726 // Now verify the slot data. We should have two vbmeta
727 // structs. Verify both of them. Note that the A/B suffix isn't
728 // appended.
729 EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
730 EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
731 EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
732 EXPECT_EQ(0,
733 memcmp(vbmeta_image_.data(),
734 slot_data->vbmeta_images[0].vbmeta_data,
735 slot_data->vbmeta_images[0].vbmeta_size));
736 // And for the second vbmeta struct we check that the descriptors
737 // match the info_image output from above.
738 EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
739 const AvbDescriptor** descriptors =
740 avb_descriptor_get_all(slot_data->vbmeta_images[1].vbmeta_data,
741 slot_data->vbmeta_images[1].vbmeta_size,
742 NULL);
743 EXPECT_NE(nullptr, descriptors);
744 AvbHashDescriptor hash_desc;
745 EXPECT_EQ(true,
746 avb_hash_descriptor_validate_and_byteswap(
747 ((AvbHashDescriptor*)descriptors[0]), &hash_desc));
748 const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
749 sizeof(AvbHashDescriptor);
750 uint64_t o = 0;
751 EXPECT_EQ("boot",
752 std::string(reinterpret_cast<const char*>(desc_end + o),
753 hash_desc.partition_name_len));
754 o += hash_desc.partition_name_len;
755 EXPECT_EQ("deadbeef", mem_to_hexstring(desc_end + o, hash_desc.salt_len));
756 o += hash_desc.salt_len;
757 EXPECT_EQ("184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d",
758 mem_to_hexstring(desc_end + o, hash_desc.digest_len));
759 AvbKernelCmdlineDescriptor cmdline_desc;
760 EXPECT_EQ(true,
761 avb_kernel_cmdline_descriptor_validate_and_byteswap(
762 ((AvbKernelCmdlineDescriptor*)descriptors[1]), &cmdline_desc));
763 desc_end = reinterpret_cast<const uint8_t*>(descriptors[1]) +
764 sizeof(AvbKernelCmdlineDescriptor);
765 EXPECT_EQ("cmdline2 in hash footer",
766 std::string(reinterpret_cast<const char*>(desc_end),
767 cmdline_desc.kernel_cmdline_length));
768 avb_free(descriptors);
769
770 // The boot image data should match what is generated above with
771 // GenerateImage().
772 EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
773 EXPECT_EQ("boot",
774 std::string(slot_data->loaded_partitions[0].partition_name));
775 EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
776 for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
777 EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
778 }
779
780 // This should match the two cmdlines with a space (U+0020) between them.
781 EXPECT_EQ(
782 "cmdline2 in hash footer cmdline2 in vbmeta "
783 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
784 "androidboot.vbmeta.avb_version=1.0 "
785 "androidboot.vbmeta.device_state=locked "
786 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
787 "androidboot.vbmeta.digest="
788 "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4 "
789 "androidboot.vbmeta.invalidate_on_error=yes "
790 "androidboot.veritymode=enforcing",
791 std::string(slot_data->cmdline));
792 EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
793 EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
794 for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
795 EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
796 }
797 avb_slot_verify_data_free(slot_data);
798 }
799
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionCorruptBoot)800 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionCorruptBoot) {
801 size_t boot_partition_size = 16 * 1024 * 1024;
802 base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
803 const char* requested_partitions[] = {"boot", NULL};
804
805 EXPECT_COMMAND(0,
806 "./avbtool add_hash_footer"
807 " --image %s"
808 " --rollback_index 0"
809 " --partition_name boot"
810 " --partition_size %zd"
811 " --algorithm SHA256_RSA4096"
812 " --key test/data/testkey_rsa4096.pem"
813 " --salt deadbeef"
814 " --internal_release_string \"\"",
815 boot_path.value().c_str(),
816 boot_partition_size);
817
818 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
819 EXPECT_COMMAND(
820 0,
821 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
822 " --output %s",
823 pk_path.value().c_str());
824
825 GenerateVBMetaImage("vbmeta_a.img",
826 "SHA256_RSA2048",
827 0,
828 base::FilePath("test/data/testkey_rsa2048.pem"),
829 base::StringPrintf("--chain_partition boot:1:%s"
830 " --internal_release_string \"\"",
831 pk_path.value().c_str()));
832
833 ops_.set_expected_public_key(
834 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
835
836 AvbSlotVerifyData* slot_data = NULL;
837 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
838 avb_slot_verify(ops_.avb_ops(),
839 requested_partitions,
840 "_a",
841 AVB_SLOT_VERIFY_FLAGS_NONE,
842 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
843 &slot_data));
844 EXPECT_NE(nullptr, slot_data);
845 avb_slot_verify_data_free(slot_data);
846
847 // Now corrupt boot_a.img and expect verification error.
848 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
849 EXPECT_EQ(AVB_IO_RESULT_OK,
850 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
851 "boot_a",
852 1024 * 1024, // offset: 1 MiB
853 sizeof corrupt_data,
854 corrupt_data));
855
856 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
857 avb_slot_verify(ops_.avb_ops(),
858 requested_partitions,
859 "_a",
860 AVB_SLOT_VERIFY_FLAGS_NONE,
861 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
862 &slot_data));
863 EXPECT_EQ(nullptr, slot_data);
864 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
865 avb_slot_verify(ops_.avb_ops(),
866 requested_partitions,
867 "_a",
868 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
869 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
870 &slot_data));
871 EXPECT_NE(nullptr, slot_data);
872 avb_slot_verify_data_free(slot_data);
873 }
874
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionKeyMismatch)875 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionKeyMismatch) {
876 size_t boot_partition_size = 16 * 1024 * 1024;
877 base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
878 const char* requested_partitions[] = {"boot", NULL};
879
880 // Use different key to sign vbmeta in boot_a (we use the 8192 bit
881 // key) than what's in the chained partition descriptor (which is
882 // the 4096 bit key) and expect
883 // AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED.
884
885 EXPECT_COMMAND(0,
886 "./avbtool add_hash_footer"
887 " --image %s"
888 " --rollback_index 0"
889 " --partition_name boot"
890 " --partition_size %zd"
891 " --algorithm SHA256_RSA8192"
892 " --key test/data/testkey_rsa8192.pem"
893 " --salt deadbeef"
894 " --internal_release_string \"\"",
895 boot_path.value().c_str(),
896 boot_partition_size);
897
898 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
899 EXPECT_COMMAND(
900 0,
901 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
902 " --output %s",
903 pk_path.value().c_str());
904
905 GenerateVBMetaImage("vbmeta_a.img",
906 "SHA256_RSA2048",
907 0,
908 base::FilePath("test/data/testkey_rsa2048.pem"),
909 base::StringPrintf("--chain_partition boot:1:%s"
910 " --internal_release_string \"\"",
911 pk_path.value().c_str()));
912
913 ops_.set_expected_public_key(
914 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
915
916 AvbSlotVerifyData* slot_data = NULL;
917 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
918 avb_slot_verify(ops_.avb_ops(),
919 requested_partitions,
920 "_a",
921 AVB_SLOT_VERIFY_FLAGS_NONE,
922 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
923 &slot_data));
924 EXPECT_EQ(nullptr, slot_data);
925 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
926 avb_slot_verify(ops_.avb_ops(),
927 requested_partitions,
928 "_a",
929 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
930 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
931 &slot_data));
932 EXPECT_NE(nullptr, slot_data);
933 avb_slot_verify_data_free(slot_data);
934 }
935
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionRollbackIndexFail)936 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionRollbackIndexFail) {
937 size_t boot_partition_size = 16 * 1024 * 1024;
938 base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
939 const char* requested_partitions[] = {"boot", NULL};
940
941 EXPECT_COMMAND(0,
942 "./avbtool add_hash_footer"
943 " --image %s"
944 " --rollback_index 10"
945 " --partition_name boot"
946 " --partition_size %zd"
947 " --algorithm SHA256_RSA4096"
948 " --key test/data/testkey_rsa4096.pem"
949 " --salt deadbeef"
950 " --internal_release_string \"\"",
951 boot_path.value().c_str(),
952 boot_partition_size);
953
954 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
955 EXPECT_COMMAND(
956 0,
957 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
958 " --output %s",
959 pk_path.value().c_str());
960
961 GenerateVBMetaImage("vbmeta_a.img",
962 "SHA256_RSA2048",
963 110,
964 base::FilePath("test/data/testkey_rsa2048.pem"),
965 base::StringPrintf("--chain_partition boot:1:%s"
966 " --internal_release_string \"\"",
967 pk_path.value().c_str()));
968
969 ops_.set_expected_public_key(
970 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
971
972 AvbSlotVerifyData* slot_data = NULL;
973
974 // Both images (vbmeta_a and boot_a) have rollback index 10 and 11
975 // so it should work if the stored rollback indexes are 0 and 0.
976 ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}});
977 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
978 avb_slot_verify(ops_.avb_ops(),
979 requested_partitions,
980 "_a",
981 AVB_SLOT_VERIFY_FLAGS_NONE,
982 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
983 &slot_data));
984 EXPECT_NE(nullptr, slot_data);
985 avb_slot_verify_data_free(slot_data);
986
987 // Check failure if we set the stored rollback index of the chained
988 // partition to 20 (see AvbSlotVerifyTest.RollbackIndex above
989 // where we test rollback index checks for the vbmeta partition).
990 ops_.set_stored_rollback_indexes({{0, 0}, {1, 20}});
991 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
992 avb_slot_verify(ops_.avb_ops(),
993 requested_partitions,
994 "_a",
995 AVB_SLOT_VERIFY_FLAGS_NONE,
996 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
997 &slot_data));
998 EXPECT_EQ(nullptr, slot_data);
999 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
1000 avb_slot_verify(ops_.avb_ops(),
1001 requested_partitions,
1002 "_a",
1003 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
1004 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1005 &slot_data));
1006 EXPECT_NE(nullptr, slot_data);
1007 avb_slot_verify_data_free(slot_data);
1008
1009 // Check failure if there is no rollback index slot 1 - in that case
1010 // we expect an I/O error since ops->read_rollback_index() will
1011 // fail.
1012 ops_.set_stored_rollback_indexes({{0, 0}});
1013 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
1014 avb_slot_verify(ops_.avb_ops(),
1015 requested_partitions,
1016 "_a",
1017 AVB_SLOT_VERIFY_FLAGS_NONE,
1018 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1019 &slot_data));
1020 EXPECT_EQ(nullptr, slot_data);
1021 }
1022
TEST_F(AvbSlotVerifyTest,ChainedPartitionNoSlots)1023 TEST_F(AvbSlotVerifyTest, ChainedPartitionNoSlots) {
1024 size_t boot_partition_size = 16 * 1024 * 1024;
1025 const size_t boot_image_size = 5 * 1024 * 1024;
1026 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
1027 const char* requested_partitions[] = {"boot", NULL};
1028
1029 EXPECT_COMMAND(0,
1030 "./avbtool add_hash_footer"
1031 " --image %s"
1032 " --kernel_cmdline 'cmdline2 in hash footer'"
1033 " --rollback_index 12"
1034 " --partition_name boot"
1035 " --partition_size %zd"
1036 " --algorithm SHA256_RSA4096"
1037 " --key test/data/testkey_rsa4096.pem"
1038 " --salt deadbeef"
1039 " --internal_release_string \"\"",
1040 boot_path.value().c_str(),
1041 boot_partition_size);
1042
1043 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
1044 EXPECT_COMMAND(
1045 0,
1046 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
1047 " --output %s",
1048 pk_path.value().c_str());
1049
1050 GenerateVBMetaImage(
1051 "vbmeta.img",
1052 "SHA256_RSA2048",
1053 11,
1054 base::FilePath("test/data/testkey_rsa2048.pem"),
1055 base::StringPrintf("--chain_partition boot:1:%s"
1056 " --kernel_cmdline 'cmdline2 in vbmeta'"
1057 " --internal_release_string \"\"",
1058 pk_path.value().c_str()));
1059
1060 EXPECT_EQ(
1061 "Minimum libavb version: 1.0\n"
1062 "Header Block: 256 bytes\n"
1063 "Authentication Block: 320 bytes\n"
1064 "Auxiliary Block: 1728 bytes\n"
1065 "Algorithm: SHA256_RSA2048\n"
1066 "Rollback Index: 11\n"
1067 "Flags: 0\n"
1068 "Release String: ''\n"
1069 "Descriptors:\n"
1070 " Chain Partition descriptor:\n"
1071 " Partition Name: boot\n"
1072 " Rollback Index Location: 1\n"
1073 " Public key (sha1): "
1074 "2597c218aae470a130f61162feaae70afd97f011\n"
1075 " Kernel Cmdline descriptor:\n"
1076 " Flags: 0\n"
1077 " Kernel Cmdline: 'cmdline2 in vbmeta'\n",
1078 InfoImage(vbmeta_image_path_));
1079
1080 ops_.set_expected_public_key(
1081 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1082
1083 AvbSlotVerifyData* slot_data = NULL;
1084 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1085 avb_slot_verify(ops_.avb_ops(),
1086 requested_partitions,
1087 "",
1088 AVB_SLOT_VERIFY_FLAGS_NONE,
1089 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1090 &slot_data));
1091 EXPECT_NE(nullptr, slot_data);
1092
1093 // Now verify the slot data. The first vbmeta data should match our
1094 // vbmeta_image_ member and the second one should be for the 'boot'
1095 // partition.
1096 EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
1097 EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
1098 EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
1099 EXPECT_EQ(0,
1100 memcmp(vbmeta_image_.data(),
1101 slot_data->vbmeta_images[0].vbmeta_data,
1102 slot_data->vbmeta_images[0].vbmeta_size));
1103 EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
1104
1105 // The boot image data should match what is generated above with
1106 // GenerateImage().
1107 EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
1108 EXPECT_EQ("boot",
1109 std::string(slot_data->loaded_partitions[0].partition_name));
1110 EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
1111 for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
1112 EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
1113 }
1114
1115 // This should match the two cmdlines with a space (U+0020) between
1116 // them.
1117 EXPECT_EQ(
1118 "cmdline2 in hash footer cmdline2 in vbmeta "
1119 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
1120 "androidboot.vbmeta.avb_version=1.0 "
1121 "androidboot.vbmeta.device_state=locked "
1122 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
1123 "androidboot.vbmeta.digest="
1124 "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4 "
1125 "androidboot.vbmeta.invalidate_on_error=yes "
1126 "androidboot.veritymode=enforcing",
1127 std::string(slot_data->cmdline));
1128 EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
1129 EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
1130 for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
1131 EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
1132 }
1133 avb_slot_verify_data_free(slot_data);
1134 }
1135
TEST_F(AvbSlotVerifyTest,PartitionsOtherThanBoot)1136 TEST_F(AvbSlotVerifyTest, PartitionsOtherThanBoot) {
1137 const size_t foo_partition_size = 16 * 1024 * 1024;
1138 const size_t bar_partition_size = 32 * 1024 * 1024;
1139 const size_t foo_image_size = 5 * 1024 * 1024;
1140 const size_t bar_image_size = 10 * 1024 * 1024;
1141 base::FilePath foo_path = GenerateImage("foo_a.img", foo_image_size);
1142 base::FilePath bar_path = GenerateImage("bar_a.img", bar_image_size);
1143
1144 EXPECT_COMMAND(0,
1145 "./avbtool add_hash_footer"
1146 " --image %s"
1147 " --partition_name foo"
1148 " --partition_size %zd"
1149 " --salt deadbeef"
1150 " --internal_release_string \"\"",
1151 foo_path.value().c_str(),
1152 foo_partition_size);
1153
1154 EXPECT_COMMAND(0,
1155 "./avbtool add_hash_footer"
1156 " --image %s"
1157 " --partition_name bar"
1158 " --partition_size %zd"
1159 " --salt deadbeef"
1160 " --internal_release_string \"\"",
1161 bar_path.value().c_str(),
1162 bar_partition_size);
1163
1164 GenerateVBMetaImage("vbmeta_a.img",
1165 "SHA256_RSA2048",
1166 4,
1167 base::FilePath("test/data/testkey_rsa2048.pem"),
1168 base::StringPrintf("--include_descriptors_from_image %s"
1169 " --include_descriptors_from_image %s"
1170 " --internal_release_string \"\"",
1171 foo_path.value().c_str(),
1172 bar_path.value().c_str()));
1173
1174 EXPECT_EQ(
1175 "Minimum libavb version: 1.0\n"
1176 "Header Block: 256 bytes\n"
1177 "Authentication Block: 320 bytes\n"
1178 "Auxiliary Block: 896 bytes\n"
1179 "Algorithm: SHA256_RSA2048\n"
1180 "Rollback Index: 4\n"
1181 "Flags: 0\n"
1182 "Release String: ''\n"
1183 "Descriptors:\n"
1184 " Hash descriptor:\n"
1185 " Image Size: 5242880 bytes\n"
1186 " Hash Algorithm: sha256\n"
1187 " Partition Name: foo\n"
1188 " Salt: deadbeef\n"
1189 " Digest: "
1190 "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
1191 " Hash descriptor:\n"
1192 " Image Size: 10485760 bytes\n"
1193 " Hash Algorithm: sha256\n"
1194 " Partition Name: bar\n"
1195 " Salt: deadbeef\n"
1196 " Digest: "
1197 "baea4bbd261d0edf4d1fe5e6e5a36976c291eeba66b6a46fa81dba691327a727\n",
1198 InfoImage(vbmeta_image_path_));
1199
1200 ops_.set_expected_public_key(
1201 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1202
1203 AvbSlotVerifyData* slot_data = NULL;
1204 const char* requested_partitions[] = {"foo", "bar", NULL};
1205 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1206 avb_slot_verify(ops_.avb_ops(),
1207 requested_partitions,
1208 "_a",
1209 AVB_SLOT_VERIFY_FLAGS_NONE,
1210 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1211 &slot_data));
1212 EXPECT_NE(nullptr, slot_data);
1213
1214 // Now verify the slot data. The vbmeta data should match our
1215 // vbmeta_image_ member.
1216 EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
1217 EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
1218 EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
1219 EXPECT_EQ(0,
1220 memcmp(vbmeta_image_.data(),
1221 slot_data->vbmeta_images[0].vbmeta_data,
1222 slot_data->vbmeta_images[0].vbmeta_size));
1223
1224 // The 'foo' and 'bar' image data should match what is generated
1225 // above with GenerateImage().
1226 EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
1227 EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[0].partition_name));
1228 EXPECT_EQ(foo_image_size, slot_data->loaded_partitions[0].data_size);
1229 for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
1230 EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
1231 }
1232 EXPECT_EQ("bar", std::string(slot_data->loaded_partitions[1].partition_name));
1233 EXPECT_EQ(bar_image_size, slot_data->loaded_partitions[1].data_size);
1234 for (size_t n = 0; n < slot_data->loaded_partitions[1].data_size; n++) {
1235 EXPECT_EQ(slot_data->loaded_partitions[1].data[n], uint8_t(n));
1236 }
1237 avb_slot_verify_data_free(slot_data);
1238
1239 // Check that we loaded vbmeta_a, foo_a, and bar_a.
1240 std::set<std::string> partitions = ops_.get_partition_names_read_from();
1241 EXPECT_EQ(size_t(3), partitions.size());
1242 EXPECT_TRUE(partitions.find("vbmeta_a") != partitions.end());
1243 EXPECT_TRUE(partitions.find("foo_a") != partitions.end());
1244 EXPECT_TRUE(partitions.find("bar_a") != partitions.end());
1245 }
1246
TEST_F(AvbSlotVerifyTest,OnlyLoadWhatHasBeenRequested)1247 TEST_F(AvbSlotVerifyTest, OnlyLoadWhatHasBeenRequested) {
1248 const size_t foo_partition_size = 16 * 1024 * 1024;
1249 const size_t bar_partition_size = 32 * 1024 * 1024;
1250 const size_t foo_image_size = 5 * 1024 * 1024;
1251 const size_t bar_image_size = 10 * 1024 * 1024;
1252 base::FilePath foo_path = GenerateImage("foo_a.img", foo_image_size);
1253 base::FilePath bar_path = GenerateImage("bar_a.img", bar_image_size);
1254
1255 EXPECT_COMMAND(0,
1256 "./avbtool add_hash_footer"
1257 " --image %s"
1258 " --partition_name foo"
1259 " --partition_size %zd"
1260 " --salt deadbeef"
1261 " --internal_release_string \"\"",
1262 foo_path.value().c_str(),
1263 foo_partition_size);
1264
1265 EXPECT_COMMAND(0,
1266 "./avbtool add_hash_footer"
1267 " --image %s"
1268 " --partition_name bar"
1269 " --partition_size %zd"
1270 " --salt deadbeef"
1271 " --internal_release_string \"\"",
1272 bar_path.value().c_str(),
1273 bar_partition_size);
1274
1275 GenerateVBMetaImage("vbmeta_a.img",
1276 "SHA256_RSA2048",
1277 4,
1278 base::FilePath("test/data/testkey_rsa2048.pem"),
1279 base::StringPrintf("--include_descriptors_from_image %s"
1280 " --include_descriptors_from_image %s"
1281 " --internal_release_string \"\"",
1282 foo_path.value().c_str(),
1283 bar_path.value().c_str()));
1284
1285 EXPECT_EQ(
1286 "Minimum libavb version: 1.0\n"
1287 "Header Block: 256 bytes\n"
1288 "Authentication Block: 320 bytes\n"
1289 "Auxiliary Block: 896 bytes\n"
1290 "Algorithm: SHA256_RSA2048\n"
1291 "Rollback Index: 4\n"
1292 "Flags: 0\n"
1293 "Release String: ''\n"
1294 "Descriptors:\n"
1295 " Hash descriptor:\n"
1296 " Image Size: 5242880 bytes\n"
1297 " Hash Algorithm: sha256\n"
1298 " Partition Name: foo\n"
1299 " Salt: deadbeef\n"
1300 " Digest: "
1301 "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
1302 " Hash descriptor:\n"
1303 " Image Size: 10485760 bytes\n"
1304 " Hash Algorithm: sha256\n"
1305 " Partition Name: bar\n"
1306 " Salt: deadbeef\n"
1307 " Digest: "
1308 "baea4bbd261d0edf4d1fe5e6e5a36976c291eeba66b6a46fa81dba691327a727\n",
1309 InfoImage(vbmeta_image_path_));
1310
1311 ops_.set_expected_public_key(
1312 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1313 AvbSlotVerifyData* slot_data = NULL;
1314 const char* requested_partitions[] = {"foo", NULL};
1315 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1316 avb_slot_verify(ops_.avb_ops(),
1317 requested_partitions,
1318 "_a",
1319 AVB_SLOT_VERIFY_FLAGS_NONE,
1320 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1321 &slot_data));
1322 EXPECT_NE(nullptr, slot_data);
1323 EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
1324 EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[0].partition_name));
1325 avb_slot_verify_data_free(slot_data);
1326
1327 // Check that we loaded vbmeta_a, foo_a but not bar_a.
1328 std::set<std::string> partitions = ops_.get_partition_names_read_from();
1329 EXPECT_EQ(size_t(2), partitions.size());
1330 EXPECT_TRUE(partitions.find("vbmeta_a") != partitions.end());
1331 EXPECT_TRUE(partitions.find("foo_a") != partitions.end());
1332 EXPECT_TRUE(partitions.find("bar_a") == partitions.end());
1333 }
1334
TEST_F(AvbSlotVerifyTest,PublicKeyMetadata)1335 TEST_F(AvbSlotVerifyTest, PublicKeyMetadata) {
1336 base::FilePath md_path = GenerateImage("md.bin", 1536);
1337
1338 GenerateVBMetaImage("vbmeta_a.img",
1339 "SHA256_RSA2048",
1340 0,
1341 base::FilePath("test/data/testkey_rsa2048.pem"),
1342 base::StringPrintf("--public_key_metadata %s"
1343 " --internal_release_string \"\"",
1344 md_path.value().c_str()));
1345
1346 ops_.set_expected_public_key(
1347 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1348
1349 std::string md_data;
1350 ASSERT_TRUE(base::ReadFileToString(md_path, &md_data));
1351 ops_.set_expected_public_key_metadata(md_data);
1352
1353 AvbSlotVerifyData* slot_data = NULL;
1354 const char* requested_partitions[] = {"boot", NULL};
1355 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1356 avb_slot_verify(ops_.avb_ops(),
1357 requested_partitions,
1358 "_a",
1359 AVB_SLOT_VERIFY_FLAGS_NONE,
1360 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1361 &slot_data));
1362 EXPECT_NE(nullptr, slot_data);
1363 EXPECT_EQ(
1364 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
1365 "androidboot.vbmeta.avb_version=1.0 "
1366 "androidboot.vbmeta.device_state=locked "
1367 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=2688 "
1368 "androidboot.vbmeta.digest="
1369 "5edcaa54f40382ee6a2fc3b86cdf383348b35ed07955e83ea32d84b69a97eaa0 "
1370 "androidboot.vbmeta.invalidate_on_error=yes "
1371 "androidboot.veritymode=enforcing",
1372 std::string(slot_data->cmdline));
1373 avb_slot_verify_data_free(slot_data);
1374 }
1375
CmdlineWithHashtreeVerification(bool hashtree_verification_on)1376 void AvbSlotVerifyTest::CmdlineWithHashtreeVerification(
1377 bool hashtree_verification_on) {
1378 const size_t rootfs_size = 1028 * 1024;
1379 const size_t partition_size = 1536 * 1024;
1380
1381 // Generate a 1028 KiB file with known content.
1382 std::vector<uint8_t> rootfs;
1383 rootfs.resize(rootfs_size);
1384 for (size_t n = 0; n < rootfs_size; n++)
1385 rootfs[n] = uint8_t(n);
1386 base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
1387 EXPECT_EQ(rootfs_size,
1388 static_cast<const size_t>(
1389 base::WriteFile(rootfs_path,
1390 reinterpret_cast<const char*>(rootfs.data()),
1391 rootfs.size())));
1392
1393 EXPECT_COMMAND(0,
1394 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1395 "--partition_size %d --partition_name foobar "
1396 "--algorithm SHA256_RSA2048 "
1397 "--key test/data/testkey_rsa2048.pem "
1398 "--internal_release_string \"\" "
1399 "--do_not_generate_fec",
1400 rootfs_path.value().c_str(),
1401 (int)partition_size);
1402
1403 // Check that we correctly generate dm-verity kernel cmdline
1404 // snippets, if requested.
1405 GenerateVBMetaImage(
1406 "vbmeta_a.img",
1407 "SHA256_RSA2048",
1408 4,
1409 base::FilePath("test/data/testkey_rsa2048.pem"),
1410 base::StringPrintf("--setup_rootfs_from_kernel %s "
1411 "--kernel_cmdline should_be_in_both=1 "
1412 "--algorithm SHA256_RSA2048 "
1413 "--flags %d "
1414 "--internal_release_string \"\"",
1415 rootfs_path.value().c_str(),
1416 hashtree_verification_on
1417 ? 0
1418 : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED));
1419
1420 EXPECT_EQ(
1421 base::StringPrintf(
1422 "Minimum libavb version: 1.0\n"
1423 "Header Block: 256 bytes\n"
1424 "Authentication Block: 320 bytes\n"
1425 "Auxiliary Block: 960 bytes\n"
1426 "Algorithm: SHA256_RSA2048\n"
1427 "Rollback Index: 4\n"
1428 "Flags: %d\n"
1429 "Release String: ''\n"
1430 "Descriptors:\n"
1431 " Kernel Cmdline descriptor:\n"
1432 " Flags: 1\n"
1433 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity "
1434 "1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
1435 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
1436 "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
1437 "$(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
1438 " Kernel Cmdline descriptor:\n"
1439 " Flags: 2\n"
1440 " Kernel Cmdline: "
1441 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
1442 " Kernel Cmdline descriptor:\n"
1443 " Flags: 0\n"
1444 " Kernel Cmdline: 'should_be_in_both=1'\n",
1445 hashtree_verification_on ? 0
1446 : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED),
1447 InfoImage(vbmeta_image_path_));
1448
1449 ops_.set_expected_public_key(
1450 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1451
1452 // Check that avb_slot_verify() picks the cmdline decsriptors based
1453 // on their flags value.
1454 AvbSlotVerifyData* slot_data = NULL;
1455 const char* requested_partitions[] = {"boot", NULL};
1456 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1457 avb_slot_verify(ops_.avb_ops(),
1458 requested_partitions,
1459 "_a",
1460 AVB_SLOT_VERIFY_FLAGS_NONE,
1461 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1462 &slot_data));
1463 EXPECT_NE(nullptr, slot_data);
1464 if (hashtree_verification_on) {
1465 EXPECT_EQ(
1466 "dm=\"1 vroot none ro 1,0 2056 verity 1 "
1467 "PARTUUID=1234-fake-guid-for:system_a "
1468 "PARTUUID=1234-fake-guid-for:system_a 4096 4096 257 257 sha1 "
1469 "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
1470 "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
1471 "should_be_in_both=1 "
1472 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
1473 "androidboot.vbmeta.avb_version=1.0 "
1474 "androidboot.vbmeta.device_state=locked "
1475 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
1476 "androidboot.vbmeta.digest="
1477 "946996b4cd78f2c060f6bb062b94054b809cbfbe9bf4425df263a0e55395ceea "
1478 "androidboot.vbmeta.invalidate_on_error=yes "
1479 "androidboot.veritymode=enforcing",
1480 std::string(slot_data->cmdline));
1481 } else {
1482 // NOTE: androidboot.veritymode is 'disabled', not 'enforcing' and
1483 // androidboot.vbmeta.invalidate_on_error isn't set.
1484 EXPECT_EQ(
1485 "root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
1486 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
1487 "androidboot.vbmeta.avb_version=1.0 "
1488 "androidboot.vbmeta.device_state=locked "
1489 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
1490 "androidboot.vbmeta.digest="
1491 "c74338b2b366f7f774d264abb4ac06c997cbaacbf5edd70a6ef1a552f744076b "
1492 "androidboot.veritymode=disabled",
1493 std::string(slot_data->cmdline));
1494 }
1495 avb_slot_verify_data_free(slot_data);
1496 }
1497
TEST_F(AvbSlotVerifyTest,CmdlineWithHashtreeVerificationOff)1498 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOff) {
1499 CmdlineWithHashtreeVerification(false);
1500 }
1501
TEST_F(AvbSlotVerifyTest,CmdlineWithHashtreeVerificationOn)1502 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOn) {
1503 CmdlineWithHashtreeVerification(true);
1504 }
1505
CmdlineWithChainedHashtreeVerification(bool hashtree_verification_on)1506 void AvbSlotVerifyTest::CmdlineWithChainedHashtreeVerification(
1507 bool hashtree_verification_on) {
1508 const size_t system_size = 1028 * 1024;
1509 const size_t system_partition_size = 1536 * 1024;
1510
1511 // Generate a 1028 KiB file with known content.
1512 std::vector<uint8_t> contents;
1513 contents.resize(system_size);
1514 for (size_t n = 0; n < system_size; n++)
1515 contents[n] = uint8_t(n);
1516 base::FilePath system_path = testdir_.Append("system_a.img");
1517 EXPECT_EQ(system_size,
1518 static_cast<const size_t>(
1519 base::WriteFile(system_path,
1520 reinterpret_cast<const char*>(contents.data()),
1521 contents.size())));
1522
1523 // Check that we correctly generate dm-verity kernel cmdline
1524 // snippets, if requested.
1525 EXPECT_COMMAND(0,
1526 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1527 "--partition_size %d --partition_name foobar "
1528 "--algorithm SHA256_RSA2048 "
1529 "--key test/data/testkey_rsa2048.pem "
1530 "--internal_release_string \"\" "
1531 "--do_not_generate_fec "
1532 "--setup_as_rootfs_from_kernel",
1533 system_path.value().c_str(),
1534 (int)system_partition_size);
1535
1536 EXPECT_EQ(
1537 "Footer version: 1.0\n"
1538 "Image size: 1572864 bytes\n"
1539 "Original image size: 1052672 bytes\n"
1540 "VBMeta offset: 1069056\n"
1541 "VBMeta size: 1664 bytes\n"
1542 "--\n"
1543 "Minimum libavb version: 1.0\n"
1544 "Header Block: 256 bytes\n"
1545 "Authentication Block: 320 bytes\n"
1546 "Auxiliary Block: 1088 bytes\n"
1547 "Algorithm: SHA256_RSA2048\n"
1548 "Rollback Index: 0\n"
1549 "Flags: 0\n"
1550 "Release String: ''\n"
1551 "Descriptors:\n"
1552 " Hashtree descriptor:\n"
1553 " Version of dm-verity: 1\n"
1554 " Image Size: 1052672 bytes\n"
1555 " Tree Offset: 1052672\n"
1556 " Tree Size: 16384 bytes\n"
1557 " Data Block Size: 4096 bytes\n"
1558 " Hash Block Size: 4096 bytes\n"
1559 " FEC num roots: 0\n"
1560 " FEC offset: 0\n"
1561 " FEC size: 0 bytes\n"
1562 " Hash Algorithm: sha1\n"
1563 " Partition Name: foobar\n"
1564 " Salt: d00df00d\n"
1565 " Root Digest: e811611467dcd6e8dc4324e45f706c2bdd51db67\n"
1566 " Kernel Cmdline descriptor:\n"
1567 " Flags: 1\n"
1568 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity 1 "
1569 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
1570 "4096 4096 257 257 sha1 e811611467dcd6e8dc4324e45f706c2bdd51db67 "
1571 "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
1572 " Kernel Cmdline descriptor:\n"
1573 " Flags: 2\n"
1574 " Kernel Cmdline: "
1575 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n",
1576 InfoImage(system_path));
1577
1578 base::FilePath pk_path = testdir_.Append("testkey_rsa2048.avbpubkey");
1579 EXPECT_COMMAND(
1580 0,
1581 "./avbtool extract_public_key --key test/data/testkey_rsa2048.pem"
1582 " --output %s",
1583 pk_path.value().c_str());
1584
1585 GenerateVBMetaImage(
1586 "vbmeta_a.img",
1587 "SHA256_RSA2048",
1588 4,
1589 base::FilePath("test/data/testkey_rsa2048.pem"),
1590 base::StringPrintf("--kernel_cmdline should_be_in_both=1 "
1591 "--algorithm SHA256_RSA2048 "
1592 "--flags %d "
1593 "--chain_partition system:1:%s "
1594 "--internal_release_string \"\"",
1595 hashtree_verification_on
1596 ? 0
1597 : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED,
1598 pk_path.value().c_str()));
1599
1600 EXPECT_EQ(
1601 base::StringPrintf("Minimum libavb version: 1.0\n"
1602 "Header Block: 256 bytes\n"
1603 "Authentication Block: 320 bytes\n"
1604 "Auxiliary Block: 1216 bytes\n"
1605 "Algorithm: SHA256_RSA2048\n"
1606 "Rollback Index: 4\n"
1607 "Flags: %d\n"
1608 "Release String: ''\n"
1609 "Descriptors:\n"
1610 " Chain Partition descriptor:\n"
1611 " Partition Name: system\n"
1612 " Rollback Index Location: 1\n"
1613 " Public key (sha1): "
1614 "cdbb77177f731920bbe0a0f94f84d9038ae0617d\n"
1615 " Kernel Cmdline descriptor:\n"
1616 " Flags: 0\n"
1617 " Kernel Cmdline: 'should_be_in_both=1'\n",
1618 hashtree_verification_on
1619 ? 0
1620 : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED),
1621 InfoImage(vbmeta_image_path_));
1622
1623 ops_.set_expected_public_key(
1624 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1625
1626 // Check that avb_slot_verify() picks the cmdline descriptors based
1627 // on their flags value... note that these descriptors are in the
1628 // 'system' partition.
1629 AvbSlotVerifyData* slot_data = NULL;
1630 const char* requested_partitions[] = {"boot", NULL};
1631 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1632 avb_slot_verify(ops_.avb_ops(),
1633 requested_partitions,
1634 "_a",
1635 AVB_SLOT_VERIFY_FLAGS_NONE,
1636 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1637 &slot_data));
1638 EXPECT_NE(nullptr, slot_data);
1639 if (hashtree_verification_on) {
1640 EXPECT_EQ(
1641 "dm=\"1 vroot none ro 1,0 2056 verity 1 "
1642 "PARTUUID=1234-fake-guid-for:system_a "
1643 "PARTUUID=1234-fake-guid-for:system_a 4096 4096 257 257 sha1 "
1644 "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
1645 "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
1646 "should_be_in_both=1 "
1647 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
1648 "androidboot.vbmeta.avb_version=1.0 "
1649 "androidboot.vbmeta.device_state=locked "
1650 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=3456 "
1651 "androidboot.vbmeta.digest="
1652 "5ee1669b112625322657b83ec932c73dad9b0222011b5aa3e8273f4e0ee025dc "
1653 "androidboot.vbmeta.invalidate_on_error=yes "
1654 "androidboot.veritymode=enforcing",
1655 std::string(slot_data->cmdline));
1656 } else {
1657 // NOTE: androidboot.veritymode is 'disabled', not 'enforcing' and
1658 // androidboot.vbmeta.invalidate_on_error isn't set.
1659 EXPECT_EQ(
1660 "root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
1661 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
1662 "androidboot.vbmeta.avb_version=1.0 "
1663 "androidboot.vbmeta.device_state=locked "
1664 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=3456 "
1665 "androidboot.vbmeta.digest="
1666 "ae792c45a9d898b532ff9625b60043a8d9eae7e6106b9cba31837d50ba40f81c "
1667 "androidboot.veritymode=disabled",
1668 std::string(slot_data->cmdline));
1669 }
1670 avb_slot_verify_data_free(slot_data);
1671 }
1672
TEST_F(AvbSlotVerifyTest,CmdlineWithChainedHashtreeVerificationOff)1673 TEST_F(AvbSlotVerifyTest, CmdlineWithChainedHashtreeVerificationOff) {
1674 CmdlineWithChainedHashtreeVerification(false);
1675 }
1676
TEST_F(AvbSlotVerifyTest,CmdlineWithChainedHashtreeVerificationOn)1677 TEST_F(AvbSlotVerifyTest, CmdlineWithChainedHashtreeVerificationOn) {
1678 CmdlineWithChainedHashtreeVerification(true);
1679 }
1680
VerificationDisabled(bool use_avbctl)1681 void AvbSlotVerifyTest::VerificationDisabled(bool use_avbctl) {
1682 const size_t boot_part_size = 32 * 1024 * 1024;
1683 const size_t dtbo_part_size = 4 * 1024 * 1024;
1684 const size_t rootfs_size = 1028 * 1024;
1685 const size_t partition_size = 1536 * 1024;
1686
1687 // Generate boot_a.img and dtbo_a.img since avb_slot_verify() will
1688 // attempt to load them upon encountering the VERIFICATION_DISABLED
1689 // flag.
1690 base::FilePath boot_path = GenerateImage("boot_a.img", boot_part_size);
1691 const size_t DTBO_DATA_OFFSET = 42;
1692 base::FilePath dtbo_path =
1693 GenerateImage("dtbo_a.img", dtbo_part_size, DTBO_DATA_OFFSET);
1694
1695 // Generate a 1028 KiB file with known content.
1696 std::vector<uint8_t> rootfs;
1697 rootfs.resize(rootfs_size);
1698 for (size_t n = 0; n < rootfs_size; n++)
1699 rootfs[n] = uint8_t(n);
1700 base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
1701 EXPECT_EQ(rootfs_size,
1702 static_cast<const size_t>(
1703 base::WriteFile(rootfs_path,
1704 reinterpret_cast<const char*>(rootfs.data()),
1705 rootfs.size())));
1706
1707 EXPECT_COMMAND(0,
1708 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1709 "--partition_size %d --partition_name foobar "
1710 "--algorithm SHA256_RSA2048 "
1711 "--key test/data/testkey_rsa2048.pem "
1712 "--internal_release_string \"\" "
1713 "--do_not_generate_fec",
1714 rootfs_path.value().c_str(),
1715 (int)partition_size);
1716
1717 // Check that we correctly generate dm-verity kernel cmdline
1718 // snippets, if requested.
1719 GenerateVBMetaImage(
1720 "vbmeta_a.img",
1721 "SHA256_RSA2048",
1722 4,
1723 base::FilePath("test/data/testkey_rsa2048.pem"),
1724 base::StringPrintf(
1725 "--setup_rootfs_from_kernel %s "
1726 "--kernel_cmdline should_be_in_both=1 "
1727 "--algorithm SHA256_RSA2048 "
1728 "--flags %d "
1729 "--internal_release_string \"\"",
1730 rootfs_path.value().c_str(),
1731 use_avbctl ? 0 : AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED));
1732
1733 EXPECT_EQ(
1734 base::StringPrintf(
1735 "Minimum libavb version: 1.0\n"
1736 "Header Block: 256 bytes\n"
1737 "Authentication Block: 320 bytes\n"
1738 "Auxiliary Block: 960 bytes\n"
1739 "Algorithm: SHA256_RSA2048\n"
1740 "Rollback Index: 4\n"
1741 "Flags: %d\n"
1742 "Release String: ''\n"
1743 "Descriptors:\n"
1744 " Kernel Cmdline descriptor:\n"
1745 " Flags: 1\n"
1746 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity "
1747 "1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
1748 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
1749 "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
1750 "$(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
1751 " Kernel Cmdline descriptor:\n"
1752 " Flags: 2\n"
1753 " Kernel Cmdline: "
1754 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
1755 " Kernel Cmdline descriptor:\n"
1756 " Flags: 0\n"
1757 " Kernel Cmdline: 'should_be_in_both=1'\n",
1758 use_avbctl ? 0 : AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED),
1759 InfoImage(vbmeta_image_path_));
1760
1761 ops_.set_expected_public_key(
1762 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1763
1764 // Manually set the flag the same way 'avbctl disable-verification'
1765 // would do it.
1766 if (use_avbctl) {
1767 uint32_t flags_data;
1768 flags_data = avb_htobe32(AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
1769 EXPECT_EQ(AVB_IO_RESULT_OK,
1770 ops_.avb_ops()->write_to_partition(
1771 ops_.avb_ops(),
1772 "vbmeta_a",
1773 offsetof(AvbVBMetaImageHeader, flags),
1774 sizeof flags_data,
1775 &flags_data));
1776 }
1777
1778 // Check that avb_slot_verify() doesn't return any of the
1779 // descriptors and instead return a kernel command-line with
1780 // root=PARTUUID=<whatever_for_system_a> and none of the
1781 // androidboot.vbmeta.* options are set. Also ensure all the
1782 // requested partitions are loaded.
1783 //
1784 // Also if we modified via avbctl we should expect
1785 // ERROR_VERIFICATION instead of OK.
1786 //
1787 AvbSlotVerifyResult expected_result = AVB_SLOT_VERIFY_RESULT_OK;
1788 if (use_avbctl) {
1789 expected_result = AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION;
1790 }
1791 AvbSlotVerifyData* slot_data = NULL;
1792 const char* requested_partitions[] = {"boot", "dtbo", NULL};
1793 EXPECT_EQ(expected_result,
1794 avb_slot_verify(ops_.avb_ops(),
1795 requested_partitions,
1796 "_a",
1797 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
1798 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1799 &slot_data));
1800 EXPECT_NE(nullptr, slot_data);
1801 EXPECT_EQ("root=PARTUUID=1234-fake-guid-for:system_a",
1802 std::string(slot_data->cmdline));
1803 // Also make sure that it actually loads the boot and dtbo partitions.
1804 EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
1805 EXPECT_EQ("boot",
1806 std::string(slot_data->loaded_partitions[0].partition_name));
1807 EXPECT_EQ(boot_part_size, slot_data->loaded_partitions[0].data_size);
1808 for (size_t n = 0; n < boot_part_size; n++) {
1809 EXPECT_EQ(uint8_t(n), slot_data->loaded_partitions[0].data[n]);
1810 }
1811 EXPECT_EQ("dtbo",
1812 std::string(slot_data->loaded_partitions[1].partition_name));
1813 EXPECT_EQ(dtbo_part_size, slot_data->loaded_partitions[1].data_size);
1814 for (size_t n = 0; n < dtbo_part_size; n++) {
1815 EXPECT_EQ(uint8_t(n + DTBO_DATA_OFFSET),
1816 slot_data->loaded_partitions[1].data[n]);
1817 }
1818 avb_slot_verify_data_free(slot_data);
1819 }
1820
TEST_F(AvbSlotVerifyTest,VerificationDisabledUnmodified)1821 TEST_F(AvbSlotVerifyTest, VerificationDisabledUnmodified) {
1822 VerificationDisabled(false); // use_avbctl
1823 }
1824
TEST_F(AvbSlotVerifyTest,VerificationDisabledModified)1825 TEST_F(AvbSlotVerifyTest, VerificationDisabledModified) {
1826 VerificationDisabled(true); // use_avbctl
1827 }
1828
1829 // In the event that there's no vbmeta partition, we treat the vbmeta
1830 // struct from 'boot' as the top-level partition. Check that this
1831 // works.
TEST_F(AvbSlotVerifyTest,NoVBMetaPartition)1832 TEST_F(AvbSlotVerifyTest, NoVBMetaPartition) {
1833 const size_t MiB = 1024 * 1024;
1834 const size_t boot_size = 6 * MiB;
1835 const size_t boot_part_size = 8 * MiB;
1836 const size_t system_size = 16 * MiB;
1837 const size_t system_part_size = 32 * MiB;
1838 const size_t foobar_size = 8 * MiB;
1839 const size_t foobar_part_size = 16 * MiB;
1840 const size_t bazboo_size = 4 * MiB;
1841 const size_t bazboo_part_size = 8 * MiB;
1842 base::FilePath boot_path = GenerateImage("boot.img", boot_size);
1843 base::FilePath system_path = GenerateImage("system.img", system_size);
1844 base::FilePath foobar_path = GenerateImage("foobar.img", foobar_size);
1845 base::FilePath bazboo_path = GenerateImage("bazboo.img", bazboo_size);
1846
1847 EXPECT_COMMAND(0,
1848 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1849 "--partition_size %d --partition_name system "
1850 "--algorithm SHA256_RSA2048 "
1851 "--key test/data/testkey_rsa2048.pem "
1852 "--internal_release_string \"\" "
1853 "--do_not_generate_fec",
1854 system_path.value().c_str(),
1855 (int)system_part_size);
1856
1857 EXPECT_COMMAND(0,
1858 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1859 "--partition_size %d --partition_name foobar "
1860 "--algorithm SHA256_RSA2048 "
1861 "--key test/data/testkey_rsa2048.pem "
1862 "--internal_release_string \"\" "
1863 "--do_not_generate_fec",
1864 foobar_path.value().c_str(),
1865 (int)foobar_part_size);
1866
1867 EXPECT_COMMAND(0,
1868 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1869 "--partition_size %d --partition_name bazboo "
1870 "--algorithm SHA512_RSA4096 "
1871 "--key test/data/testkey_rsa4096.pem "
1872 "--internal_release_string \"\" "
1873 "--do_not_generate_fec",
1874 bazboo_path.value().c_str(),
1875 (int)bazboo_part_size);
1876
1877 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
1878 EXPECT_COMMAND(
1879 0,
1880 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
1881 " --output %s",
1882 pk_path.value().c_str());
1883
1884 // Explicitly pass "--flags 2147483648" (i.e. 1<<31) to check that
1885 // boot.img is treated as top-level. Note the corresponding "Flags:"
1886 // field below in the avbtool info_image output.
1887 EXPECT_COMMAND(0,
1888 "./avbtool add_hash_footer --salt d00df00d "
1889 "--hash_algorithm sha256 --image %s "
1890 "--partition_size %d --partition_name boot "
1891 "--algorithm SHA256_RSA2048 "
1892 "--key test/data/testkey_rsa2048.pem "
1893 "--internal_release_string \"\" "
1894 "--include_descriptors_from_image %s "
1895 "--include_descriptors_from_image %s "
1896 "--setup_rootfs_from_kernel %s "
1897 "--chain_partition bazboo:1:%s "
1898 "--flags 2147483648",
1899 boot_path.value().c_str(),
1900 (int)boot_part_size,
1901 system_path.value().c_str(),
1902 foobar_path.value().c_str(),
1903 system_path.value().c_str(),
1904 pk_path.value().c_str());
1905
1906 ASSERT_EQ(
1907 "Footer version: 1.0\n"
1908 "Image size: 8388608 bytes\n"
1909 "Original image size: 6291456 bytes\n"
1910 "VBMeta offset: 6291456\n"
1911 "VBMeta size: 3200 bytes\n"
1912 "--\n"
1913 "Minimum libavb version: 1.0\n"
1914 "Header Block: 256 bytes\n"
1915 "Authentication Block: 320 bytes\n"
1916 "Auxiliary Block: 2624 bytes\n"
1917 "Algorithm: SHA256_RSA2048\n"
1918 "Rollback Index: 0\n"
1919 "Flags: 2147483648\n"
1920 "Release String: ''\n"
1921 "Descriptors:\n"
1922 " Hash descriptor:\n"
1923 " Image Size: 6291456 bytes\n"
1924 " Hash Algorithm: sha256\n"
1925 " Partition Name: boot\n"
1926 " Salt: d00df00d\n"
1927 " Digest: "
1928 "4c109399b20e476bab15363bff55740add83e1c1e97e0b132f5c713ddd8c7868\n"
1929 " Chain Partition descriptor:\n"
1930 " Partition Name: bazboo\n"
1931 " Rollback Index Location: 1\n"
1932 " Public key (sha1): "
1933 "2597c218aae470a130f61162feaae70afd97f011\n"
1934 " Kernel Cmdline descriptor:\n"
1935 " Flags: 1\n"
1936 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 32768 verity 1 "
1937 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
1938 "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
1939 "d00df00d 2 $(ANDROID_VERITY_MODE) ignore_zero_blocks\" root=/dev/dm-0'\n"
1940 " Kernel Cmdline descriptor:\n"
1941 " Flags: 2\n"
1942 " Kernel Cmdline: "
1943 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
1944 " Hashtree descriptor:\n"
1945 " Version of dm-verity: 1\n"
1946 " Image Size: 16777216 bytes\n"
1947 " Tree Offset: 16777216\n"
1948 " Tree Size: 135168 bytes\n"
1949 " Data Block Size: 4096 bytes\n"
1950 " Hash Block Size: 4096 bytes\n"
1951 " FEC num roots: 0\n"
1952 " FEC offset: 0\n"
1953 " FEC size: 0 bytes\n"
1954 " Hash Algorithm: sha1\n"
1955 " Partition Name: system\n"
1956 " Salt: d00df00d\n"
1957 " Root Digest: c9ffc3bfae5000269a55a56621547fd1fcf819df\n"
1958 " Hashtree descriptor:\n"
1959 " Version of dm-verity: 1\n"
1960 " Image Size: 8388608 bytes\n"
1961 " Tree Offset: 8388608\n"
1962 " Tree Size: 69632 bytes\n"
1963 " Data Block Size: 4096 bytes\n"
1964 " Hash Block Size: 4096 bytes\n"
1965 " FEC num roots: 0\n"
1966 " FEC offset: 0\n"
1967 " FEC size: 0 bytes\n"
1968 " Hash Algorithm: sha1\n"
1969 " Partition Name: foobar\n"
1970 " Salt: d00df00d\n"
1971 " Root Digest: d52d93c988d336a79abe1c05240ae9a79a9b7d61\n",
1972 InfoImage(boot_path));
1973
1974 ops_.set_expected_public_key(
1975 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1976
1977 // Now check that libavb will fall back to reading from 'boot'
1978 // instead of 'vbmeta' when encountering
1979 // AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION on trying to read from
1980 // 'vbmeta'.
1981 AvbSlotVerifyData* slot_data = NULL;
1982 const char* requested_partitions[] = {"boot", NULL};
1983 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1984 avb_slot_verify(ops_.avb_ops(),
1985 requested_partitions,
1986 "",
1987 AVB_SLOT_VERIFY_FLAGS_NONE,
1988 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
1989 &slot_data));
1990 EXPECT_NE(nullptr, slot_data);
1991 // Note 'boot' in the value androidboot.vbmeta.device since we've
1992 // read from 'boot' and not 'vbmeta'.
1993 EXPECT_EQ(
1994 "dm=\"1 vroot none ro 1,0 32768 verity 1 "
1995 "PARTUUID=1234-fake-guid-for:system PARTUUID=1234-fake-guid-for:system "
1996 "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
1997 "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
1998 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:boot "
1999 "androidboot.vbmeta.avb_version=1.0 "
2000 "androidboot.vbmeta.device_state=locked "
2001 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=5312 "
2002 "androidboot.vbmeta.digest="
2003 "6b06719a940e5d8fa53ffef91eb4f0517ff0dda9833b90be1c9624ab3a5261d2 "
2004 "androidboot.vbmeta.invalidate_on_error=yes "
2005 "androidboot.veritymode=enforcing",
2006 std::string(slot_data->cmdline));
2007 avb_slot_verify_data_free(slot_data);
2008 }
2009
2010 // Check that non-zero flags in chained partition are caught in
2011 // avb_slot_verify().
TEST_F(AvbSlotVerifyTest,ChainedPartitionEnforceFlagsZero)2012 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceFlagsZero) {
2013 size_t boot_partition_size = 16 * 1024 * 1024;
2014 const size_t boot_image_size = 5 * 1024 * 1024;
2015 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
2016 const char* requested_partitions[] = {"boot", NULL};
2017
2018 EXPECT_COMMAND(0,
2019 "./avbtool add_hash_footer"
2020 " --image %s"
2021 " --kernel_cmdline 'cmdline2 in hash footer'"
2022 " --rollback_index 12"
2023 " --partition_name boot"
2024 " --partition_size %zd"
2025 " --algorithm SHA256_RSA4096"
2026 " --key test/data/testkey_rsa4096.pem"
2027 " --salt deadbeef"
2028 " --flags 1"
2029 " --internal_release_string \"\"",
2030 boot_path.value().c_str(),
2031 boot_partition_size);
2032
2033 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
2034 EXPECT_COMMAND(
2035 0,
2036 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
2037 " --output %s",
2038 pk_path.value().c_str());
2039
2040 GenerateVBMetaImage(
2041 "vbmeta_a.img",
2042 "SHA256_RSA2048",
2043 11,
2044 base::FilePath("test/data/testkey_rsa2048.pem"),
2045 base::StringPrintf("--chain_partition boot:1:%s"
2046 " --kernel_cmdline 'cmdline2 in vbmeta'"
2047 " --internal_release_string \"\"",
2048 pk_path.value().c_str()));
2049
2050 ops_.set_expected_public_key(
2051 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
2052
2053 AvbSlotVerifyData* slot_data = NULL;
2054 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
2055 avb_slot_verify(ops_.avb_ops(),
2056 requested_partitions,
2057 "_a",
2058 AVB_SLOT_VERIFY_FLAGS_NONE,
2059 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2060 &slot_data));
2061 EXPECT_EQ(nullptr, slot_data);
2062 }
2063
2064 // Check that chain descriptors in chained partitions are caught in
2065 // avb_slot_verify().
TEST_F(AvbSlotVerifyTest,ChainedPartitionEnforceNoChainPartitions)2066 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceNoChainPartitions) {
2067 size_t boot_partition_size = 16 * 1024 * 1024;
2068 const size_t boot_image_size = 5 * 1024 * 1024;
2069 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
2070 const char* requested_partitions[] = {"boot", NULL};
2071
2072 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
2073 EXPECT_COMMAND(
2074 0,
2075 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
2076 " --output %s",
2077 pk_path.value().c_str());
2078
2079 EXPECT_COMMAND(0,
2080 "./avbtool add_hash_footer"
2081 " --image %s"
2082 " --kernel_cmdline 'cmdline2 in hash footer'"
2083 " --rollback_index 12"
2084 " --partition_name boot"
2085 " --partition_size %zd"
2086 " --algorithm SHA256_RSA4096"
2087 " --key test/data/testkey_rsa4096.pem"
2088 " --salt deadbeef"
2089 " --chain_partition other:2:%s"
2090 " --internal_release_string \"\"",
2091 boot_path.value().c_str(),
2092 boot_partition_size,
2093 pk_path.value().c_str());
2094
2095 GenerateVBMetaImage(
2096 "vbmeta_a.img",
2097 "SHA256_RSA2048",
2098 11,
2099 base::FilePath("test/data/testkey_rsa2048.pem"),
2100 base::StringPrintf("--chain_partition boot:1:%s"
2101 " --kernel_cmdline 'cmdline2 in vbmeta'"
2102 " --internal_release_string \"\"",
2103 pk_path.value().c_str()));
2104
2105 ops_.set_expected_public_key(
2106 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
2107
2108 AvbSlotVerifyData* slot_data = NULL;
2109 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
2110 avb_slot_verify(ops_.avb_ops(),
2111 requested_partitions,
2112 "_a",
2113 AVB_SLOT_VERIFY_FLAGS_NONE,
2114 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2115 &slot_data));
2116 EXPECT_EQ(nullptr, slot_data);
2117 }
2118
TEST_F(AvbSlotVerifyTest,HashtreeErrorModes)2119 TEST_F(AvbSlotVerifyTest, HashtreeErrorModes) {
2120 const size_t MiB = 1024 * 1024;
2121 const size_t system_size = 16 * MiB;
2122 const size_t system_part_size = 32 * MiB;
2123 base::FilePath system_path = GenerateImage("system.img", system_size);
2124
2125 EXPECT_COMMAND(0,
2126 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
2127 "--partition_size %d --partition_name system "
2128 "--algorithm SHA256_RSA2048 "
2129 "--key test/data/testkey_rsa2048.pem "
2130 "--internal_release_string \"\" "
2131 "--do_not_generate_fec",
2132 system_path.value().c_str(),
2133 (int)system_part_size);
2134
2135 GenerateVBMetaImage("vbmeta.img",
2136 "SHA256_RSA2048",
2137 0,
2138 base::FilePath("test/data/testkey_rsa2048.pem"),
2139 base::StringPrintf("--setup_rootfs_from_kernel %s "
2140 "--include_descriptors_from_image %s"
2141 " --internal_release_string \"\"",
2142 system_path.value().c_str(),
2143 system_path.value().c_str()));
2144
2145 ops_.set_expected_public_key(
2146 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
2147
2148 AvbSlotVerifyData* slot_data = NULL;
2149 const char* requested_partitions[] = {"boot", NULL};
2150
2151 // For AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE we should get
2152 // androidboot.vbmeta.invalidate_on_error=yes and
2153 // androidboot.veritymode=enforcing. We should get
2154 // 'restart_on_corruption' in the dm="..." string.
2155 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2156 avb_slot_verify(ops_.avb_ops(),
2157 requested_partitions,
2158 "",
2159 AVB_SLOT_VERIFY_FLAGS_NONE,
2160 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2161 &slot_data));
2162 EXPECT_NE(nullptr, slot_data);
2163 EXPECT_EQ(
2164 "dm=\"1 vroot none ro 1,0 32768 verity 1 "
2165 "PARTUUID=1234-fake-guid-for:system "
2166 "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
2167 "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
2168 "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
2169 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
2170 "androidboot.vbmeta.avb_version=1.0 "
2171 "androidboot.vbmeta.device_state=locked "
2172 "androidboot.vbmeta.hash_alg=sha256 "
2173 "androidboot.vbmeta.size=1664 "
2174 "androidboot.vbmeta.digest="
2175 "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
2176 "androidboot.vbmeta.invalidate_on_error=yes "
2177 "androidboot.veritymode=enforcing",
2178 std::string(slot_data->cmdline));
2179 avb_slot_verify_data_free(slot_data);
2180
2181 // For AVB_HASHTREE_ERROR_MODE_RESTART we should get
2182 // androidboot.veritymode=enforcing and
2183 // androidboot.vbmeta.invalidate_on_error should be unset. We should
2184 // get 'restart_on_corruption' in the dm="..." string.
2185 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2186 avb_slot_verify(ops_.avb_ops(),
2187 requested_partitions,
2188 "",
2189 AVB_SLOT_VERIFY_FLAGS_NONE,
2190 AVB_HASHTREE_ERROR_MODE_RESTART,
2191 &slot_data));
2192 EXPECT_NE(nullptr, slot_data);
2193 EXPECT_EQ(
2194 "dm=\"1 vroot none ro 1,0 32768 verity 1 "
2195 "PARTUUID=1234-fake-guid-for:system "
2196 "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
2197 "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
2198 "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
2199 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
2200 "androidboot.vbmeta.avb_version=1.0 "
2201 "androidboot.vbmeta.device_state=locked "
2202 "androidboot.vbmeta.hash_alg=sha256 "
2203 "androidboot.vbmeta.size=1664 "
2204 "androidboot.vbmeta.digest="
2205 "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
2206 "androidboot.veritymode=enforcing",
2207 std::string(slot_data->cmdline));
2208 avb_slot_verify_data_free(slot_data);
2209
2210 // For AVB_HASHTREE_ERROR_MODE_EIO we should get
2211 // androidboot.veritymode=eio and
2212 // androidboot.vbmeta.invalidate_on_error should be unset. We should
2213 // get 'ignore_zero_blocks' in the dm="..." string.
2214 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2215 avb_slot_verify(ops_.avb_ops(),
2216 requested_partitions,
2217 "",
2218 AVB_SLOT_VERIFY_FLAGS_NONE,
2219 AVB_HASHTREE_ERROR_MODE_EIO,
2220 &slot_data));
2221 EXPECT_NE(nullptr, slot_data);
2222 EXPECT_EQ(
2223 "dm=\"1 vroot none ro 1,0 32768 verity 1 "
2224 "PARTUUID=1234-fake-guid-for:system "
2225 "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
2226 "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
2227 "ignore_zero_blocks ignore_zero_blocks\" root=/dev/dm-0 "
2228 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
2229 "androidboot.vbmeta.avb_version=1.0 "
2230 "androidboot.vbmeta.device_state=locked "
2231 "androidboot.vbmeta.hash_alg=sha256 "
2232 "androidboot.vbmeta.size=1664 "
2233 "androidboot.vbmeta.digest="
2234 "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
2235 "androidboot.veritymode=eio",
2236 std::string(slot_data->cmdline));
2237 avb_slot_verify_data_free(slot_data);
2238
2239 // For AVB_HASHTREE_ERROR_MODE_LOGGING we should get
2240 // androidboot.veritymode=logging and
2241 // androidboot.vbmeta.invalidate_on_error should be unset. We should
2242 // get 'ignore_corruption' in the dm="..." string.
2243 //
2244 // Check AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT is returned
2245 // unless we pass AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR.
2246 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT,
2247 avb_slot_verify(ops_.avb_ops(),
2248 requested_partitions,
2249 "",
2250 AVB_SLOT_VERIFY_FLAGS_NONE,
2251 AVB_HASHTREE_ERROR_MODE_LOGGING,
2252 &slot_data));
2253 EXPECT_EQ(nullptr, slot_data);
2254 // --
2255 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2256 avb_slot_verify(ops_.avb_ops(),
2257 requested_partitions,
2258 "",
2259 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
2260 AVB_HASHTREE_ERROR_MODE_LOGGING,
2261 &slot_data));
2262 EXPECT_NE(nullptr, slot_data);
2263 EXPECT_EQ(
2264 "dm=\"1 vroot none ro 1,0 32768 verity 1 "
2265 "PARTUUID=1234-fake-guid-for:system "
2266 "PARTUUID=1234-fake-guid-for:system 4096 4096 4096 4096 sha1 "
2267 "c9ffc3bfae5000269a55a56621547fd1fcf819df d00df00d 2 "
2268 "ignore_corruption ignore_zero_blocks\" root=/dev/dm-0 "
2269 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
2270 "androidboot.vbmeta.avb_version=1.0 "
2271 "androidboot.vbmeta.device_state=locked "
2272 "androidboot.vbmeta.hash_alg=sha256 "
2273 "androidboot.vbmeta.size=1664 "
2274 "androidboot.vbmeta.digest="
2275 "e6c8c7d819f6b05ec0ebf7f73ee3b09f8d395e70ee040fe34f8fa6bccc8df798 "
2276 "androidboot.veritymode=logging",
2277 std::string(slot_data->cmdline));
2278 avb_slot_verify_data_free(slot_data);
2279
2280 // Check we'll get androidboot.veritymode=disabled for any
2281 // |hashtree_error_mode| if dm-verity is disabled.
2282 GenerateVBMetaImage("vbmeta.img",
2283 "SHA256_RSA2048",
2284 0,
2285 base::FilePath("test/data/testkey_rsa2048.pem"),
2286 base::StringPrintf("--setup_rootfs_from_kernel %s "
2287 "--include_descriptors_from_image %s "
2288 "--set_hashtree_disabled_flag "
2289 "--internal_release_string \"\"",
2290 system_path.value().c_str(),
2291 system_path.value().c_str()));
2292 for (int n = 0; n < 4; n++) {
2293 AvbHashtreeErrorMode modes[4] = {
2294 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
2295 AVB_HASHTREE_ERROR_MODE_RESTART,
2296 AVB_HASHTREE_ERROR_MODE_EIO,
2297 AVB_HASHTREE_ERROR_MODE_LOGGING};
2298 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
2299 avb_slot_verify(ops_.avb_ops(),
2300 requested_partitions,
2301 "",
2302 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR,
2303 modes[n],
2304 &slot_data));
2305 EXPECT_NE(nullptr, slot_data);
2306 EXPECT_EQ(
2307 "root=PARTUUID=1234-fake-guid-for:system "
2308 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
2309 "androidboot.vbmeta.avb_version=1.0 "
2310 "androidboot.vbmeta.device_state=locked "
2311 "androidboot.vbmeta.hash_alg=sha256 "
2312 "androidboot.vbmeta.size=1664 "
2313 "androidboot.vbmeta.digest="
2314 "e73a466d63f451dcf5c051ff12a32c006ba282a34b37420c0d563f0282cad703 "
2315 "androidboot.veritymode=disabled",
2316 std::string(slot_data->cmdline));
2317 avb_slot_verify_data_free(slot_data);
2318 }
2319 }
2320
2321 } // namespace avb
2322