/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <functional>
#include <memory>
#include <string>
#include <vector>

#include <fstab/fstab.h>
#include <libavb/libavb.h>

namespace android {
namespace fs_mgr {

enum class AvbHashtreeResult {
    kSuccess = 0,
    kFail,
    kDisabled,
};

enum class HashAlgorithm {
    kInvalid = 0,
    kSHA256 = 1,
    kSHA512 = 2,
};

enum class AvbHandleStatus {
    kSuccess = 0,
    kUninitialized = 1,
    kHashtreeDisabled = 2,
    kVerificationDisabled = 3,
    kVerificationError = 4,
};

struct VBMetaInfo {
    std::string digest;
    HashAlgorithm hash_algorithm;
    size_t total_size;

    VBMetaInfo() {}

    VBMetaInfo(std::string digest_value, HashAlgorithm algorithm, size_t size)
        : digest(std::move(digest_value)), hash_algorithm(algorithm), total_size(size) {}
};

class VBMetaData {
  public:
    // Constructors
    VBMetaData() : vbmeta_ptr_(nullptr), vbmeta_size_(0){};

    VBMetaData(const uint8_t* data, size_t size, const std::string& partition_name)
        : vbmeta_ptr_(new (std::nothrow) uint8_t[size]),
          vbmeta_size_(size),
          partition_name_(partition_name) {
        // 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, const std::string& partition_name)
        : vbmeta_ptr_(new (std::nothrow) uint8_t[size]),
          vbmeta_size_(size),
          partition_name_(partition_name) {}

    // Extracts vbmeta header from the vbmeta buffer, set update_vbmeta_size to
    // true to update vbmeta_size_ to the actual size with valid content.
    std::unique_ptr<AvbVBMetaImageHeader> GetVBMetaHeader(bool update_vbmeta_size = false);

    // Sets the vbmeta_path where we load the vbmeta data. Could be a partition or a file.
    // e.g.,
    // - /dev/block/by-name/system_a
    // - /path/to/system_other.img.
    void set_vbmeta_path(std::string vbmeta_path) { vbmeta_path_ = std::move(vbmeta_path); }

    // Get methods for each data member.
    const std::string& partition() const { return partition_name_; }
    const std::string& vbmeta_path() const { return vbmeta_path_; }
    uint8_t* data() const { return vbmeta_ptr_.get(); }
    const size_t& size() const { return vbmeta_size_; }

    // Maximum size of a vbmeta data - 64 KiB.
    static const size_t kMaxVBMetaSize = 64 * 1024;

  private:
    std::unique_ptr<uint8_t[]> vbmeta_ptr_;
    size_t vbmeta_size_;
    std::string partition_name_;
    std::string vbmeta_path_;
};

class FsManagerAvbOps;

class AvbHandle;
using AvbUniquePtr = std::unique_ptr<AvbHandle>;

// Provides a factory method to return a unique_ptr pointing to itself and the
// SetUpAvbHashtree() function to extract dm-verity parameters from AVB HASHTREE
// descriptors to load verity table into kernel through ioctl.
class AvbHandle {
  public:
    // The factory methods to return a AvbUniquePtr that holds
    // the verified AVB (external/avb) metadata of all verified partitions
    // in vbmeta_images_.
    //
    // The metadata is checked against the following values from /proc/cmdline.
    //   - androidboot.vbmeta.{hash_alg, size, digest}.
    //
    // A typical usage will be:
    //   - AvbUniquePtr handle = AvbHandle::Open(); or
    //   - AvbUniquePtr handle = AvbHandle::LoadAndVerifyVbmeta();
    //
    // Possible return values:
    //   - nullptr: any error when reading and verifying the metadata,
    //     e.g., I/O error, digest value mismatch, size mismatch, etc.
    //
    //   - a valid unique_ptr with status AvbHandleStatus::HashtreeDisabled:
    //     to support the existing 'adb disable-verity' feature in Android.
    //     It's very helpful for developers to make the filesystem writable to
    //     allow replacing binaries on the device.
    //
    //   - a valid unique_ptr with status AvbHandleStatus::VerificationDisabled:
    //     to support 'avbctl disable-verification': only the top-level
    //     vbmeta is read, vbmeta structs in other partitions are not processed.
    //     It's needed to bypass AVB when using the generic system.img to run
    //     VTS for project Treble.
    //
    //   - a valid unique_ptr with status AvbHandleStatus::VerificationError:
    //     there is verification error when libavb loads vbmeta from each
    //     partition. This is only allowed when the device is unlocked.
    //
    //   - a valid unique_ptr with status AvbHandleStatus::Success: the metadata
    //     is verified and can be trusted.
    //
    // TODO(bowgotsai): remove Open() and switch to LoadAndVerifyVbmeta().
    static AvbUniquePtr Open();                 // loads inline vbmeta, via libavb.
    static AvbUniquePtr LoadAndVerifyVbmeta();  // loads inline vbmeta.
    static AvbUniquePtr LoadAndVerifyVbmeta(    // loads offline vbmeta.
            const std::string& partition_name, const std::string& ab_suffix,
            const std::string& ab_other_suffix, const std::string& expected_public_key,
            const HashAlgorithm& hash_algorithm, bool allow_verification_error,
            bool load_chained_vbmeta, bool rollback_protection,
            std::function<std::string(const std::string&)> custom_device_path = nullptr);

    // Sets up dm-verity on the given fstab entry.
    // The 'wait_for_verity_dev' parameter makes this function wait for the
    // verity device to get created before return.
    //
    // Return value:
    //   - kSuccess: successfully loads dm-verity table into kernel.
    //   - kFailed: failed to setup dm-verity, e.g., vbmeta verification error,
    //     failed to get the HASHTREE descriptor, runtime error when set up
    //     device-mapper, etc.
    //   - kDisabled: hashtree is disabled.
    AvbHashtreeResult SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev);

    // Similar to above, but loads the offline vbmeta from the end of fstab_entry->blk_device.
    static AvbHashtreeResult SetUpStandaloneAvbHashtree(FstabEntry* fstab_entry,
                                                        bool wait_for_verity_dev = true);

    const std::string& avb_version() const { return avb_version_; }
    const VBMetaInfo& vbmeta_info() const { return vbmeta_info_; }
    AvbHandleStatus status() const { return status_; }

    AvbHandle(const AvbHandle&) = delete;             // no copy
    AvbHandle& operator=(const AvbHandle&) = delete;  // no assignment

    AvbHandle(AvbHandle&&) noexcept = delete;             // no move
    AvbHandle& operator=(AvbHandle&&) noexcept = delete;  // no move assignment

  private:
    AvbHandle() : status_(AvbHandleStatus::kUninitialized) {}

    std::vector<VBMetaData> vbmeta_images_;
    VBMetaInfo vbmeta_info_;  // A summary info for vbmeta_images_.
    AvbHandleStatus status_;
    std::string avb_version_;
};

}  // namespace fs_mgr
}  // namespace android
