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

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

#include <common/debug.h>
#include <drivers/auth/auth_common.h>
#include <drivers/auth/img_parser_mod.h>
#include <lib/utils_def.h>

IMPORT_SYM(uintptr_t, __PARSER_LIB_DESCS_START__,	PARSER_LIB_DESCS_START);
IMPORT_SYM(uintptr_t, __PARSER_LIB_DESCS_END__,		PARSER_LIB_DESCS_END);
static unsigned int parser_lib_indices[IMG_MAX_TYPES];
static img_parser_lib_desc_t *parser_lib_descs;

#define INVALID_IDX		UINT_MAX

static void validate_desc(img_parser_lib_desc_t *desc)
{
	assert(desc != NULL);
	assert(desc->init != NULL);
	assert(desc->name != NULL);
	assert(desc->check_integrity != NULL);
	assert(desc->get_auth_param != NULL);
}

void img_parser_init(void)
{
	unsigned int index, mod_num;

	/* Initialise internal variables to invalid state */
	for (index = 0; index < IMG_MAX_TYPES; index++) {
		parser_lib_indices[index] = INVALID_IDX;
	}

	/* Calculate how many image parsers are registered. At least one parser
	 * must be present */
	mod_num = PARSER_LIB_DESCS_END - PARSER_LIB_DESCS_START;
	mod_num /= sizeof(img_parser_lib_desc_t);
	assert(mod_num > 0);

	parser_lib_descs = (img_parser_lib_desc_t *) PARSER_LIB_DESCS_START;
	for (index = 0; index < mod_num; index++) {

		/* Check that the image parser library descriptor is valid */
		validate_desc(&parser_lib_descs[index]);

		/* Initialize image parser */
		parser_lib_descs[index].init();

		/* Ensure only one parser is registered for each image type */
		assert(parser_lib_indices[parser_lib_descs[index].img_type] ==
				INVALID_IDX);

		/* Keep the index of this hash calculator */
		parser_lib_indices[parser_lib_descs[index].img_type] = index;
	}
}

int img_parser_check_integrity(img_type_t img_type,
			       void *img_ptr, unsigned int img_len)
{
	unsigned int idx;

	assert(img_ptr != NULL);
	assert(img_len != 0);

	/* No integrity checks on raw images */
	if (img_type == IMG_RAW) {
		return IMG_PARSER_OK;
	}

	/* Find the index of the required image parser */
	idx = parser_lib_indices[img_type];
	assert(idx != INVALID_IDX);

	/* Call the function to check the image integrity */
	return parser_lib_descs[idx].check_integrity(img_ptr, img_len);
}

/*
 * Extract an authentication parameter from an image
 *
 * Parameters:
 *   img_type: image type (certificate, raw image, etc)
 *   type_desc: provides info to obtain the parameter
 *   img_ptr: pointer to image data
 *   img_len: image length
 *   param_ptr: [out] stores a pointer to the parameter
 *   param_len: [out] stores the length of the parameter
 */
int img_parser_get_auth_param(img_type_t img_type,
			      const auth_param_type_desc_t *type_desc,
			      void *img_ptr, unsigned int img_len,
			      void **param_ptr, unsigned int *param_len)
{
	unsigned int idx;

	assert(type_desc != NULL);
	assert(img_ptr != NULL);
	assert(img_len != 0);
	assert(param_ptr != NULL);
	assert(param_len != NULL);

	/* In a raw image we can only get the data itself */
	if (img_type == IMG_RAW) {
		assert(type_desc->type == AUTH_PARAM_RAW_DATA);
		*param_ptr = img_ptr;
		*param_len = img_len;
		return IMG_PARSER_OK;
	}

	/* Find the index of the required image parser library */
	idx = parser_lib_indices[img_type];
	assert(idx != INVALID_IDX);

	/* Call the function to obtain the parameter */
	return parser_lib_descs[idx].get_auth_param(type_desc, img_ptr, img_len,
			param_ptr, param_len);
}
