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>
This commit is contained in:
Alexei Fedorov 2020-03-20 18:38:55 +00:00
parent d9f405edeb
commit 0ab496458b
8 changed files with 187 additions and 8 deletions

View File

@ -367,6 +367,10 @@ DTC_FLAGS += -I dts -O dtb
DTC_CPPFLAGS += -P -nostdinc -Iinclude -Ifdts -undef \
-x assembler-with-cpp $(DEFINES)
ifeq ($(MEASURED_BOOT),1)
DTC_CPPFLAGS += -DMEASURED_BOOT -DBL2_HASH_SIZE=${TCG_DIGEST_SIZE}
endif
################################################################################
# Common sources and include directories
################################################################################

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -75,10 +75,19 @@ endif
ifeq (${HASH_ALG}, sha384)
TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384
MBEDTLS_MD_ID := MBEDTLS_MD_SHA384
TPM_ALG_ID := TPM_ALG_SHA384
TCG_DIGEST_SIZE := 48
else ifeq (${HASH_ALG}, sha512)
TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512
TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512
MBEDTLS_MD_ID := MBEDTLS_MD_SHA512
TPM_ALG_ID := TPM_ALG_SHA512
TCG_DIGEST_SIZE := 64
else
TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256
MBEDTLS_MD_ID := MBEDTLS_MD_SHA256
TPM_ALG_ID := TPM_ALG_SHA256
TCG_DIGEST_SIZE := 32
endif
ifeq (${TF_MBEDTLS_KEY_ALG},ecdsa)
@ -103,6 +112,11 @@ $(eval $(call add_define,TF_MBEDTLS_KEY_SIZE))
$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
$(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM))
# Set definitions for measured boot driver
$(eval $(call add_define,MBEDTLS_MD_ID))
$(eval $(call add_define,TPM_ALG_ID))
$(eval $(call add_define,TCG_DIGEST_SIZE))
$(eval $(call MAKE_LIB,mbedtls))
endif

View File

@ -14,4 +14,8 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node);
int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr,
size_t heap_size);
#if MEASURED_BOOT
int arm_set_bl2_hash_info(void *dtb, void *data);
#endif
#endif /* ARM_DYN_CFG_HELPERS_H */

View File

@ -238,6 +238,11 @@ void arm_bl2_dyn_cfg_init(void);
void arm_bl1_set_mbedtls_heap(void);
int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
#if MEASURED_BOOT
/* Measured boot related functions */
void arm_bl1_set_bl2_hash(image_desc_t *image_desc);
#endif
/*
* Free the memory storing initialization code only used during an images boot
* time so it can be reclaimed for runtime data

View File

@ -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 */
};
/*

View File

@ -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 */

View File

@ -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 */
/*

View File

@ -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 */