diff options
Diffstat (limited to 'plat/arm/common/arm_dyn_cfg.c')
-rw-r--r-- | plat/arm/common/arm_dyn_cfg.c | 221 |
1 files changed, 108 insertions, 113 deletions
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index e6c5a7361..6b3a61180 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,13 +15,17 @@ #include <common/tbbr/tbbr_img_def.h> #if TRUSTED_BOARD_BOOT #include <drivers/auth/mbedtls/mbedtls_config.h> +#if MEASURED_BOOT +#include <drivers/auth/crypto_mod.h> +#include <mbedtls/md.h> #endif +#endif +#include <lib/fconf/fconf.h> +#include <lib/fconf/fconf_dyn_cfg_getter.h> +#include <lib/fconf/fconf_tbbr_getter.h> + #include <plat/arm/common/arm_dyn_cfg_helpers.h> #include <plat/arm/common/plat_arm.h> -#include <plat/common/platform.h> - -/* Variable to store the address to TB_FW_CONFIG passed from BL1 */ -static void *tb_fw_cfg_dtb; #if TRUSTED_BOARD_BOOT @@ -57,20 +61,10 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) #elif defined(IMAGE_BL2) - int err; - /* If in BL2, retrieve the already allocated heap's info from DTB */ - if (tb_fw_cfg_dtb != NULL) { - err = arm_get_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, heap_addr, - heap_size); - if (err < 0) { - ERROR("BL2: unable to retrieve shared Mbed TLS heap information from DTB\n"); - panic(); - } - } else { - ERROR("BL2: DTB missing, cannot get Mbed TLS heap\n"); - panic(); - } + *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr); + *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size); + #endif return 0; @@ -83,6 +77,8 @@ int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size) void arm_bl1_set_mbedtls_heap(void) { int err; + uintptr_t tb_fw_cfg_dtb; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; /* * If tb_fw_cfg_dtb==NULL then DTB is not present for the current @@ -96,141 +92,150 @@ void arm_bl1_set_mbedtls_heap(void) * information, we would need to call plat_get_mbedtls_heap to retrieve * the default heap's address and size. */ - if ((tb_fw_cfg_dtb != NULL) && (mbedtls_heap_addr != NULL)) { - err = arm_set_dtb_mbedtls_heap_info(tb_fw_cfg_dtb, + + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; + + if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { + /* As libfdt uses void *, we can't avoid this cast */ + void *dtb = (void *)tb_fw_cfg_dtb; + + err = arm_set_dtb_mbedtls_heap_info(dtb, mbedtls_heap_addr, mbedtls_heap_size); if (err < 0) { - ERROR("BL1: unable to write shared Mbed TLS heap information to DTB\n"); + ERROR("%swrite shared Mbed TLS heap information%s", + "BL1: unable to ", " to DTB\n"); panic(); } +#if !MEASURED_BOOT /* * Ensure that the info written to the DTB is visible to other * images. It's critical because BL2 won't be able to proceed * without the heap info. + * + * In MEASURED_BOOT case flushing is done in + * arm_bl1_set_bl2_hash() function which is called after heap + * information is written in the DTB. */ - flush_dcache_range((uintptr_t)tb_fw_cfg_dtb, - fdt_totalsize(tb_fw_cfg_dtb)); + flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb)); +#endif /* !MEASURED_BOOT */ } } -#endif /* TRUSTED_BOARD_BOOT */ - +#if MEASURED_BOOT /* - * Helper function to load TB_FW_CONFIG and populate the load information to - * arg0 of BL2 entrypoint info. + * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. + * Executed only from BL1. */ -void arm_load_tb_fw_config(void) +void arm_bl1_set_bl2_hash(const image_desc_t *image_desc) { + unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; + const image_info_t image_info = image_desc->image_info; + uintptr_t tb_fw_cfg_dtb; int err; - uintptr_t config_base = 0UL; - image_desc_t *desc; - - image_desc_t arm_tb_fw_info = { - .image_id = TB_FW_CONFIG_ID, - SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, - VERSION_2, image_info_t, 0), - .image_info.image_base = ARM_TB_FW_CONFIG_BASE, - .image_info.image_max_size = - ARM_TB_FW_CONFIG_LIMIT - ARM_TB_FW_CONFIG_BASE - }; + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; - VERBOSE("BL1: Loading TB_FW_CONFIG\n"); - err = load_auth_image(TB_FW_CONFIG_ID, &arm_tb_fw_info.image_info); - if (err != 0) { - /* Return if TB_FW_CONFIG is not loaded */ - VERBOSE("Failed to load TB_FW_CONFIG\n"); - return; - } - - /* At this point we know that a DTB is indeed available */ - config_base = arm_tb_fw_info.image_info.image_base; - tb_fw_cfg_dtb = (void *)config_base; + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); - /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */ - desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(desc != NULL); - desc->ep_info.args.arg0 = config_base; + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; - INFO("BL1: TB_FW_CONFIG loaded at address = 0x%lx\n", config_base); + /* + * If tb_fw_cfg_dtb==NULL then DTB is not present for the current + * platform. As such, we cannot write to the DTB at all and pass + * measured data. + */ + if (tb_fw_cfg_dtb == 0UL) { + panic(); + } -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - int tb_fw_node; - uint32_t disable_auth = 0; + /* Calculate hash */ + err = crypto_mod_calc_hash(MBEDTLS_MD_ID, + (void *)image_info.image_base, + image_info.image_size, hash_data); + if (err != 0) { + ERROR("%scalculate%s\n", "BL1: unable to ", + " BL2 hash"); + panic(); + } - err = arm_dyn_tb_fw_cfg_init((void *)config_base, &tb_fw_node); + err = arm_set_bl2_hash_info((void *)tb_fw_cfg_dtb, hash_data); if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded\n"); + ERROR("%swrite%sdata%s\n", "BL1: unable to ", + " BL2 hash ", "to DTB\n"); panic(); } - err = arm_dyn_get_disable_auth((void *)config_base, tb_fw_node, &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif + /* + * Ensure that the info written to the DTB is visible to other + * images. It's critical because BL2 won't be able to proceed + * without the heap info and its hash data. + */ + flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize((void *)tb_fw_cfg_dtb)); } /* - * BL2 utility function to set the address of TB_FW_CONFIG passed from BL1. + * Reads TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB. + * Executed only from BL2. */ -void arm_bl2_set_tb_cfg_addr(void *dtb) +void arm_bl2_get_hash(void *data) { - assert(dtb != NULL); - tb_fw_cfg_dtb = dtb; + const void *bl2_hash; + + assert(data != NULL); + + /* Retrieve TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB */ + bl2_hash = FCONF_GET_PROPERTY(tbbr, dyn_config, bl2_hash_data); + (void)memcpy(data, bl2_hash, TCG_DIGEST_SIZE); } +#endif /* MEASURED_BOOT */ +#endif /* TRUSTED_BOARD_BOOT */ /* * BL2 utility function to initialize dynamic configuration specified by - * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if - * specified in TB_FW_CONFIG. + * FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if + * specified in FW_CONFIG. */ void arm_bl2_dyn_cfg_init(void) { - int err = 0, tb_fw_node; unsigned int i; bl_mem_params_node_t *cfg_mem_params = NULL; - uint64_t image_base; + uintptr_t image_base; uint32_t image_size; const unsigned int config_ids[] = { HW_CONFIG_ID, SOC_FW_CONFIG_ID, NT_FW_CONFIG_ID, -#ifdef SPD_tspd - /* Currently tos_fw_config is only present for TSP */ +#if defined(SPD_tspd) || defined(SPD_spmd) + /* tos_fw_config is only present for TSPD/SPMD */ TOS_FW_CONFIG_ID #endif }; - if (tb_fw_cfg_dtb == NULL) { - VERBOSE("No TB_FW_CONFIG specified\n"); - return; - } - - err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node); - if (err < 0) { - ERROR("Invalid TB_FW_CONFIG passed from BL1\n"); - panic(); - } + const struct dyn_cfg_dtb_info_t *dtb_info; /* Iterate through all the fw config IDs */ for (i = 0; i < ARRAY_SIZE(config_ids); i++) { /* Get the config load address and size from TB_FW_CONFIG */ cfg_mem_params = get_bl_mem_params_node(config_ids[i]); if (cfg_mem_params == NULL) { - VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n"); + VERBOSE("%sHW_CONFIG in bl_mem_params_node\n", + "Couldn't find "); continue; } - err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node, - config_ids[i], &image_base, &image_size); - if (err < 0) { - VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", - config_ids[i]); + dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]); + if (dtb_info == NULL) { + VERBOSE("%sconfig_id %d load info in TB_FW_CONFIG\n", + "Couldn't find ", config_ids[i]); continue; } + image_base = dtb_info->config_addr; + image_size = dtb_info->config_max_size; + /* * Do some runtime checks on the load addresses of soc_fw_config, * tos_fw_config, nt_fw_config. This is not a comprehensive check @@ -238,32 +243,34 @@ void arm_bl2_dyn_cfg_init(void) */ if (config_ids[i] != HW_CONFIG_ID) { - if (check_uptr_overflow(image_base, image_size)) + if (check_uptr_overflow(image_base, image_size)) { continue; - + } #ifdef BL31_BASE /* Ensure the configs don't overlap with BL31 */ if ((image_base >= BL31_BASE) && - (image_base <= BL31_LIMIT)) + (image_base <= BL31_LIMIT)) { continue; + } #endif /* Ensure the configs are loaded in a valid address */ - if (image_base < ARM_BL_RAM_BASE) + if (image_base < ARM_BL_RAM_BASE) { continue; + } #ifdef BL32_BASE /* * If BL32 is present, ensure that the configs don't * overlap with it. */ if ((image_base >= BL32_BASE) && - (image_base <= BL32_LIMIT)) + (image_base <= BL32_LIMIT)) { continue; + } #endif } - - cfg_mem_params->image_info.image_base = (uintptr_t)image_base; - cfg_mem_params->image_info.image_max_size = image_size; + cfg_mem_params->image_info.image_base = image_base; + cfg_mem_params->image_info.image_max_size = (uint32_t)image_size; /* * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from @@ -271,16 +278,4 @@ void arm_bl2_dyn_cfg_init(void) */ cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; } - -#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH) - uint32_t disable_auth = 0; - - err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node, - &disable_auth); - if (err < 0) - return; - - if (disable_auth == 1) - dyn_disable_auth(); -#endif } |