/*
 * Copyright (c) 2019 The Fuchsia Authors
 */

#include <abr/abr.h>
#include <abr/ops.h>
#include <libavb/libavb.h>
#include <zircon/boot/image.h>
#include <zircon-estelle/partition.h>
#include <zircon-estelle/vboot.h>
#include <zircon-estelle/zircon.h>
#include <common.h>
#include <asm/arch/bl31_apis.h>
#include <asm/arch/secure_apb.h>
#include <linux/ctype.h>
#include <linux/list.h>
#include <zbi/zbi.h>

#include <stdlib.h>

#include <linux/compat.h>

#define errorP(fmt...)                                                         \
	printf("Err zircon load(%s:%d):", __func__, __LINE__), printf(fmt)

#ifdef DEBUG
#define debugP(fmt...)                                                         \
	printf("[Dbg zircon load]%s:%d:", __func__, __LINE__), printf(fmt)
#else
#define debugP(fmt...)
#endif

#define CONFIG_AML_SECURE_BOOT_VERSION 4
#define AML_SECURE_HEADER_SIZE 512

#define AVB_DATA_FREE(x)                                                       \
	do {                                                                   \
		if (x != NULL) {                                               \
			avb_slot_verify_data_free(x);                          \
			x = NULL;                                              \
		}                                                              \
	} while (0);

static AvbSlotVerifyData *g_slot_verify_data = NULL;

/* libabr callback implementations to read/write metadata from disk. */

#ifdef CONFIG_ABR_WEAR_LEVELING
#define ABR_PARTITION_NAME "abr-wear-leveling"
#else
#define ABR_PARTITION_NAME "misc"
#endif

static uint8_t abr_read_write_buffer[PAGE_SIZE];

static bool read_abr_metadata(void *context, size_t size, uint8_t *buffer)
{
	assert(buffer != NULL);

	if (size > sizeof(abr_read_write_buffer)) {
		errorP("Unexpected read size for abr metadata, %zu\n", size);
		return false;
	}

	debugP("Read A/B/R metadata from " ABR_PARTITION_NAME " partition\n");
	if (zircon_partition_read(ABR_PARTITION_NAME, 0, abr_read_write_buffer,
				  sizeof(abr_read_write_buffer)) != 0) {
		errorP("failed to read A/B/R metadata.\n");
		return false;
	}
	memcpy(buffer, abr_read_write_buffer, size);
	return true;
}

static bool write_abr_metadata(void *context, const uint8_t *buffer,
			       size_t size)
{
	assert(buffer != NULL);

	if (size > sizeof(abr_read_write_buffer)) {
		errorP("Unexpected write size for abr metadata, %zu\n", size);
		return false;
	}
	memcpy(abr_read_write_buffer, buffer, size);

	debugP("Write A/B/R metadata to " ABR_PARTITION_NAME " partition\n");
	if (zircon_partition_write(ABR_PARTITION_NAME, 0, abr_read_write_buffer,
				   sizeof(abr_read_write_buffer)) != 0) {
		errorP("failed to read A/B/R metadata.\n");
		return false;
	}

	return true;
}

static const AbrOps kAbrOps = { .context = NULL,
				.read_abr_metadata = read_abr_metadata,
				.write_abr_metadata = write_abr_metadata };

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

#define ZBI_PROPERTY_PREFIX "zbi"

/* If the given property holds a ZBI container, appends its contents to the ZBI
 * container in |lookup_data|. */
