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