From a90bfdd8742f765d208c3f16e3ac8c97b8974fd1 Mon Sep 17 00:00:00 2001 From: Steve Muckle Date: Sun, 17 May 2020 16:44:18 -0700 Subject: [PATCH] add API to get hash descriptor The GKI verification VTS test will need to examine the boot partition's hash descriptor, so add support to access this descriptor. Bug: 148800209 Test: atest AvbTest#Boot Change-Id: I92e32f61a265671ae0940c44147391f73776e66a --- fs_mgr/libfs_avb/avb_util.cpp | 58 +++++++++++++++++++ fs_mgr/libfs_avb/avb_util.h | 3 + fs_mgr/libfs_avb/fs_avb_util.cpp | 10 ++++ fs_mgr/libfs_avb/include/fs_avb/fs_avb_util.h | 11 ++++ fs_mgr/libfs_avb/include/fs_avb/types.h | 6 ++ 5 files changed, 88 insertions(+) diff --git a/fs_mgr/libfs_avb/avb_util.cpp b/fs_mgr/libfs_avb/avb_util.cpp index 4505382cc..228867411 100644 --- a/fs_mgr/libfs_avb/avb_util.cpp +++ b/fs_mgr/libfs_avb/avb_util.cpp @@ -124,6 +124,64 @@ bool HashtreeDmVeritySetup(FstabEntry* fstab_entry, const FsAvbHashtreeDescripto return true; } +std::unique_ptr GetHashDescriptor( + const std::string& partition_name, const std::vector& vbmeta_images) { + bool found = false; + const uint8_t* desc_partition_name; + auto hash_desc = std::make_unique(); + + for (const auto& vbmeta : vbmeta_images) { + size_t num_descriptors; + std::unique_ptr descriptors( + avb_descriptor_get_all(vbmeta.data(), vbmeta.size(), &num_descriptors), avb_free); + + if (!descriptors || num_descriptors < 1) { + continue; + } + + for (size_t n = 0; n < num_descriptors && !found; n++) { + AvbDescriptor desc; + if (!avb_descriptor_validate_and_byteswap(descriptors[n], &desc)) { + LWARNING << "Descriptor[" << n << "] is invalid"; + continue; + } + if (desc.tag == AVB_DESCRIPTOR_TAG_HASH) { + desc_partition_name = (const uint8_t*)descriptors[n] + sizeof(AvbHashDescriptor); + if (!avb_hash_descriptor_validate_and_byteswap((AvbHashDescriptor*)descriptors[n], + hash_desc.get())) { + continue; + } + if (hash_desc->partition_name_len != partition_name.length()) { + continue; + } + // Notes that desc_partition_name is not NUL-terminated. + std::string hash_partition_name((const char*)desc_partition_name, + hash_desc->partition_name_len); + if (hash_partition_name == partition_name) { + found = true; + } + } + } + + if (found) break; + } + + if (!found) { + LERROR << "Hash descriptor not found: " << partition_name; + return nullptr; + } + + hash_desc->partition_name = partition_name; + + const uint8_t* desc_salt = desc_partition_name + hash_desc->partition_name_len; + hash_desc->salt = BytesToHex(desc_salt, hash_desc->salt_len); + + const uint8_t* desc_digest = desc_salt + hash_desc->salt_len; + hash_desc->digest = BytesToHex(desc_digest, hash_desc->digest_len); + + return hash_desc; +} + std::unique_ptr GetHashtreeDescriptor( const std::string& partition_name, const std::vector& vbmeta_images) { bool found = false; diff --git a/fs_mgr/libfs_avb/avb_util.h b/fs_mgr/libfs_avb/avb_util.h index 09c786a52..e8f7c39bf 100644 --- a/fs_mgr/libfs_avb/avb_util.h +++ b/fs_mgr/libfs_avb/avb_util.h @@ -40,6 +40,9 @@ struct ChainInfo { std::string GetAvbPropertyDescriptor(const std::string& key, const std::vector& vbmeta_images); +std::unique_ptr GetHashDescriptor( + const std::string& partition_name, const std::vector& vbmeta_images); + // AvbHashtreeDescriptor to dm-verity table setup. std::unique_ptr GetHashtreeDescriptor( const std::string& partition_name, const std::vector& vbmeta_images); diff --git a/fs_mgr/libfs_avb/fs_avb_util.cpp b/fs_mgr/libfs_avb/fs_avb_util.cpp index f82f83dea..1c14cc0d8 100644 --- a/fs_mgr/libfs_avb/fs_avb_util.cpp +++ b/fs_mgr/libfs_avb/fs_avb_util.cpp @@ -74,5 +74,15 @@ std::unique_ptr GetHashtreeDescriptor( return GetHashtreeDescriptor(avb_partition_name, vbmeta_images); } +// Given a path, loads and verifies the vbmeta, to extract the Avb Hash descriptor. +std::unique_ptr GetHashDescriptor(const std::string& avb_partition_name, + VBMetaData&& vbmeta) { + if (!vbmeta.size()) return nullptr; + + std::vector vbmeta_images; + vbmeta_images.emplace_back(std::move(vbmeta)); + return GetHashDescriptor(avb_partition_name, vbmeta_images); +} + } // namespace fs_mgr } // namespace android diff --git a/fs_mgr/libfs_avb/include/fs_avb/fs_avb_util.h b/fs_mgr/libfs_avb/include/fs_avb/fs_avb_util.h index ec8badbcb..3f37bd7db 100644 --- a/fs_mgr/libfs_avb/include/fs_avb/fs_avb_util.h +++ b/fs_mgr/libfs_avb/include/fs_avb/fs_avb_util.h @@ -32,9 +32,20 @@ std::unique_ptr LoadAndVerifyVbmeta(const FstabEntry& fstab_entry, std::string* out_avb_partition_name, VBMetaVerifyResult* out_verify_result); +// Loads the single vbmeta from a given path. +std::unique_ptr LoadAndVerifyVbmetaByPath( + const std::string& image_path, const std::string& partition_name, + const std::string& expected_public_key_blob, bool allow_verification_error, + bool rollback_protection, bool is_chained_vbmeta, std::string* out_public_key_data, + bool* out_verification_disabled, VBMetaVerifyResult* out_verify_result); + // Gets the hashtree descriptor for avb_partition_name from the vbmeta. std::unique_ptr GetHashtreeDescriptor( const std::string& avb_partition_name, VBMetaData&& vbmeta); +// Gets the hash descriptor for avb_partition_name from the vbmeta. +std::unique_ptr GetHashDescriptor(const std::string& avb_partition_name, + VBMetaData&& vbmeta); + } // namespace fs_mgr } // namespace android diff --git a/fs_mgr/libfs_avb/include/fs_avb/types.h b/fs_mgr/libfs_avb/include/fs_avb/types.h index bd638e663..f2aa7ccb2 100644 --- a/fs_mgr/libfs_avb/include/fs_avb/types.h +++ b/fs_mgr/libfs_avb/include/fs_avb/types.h @@ -55,6 +55,12 @@ enum class AvbHandleStatus { std::ostream& operator<<(std::ostream& os, AvbHandleStatus status); +struct FsAvbHashDescriptor : AvbHashDescriptor { + std::string partition_name; + std::string salt; + std::string digest; +}; + struct FsAvbHashtreeDescriptor : AvbHashtreeDescriptor { std::string partition_name; std::string salt;