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

#include <string.h>

#include <common/debug.h>
#include <drivers/measured_boot/metadata.h>
#include <measured_boot.h>
#include <psa/client.h>
#include <psa_manifest/sid.h>

#include "measured_boot_private.h"

static void print_byte_array(const uint8_t *array __unused, size_t len __unused)
{
#if LOG_LEVEL >= LOG_LEVEL_INFO
	size_t i;

	if (array == NULL || len == 0U) {
		(void)printf("\n");
	} else {
		for (i = 0U; i < len; ++i) {
			(void)printf(" %02x", array[i]);
			if ((i & U(0xF)) == U(0xF)) {
				(void)printf("\n");
				if (i < (len - 1U)) {
					INFO("\t\t:");
				}
			}
		}
	}
#endif
}

static void log_measurement(uint8_t index,
			    const uint8_t *signer_id,
			    size_t signer_id_size,
			    const uint8_t *version,     /* string */
			    size_t version_size,
			    const uint8_t *sw_type,     /* string */
			    size_t sw_type_size,
			    uint32_t measurement_algo,
			    const uint8_t *measurement_value,
			    size_t measurement_value_size,
			    bool lock_measurement)
{
	INFO("Measured boot extend measurement:\n");
	INFO(" - slot        : %u\n", index);
	INFO(" - signer_id   :");
	print_byte_array(signer_id, signer_id_size);
	INFO(" - version     : %s\n",  version);
	INFO(" - version_size: %zu\n", version_size);
	INFO(" - sw_type     : %s\n",  sw_type);
	INFO(" - sw_type_size: %zu\n", sw_type_size);
	INFO(" - algorithm   : %x\n", measurement_algo);
	INFO(" - measurement :");
	print_byte_array(measurement_value, measurement_value_size);
	INFO(" - locking     : %s\n", lock_measurement ? "true" : "false");
}

psa_status_t
rse_measured_boot_extend_measurement(uint8_t index,
				     const uint8_t *signer_id,
				     size_t signer_id_size,
				     const uint8_t *version,
				     size_t version_size,
				     uint32_t measurement_algo,
				     const uint8_t *sw_type,
				     size_t sw_type_size,
				     const uint8_t *measurement_value,
				     size_t measurement_value_size,
				     bool lock_measurement)
{
	struct measured_boot_extend_iovec_t extend_iov = {
		.index = index,
		.lock_measurement = lock_measurement,
		.measurement_algo = measurement_algo,
		.sw_type = {0},
		.sw_type_size = sw_type_size,
	};

	if (version_size > VERSION_MAX_SIZE) {
		return PSA_ERROR_INVALID_ARGUMENT;
	}


	if (version_size > 0 && version[version_size - 1] == '\0') {
		version_size--;
	}

	psa_invec in_vec[] = {
		{.base = &extend_iov,
			.len = sizeof(struct measured_boot_extend_iovec_t)},
		{.base = signer_id, .len = signer_id_size},
		{.base = version, .len = version_size },
		{.base = measurement_value, .len = measurement_value_size}
	};

	if (sw_type != NULL) {
		if (extend_iov.sw_type_size > SW_TYPE_MAX_SIZE) {
			return PSA_ERROR_INVALID_ARGUMENT;
		}
		if (sw_type_size > 0 && sw_type[sw_type_size - 1] == '\0') {
			extend_iov.sw_type_size--;
		}
		memcpy(extend_iov.sw_type, sw_type, extend_iov.sw_type_size);
	}

	log_measurement(index, signer_id, signer_id_size,
			version, version_size, sw_type, sw_type_size,
			measurement_algo, measurement_value,
			measurement_value_size, lock_measurement);

	return psa_call(RSE_MEASURED_BOOT_HANDLE,
			RSE_MEASURED_BOOT_EXTEND,
			in_vec, IOVEC_LEN(in_vec),
			NULL, 0);
}

psa_status_t rse_measured_boot_read_measurement(uint8_t index,
					uint8_t *signer_id,
					size_t signer_id_size,
					size_t *signer_id_len,
					uint8_t *version,
					size_t version_size,
					size_t *version_len,
					uint32_t *measurement_algo,
					uint8_t *sw_type,
					size_t sw_type_size,
					size_t *sw_type_len,
					uint8_t *measurement_value,
					size_t measurement_value_size,
					size_t *measurement_value_len,
					bool *is_locked)
{
	psa_status_t status;
	struct measured_boot_read_iovec_in_t read_iov_in = {
		.index = index,
		.sw_type_size = sw_type_size,
		.version_size = version_size,
	};

	struct measured_boot_read_iovec_out_t read_iov_out;

	psa_invec in_vec[] = {
		{.base = &read_iov_in,
		 .len = sizeof(struct measured_boot_read_iovec_in_t)},
	};

	psa_outvec out_vec[] = {
		{.base = &read_iov_out,
		 .len = sizeof(struct measured_boot_read_iovec_out_t)},
		{.base = signer_id, .len = signer_id_size},
		{.base = measurement_value, .len = measurement_value_size}
	};

	status = psa_call(RSE_MEASURED_BOOT_HANDLE, RSE_MEASURED_BOOT_READ,
					  in_vec, IOVEC_LEN(in_vec),
					  out_vec, IOVEC_LEN(out_vec));

	if (status == PSA_SUCCESS) {
		*is_locked = read_iov_out.is_locked;
		*measurement_algo = read_iov_out.measurement_algo;
		*sw_type_len = read_iov_out.sw_type_len;
		*version_len = read_iov_out.version_len;
		memcpy(sw_type, read_iov_out.sw_type, read_iov_out.sw_type_len);
		memcpy(version, read_iov_out.version, read_iov_out.version_len);
		*signer_id_len = out_vec[1].len;
		*measurement_value_len = out_vec[2].len;
	}

	return status;
}
