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
49 FakeAvbOps ops_;
50 };
51
TEST_F(AvbSlotVerifyTest,Basic)52 TEST_F(AvbSlotVerifyTest, Basic) {
53 GenerateVBMetaImage("vbmeta_a.img",
54 "SHA256_RSA2048",
55 0,
56 base::FilePath("test/data/testkey_rsa2048.pem"),
57 "--internal_release_string \"\"");
58
59 ops_.set_expected_public_key(
60 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
61
62 AvbSlotVerifyData* slot_data = NULL;
63 const char* requested_partitions[] = {"boot", NULL};
64 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
65 avb_slot_verify(ops_.avb_ops(),
66 requested_partitions,
67 "_a",
68 false /* allow_verification_error */,
69 &slot_data));
70 EXPECT_NE(nullptr, slot_data);
71 EXPECT_EQ(
72 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
73 "androidboot.vbmeta.avb_version=1.0 "
74 "androidboot.vbmeta.device_state=locked "
75 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
76 "androidboot.vbmeta.digest="
77 "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
78 std::string(slot_data->cmdline));
79 avb_slot_verify_data_free(slot_data);
80 }
81
TEST_F(AvbSlotVerifyTest,BasicSha512)82 TEST_F(AvbSlotVerifyTest, BasicSha512) {
83 GenerateVBMetaImage("vbmeta_a.img",
84 "SHA512_RSA2048",
85 0,
86 base::FilePath("test/data/testkey_rsa2048.pem"),
87 "--internal_release_string \"\"");
88
89 ops_.set_expected_public_key(
90 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
91
92 AvbSlotVerifyData* slot_data = NULL;
93 const char* requested_partitions[] = {"boot", NULL};
94 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
95 avb_slot_verify(ops_.avb_ops(),
96 requested_partitions,
97 "_a",
98 false /* allow_verification_error */,
99 &slot_data));
100 EXPECT_NE(nullptr, slot_data);
101 EXPECT_EQ(
102 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
103 "androidboot.vbmeta.avb_version=1.0 "
104 "androidboot.vbmeta.device_state=locked "
105 "androidboot.vbmeta.hash_alg=sha512 androidboot.vbmeta.size=1152 "
106 "androidboot.vbmeta.digest="
107 "cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
108 "e01932cf70f38b8960877470b448f1588dff022808387cc52fa77e77",
109 std::string(slot_data->cmdline));
110 avb_slot_verify_data_free(slot_data);
111 }
112
TEST_F(AvbSlotVerifyTest,BasicUnlocked)113 TEST_F(AvbSlotVerifyTest, BasicUnlocked) {
114 GenerateVBMetaImage("vbmeta_a.img",
115 "SHA256_RSA2048",
116 0,
117 base::FilePath("test/data/testkey_rsa2048.pem"),
118 "--internal_release_string \"\"");
119
120 ops_.set_expected_public_key(
121 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
122
123 ops_.set_stored_is_device_unlocked(true);
124
125 AvbSlotVerifyData* slot_data = NULL;
126 const char* requested_partitions[] = {"boot", NULL};
127 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
128 avb_slot_verify(ops_.avb_ops(),
129 requested_partitions,
130 "_a",
131 false /* allow_verification_error */,
132 &slot_data));
133 EXPECT_NE(nullptr, slot_data);
134 EXPECT_EQ(
135 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
136 "androidboot.vbmeta.avb_version=1.0 "
137 "androidboot.vbmeta.device_state=unlocked "
138 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
139 "androidboot.vbmeta.digest="
140 "4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
141 std::string(slot_data->cmdline));
142 avb_slot_verify_data_free(slot_data);
143 }
144
TEST_F(AvbSlotVerifyTest,SlotDataIsCorrect)145 TEST_F(AvbSlotVerifyTest, SlotDataIsCorrect) {
146 GenerateVBMetaImage("vbmeta_a.img",
147 "SHA256_RSA2048",
148 0,
149 base::FilePath("test/data/testkey_rsa2048.pem"),
150 "--internal_release_string \"\"");
151
152 ops_.set_expected_public_key(
153 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
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 false /* allow_verification_error */,
162 &slot_data));
163 EXPECT_NE(nullptr, slot_data);
164 avb_slot_verify_data_free(slot_data);
165 }
166
TEST_F(AvbSlotVerifyTest,WrongPublicKey)167 TEST_F(AvbSlotVerifyTest, WrongPublicKey) {
168 GenerateVBMetaImage("vbmeta_a.img",
169 "SHA256_RSA2048",
170 0,
171 base::FilePath("test/data/testkey_rsa2048.pem"),
172 "--internal_release_string \"\"");
173
174 AvbSlotVerifyData* slot_data = NULL;
175 const char* requested_partitions[] = {"boot", NULL};
176 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
177 avb_slot_verify(ops_.avb_ops(),
178 requested_partitions,
179 "_a",
180 false /* allow_verification_error */,
181 &slot_data));
182 EXPECT_EQ(nullptr, slot_data);
183 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
184 avb_slot_verify(ops_.avb_ops(),
185 requested_partitions,
186 "_a",
187 true /* allow_verification_error */,
188 &slot_data));
189 EXPECT_NE(nullptr, slot_data);
190 avb_slot_verify_data_free(slot_data);
191 }
192
TEST_F(AvbSlotVerifyTest,NoImage)193 TEST_F(AvbSlotVerifyTest, NoImage) {
194 const char* requested_partitions[] = {"boot", NULL};
195 AvbSlotVerifyData* slot_data = NULL;
196 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
197 avb_slot_verify(ops_.avb_ops(),
198 requested_partitions,
199 "_a",
200 false /* allow_verification_error */,
201 &slot_data));
202 EXPECT_EQ(nullptr, slot_data);
203 }
204
TEST_F(AvbSlotVerifyTest,UnsignedVBMeta)205 TEST_F(AvbSlotVerifyTest, UnsignedVBMeta) {
206 GenerateVBMetaImage("vbmeta_a.img",
207 "",
208 0,
209 base::FilePath(""),
210 "--internal_release_string \"\"");
211
212 AvbSlotVerifyData* slot_data = NULL;
213 const char* requested_partitions[] = {"boot", NULL};
214 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
215 avb_slot_verify(ops_.avb_ops(),
216 requested_partitions,
217 "_a",
218 false /* allow_verification_error */,
219 &slot_data));
220 EXPECT_EQ(nullptr, slot_data);
221 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
222 avb_slot_verify(ops_.avb_ops(),
223 requested_partitions,
224 "_a",
225 true /* allow_verification_error */,
226 &slot_data));
227 EXPECT_NE(nullptr, slot_data);
228 avb_slot_verify_data_free(slot_data);
229 }
230
TEST_F(AvbSlotVerifyTest,CorruptedImage)231 TEST_F(AvbSlotVerifyTest, CorruptedImage) {
232 GenerateVBMetaImage("vbmeta_a.img",
233 "SHA256_RSA2048",
234 0,
235 base::FilePath("test/data/testkey_rsa2048.pem"),
236 "--internal_release_string \"\"");
237
238 // Corrupt four bytes of data in the end of the image. Since the aux
239 // data is at the end and this data is signed, this will change the
240 // value of the computed hash.
241 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
242 EXPECT_EQ(AVB_IO_RESULT_OK,
243 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
244 "vbmeta_a",
245 -4, // offset from end
246 sizeof corrupt_data,
247 corrupt_data));
248
249 AvbSlotVerifyData* slot_data = NULL;
250 const char* requested_partitions[] = {"boot", NULL};
251 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
252 avb_slot_verify(ops_.avb_ops(),
253 requested_partitions,
254 "_a",
255 false /* allow_verification_error */,
256 &slot_data));
257 EXPECT_EQ(nullptr, slot_data);
258 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
259 avb_slot_verify(ops_.avb_ops(),
260 requested_partitions,
261 "_a",
262 true /* allow_verification_error */,
263 &slot_data));
264 EXPECT_NE(nullptr, slot_data);
265 avb_slot_verify_data_free(slot_data);
266 }
267
TEST_F(AvbSlotVerifyTest,CorruptedMetadata)268 TEST_F(AvbSlotVerifyTest, CorruptedMetadata) {
269 GenerateVBMetaImage("vbmeta_a.img",
270 "SHA256_RSA2048",
271 0,
272 base::FilePath("test/data/testkey_rsa2048.pem"),
273 "--internal_release_string \"\"");
274
275 // Corrupt four bytes of data in the beginning of the image. Unlike
276 // the CorruptedImage test-case above (which is valid metadata) this
277 // will make the metadata invalid and render the slot unbootable
278 // even if the device is unlocked. Specifically no AvbSlotVerifyData
279 // is returned.
280 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
281 EXPECT_EQ(AVB_IO_RESULT_OK,
282 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
283 "vbmeta_a",
284 0, // offset: beginning
285 sizeof corrupt_data,
286 corrupt_data));
287
288 AvbSlotVerifyData* slot_data = NULL;
289 const char* requested_partitions[] = {"boot", NULL};
290 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
291 avb_slot_verify(ops_.avb_ops(),
292 requested_partitions,
293 "_a",
294 false /* allow_verification_error */,
295 &slot_data));
296 EXPECT_EQ(nullptr, slot_data);
297 }
298
TEST_F(AvbSlotVerifyTest,RollbackIndex)299 TEST_F(AvbSlotVerifyTest, RollbackIndex) {
300 GenerateVBMetaImage("vbmeta_a.img",
301 "SHA256_RSA2048",
302 42,
303 base::FilePath("test/data/testkey_rsa2048.pem"),
304 "--internal_release_string \"\"");
305
306 ops_.set_expected_public_key(
307 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
308
309 AvbSlotVerifyData* slot_data = NULL;
310 const char* requested_partitions[] = {"boot", NULL};
311
312 // First try with 42 as the stored rollback index - this should
313 // succeed since the image rollback index is 42 (as set above).
314 ops_.set_stored_rollback_indexes({{0, 42}});
315 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
316 avb_slot_verify(ops_.avb_ops(),
317 requested_partitions,
318 "_a",
319 false /* allow_verification_error */,
320 &slot_data));
321 EXPECT_NE(nullptr, slot_data);
322 avb_slot_verify_data_free(slot_data);
323
324 // Then try with 43 for the stored rollback index - this should fail
325 // because the image has rollback index 42 which is less than 43.
326 ops_.set_stored_rollback_indexes({{0, 43}});
327 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
328 avb_slot_verify(ops_.avb_ops(),
329 requested_partitions,
330 "_a",
331 false /* allow_verification_error */,
332 &slot_data));
333 EXPECT_EQ(nullptr, slot_data);
334 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
335 avb_slot_verify(ops_.avb_ops(),
336 requested_partitions,
337 "_a",
338 true /* allow_verification_error */,
339 &slot_data));
340 EXPECT_NE(nullptr, slot_data);
341 avb_slot_verify_data_free(slot_data);
342 }
343
TEST_F(AvbSlotVerifyTest,HashDescriptorInVBMeta)344 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMeta) {
345 const size_t boot_partition_size = 16 * 1024 * 1024;
346 const size_t boot_image_size = 5 * 1024 * 1024;
347 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
348
349 EXPECT_COMMAND(
350 0,
351 "./avbtool add_hash_footer"
352 " --image %s"
353 " --rollback_index 0"
354 " --partition_name boot"
355 " --partition_size %zd"
356 " --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
357 " --salt deadbeef"
358 " --internal_release_string \"\"",
359 boot_path.value().c_str(),
360 boot_partition_size);
361
362 GenerateVBMetaImage(
363 "vbmeta_a.img",
364 "SHA256_RSA2048",
365 4,
366 base::FilePath("test/data/testkey_rsa2048.pem"),
367 base::StringPrintf(
368 "--include_descriptors_from_image %s"
369 " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
370 " --internal_release_string \"\"",
371 boot_path.value().c_str()));
372
373 EXPECT_EQ(
374 "Minimum libavb version: 1.0\n"
375 "Header Block: 256 bytes\n"
376 "Authentication Block: 320 bytes\n"
377 "Auxiliary Block: 896 bytes\n"
378 "Algorithm: SHA256_RSA2048\n"
379 "Rollback Index: 4\n"
380 "Flags: 0\n"
381 "Release String: ''\n"
382 "Descriptors:\n"
383 " Kernel Cmdline descriptor:\n"
384 " Flags: 0\n"
385 " Kernel Cmdline: 'cmdline in vbmeta "
386 "$(ANDROID_BOOT_PARTUUID)'\n"
387 " Hash descriptor:\n"
388 " Image Size: 5242880 bytes\n"
389 " Hash Algorithm: sha256\n"
390 " Partition Name: boot\n"
391 " Salt: deadbeef\n"
392 " Digest: "
393 "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
394 " Kernel Cmdline descriptor:\n"
395 " Flags: 0\n"
396 " Kernel Cmdline: 'cmdline in hash footer "
397 "$(ANDROID_SYSTEM_PARTUUID)'\n",
398 InfoImage(vbmeta_image_path_));
399
400 EXPECT_COMMAND(0,
401 "./avbtool erase_footer"
402 " --image %s",
403 boot_path.value().c_str());
404
405 // With no footer, 'avbtool info_image' should fail (exit status 1).
406 EXPECT_COMMAND(
407 1, "./avbtool info_image --image %s", boot_path.value().c_str());
408
409 ops_.set_expected_public_key(
410 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
411
412 AvbSlotVerifyData* slot_data = NULL;
413 const char* requested_partitions[] = {"boot", NULL};
414 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
415 avb_slot_verify(ops_.avb_ops(),
416 requested_partitions,
417 "_a",
418 false /* allow_verification_error */,
419 &slot_data));
420 EXPECT_NE(nullptr, slot_data);
421
422 // Now verify the slot data. The vbmeta data should match our
423 // vbmeta_image_ member.
424 EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
425 EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
426 EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
427 EXPECT_EQ(0,
428 memcmp(vbmeta_image_.data(),
429 slot_data->vbmeta_images[0].vbmeta_data,
430 slot_data->vbmeta_images[0].vbmeta_size));
431
432 // The boot image data should match what is generated above with
433 // GenerateImage().
434 EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
435 EXPECT_EQ("boot",
436 std::string(slot_data->loaded_partitions[0].partition_name));
437 EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
438 for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
439 EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
440 }
441
442 // This should match the two cmdlines with a space (U+0020) between
443 // them and the $(ANDROID_SYSTEM_PARTUUID) and
444 // $(ANDROID_BOOT_PARTUUID) variables replaced.
445 EXPECT_EQ(
446 "cmdline in vbmeta 1234-fake-guid-for:boot_a cmdline in hash footer "
447 "1234-fake-guid-for:system_a "
448 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
449 "androidboot.vbmeta.avb_version=1.0 "
450 "androidboot.vbmeta.device_state=locked "
451 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
452 "androidboot.vbmeta.digest="
453 "34cdb59b955aa35d4da97701f304fabf7392eecca8c50ff1a0b7b6e1c9aaa1b8",
454 std::string(slot_data->cmdline));
455 EXPECT_EQ(4UL, slot_data->rollback_indexes[0]);
456 for (size_t n = 1; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
457 EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
458 }
459 avb_slot_verify_data_free(slot_data);
460 }
461
TEST_F(AvbSlotVerifyTest,HashDescriptorInVBMetaCorruptBoot)462 TEST_F(AvbSlotVerifyTest, HashDescriptorInVBMetaCorruptBoot) {
463 size_t boot_partition_size = 16 * 1024 * 1024;
464 base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
465 const char* requested_partitions[] = {"boot", NULL};
466
467 EXPECT_COMMAND(0,
468 "./avbtool add_hash_footer"
469 " --image %s"
470 " --rollback_index 0"
471 " --partition_name boot"
472 " --partition_size %zd"
473 " --salt deadbeef"
474 " --internal_release_string \"\"",
475 boot_path.value().c_str(),
476 boot_partition_size);
477
478 GenerateVBMetaImage("vbmeta_a.img",
479 "SHA256_RSA2048",
480 0,
481 base::FilePath("test/data/testkey_rsa2048.pem"),
482 base::StringPrintf("--include_descriptors_from_image %s"
483 " --internal_release_string \"\"",
484 boot_path.value().c_str()));
485
486 EXPECT_COMMAND(0,
487 "./avbtool erase_footer"
488 " --image %s",
489 boot_path.value().c_str());
490
491 ops_.set_expected_public_key(
492 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
493
494 // So far, so good.
495 AvbSlotVerifyData* slot_data = NULL;
496 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
497 avb_slot_verify(ops_.avb_ops(),
498 requested_partitions,
499 "_a",
500 false /* allow_verification_error */,
501 &slot_data));
502 EXPECT_NE(nullptr, slot_data);
503 avb_slot_verify_data_free(slot_data);
504
505 // Now corrupt boot_a.img and expect verification error.
506 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
507 EXPECT_EQ(AVB_IO_RESULT_OK,
508 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
509 "boot_a",
510 1024 * 1024, // offset: 1 MiB
511 sizeof corrupt_data,
512 corrupt_data));
513
514 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
515 avb_slot_verify(ops_.avb_ops(),
516 requested_partitions,
517 "_a",
518 false /* allow_verification_error */,
519 &slot_data));
520 EXPECT_EQ(nullptr, slot_data);
521 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
522 avb_slot_verify(ops_.avb_ops(),
523 requested_partitions,
524 "_a",
525 true /* allow_verification_error */,
526 &slot_data));
527 EXPECT_NE(nullptr, slot_data);
528 avb_slot_verify_data_free(slot_data);
529 }
530
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartition)531 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartition) {
532 size_t boot_partition_size = 16 * 1024 * 1024;
533 const size_t boot_image_size = 5 * 1024 * 1024;
534 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
535 const char* requested_partitions[] = {"boot", NULL};
536
537 EXPECT_COMMAND(0,
538 "./avbtool add_hash_footer"
539 " --image %s"
540 " --kernel_cmdline 'cmdline2 in hash footer'"
541 " --rollback_index 12"
542 " --partition_name boot"
543 " --partition_size %zd"
544 " --algorithm SHA256_RSA4096"
545 " --key test/data/testkey_rsa4096.pem"
546 " --salt deadbeef"
547 " --internal_release_string \"\"",
548 boot_path.value().c_str(),
549 boot_partition_size);
550
551 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
552 EXPECT_COMMAND(
553 0,
554 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
555 " --output %s",
556 pk_path.value().c_str());
557
558 GenerateVBMetaImage(
559 "vbmeta_a.img",
560 "SHA256_RSA2048",
561 11,
562 base::FilePath("test/data/testkey_rsa2048.pem"),
563 base::StringPrintf("--chain_partition boot:1:%s"
564 " --kernel_cmdline 'cmdline2 in vbmeta'"
565 " --internal_release_string \"\"",
566 pk_path.value().c_str()));
567
568 EXPECT_EQ(
569 "Minimum libavb version: 1.0\n"
570 "Header Block: 256 bytes\n"
571 "Authentication Block: 320 bytes\n"
572 "Auxiliary Block: 1728 bytes\n"
573 "Algorithm: SHA256_RSA2048\n"
574 "Rollback Index: 11\n"
575 "Flags: 0\n"
576 "Release String: ''\n"
577 "Descriptors:\n"
578 " Chain Partition descriptor:\n"
579 " Partition Name: boot\n"
580 " Rollback Index Location: 1\n"
581 " Public key (sha1): "
582 "2597c218aae470a130f61162feaae70afd97f011\n"
583 " Kernel Cmdline descriptor:\n"
584 " Flags: 0\n"
585 " Kernel Cmdline: 'cmdline2 in vbmeta'\n",
586 InfoImage(vbmeta_image_path_));
587
588 EXPECT_EQ(
589 "Footer version: 1.0\n"
590 "Image size: 16777216 bytes\n"
591 "Original image size: 5242880 bytes\n"
592 "VBMeta offset: 5242880\n"
593 "VBMeta size: 2112 bytes\n"
594 "--\n"
595 "Minimum libavb version: 1.0\n"
596 "Header Block: 256 bytes\n"
597 "Authentication Block: 576 bytes\n"
598 "Auxiliary Block: 1280 bytes\n"
599 "Algorithm: SHA256_RSA4096\n"
600 "Rollback Index: 12\n"
601 "Flags: 0\n"
602 "Release String: ''\n"
603 "Descriptors:\n"
604 " Hash descriptor:\n"
605 " Image Size: 5242880 bytes\n"
606 " Hash Algorithm: sha256\n"
607 " Partition Name: boot\n"
608 " Salt: deadbeef\n"
609 " Digest: "
610 "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
611 " Kernel Cmdline descriptor:\n"
612 " Flags: 0\n"
613 " Kernel Cmdline: 'cmdline2 in hash footer'\n",
614 InfoImage(boot_path));
615
616 ops_.set_expected_public_key(
617 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
618
619 AvbSlotVerifyData* slot_data = NULL;
620 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
621 avb_slot_verify(ops_.avb_ops(),
622 requested_partitions,
623 "_a",
624 false /* allow_verification_error */,
625 &slot_data));
626 EXPECT_NE(nullptr, slot_data);
627
628 // Now verify the slot data. We should have two vbmeta
629 // structs. Verify both of them. Note that the A/B suffix isn't
630 // appended.
631 EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
632 EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
633 EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
634 EXPECT_EQ(0,
635 memcmp(vbmeta_image_.data(),
636 slot_data->vbmeta_images[0].vbmeta_data,
637 slot_data->vbmeta_images[0].vbmeta_size));
638 // And for the second vbmeta struct we check that the descriptors
639 // match the info_image output from above.
640 EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
641 const AvbDescriptor** descriptors =
642 avb_descriptor_get_all(slot_data->vbmeta_images[1].vbmeta_data,
643 slot_data->vbmeta_images[1].vbmeta_size,
644 NULL);
645 EXPECT_NE(nullptr, descriptors);
646 AvbHashDescriptor hash_desc;
647 EXPECT_EQ(true,
648 avb_hash_descriptor_validate_and_byteswap(
649 ((AvbHashDescriptor*)descriptors[0]), &hash_desc));
650 const uint8_t* desc_end = reinterpret_cast<const uint8_t*>(descriptors[0]) +
651 sizeof(AvbHashDescriptor);
652 uint64_t o = 0;
653 EXPECT_EQ("boot",
654 std::string(reinterpret_cast<const char*>(desc_end + o),
655 hash_desc.partition_name_len));
656 o += hash_desc.partition_name_len;
657 EXPECT_EQ("deadbeef", mem_to_hexstring(desc_end + o, hash_desc.salt_len));
658 o += hash_desc.salt_len;
659 EXPECT_EQ("184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d",
660 mem_to_hexstring(desc_end + o, hash_desc.digest_len));
661 AvbKernelCmdlineDescriptor cmdline_desc;
662 EXPECT_EQ(true,
663 avb_kernel_cmdline_descriptor_validate_and_byteswap(
664 ((AvbKernelCmdlineDescriptor*)descriptors[1]), &cmdline_desc));
665 desc_end = reinterpret_cast<const uint8_t*>(descriptors[1]) +
666 sizeof(AvbKernelCmdlineDescriptor);
667 EXPECT_EQ("cmdline2 in hash footer",
668 std::string(reinterpret_cast<const char*>(desc_end),
669 cmdline_desc.kernel_cmdline_length));
670 avb_free(descriptors);
671
672 // The boot image data should match what is generated above with
673 // GenerateImage().
674 EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
675 EXPECT_EQ("boot",
676 std::string(slot_data->loaded_partitions[0].partition_name));
677 EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
678 for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
679 EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
680 }
681
682 // This should match the two cmdlines with a space (U+0020) between them.
683 EXPECT_EQ(
684 "cmdline2 in hash footer cmdline2 in vbmeta "
685 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
686 "androidboot.vbmeta.avb_version=1.0 "
687 "androidboot.vbmeta.device_state=locked "
688 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
689 "androidboot.vbmeta.digest="
690 "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
691 std::string(slot_data->cmdline));
692 EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
693 EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
694 for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
695 EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
696 }
697 avb_slot_verify_data_free(slot_data);
698 }
699
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionCorruptBoot)700 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionCorruptBoot) {
701 size_t boot_partition_size = 16 * 1024 * 1024;
702 base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
703 const char* requested_partitions[] = {"boot", NULL};
704
705 EXPECT_COMMAND(0,
706 "./avbtool add_hash_footer"
707 " --image %s"
708 " --rollback_index 0"
709 " --partition_name boot"
710 " --partition_size %zd"
711 " --algorithm SHA256_RSA4096"
712 " --key test/data/testkey_rsa4096.pem"
713 " --salt deadbeef"
714 " --internal_release_string \"\"",
715 boot_path.value().c_str(),
716 boot_partition_size);
717
718 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
719 EXPECT_COMMAND(
720 0,
721 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
722 " --output %s",
723 pk_path.value().c_str());
724
725 GenerateVBMetaImage("vbmeta_a.img",
726 "SHA256_RSA2048",
727 0,
728 base::FilePath("test/data/testkey_rsa2048.pem"),
729 base::StringPrintf("--chain_partition boot:1:%s"
730 " --internal_release_string \"\"",
731 pk_path.value().c_str()));
732
733 ops_.set_expected_public_key(
734 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
735
736 AvbSlotVerifyData* slot_data = NULL;
737 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
738 avb_slot_verify(ops_.avb_ops(),
739 requested_partitions,
740 "_a",
741 false /* allow_verification_error */,
742 &slot_data));
743 EXPECT_NE(nullptr, slot_data);
744 avb_slot_verify_data_free(slot_data);
745
746 // Now corrupt boot_a.img and expect verification error.
747 uint8_t corrupt_data[4] = {0xff, 0xff, 0xff, 0xff};
748 EXPECT_EQ(AVB_IO_RESULT_OK,
749 ops_.avb_ops()->write_to_partition(ops_.avb_ops(),
750 "boot_a",
751 1024 * 1024, // offset: 1 MiB
752 sizeof corrupt_data,
753 corrupt_data));
754
755 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
756 avb_slot_verify(ops_.avb_ops(),
757 requested_partitions,
758 "_a",
759 false /* allow_verification_error */,
760 &slot_data));
761 EXPECT_EQ(nullptr, slot_data);
762 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
763 avb_slot_verify(ops_.avb_ops(),
764 requested_partitions,
765 "_a",
766 true /* allow_verification_error */,
767 &slot_data));
768 EXPECT_NE(nullptr, slot_data);
769 avb_slot_verify_data_free(slot_data);
770 }
771
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionKeyMismatch)772 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionKeyMismatch) {
773 size_t boot_partition_size = 16 * 1024 * 1024;
774 base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
775 const char* requested_partitions[] = {"boot", NULL};
776
777 // Use different key to sign vbmeta in boot_a (we use the 8192 bit
778 // key) than what's in the chained partition descriptor (which is
779 // the 4096 bit key) and expect
780 // AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED.
781
782 EXPECT_COMMAND(0,
783 "./avbtool add_hash_footer"
784 " --image %s"
785 " --rollback_index 0"
786 " --partition_name boot"
787 " --partition_size %zd"
788 " --algorithm SHA256_RSA8192"
789 " --key test/data/testkey_rsa8192.pem"
790 " --salt deadbeef"
791 " --internal_release_string \"\"",
792 boot_path.value().c_str(),
793 boot_partition_size);
794
795 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
796 EXPECT_COMMAND(
797 0,
798 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
799 " --output %s",
800 pk_path.value().c_str());
801
802 GenerateVBMetaImage("vbmeta_a.img",
803 "SHA256_RSA2048",
804 0,
805 base::FilePath("test/data/testkey_rsa2048.pem"),
806 base::StringPrintf("--chain_partition boot:1:%s"
807 " --internal_release_string \"\"",
808 pk_path.value().c_str()));
809
810 ops_.set_expected_public_key(
811 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
812
813 AvbSlotVerifyData* slot_data = NULL;
814 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
815 avb_slot_verify(ops_.avb_ops(),
816 requested_partitions,
817 "_a",
818 false /* allow_verification_error */,
819 &slot_data));
820 EXPECT_EQ(nullptr, slot_data);
821 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
822 avb_slot_verify(ops_.avb_ops(),
823 requested_partitions,
824 "_a",
825 true /* allow_verification_error */,
826 &slot_data));
827 EXPECT_NE(nullptr, slot_data);
828 avb_slot_verify_data_free(slot_data);
829 }
830
TEST_F(AvbSlotVerifyTest,HashDescriptorInChainedPartitionRollbackIndexFail)831 TEST_F(AvbSlotVerifyTest, HashDescriptorInChainedPartitionRollbackIndexFail) {
832 size_t boot_partition_size = 16 * 1024 * 1024;
833 base::FilePath boot_path = GenerateImage("boot_a.img", 5 * 1024 * 1024);
834 const char* requested_partitions[] = {"boot", NULL};
835
836 EXPECT_COMMAND(0,
837 "./avbtool add_hash_footer"
838 " --image %s"
839 " --rollback_index 10"
840 " --partition_name boot"
841 " --partition_size %zd"
842 " --algorithm SHA256_RSA4096"
843 " --key test/data/testkey_rsa4096.pem"
844 " --salt deadbeef"
845 " --internal_release_string \"\"",
846 boot_path.value().c_str(),
847 boot_partition_size);
848
849 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
850 EXPECT_COMMAND(
851 0,
852 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
853 " --output %s",
854 pk_path.value().c_str());
855
856 GenerateVBMetaImage("vbmeta_a.img",
857 "SHA256_RSA2048",
858 110,
859 base::FilePath("test/data/testkey_rsa2048.pem"),
860 base::StringPrintf("--chain_partition boot:1:%s"
861 " --internal_release_string \"\"",
862 pk_path.value().c_str()));
863
864 ops_.set_expected_public_key(
865 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
866
867 AvbSlotVerifyData* slot_data = NULL;
868
869 // Both images (vbmeta_a and boot_a) have rollback index 10 and 11
870 // so it should work if the stored rollback indexes are 0 and 0.
871 ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}});
872 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
873 avb_slot_verify(ops_.avb_ops(),
874 requested_partitions,
875 "_a",
876 false /* allow_verification_error */,
877 &slot_data));
878 EXPECT_NE(nullptr, slot_data);
879 avb_slot_verify_data_free(slot_data);
880
881 // Check failure if we set the stored rollback index of the chained
882 // partition to 20 (see AvbSlotVerifyTest.RollbackIndex above
883 // where we test rollback index checks for the vbmeta partition).
884 ops_.set_stored_rollback_indexes({{0, 0}, {1, 20}});
885 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
886 avb_slot_verify(ops_.avb_ops(),
887 requested_partitions,
888 "_a",
889 false /* allow_verification_error */,
890 &slot_data));
891 EXPECT_EQ(nullptr, slot_data);
892 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
893 avb_slot_verify(ops_.avb_ops(),
894 requested_partitions,
895 "_a",
896 true /* allow_verification_error */,
897 &slot_data));
898 EXPECT_NE(nullptr, slot_data);
899 avb_slot_verify_data_free(slot_data);
900
901 // Check failure if there is no rollback index slot 1 - in that case
902 // we expect an I/O error since ops->read_rollback_index() will
903 // fail.
904 ops_.set_stored_rollback_indexes({{0, 0}});
905 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_IO,
906 avb_slot_verify(ops_.avb_ops(),
907 requested_partitions,
908 "_a",
909 false /* allow_verification_error */,
910 &slot_data));
911 EXPECT_EQ(nullptr, slot_data);
912 }
913
TEST_F(AvbSlotVerifyTest,ChainedPartitionNoSlots)914 TEST_F(AvbSlotVerifyTest, ChainedPartitionNoSlots) {
915 size_t boot_partition_size = 16 * 1024 * 1024;
916 const size_t boot_image_size = 5 * 1024 * 1024;
917 base::FilePath boot_path = GenerateImage("boot.img", boot_image_size);
918 const char* requested_partitions[] = {"boot", NULL};
919
920 EXPECT_COMMAND(0,
921 "./avbtool add_hash_footer"
922 " --image %s"
923 " --kernel_cmdline 'cmdline2 in hash footer'"
924 " --rollback_index 12"
925 " --partition_name boot"
926 " --partition_size %zd"
927 " --algorithm SHA256_RSA4096"
928 " --key test/data/testkey_rsa4096.pem"
929 " --salt deadbeef"
930 " --internal_release_string \"\"",
931 boot_path.value().c_str(),
932 boot_partition_size);
933
934 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
935 EXPECT_COMMAND(
936 0,
937 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
938 " --output %s",
939 pk_path.value().c_str());
940
941 GenerateVBMetaImage(
942 "vbmeta.img",
943 "SHA256_RSA2048",
944 11,
945 base::FilePath("test/data/testkey_rsa2048.pem"),
946 base::StringPrintf("--chain_partition boot:1:%s"
947 " --kernel_cmdline 'cmdline2 in vbmeta'"
948 " --internal_release_string \"\"",
949 pk_path.value().c_str()));
950
951 EXPECT_EQ(
952 "Minimum libavb version: 1.0\n"
953 "Header Block: 256 bytes\n"
954 "Authentication Block: 320 bytes\n"
955 "Auxiliary Block: 1728 bytes\n"
956 "Algorithm: SHA256_RSA2048\n"
957 "Rollback Index: 11\n"
958 "Flags: 0\n"
959 "Release String: ''\n"
960 "Descriptors:\n"
961 " Chain Partition descriptor:\n"
962 " Partition Name: boot\n"
963 " Rollback Index Location: 1\n"
964 " Public key (sha1): "
965 "2597c218aae470a130f61162feaae70afd97f011\n"
966 " Kernel Cmdline descriptor:\n"
967 " Flags: 0\n"
968 " Kernel Cmdline: 'cmdline2 in vbmeta'\n",
969 InfoImage(vbmeta_image_path_));
970
971 ops_.set_expected_public_key(
972 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
973
974 AvbSlotVerifyData* slot_data = NULL;
975 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
976 avb_slot_verify(ops_.avb_ops(),
977 requested_partitions,
978 "",
979 false /* allow_verification_error */,
980 &slot_data));
981 EXPECT_NE(nullptr, slot_data);
982
983 // Now verify the slot data. The first vbmeta data should match our
984 // vbmeta_image_ member and the second one should be for the 'boot'
985 // partition.
986 EXPECT_EQ(size_t(2), slot_data->num_vbmeta_images);
987 EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
988 EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
989 EXPECT_EQ(0,
990 memcmp(vbmeta_image_.data(),
991 slot_data->vbmeta_images[0].vbmeta_data,
992 slot_data->vbmeta_images[0].vbmeta_size));
993 EXPECT_EQ("boot", std::string(slot_data->vbmeta_images[1].partition_name));
994
995 // The boot image data should match what is generated above with
996 // GenerateImage().
997 EXPECT_EQ(size_t(1), slot_data->num_loaded_partitions);
998 EXPECT_EQ("boot",
999 std::string(slot_data->loaded_partitions[0].partition_name));
1000 EXPECT_EQ(boot_image_size, slot_data->loaded_partitions[0].data_size);
1001 for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
1002 EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
1003 }
1004
1005 // This should match the two cmdlines with a space (U+0020) between
1006 // them.
1007 EXPECT_EQ(
1008 "cmdline2 in hash footer cmdline2 in vbmeta "
1009 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
1010 "androidboot.vbmeta.avb_version=1.0 "
1011 "androidboot.vbmeta.device_state=locked "
1012 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
1013 "androidboot.vbmeta.digest="
1014 "4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
1015 std::string(slot_data->cmdline));
1016 EXPECT_EQ(11UL, slot_data->rollback_indexes[0]);
1017 EXPECT_EQ(12UL, slot_data->rollback_indexes[1]);
1018 for (size_t n = 2; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
1019 EXPECT_EQ(0UL, slot_data->rollback_indexes[n]);
1020 }
1021 avb_slot_verify_data_free(slot_data);
1022 }
1023
TEST_F(AvbSlotVerifyTest,PartitionsOtherThanBoot)1024 TEST_F(AvbSlotVerifyTest, PartitionsOtherThanBoot) {
1025 const size_t foo_partition_size = 16 * 1024 * 1024;
1026 const size_t bar_partition_size = 32 * 1024 * 1024;
1027 const size_t foo_image_size = 5 * 1024 * 1024;
1028 const size_t bar_image_size = 10 * 1024 * 1024;
1029 base::FilePath foo_path = GenerateImage("foo_a.img", foo_image_size);
1030 base::FilePath bar_path = GenerateImage("bar_a.img", bar_image_size);
1031
1032 EXPECT_COMMAND(0,
1033 "./avbtool add_hash_footer"
1034 " --image %s"
1035 " --partition_name foo"
1036 " --partition_size %zd"
1037 " --salt deadbeef"
1038 " --internal_release_string \"\"",
1039 foo_path.value().c_str(),
1040 foo_partition_size);
1041
1042 EXPECT_COMMAND(0,
1043 "./avbtool add_hash_footer"
1044 " --image %s"
1045 " --partition_name bar"
1046 " --partition_size %zd"
1047 " --salt deadbeef"
1048 " --internal_release_string \"\"",
1049 bar_path.value().c_str(),
1050 bar_partition_size);
1051
1052 GenerateVBMetaImage("vbmeta_a.img",
1053 "SHA256_RSA2048",
1054 4,
1055 base::FilePath("test/data/testkey_rsa2048.pem"),
1056 base::StringPrintf("--include_descriptors_from_image %s"
1057 " --include_descriptors_from_image %s"
1058 " --internal_release_string \"\"",
1059 foo_path.value().c_str(),
1060 bar_path.value().c_str()));
1061
1062 EXPECT_EQ(
1063 "Minimum libavb version: 1.0\n"
1064 "Header Block: 256 bytes\n"
1065 "Authentication Block: 320 bytes\n"
1066 "Auxiliary Block: 896 bytes\n"
1067 "Algorithm: SHA256_RSA2048\n"
1068 "Rollback Index: 4\n"
1069 "Flags: 0\n"
1070 "Release String: ''\n"
1071 "Descriptors:\n"
1072 " Hash descriptor:\n"
1073 " Image Size: 5242880 bytes\n"
1074 " Hash Algorithm: sha256\n"
1075 " Partition Name: foo\n"
1076 " Salt: deadbeef\n"
1077 " Digest: "
1078 "184cb36243adb8b87d2d8c4802de32125fe294ec46753d732144ee65df68a23d\n"
1079 " Hash descriptor:\n"
1080 " Image Size: 10485760 bytes\n"
1081 " Hash Algorithm: sha256\n"
1082 " Partition Name: bar\n"
1083 " Salt: deadbeef\n"
1084 " Digest: "
1085 "baea4bbd261d0edf4d1fe5e6e5a36976c291eeba66b6a46fa81dba691327a727\n",
1086 InfoImage(vbmeta_image_path_));
1087
1088 ops_.set_expected_public_key(
1089 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1090
1091 AvbSlotVerifyData* slot_data = NULL;
1092 const char* requested_partitions[] = {"foo", "bar", NULL};
1093 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1094 avb_slot_verify(ops_.avb_ops(),
1095 requested_partitions,
1096 "_a",
1097 false /* allow_verification_error */,
1098 &slot_data));
1099 EXPECT_NE(nullptr, slot_data);
1100
1101 // Now verify the slot data. The vbmeta data should match our
1102 // vbmeta_image_ member.
1103 EXPECT_EQ(size_t(1), slot_data->num_vbmeta_images);
1104 EXPECT_EQ("vbmeta", std::string(slot_data->vbmeta_images[0].partition_name));
1105 EXPECT_EQ(slot_data->vbmeta_images[0].vbmeta_size, vbmeta_image_.size());
1106 EXPECT_EQ(0,
1107 memcmp(vbmeta_image_.data(),
1108 slot_data->vbmeta_images[0].vbmeta_data,
1109 slot_data->vbmeta_images[0].vbmeta_size));
1110
1111 // The 'foo' and 'bar' image data should match what is generated
1112 // above with GenerateImage().
1113 EXPECT_EQ(size_t(2), slot_data->num_loaded_partitions);
1114 EXPECT_EQ("foo", std::string(slot_data->loaded_partitions[0].partition_name));
1115 EXPECT_EQ(foo_image_size, slot_data->loaded_partitions[0].data_size);
1116 for (size_t n = 0; n < slot_data->loaded_partitions[0].data_size; n++) {
1117 EXPECT_EQ(slot_data->loaded_partitions[0].data[n], uint8_t(n));
1118 }
1119 EXPECT_EQ("bar", std::string(slot_data->loaded_partitions[1].partition_name));
1120 EXPECT_EQ(bar_image_size, slot_data->loaded_partitions[1].data_size);
1121 for (size_t n = 0; n < slot_data->loaded_partitions[1].data_size; n++) {
1122 EXPECT_EQ(slot_data->loaded_partitions[1].data[n], uint8_t(n));
1123 }
1124
1125 avb_slot_verify_data_free(slot_data);
1126 }
1127
TEST_F(AvbSlotVerifyTest,PublicKeyMetadata)1128 TEST_F(AvbSlotVerifyTest, PublicKeyMetadata) {
1129 base::FilePath md_path = GenerateImage("md.bin", 1536);
1130
1131 GenerateVBMetaImage("vbmeta_a.img",
1132 "SHA256_RSA2048",
1133 0,
1134 base::FilePath("test/data/testkey_rsa2048.pem"),
1135 base::StringPrintf("--public_key_metadata %s"
1136 " --internal_release_string \"\"",
1137 md_path.value().c_str()));
1138
1139 ops_.set_expected_public_key(
1140 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1141
1142 std::string md_data;
1143 ASSERT_TRUE(base::ReadFileToString(md_path, &md_data));
1144 ops_.set_expected_public_key_metadata(md_data);
1145
1146 AvbSlotVerifyData* slot_data = NULL;
1147 const char* requested_partitions[] = {"boot", NULL};
1148 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1149 avb_slot_verify(ops_.avb_ops(),
1150 requested_partitions,
1151 "_a",
1152 false /* allow_verification_error */,
1153 &slot_data));
1154 EXPECT_NE(nullptr, slot_data);
1155 EXPECT_EQ(
1156 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
1157 "androidboot.vbmeta.avb_version=1.0 "
1158 "androidboot.vbmeta.device_state=locked "
1159 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=2688 "
1160 "androidboot.vbmeta.digest="
1161 "5edcaa54f40382ee6a2fc3b86cdf383348b35ed07955e83ea32d84b69a97eaa0",
1162 std::string(slot_data->cmdline));
1163 avb_slot_verify_data_free(slot_data);
1164 }
1165
CmdlineWithHashtreeVerification(bool hashtree_verification_on)1166 void AvbSlotVerifyTest::CmdlineWithHashtreeVerification(
1167 bool hashtree_verification_on) {
1168 const size_t rootfs_size = 1028 * 1024;
1169 const size_t partition_size = 1536 * 1024;
1170
1171 // Generate a 1028 KiB file with known content.
1172 std::vector<uint8_t> rootfs;
1173 rootfs.resize(rootfs_size);
1174 for (size_t n = 0; n < rootfs_size; n++)
1175 rootfs[n] = uint8_t(n);
1176 base::FilePath rootfs_path = testdir_.Append("rootfs.bin");
1177 EXPECT_EQ(rootfs_size,
1178 static_cast<const size_t>(
1179 base::WriteFile(rootfs_path,
1180 reinterpret_cast<const char*>(rootfs.data()),
1181 rootfs.size())));
1182
1183 EXPECT_COMMAND(0,
1184 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1185 "--partition_size %d --partition_name foobar "
1186 "--algorithm SHA256_RSA2048 "
1187 "--key test/data/testkey_rsa2048.pem "
1188 "--internal_release_string \"\"",
1189 rootfs_path.value().c_str(),
1190 (int)partition_size);
1191
1192 // Check that we correctly generate dm-verity kernel cmdline
1193 // snippets, if requested.
1194 GenerateVBMetaImage(
1195 "vbmeta_a.img",
1196 "SHA256_RSA2048",
1197 4,
1198 base::FilePath("test/data/testkey_rsa2048.pem"),
1199 base::StringPrintf("--setup_rootfs_from_kernel %s "
1200 "--kernel_cmdline should_be_in_both=1 "
1201 "--algorithm SHA256_RSA2048 "
1202 "--flags %d "
1203 "--internal_release_string \"\"",
1204 rootfs_path.value().c_str(),
1205 hashtree_verification_on
1206 ? 0
1207 : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED));
1208
1209 EXPECT_EQ(
1210 base::StringPrintf(
1211 "Minimum libavb version: 1.0\n"
1212 "Header Block: 256 bytes\n"
1213 "Authentication Block: 320 bytes\n"
1214 "Auxiliary Block: 960 bytes\n"
1215 "Algorithm: SHA256_RSA2048\n"
1216 "Rollback Index: 4\n"
1217 "Flags: %d\n"
1218 "Release String: ''\n"
1219 "Descriptors:\n"
1220 " Kernel Cmdline descriptor:\n"
1221 " Flags: 1\n"
1222 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 2056 verity "
1223 "1 PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
1224 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) 4096 4096 257 257 sha1 "
1225 "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
1226 "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0'\n"
1227 " Kernel Cmdline descriptor:\n"
1228 " Flags: 2\n"
1229 " Kernel Cmdline: "
1230 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
1231 " Kernel Cmdline descriptor:\n"
1232 " Flags: 0\n"
1233 " Kernel Cmdline: 'should_be_in_both=1'\n",
1234 hashtree_verification_on ? 0
1235 : AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED),
1236 InfoImage(vbmeta_image_path_));
1237
1238 ops_.set_expected_public_key(
1239 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1240
1241 // Check that avb_slot_verify() picks the cmdline decsriptors based
1242 // on their flags value.
1243 AvbSlotVerifyData* slot_data = NULL;
1244 const char* requested_partitions[] = {"boot", NULL};
1245 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1246 avb_slot_verify(ops_.avb_ops(),
1247 requested_partitions,
1248 "_a",
1249 false /* allow_verification_error */,
1250 &slot_data));
1251 EXPECT_NE(nullptr, slot_data);
1252 if (hashtree_verification_on) {
1253 EXPECT_EQ(
1254 "dm=\"1 vroot none ro 1,0 2056 verity 1 "
1255 "PARTUUID=1234-fake-guid-for:system_a "
1256 "PARTUUID=1234-fake-guid-for:system_a 4096 4096 257 257 sha1 "
1257 "e811611467dcd6e8dc4324e45f706c2bdd51db67 d00df00d 2 "
1258 "restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
1259 "should_be_in_both=1 "
1260 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
1261 "androidboot.vbmeta.avb_version=1.0 "
1262 "androidboot.vbmeta.device_state=locked "
1263 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
1264 "androidboot.vbmeta.digest="
1265 "51ea1638d8cc19a7a15b2bade22d155fb5150a6e376171ea1a89b7d6c89d6f17",
1266 std::string(slot_data->cmdline));
1267 } else {
1268 EXPECT_EQ(
1269 "root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
1270 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
1271 "androidboot.vbmeta.avb_version=1.0 "
1272 "androidboot.vbmeta.device_state=locked "
1273 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1536 "
1274 "androidboot.vbmeta.digest="
1275 "877daa21c04df1d9e1776bc6169c98de947ce44b1b34b545021bb3f34e287da6",
1276 std::string(slot_data->cmdline));
1277 }
1278 avb_slot_verify_data_free(slot_data);
1279 }
1280
TEST_F(AvbSlotVerifyTest,CmdlineWithHashtreeVerificationOff)1281 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOff) {
1282 CmdlineWithHashtreeVerification(false);
1283 }
1284
TEST_F(AvbSlotVerifyTest,CmdlineWithHashtreeVerificationOn)1285 TEST_F(AvbSlotVerifyTest, CmdlineWithHashtreeVerificationOn) {
1286 CmdlineWithHashtreeVerification(true);
1287 }
1288
1289 // In the event that there's no vbmeta partition, we treat the vbmeta
1290 // struct from 'boot' as the top-level partition. Check that this
1291 // works.
TEST_F(AvbSlotVerifyTest,NoVBMetaPartition)1292 TEST_F(AvbSlotVerifyTest, NoVBMetaPartition) {
1293 const size_t MiB = 1024 * 1024;
1294 const size_t boot_size = 6 * MiB;
1295 const size_t boot_part_size = 8 * MiB;
1296 const size_t system_size = 16 * MiB;
1297 const size_t system_part_size = 32 * MiB;
1298 const size_t foobar_size = 8 * MiB;
1299 const size_t foobar_part_size = 16 * MiB;
1300 const size_t bazboo_size = 4 * MiB;
1301 const size_t bazboo_part_size = 8 * MiB;
1302 base::FilePath boot_path = GenerateImage("boot.img", boot_size);
1303 base::FilePath system_path = GenerateImage("system.img", system_size);
1304 base::FilePath foobar_path = GenerateImage("foobar.img", foobar_size);
1305 base::FilePath bazboo_path = GenerateImage("bazboo.img", bazboo_size);
1306
1307 EXPECT_COMMAND(0,
1308 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1309 "--partition_size %d --partition_name system "
1310 "--algorithm SHA256_RSA2048 "
1311 "--key test/data/testkey_rsa2048.pem "
1312 "--internal_release_string \"\"",
1313 system_path.value().c_str(),
1314 (int)system_part_size);
1315
1316 EXPECT_COMMAND(0,
1317 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1318 "--partition_size %d --partition_name foobar "
1319 "--algorithm SHA256_RSA2048 "
1320 "--key test/data/testkey_rsa2048.pem "
1321 "--internal_release_string \"\"",
1322 foobar_path.value().c_str(),
1323 (int)foobar_part_size);
1324
1325 EXPECT_COMMAND(0,
1326 "./avbtool add_hashtree_footer --salt d00df00d --image %s "
1327 "--partition_size %d --partition_name bazboo "
1328 "--algorithm SHA512_RSA4096 "
1329 "--key test/data/testkey_rsa4096.pem "
1330 "--internal_release_string \"\"",
1331 bazboo_path.value().c_str(),
1332 (int)bazboo_part_size);
1333
1334 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
1335 EXPECT_COMMAND(
1336 0,
1337 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
1338 " --output %s",
1339 pk_path.value().c_str());
1340
1341 // Explicitly pass "--flags 2147483648" (i.e. 1<<31) to check that
1342 // boot.img is treated as top-level. Note the corresponding "Flags:"
1343 // field below in the avbtool info_image output.
1344 EXPECT_COMMAND(0,
1345 "./avbtool add_hash_footer --salt d00df00d "
1346 "--hash_algorithm sha256 --image %s "
1347 "--partition_size %d --partition_name boot "
1348 "--algorithm SHA256_RSA2048 "
1349 "--key test/data/testkey_rsa2048.pem "
1350 "--internal_release_string \"\" "
1351 "--include_descriptors_from_image %s "
1352 "--include_descriptors_from_image %s "
1353 "--setup_rootfs_from_kernel %s "
1354 "--chain_partition bazboo:1:%s "
1355 "--flags 2147483648",
1356 boot_path.value().c_str(),
1357 (int)boot_part_size,
1358 system_path.value().c_str(),
1359 foobar_path.value().c_str(),
1360 system_path.value().c_str(),
1361 pk_path.value().c_str());
1362
1363 ASSERT_EQ(
1364 "Footer version: 1.0\n"
1365 "Image size: 8388608 bytes\n"
1366 "Original image size: 6291456 bytes\n"
1367 "VBMeta offset: 6291456\n"
1368 "VBMeta size: 3200 bytes\n"
1369 "--\n"
1370 "Minimum libavb version: 1.0\n"
1371 "Header Block: 256 bytes\n"
1372 "Authentication Block: 320 bytes\n"
1373 "Auxiliary Block: 2624 bytes\n"
1374 "Algorithm: SHA256_RSA2048\n"
1375 "Rollback Index: 0\n"
1376 "Flags: 2147483648\n"
1377 "Release String: ''\n"
1378 "Descriptors:\n"
1379 " Hash descriptor:\n"
1380 " Image Size: 6291456 bytes\n"
1381 " Hash Algorithm: sha256\n"
1382 " Partition Name: boot\n"
1383 " Salt: d00df00d\n"
1384 " Digest: "
1385 "4c109399b20e476bab15363bff55740add83e1c1e97e0b132f5c713ddd8c7868\n"
1386 " Chain Partition descriptor:\n"
1387 " Partition Name: bazboo\n"
1388 " Rollback Index Location: 1\n"
1389 " Public key (sha1): "
1390 "2597c218aae470a130f61162feaae70afd97f011\n"
1391 " Kernel Cmdline descriptor:\n"
1392 " Flags: 1\n"
1393 " Kernel Cmdline: 'dm=\"1 vroot none ro 1,0 32768 verity 1 "
1394 "PARTUUID=$(ANDROID_SYSTEM_PARTUUID) PARTUUID=$(ANDROID_SYSTEM_PARTUUID) "
1395 "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
1396 "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0'\n"
1397 " Kernel Cmdline descriptor:\n"
1398 " Flags: 2\n"
1399 " Kernel Cmdline: "
1400 "'root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)'\n"
1401 " Hashtree descriptor:\n"
1402 " Version of dm-verity: 1\n"
1403 " Image Size: 16777216 bytes\n"
1404 " Tree Offset: 16777216\n"
1405 " Tree Size: 135168 bytes\n"
1406 " Data Block Size: 4096 bytes\n"
1407 " Hash Block Size: 4096 bytes\n"
1408 " FEC num roots: 0\n"
1409 " FEC offset: 0\n"
1410 " FEC size: 0 bytes\n"
1411 " Hash Algorithm: sha1\n"
1412 " Partition Name: system\n"
1413 " Salt: d00df00d\n"
1414 " Root Digest: c9ffc3bfae5000269a55a56621547fd1fcf819df\n"
1415 " Hashtree descriptor:\n"
1416 " Version of dm-verity: 1\n"
1417 " Image Size: 8388608 bytes\n"
1418 " Tree Offset: 8388608\n"
1419 " Tree Size: 69632 bytes\n"
1420 " Data Block Size: 4096 bytes\n"
1421 " Hash Block Size: 4096 bytes\n"
1422 " FEC num roots: 0\n"
1423 " FEC offset: 0\n"
1424 " FEC size: 0 bytes\n"
1425 " Hash Algorithm: sha1\n"
1426 " Partition Name: foobar\n"
1427 " Salt: d00df00d\n"
1428 " Root Digest: d52d93c988d336a79abe1c05240ae9a79a9b7d61\n",
1429 InfoImage(boot_path));
1430
1431 ops_.set_expected_public_key(
1432 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1433
1434 // Now check that libavb will fall back to reading from 'boot'
1435 // instead of 'vbmeta' when encountering
1436 // AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION on trying to read from
1437 // 'vbmeta'.
1438 AvbSlotVerifyData* slot_data = NULL;
1439 const char* requested_partitions[] = {"boot", NULL};
1440 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_OK,
1441 avb_slot_verify(ops_.avb_ops(),
1442 requested_partitions,
1443 "",
1444 false /* allow_verification_error */,
1445 &slot_data));
1446 EXPECT_NE(nullptr, slot_data);
1447 // Note 'boot' in the value androidboot.vbmeta.device since we've
1448 // read from 'boot' and not 'vbmeta'.
1449 EXPECT_EQ(
1450 "dm=\"1 vroot none ro 1,0 32768 verity 1 "
1451 "PARTUUID=1234-fake-guid-for:system PARTUUID=1234-fake-guid-for:system "
1452 "4096 4096 4096 4096 sha1 c9ffc3bfae5000269a55a56621547fd1fcf819df "
1453 "d00df00d 2 restart_on_corruption ignore_zero_blocks\" root=/dev/dm-0 "
1454 "androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:boot "
1455 "androidboot.vbmeta.avb_version=1.0 "
1456 "androidboot.vbmeta.device_state=locked "
1457 "androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=5312 "
1458 "androidboot.vbmeta.digest="
1459 "87bf39949a560f93d54aa0a5e9d158439110141246e40fb103f131633a3ca456",
1460 std::string(slot_data->cmdline));
1461 avb_slot_verify_data_free(slot_data);
1462 }
1463
1464 // Check that non-zero flags in chained partition are caught in
1465 // avb_slot_verify().
TEST_F(AvbSlotVerifyTest,ChainedPartitionEnforceFlagsZero)1466 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceFlagsZero) {
1467 size_t boot_partition_size = 16 * 1024 * 1024;
1468 const size_t boot_image_size = 5 * 1024 * 1024;
1469 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
1470 const char* requested_partitions[] = {"boot", NULL};
1471
1472 EXPECT_COMMAND(0,
1473 "./avbtool add_hash_footer"
1474 " --image %s"
1475 " --kernel_cmdline 'cmdline2 in hash footer'"
1476 " --rollback_index 12"
1477 " --partition_name boot"
1478 " --partition_size %zd"
1479 " --algorithm SHA256_RSA4096"
1480 " --key test/data/testkey_rsa4096.pem"
1481 " --salt deadbeef"
1482 " --flags 1"
1483 " --internal_release_string \"\"",
1484 boot_path.value().c_str(),
1485 boot_partition_size);
1486
1487 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
1488 EXPECT_COMMAND(
1489 0,
1490 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
1491 " --output %s",
1492 pk_path.value().c_str());
1493
1494 GenerateVBMetaImage(
1495 "vbmeta_a.img",
1496 "SHA256_RSA2048",
1497 11,
1498 base::FilePath("test/data/testkey_rsa2048.pem"),
1499 base::StringPrintf("--chain_partition boot:1:%s"
1500 " --kernel_cmdline 'cmdline2 in vbmeta'"
1501 " --internal_release_string \"\"",
1502 pk_path.value().c_str()));
1503
1504 ops_.set_expected_public_key(
1505 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1506
1507 AvbSlotVerifyData* slot_data = NULL;
1508 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
1509 avb_slot_verify(ops_.avb_ops(),
1510 requested_partitions,
1511 "_a",
1512 false /* allow_verification_error */,
1513 &slot_data));
1514 EXPECT_EQ(nullptr, slot_data);
1515 }
1516
1517 // Check that chain descriptors in chained partitions are caught in
1518 // avb_slot_verify().
TEST_F(AvbSlotVerifyTest,ChainedPartitionEnforceNoChainPartitions)1519 TEST_F(AvbSlotVerifyTest, ChainedPartitionEnforceNoChainPartitions) {
1520 size_t boot_partition_size = 16 * 1024 * 1024;
1521 const size_t boot_image_size = 5 * 1024 * 1024;
1522 base::FilePath boot_path = GenerateImage("boot_a.img", boot_image_size);
1523 const char* requested_partitions[] = {"boot", NULL};
1524
1525 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey");
1526 EXPECT_COMMAND(
1527 0,
1528 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem"
1529 " --output %s",
1530 pk_path.value().c_str());
1531
1532 EXPECT_COMMAND(0,
1533 "./avbtool add_hash_footer"
1534 " --image %s"
1535 " --kernel_cmdline 'cmdline2 in hash footer'"
1536 " --rollback_index 12"
1537 " --partition_name boot"
1538 " --partition_size %zd"
1539 " --algorithm SHA256_RSA4096"
1540 " --key test/data/testkey_rsa4096.pem"
1541 " --salt deadbeef"
1542 " --chain_partition other:2:%s"
1543 " --internal_release_string \"\"",
1544 boot_path.value().c_str(),
1545 boot_partition_size,
1546 pk_path.value().c_str());
1547
1548 GenerateVBMetaImage(
1549 "vbmeta_a.img",
1550 "SHA256_RSA2048",
1551 11,
1552 base::FilePath("test/data/testkey_rsa2048.pem"),
1553 base::StringPrintf("--chain_partition boot:1:%s"
1554 " --kernel_cmdline 'cmdline2 in vbmeta'"
1555 " --internal_release_string \"\"",
1556 pk_path.value().c_str()));
1557
1558 ops_.set_expected_public_key(
1559 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
1560
1561 AvbSlotVerifyData* slot_data = NULL;
1562 EXPECT_EQ(AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
1563 avb_slot_verify(ops_.avb_ops(),
1564 requested_partitions,
1565 "_a",
1566 false /* allow_verification_error */,
1567 &slot_data));
1568 EXPECT_EQ(nullptr, slot_data);
1569 }
1570
1571 } // namespace avb
1572