aboutsummaryrefslogtreecommitdiffstats
path: root/plat
diff options
context:
space:
mode:
authorAlexei Fedorov <Alexei.Fedorov@arm.com>2020-03-20 18:38:55 +0000
committerAlexei Fedorov <Alexei.Fedorov@arm.com>2020-03-25 16:14:26 +0000
commit0ab496458b4cf55fa4116007506d8f38884bd31f (patch)
tree0f91c27c177123c6e8d0c5060ffa8819d81a1c33 /plat
parentd9f405edebca87ef83694ce616a8e6dec93973fb (diff)
downloadplatform_external_arm-trusted-firmware-0ab496458b4cf55fa4116007506d8f38884bd31f.tar.gz
platform_external_arm-trusted-firmware-0ab496458b4cf55fa4116007506d8f38884bd31f.tar.bz2
platform_external_arm-trusted-firmware-0ab496458b4cf55fa4116007506d8f38884bd31f.zip
FVP: Add BL2 hash calculation in BL1
This patch provides support for measured boot by adding calculation of BL2 image hash in BL1 and writing these data in TB_FW_CONFIG DTB. Change-Id: Ic074a7ed19b14956719c271c805b35d147b7cec1 Signed-off-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
Diffstat (limited to 'plat')
-rw-r--r--plat/arm/board/fvp/fdts/fvp_fw_config.dts13
-rw-r--r--plat/arm/board/fvp/fvp_bl1_setup.c54
-rw-r--r--plat/arm/common/arm_dyn_cfg.c59
-rw-r--r--plat/arm/common/arm_dyn_cfg_helpers.c38
4 files changed, 158 insertions, 6 deletions
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index 704bf29cd..98ea85760 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -67,6 +67,19 @@
*/
mbedtls_heap_addr = <0x0 0x0>;
mbedtls_heap_size = <0x0>;
+
+#if MEASURED_BOOT
+ /* BL2 image hash calculated by BL1 */
+ bl2_hash_data = [
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+#if BL2_HASH_SIZE > 32
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+#if BL2_HASH_SIZE > 48
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+#endif /* > 48 */
+#endif /* > 32 */
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00];
+#endif /* MEASURED_BOOT */
};
/*
diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c
index 8f6170daa..d13cc81f3 100644
--- a/plat/arm/board/fvp/fvp_bl1_setup.c
+++ b/plat/arm/board/fvp/fvp_bl1_setup.c
@@ -1,9 +1,12 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
+
+#include <bl1/bl1.h>
#include <common/tbbr/tbbr_img_def.h>
#include <drivers/arm/smmu_v3.h>
#include <drivers/arm/sp805.h>
@@ -64,3 +67,52 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved)
while (1)
wfi();
}
+
+#if MEASURED_BOOT
+/*
+ * Implementation for bl1_plat_handle_post_image_load(). This function
+ * populates the default arguments to BL2. The BL2 memory layout structure
+ * is allocated and the calculated layout is populated in arg1 to BL2.
+ */
+int bl1_plat_handle_post_image_load(unsigned int image_id)
+{
+ meminfo_t *bl2_tzram_layout;
+ meminfo_t *bl1_tzram_layout;
+ image_desc_t *image_desc;
+ entry_point_info_t *ep_info;
+
+ if (image_id != BL2_IMAGE_ID) {
+ return 0;
+ }
+
+ /* Get the image descriptor */
+ image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+ assert(image_desc != NULL);
+
+ /* Calculate BL2 hash and set it in TB_FW_CONFIG */
+ arm_bl1_set_bl2_hash(image_desc);
+
+ /* Get the entry point info */
+ ep_info = &image_desc->ep_info;
+
+ /* Find out how much free trusted ram remains after BL1 load */
+ bl1_tzram_layout = bl1_plat_sec_mem_layout();
+
+ /*
+ * Create a new layout of memory for BL2 as seen by BL1 i.e.
+ * tell it the amount of total and free memory available.
+ * This layout is created at the first free address visible
+ * to BL2. BL2 will read the memory layout before using its
+ * memory for other purposes.
+ */
+ bl2_tzram_layout = (meminfo_t *)bl1_tzram_layout->total_base;
+
+ bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout);
+
+ ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout;
+
+ VERBOSE("BL1: BL2 memory layout address = %p\n",
+ (void *)bl2_tzram_layout);
+ return 0;
+}
+#endif /* MEASURED_BOOT */
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index df7530733..ffa2a64d8 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -15,6 +15,10 @@
#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>
@@ -87,7 +91,7 @@ void arm_bl1_set_mbedtls_heap(void)
* the default heap's address and size.
*/
- /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB*/
+ /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */
tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr);
if ((tb_fw_cfg_dtb != 0UL) && (mbedtls_heap_addr != NULL)) {
@@ -100,15 +104,68 @@ void arm_bl1_set_mbedtls_heap(void)
ERROR("BL1: unable to write shared Mbed TLS heap information 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(tb_fw_cfg_dtb, fdt_totalsize(dtb));
+#endif /* !MEASURED_BOOT */
}
}
+#if MEASURED_BOOT
+/*
+ * Puts the BL2 hash data to TB_FW_CONFIG DTB.
+ * Executed only from BL1.
+ */
+void arm_bl1_set_bl2_hash(image_desc_t *image_desc)
+{
+ unsigned char hash_data[MBEDTLS_MD_MAX_SIZE];
+ image_info_t image_info = image_desc->image_info;
+ uintptr_t tb_fw_cfg_dtb;
+ int err;
+
+ /* fconf FW_CONFIG and TB_FW_CONFIG are currently the same DTB */
+ tb_fw_cfg_dtb = FCONF_GET_PROPERTY(fconf, dtb, base_addr);
+
+ /*
+ * 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();
+ }
+
+ /* 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("BL1: unable to calculate BL2 hash\n");
+ 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");
+ panic();
+ }
+
+ /*
+ * 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));
+}
+#endif /* MEASURED_BOOT */
#endif /* TRUSTED_BOARD_BOOT */
/*
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index 909c4a671..f110e3bb6 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -15,6 +15,12 @@
#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
+#if MEASURED_BOOT
+#define DTB_PROP_BL2_HASH_DATA "bl2_hash_data"
+
+static int dtb_root = -1;
+#endif /* MEASURED_BOOT */
+
/*******************************************************************************
* Validate the tb_fw_config is a valid DTB file and returns the node offset
* to "arm,tb_fw" property.
@@ -57,17 +63,18 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
*
* Returns:
* 0 = success
- * 1 = error
+ * -1 = error
*/
int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
{
- int err, dtb_root;
-
+#if !MEASURED_BOOT
+ int dtb_root;
+#endif
/*
* Verify that the DTB is valid, before attempting to write to it,
* and get the DTB root node.
*/
- err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
+ 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");
return -1;
@@ -98,3 +105,26 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
return 0;
}
+
+#if MEASURED_BOOT
+/*
+ * This function writes the BL2 hash data in HW_FW_CONFIG DTB.
+ * When it is called, it is guaranteed that a DTB is available.
+ *
+ * This function is supposed to be called only by BL1.
+ *
+ * Returns:
+ * 0 = success
+ * < 0 = error
+ */
+int arm_set_bl2_hash_info(void *dtb, void *data)
+{
+ assert(dtb_root >= 0);
+
+ /*
+ * Write the BL2 hash data in the DTB.
+ */
+ return fdtw_write_inplace_bytes(dtb, dtb_root, DTB_PROP_BL2_HASH_DATA,
+ TCG_DIGEST_SIZE, data);
+}
+#endif /* MEASURED_BOOT */