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