/*
 * Copyright (c) 2019 The Fuchsia Authors
 *
 * SPDX-License-Identifier:	BSD-3-Clause
 */

#include <asm/arch/bl31_apis.h>
#include <asm/arch/efuse.h>
#include <common.h>
#include <libavb/libavb.h>
#include <libavb_atx/libavb_atx.h>
#include <u-boot/sha256.h>

#ifdef CONFIG_DEV_BUILD
#include "avb_dev_attrs/atx_permanent_attrs.h"
#elif defined(CONFIG_DOGFOOD_BUILD)
#include "avb_dogfood_attrs/atx_permanent_attrs.h"
#elif defined(CONFIG_PROD_BUILD)
#include "avb_prod_attrs/atx_permanent_attrs.h"
#else
#error "Unknown build config"
#endif

#define ROLLBACK_INDEX_BYTES 8
#define MAX_ROLLBACK_INDEX 8 * ROLLBACK_INDEX_BYTES

#define AVB_ATX_PIK_VERSION_LOCATION_MAX 63
#define AVB_ATX_PIK_VERSION_LOCATION_MASK                                      \
	((1ULL << AVB_ATX_PIK_VERSION_LOCATION_MAX) - 1)

/* Make sure we agree with BL31 on the sizes of the perm attrs and hashes. */
_Static_assert(sizeof(AvbAtxPermanentAttributes) == PERMANENT_ATTRIBUTES_SIZE,
	       "Permanent attribute size mismatch");
_Static_assert(sizeof(avb_atx_permanent_attributes_hash) ==
		       PERMANENT_ATTRIBUTES_HASH_SIZE,
	       "Permanent attribute hash size mismatch");
_Static_assert(sizeof(avb_atx_permanent_attributes_hash) ==
		       AVB_SHA256_DIGEST_SIZE,
	       "AVB digest size mismatch");

AvbIOResult avb_read_permanent_attributes(AvbAtxOps *atx_ops,
					  AvbAtxPermanentAttributes *attributes)
{
	int result = bl31_get_permanent_attributes(
		avb_atx_permanent_attributes_hash, attributes);
	return (result == 0) ? AVB_IO_RESULT_OK : AVB_IO_RESULT_ERROR_IO;
}

AvbIOResult
avb_read_permanent_attributes_hash(AvbAtxOps *atx_ops,
				   uint8_t hash[AVB_SHA256_DIGEST_SIZE])
{
	memcpy(hash, avb_atx_permanent_attributes_hash, AVB_SHA256_DIGEST_SIZE);
	return AVB_IO_RESULT_OK;
}

/* Reads rollback index from user data area of OTP. */
AvbIOResult avb_read_rollback_index(AvbOps *ops, size_t rollback_index_location,
				    uint64_t *out_rollback_index)
{
#ifdef CONFIG_USE_ROLLBACK_IN_FUSE
	char buf[ROLLBACK_INDEX_BYTES];
	uint64_t *fuse_bits;
	ssize_t ret;

	if ((rollback_index_location >
	     AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) &&
	    (rollback_index_location != AVB_ATX_PIK_VERSION_LOCATION) &&
	    (rollback_index_location != AVB_ATX_PSK_VERSION_LOCATION)) {
		return AVB_IO_RESULT_ERROR_RANGE_OUTSIDE_PARTITION;
	}

	loff_t offset = rollback_index_location * ROLLBACK_INDEX_BYTES;

	ret = efuse_read_usr(buf, ROLLBACK_INDEX_BYTES, &offset);
	if (ret != ROLLBACK_INDEX_BYTES) {
		return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
	}
	fuse_bits = (uint64_t *)buf;

	if (rollback_index_location == AVB_ATX_PIK_VERSION_LOCATION) {
		*fuse_bits &= AVB_ATX_PIK_VERSION_LOCATION_MASK;
	}

	*out_rollback_index = __builtin_popcountl(*fuse_bits);
#else
	*out_rollback_index = 0;
#endif
	return AVB_IO_RESULT_OK;
}

/* Writes rollback index to user data area of OTP. If the rollback_index is
 * less than the current rollback index, the function does nothing and
 * returns with no error.
 */
AvbIOResult avb_write_rollback_index(AvbOps *ops,
				     size_t rollback_index_location,
				     uint64_t rollback_index)
{
#ifdef CONFIG_USE_ROLLBACK_IN_FUSE
	uint64_t cur_index;

	if (rollback_index > MAX_ROLLBACK_INDEX) {
		return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
	}
	// read_rollback_index() performs bounds check on the index location.
	AvbIOResult ret = avb_read_rollback_index(ops, rollback_index_location,
						  &cur_index);
	if (ret != AVB_IO_RESULT_OK) {
		return ret;
	}
	if (rollback_index <= cur_index) {
		return AVB_IO_RESULT_OK;
	}

	if ((rollback_index_location == AVB_ATX_PIK_VERSION_LOCATION) &&
	    (rollback_index > AVB_ATX_PIK_VERSION_LOCATION_MAX)) {
		return AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX;
	}

	loff_t offset = rollback_index_location * ROLLBACK_INDEX_BYTES;
	uint64_t fuse_bits = (1 << rollback_index) - 1;
	ssize_t bytes_written = efuse_write_usr((char *)&fuse_bits,
						ROLLBACK_INDEX_BYTES, &offset);
	if (bytes_written != ROLLBACK_INDEX_BYTES) {
		return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
	}
#endif
	return AVB_IO_RESULT_OK;
}
