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

Commit c126ad82 authored by Yi-yo Chiang's avatar Yi-yo Chiang Committed by Gerrit Code Review
Browse files

Merge "libfs_avb: Export more utilities to facilitate VTS"

parents f452a42d d543bebb
Loading
Loading
Loading
Loading
+0 −71
Original line number Diff line number Diff line
@@ -35,19 +35,6 @@ using android::base::unique_fd;
namespace android {
namespace fs_mgr {

std::string GetAvbPropertyDescriptor(const std::string& key,
                                     const std::vector<VBMetaData>& vbmeta_images) {
    size_t value_size;
    for (const auto& vbmeta : vbmeta_images) {
        const char* value = avb_property_lookup(vbmeta.data(), vbmeta.size(), key.data(),
                                                key.size(), &value_size);
        if (value != nullptr) {
            return {value, value_size};
        }
    }
    return "";
}

// Constructs dm-verity arguments for sending DM_TABLE_LOAD ioctl to kernel.
// See the following link for more details:
// https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity
@@ -130,64 +117,6 @@ 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;
+0 −6
Original line number Diff line number Diff line
@@ -37,12 +37,6 @@ struct ChainInfo {
        : partition_name(chain_partition_name), public_key_blob(chain_public_key_blob) {}
};

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);
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@

#include "avb_ops.h"
#include "avb_util.h"
#include "fs_avb/fs_avb_util.h"
#include "sha.h"
#include "util.h"

+71 −0
Original line number Diff line number Diff line
@@ -74,6 +74,64 @@ std::unique_ptr<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
    return GetHashtreeDescriptor(avb_partition_name, vbmeta_images);
}

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

// 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) {
@@ -84,5 +142,18 @@ std::unique_ptr<FsAvbHashDescriptor> GetHashDescriptor(const std::string& avb_pa
    return GetHashDescriptor(avb_partition_name, vbmeta_images);
}

std::string GetAvbPropertyDescriptor(const std::string& key,
                                     const std::vector<VBMetaData>& vbmeta_images) {
    size_t value_size;
    for (const auto& vbmeta : vbmeta_images) {
        const char* value = avb_property_lookup(vbmeta.data(), vbmeta.size(), key.data(),
                                                key.size(), &value_size);
        if (value != nullptr) {
            return {value, value_size};
        }
    }
    return "";
}

}  // namespace fs_mgr
}  // namespace android
+6 −0
Original line number Diff line number Diff line
@@ -43,9 +43,15 @@ std::unique_ptr<VBMetaData> LoadAndVerifyVbmetaByPath(
std::unique_ptr<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
        const std::string& avb_partition_name, VBMetaData&& vbmeta);

std::unique_ptr<FsAvbHashDescriptor> GetHashDescriptor(
        const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images);

// Gets the hash descriptor for avb_partition_name from the vbmeta.
std::unique_ptr<FsAvbHashDescriptor> GetHashDescriptor(const std::string& avb_partition_name,
                                                       VBMetaData&& vbmeta);

std::string GetAvbPropertyDescriptor(const std::string& key,
                                     const std::vector<VBMetaData>& vbmeta_images);

}  // namespace fs_mgr
}  // namespace android
Loading