/*
 * Initialize_tl.c
 */

#include "tz_arcounter_errors.h"
#include "Initialize_tl.h"
#ifdef ICCC_v4
#include "icccOperations_v4.h"
#else
#include "icccOperations.h"
#endif

static uint32_t arcounter_ICCC_check(void)
{
        TTY_LOG("arcounter_ICCC_check()");
        uint32_t result_code = ICCC_STATUS_RETURN_NOT_SECURE;
        uint32_t ret = ICCC_ERROR_DEVICE_STATUS_FAILED;
        uint32_t comp_type = ICCC_STATUS_COMP_TYPE_SOFT_INTEGRITY;
        uint32_t ta_status_msg_len = 0;
        uint8_t ta_status_msg[ICCC_STATUS_MAX_RESULT_MESSAGE];

        ret = Iccc_DeviceStatus_TA(comp_type, ta_status_msg, sizeof(ta_status_msg), &ta_status_msg_len, &result_code);
        if (ret != ICCC_SUCCESS)
        {
                TTY_LOG("Unable to verify device status");
                return 0;
        }

        if (result_code != ICCC_STATUS_RETURN_SECURE)
        {
                TTY_LOG("Device is not secure");
                return 0;
        }

        return 1;
}

tciReturnCode_t arcounter_init(void)
{
	uint32_t ret = TZ_ARCOUNTER_NOT_INITIALIZED;
	printf("TL_TZ_ARCOUNTER: INIT\n");

	// Device integrity check
	if (arcounter_ICCC_check()) {
		ret = RET_TL_TZ_ARCOUNTER_OK;
	}

	return ret;
}

uint32_t process_Initialize(
	tl_arcounter_ctx_t * ctx,
	tz_init_payload_t * sendmsg,
	tz_init_payload_t * respmsg
)
{
	/* Slight abuse of return code
	 * Because of standards and our common init logic
	 */
	tciReturnCode_t ret = TZ_ARCOUNTER_SUCCESS;

	if (0 != ctx->arcounter_init_count) {
		TTY_LOG("TL_TZ_ARCOUNTER: TZ ARCOUNTER already initialized");
		ret = TZ_ARCOUNTER_ALREADY_INITIALIZED;
		ctx->arcounter_init_count++;
		goto exit;
	}

	ret = arcounter_init();
	/* Slight abuse of return code
	 * Because TZ_COMMON_OK == RET_TL_TZ_ARCOUNTER_OK
	 * and it doesn't make sense to include tlc_tz_common.h here
	 */
	if (RET_TL_TZ_ARCOUNTER_OK != ret) {
		TTY_LOG("TL_TZ_ARCOUNTER: TL ARCOUNTER measurement command processing failure");
		ret = TZ_ARCOUNTER_FUNCTION_FAILED;
		goto exit;
	}

	if (RET_TL_TZ_ARCOUNTER_OK != tl_arcounter_ctx_initialize(ctx)) {
		TTY_LOG("TL_TZ_ARCOUNTER: TL ARCOUNTER context initialization failure");
		ret = TZ_ARCOUNTER_FUNCTION_FAILED;
		goto exit;
	}
	ret = RET_TL_TZ_ARCOUNTER_OK;
	ctx->arcounter_init_count++;

	if (RET_TL_TZ_ARCOUNTER_OK != arcounter_rpmb_init()) {
		TTY_LOG("TL_TZ_ARCOUNTER: RPMB initialization failure");
		ret = TZ_ARCOUNTER_FUNCTION_FAILED;
		goto exit;
	}

exit:
	respmsg->payload.resp.return_code = ret;
	return ret;
}
