/*
 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <stdint.h>
#include <string.h>

#include <common/debug.h>
#include <drivers/arm/cryptocell/cc_rotpk.h>
#include <drivers/delay_timer.h>
#include <lib/cassert.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <tools_share/tbbr_oid.h>


#if !ARM_CRYPTOCELL_INTEG
#if !ARM_ROTPK_LOCATION_ID
  #error "ARM_ROTPK_LOCATION_ID not defined"
#endif
#endif

/* Weak definition may be overridden in specific platform */
#pragma weak plat_get_nv_ctr
#pragma weak plat_set_nv_ctr

extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];

static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];

/*
 * Return the ROTPK hash stored in dedicated registers.
 */
int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
			unsigned int *flags)
{
	uint8_t *dst;
	uint32_t *src, tmp;
	unsigned int words, i;

	assert(key_ptr != NULL);
	assert(key_len != NULL);
	assert(flags != NULL);

	/* Copy the DER header */

	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
	dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];

	words = ARM_ROTPK_HASH_LEN >> 2;

	src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
	for (i = 0 ; i < words ; i++) {
		tmp = src[words - 1 - i];
		/* Words are read in little endian */
		*dst++ = (uint8_t)(tmp & 0xFF);
		*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
		*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
		*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
	}

	*key_ptr = (void *)rotpk_hash_der;
	*key_len = (unsigned int)sizeof(rotpk_hash_der);
	*flags = ROTPK_IS_HASH;
	return 0;
}

#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
/*
 * Return development ROTPK hash generated from ROT_KEY.
 */
int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
			unsigned int *flags)
{
	*key_ptr = arm_rotpk_header;
	*key_len = arm_rotpk_hash_end - arm_rotpk_header;
	*flags = ROTPK_IS_HASH;
	return 0;
}
#endif

#if ARM_CRYPTOCELL_INTEG
/*
 * Return ROTPK hash from CryptoCell.
 */
int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
			unsigned int *flags)
{
	unsigned char *dst;

	assert(key_ptr != NULL);
	assert(key_len != NULL);
	assert(flags != NULL);

	/* Copy the DER header */
	memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
	dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
	*key_ptr = rotpk_hash_der;
	*key_len = sizeof(rotpk_hash_der);
	return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
}
#endif

/*
 * Wraper function for most Arm platforms to get ROTPK hash.
 */
int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len,
			unsigned int *flags)
{
#if ARM_CRYPTOCELL_INTEG
	return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
#else

#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
    (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
	return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
	return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
#else
	return 1;
#endif

#endif /* ARM_CRYPTOCELL_INTEG */
}

/*
 * Return the non-volatile counter value stored in the platform. The cookie
 * will contain the OID of the counter in the certificate.
 *
 * Return: 0 = success, Otherwise = error
 */
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
{
	const char *oid;
	uint32_t *nv_ctr_addr;

	assert(cookie != NULL);
	assert(nv_ctr != NULL);

	oid = (const char *)cookie;
	if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
		nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
	} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
		nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
	} else {
		return 1;
	}

	*nv_ctr = (unsigned int)(*nv_ctr_addr);

	return 0;
}

/*
 * Store a new non-volatile counter value. By default on ARM development
 * platforms, the non-volatile counters are RO and cannot be modified. We expect
 * the values in the certificates to always match the RO values so that this
 * function is never called.
 *
 * Return: 0 = success, Otherwise = error
 */
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
	return 1;
}
