/** Copyright 2020 The Fuchsia Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifdef ZIRCON_BOOT_CUSTOM_SYSDEPS_HEADER
#include <zircon_boot_sysdeps.h>
#else
#include <assert.h>
#include <string.h>
#endif

#include <lib/zbi/zbi.h>
#include <lib/zircon_boot/zircon_boot.h>

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

#include "utils.h"
#include "zircon_vboot.h"

#define AVB_ATX_NUM_KEY_VERSIONS 2
#define ROLLBACK_INDEX_NOT_USED 0

typedef struct VBootContext {
  struct {
    size_t location;
    uint64_t value;
  } key_versions[AVB_ATX_NUM_KEY_VERSIONS];
  size_t next_key_version_index;
  zbi_header_t* preloaded_image;
  ZirconBootOps* ops;
} VBootContext;

static AvbIOResult GetPreloadedPartition(AvbOps* ops, const char* partition, size_t num_bytes,
                                         uint8_t** out_pointer, size_t* out_num_bytes_preloaded) {
  VBootContext* context = (VBootContext*)ops->user_data;

  *out_pointer = NULL;
  *out_num_bytes_preloaded = 0;

  if (!strncmp(partition, GPT_ZIRCON_SLOTLESS_NAME, strlen(GPT_ZIRCON_SLOTLESS_NAME))) {
    *out_pointer = (uint8_t*)context->preloaded_image;
    size_t preloaded_size = context->preloaded_image->length + sizeof(zbi_header_t);
    if (num_bytes <= preloaded_size) {
      *out_num_bytes_preloaded = num_bytes;
    } else {
      *out_num_bytes_preloaded = preloaded_size;
    }
  }
  return AVB_IO_RESULT_OK;
}

// If a negative offset is given, computes the unsigned offset.
static inline int64_t calc_offset(uint64_t size, int64_t offset) {
  if (offset < 0) {
    return size + offset;
  }
  return offset;
}

static AvbIOResult ReadFromPartition(AvbOps* ops, const char* partition, int64_t offset,
                                     size_t num_bytes, void* buffer, size_t* out_num_read) {
  VBootContext* context = (VBootContext*)ops->user_data;
  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  size_t part_size;
  if (!ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_get_partition_size, partition, &part_size)) {
    zircon_boot_dlog("Failed to find partition %s\n", partition);
    return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
  }

  int64_t abs_offset;
  abs_offset = calc_offset(part_size, offset);
  if (((size_t)abs_offset > part_size) || (abs_offset < 0)) {
    return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
  }
  if ((abs_offset + num_bytes) > part_size) {
    num_bytes = part_size - abs_offset;
  }

  bool res = ZIRCON_BOOT_OPS_CALL(zb_ops, read_from_partition, partition, abs_offset, num_bytes,
                                  buffer, out_num_read);
  if (!res || *out_num_read != num_bytes) {
    return AVB_IO_RESULT_ERROR_IO;
  }
  return AVB_IO_RESULT_OK;
}

static AvbIOResult WriteToPartition(AvbOps* ops, const char* partition, int64_t offset,
                                    size_t num_bytes, const void* buffer) {
  // Our usage of libavb should never be writing to a partition - this is only
  // used by the (deprecated) libavb_ab extension.
  zircon_boot_dlog("Errors: libavb write_to_partition() unimplemented\n");
  return AVB_IO_RESULT_ERROR_IO;
}

static void SetKeyVersion(AvbAtxOps* atx_ops, size_t rollback_index_location,
                          uint64_t key_version) {
  VBootContext* context = (VBootContext*)atx_ops->ops->user_data;
  size_t index = context->next_key_version_index++;
  if (index < AVB_ATX_NUM_KEY_VERSIONS) {
    context->key_versions[index].location = rollback_index_location;
    context->key_versions[index].value = key_version;
  } else {
    zircon_boot_dlog("ERROR: set_key_version index out of bounds: %zu\n", index);
    avb_abort();
  }
}

// avb_slot_verify uses this call to check that a partition exists.
// Checks for existence but ignores GUID because it's unused.
static AvbIOResult GetUniqueGuidForPartition(AvbOps* ops, const char* partition, char* guid_buf,
                                             size_t guid_buf_size) {
  VBootContext* context = (VBootContext*)ops->user_data;
  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  memset(guid_buf, 0, guid_buf_size);
  size_t part_size;
  bool res = ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_get_partition_size, partition, &part_size);
  return res ? AVB_IO_RESULT_OK : AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
}

static AvbIOResult GetSizeOfPartition(AvbOps* ops, const char* partition,
                                      uint64_t* out_size_num_bytes) {
  VBootContext* context = (VBootContext*)ops->user_data;
  if (strncmp(partition, GPT_ZIRCON_SLOTLESS_NAME, strlen(GPT_ZIRCON_SLOTLESS_NAME)) == 0) {
    *out_size_num_bytes = context->preloaded_image->length + sizeof(zbi_header_t);
    return AVB_IO_RESULT_OK;
  }

  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  size_t out;
  if (!ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_get_partition_size, partition, &out)) {
    zircon_boot_dlog("Fail to find partition %s\n", partition);
    return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
  }
  *out_size_num_bytes = out;
  return AVB_IO_RESULT_OK;
}

static AvbIOResult ReadIsDeviceUnlocked(AvbOps* ops, bool* out_is_unlocked) {
  VBootContext* context = (VBootContext*)ops->user_data;
  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  bool status;
  if (!ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_read_is_device_locked, &status)) {
    zircon_boot_dlog("Failed to read is device unlock\n");
    return AVB_IO_RESULT_ERROR_IO;
  }
  *out_is_unlocked = !status;
  return AVB_IO_RESULT_OK;
}

static AvbIOResult AvbReadRollbackIndex(AvbOps* ops, size_t rollback_index_location,
                                        uint64_t* out_rollback_index) {
  VBootContext* context = (VBootContext*)ops->user_data;
  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  if (!ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_read_rollback_index, rollback_index_location,
                            out_rollback_index)) {
    zircon_boot_dlog("Failed to read rollback index %zu\n", rollback_index_location);
    return AVB_IO_RESULT_ERROR_IO;
  }
  return AVB_IO_RESULT_OK;
}

static AvbIOResult AvbWriteRollbackIndex(AvbOps* ops, size_t rollback_index_location,
                                         uint64_t rollback_index) {
  VBootContext* context = (VBootContext*)ops->user_data;
  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  if (!ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_write_rollback_index, rollback_index_location,
                            rollback_index)) {
    zircon_boot_dlog("Failed to write rollback index %zu\n", rollback_index_location);
    return AVB_IO_RESULT_ERROR_IO;
  }
  return AVB_IO_RESULT_OK;
}

static AvbIOResult ReadPermanentAttributes(AvbAtxOps* atx_ops,
                                           AvbAtxPermanentAttributes* attributes) {
  VBootContext* context = (VBootContext*)atx_ops->ops->user_data;
  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  if (!ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_read_permanent_attributes, attributes)) {
    zircon_boot_dlog("Failed to read permanent attributes\n");
    return AVB_IO_RESULT_ERROR_IO;
  }
  return AVB_IO_RESULT_OK;
}

static AvbIOResult ReadPermanentAttributesHash(AvbAtxOps* atx_ops,
                                               uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
  VBootContext* context = (VBootContext*)atx_ops->ops->user_data;
  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  if (!ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_read_permanent_attributes_hash, hash)) {
    zircon_boot_dlog("Failed to read permanent attribute hash\n");
    return AVB_IO_RESULT_ERROR_IO;
  }
  return AVB_IO_RESULT_OK;
}

static AvbIOResult GetRandom(AvbAtxOps* atx_ops, size_t num_bytes, uint8_t* output) {
  VBootContext* context = (VBootContext*)atx_ops->ops->user_data;
  ZirconBootOps* zb_ops = (ZirconBootOps*)context->ops;
  if (!ZIRCON_BOOT_OPS_CALL(zb_ops, verified_boot_get_random, num_bytes, output)) {
    zircon_boot_dlog("Failed to get random bytes\n");
    return AVB_IO_RESULT_ERROR_IO;
  }
  return AVB_IO_RESULT_OK;
}

static void CreateAvbAndAvbAtxOps(ZirconBootOps* zb_ops, VBootContext* ctx, AvbOps* avb_ops,
                                  AvbAtxOps* atx_ops) {
  ctx->ops = zb_ops;
  avb_ops->user_data = ctx;
  avb_ops->atx_ops = atx_ops;
  avb_ops->read_from_partition = ReadFromPartition;
  avb_ops->get_preloaded_partition = GetPreloadedPartition;
  avb_ops->write_to_partition = WriteToPartition;
  avb_ops->validate_vbmeta_public_key = avb_atx_validate_vbmeta_public_key;
  avb_ops->read_rollback_index = AvbReadRollbackIndex;
  avb_ops->write_rollback_index = AvbWriteRollbackIndex;
  avb_ops->read_is_device_unlocked = ReadIsDeviceUnlocked;
  avb_ops->get_unique_guid_for_partition = GetUniqueGuidForPartition;
  avb_ops->get_size_of_partition = GetSizeOfPartition;
  // As of now, persistent value are not needed yet for our use.
  avb_ops->read_persistent_value = NULL;
  avb_ops->write_persistent_value = NULL;

  atx_ops->ops = avb_ops;
  atx_ops->read_permanent_attributes = ReadPermanentAttributes;
  atx_ops->read_permanent_attributes_hash = ReadPermanentAttributesHash;
  atx_ops->set_key_version = SetKeyVersion;
  atx_ops->get_random = GetRandom;
}

struct property_lookup_user_data {
  zbi_header_t* zbi;
  size_t capacity;
};

static bool PropertyLookupDescForeach(const AvbDescriptor* header, void* user_data);

static bool UnlockIgnorableError(AvbSlotVerifyResult result) {
  switch (result) {
    case AVB_SLOT_VERIFY_RESULT_OK:
    case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
    case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
    case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
      return true;
    default:
      return false;
  }
}

static bool ZirconVBootSlotVerifyInternal(ZirconBootOps* zb_ops, zbi_header_t* image,
                                          size_t capacity, const char* ab_suffix,
                                          bool has_successfully_booted,
                                          AvbSlotVerifyData** ptr_verify_data) {
  AvbOps avb_ops;
  AvbAtxOps atx_ops;
  VBootContext context = {
      .next_key_version_index = 0,
      .preloaded_image = image,
  };
  CreateAvbAndAvbAtxOps(zb_ops, &context, &avb_ops, &atx_ops);

  bool unlocked;
  if (avb_ops.read_is_device_unlocked(&avb_ops, &unlocked)) {
    zircon_boot_dlog("Failed to read lock state.\n");
    return false;
  }

  const char* const requested_partitions[] = {GPT_ZIRCON_SLOTLESS_NAME, NULL};

  AvbSlotVerifyFlags flag =
      unlocked ? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR : AVB_SLOT_VERIFY_FLAGS_NONE;
  AvbHashtreeErrorMode error_mode =
      unlocked ? AVB_HASHTREE_ERROR_MODE_LOGGING : AVB_HASHTREE_ERROR_MODE_EIO;
  AvbSlotVerifyResult result =
      avb_slot_verify(&avb_ops, requested_partitions, ab_suffix, flag, error_mode, ptr_verify_data);

  AvbSlotVerifyData* verify_data = *ptr_verify_data;
  // Copy zbi items within vbmeta regardless of lock state.
  if (result == AVB_SLOT_VERIFY_RESULT_OK || (unlocked && UnlockIgnorableError(result))) {
    struct property_lookup_user_data lookup_data = {.zbi = image, .capacity = capacity};

    for (size_t i = 0; i < verify_data->num_vbmeta_images; ++i) {
      AvbVBMetaData* vb = &verify_data->vbmeta_images[i];
      // load properties into KV store.
      if (!avb_descriptor_foreach(vb->vbmeta_data, vb->vbmeta_size, PropertyLookupDescForeach,
                                  &lookup_data)) {
        zircon_boot_dlog("Fail to parse VBMETA properties\n");
        return false;
      }
    }
  }

  if (unlocked) {
    zircon_boot_dlog("Device unlocked: not checking verification result.\n");
    return true;
  }

  if (result != AVB_SLOT_VERIFY_RESULT_OK) {
    zircon_boot_dlog("Failed to verify slot: %s, err_code: %s\n", ab_suffix,
                     avb_slot_verify_result_to_string(result));
    return false;
  }

  // Increase rollback index values to match the verified slot only if
  // it has already successfully booted.
  if (has_successfully_booted) {
    for (size_t i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; i++) {
      uint64_t rollback_index_value = verify_data->rollback_indexes[i];

      if (rollback_index_value == ROLLBACK_INDEX_NOT_USED) {
        continue;
      }

      AvbIOResult write_rb_idx_res =
          avb_ops.write_rollback_index(&avb_ops, i, rollback_index_value);
      if (write_rb_idx_res != AVB_IO_RESULT_OK) {
        zircon_boot_dlog("Failed to write rollback index: %zu\n", i);
        return false;
      }
    }

    // Also increase rollback index values for Fuchsia key version locations.
    for (size_t i = 0; i < AVB_ATX_NUM_KEY_VERSIONS; i++) {
      AvbIOResult write_key_rb_idx_res = avb_ops.write_rollback_index(
          &avb_ops, context.key_versions[i].location, context.key_versions[i].value);
      if (write_key_rb_idx_res != AVB_IO_RESULT_OK) {
        zircon_boot_dlog("Failed to write rollback index: %zu\n", context.key_versions[i].location);
        return false;
      }
    }
  }
  zircon_boot_dlog("slot: %s successfully verified.\n", ab_suffix);
  return true;
}

bool ZirconVBootSlotVerify(ZirconBootOps* zb_ops, zbi_header_t* image, size_t capacity,
                           const char* ab_suffix, bool has_successfully_booted) {
  AvbSlotVerifyData* verify_data = NULL;
  bool res = ZirconVBootSlotVerifyInternal(zb_ops, image, capacity, ab_suffix,
                                           has_successfully_booted, &verify_data);
  if (verify_data) {
    avb_slot_verify_data_free(verify_data);
  }
  return res;
}

// If the given property holds a ZBI container, appends its contents to the ZBI
// container in |lookup_data|.
static void ProcessProperty(const AvbPropertyDescriptor prop_desc, uint8_t* start,
                            const struct property_lookup_user_data* lookup_data) {
  const char* key = (const char*)start;
  if (key[prop_desc.key_num_bytes] != 0) {
    zircon_boot_dlog(
        "No terminating NUL byte in the property key."
        "Skipping this property descriptor.\n");
    return;
  }
  // Only look at properties whose keys start with the 'zbi' prefix.
  if (strncmp(key, "zbi", strlen("zbi"))) {
    return;
  }
  zircon_boot_dlog("Found vbmeta ZBI property '%s' (%llu bytes)\n", key,
                   (unsigned long long)prop_desc.value_num_bytes);

  // We don't care about the key. Move value data to the start address to make sure
  // that the zbi item starts from an aligned address.
  uint64_t value_offset, value_size;
  if (!avb_safe_add(&value_offset, prop_desc.key_num_bytes, 1) ||
      !avb_safe_add(&value_size, prop_desc.value_num_bytes, 1)) {
    zircon_boot_dlog(
        "Overflow while computing offset and size for value."
        "Skipping this property descriptor.\n");
    return;
  }
  memmove(start, start + value_offset, value_size);

  const zbi_header_t* vbmeta_zbi = (const zbi_header_t*)start;

  const uint64_t zbi_size = sizeof(zbi_header_t) + vbmeta_zbi->length;
  if (zbi_size > prop_desc.value_num_bytes) {
    zircon_boot_dlog("vbmeta ZBI length exceeds property size (%llu > %llu)\n",
                     (unsigned long long)zbi_size, (unsigned long long)prop_desc.value_num_bytes);
    return;
  }

  zbi_result_t result = zbi_check(vbmeta_zbi, NULL);
  if (result != ZBI_RESULT_OK) {
    zircon_boot_dlog("Mal-formed vbmeta ZBI: error %d\n", result);
    return;
  }

  result = zbi_extend(lookup_data->zbi, lookup_data->capacity, vbmeta_zbi);
  if (result != ZBI_RESULT_OK) {
    zircon_boot_dlog("Failed to add vbmeta ZBI: error %d\n", result);
    return;
  }
}

// Callback for vbmeta property iteration. |user_data| must be a pointer to a
// property_lookup_user_data struct.
static bool PropertyLookupDescForeach(const AvbDescriptor* header, void* user_data) {
  AvbPropertyDescriptor prop_desc;
  if (header->tag == AVB_DESCRIPTOR_TAG_PROPERTY &&
      avb_property_descriptor_validate_and_byteswap((const AvbPropertyDescriptor*)header,
                                                    &prop_desc)) {
    ProcessProperty(prop_desc, (uint8_t*)header + sizeof(AvbPropertyDescriptor),
                    (struct property_lookup_user_data*)user_data);
  }
  return true;
}

bool ZirconVbootGenerateUnlockChallenge(ZirconBootOps* zb_ops,
                                        AvbAtxUnlockChallenge* out_unlock_challenge) {
  AvbOps avb_ops;
  AvbAtxOps atx_ops;
  VBootContext ctx;
  CreateAvbAndAvbAtxOps(zb_ops, &ctx, &avb_ops, &atx_ops);
  AvbIOResult ret = avb_atx_generate_unlock_challenge(&atx_ops, out_unlock_challenge);
  return ret == AVB_IO_RESULT_OK;
}

bool ZirconVbootValidateUnlockCredential(ZirconBootOps* zb_ops,
                                         const AvbAtxUnlockCredential* unlock_credential) {
  AvbOps avb_ops;
  AvbAtxOps atx_ops;
  VBootContext ctx;
  CreateAvbAndAvbAtxOps(zb_ops, &ctx, &avb_ops, &atx_ops);
  bool trusted = false;
  AvbIOResult ret = avb_atx_validate_unlock_credential(&atx_ops, unlock_credential, &trusted);
  return ret == AVB_IO_RESULT_OK && trusted;
}
