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 <string.h> 26 27 #include <map> 28 #include <vector> 29 30 #include <gtest/gtest.h> 31 32 #include <libavb_ab/libavb_ab.h> 33 34 #include "avb_unittest_util.h" 35 #include "fake_avb_ops.h" 36 37 namespace avb { 38 39 static_assert(sizeof(AvbABSlotData) == 4, "AvbABSlotData has wrong size"); 40 static_assert(sizeof(AvbABData) == AVB_AB_DATA_SIZE, 41 "AvbABData has wrong size"); 42 static_assert(offsetof(AvbABData, slots) % 8 == 0, 43 "AvbABData slots member has wrong offset"); 44 45 // Subclass BaseAvbToolTest to check for memory leaks. 46 class ABTest : public BaseAvbToolTest { 47 public: 48 ABTest() {} 49 }; 50 51 TEST_F(ABTest, InitData) { 52 AvbABData data; 53 avb_ab_data_init(&data); 54 EXPECT_EQ(0, 55 strncmp(reinterpret_cast<const char*>(data.magic), 56 AVB_AB_MAGIC, 57 AVB_AB_MAGIC_LEN)); 58 EXPECT_EQ(AVB_AB_MAX_PRIORITY, data.slots[0].priority); 59 EXPECT_EQ(AVB_AB_MAX_TRIES_REMAINING, data.slots[0].tries_remaining); 60 EXPECT_EQ(0, data.slots[0].successful_boot); 61 EXPECT_EQ(AVB_AB_MAX_PRIORITY - 1, data.slots[1].priority); 62 EXPECT_EQ(AVB_AB_MAX_TRIES_REMAINING, data.slots[1].tries_remaining); 63 EXPECT_EQ(0, data.slots[1].successful_boot); 64 EXPECT_EQ(uint32_t(0), data.crc32); 65 } 66 67 TEST_F(ABTest, DataSerialization) { 68 AvbABData data; 69 AvbABData serialized; 70 AvbABData restored; 71 72 avb_ab_data_init(&data); 73 EXPECT_EQ(uint32_t(0), data.crc32); 74 avb_ab_data_update_crc_and_byteswap(&data, &serialized); 75 EXPECT_NE(uint32_t(0), serialized.crc32); 76 EXPECT_TRUE(avb_ab_data_verify_and_byteswap(&serialized, &restored)); 77 EXPECT_EQ(std::string(reinterpret_cast<const char*>(data.magic), 4), 78 std::string(reinterpret_cast<const char*>(restored.magic), 4)); 79 EXPECT_EQ(data.version_major, restored.version_major); 80 EXPECT_EQ(data.version_minor, restored.version_minor); 81 EXPECT_EQ(0, 82 memcmp(reinterpret_cast<void*>(data.slots), 83 reinterpret_cast<void*>(restored.slots), 84 sizeof(AvbABSlotData) * 2)); 85 } 86 87 TEST_F(ABTest, CatchBadCRC) { 88 AvbABData data; 89 AvbABData serialized; 90 AvbABData restored; 91 92 avb_ab_data_init(&data); 93 avb_ab_data_update_crc_and_byteswap(&data, &serialized); 94 serialized.crc32 += 1; 95 EXPECT_FALSE(avb_ab_data_verify_and_byteswap(&serialized, &restored)); 96 } 97 98 TEST_F(ABTest, CatchUnsupportedMajorVersion) { 99 AvbABData data; 100 AvbABData serialized; 101 AvbABData restored; 102 103 avb_ab_data_init(&data); 104 data.version_major += 1; 105 avb_ab_data_update_crc_and_byteswap(&data, &serialized); 106 EXPECT_FALSE(avb_ab_data_verify_and_byteswap(&serialized, &restored)); 107 } 108 109 TEST_F(ABTest, SupportSameMajorFutureMinorVersion) { 110 AvbABData data; 111 AvbABData serialized; 112 AvbABData restored; 113 114 avb_ab_data_init(&data); 115 data.version_minor += 1; 116 avb_ab_data_update_crc_and_byteswap(&data, &serialized); 117 EXPECT_TRUE(avb_ab_data_verify_and_byteswap(&serialized, &restored)); 118 } 119 120 #define MISC_PART_SIZE 8 * 1024 121 122 // These values are kept short since they are used in SetMD() and it's 123 // helpful if the information for a slot fits in one 80-character 124 // line. 125 enum SlotValidity { 126 SV_OK, // Slot is valid and verified. 127 SV_INV, // Slot is invalid. 128 SV_UNV, // Slot is valid but unverified. 129 }; 130 131 class AvbABFlowTest : public BaseAvbToolTest { 132 public: 133 AvbABFlowTest() {} 134 135 virtual void SetUp() override { 136 BaseAvbToolTest::SetUp(); 137 ops_.set_partition_dir(testdir_); 138 ops_.set_stored_rollback_indexes({{0, 0}, {1, 0}, {2, 0}, {3, 0}}); 139 ops_.set_stored_is_device_unlocked(false); 140 141 // Create large enough 'misc' partition and initialize it with 142 // zeroes. 143 std::vector<uint8_t> misc; 144 misc.resize(MISC_PART_SIZE); 145 base::FilePath misc_path = testdir_.Append("misc.img"); 146 EXPECT_EQ(misc.size(), 147 static_cast<const size_t>( 148 base::WriteFile(misc_path, 149 reinterpret_cast<const char*>(misc.data()), 150 misc.size()))); 151 152 // We're going to use this key for all images. 153 ops_.set_expected_public_key( 154 PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem"))); 155 } 156 157 void GenerateSlot(unsigned int slot_number, 158 SlotValidity slot_validity, 159 uint64_t rollback_boot, 160 uint64_t rollback_odm) { 161 std::string boot_name = "boot_a.img"; 162 std::string vbmeta_name = "vbmeta_a.img"; 163 std::string odm_name = "odm_a.img"; 164 if (slot_number > 0) { 165 boot_name = "boot_b.img"; 166 vbmeta_name = "vbmeta_b.img"; 167 odm_name = "odm_b.img"; 168 } 169 170 // If asked to make an invalid slot, just generate 1MiB garbage 171 // for each the three images in the slot. 172 if (slot_validity == SV_INV) { 173 GenerateImage(boot_name, 1024 * 1024); 174 GenerateImage(vbmeta_name, 1024 * 1024); 175 GenerateImage(odm_name, 1024 * 1024); 176 return; 177 } 178 179 const size_t boot_partition_size = 16 * 1024 * 1024; 180 const size_t boot_image_size = 5 * 1024 * 1024; 181 base::FilePath boot_path = GenerateImage(boot_name, boot_image_size); 182 EXPECT_COMMAND(0, 183 "./avbtool add_hash_footer" 184 " --image %s" 185 " --rollback_index %" PRIu64 186 " --partition_name boot" 187 " --partition_size %zd" 188 " --salt deadbeef", 189 boot_path.value().c_str(), 190 rollback_boot, 191 boot_partition_size); 192 193 const size_t odm_partition_size = 512 * 1024; 194 const size_t odm_image_size = 80 * 1024; 195 base::FilePath odm_path = GenerateImage(odm_name, odm_image_size); 196 EXPECT_COMMAND(0, 197 "./avbtool add_hashtree_footer" 198 " --image %s" 199 " --rollback_index %" PRIu64 200 " --partition_name odm" 201 " --partition_size %zd" 202 " --salt deadbeef" 203 " --algorithm SHA512_RSA4096 " 204 " --key test/data/testkey_rsa4096.pem" 205 " --do_not_generate_fec", 206 odm_path.value().c_str(), 207 rollback_odm, 208 odm_partition_size); 209 210 base::FilePath pk_path = testdir_.Append("testkey_rsa4096.avbpubkey"); 211 EXPECT_COMMAND( 212 0, 213 "./avbtool extract_public_key --key test/data/testkey_rsa4096.pem" 214 " --output %s", 215 pk_path.value().c_str()); 216 217 // If requested to make the image unverified, just use another key 218 // in the chain_partition descriptor since this will cause 219 // avb_slot_verify() to return ERROR_PUBLIC_KEY_REJECTED. 220 if (slot_validity == SV_UNV) { 221 pk_path = GenerateImage("dummy.avbpubkey", 32); 222 } 223 224 GenerateVBMetaImage(vbmeta_name, 225 "SHA256_RSA2048", 226 rollback_boot, 227 base::FilePath("test/data/testkey_rsa2048.pem"), 228 base::StringPrintf("--include_descriptors_from_image %s" 229 " --chain_partition odm:1:%s", 230 boot_path.value().c_str(), 231 pk_path.value().c_str())); 232 } 233 234 void SetMD(int a_pri, 235 int a_tries, 236 bool a_success, 237 SlotValidity a_slot_validity, 238 uint64_t a_rollback_boot, 239 uint64_t a_rollback_odm, 240 int b_pri, 241 int b_tries, 242 bool b_success, 243 SlotValidity b_slot_validity, 244 uint64_t b_rollback_boot, 245 uint64_t b_rollback_odm, 246 const std::map<size_t, uint64_t>& stored_rollback_indexes) { 247 AvbABData data; 248 avb_ab_data_init(&data); 249 data.slots[0].priority = a_pri; 250 data.slots[0].tries_remaining = a_tries; 251 data.slots[0].successful_boot = (a_success ? 1 : 0); 252 data.slots[1].priority = b_pri; 253 data.slots[1].tries_remaining = b_tries; 254 data.slots[1].successful_boot = (b_success ? 1 : 0); 255 EXPECT_EQ(AVB_IO_RESULT_OK, 256 ops_.avb_ab_ops()->write_ab_metadata(ops_.avb_ab_ops(), &data)); 257 GenerateSlot(0, a_slot_validity, a_rollback_boot, a_rollback_odm); 258 GenerateSlot(1, b_slot_validity, b_rollback_boot, b_rollback_odm); 259 ops_.set_stored_rollback_indexes(stored_rollback_indexes); 260 } 261 262 std::map<size_t, uint64_t> MakeRollbackIndexes(uint64_t slot_0_value, 263 uint64_t slot_1_value) { 264 return std::map<size_t, uint64_t>{{0, slot_0_value}, {1, slot_1_value}}; 265 } 266 267 FakeAvbOps ops_; 268 }; 269 270 #define ExpMD(a_pri, \ 271 a_tries, \ 272 a_success, \ 273 b_pri, \ 274 b_tries, \ 275 b_success, \ 276 stored_rollback_indexes) \ 277 do { \ 278 AvbABData data; \ 279 EXPECT_EQ(AVB_IO_RESULT_OK, \ 280 ops_.avb_ab_ops()->read_ab_metadata(ops_.avb_ab_ops(), &data)); \ 281 EXPECT_EQ(a_pri, data.slots[0].priority); \ 282 EXPECT_EQ(a_tries, data.slots[0].tries_remaining); \ 283 EXPECT_EQ(a_success ? 1 : 0, data.slots[0].successful_boot); \ 284 EXPECT_EQ(b_pri, data.slots[1].priority); \ 285 EXPECT_EQ(b_tries, data.slots[1].tries_remaining); \ 286 EXPECT_EQ(b_success ? 1 : 0, data.slots[1].successful_boot); \ 287 EXPECT_EQ(stored_rollback_indexes, ops_.get_stored_rollback_indexes()); \ 288 } while (0); 289 290 TEST_F(AvbABFlowTest, MetadataReadAndWrite) { 291 AvbABData data; 292 AvbABData loaded; 293 294 // First load from an uninitialized 'misc' partition. This should 295 // not fail and just returned initialized data. 296 EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_data_read(ops_.avb_ab_ops(), &loaded)); 297 EXPECT_EQ(AVB_AB_MAX_PRIORITY, loaded.slots[0].priority); 298 EXPECT_EQ(AVB_AB_MAX_TRIES_REMAINING, loaded.slots[0].tries_remaining); 299 EXPECT_EQ(0, loaded.slots[0].successful_boot); 300 EXPECT_EQ(AVB_AB_MAX_PRIORITY - 1, loaded.slots[1].priority); 301 EXPECT_EQ(AVB_AB_MAX_TRIES_REMAINING, loaded.slots[1].tries_remaining); 302 EXPECT_EQ(0, loaded.slots[1].successful_boot); 303 304 // Then initialize and save well-known A/B metadata and check we 305 // read back the same thing. 306 avb_ab_data_init(&data); 307 data.slots[0].priority = 2; 308 data.slots[0].tries_remaining = 3; 309 EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_data_write(ops_.avb_ab_ops(), &data)); 310 EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_data_read(ops_.avb_ab_ops(), &loaded)); 311 EXPECT_EQ(2, loaded.slots[0].priority); 312 EXPECT_EQ(3, loaded.slots[0].tries_remaining); 313 } 314 315 TEST_F(AvbABFlowTest, EverythingIsValid) { 316 AvbSlotVerifyData* data; 317 const char* requested_partitions[] = {"boot", NULL}; 318 319 SetMD(14, 320 0, 321 1, 322 SV_OK, 323 0, 324 0, // A: pri, tries, success, slot_validity, RIs 325 15, 326 0, 327 1, 328 SV_OK, 329 0, 330 0, // B: pri, tries, success, slot_validity, RIs 331 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 332 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 333 avb_ab_flow(ops_.avb_ab_ops(), 334 requested_partitions, 335 AVB_SLOT_VERIFY_FLAGS_NONE, 336 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 337 &data)); 338 ExpMD(14, 339 0, 340 1, // A: pri, tries, successful 341 15, 342 0, 343 1, // B: pri, tries, successful 344 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 345 ASSERT_NE(nullptr, data); 346 EXPECT_EQ("_b", std::string(data->ab_suffix)); 347 avb_slot_verify_data_free(data); 348 349 // Also check the other slot. 350 SetMD(15, 351 0, 352 1, 353 SV_OK, 354 0, 355 0, // A: pri, tries, success, slot_validity, RIs 356 14, 357 0, 358 1, 359 SV_OK, 360 0, 361 0, // B: pri, tries, success, slot_validity, RIs 362 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 363 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 364 avb_ab_flow(ops_.avb_ab_ops(), 365 requested_partitions, 366 AVB_SLOT_VERIFY_FLAGS_NONE, 367 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 368 &data)); 369 ExpMD(15, 370 0, 371 1, // A: pri, tries, successful 372 14, 373 0, 374 1, // B: pri, tries, successful 375 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 376 ASSERT_NE(nullptr, data); 377 EXPECT_EQ("_a", std::string(data->ab_suffix)); 378 avb_slot_verify_data_free(data); 379 } 380 381 TEST_F(AvbABFlowTest, NoBootableSlots) { 382 AvbSlotVerifyData* data; 383 const char* requested_partitions[] = {"boot", NULL}; 384 385 SetMD(0, 386 0, 387 0, 388 SV_OK, 389 0, 390 0, // A: pri, tries, success, slot_validity, RIs 391 0, 392 0, 393 0, 394 SV_OK, 395 0, 396 0, // B: pri, tries, success, slot_validity, RIs 397 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 398 EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS, 399 avb_ab_flow(ops_.avb_ab_ops(), 400 requested_partitions, 401 AVB_SLOT_VERIFY_FLAGS_NONE, 402 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 403 &data)); 404 ExpMD(0, 405 0, 406 0, // A: pri, tries, successful 407 0, 408 0, 409 0, // B: pri, tries, successful 410 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 411 ASSERT_EQ(nullptr, data); 412 } 413 414 TEST_F(AvbABFlowTest, TriesRemainingDecreasing) { 415 AvbSlotVerifyData* data; 416 const char* requested_partitions[] = {"boot", NULL}; 417 418 SetMD(15, 419 3, 420 0, 421 SV_OK, 422 0, 423 0, // A: pri, tries, success, slot_validity, RIs 424 0, 425 0, 426 0, 427 SV_OK, 428 0, 429 0, // B: pri, tries, success, slot_validity, RIs 430 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 431 432 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 433 avb_ab_flow(ops_.avb_ab_ops(), 434 requested_partitions, 435 AVB_SLOT_VERIFY_FLAGS_NONE, 436 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 437 &data)); 438 ExpMD(15, 439 2, 440 0, // A: pri, tries, successful 441 0, 442 0, 443 0, // B: pri, tries, successful 444 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 445 ASSERT_NE(nullptr, data); 446 EXPECT_EQ("_a", std::string(data->ab_suffix)); 447 avb_slot_verify_data_free(data); 448 449 // Keep counting down... 450 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 451 avb_ab_flow(ops_.avb_ab_ops(), 452 requested_partitions, 453 AVB_SLOT_VERIFY_FLAGS_NONE, 454 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 455 &data)); 456 ExpMD(15, 457 1, 458 0, // A: pri, tries, successful 459 0, 460 0, 461 0, // B: pri, tries, successful 462 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 463 ASSERT_NE(nullptr, data); 464 EXPECT_EQ("_a", std::string(data->ab_suffix)); 465 avb_slot_verify_data_free(data); 466 467 // Last try... 468 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 469 avb_ab_flow(ops_.avb_ab_ops(), 470 requested_partitions, 471 AVB_SLOT_VERIFY_FLAGS_NONE, 472 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 473 &data)); 474 ExpMD(15, 475 0, 476 0, // A: pri, tries, successful 477 0, 478 0, 479 0, // B: pri, tries, successful 480 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 481 ASSERT_NE(nullptr, data); 482 EXPECT_EQ("_a", std::string(data->ab_suffix)); 483 avb_slot_verify_data_free(data); 484 485 // And we're out of tries. At this point, (15, 0, 0) is normalized 486 // to (0, 0, 0) so expect that. 487 EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS, 488 avb_ab_flow(ops_.avb_ab_ops(), 489 requested_partitions, 490 AVB_SLOT_VERIFY_FLAGS_NONE, 491 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 492 &data)); 493 ExpMD(0, 494 0, 495 0, // A: pri, tries, successful 496 0, 497 0, 498 0, // B: pri, tries, successful 499 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 500 ASSERT_EQ(nullptr, data); 501 } 502 503 TEST_F(AvbABFlowTest, TryingThenFallback) { 504 AvbSlotVerifyData* data; 505 const char* requested_partitions[] = {"boot", NULL}; 506 507 SetMD(15, 508 2, 509 0, 510 SV_OK, 511 0, 512 0, // A: pri, tries, success, slot_validity, RIs 513 14, 514 0, 515 1, 516 SV_OK, 517 0, 518 0, // B: pri, tries, success, slot_validity, RIs 519 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 520 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 521 avb_ab_flow(ops_.avb_ab_ops(), 522 requested_partitions, 523 AVB_SLOT_VERIFY_FLAGS_NONE, 524 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 525 &data)); 526 ExpMD(15, 527 1, 528 0, // A: pri, tries, successful 529 14, 530 0, 531 1, // B: pri, tries, successful 532 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 533 ASSERT_NE(nullptr, data); 534 EXPECT_EQ("_a", std::string(data->ab_suffix)); 535 avb_slot_verify_data_free(data); 536 537 // Last try... 538 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 539 avb_ab_flow(ops_.avb_ab_ops(), 540 requested_partitions, 541 AVB_SLOT_VERIFY_FLAGS_NONE, 542 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 543 &data)); 544 ExpMD(15, 545 0, 546 0, // A: pri, tries, successful 547 14, 548 0, 549 1, // B: pri, tries, successful 550 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 551 ASSERT_NE(nullptr, data); 552 EXPECT_EQ("_a", std::string(data->ab_suffix)); 553 avb_slot_verify_data_free(data); 554 555 // And we're out of tries. Check we fall back to slot B. 556 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 557 avb_ab_flow(ops_.avb_ab_ops(), 558 requested_partitions, 559 AVB_SLOT_VERIFY_FLAGS_NONE, 560 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 561 &data)); 562 ExpMD(0, 563 0, 564 0, // A: pri, tries, successful 565 14, 566 0, 567 1, // B: pri, tries, successful 568 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 569 ASSERT_NE(nullptr, data); 570 EXPECT_EQ("_b", std::string(data->ab_suffix)); 571 avb_slot_verify_data_free(data); 572 } 573 574 TEST_F(AvbABFlowTest, TriesRemainingNotDecreasingIfNotPriority) { 575 AvbSlotVerifyData* data; 576 const char* requested_partitions[] = {"boot", NULL}; 577 578 SetMD(15, 579 0, 580 1, 581 SV_OK, 582 0, 583 0, // A: pri, tries, success, slot_validity, RIs 584 14, 585 7, 586 0, 587 SV_OK, 588 0, 589 0, // B: pri, tries, success, slot_validity, RIs 590 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 591 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 592 avb_ab_flow(ops_.avb_ab_ops(), 593 requested_partitions, 594 AVB_SLOT_VERIFY_FLAGS_NONE, 595 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 596 &data)); 597 ExpMD(15, 598 0, 599 1, // A: pri, tries, successful 600 14, 601 7, 602 0, // B: pri, tries, successful 603 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 604 ASSERT_NE(nullptr, data); 605 EXPECT_EQ("_a", std::string(data->ab_suffix)); 606 avb_slot_verify_data_free(data); 607 } 608 609 TEST_F(AvbABFlowTest, InvalidSlotIsMarkedAsSuch) { 610 AvbSlotVerifyData* data; 611 const char* requested_partitions[] = {"boot", NULL}; 612 613 // Slot A is invalid. 614 SetMD(15, 615 0, 616 1, 617 SV_INV, 618 0, 619 0, // A: pri, tries, success, slot_validity, RIs 620 14, 621 0, 622 1, 623 SV_OK, 624 0, 625 0, // B: pri, tries, success, slot_validity, RIs 626 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 627 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 628 avb_ab_flow(ops_.avb_ab_ops(), 629 requested_partitions, 630 AVB_SLOT_VERIFY_FLAGS_NONE, 631 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 632 &data)); 633 ExpMD(0, 634 0, 635 0, // A: pri, tries, successful 636 14, 637 0, 638 1, // B: pri, tries, successful 639 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 640 ASSERT_NE(nullptr, data); 641 EXPECT_EQ("_b", std::string(data->ab_suffix)); 642 avb_slot_verify_data_free(data); 643 644 // Slot B is invalid. 645 SetMD(15, 646 0, 647 1, 648 SV_OK, 649 0, 650 0, // A: pri, tries, success, slot_validity, RIs 651 14, 652 0, 653 1, 654 SV_INV, 655 0, 656 0, // B: pri, tries, success, slot_validity, RIs 657 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 658 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 659 avb_ab_flow(ops_.avb_ab_ops(), 660 requested_partitions, 661 AVB_SLOT_VERIFY_FLAGS_NONE, 662 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 663 &data)); 664 ExpMD(15, 665 0, 666 1, // A: pri, tries, successful 667 0, 668 0, 669 0, // B: pri, tries, successful 670 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 671 ASSERT_NE(nullptr, data); 672 EXPECT_EQ("_a", std::string(data->ab_suffix)); 673 avb_slot_verify_data_free(data); 674 675 // Both slots are invalid. 676 SetMD(15, 677 0, 678 1, 679 SV_INV, 680 0, 681 0, // A: pri, tries, success, slot_validity, RIs 682 14, 683 0, 684 1, 685 SV_INV, 686 0, 687 0, // B: pri, tries, success, slot_validity, RIs 688 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 689 EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS, 690 avb_ab_flow(ops_.avb_ab_ops(), 691 requested_partitions, 692 AVB_SLOT_VERIFY_FLAGS_NONE, 693 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 694 &data)); 695 ExpMD(0, 696 0, 697 0, // A: pri, tries, successful 698 0, 699 0, 700 0, // B: pri, tries, successful 701 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 702 ASSERT_EQ(nullptr, data); 703 } 704 705 TEST_F(AvbABFlowTest, UnverifiedSlotIsMarkedAsSuch) { 706 AvbSlotVerifyData* data; 707 const char* requested_partitions[] = {"boot", NULL}; 708 709 // Slot A fails verification. 710 SetMD(15, 711 0, 712 1, 713 SV_UNV, 714 0, 715 0, // A: pri, tries, success, slot_validity, RIs 716 14, 717 0, 718 1, 719 SV_OK, 720 0, 721 0, // B: pri, tries, success, slot_validity, RIs 722 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 723 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 724 avb_ab_flow(ops_.avb_ab_ops(), 725 requested_partitions, 726 AVB_SLOT_VERIFY_FLAGS_NONE, 727 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 728 &data)); 729 ExpMD(0, 730 0, 731 0, // A: pri, tries, successful 732 14, 733 0, 734 1, // B: pri, tries, successful 735 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 736 ASSERT_NE(nullptr, data); 737 EXPECT_EQ("_b", std::string(data->ab_suffix)); 738 avb_slot_verify_data_free(data); 739 740 // Slot B fails verification. 741 SetMD(15, 742 0, 743 1, 744 SV_OK, 745 0, 746 0, // A: pri, tries, success, slot_validity, RIs 747 14, 748 0, 749 1, 750 SV_UNV, 751 0, 752 0, // B: pri, tries, success, slot_validity, RIs 753 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 754 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 755 avb_ab_flow(ops_.avb_ab_ops(), 756 requested_partitions, 757 AVB_SLOT_VERIFY_FLAGS_NONE, 758 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 759 &data)); 760 ExpMD(15, 761 0, 762 1, // A: pri, tries, successful 763 0, 764 0, 765 0, // B: pri, tries, successful 766 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 767 ASSERT_NE(nullptr, data); 768 EXPECT_EQ("_a", std::string(data->ab_suffix)); 769 avb_slot_verify_data_free(data); 770 771 // Both slots fail verification. 772 SetMD(15, 773 0, 774 1, 775 SV_UNV, 776 0, 777 0, // A: pri, tries, success, slot_validity, RIs 778 14, 779 0, 780 1, 781 SV_UNV, 782 0, 783 0, // B: pri, tries, success, slot_validity, RIs 784 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 785 EXPECT_EQ(AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS, 786 avb_ab_flow(ops_.avb_ab_ops(), 787 requested_partitions, 788 AVB_SLOT_VERIFY_FLAGS_NONE, 789 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 790 &data)); 791 ExpMD(0, 792 0, 793 0, // A: pri, tries, successful 794 0, 795 0, 796 0, // B: pri, tries, successful 797 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 798 ASSERT_EQ(nullptr, data); 799 } 800 801 TEST_F(AvbABFlowTest, RollbackIndexFailures) { 802 AvbSlotVerifyData* data; 803 const char* requested_partitions[] = {"boot", NULL}; 804 805 // Slot A rollback index failure for 'boot'. 806 SetMD(15, 807 0, 808 1, 809 SV_OK, 810 0, 811 2, // A: pri, tries, success, slot_validity, RIs 812 14, 813 0, 814 1, 815 SV_OK, 816 2, 817 2, // B: pri, tries, success, slot_validity, RIs 818 MakeRollbackIndexes(2, 2)); // stored_rollback_indexes 819 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 820 avb_ab_flow(ops_.avb_ab_ops(), 821 requested_partitions, 822 AVB_SLOT_VERIFY_FLAGS_NONE, 823 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 824 &data)); 825 ExpMD(0, 826 0, 827 0, // A: pri, tries, successful 828 14, 829 0, 830 1, // B: pri, tries, successful 831 MakeRollbackIndexes(2, 2)); // stored_rollback_indexes 832 ASSERT_NE(nullptr, data); 833 EXPECT_EQ("_b", std::string(data->ab_suffix)); 834 avb_slot_verify_data_free(data); 835 836 // Slot A rollback index failure for 'odm'. 837 SetMD(15, 838 0, 839 1, 840 SV_OK, 841 2, 842 0, // A: pri, tries, success, slot_validity, RIs 843 14, 844 0, 845 1, 846 SV_OK, 847 2, 848 2, // B: pri, tries, success, slot_validity, RIs 849 MakeRollbackIndexes(2, 2)); // stored_rollback_indexes 850 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 851 avb_ab_flow(ops_.avb_ab_ops(), 852 requested_partitions, 853 AVB_SLOT_VERIFY_FLAGS_NONE, 854 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 855 &data)); 856 ExpMD(0, 857 0, 858 0, // A: pri, tries, successful 859 14, 860 0, 861 1, // B: pri, tries, successful 862 MakeRollbackIndexes(2, 2)); // stored_rollback_indexes 863 ASSERT_NE(nullptr, data); 864 EXPECT_EQ("_b", std::string(data->ab_suffix)); 865 avb_slot_verify_data_free(data); 866 } 867 868 TEST_F(AvbABFlowTest, StoredRollbackIndexBumped) { 869 AvbSlotVerifyData* data; 870 const char* requested_partitions[] = {"boot", NULL}; 871 872 SetMD(15, 873 0, 874 1, 875 SV_OK, 876 3, 877 3, // A: pri, tries, success, slot_validity, RIs 878 14, 879 0, 880 1, 881 SV_OK, 882 3, 883 3, // B: pri, tries, success, slot_validity, RIs 884 MakeRollbackIndexes(2, 2)); // stored_rollback_indexes 885 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 886 avb_ab_flow(ops_.avb_ab_ops(), 887 requested_partitions, 888 AVB_SLOT_VERIFY_FLAGS_NONE, 889 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 890 &data)); 891 ExpMD(15, 892 0, 893 1, // A: pri, tries, successful 894 14, 895 0, 896 1, // B: pri, tries, successful 897 MakeRollbackIndexes(3, 3)); // stored_rollback_indexes 898 ASSERT_NE(nullptr, data); 899 EXPECT_EQ("_a", std::string(data->ab_suffix)); 900 avb_slot_verify_data_free(data); 901 902 // The case where different partitions have different rollback 903 // index values. 904 SetMD(15, 905 0, 906 1, 907 SV_OK, 908 4, 909 9, // A: pri, tries, success, slot_validity, RIs 910 14, 911 0, 912 1, 913 SV_OK, 914 5, 915 7, // B: pri, tries, success, slot_validity, RIs 916 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 917 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 918 avb_ab_flow(ops_.avb_ab_ops(), 919 requested_partitions, 920 AVB_SLOT_VERIFY_FLAGS_NONE, 921 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 922 &data)); 923 ExpMD(15, 924 0, 925 1, // A: pri, tries, successful 926 14, 927 0, 928 1, // B: pri, tries, successful 929 MakeRollbackIndexes(4, 7)); // stored_rollback_indexes 930 ASSERT_NE(nullptr, data); 931 EXPECT_EQ("_a", std::string(data->ab_suffix)); 932 avb_slot_verify_data_free(data); 933 934 // If the slot with the low RI fails verification (or is invalid), 935 // check that these low Rollback Indexs are not taken into account 936 // after marking it as unbootable. 937 SetMD(15, 938 0, 939 1, 940 SV_INV, 941 4, 942 9, // A: pri, tries, success, slot_validity, RIs 943 14, 944 0, 945 1, 946 SV_OK, 947 5, 948 7, // B: pri, tries, success, slot_validity, RIs 949 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 950 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 951 avb_ab_flow(ops_.avb_ab_ops(), 952 requested_partitions, 953 AVB_SLOT_VERIFY_FLAGS_NONE, 954 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 955 &data)); 956 ExpMD(0, 957 0, 958 0, // A: pri, tries, successful 959 14, 960 0, 961 1, // B: pri, tries, successful 962 MakeRollbackIndexes(5, 7)); // stored_rollback_indexes 963 ASSERT_NE(nullptr, data); 964 EXPECT_EQ("_b", std::string(data->ab_suffix)); 965 avb_slot_verify_data_free(data); 966 } 967 968 TEST_F(AvbABFlowTest, MarkSlotActive) { 969 SetMD(15, 970 0, 971 1, 972 SV_INV, 973 0, 974 0, // A: pri, tries, success, slot_validity, RIs 975 11, 976 0, 977 1, 978 SV_OK, 979 0, 980 0, // B: pri, tries, success, slot_validity, RIs 981 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 982 EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_mark_slot_active(ops_.avb_ab_ops(), 0)); 983 ExpMD(15, 984 7, 985 0, // A: pri, tries, successful 986 11, 987 0, 988 1, // B: pri, tries, successful 989 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 990 991 // Note how priority of slot A is altered to make room for newly 992 // activated slot. 993 SetMD(15, 994 0, 995 1, 996 SV_INV, 997 0, 998 0, // A: pri, tries, success, slot_validity, RIs 999 14, 1000 0, 1001 1, 1002 SV_OK, 1003 0, 1004 0, // B: pri, tries, success, slot_validity, RIs 1005 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1006 EXPECT_EQ(AVB_IO_RESULT_OK, avb_ab_mark_slot_active(ops_.avb_ab_ops(), 1)); 1007 ExpMD(14, 1008 0, 1009 1, // A: pri, tries, successful 1010 15, 1011 7, 1012 0, // B: pri, tries, successful 1013 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1014 } 1015 1016 TEST_F(AvbABFlowTest, MarkSlotUnbootable) { 1017 SetMD(15, 1018 0, 1019 1, 1020 SV_INV, 1021 0, 1022 0, // A: pri, tries, success, slot_validity, RIs 1023 11, 1024 0, 1025 1, 1026 SV_OK, 1027 0, 1028 0, // B: pri, tries, success, slot_validity, RIs 1029 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1030 EXPECT_EQ(AVB_IO_RESULT_OK, 1031 avb_ab_mark_slot_unbootable(ops_.avb_ab_ops(), 0)); 1032 ExpMD(0, 1033 0, 1034 0, // A: pri, tries, successful 1035 11, 1036 0, 1037 1, // B: pri, tries, successful 1038 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1039 1040 SetMD(15, 1041 0, 1042 1, 1043 SV_INV, 1044 0, 1045 0, // A: pri, tries, success, slot_validity, RIs 1046 14, 1047 0, 1048 1, 1049 SV_OK, 1050 0, 1051 0, // B: pri, tries, success, slot_validity, RIs 1052 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1053 EXPECT_EQ(AVB_IO_RESULT_OK, 1054 avb_ab_mark_slot_unbootable(ops_.avb_ab_ops(), 1)); 1055 ExpMD(15, 1056 0, 1057 1, // A: pri, tries, successful 1058 0, 1059 0, 1060 0, // B: pri, tries, successful 1061 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1062 } 1063 1064 TEST_F(AvbABFlowTest, MarkSlotSuccessful) { 1065 SetMD(15, 1066 5, 1067 0, 1068 SV_INV, 1069 0, 1070 0, // A: pri, tries, success, slot_validity, RIs 1071 11, 1072 3, 1073 0, 1074 SV_OK, 1075 0, 1076 0, // B: pri, tries, success, slot_validity, RIs 1077 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1078 EXPECT_EQ(AVB_IO_RESULT_OK, 1079 avb_ab_mark_slot_successful(ops_.avb_ab_ops(), 0)); 1080 ExpMD(15, 1081 0, 1082 1, // A: pri, tries, successful 1083 11, 1084 3, 1085 0, // B: pri, tries, successful 1086 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1087 1088 SetMD(15, 1089 5, 1090 0, 1091 SV_INV, 1092 0, 1093 0, // A: pri, tries, success, slot_validity, RIs 1094 14, 1095 0, 1096 1, 1097 SV_OK, 1098 0, 1099 0, // B: pri, tries, success, slot_validity, RIs 1100 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1101 EXPECT_EQ(AVB_IO_RESULT_OK, 1102 avb_ab_mark_slot_successful(ops_.avb_ab_ops(), 1)); 1103 ExpMD(15, 1104 5, 1105 0, // A: pri, tries, successful 1106 14, 1107 0, 1108 1, // B: pri, tries, successful 1109 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1110 1111 // Marking an unbootable slot (A) as successful won't work (it's a 1112 // programmer error to do so)... notice however that the unbootable 1113 // slot is normalized in the process. 1114 SetMD(0, 1115 3, 1116 2, 1117 SV_INV, 1118 0, 1119 0, // A: pri, tries, success, slot_validity, RIs 1120 14, 1121 0, 1122 1, 1123 SV_OK, 1124 0, 1125 0, // B: pri, tries, success, slot_validity, RIs 1126 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1127 EXPECT_EQ(AVB_IO_RESULT_OK, 1128 avb_ab_mark_slot_successful(ops_.avb_ab_ops(), 0)); 1129 ExpMD(0, 1130 0, 1131 0, // A: pri, tries, successful 1132 14, 1133 0, 1134 1, // B: pri, tries, successful 1135 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1136 } 1137 1138 static AvbABData my_serialized_data; 1139 1140 static AvbIOResult my_write_ab_metadata(AvbABOps* ops, 1141 const struct AvbABData* data) { 1142 avb_ab_data_update_crc_and_byteswap(data, &my_serialized_data); 1143 return AVB_IO_RESULT_OK; 1144 } 1145 1146 static AvbIOResult my_read_ab_metadata(AvbABOps* ops, struct AvbABData* data) { 1147 if (!avb_ab_data_verify_and_byteswap(&my_serialized_data, data)) { 1148 avb_error( 1149 "Error validating A/B metadata from persistent storage. " 1150 "Resetting and writing new A/B metadata to persistent storage.\n"); 1151 avb_ab_data_init(data); 1152 return my_write_ab_metadata(ops, data); 1153 } 1154 return AVB_IO_RESULT_OK; 1155 } 1156 1157 TEST_F(AvbABFlowTest, OtherMetadataStorage) { 1158 AvbSlotVerifyData* data; 1159 const char* requested_partitions[] = {"boot", NULL}; 1160 1161 // Use our own A/B storage routines (see above). 1162 ops_.avb_ab_ops()->read_ab_metadata = my_read_ab_metadata; 1163 ops_.avb_ab_ops()->write_ab_metadata = my_write_ab_metadata; 1164 1165 SetMD(14, 1166 0, 1167 1, 1168 SV_OK, 1169 0, 1170 0, // A: pri, tries, success, slot_validity, RIs 1171 15, 1172 0, 1173 1, 1174 SV_OK, 1175 0, 1176 0, // B: pri, tries, success, slot_validity, RIs 1177 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1178 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 1179 avb_ab_flow(ops_.avb_ab_ops(), 1180 requested_partitions, 1181 AVB_SLOT_VERIFY_FLAGS_NONE, 1182 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 1183 &data)); 1184 ExpMD(14, 1185 0, 1186 1, // A: pri, tries, successful 1187 15, 1188 0, 1189 1, // B: pri, tries, successful 1190 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1191 ASSERT_NE(nullptr, data); 1192 EXPECT_EQ("_b", std::string(data->ab_suffix)); 1193 avb_slot_verify_data_free(data); 1194 1195 // Also check the other slot. 1196 SetMD(15, 1197 0, 1198 1, 1199 SV_OK, 1200 0, 1201 0, // A: pri, tries, success, slot_validity, RIs 1202 14, 1203 0, 1204 1, 1205 SV_OK, 1206 0, 1207 0, // B: pri, tries, success, slot_validity, RIs 1208 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1209 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK, 1210 avb_ab_flow(ops_.avb_ab_ops(), 1211 requested_partitions, 1212 AVB_SLOT_VERIFY_FLAGS_NONE, 1213 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 1214 &data)); 1215 ExpMD(15, 1216 0, 1217 1, // A: pri, tries, successful 1218 14, 1219 0, 1220 1, // B: pri, tries, successful 1221 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1222 ASSERT_NE(nullptr, data); 1223 EXPECT_EQ("_a", std::string(data->ab_suffix)); 1224 avb_slot_verify_data_free(data); 1225 1226 // Check that 'misc' hasn't been written to at all. 1227 std::string misc_data; 1228 base::FilePath misc_path = testdir_.Append("misc.img"); 1229 ASSERT_TRUE(base::ReadFileToString(misc_path, &misc_data)); 1230 EXPECT_EQ(size_t(MISC_PART_SIZE), misc_data.size()); 1231 for (size_t n = 0; n < misc_data.size(); n++) { 1232 ASSERT_EQ(uint8_t(misc_data[n]), 0); 1233 } 1234 } 1235 1236 TEST_F(AvbABFlowTest, UnlockedUnverifiedSlot) { 1237 AvbSlotVerifyData* data; 1238 const char* requested_partitions[] = {"boot", NULL}; 1239 1240 SetMD(14, 1241 0, 1242 1, 1243 SV_OK, 1244 0, 1245 0, // A: pri, tries, success, slot_validity, RIs 1246 15, 1247 0, 1248 1, 1249 SV_UNV, 1250 0, 1251 0, // B: pri, tries, success, slot_validity, RIs 1252 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1253 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR, 1254 avb_ab_flow(ops_.avb_ab_ops(), 1255 requested_partitions, 1256 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR, 1257 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 1258 &data)); 1259 ExpMD(14, 1260 0, 1261 1, // A: pri, tries, successful 1262 15, 1263 0, 1264 1, // B: pri, tries, successful 1265 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1266 ASSERT_NE(nullptr, data); 1267 EXPECT_EQ("_b", std::string(data->ab_suffix)); 1268 avb_slot_verify_data_free(data); 1269 1270 // Also check the other slot. 1271 SetMD(15, 1272 0, 1273 1, 1274 SV_UNV, 1275 0, 1276 0, // A: pri, tries, success, slot_validity, RIs 1277 14, 1278 0, 1279 1, 1280 SV_OK, 1281 0, 1282 0, // B: pri, tries, success, slot_validity, RIs 1283 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1284 EXPECT_EQ(AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR, 1285 avb_ab_flow(ops_.avb_ab_ops(), 1286 requested_partitions, 1287 AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR, 1288 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, 1289 &data)); 1290 ExpMD(15, 1291 0, 1292 1, // A: pri, tries, successful 1293 14, 1294 0, 1295 1, // B: pri, tries, successful 1296 MakeRollbackIndexes(0, 0)); // stored_rollback_indexes 1297 ASSERT_NE(nullptr, data); 1298 EXPECT_EQ("_a", std::string(data->ab_suffix)); 1299 avb_slot_verify_data_free(data); 1300 } 1301 1302 TEST_F(AvbABFlowTest, AvbtoolMetadataGeneratorEmptyFile) { 1303 AvbABData data; 1304 1305 base::FilePath misc_path = testdir_.Append("misc.img"); 1306 EXPECT_COMMAND(0, 1307 "./avbtool set_ab_metadata" 1308 " --misc_image %s" 1309 " --slot_data 13:3:0:11:2:1", 1310 misc_path.value().c_str()); 1311 1312 EXPECT_EQ(AVB_IO_RESULT_OK, 1313 ops_.avb_ab_ops()->read_ab_metadata(ops_.avb_ab_ops(), &data)); 1314 EXPECT_EQ(13, data.slots[0].priority); 1315 EXPECT_EQ(3, data.slots[0].tries_remaining); 1316 EXPECT_EQ(0, data.slots[0].successful_boot); 1317 EXPECT_EQ(11, data.slots[1].priority); 1318 EXPECT_EQ(2, data.slots[1].tries_remaining); 1319 EXPECT_EQ(1, data.slots[1].successful_boot); 1320 } 1321 1322 TEST_F(AvbABFlowTest, AvbtoolMetadataGeneratorExistingFile) { 1323 AvbABData data; 1324 size_t n; 1325 1326 size_t misc_size = 1024 * 1024; 1327 base::FilePath misc_path = GenerateImage("misc.img", misc_size); 1328 EXPECT_COMMAND(0, 1329 "./avbtool set_ab_metadata" 1330 " --misc_image %s" 1331 " --slot_data 12:2:1:10:5:0", 1332 misc_path.value().c_str()); 1333 1334 EXPECT_EQ(AVB_IO_RESULT_OK, 1335 ops_.avb_ab_ops()->read_ab_metadata(ops_.avb_ab_ops(), &data)); 1336 EXPECT_EQ(12, data.slots[0].priority); 1337 EXPECT_EQ(2, data.slots[0].tries_remaining); 1338 EXPECT_EQ(1, data.slots[0].successful_boot); 1339 EXPECT_EQ(10, data.slots[1].priority); 1340 EXPECT_EQ(5, data.slots[1].tries_remaining); 1341 EXPECT_EQ(0, data.slots[1].successful_boot); 1342 1343 std::string misc_data; 1344 ASSERT_TRUE(base::ReadFileToString(misc_path, &misc_data)); 1345 EXPECT_EQ(misc_size, misc_data.size()); 1346 for (n = 0; n < 2048; n++) { 1347 ASSERT_EQ(uint8_t(misc_data[n]), uint8_t(n)); 1348 } 1349 for (n = 2048 + 32; n < misc_data.size(); n++) { 1350 ASSERT_EQ(uint8_t(misc_data[n]), uint8_t(n)); 1351 } 1352 } 1353 1354 } // namespace avb 1355