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