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
This commit is contained in:
Steve Muckle 2020-05-17 16:44:18 -07:00
parent f464e6e0ac
commit a90bfdd874
5 changed files with 88 additions and 0 deletions

View File

@ -124,6 +124,64 @@ bool HashtreeDmVeritySetup(FstabEntry* fstab_entry, const FsAvbHashtreeDescripto
return true;
}
std::unique_ptr<FsAvbHashDescriptor> GetHashDescriptor(
const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images) {
bool found = false;
const uint8_t* desc_partition_name;
auto hash_desc = std::make_unique<FsAvbHashDescriptor>();
for (const auto& vbmeta : vbmeta_images) {
size_t num_descriptors;
std::unique_ptr<const AvbDescriptor*[], decltype(&avb_free)> 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<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images) {
bool found = false;

View File

@ -40,6 +40,9 @@ struct ChainInfo {
std::string GetAvbPropertyDescriptor(const std::string& key,
const std::vector<VBMetaData>& vbmeta_images);
std::unique_ptr<FsAvbHashDescriptor> GetHashDescriptor(
const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images);
// AvbHashtreeDescriptor to dm-verity table setup.
std::unique_ptr<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images);

View File

@ -74,5 +74,15 @@ std::unique_ptr<FsAvbHashtreeDescriptor> 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<FsAvbHashDescriptor> GetHashDescriptor(const std::string& avb_partition_name,
VBMetaData&& vbmeta) {
if (!vbmeta.size()) return nullptr;
std::vector<VBMetaData> vbmeta_images;
vbmeta_images.emplace_back(std::move(vbmeta));
return GetHashDescriptor(avb_partition_name, vbmeta_images);
}
} // namespace fs_mgr
} // namespace android

View File

@ -32,9 +32,20 @@ std::unique_ptr<VBMetaData> 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<VBMetaData> 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<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
const std::string& avb_partition_name, VBMetaData&& vbmeta);
// Gets the hash descriptor for avb_partition_name from the vbmeta.
std::unique_ptr<FsAvbHashDescriptor> GetHashDescriptor(const std::string& avb_partition_name,
VBMetaData&& vbmeta);
} // namespace fs_mgr
} // namespace android

View File

@ -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;