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