diff --git a/fs_mgr/libfs_avb/tests/Android.bp b/fs_mgr/libfs_avb/tests/Android.bp new file mode 100644 index 000000000..4c02237f0 --- /dev/null +++ b/fs_mgr/libfs_avb/tests/Android.bp @@ -0,0 +1,35 @@ +// +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_test_host { + name: "libfs_avb_host_unittest", + required: [ + "avbtool", + ], + data: [ + "data/*", + ], + static_libs: [ + "libgtest_host", + ], + shared_libs: [ + "libbase", + "libchrome", + ], + srcs: [ + "fs_avb_unittest_util.cpp", + ], +} diff --git a/fs_mgr/libfs_avb/tests/data/testkey_rsa2048.pem b/fs_mgr/libfs_avb/tests/data/testkey_rsa2048.pem new file mode 100644 index 000000000..867dcff54 --- /dev/null +++ b/fs_mgr/libfs_avb/tests/data/testkey_rsa2048.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAxlVR3TIkouAOvH79vaJTgFhpfvVKQIeVkFRZPVXK/zY0Gvrh +4JAqGjJoW/PfrQv5sdD36qtHH3a+G5hLZ6Ni+t/mtfjucxZfuLGC3kmJ1T3XqEKZ +gXXI2IR7vVSoImREvDQGEDyJwtHzLANlkbGg0cghVhWZSCAndO8BenalC2v94/rt +DfkPekH6dgU3Sf40T0sBSeSY94mOzTaqOR2pfV1rWlLRdWmo33zeHBv52Rlbt0dM +uXAureXWiHztkm5GCBC1dgM+CaxNtizNEgC91KcD0xuRCCM2WxH+r1lpszyIJDct +YbrFmVEYl/kjQpafhy7Nsk1fqSTyRdriZSYmTQIDAQABAoIBAQC+kJgaCuX8wYAn +SXWQ0fmdZlXnMNRpcF0a0pD0SAzGb1RdYBXMaXiqtyhiwc53PPxsCDdNecjayIMd +jJVXPTwLhTruOgMS/bp3gcgWwV34UHV4LJXGOGAE+jbS0hbDBMiudOYmj6RmVshp +z9G1zZCSQNMXHaWsEYkX59XpzzoB384nRul2QgEtwzUNR9XlpzgtJBLk3SACkvsN +mQ/DW8IWHXLg8vLn1LzVJ2e3B16H4MoE2TCHxqfMgr03IDRRJogkenQuQsFhevYT +o/mJyHSWavVgzMHG9I5m+eepF4Wyhj1Y4WyKAuMI+9dHAX/h7Lt8XFCQCh5DbkVG +zGr34sWBAoGBAOs7n7YZqNaaguovfIdRRsxxZr1yJAyDsr6w3yGImDZYju4c4WY9 +5esO2kP3FA4p0c7FhQF5oOb1rBuHEPp36cpL4aGeK87caqTfq63WZAujoTZpr9Lp +BRbkL7w/xG7jpQ/clpA8sHzHGQs/nelxoOtC7E118FiRgvD/jdhlMyL9AoGBANfX +vyoN1pplfT2xR8QOjSZ+Q35S/+SAtMuBnHx3l0qH2bbBjcvM1MNDWjnRDyaYhiRu +i+KA7tqfib09+XpB3g5D6Ov7ls/Ldx0S/VcmVWtia2HK8y8iLGtokoBZKQ5AaFX2 +iQU8+tC4h69GnJYQKqNwgCUzh8+gHX5Y46oDiTmRAoGAYpOx8lX+czB8/Da6MNrW +mIZNT8atZLEsDs2ANEVRxDSIcTCZJId7+m1W+nRoaycLTWNowZ1+2ErLvR10+AGY +b7Ys79Wg9idYaY9yGn9lnZsMzAiuLeyIvXcSqgjvAKlVWrhOQFOughvNWvFl85Yy +oWSCMlPiTLtt7CCsCKsgKuECgYBgdIp6GZsIfkgclKe0hqgvRoeU4TR3gcjJlM9A +lBTo+pKhaBectplx9RxR8AnsPobbqwcaHnIfAuKDzjk5mEvKZjClnFXF4HAHbyAF +nRzZEy9XkWFhc80T5rRpZO7C7qdxmu2aiKixM3V3L3/0U58qULEDbubHMw9bEhAT +PudI8QKBgHEEiMm/hr9T41hbQi/LYanWnlFw1ue+osKuF8bXQuxnnHNuFT/c+9/A +vWhgqG6bOEHu+p/IPrYm4tBMYlwsyh4nXCyGgDJLbLIfzKwKAWCtH9LwnyDVhOow +GH9shdR+sW3Ew97xef02KAH4VlNANEmBV4sQNqWWvsYrcFm2rOdL +-----END RSA PRIVATE KEY----- diff --git a/fs_mgr/libfs_avb/tests/data/testkey_rsa4096.pem b/fs_mgr/libfs_avb/tests/data/testkey_rsa4096.pem new file mode 100644 index 000000000..26db5c3c0 --- /dev/null +++ b/fs_mgr/libfs_avb/tests/data/testkey_rsa4096.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/fs_mgr/libfs_avb/tests/data/testkey_rsa8192.pem b/fs_mgr/libfs_avb/tests/data/testkey_rsa8192.pem new file mode 100644 index 000000000..a383428a8 --- /dev/null +++ b/fs_mgr/libfs_avb/tests/data/testkey_rsa8192.pem @@ -0,0 +1,99 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/fs_mgr/libfs_avb/tests/fs_avb_unittest_util.cpp b/fs_mgr/libfs_avb/tests/fs_avb_unittest_util.cpp new file mode 100644 index 000000000..216d1cb5c --- /dev/null +++ b/fs_mgr/libfs_avb/tests/fs_avb_unittest_util.cpp @@ -0,0 +1,465 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fs_avb_unittest_util.h" + +#include + +#include +#include +#include + +namespace fs_avb_host_test { + +void BaseFsAvbTest::SetUp() { + // Changes current directory to test executable directory so that relative path + // references to test dependencies don't rely on being manually run from + // the executable directory. With this, we can just open "./data/testkey_rsa2048.pem" + // from the source. + base::SetCurrentDirectory(base::FilePath(android::base::GetExecutableDirectory())); + + // Creates a temporary directory, e.g., /tmp/libfs_avb-tests.XXXXXX to stash images in. + base::FilePath tmp_dir; + ASSERT_TRUE(GetTempDir(&tmp_dir)); + base::CreateTemporaryDirInDir(tmp_dir, "libfs_avb-tests.", &test_dir_); +} + +void BaseFsAvbTest::TearDown() { + // Nukes temporary directory. + ASSERT_NE(std::string::npos, test_dir_.value().find("libfs_avb-tests")); + ASSERT_TRUE(base::DeleteFile(test_dir_, true /* recursive */)); +} + +std::string BaseFsAvbTest::CalcVBMetaDigest(const std::string& file_name, + const std::string& hash_algorithm) { + auto iter = vbmeta_images_.find(file_name); + EXPECT_NE(iter, vbmeta_images_.end()); // ensures file_name is generated before. + + // Gets the image path from iterator->second.path: VBMetaImage.path. + base::FilePath image_path = iter->second.path; + base::FilePath vbmeta_digest_path = test_dir_.Append("vbmeta_digest"); + EXPECT_COMMAND(0, + "avbtool calculate_vbmeta_digest --image %s --hash_algorithm %s" + " --output %s", + image_path.value().c_str(), hash_algorithm.c_str(), + vbmeta_digest_path.value().c_str()); + // Reads the content of the output digest file. + std::string vbmeta_digest_data; + EXPECT_TRUE(base::ReadFileToString(vbmeta_digest_path, &vbmeta_digest_data)); + // Returns the trimmed digest. + std::string trimmed_digest_data; + base::TrimString(vbmeta_digest_data, " \t\n", &trimmed_digest_data); + return trimmed_digest_data; +} + +void BaseFsAvbTest::GenerateVBMetaImage( + const std::string& file_name, const std::string& avb_algorithm, uint64_t rollback_index, + const base::FilePath& key_path, + const std::vector& include_descriptor_image_paths, + const std::vector& chain_partitions, + const std::string& additional_options) { + // --algorithm and --key + std::string signing_options; + if (avb_algorithm == "") { + signing_options = " --algorithm NONE "; + } else { + signing_options = + std::string(" --algorithm ") + avb_algorithm + " --key " + key_path.value() + " "; + } + // --include_descriptors_from_image + std::string include_descriptor_options; + for (const auto& path : include_descriptor_image_paths) { + include_descriptor_options += " --include_descriptors_from_image " + path.value(); + } + // --chain_partitions + std::string chain_partition_options; + for (const auto& partition : chain_partitions) { + chain_partition_options += base::StringPrintf( + " --chain_partition %s:%u:%s", partition.partition_name.c_str(), + partition.rollback_index_location, partition.key_blob_path.value().c_str()); + } + // Starts to 'make_vbmeta_image'. + VBMetaImage vbmeta_image; + vbmeta_image.path = test_dir_.Append(file_name); + EXPECT_COMMAND(0, + "avbtool make_vbmeta_image" + " --rollback_index %" PRIu64 + " %s %s %s %s" + " --output %s", + rollback_index, signing_options.c_str(), include_descriptor_options.c_str(), + chain_partition_options.c_str(), additional_options.c_str(), + vbmeta_image.path.value().c_str()); + int64_t file_size; + ASSERT_TRUE(base::GetFileSize(vbmeta_image.path, &file_size)); + vbmeta_image.content.resize(file_size); + ASSERT_TRUE(base::ReadFile(vbmeta_image.path, + reinterpret_cast(vbmeta_image.content.data()), file_size)); + // Stores the generated vbmeta image into vbmeta_images_ member object. + vbmeta_images_.emplace(file_name, std::move(vbmeta_image)); +} + +void BaseFsAvbTest::ExtractVBMetaImage(const base::FilePath& image_path, + const std::string& output_file_name, + const size_t padding_size) { + VBMetaImage vbmeta_image; + vbmeta_image.path = test_dir_.Append(output_file_name); + EXPECT_COMMAND(0, + "avbtool extract_vbmeta_image" + " --image %s" + " --output %s" + " --padding_size %zu", + image_path.value().c_str(), vbmeta_image.path.value().c_str(), padding_size); + int64_t file_size; + ASSERT_TRUE(base::GetFileSize(vbmeta_image.path, &file_size)); + vbmeta_image.content.resize(file_size); + ASSERT_TRUE(base::ReadFile(vbmeta_image.path, + reinterpret_cast(vbmeta_image.content.data()), file_size)); + // Stores the extracted vbmeta image into vbmeta_images_ member object. + vbmeta_images_.emplace(output_file_name, std::move(vbmeta_image)); +} + +// Generates a file with name |file_name| of size |image_size| with +// known content (0x00 0x01 0x02 .. 0xff 0x00 0x01 ..). +base::FilePath BaseFsAvbTest::GenerateImage(const std::string file_name, size_t image_size, + uint8_t start_byte) { + std::vector image; + image.resize(image_size); + for (size_t n = 0; n < image_size; n++) { + image[n] = uint8_t(n + start_byte); + } + base::FilePath image_path = test_dir_.Append(file_name); + EXPECT_EQ(image_size, + static_cast(base::WriteFile( + image_path, reinterpret_cast(image.data()), image.size()))); + return image_path; +} + +void BaseFsAvbTest::AddAvbFooter(const base::FilePath& image_path, const std::string& footer_type, + const std::string& partition_name, const uint64_t partition_size, + const std::string& avb_algorithm, uint64_t rollback_index, + const base::FilePath& key_path, const std::string& salt, + const std::string& additional_options) { + // 'add_hash_footer' or 'add_hashtree_footer'. + EXPECT_TRUE(footer_type == "hash" or footer_type == "hashtree"); + std::string add_footer_option = "add_" + footer_type + "_footer"; + + std::string signing_options; + if (avb_algorithm == "") { + signing_options = " --algorithm NONE "; + } else { + signing_options = + std::string(" --algorithm ") + avb_algorithm + " --key " + key_path.value() + " "; + } + EXPECT_COMMAND(0, + "avbtool %s" + " --image %s" + " --partition_name %s " + " --partition_size %" PRIu64 " --rollback_index %" PRIu64 + " --salt %s" + " %s %s", + add_footer_option.c_str(), image_path.value().c_str(), partition_name.c_str(), + partition_size, rollback_index, salt.c_str(), signing_options.c_str(), + additional_options.c_str()); +} + +std::string BaseFsAvbTest::InfoImage(const base::FilePath& image_path) { + base::FilePath tmp_path = test_dir_.Append("info_output.txt"); + EXPECT_COMMAND(0, "avbtool info_image --image %s --output %s", image_path.value().c_str(), + tmp_path.value().c_str()); + std::string info_data; + EXPECT_TRUE(base::ReadFileToString(tmp_path, &info_data)); + return info_data; +} + +std::string BaseFsAvbTest::InfoImage(const std::string& file_name) { + auto iter = vbmeta_images_.find(file_name); + EXPECT_NE(iter, vbmeta_images_.end()); // ensures file_name is generated before. + // Gets the image path from iterator->second.path: VBMetaImage.path. + base::FilePath image_path = iter->second.path; + return InfoImage(image_path); +} + +base::FilePath BaseFsAvbTest::ExtractPublicKeyAvb(const base::FilePath& key_path) { + std::string file_name = key_path.RemoveExtension().BaseName().value(); + base::FilePath tmp_path = test_dir_.Append(file_name + "public_key.bin"); + EXPECT_COMMAND(0, + "avbtool extract_public_key --key %s" + " --output %s", + key_path.value().c_str(), tmp_path.value().c_str()); + return tmp_path; +} + +std::string BaseFsAvbTest::ExtractPublicKeyAvbBlob(const base::FilePath& key_path) { + base::FilePath tmp_path = test_dir_.Append("public_key.bin"); + EXPECT_COMMAND(0, + "avbtool extract_public_key --key %s" + " --output %s", + key_path.value().c_str(), tmp_path.value().c_str()); + std::string key_data; + EXPECT_TRUE(base::ReadFileToString(tmp_path, &key_data)); + return key_data; +} + +TEST_F(BaseFsAvbTest, GenerateImage) { + const size_t image_size = 5 * 1024 * 1024; + base::FilePath boot_path = GenerateImage("boot.img", image_size); + EXPECT_NE(0U, boot_path.value().size()); + + // Checks file size is as expected. + int64_t file_size; + ASSERT_TRUE(base::GetFileSize(boot_path, &file_size)); + EXPECT_EQ(file_size, image_size); + + // Checks file content is as expected. + std::vector expected_content; + expected_content.resize(image_size); + for (size_t n = 0; n < image_size; n++) { + expected_content[n] = uint8_t(n); + } + std::vector actual_content; + actual_content.resize(image_size); + EXPECT_TRUE( + base::ReadFile(boot_path, reinterpret_cast(actual_content.data()), image_size)); + EXPECT_EQ(expected_content, actual_content); +} + +TEST_F(BaseFsAvbTest, GenerateVBMetaImage) { + GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0, + base::FilePath("data/testkey_rsa2048.pem"), + {}, /* include_descriptor_image_paths */ + {}, /* chain_partitions */ + "--internal_release_string \"unit test\""); + EXPECT_EQ("5eba9ad4e775645e7eac441a563c200681ae868158d06f6a6cd36d06c07bd781", + CalcVBMetaDigest("vbmeta.img", "sha256")); + EXPECT_EQ( + "Minimum libavb version: 1.0\n" + "Header Block: 256 bytes\n" + "Authentication Block: 320 bytes\n" + "Auxiliary Block: 576 bytes\n" + "Algorithm: SHA256_RSA2048\n" + "Rollback Index: 0\n" + "Flags: 0\n" + "Release String: 'unit test'\n" + "Descriptors:\n" + " (none)\n", + InfoImage("vbmeta.img")); +} + +TEST_F(BaseFsAvbTest, AddHashFooter) { + // Generates a raw boot.img + const size_t image_size = 5 * 1024 * 1024; + const size_t partition_size = 10 * 1024 * 1024; + base::FilePath boot_path = GenerateImage("boot.img", image_size); + EXPECT_NE(0U, boot_path.value().size()); + // Checks file size is as expected. + int64_t file_size; + ASSERT_TRUE(base::GetFileSize(boot_path, &file_size)); + EXPECT_EQ(file_size, image_size); + // Appends AVB Hash Footer. + AddAvbFooter(boot_path, "hash", "boot", partition_size, "SHA256_RSA4096", 10, + base::FilePath("data/testkey_rsa4096.pem"), "d00df00d", + "--internal_release_string \"unit test\""); + // Extracts boot vbmeta from boot.img into boot-vbmeta.img. + ExtractVBMetaImage(boot_path, "boot-vbmeta.img"); + EXPECT_EQ( + "Minimum libavb version: 1.0\n" + "Header Block: 256 bytes\n" + "Authentication Block: 576 bytes\n" + "Auxiliary Block: 1216 bytes\n" + "Algorithm: SHA256_RSA4096\n" + "Rollback Index: 10\n" + "Flags: 0\n" + "Release String: 'unit test'\n" + "Descriptors:\n" + " Hash descriptor:\n" + " Image Size: 5242880 bytes\n" + " Hash Algorithm: sha256\n" + " Partition Name: boot\n" + " Salt: d00df00d\n" + " Digest: " + "222dd01e98284a1fcd7781f85d1392e43a530511a64eff96db197db90ebc4df1\n" + " Flags: 0\n", + InfoImage("boot-vbmeta.img")); +} + +TEST_F(BaseFsAvbTest, AddHashtreeFooter) { + // Generates a raw system.img + const size_t image_size = 50 * 1024 * 1024; + const size_t partition_size = 60 * 1024 * 1024; + base::FilePath system_path = GenerateImage("system.img", image_size); + EXPECT_NE(0U, system_path.value().size()); + // Checks file size is as expected. + int64_t file_size; + ASSERT_TRUE(base::GetFileSize(system_path, &file_size)); + EXPECT_EQ(file_size, image_size); + // Appends AVB Hashtree Footer. + AddAvbFooter(system_path, "hashtree", "system", partition_size, "SHA512_RSA8192", 20, + base::FilePath("data/testkey_rsa8192.pem"), "d00df00d", + "--internal_release_string \"unit test\""); + // Extracts system vbmeta from system.img into system-vbmeta.img. + ExtractVBMetaImage(system_path, "system-vbmeta.img"); + EXPECT_EQ( + "Minimum libavb version: 1.0\n" + "Header Block: 256 bytes\n" + "Authentication Block: 1088 bytes\n" + "Auxiliary Block: 2304 bytes\n" + "Algorithm: SHA512_RSA8192\n" + "Rollback Index: 20\n" + "Flags: 0\n" + "Release String: 'unit test'\n" + "Descriptors:\n" + " Hashtree descriptor:\n" + " Version of dm-verity: 1\n" + " Image Size: 52428800 bytes\n" + " Tree Offset: 52428800\n" + " Tree Size: 413696 bytes\n" + " Data Block Size: 4096 bytes\n" + " Hash Block Size: 4096 bytes\n" + " FEC num roots: 2\n" + " FEC offset: 52842496\n" + " FEC size: 417792 bytes\n" + " Hash Algorithm: sha1\n" + " Partition Name: system\n" + " Salt: d00df00d\n" + " Root Digest: d20d40c02298e385ab6d398a61a3b91dc9947d99\n" + " Flags: 0\n", + InfoImage("system-vbmeta.img")); +} + +TEST_F(BaseFsAvbTest, GenerateVBMetaImageWithDescriptors) { + // Generates a raw boot.img + const size_t boot_image_size = 5 * 1024 * 1024; + const size_t boot_partition_size = 10 * 1024 * 1024; + base::FilePath boot_path = GenerateImage("boot.img", boot_image_size); + // Adds AVB Hash Footer. + AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA4096", 10, + base::FilePath("data/testkey_rsa4096.pem"), "d00df00d", + "--internal_release_string \"unit test\""); + + // Generates a raw system.img, use a smaller size to speed-up unit test. + const size_t system_image_size = 10 * 1024 * 1024; + const size_t system_partition_size = 15 * 1024 * 1024; + base::FilePath system_path = GenerateImage("system.img", system_image_size); + // Adds AVB Hashtree Footer. + AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA8192", 20, + base::FilePath("data/testkey_rsa8192.pem"), "d00df00d", + "--internal_release_string \"unit test\""); + + // Makes a vbmeta.img including both 'boot' and 'system' descriptors. + GenerateVBMetaImage("vbmeta.img", "SHA256_RSA2048", 0, + base::FilePath("data/testkey_rsa2048.pem"), + {boot_path, system_path}, /* include_descriptor_image_paths */ + {}, /* chain_partitions */ + "--internal_release_string \"unit test\""); + EXPECT_EQ("a069cbfc30c816cddf3b53f1ad53b7ca5d61a3d93845eb596bbb1b40caa1c62f", + CalcVBMetaDigest("vbmeta.img", "sha256")); + EXPECT_EQ( + "Minimum libavb version: 1.0\n" + "Header Block: 256 bytes\n" + "Authentication Block: 320 bytes\n" + "Auxiliary Block: 960 bytes\n" + "Algorithm: SHA256_RSA2048\n" + "Rollback Index: 0\n" + "Flags: 0\n" + "Release String: 'unit test'\n" + "Descriptors:\n" + " Hash descriptor:\n" + " Image Size: 5242880 bytes\n" + " Hash Algorithm: sha256\n" + " Partition Name: boot\n" + " Salt: d00df00d\n" + " Digest: " + "222dd01e98284a1fcd7781f85d1392e43a530511a64eff96db197db90ebc4df1\n" + " Flags: 0\n" + " Hashtree descriptor:\n" + " Version of dm-verity: 1\n" + " Image Size: 10485760 bytes\n" + " Tree Offset: 10485760\n" + " Tree Size: 86016 bytes\n" + " Data Block Size: 4096 bytes\n" + " Hash Block Size: 4096 bytes\n" + " FEC num roots: 2\n" + " FEC offset: 10571776\n" + " FEC size: 90112 bytes\n" + " Hash Algorithm: sha1\n" + " Partition Name: system\n" + " Salt: d00df00d\n" + " Root Digest: a3d5dd307341393d85de356c384ff543ec1ed81b\n" + " Flags: 0\n", + InfoImage("vbmeta.img")); +} + +TEST_F(BaseFsAvbTest, GenerateVBMetaImageWithChainDescriptors) { + // Generates a raw boot.img + const size_t boot_image_size = 5 * 1024 * 1024; + const size_t boot_partition_size = 10 * 1024 * 1024; + base::FilePath boot_path = GenerateImage("boot.img", boot_image_size); + // Adds AVB Hash Footer. + AddAvbFooter(boot_path, "hash", "boot", boot_partition_size, "SHA256_RSA2048", 10, + base::FilePath("data/testkey_rsa2048.pem"), "d00df00d", + "--internal_release_string \"unit test\""); + + // Generates a raw system.img, use a smaller size to speed-up unit test. + const size_t system_image_size = 10 * 1024 * 1024; + const size_t system_partition_size = 15 * 1024 * 1024; + base::FilePath system_path = GenerateImage("system.img", system_image_size); + // Adds AVB Hashtree Footer. + AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20, + base::FilePath("data/testkey_rsa4096.pem"), "d00df00d", + "--internal_release_string \"unit test\""); + + // Make a vbmeta image with chain partitions. + base::FilePath rsa2048_public_key = + ExtractPublicKeyAvb(base::FilePath("data/testkey_rsa2048.pem")); + base::FilePath rsa4096_public_key = + ExtractPublicKeyAvb(base::FilePath("data/testkey_rsa4096.pem")); + GenerateVBMetaImage("vbmeta.img", "SHA256_RSA8192", 0, + base::FilePath("data/testkey_rsa8192.pem"), + {}, /* include_descriptor_image_paths */ + {{"boot", 1, rsa2048_public_key}, /* chain_partitions */ + {"system", 2, rsa4096_public_key}}, + "--internal_release_string \"unit test\""); + + // vbmeta digest calculation includes the chained vbmeta from boot.img and system.img. + EXPECT_EQ("abbe11b316901f3336e26630f64c4732dadbe14532186ac8640e4141a403721f", + CalcVBMetaDigest("vbmeta.img", "sha256")); + EXPECT_EQ( + "Minimum libavb version: 1.0\n" + "Header Block: 256 bytes\n" + "Authentication Block: 1088 bytes\n" + "Auxiliary Block: 3840 bytes\n" + "Algorithm: SHA256_RSA8192\n" + "Rollback Index: 0\n" + "Flags: 0\n" + "Release String: 'unit test'\n" + "Descriptors:\n" + " Chain Partition descriptor:\n" + " Partition Name: boot\n" + " Rollback Index Location: 1\n" + " Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d\n" + " Chain Partition descriptor:\n" + " Partition Name: system\n" + " Rollback Index Location: 2\n" + " Public key (sha1): 2597c218aae470a130f61162feaae70afd97f011\n", + InfoImage("vbmeta.img")); +} + +} // namespace fs_avb_host_test + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/fs_mgr/libfs_avb/tests/fs_avb_unittest_util.h b/fs_mgr/libfs_avb/tests/fs_avb_unittest_util.h new file mode 100644 index 000000000..f3294660c --- /dev/null +++ b/fs_mgr/libfs_avb/tests/fs_avb_unittest_util.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + +// Utility macro to run the command expressed by the printf()-style string +// |command_format| using the system(3) utility function. Will assert unless +// the command exits normally with exit status |expected_exit_status|. +#define EXPECT_COMMAND(expected_exit_status, command_format, ...) \ + do { \ + int rc = system(base::StringPrintf(command_format, ##__VA_ARGS__).c_str()); \ + EXPECT_TRUE(WIFEXITED(rc)); \ + EXPECT_EQ(WEXITSTATUS(rc), expected_exit_status); \ + } while (0); + +namespace fs_avb_host_test { + +struct VBMetaImage { + // Path to vbmeta image generated with GenerateVBMetaImage(). + base::FilePath path; + // Contents of the image generated with GenerateVBMetaImage(). + std::vector content; +}; + +struct ChainPartitionConfig { + std::string partition_name; + uint32_t rollback_index_location; + base::FilePath key_blob_path; +}; + +/* Base-class used for unit test. */ +class BaseFsAvbTest : public ::testing::Test { + public: + BaseFsAvbTest() {} + + protected: + virtual ~BaseFsAvbTest() {} + + // Calculates the vbmeta digest using 'avbtool calc_vbmeta_digest' command. + // Note that the calculation includes chained vbmeta images. + std::string CalcVBMetaDigest(const std::string& file_name, const std::string& hash_algorithm); + + // Generates a vbmeta image with |file_name| by avbtool. + // The generated vbmeta image will be written to disk, see the + // |vbmeta_images_| variable for its path and the content. + void GenerateVBMetaImage(const std::string& file_name, const std::string& avb_algorithm, + uint64_t rollback_index, const base::FilePath& key_path, + const std::vector& include_descriptor_image_paths, + const std::vector& chain_partitions, + const std::string& additional_options = ""); + // Similar to above, but extracts a vbmeta image from the given image_path. + // The extracted vbmeta image will be written to disk, with |output_file_name|. + // See the |vbmeta_images_| variable for its path and the content. + void ExtractVBMetaImage(const base::FilePath& image_path, const std::string& output_file_name, + const size_t padding_size = 0); + + // Generate a file with name |file_name| of size |image_size| with + // known content (0x00 0x01 0x02 .. 0xff 0x00 0x01 ..). + base::FilePath GenerateImage(const std::string file_name, size_t image_size, + uint8_t start_byte = 0); + // Invokes 'avbtool add_hash_footer' or 'avbtool add_hashtree_footer' to sign + // the |image_path|. The |footer_type| can be either "hash" or "hashtree". + void AddAvbFooter(const base::FilePath& image_path, const std::string& footer_type, + const std::string& partition_name, const uint64_t partition_size, + const std::string& avb_algorithm, uint64_t rollback_index, + const base::FilePath& key_path, const std::string& salt = "d00df00d", + const std::string& additional_options = ""); + + // Returns the output of 'avbtool info_image' for the |image_path|. + std::string InfoImage(const base::FilePath& image_path); + // Same as above, but for an internal vbmeta image with |file_name| in |vbmeta_images_|. + std::string InfoImage(const std::string& file_name); + + // Extracts public key blob in AVB format for a .pem key, then returns the + // file path: a .bin file. + base::FilePath ExtractPublicKeyAvb(const base::FilePath& key_path); + // Same as above, but returns the key blob binary instead. + std::string ExtractPublicKeyAvbBlob(const base::FilePath& key_path); + + void SetUp() override; + void TearDown() override; + + // Temporary directory created in SetUp(). + base::FilePath test_dir_; + // Maps vbmeta image name (e.g., vbmeta_a.img, system_a.img) to VBMetaImage. + std::map vbmeta_images_; +}; + +} // namespace fs_avb_host_test