Merge "fs_mgr_avb: introducing class VBMetaData"
This commit is contained in:
commit
aed2ee9664
|
@ -170,16 +170,32 @@ AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t of
|
|||
|
||||
AvbSlotVerifyResult FsManagerAvbOps::AvbSlotVerify(const std::string& ab_suffix,
|
||||
AvbSlotVerifyFlags flags,
|
||||
AvbSlotVerifyData** out_data) {
|
||||
std::vector<VBMetaData>* out_vbmeta_images) {
|
||||
// Invokes avb_slot_verify() to load and verify all vbmeta images.
|
||||
// Sets requested_partitions to nullptr as it's to copy the contents
|
||||
// of HASH partitions into handle>avb_slot_data_, which is not required as
|
||||
// fs_mgr only deals with HASHTREE partitions.
|
||||
const char* requested_partitions[] = {nullptr};
|
||||
|
||||
// Local resource to store vbmeta images from avb_slot_verify();
|
||||
AvbSlotVerifyData* avb_slot_data;
|
||||
|
||||
// The |hashtree_error_mode| field doesn't matter as it only
|
||||
// influences the generated kernel cmdline parameters.
|
||||
return avb_slot_verify(&avb_ops_, requested_partitions, ab_suffix.c_str(), flags,
|
||||
AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, out_data);
|
||||
auto verify_result =
|
||||
avb_slot_verify(&avb_ops_, requested_partitions, ab_suffix.c_str(), flags,
|
||||
AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_slot_data);
|
||||
|
||||
// Copies avb_slot_data->vbmeta_images[].
|
||||
for (size_t i = 0; i < avb_slot_data->num_vbmeta_images; i++) {
|
||||
out_vbmeta_images->emplace_back(VBMetaData(avb_slot_data->vbmeta_images[i].vbmeta_data,
|
||||
avb_slot_data->vbmeta_images[i].vbmeta_size));
|
||||
}
|
||||
|
||||
// Free the local resource.
|
||||
avb_slot_verify_data_free(avb_slot_data);
|
||||
|
||||
return verify_result;
|
||||
}
|
||||
|
||||
} // namespace fs_mgr
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <fs_avb/fs_avb.h>
|
||||
#include <libavb/libavb.h>
|
||||
|
||||
namespace android {
|
||||
|
@ -55,7 +57,7 @@ class FsManagerAvbOps {
|
|||
void* buffer, size_t* out_num_read);
|
||||
|
||||
AvbSlotVerifyResult AvbSlotVerify(const std::string& ab_suffix, AvbSlotVerifyFlags flags,
|
||||
AvbSlotVerifyData** out_data);
|
||||
std::vector<VBMetaData>* out_vbmeta_images);
|
||||
|
||||
private:
|
||||
AvbOps avb_ops_;
|
||||
|
|
|
@ -99,14 +99,13 @@ static std::string bytes_to_hex(const uint8_t* bytes, size_t bytes_len) {
|
|||
}
|
||||
|
||||
template <typename Hasher>
|
||||
static std::pair<size_t, bool> verify_vbmeta_digest(const AvbSlotVerifyData& verify_data,
|
||||
static std::pair<size_t, bool> verify_vbmeta_digest(const std::vector<VBMetaData>& vbmeta_images,
|
||||
const uint8_t* expected_digest) {
|
||||
size_t total_size = 0;
|
||||
Hasher hasher;
|
||||
for (size_t n = 0; n < verify_data.num_vbmeta_images; n++) {
|
||||
hasher.update(verify_data.vbmeta_images[n].vbmeta_data,
|
||||
verify_data.vbmeta_images[n].vbmeta_size);
|
||||
total_size += verify_data.vbmeta_images[n].vbmeta_size;
|
||||
for (size_t n = 0; n < vbmeta_images.size(); n++) {
|
||||
hasher.update(vbmeta_images[n].vbmeta_data(), vbmeta_images[n].vbmeta_size());
|
||||
total_size += vbmeta_images[n].vbmeta_size();
|
||||
}
|
||||
|
||||
bool matched = (memcmp(hasher.finalize(), expected_digest, Hasher::DIGEST_SIZE) == 0);
|
||||
|
@ -123,7 +122,7 @@ class AvbVerifier {
|
|||
public:
|
||||
// The factory method to return a unique_ptr<AvbVerifier>
|
||||
static std::unique_ptr<AvbVerifier> Create();
|
||||
bool VerifyVbmetaImages(const AvbSlotVerifyData& verify_data);
|
||||
bool VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_images);
|
||||
|
||||
protected:
|
||||
AvbVerifier() = default;
|
||||
|
@ -186,8 +185,8 @@ std::unique_ptr<AvbVerifier> AvbVerifier::Create() {
|
|||
return avb_verifier;
|
||||
}
|
||||
|
||||
bool AvbVerifier::VerifyVbmetaImages(const AvbSlotVerifyData& verify_data) {
|
||||
if (verify_data.num_vbmeta_images == 0) {
|
||||
bool AvbVerifier::VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_images) {
|
||||
if (vbmeta_images.empty()) {
|
||||
LERROR << "No vbmeta images";
|
||||
return false;
|
||||
}
|
||||
|
@ -197,10 +196,10 @@ bool AvbVerifier::VerifyVbmetaImages(const AvbSlotVerifyData& verify_data) {
|
|||
|
||||
if (hash_alg_ == kSHA256) {
|
||||
std::tie(total_size, digest_matched) =
|
||||
verify_vbmeta_digest<SHA256Hasher>(verify_data, digest_);
|
||||
verify_vbmeta_digest<SHA256Hasher>(vbmeta_images, digest_);
|
||||
} else if (hash_alg_ == kSHA512) {
|
||||
std::tie(total_size, digest_matched) =
|
||||
verify_vbmeta_digest<SHA512Hasher>(verify_data, digest_);
|
||||
verify_vbmeta_digest<SHA512Hasher>(vbmeta_images, digest_);
|
||||
}
|
||||
|
||||
if (total_size != vbmeta_size_) {
|
||||
|
@ -306,18 +305,18 @@ static bool hashtree_dm_verity_setup(FstabEntry* fstab_entry,
|
|||
}
|
||||
|
||||
static bool get_hashtree_descriptor(const std::string& partition_name,
|
||||
const AvbSlotVerifyData& verify_data,
|
||||
const std::vector<VBMetaData>& vbmeta_images,
|
||||
AvbHashtreeDescriptor* out_hashtree_desc, std::string* out_salt,
|
||||
std::string* out_digest) {
|
||||
bool found = false;
|
||||
const uint8_t* desc_partition_name;
|
||||
|
||||
for (size_t i = 0; i < verify_data.num_vbmeta_images && !found; i++) {
|
||||
for (size_t i = 0; i < vbmeta_images.size() && !found; i++) {
|
||||
// Get descriptors from vbmeta_images[i].
|
||||
size_t num_descriptors;
|
||||
std::unique_ptr<const AvbDescriptor* [], decltype(&avb_free)> descriptors(
|
||||
avb_descriptor_get_all(verify_data.vbmeta_images[i].vbmeta_data,
|
||||
verify_data.vbmeta_images[i].vbmeta_size, &num_descriptors),
|
||||
avb_descriptor_get_all(vbmeta_images[i].vbmeta_data(),
|
||||
vbmeta_images[i].vbmeta_size(), &num_descriptors),
|
||||
avb_free);
|
||||
|
||||
if (!descriptors || num_descriptors < 1) {
|
||||
|
@ -377,7 +376,7 @@ AvbUniquePtr AvbHandle::Open() {
|
|||
AvbSlotVerifyFlags flags = is_device_unlocked ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
|
||||
: AVB_SLOT_VERIFY_FLAGS_NONE;
|
||||
AvbSlotVerifyResult verify_result =
|
||||
avb_ops.AvbSlotVerify(fs_mgr_get_slot_suffix(), flags, &avb_handle->avb_slot_data_);
|
||||
avb_ops.AvbSlotVerify(fs_mgr_get_slot_suffix(), flags, &avb_handle->vbmeta_images_);
|
||||
|
||||
// Only allow two verify results:
|
||||
// - AVB_SLOT_VERIFY_RESULT_OK.
|
||||
|
@ -417,8 +416,7 @@ AvbUniquePtr AvbHandle::Open() {
|
|||
// and AVB HASHTREE descriptor(s).
|
||||
AvbVBMetaImageHeader vbmeta_header;
|
||||
avb_vbmeta_image_header_to_host_byte_order(
|
||||
(AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
|
||||
&vbmeta_header);
|
||||
(AvbVBMetaImageHeader*)avb_handle->vbmeta_images_[0].vbmeta_data(), &vbmeta_header);
|
||||
bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags &
|
||||
AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);
|
||||
|
||||
|
@ -431,7 +429,7 @@ AvbUniquePtr AvbHandle::Open() {
|
|||
LERROR << "Failed to create AvbVerifier";
|
||||
return nullptr;
|
||||
}
|
||||
if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
|
||||
if (!avb_verifier->VerifyVbmetaImages(avb_handle->vbmeta_images_)) {
|
||||
LERROR << "VerifyVbmetaImages failed";
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -449,8 +447,7 @@ AvbUniquePtr AvbHandle::Open() {
|
|||
}
|
||||
|
||||
AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev) {
|
||||
if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ ||
|
||||
avb_slot_data_->num_vbmeta_images < 1) {
|
||||
if (!fstab_entry || status_ == kAvbHandleUninitialized || vbmeta_images_.size() < 1) {
|
||||
return AvbHashtreeResult::kFail;
|
||||
}
|
||||
|
||||
|
@ -478,7 +475,7 @@ AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait
|
|||
AvbHashtreeDescriptor hashtree_descriptor;
|
||||
std::string salt;
|
||||
std::string root_digest;
|
||||
if (!get_hashtree_descriptor(partition_name, *avb_slot_data_, &hashtree_descriptor, &salt,
|
||||
if (!get_hashtree_descriptor(partition_name, vbmeta_images_, &hashtree_descriptor, &salt,
|
||||
&root_digest)) {
|
||||
return AvbHashtreeResult::kFail;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <fstab/fstab.h>
|
||||
#include <libavb/libavb.h>
|
||||
|
@ -31,6 +32,35 @@ enum class AvbHashtreeResult {
|
|||
kDisabled,
|
||||
};
|
||||
|
||||
class VBMetaData {
|
||||
public:
|
||||
// Constructors
|
||||
VBMetaData() : vbmeta_ptr_(nullptr), vbmeta_size_(0){};
|
||||
|
||||
VBMetaData(uint8_t* data, size_t size)
|
||||
: vbmeta_ptr_(new (std::nothrow) uint8_t[size]), vbmeta_size_(size) {
|
||||
// The ownership of data is NOT transferred, i.e., the caller still
|
||||
// needs to release the memory as we make a copy here.
|
||||
memcpy(vbmeta_ptr_.get(), data, size * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
explicit VBMetaData(size_t size)
|
||||
: vbmeta_ptr_(new (std::nothrow) uint8_t[size]), vbmeta_size_(size) {}
|
||||
|
||||
// Get methods for each data member.
|
||||
const std::string& device_path() const { return device_path_; }
|
||||
uint8_t* vbmeta_data() const { return vbmeta_ptr_.get(); }
|
||||
const size_t& vbmeta_size() const { return vbmeta_size_; }
|
||||
|
||||
// Maximum size of a vbmeta data - 64 KiB.
|
||||
static const size_t kMaxVBMetaSize = 64 * 1024;
|
||||
|
||||
private:
|
||||
std::string device_path_;
|
||||
std::unique_ptr<uint8_t[]> vbmeta_ptr_;
|
||||
size_t vbmeta_size_;
|
||||
};
|
||||
|
||||
class FsManagerAvbOps;
|
||||
|
||||
class AvbHandle;
|
||||
|
@ -43,7 +73,7 @@ class AvbHandle {
|
|||
public:
|
||||
// The factory method to return a AvbUniquePtr that holds
|
||||
// the verified AVB (external/avb) metadata of all verified partitions
|
||||
// in avb_slot_data_.vbmeta_images[].
|
||||
// in vbmeta_images_.
|
||||
//
|
||||
// The metadata is checked against the following values from /proc/cmdline.
|
||||
// - androidboot.vbmeta.{hash_alg, size, digest}.
|
||||
|
@ -95,12 +125,6 @@ class AvbHandle {
|
|||
AvbHandle(AvbHandle&&) noexcept = delete; // no move
|
||||
AvbHandle& operator=(AvbHandle&&) noexcept = delete; // no move assignment
|
||||
|
||||
~AvbHandle() {
|
||||
if (avb_slot_data_) {
|
||||
avb_slot_verify_data_free(avb_slot_data_);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
enum AvbHandleStatus {
|
||||
kAvbHandleSuccess = 0,
|
||||
|
@ -110,9 +134,9 @@ class AvbHandle {
|
|||
kAvbHandleVerificationError,
|
||||
};
|
||||
|
||||
AvbHandle() : avb_slot_data_(nullptr), status_(kAvbHandleUninitialized) {}
|
||||
AvbHandle() : status_(kAvbHandleUninitialized) {}
|
||||
|
||||
AvbSlotVerifyData* avb_slot_data_;
|
||||
std::vector<VBMetaData> vbmeta_images_;
|
||||
AvbHandleStatus status_;
|
||||
std::string avb_version_;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue