/*
 * Copyright (c) 2022, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */

#include <string.h>

#include <delegated_attestation.h>
#include <psa/client.h>
#include <psa_manifest/sid.h>

#if !PLAT_RSS_NOT_SUPPORTED
psa_status_t
rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
				       uint32_t  key_bits,
				       uint8_t  *key_buf,
				       size_t    key_buf_size,
				       size_t   *key_size,
				       uint32_t  hash_algo)
{
	psa_status_t status;
	psa_invec in_vec[] = {
		{&ecc_curve, sizeof(ecc_curve)},
		{&key_bits,  sizeof(key_bits)},
		{&hash_algo, sizeof(hash_algo)}
	};
	psa_outvec out_vec[] = {
		{key_buf, key_buf_size}
	};

	if (key_size == NULL) {
		return PSA_ERROR_INVALID_ARGUMENT;
	}

	status = psa_call(RSS_DELEGATED_SERVICE_HANDLE,
			  RSS_DELEGATED_ATTEST_GET_DELEGATED_KEY,
			  in_vec,  IOVEC_LEN(in_vec),
			  out_vec, IOVEC_LEN(out_vec));
	if (status == PSA_SUCCESS) {
		*key_size = out_vec[0].len;
	}

	return status;
}

psa_status_t
rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
			       size_t         dak_pub_hash_size,
			       uint8_t       *token_buf,
			       size_t         token_buf_size,
			       size_t        *token_size)
{
	psa_status_t status;
	psa_invec in_vec[] = {
		{dak_pub_hash, dak_pub_hash_size}
	};
	psa_outvec out_vec[] = {
		{token_buf, token_buf_size}
	};

	if (token_size == NULL) {
		return PSA_ERROR_INVALID_ARGUMENT;
	}

	status = psa_call(RSS_DELEGATED_SERVICE_HANDLE,
			  RSS_DELEGATED_ATTEST_GET_PLATFORM_TOKEN,
			  in_vec, IOVEC_LEN(in_vec),
			  out_vec, IOVEC_LEN(out_vec));
	if (status == PSA_SUCCESS) {
		*token_size = out_vec[0].len;
	}

	return status;
}


#else /* !PLAT_RSS_NOT_SUPPORTED */

static const uint8_t delegated_key[] = {
	0x20, 0x11, 0xC7, 0xF0, 0x3C, 0xEE, 0x43, 0x25, 0x17, 0x6E,
	0x52, 0x4F, 0x03, 0x3C, 0x0C, 0xE1, 0xE2, 0x1A, 0x76, 0xE6,
	0xC1, 0xA4, 0xF0, 0xB8, 0x39, 0xAA, 0x1D, 0xF6, 0x1E, 0x0E,
	0x8A, 0x5C, 0x8A, 0x05, 0x74, 0x0F, 0x9B, 0x69, 0xEF, 0xA7,
	0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
}

