/* * Copyright (C) 2020 The Android Open Source Project * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "libavb_aftl/avb_aftl_util.h" #include #include "avb_unittest_util.h" #include "libavb_aftl/avb_aftl_types.h" namespace { /* TODO(b/154115873): These VBMetas are manually generated. We need to implement * a mock in aftltool that generates an inclusion proof and call that mock from * the unit tests, similarly to what is done with GenerateVBMetaImage. */ const char kAftlImagePath[] = "test/data/aftl_output_vbmeta_with_1_icp.img"; const uint64_t kAftlImageOffset = 0x1100; const char kAftlImageMultiPath[] = "test/data/aftl_output_vbmeta_with_2_icp_same_log.img"; } // namespace namespace avb { /* Extend BaseAvbToolTest to take advantage of common checks and tooling. */ class AvbAftlUtilTest : public BaseAvbToolTest { public: AvbAftlUtilTest() {} ~AvbAftlUtilTest() {} void SetUp() override { std::string content; BaseAvbToolTest::SetUp(); /* Read in test data from the aftl_image binaries. */ ASSERT_TRUE( base::ReadFileToString(base::FilePath(kAftlImagePath), &content)); content = content.substr(kAftlImageOffset); /* Allocate and populate an AftlImage for testing. */ aftl_image_ = parse_aftl_image((uint8_t*)content.data(), content.size()); /* Read in test data from the aftl_image file with multiple ICPs. */ ASSERT_TRUE( base::ReadFileToString(base::FilePath(kAftlImageMultiPath), &content)); content = content.substr(kAftlImageOffset); /* Allocate and populate an AftlImage for testing. */ aftl_image_multi_ = parse_aftl_image((uint8_t*)content.data(), content.size()); } void TearDown() override { free_aftl_image(aftl_image_); free_aftl_image(aftl_image_multi_); BaseAvbToolTest::TearDown(); } void TestAftlImageHeader(AftlImageHeader* aftl_header, uint16_t icp_count) { EXPECT_EQ(aftl_header->magic, 0x4c544641ul); EXPECT_EQ(aftl_header->required_icp_version_major, 1ul); EXPECT_EQ(aftl_header->required_icp_version_minor, 2ul); EXPECT_EQ(aftl_header->icp_count, icp_count); } void TestAftlIcpEntry(AftlIcpEntry* icp_entry) { /* Test each field in the AftlIcpEntry. */ EXPECT_GT(icp_entry->log_url_size, 0ul); EXPECT_GT(icp_entry->leaf_index, 1ul); EXPECT_GT(icp_entry->log_root_descriptor_size, 0ul); EXPECT_GT(icp_entry->annotation_leaf_size, 0ul); EXPECT_EQ(icp_entry->log_root_sig_size, AVB_AFTL_SIGNATURE_SIZE); EXPECT_GT(icp_entry->proof_hash_count, 0ul); EXPECT_LT(icp_entry->proof_hash_count, 64ul); EXPECT_GT(icp_entry->inc_proof_size, 0ul); EXPECT_EQ(mem_to_hexstring(icp_entry->log_url, 8), "6c6f672e656e6470"); /* Test the TrillianLogRootDescriptor fields. */ EXPECT_EQ(icp_entry->log_root_descriptor.version, 1ul); EXPECT_GT(icp_entry->log_root_descriptor.tree_size, 0ull); EXPECT_EQ(icp_entry->log_root_descriptor.root_hash_size, AVB_AFTL_HASH_SIZE); EXPECT_GT(icp_entry->log_root_descriptor.timestamp, 0ull); EXPECT_GT(icp_entry->log_root_descriptor.revision, 0ull); EXPECT_EQ(icp_entry->log_root_descriptor.metadata_size, 0); /* Test the FirmwareInfo fields. */ EXPECT_EQ(icp_entry->annotation_leaf->annotation->vbmeta_hash_size, AVB_AFTL_HASH_SIZE); EXPECT_EQ(icp_entry->proof_hash_count * 32ul, icp_entry->inc_proof_size); } protected: AftlImage* aftl_image_; AftlImage* aftl_image_multi_; }; TEST_F(AvbAftlUtilTest, AftlImageHeaderStructure) { AftlImageHeader* header; ASSERT_NE(aftl_image_, nullptr); header = &(aftl_image_->header); ASSERT_NE(header, nullptr); TestAftlImageHeader(header, 1); } TEST_F(AvbAftlUtilTest, AftlImageMultipleIcps) { AftlImageHeader* header; size_t i; ASSERT_NE(aftl_image_multi_, nullptr); header = &(aftl_image_multi_->header); ASSERT_NE(header, nullptr); TestAftlImageHeader(header, 2); for (i = 0; i < header->icp_count; i++) { ASSERT_NE(aftl_image_multi_->entries[i], nullptr) << " Failed at entry " << i; TestAftlIcpEntry(aftl_image_multi_->entries[i]); } } TEST_F(AvbAftlUtilTest, AftlIcpEntryStructure) { AftlIcpEntry* icp_entry; icp_entry = aftl_image_->entries[0]; ASSERT_NE(icp_entry, nullptr); TestAftlIcpEntry(icp_entry); } } /* namespace avb */