Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aed2ee96 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "fs_mgr_avb: introducing class VBMetaData"

parents 1f946178 b92fc1f4
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -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
+3 −1
Original line number Diff line number Diff line
@@ -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_;
+18 −21
Original line number Diff line number Diff line
@@ -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;
    }
+33 −9
Original line number Diff line number Diff line
@@ -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_;
};