diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h index db98b68..6066af6 100644 --- a/include/lib/fconf/fconf_tbbr_getter.h +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -23,6 +23,9 @@ uint32_t disable_auth; void *mbedtls_heap_addr; size_t mbedtls_heap_size; +#if MEASURED_BOOT + uint8_t bl2_hash_data[TCG_DIGEST_SIZE]; +#endif }; extern struct tbbr_dyn_config_t tbbr_dyn_config; diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 680d354..139145b 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -81,7 +81,7 @@ ARM_SCP_TZC_DRAM1_SIZE) #define ARM_SCP_TZC_DRAM1_SIZE PLAT_ARM_SCP_TZC_DRAM1_SIZE #define ARM_SCP_TZC_DRAM1_END (ARM_SCP_TZC_DRAM1_BASE + \ - ARM_SCP_TZC_DRAM1_SIZE - 1) + ARM_SCP_TZC_DRAM1_SIZE - 1U) /* * Define a 2MB region within the TZC secured DRAM for use by EL3 runtime @@ -92,7 +92,7 @@ #define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - ARM_EL3_TZC_DRAM1_SIZE) #define ARM_EL3_TZC_DRAM1_SIZE UL(0x00200000) /* 2 MB */ #define ARM_EL3_TZC_DRAM1_END (ARM_EL3_TZC_DRAM1_BASE + \ - ARM_EL3_TZC_DRAM1_SIZE - 1) + ARM_EL3_TZC_DRAM1_SIZE - 1U) #define ARM_AP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \ ARM_DRAM1_SIZE - \ @@ -101,7 +101,7 @@ (ARM_SCP_TZC_DRAM1_SIZE + \ ARM_EL3_TZC_DRAM1_SIZE)) #define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \ - ARM_AP_TZC_DRAM1_SIZE - 1) + ARM_AP_TZC_DRAM1_SIZE - 1U) /* Define the Access permissions for Secure peripherals to NS_DRAM */ #if ARM_CRYPTOCELL_INTEG @@ -148,17 +148,17 @@ #define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \ ARM_TZC_DRAM1_SIZE) #define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \ - ARM_NS_DRAM1_SIZE - 1) + ARM_NS_DRAM1_SIZE - 1U) #define ARM_DRAM1_BASE ULL(0x80000000) #define ARM_DRAM1_SIZE ULL(0x80000000) #define ARM_DRAM1_END (ARM_DRAM1_BASE + \ - ARM_DRAM1_SIZE - 1) + ARM_DRAM1_SIZE - 1U) #define ARM_DRAM2_BASE PLAT_ARM_DRAM2_BASE #define ARM_DRAM2_SIZE PLAT_ARM_DRAM2_SIZE #define ARM_DRAM2_END (ARM_DRAM2_BASE + \ - ARM_DRAM2_SIZE - 1) + ARM_DRAM2_SIZE - 1U) #define ARM_IRQ_SEC_PHY_TIMER 29 diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 3625530..95fc18e 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -235,8 +235,20 @@ #if MEASURED_BOOT /* Measured boot related functions */ -void arm_bl1_set_bl2_hash(image_desc_t *image_desc); +void arm_bl1_set_bl2_hash(const image_desc_t *image_desc); +void arm_bl2_get_hash(void *data); +int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, + size_t log_size); +int arm_set_nt_fw_info(uintptr_t config_base, +/* + * Currently OP-TEE does not support reading DTBs from Secure memory + * and this option should be removed when feature is supported. + */ +#ifdef SPD_opteed + uintptr_t log_addr, #endif + size_t log_size, uintptr_t *ns_log_addr); +#endif /* MEASURED_BOOT */ /* * Free the memory storing initialization code only used during an images boot diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 720c259..658b423 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -175,6 +175,14 @@ int bl1_plat_handle_pre_image_load(unsigned int image_id); int bl1_plat_handle_post_image_load(unsigned int image_id); +#if MEASURED_BOOT +/* + * Calculates and writes BL2 hash data to the platform's defined location. + * For ARM platforms the data are written to TB_FW_CONFIG DTB. + */ +void bl1_plat_set_bl2_hash(const image_desc_t *image_desc); +#endif + /******************************************************************************* * Mandatory BL2 functions ******************************************************************************/ @@ -190,11 +198,13 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id); int bl2_plat_handle_post_image_load(unsigned int image_id); - /******************************************************************************* * Optional BL2 functions (may be overridden) ******************************************************************************/ - +#if MEASURED_BOOT +/* Read TCG_DIGEST_SIZE bytes of BL2 hash data */ +void bl2_plat_get_hash(void *data); +#endif /******************************************************************************* * Mandatory BL2 at EL3 functions: Must be implemented if BL2_AT_EL3 image is @@ -204,7 +214,6 @@ u_register_t arg2, u_register_t arg3); void bl2_el3_plat_arch_setup(void); - /******************************************************************************* * Optional BL2 at EL3 functions (may be overridden) ******************************************************************************/ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index fd60c2b..80f3b32 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -37,6 +37,9 @@ #pragma weak bl2_platform_setup #pragma weak bl2_plat_arch_setup #pragma weak bl2_plat_sec_mem_layout +#if MEASURED_BOOT +#pragma weak bl2_plat_get_hash +#endif #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ bl2_tzram_layout.total_base, \ @@ -225,3 +228,11 @@ { return arm_bl2_plat_handle_post_image_load(image_id); } + +#if MEASURED_BOOT +/* Read TCG_DIGEST_SIZE bytes of BL2 hash data */ +void bl2_plat_get_hash(void *data) +{ + arm_bl2_get_hash(data); +} +#endif diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 633445b..b31870b 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -23,6 +23,7 @@ #include #include #include + #include #include @@ -98,13 +99,14 @@ tb_fw_cfg_dtb = tb_fw_config_info->config_addr; if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) { - /* As libfdt use void *, we can't avoid this cast */ + /* 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 @@ -124,13 +126,13 @@ #if MEASURED_BOOT /* - * Puts the BL2 hash data to TB_FW_CONFIG DTB. + * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. * Executed only from BL1. */ -void arm_bl1_set_bl2_hash(image_desc_t *image_desc) +void arm_bl1_set_bl2_hash(const image_desc_t *image_desc) { unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; - image_info_t image_info = image_desc->image_info; + const image_info_t image_info = image_desc->image_info; uintptr_t tb_fw_cfg_dtb; int err; const struct dyn_cfg_dtb_info_t *tb_fw_config_info; @@ -154,13 +156,15 @@ (void *)image_info.image_base, image_info.image_size, hash_data); if (err != 0) { - ERROR("BL1: unable to calculate BL2 hash\n"); + ERROR("%scalculate%s\n", "BL1: unable to ", + " BL2 hash"); panic(); } err = arm_set_bl2_hash_info((void *)tb_fw_cfg_dtb, hash_data); if (err < 0) { - ERROR("BL1: unable to write BL2 hash data to DTB\n"); + ERROR("%swrite%sdata%s\n", "BL1: unable to ", + " BL2 hash ", "to DTB\n"); panic(); } @@ -171,6 +175,21 @@ */ flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize((void *)tb_fw_cfg_dtb)); } + +/* + * Reads TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB. + * Executed only from BL2. + */ +void arm_bl2_get_hash(void *data) +{ + 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 */ @@ -202,14 +221,15 @@ /* 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; } dtb_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, config_ids[i]); if (dtb_info == NULL) { - VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n", - config_ids[i]); + VERBOSE("%sconfig_id %d load info in TB_FW_CONFIG\n", + "Couldn't find ", config_ids[i]); continue; } @@ -223,30 +243,32 @@ */ 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 = image_base; cfg_mem_params->image_info.image_max_size = (uint32_t)image_size; diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index f110e3b..5f20c8d 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -6,9 +6,13 @@ #include +#if MEASURED_BOOT +#include +#endif +#include + #include -#include #include #include @@ -17,6 +21,15 @@ #if MEASURED_BOOT #define DTB_PROP_BL2_HASH_DATA "bl2_hash_data" +#ifdef SPD_opteed +/* + * Currently OP-TEE does not support reading DTBs from Secure memory + * and this property should be removed when this feature is supported. + */ +#define DTB_PROP_HW_SM_LOG_ADDR "tpm_event_log_sm_addr" +#endif +#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr" +#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size" static int dtb_root = -1; #endif /* MEASURED_BOOT */ @@ -37,18 +50,19 @@ /* Check if the pointer to DT is correct */ if (fdt_check_header(dtb) != 0) { - WARN("Invalid DTB file passed as TB_FW_CONFIG\n"); + WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG"); return -1; } /* Assert the node offset point to "arm,tb_fw" compatible property */ *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"); if (*node < 0) { - WARN("The compatible property `arm,tb_fw` not found in the config\n"); + WARN("The compatible property '%s' not%s", "arm,tb_fw", + " found in the config\n"); return -1; } - VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n"); + VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n"); return 0; } @@ -76,7 +90,8 @@ */ int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root); if (err < 0) { - ERROR("Invalid TB_FW_CONFIG loaded. Unable to get root node\n"); + ERROR("Invalid%s loaded. Unable to get root node\n", + " TB_FW_CONFIG"); return -1; } @@ -90,16 +105,16 @@ err = fdtw_write_inplace_cells(dtb, dtb_root, DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr); if (err < 0) { - ERROR("Unable to write DTB property %s\n", - DTB_PROP_MBEDTLS_HEAP_ADDR); + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR); return -1; } err = fdtw_write_inplace_cells(dtb, dtb_root, DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size); if (err < 0) { - ERROR("Unable to write DTB property %s\n", - DTB_PROP_MBEDTLS_HEAP_SIZE); + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE); return -1; } @@ -124,7 +139,165 @@ /* * Write the BL2 hash data in the DTB. */ - return fdtw_write_inplace_bytes(dtb, dtb_root, DTB_PROP_BL2_HASH_DATA, + return fdtw_write_inplace_bytes(dtb, dtb_root, + DTB_PROP_BL2_HASH_DATA, TCG_DIGEST_SIZE, data); } + +/* + * Write the Event Log address and its size in the DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +static int arm_set_event_log_info(uintptr_t config_base, +#ifdef SPD_opteed + uintptr_t sm_log_addr, +#endif + uintptr_t log_addr, size_t log_size) +{ + /* As libfdt uses void *, we can't avoid this cast */ + void *dtb = (void *)config_base; + const char *compatible = "arm,tpm_event_log"; + int err, node; + + /* + * Verify that the DTB is valid, before attempting to write to it, + * and get the DTB root node. + */ + + /* Check if the pointer to DT is correct */ + err = fdt_check_header(dtb); + if (err < 0) { + WARN("Invalid DTB file passed\n"); + return err; + } + + /* Assert the node offset point to compatible property */ + node = fdt_node_offset_by_compatible(dtb, -1, compatible); + if (node < 0) { + WARN("The compatible property '%s' not%s", compatible, + " found in the config\n"); + return node; + } + + VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n"); + +#ifdef SPD_opteed + if (sm_log_addr != 0UL) { + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_SM_LOG_ADDR); + return err; + } + } +#endif + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_LOG_ADDR, 2, &log_addr); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_LOG_ADDR); + return err; + } + + err = fdtw_write_inplace_cells(dtb, node, + DTB_PROP_HW_LOG_SIZE, 1, &log_size); + if (err < 0) { + ERROR("%sDTB property '%s'\n", + "Unable to write ", DTB_PROP_HW_LOG_SIZE); + } else { + /* + * Ensure that the info written to the DTB is visible + * to other images. + */ + flush_dcache_range(config_base, fdt_totalsize(dtb)); + } + + return err; +} + +/* + * This function writes the Event Log address and its size + * in the TOS_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, + size_t log_size) +{ + int err; + + assert(config_base != 0UL); + assert(log_addr != 0UL); + + /* Write the Event Log address and its size in the DTB */ + err = arm_set_event_log_info(config_base, +#ifdef SPD_opteed + 0UL, +#endif + log_addr, log_size); + if (err < 0) { + ERROR("%sEvent Log data to TOS_FW_CONFIG\n", + "Unable to write "); + } + + return err; +} + +/* + * This function writes the Event Log address and its size + * in the NT_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_nt_fw_info(uintptr_t config_base, +#ifdef SPD_opteed + uintptr_t log_addr, +#endif + size_t log_size, uintptr_t *ns_log_addr) +{ + uintptr_t ns_addr; + const bl_mem_params_node_t *cfg_mem_params; + int err; + + assert(config_base != 0UL); + assert(ns_log_addr != NULL); + + /* Get the config load address and size from NT_FW_CONFIG */ + cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID); + assert(cfg_mem_params != NULL); + + /* Calculate Event Log address in Non-secure memory */ + ns_addr = cfg_mem_params->image_info.image_base + + cfg_mem_params->image_info.image_max_size; + + /* Check for memory space */ + if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) { + return -1; + } + + /* Write the Event Log address and its size in the DTB */ + err = arm_set_event_log_info(config_base, +#ifdef SPD_opteed + log_addr, +#endif + ns_addr, log_size); + + /* Return Event Log address in Non-secure memory */ + *ns_log_addr = (err < 0) ? 0UL : ns_addr; + return err; +} #endif /* MEASURED_BOOT */