/*
 * Copyright (c) 2019,2020 Linaro Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <stdio.h>
#include <logging/log.h>

#include "psa/initial_attestation.h"
#include "psa_attestation.h"
#include "util_app_log.h"
#include "util_sformat.h"

LOG_MODULE_DECLARE(app, CONFIG_LOG_DEFAULT_LEVEL);

psa_status_t att_get_pub_key(void)
{
	psa_status_t err = PSA_SUCCESS;

	/* TODO: How to retrieve this?!? */

	/* Log any eventual errors via app_log */
	return err ? al_psa_status(err, __func__) : err;
}

psa_status_t att_get_iat(uint8_t *ch_buffer, uint32_t ch_sz,
			 uint8_t *token_buffer, uint32_t *token_sz)
{
	psa_status_t err = PSA_SUCCESS;
	uint32_t sys_token_sz;
	size_t token_buf_size = ATT_MAX_TOKEN_SIZE;


	/* Call with with bigger challenge object than allowed */

	/*
	 * First determine how large the token is on this system.
	 * We don't need to compare with the size of ATT_MAX_TOKEN_SIZE here
	 * since a check will be made in 'psa_initial_attest_get_token' and the
	 * error return code will indicate a mismatch.
	 */
	switch (ch_sz) {
	case 32:
		err = psa_initial_attest_get_token(
			ch_buffer,
			PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32,
			token_buffer,
			token_buf_size,
			&sys_token_sz);
		break;
	case 48:
		err = psa_initial_attest_get_token(
			ch_buffer,
			PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48,
			token_buffer,
			token_buf_size,
			&sys_token_sz);
		break;
	case 64:
		err = psa_initial_attest_get_token(
			ch_buffer,
			PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64,
			token_buffer,
			token_buf_size,
			&sys_token_sz);
		break;
	default:
		err = -EINVAL;
		break;
	}
	if (err) {
		goto err;
	}

	LOG_INF("att: System IAT size is: %u bytes.", sys_token_sz);

	/* Request the initial attestation token w/the challenge data. */
	LOG_INF("att: Requesting IAT with %u byte challenge.", ch_sz);
	err = psa_initial_attest_get_token(
		ch_buffer,      /* Challenge/nonce input buffer. */
		ch_sz,          /* Challenge size (32, 48 or 64). */
		token_buffer,   /* Token output buffer. */
		token_buf_size,
		token_sz        /* Post exec output token size. */
		);
	LOG_INF("att: IAT data received: %u bytes.", *token_sz);

err:
	/* Log any eventual errors via app_log */
	return err ? al_psa_status(err, __func__) : err;
}

psa_status_t att_test(void)
{
	psa_status_t err = PSA_SUCCESS;

	/* 64-byte nonce/challenge, encrypted using the default public key;
	 *
	 * 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
	 * 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
	 * 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
	 * 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
	 */
	uint32_t nonce_sz = 64;
	uint8_t nonce_buf[ATT_MAX_TOKEN_SIZE] = {
		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
		0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
		0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
		0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
		0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
		0
	};

	/* IAT response buffer. */
	uint32_t iat_sz = ATT_MAX_TOKEN_SIZE;
	uint8_t iat_buf[ATT_MAX_TOKEN_SIZE] = { 0 };

	/* String format output config. */
	struct sf_hex_tbl_fmt fmt = {
		.ascii = true,
		.addr_label = true,
		.addr = 0
	};

	/* Request the IAT from the initial attestation service. */
	err = att_get_iat(nonce_buf, nonce_sz, iat_buf, &iat_sz);
	if (err) {
		goto err;
	}

	/* Display queued log messages before dumping the IAT. */
	al_dump_log();

	/* Dump the IAT for debug purposes. */
	sf_hex_tabulate_16(&fmt, iat_buf, (size_t)iat_sz);

err:
	return err;
}