static const uint8_t platform_token[] = {
	0xD2, 0x84, 0x43, 0xA1, 0x01, 0x26, 0xA0, 0x59,
	0x02, 0xBE, 0xAA, 0x3A, 0x00, 0x01, 0x24, 0xFF,
	0x58, 0x20, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
	0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
	0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
	0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB,
	0xAB, 0xAB, 0x3A, 0x00, 0x01, 0x24, 0xFB, 0x58,
	0x20, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
	0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE,
	0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
	0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
	0xBF, 0x3A, 0x00, 0x01, 0x25, 0x00, 0x58, 0x21,
	0x01, 0xFA, 0x58, 0x75, 0x5F, 0x65, 0x86, 0x27,
	0xCE, 0x54, 0x60, 0xF2, 0x9B, 0x75, 0x29, 0x67,
	0x13, 0x24, 0x8C, 0xAE, 0x7A, 0xD9, 0xE2, 0x98,
	0x4B, 0x90, 0x28, 0x0E, 0xFC, 0xBC, 0xB5, 0x02,
	0x48, 0x3A, 0x00, 0x01, 0x24, 0xFA, 0x58, 0x20,
	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
	0x3A, 0x00, 0x01, 0x24, 0xF8, 0x20, 0x3A, 0x00,
	0x01, 0x24, 0xF9, 0x00, 0x3A, 0x00, 0x01, 0x24,
	0xFD, 0x85, 0xA5, 0x05, 0x58, 0x20, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60,
	0x01, 0x65, 0x42, 0x4C, 0x31, 0x5F, 0x32, 0x06,
	0x66, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x02,
	0x58, 0x20, 0xF8, 0xB7, 0xCE, 0xAD, 0x9B, 0xE4,
	0x5A, 0x8F, 0x5C, 0x52, 0x6F, 0x0C, 0x05, 0x25,
	0x8F, 0xF3, 0xE9, 0x81, 0xDC, 0xBC, 0xF2, 0x05,
	0x7F, 0x33, 0xF6, 0xBB, 0xDC, 0xD9, 0x4D, 0xA2,
	0x34, 0x3A, 0xA5, 0x05, 0x58, 0x20, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x67,
	0x31, 0x2E, 0x37, 0x2E, 0x32, 0x2B, 0x30, 0x01,
	0x63, 0x42, 0x4C, 0x32, 0x06, 0x66, 0x53, 0x48,
	0x41, 0x32, 0x35, 0x36, 0x02, 0x58, 0x20, 0x3A,
	0xE5, 0x9E, 0x40, 0xA9, 0x6B, 0xD5, 0x29, 0x1C,
	0xAB, 0x7A, 0x5F, 0xBD, 0x1F, 0x9A, 0xA6, 0x52,
	0xFB, 0x77, 0x7D, 0xA3, 0xEC, 0x9C, 0x29, 0xBC,
	0xE6, 0x5B, 0x3B, 0x43, 0xFC, 0x9D, 0x26, 0xA5,
	0x05, 0x58, 0x20, 0xBF, 0xE6, 0xD8, 0x6F, 0x88,
	0x26, 0xF4, 0xFF, 0x97, 0xFB, 0x96, 0xC4, 0xE6,
	0xFB, 0xC4, 0x99, 0x3E, 0x46, 0x19, 0xFC, 0x56,
	0x5D, 0xA2, 0x6A, 0xDF, 0x34, 0xC3, 0x29, 0x48,
	0x9A, 0xDC, 0x38, 0x04, 0x67, 0x31, 0x2E, 0x35,
	0x2E, 0x30, 0x2B, 0x30, 0x01, 0x64, 0x52, 0x54,
	0x5F, 0x30, 0x06, 0x66, 0x53, 0x48, 0x41, 0x32,
	0x35, 0x36, 0x02, 0x58, 0x20, 0x47, 0x94, 0x9D,
	0x27, 0x33, 0x82, 0x45, 0x1A, 0xDD, 0x25, 0xF4,
	0x9A, 0x89, 0x6F, 0x5F, 0xD9, 0xB0, 0xE8, 0x14,
	0xD3, 0xA4, 0x9B, 0x53, 0xB0, 0x44, 0x0B, 0xCF,
	0x32, 0x1A, 0xC4, 0xD2, 0x65, 0xA5, 0x05, 0x58,
	0x20, 0xB3, 0x60, 0xCA, 0xF5, 0xC9, 0x8C, 0x6B,
	0x94, 0x2A, 0x48, 0x82, 0xFA, 0x9D, 0x48, 0x23,
	0xEF, 0xB1, 0x66, 0xA9, 0xEF, 0x6A, 0x6E, 0x4A,
	0xA3, 0x7C, 0x19, 0x19, 0xED, 0x1F, 0xCC, 0xC0,
	0x49, 0x04, 0x67, 0x30, 0x2E, 0x30, 0x2E, 0x37,
	0x2B, 0x30, 0x01, 0x64, 0x52, 0x54, 0x5F, 0x31,
	0x06, 0x66, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
	0x02, 0x58, 0x20, 0xCD, 0x38, 0xBE, 0xC8, 0xB7,
	0xC0, 0x9E, 0xD5, 0x24, 0x30, 0xFE, 0xC8, 0xD0,
	0x19, 0x12, 0x56, 0xB2, 0x7A, 0xA5, 0x53, 0x6F,
	0xBC, 0x7D, 0x09, 0xCA, 0x11, 0xDD, 0x90, 0xD7,
	0xD6, 0x70, 0xFD, 0xA5, 0x05, 0x58, 0x20, 0xAA,
	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x04,
	0x60, 0x01, 0x60, 0x06, 0x66, 0x53, 0x48, 0x41,
	0x32, 0x35, 0x36, 0x02, 0x58, 0x20, 0x28, 0x3D,
	0x0C, 0x25, 0x22, 0x0C, 0x87, 0x46, 0xA0, 0x58,
	0x64, 0x6C, 0x0B, 0x14, 0x37, 0x39, 0x40, 0x9D,
	0x2D, 0x11, 0xD1, 0xCC, 0x54, 0x51, 0xB4, 0x29,
	0x22, 0xCD, 0x70, 0x92, 0x71, 0xC3, 0x3A, 0x00,
	0x01, 0x25, 0x01, 0x77, 0x77, 0x77, 0x77, 0x2E,
	0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x66,
	0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2E,
	0x6F, 0x72, 0x67, 0x3A, 0x00, 0x01, 0x24, 0xF7,
	0x71, 0x50, 0x53, 0x41, 0x5F, 0x49, 0x4F, 0x54,
	0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45,
	0x5F, 0x31, 0x3A, 0x00, 0x01, 0x24, 0xFC, 0x70,
	0x30, 0x36, 0x30, 0x34, 0x35, 0x36, 0x35, 0x32,
	0x37, 0x32, 0x38, 0x32, 0x39, 0x31, 0x30, 0x30,
	0x58, 0x40, 0x1E, 0x0D, 0x2B, 0xD8, 0x7A, 0xC9,
	0x2D, 0xCB, 0x73, 0xD1, 0x42, 0x2F, 0xBF, 0xDA,
	0x24, 0x71, 0xE2, 0xAF, 0xEA, 0x48, 0x60, 0x17,
	0x23, 0x75, 0x64, 0xAC, 0xCC, 0x23, 0xA2, 0x67,
	0xC4, 0xE7, 0x8F, 0x1C, 0x7C, 0x68, 0x49, 0x42,
	0x4D, 0xDA, 0xC6, 0xD6, 0x21, 0x1C, 0xAA, 0x00,
	0xDA, 0x1E, 0x68, 0x56, 0xA3, 0x48, 0xEE, 0xA7,
	0x92, 0xA9, 0x09, 0x83, 0x42, 0x04, 0x06, 0x9E,
	0x62, 0xBB
};

