Loading fs_mgr/libfs_avb/avb_ops.cpp +19 −3 Original line number Diff line number Diff line Loading @@ -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 Loading fs_mgr/libfs_avb/avb_ops.h +3 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ #pragma once #include <string> #include <vector> #include <fs_avb/fs_avb.h> #include <libavb/libavb.h> namespace android { Loading Loading @@ -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_; Loading fs_mgr/libfs_avb/fs_avb.cpp +18 −21 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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_) { Loading Loading @@ -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) { Loading Loading @@ -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. Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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; } Loading fs_mgr/libfs_avb/include/fs_avb/fs_avb.h +33 −9 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <memory> #include <string> #include <vector> #include <fstab/fstab.h> #include <libavb/libavb.h> Loading @@ -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; Loading @@ -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}. Loading Loading @@ -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, Loading @@ -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 Loading
fs_mgr/libfs_avb/avb_ops.cpp +19 −3 Original line number Diff line number Diff line Loading @@ -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 Loading
fs_mgr/libfs_avb/avb_ops.h +3 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ #pragma once #include <string> #include <vector> #include <fs_avb/fs_avb.h> #include <libavb/libavb.h> namespace android { Loading Loading @@ -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_; Loading
fs_mgr/libfs_avb/fs_avb.cpp +18 −21 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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_) { Loading Loading @@ -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) { Loading Loading @@ -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. Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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; } Loading
fs_mgr/libfs_avb/include/fs_avb/fs_avb.h +33 −9 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <memory> #include <string> #include <vector> #include <fstab/fstab.h> #include <libavb/libavb.h> Loading @@ -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; Loading @@ -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}. Loading Loading @@ -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, Loading @@ -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