static void
process_property(const AvbPropertyDescriptor *prop_desc,
		 const struct property_lookup_user_data *lookup_data)
{
	const char *key =
		(const char *)prop_desc + sizeof(AvbPropertyDescriptor);
	uint64_t offset;
	if (!avb_safe_add(&offset, sizeof(AvbPropertyDescriptor) + 1,
			  prop_desc->key_num_bytes)) {
		fprintf(stderr,
			"Overflow while computing offset for property value."
			"Skipping this property descriptor.\n");
		return;
	}

	const uint8_t *value = (const uint8_t *)prop_desc + offset;
	if (key[prop_desc->key_num_bytes] != 0) {
		fprintf(stderr, "No terminating NUL byte in the property key."
				"Skipping this property descriptor.\n");
		return;
	}

	if (value[prop_desc->value_num_bytes] != 0) {
		fprintf(stderr, "No terminating NUL byte in the property value."
				"Skipping this property descriptor.\n");
		return;
	}

	/* Only look at properties whose keys start with the 'zbi' prefix. */
	if (strncmp(key, ZBI_PROPERTY_PREFIX, strlen(ZBI_PROPERTY_PREFIX))) {
		return;
	}

	const zbi_header_t *vbmeta_zbi = (zbi_header_t *)value;
	printf("Found vbmeta ZBI property '%s' (%llu bytes)\n", key,
	       prop_desc->value_num_bytes);

	const uint64_t zbi_size = sizeof(*vbmeta_zbi) + vbmeta_zbi->length;
	if (zbi_size > prop_desc->value_num_bytes) {
		fprintf(stderr,
			"vbmeta ZBI length exceeds property size (%llu > %llu)\n",
			zbi_size, prop_desc->value_num_bytes);
		return;
	}

	zbi_result_t result = zbi_check(vbmeta_zbi, NULL);
	if (result != ZBI_RESULT_OK) {
		fprintf(stderr, "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) {
		fprintf(stderr, "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 property_lookup_desc_foreach(const AvbDescriptor *header,
					 void *user_data)
{
	if (header->tag != AVB_DESCRIPTOR_TAG_PROPERTY) {
		return true;
	}
	AvbPropertyDescriptor *prop_desc = (AvbPropertyDescriptor *)header;

	/* recover original bytes order at the end of the function */
	if (!avb_property_descriptor_validate_and_byteswap(prop_desc,
							   prop_desc)) {
		return true;
	}

	process_property(prop_desc,
			 (struct property_lookup_user_data *)user_data);

	/* return error if byte order recovering failed */
	if (!avb_property_descriptor_validate_and_byteswap(prop_desc,
							   prop_desc)) {
		errorP("failed to recover byte order in a property descriptor.\n");
		return false;
	}
	return true;
}

#define CMDLINE_ZVB_SLOT_INFO_SIZE 32
int zircon_vboot_add_extra_zbi_items(zbi_header_t *zbi, size_t capacity)
{
	int i;

	if (zbi == NULL) {
		errorP("Invalid argument: zbi is NULL\n");
		return __LINE__;
	}

	if (g_slot_verify_data == NULL) {
		debugP("No properties to load\n");
		return 0;
	}

	if ((g_slot_verify_data->ab_suffix != NULL) &&
	    strlen(g_slot_verify_data->ab_suffix)) {
		char slot_info[CMDLINE_ZVB_SLOT_INFO_SIZE];

		snprintf(slot_info, sizeof(slot_info), "zvb.current_slot=%s",
			 g_slot_verify_data->ab_suffix);
		if (append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_CMDLINE, 0,
					   slot_info, strlen(slot_info) + 1)) {
			return -1;
		}
	}

	struct property_lookup_user_data lookup_data = { .zbi = zbi,
							 .capacity = capacity };

	for (i = 0; i < g_slot_verify_data->num_vbmeta_images; ++i) {
		AvbVBMetaData *vb = &g_slot_verify_data->vbmeta_images[i];
		/* load properties into KV store */
		if (!avb_descriptor_foreach(vb->vbmeta_data, vb->vbmeta_size,
					    property_lookup_desc_foreach,
					    &lookup_data)) {
			AVB_DATA_FREE(g_slot_verify_data);
			errorP("Fail to parse VBMETA properties\n");
			return __LINE__;
		}
	}

	return 0;
}

int zircon_vboot_img_load(unsigned char *loadaddr, size_t loadsize,
			  bool force_recovery)
{
	uint64_t img_size = 0;
	int ret = 0;
	unsigned int slot_idx;
	AvbSlotVerifyData *out_data = NULL;

	const char *const requested_partitions[2] = { "zircon", NULL };

	/* clear previous data */
	AVB_DATA_FREE(g_slot_verify_data);

	do {
		AvbSlotVerifyResult verify_result;
		bool set_slot_unbootable = false;
		bool is_successful = false;

		AVB_DATA_FREE(out_data);

		/* check recovery mode */
		if (force_recovery) {
			slot_idx = kAbrSlotIndexR;
		} else {
			slot_idx =
				AbrGetBootSlot(&kAbrOps, true, &is_successful);
			assert(slot_idx < 3);
		}

		verify_result = zircon_vboot_slot_verify(
			loadaddr, loadsize, requested_partitions,
			AbrGetSlotSuffix(slot_idx),
			zircon_is_vboot_enabled() ? AVB_ATX_LOCKED :
							  AVB_ATX_UNLOCKED,
			(is_successful == true) ?
				      AVB_ATX_SLOT_MARKED_SUCCESSFUL :
				      AVB_ATX_SLOT_NOT_MARKED_SUCCESSFUL,
			&out_data);
		debugP("AVB verify status is '%s'\n",
		       avb_slot_verify_result_to_string(verify_result));
		switch (verify_result) {
		case AVB_SLOT_VERIFY_RESULT_OK:
			ret = 0;
			break;

		/* non-recoverable error. abort execution. */
		case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
		case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
			errorP("Error verifying slot %d with result %s"
			       " - abort execution.\n",
			       slot_idx,
			       avb_slot_verify_result_to_string(verify_result));
			AVB_DATA_FREE(out_data);
			return __LINE__;

		case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
		case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
		case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
			/* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
			 * these mean game over.
			 */
			set_slot_unbootable = true;
			ret = __LINE__;
			break;

		/* security verification failed */
		case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
		case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
		case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
			if (!zircon_is_vboot_enabled()) {
				/* Do nothing since we allow this. */
				debugP("Allowing slot %d which verified with result "
				       "%s because vboot disabled\n",
				       slot_idx,
				       avb_slot_verify_result_to_string(
					       verify_result));
				ret = 0;
			} else {
				set_slot_unbootable = true;
				ret = __LINE__;
			}
			break;
			/* Do not add a 'default:' case here because of -Wswitch. */
		}
		if (set_slot_unbootable) {
			errorP("Error verifying slot %d  with result %s "
			       "-- setting unbootable\n",
			       slot_idx,
			       avb_slot_verify_result_to_string(verify_result));
			AbrResult res =
				AbrMarkSlotUnbootable(&kAbrOps, slot_idx);
			if (res != kAbrResultOk) {
				errorP("Fail to set A/B/R metadata.\n");
				AVB_DATA_FREE(out_data);
				return __LINE__;
			}
		}
	} while ((ret != 0) && (slot_idx != kAbrSlotIndexR));

	if (ret != 0) {
		errorP("Fail to boot: no valid slots\n");
		AVB_DATA_FREE(out_data);
		return __LINE__;
	}

	/* save it for late use */
	assert(g_slot_verify_data == NULL);
	g_slot_verify_data = out_data;

	/*
	 * because secure boot will use DMA which need disable MMU temp
	 * here must update the cache, otherwise nand will fail (eMMC is OK)
	 */
	flush_cache((unsigned long)loadaddr, (unsigned long)img_size);

	return 0;
}

int zircon_vboot_preloaded_img_load(unsigned char *loadaddr, size_t loadsize,
				    unsigned char *zbi, size_t zbi_size,
				    unsigned char *vbmeta, size_t vbmeta_size)
{
	AVB_DATA_FREE(g_slot_verify_data);

	bool verified = zircon_vboot_preloaded_img_verify(
		zbi, zbi_size, vbmeta, vbmeta_size, &g_slot_verify_data);

	if (!verified || zbi_size > loadsize) {
		return -1;
	}

	memcpy(loadaddr, zbi, zbi_size);
	return 0;
}

const char *zircon_vboot_get_current_slot(void)
{
	int slot = AbrGetBootSlot(&kAbrOps, false, NULL);
	return AbrGetSlotSuffix(slot);
}

const char *zircon_vboot_get_slot_last_set_active(void)
{
	AbrSlotIndex slot;
	AbrResult res = AbrGetSlotLastMarkedActive(&kAbrOps, &slot);
	if (res != kAbrResultOk) {
		return NULL;
	}

	const char *ret = AbrGetSlotSuffix(slot);
	//&ret[1] skips the first '_' character. i.e. "_a" is returned as "a".
	return ret ? &ret[1] : NULL;
}

int zircon_vboot_get_slot_info(int slot_number, AbrSlotInfo *info)
{
	AbrResult res = AbrGetSlotInfo(&kAbrOps, slot_number, info);
	if (res != kAbrResultOk) {
		errorP("Fail to get slot info\n");
		return __LINE__;
	}

	return 0;
}

int zircon_vboot_set_slot_active(int slot_number)
{
	AbrResult ret = AbrMarkSlotActive(&kAbrOps, slot_number);
	if (ret != kAbrResultOk) {
		errorP("Fail to get slot info\n");
		return __LINE__;
	}

	return 0;
}
