105799ae0SJuan Castillo /*
2*e6937287SZelalem * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
305799ae0SJuan Castillo *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
505799ae0SJuan Castillo */
605799ae0SJuan Castillo
705799ae0SJuan Castillo #include <assert.h>
805799ae0SJuan Castillo #include <limits.h>
905799ae0SJuan Castillo #include <stdint.h>
1005799ae0SJuan Castillo #include <string.h>
1109d40e0eSAntonio Nino Diaz
1209d40e0eSAntonio Nino Diaz #include <common/debug.h>
1309d40e0eSAntonio Nino Diaz #include <drivers/auth/auth_common.h>
1409d40e0eSAntonio Nino Diaz #include <drivers/auth/img_parser_mod.h>
1509d40e0eSAntonio Nino Diaz #include <lib/utils_def.h>
1605799ae0SJuan Castillo
179f85f9e3SJoel Hutton IMPORT_SYM(uintptr_t, __PARSER_LIB_DESCS_START__, PARSER_LIB_DESCS_START);
189f85f9e3SJoel Hutton IMPORT_SYM(uintptr_t, __PARSER_LIB_DESCS_END__, PARSER_LIB_DESCS_END);
1905799ae0SJuan Castillo static unsigned int parser_lib_indices[IMG_MAX_TYPES];
2005799ae0SJuan Castillo static img_parser_lib_desc_t *parser_lib_descs;
2105799ae0SJuan Castillo
2205799ae0SJuan Castillo #define INVALID_IDX UINT_MAX
2305799ae0SJuan Castillo
validate_desc(img_parser_lib_desc_t * desc)2405799ae0SJuan Castillo static void validate_desc(img_parser_lib_desc_t *desc)
2505799ae0SJuan Castillo {
2605799ae0SJuan Castillo assert(desc != NULL);
2705799ae0SJuan Castillo assert(desc->init != NULL);
2805799ae0SJuan Castillo assert(desc->name != NULL);
2905799ae0SJuan Castillo assert(desc->check_integrity != NULL);
3005799ae0SJuan Castillo assert(desc->get_auth_param != NULL);
3105799ae0SJuan Castillo }
3205799ae0SJuan Castillo
img_parser_init(void)3305799ae0SJuan Castillo void img_parser_init(void)
3405799ae0SJuan Castillo {
3505799ae0SJuan Castillo unsigned int index, mod_num;
3605799ae0SJuan Castillo
3705799ae0SJuan Castillo /* Initialise internal variables to invalid state */
3805799ae0SJuan Castillo for (index = 0; index < IMG_MAX_TYPES; index++) {
3905799ae0SJuan Castillo parser_lib_indices[index] = INVALID_IDX;
4005799ae0SJuan Castillo }
4105799ae0SJuan Castillo
4205799ae0SJuan Castillo /* Calculate how many image parsers are registered. At least one parser
4305799ae0SJuan Castillo * must be present */
4405799ae0SJuan Castillo mod_num = PARSER_LIB_DESCS_END - PARSER_LIB_DESCS_START;
4505799ae0SJuan Castillo mod_num /= sizeof(img_parser_lib_desc_t);
4605799ae0SJuan Castillo assert(mod_num > 0);
4705799ae0SJuan Castillo
4805799ae0SJuan Castillo parser_lib_descs = (img_parser_lib_desc_t *) PARSER_LIB_DESCS_START;
4905799ae0SJuan Castillo for (index = 0; index < mod_num; index++) {
5005799ae0SJuan Castillo
5105799ae0SJuan Castillo /* Check that the image parser library descriptor is valid */
5205799ae0SJuan Castillo validate_desc(&parser_lib_descs[index]);
5305799ae0SJuan Castillo
5405799ae0SJuan Castillo /* Initialize image parser */
5505799ae0SJuan Castillo parser_lib_descs[index].init();
5605799ae0SJuan Castillo
5705799ae0SJuan Castillo /* Ensure only one parser is registered for each image type */
5805799ae0SJuan Castillo assert(parser_lib_indices[parser_lib_descs[index].img_type] ==
5905799ae0SJuan Castillo INVALID_IDX);
6005799ae0SJuan Castillo
6105799ae0SJuan Castillo /* Keep the index of this hash calculator */
6205799ae0SJuan Castillo parser_lib_indices[parser_lib_descs[index].img_type] = index;
6305799ae0SJuan Castillo }
6405799ae0SJuan Castillo }
6505799ae0SJuan Castillo
img_parser_check_integrity(img_type_t img_type,void * img_ptr,unsigned int img_len)6605799ae0SJuan Castillo int img_parser_check_integrity(img_type_t img_type,
6705799ae0SJuan Castillo void *img_ptr, unsigned int img_len)
6805799ae0SJuan Castillo {
6905799ae0SJuan Castillo unsigned int idx;
7005799ae0SJuan Castillo
7105799ae0SJuan Castillo assert(img_ptr != NULL);
7205799ae0SJuan Castillo assert(img_len != 0);
7305799ae0SJuan Castillo
7405799ae0SJuan Castillo /* No integrity checks on raw images */
7505799ae0SJuan Castillo if (img_type == IMG_RAW) {
7605799ae0SJuan Castillo return IMG_PARSER_OK;
7705799ae0SJuan Castillo }
7805799ae0SJuan Castillo
7905799ae0SJuan Castillo /* Find the index of the required image parser */
8005799ae0SJuan Castillo idx = parser_lib_indices[img_type];
8105799ae0SJuan Castillo assert(idx != INVALID_IDX);
8205799ae0SJuan Castillo
8305799ae0SJuan Castillo /* Call the function to check the image integrity */
8405799ae0SJuan Castillo return parser_lib_descs[idx].check_integrity(img_ptr, img_len);
8505799ae0SJuan Castillo }
8605799ae0SJuan Castillo
8705799ae0SJuan Castillo /*
8805799ae0SJuan Castillo * Extract an authentication parameter from an image
8905799ae0SJuan Castillo *
9005799ae0SJuan Castillo * Parameters:
9105799ae0SJuan Castillo * img_type: image type (certificate, raw image, etc)
9205799ae0SJuan Castillo * type_desc: provides info to obtain the parameter
9305799ae0SJuan Castillo * img_ptr: pointer to image data
9405799ae0SJuan Castillo * img_len: image length
9505799ae0SJuan Castillo * param_ptr: [out] stores a pointer to the parameter
9605799ae0SJuan Castillo * param_len: [out] stores the length of the parameter
9705799ae0SJuan Castillo */
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)9805799ae0SJuan Castillo int img_parser_get_auth_param(img_type_t img_type,
9905799ae0SJuan Castillo const auth_param_type_desc_t *type_desc,
10005799ae0SJuan Castillo void *img_ptr, unsigned int img_len,
10105799ae0SJuan Castillo void **param_ptr, unsigned int *param_len)
10205799ae0SJuan Castillo {
10305799ae0SJuan Castillo unsigned int idx;
10405799ae0SJuan Castillo
10505799ae0SJuan Castillo assert(type_desc != NULL);
10605799ae0SJuan Castillo assert(img_ptr != NULL);
10705799ae0SJuan Castillo assert(img_len != 0);
10805799ae0SJuan Castillo assert(param_ptr != NULL);
10905799ae0SJuan Castillo assert(param_len != NULL);
11005799ae0SJuan Castillo
11105799ae0SJuan Castillo /* In a raw image we can only get the data itself */
11205799ae0SJuan Castillo if (img_type == IMG_RAW) {
11305799ae0SJuan Castillo assert(type_desc->type == AUTH_PARAM_RAW_DATA);
11405799ae0SJuan Castillo *param_ptr = img_ptr;
11505799ae0SJuan Castillo *param_len = img_len;
11605799ae0SJuan Castillo return IMG_PARSER_OK;
11705799ae0SJuan Castillo }
11805799ae0SJuan Castillo
11905799ae0SJuan Castillo /* Find the index of the required image parser library */
12005799ae0SJuan Castillo idx = parser_lib_indices[img_type];
12105799ae0SJuan Castillo assert(idx != INVALID_IDX);
12205799ae0SJuan Castillo
12305799ae0SJuan Castillo /* Call the function to obtain the parameter */
12405799ae0SJuan Castillo return parser_lib_descs[idx].get_auth_param(type_desc, img_ptr, img_len,
12505799ae0SJuan Castillo param_ptr, param_len);
12605799ae0SJuan Castillo }
127