psa_status_t
rss_delegated_attest_get_delegated_key(uint8_t   ecc_curve,
				       uint32_t  key_bits,
				       uint8_t  *key_buf,
				       size_t    key_buf_size,
				       size_t   *key_size,
				       uint32_t  hash_algo)
{
	(void)ecc_curve;
	(void)key_bits;
	(void)hash_algo;

	if (key_buf_size < sizeof(delegated_key)) {
		return PSA_ERROR_BUFFER_TOO_SMALL;
	}

	(void)memcpy(key_buf, delegated_key, sizeof(delegated_key));
	*key_size = sizeof(delegated_key);

	return PSA_SUCCESS;
}
psa_status_t
rss_delegated_attest_get_token(const uint8_t *dak_pub_hash,
			       size_t         dak_pub_hash_size,
			       uint8_t       *token_buf,
			       size_t         token_buf_size,
			       size_t        *token_size)
{
	(void)dak_pub_hash;
	(void)dak_pub_hash_size;

	if (token_buf_size < sizeof(platform_token)) {
		return PSA_ERROR_BUFFER_TOO_SMALL;
	}

	(void)memcpy(token_buf, platform_token, sizeof(platform_token));
	*token_size = sizeof(platform_token);

	return PSA_SUCCESS;
}
#endif /* !PLAT_RSS_NOT_SUPPORTED */
