diff options
author | Tamas Ban <tamas.ban@arm.com> | 2018-09-18 08:09:45 +0100 |
---|---|---|
committer | Tamas Ban <tamas.ban@arm.com> | 2018-12-05 16:04:49 +0100 |
commit | a9de4a6e9caecc6b1f9be038016686149eefa9f9 (patch) | |
tree | 435770d6bf3ac2f65aef1328f7f9d2d97aee5980 | |
parent | 361e5a837f3ceffa40ec4b4217eec032ffe215e3 (diff) | |
download | trusted-firmware-m-a9de4a6e9caecc6b1f9be038016686149eefa9f9.tar.gz |
Boot: Save boot status to shared data area
Details:
- PSA requirement: Attestation service must include
the measured boot status to attestation token. Secure
bootloader measuring the runtime SW (calculatinig its hash)
ans shares the measurements with runtime SW through a shared
memory area.
- add new functions to save the boot status in TLV
encoded format to the shared data area
- save combined (S+NS) image hash to boot status
Change-Id: I4f7b4f134294aea75fe5bce10cd98c74614c32e8
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
-rw-r--r-- | bl2/ext/mcuboot/CMakeLists.txt | 5 | ||||
-rw-r--r-- | bl2/ext/mcuboot/bl2_main.c | 1 | ||||
-rw-r--r-- | bl2/ext/mcuboot/bootutil/src/loader.c | 17 | ||||
-rw-r--r-- | bl2/include/boot_record.h | 54 | ||||
-rw-r--r-- | bl2/include/tfm_boot_status.h | 86 | ||||
-rw-r--r-- | bl2/src/boot_record.c | 96 |
6 files changed, 255 insertions, 4 deletions
diff --git a/bl2/ext/mcuboot/CMakeLists.txt b/bl2/ext/mcuboot/CMakeLists.txt index 17135803c0..d488825b27 100644 --- a/bl2/ext/mcuboot/CMakeLists.txt +++ b/bl2/ext/mcuboot/CMakeLists.txt @@ -58,7 +58,8 @@ else() endif() #Append all our source files to global lists. -list(APPEND ALL_SRC_C "${MCUBOOT_DIR}/bl2_main.c" +list(APPEND ALL_SRC_C + "${MCUBOOT_DIR}/bl2_main.c" "${MCUBOOT_DIR}/flash_map.c" "${MCUBOOT_DIR}/keys.c" "${MCUBOOT_DIR}/bootutil/src/loader.c" @@ -66,6 +67,7 @@ list(APPEND ALL_SRC_C "${MCUBOOT_DIR}/bl2_main.c" "${MCUBOOT_DIR}/bootutil/src/image_validate.c" "${MCUBOOT_DIR}/bootutil/src/image_rsa.c" "${MCUBOOT_DIR}/bootutil/src/caps.c" + "${TFM_ROOT_DIR}/bl2/src/boot_record.c" ) #Define location of mbedtls source, build, and installation directory. @@ -92,6 +94,7 @@ include(${TFM_ROOT_DIR}/BuildMbedtls.cmake) #Setting include directories embedded_target_include_directories(TARGET ${PROJECT_NAME} PATH ${TFM_ROOT_DIR} ABSOLUTE APPEND) +embedded_target_include_directories(TARGET ${PROJECT_NAME} PATH ${TFM_ROOT_DIR}/bl2/include ABSOLUTE APPEND) embedded_target_include_directories(TARGET ${PROJECT_NAME} PATH ${TFM_ROOT_DIR}/bl2/ext/mcuboot/include ABSOLUTE APPEND) embedded_target_include_directories(TARGET ${PROJECT_NAME} PATH ${TFM_ROOT_DIR}/bl2/ext/mcuboot/bootutil/include/ ABSOLUTE APPEND) embedded_target_include_directories(TARGET ${PROJECT_NAME} PATH ${MBEDTLS_INSTALL_DIR}/include ABSOLUTE APPEND) diff --git a/bl2/ext/mcuboot/bl2_main.c b/bl2/ext/mcuboot/bl2_main.c index 42db36f797..79e5eec4ca 100644 --- a/bl2/ext/mcuboot/bl2_main.c +++ b/bl2/ext/mcuboot/bl2_main.c @@ -27,6 +27,7 @@ #include "bootutil/image.h" #include "bootutil/bootutil.h" #include "flash_map/flash_map.h" +#include "bl2/include/boot_record.h" /* Avoids the semihosting issue */ #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) diff --git a/bl2/ext/mcuboot/bootutil/src/loader.c b/bl2/ext/mcuboot/bootutil/src/loader.c index c268d937b2..888118efb5 100644 --- a/bl2/ext/mcuboot/bootutil/src/loader.c +++ b/bl2/ext/mcuboot/bootutil/src/loader.c @@ -38,6 +38,8 @@ #include "bootutil/bootutil.h" #include "bootutil/image.h" #include "bootutil_priv.h" +#include "bl2/include/tfm_boot_status.h" +#include "bl2/include/boot_record.h" #define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_INFO #include "bootutil/bootutil_log.h" @@ -249,12 +251,12 @@ boot_read_sectors(void) * Validate image hash/signature in a slot. */ static int -boot_image_check(struct image_header *hdr, const struct flash_area *fap) +boot_image_check(struct image_header *hdr, const struct flash_area *fap, uint8_t *out_hash) { static uint8_t tmpbuf[BOOT_TMPBUF_SZ]; if (bootutil_img_validate(hdr, fap, tmpbuf, BOOT_TMPBUF_SZ, - NULL, 0, NULL)) { + NULL, 0, out_hash)) { return BOOT_EBADIMAGE; } return 0; @@ -265,6 +267,7 @@ boot_validate_slot(int slot) { const struct flash_area *fap; struct image_header *hdr; + uint8_t hash[32]; int rc; hdr = boot_img_hdr(&boot_data, slot); @@ -278,7 +281,8 @@ boot_validate_slot(int slot) return BOOT_EFLASH; } - if ((hdr->ih_magic != IMAGE_MAGIC || boot_image_check(hdr, fap) != 0)) { + if ((hdr->ih_magic != IMAGE_MAGIC || + boot_image_check(hdr, fap, hash) != 0)) { if (slot != 0) { rc = flash_area_erase(fap, 0, fap->fa_size); if(rc != 0) { @@ -292,6 +296,13 @@ boot_validate_slot(int slot) BOOT_LOG_ERR("Authentication failed! Image in slot %d is not valid.", slot); return -1; + } else { + if (0 != boot_add_data_to_shared_area(TLV_MAJOR_IAS, + TLV_MINOR_IAS_S_NS_SHA256, + sizeof(hash), + hash)) { + BOOT_LOG_ERR("Failed to add data to shared area"); + } } flash_area_close(fap); diff --git a/bl2/include/boot_record.h b/bl2/include/boot_record.h new file mode 100644 index 0000000000..ab71a48629 --- /dev/null +++ b/bl2/include/boot_record.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __BOOT_RECORD_H__ +#define __BOOT_RECORD_H__ + +#include <stdint.h> +#include <stddef.h> +#include <limits.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \enum shared_data_err_t + * + * \brief Return values for adding data entry to shared memory area + */ +enum shared_memory_err_t { + SHARED_MEMORY_OK = 0, + SHARED_MEMORY_OVERFLOW = 1, + SHARED_MEMORY_OVERWRITE = 2, + + /* This is used to force the maximum size */ + TLV_TYPE_MAX = INT_MAX +}; + +/*! + * \brief Add a data item to the shared data area between bootloader and + * runtime SW + * + * \param[in] major_type TLV major type, identify consumer + * \param[in] minor_type TLV minor type, identify TLV type + * \param[in] size length of added data + * \param[in] data pointer to data + * + * \return Returns error code as specified in \ref shared_memory_err_t + */ +enum shared_memory_err_t +boot_add_data_to_shared_area(uint8_t major_type, + uint8_t minor_type, + size_t size, + const uint8_t *data); + +#ifdef __cplusplus +} +#endif + +#endif /* __BOOT_RECORD_H__ */ diff --git a/bl2/include/tfm_boot_status.h b/bl2/include/tfm_boot_status.h new file mode 100644 index 0000000000..30a7b1c2cc --- /dev/null +++ b/bl2/include/tfm_boot_status.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __TFM_BOOT_STATUS_H__ +#define __TFM_BOOT_STATUS_H__ + +#include <stdint.h> +#include <stddef.h> + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Major numbers to identify the consumer of shared data in runtime SW */ +#define TLV_MAJOR_CORE 0x0 +#define TLV_MAJOR_IAS 0x1 + +/* PSA Root of Trust */ +#define TLV_MINOR_IAS_PRoT_SHA256 0x00 +#define TLV_MINOR_IAS_PRoT_SW_VERSION 0x01 +#define TLV_MINOR_IAS_PRoT_EPOCH 0x02 + +/* Application Root of Trust */ +#define TLV_MINOR_IAS_ARoT_SHA256 0x03 +#define TLV_MINOR_IAS_ARoT_SW_VERSION 0x04 +#define TLV_MINOR_IAS_ARoT_EPOCH 0x05 + +/* Non-secure processing environment: single non-secure image */ +#define TLV_MINOR_IAS_NSPE_SHA256 0x06 +#define TLV_MINOR_IAS_NSPE_SW_VERSION 0x07 +#define TLV_MINOR_IAS_NSPE_EPOCH 0x08 + +/* ARoT + PRoT: single secure image */ +#define TLV_MINOR_IAS_S_SHA256 0x09 +#define TLV_MINOR_IAS_S_SW_VERSION 0x0a +#define TLV_MINOR_IAS_S_EPOCH 0x0b + +/* S + NS: combined secure and non-secure image */ +#define TLV_MINOR_IAS_S_NS_SHA256 0x0c +#define TLV_MINOR_IAS_S_NS_SW_VERSION 0x0d +#define TLV_MINOR_IAS_S_NS_EPOCH 0x0e + +#define SHARED_DATA_TLV_INFO_MAGIC 0x2016 + +/** + * Shared data TLV header. All fields in little endian. + * + * --------------------------- + * | tlv_magic | tlv_tot_len | + * --------------------------- + */ +struct shared_data_tlv_header { + uint16_t tlv_magic; + uint16_t tlv_tot_len; /* size of whole TLV area (including this header) */ +}; + +#define SHARED_DATA_HEADER_SIZE sizeof(struct shared_data_tlv_header) + +/** + * Shared data TLV entry header format. All fields in little endian. + * + * --------------------------------------------- + * | tlv_major_type | tlv_minor_type | tlv_len | + * --------------------------------------------- + * | Raw data | + * --------------------------------------------- + */ +struct shared_data_tlv_entry { + uint8_t tlv_major_type; + uint8_t tlv_minor_type; + uint16_t tlv_len; /* size of single TLV entry (including this header). */ +}; + +#define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry) +#define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE) + +#ifdef __cplusplus +} +#endif + +#endif /* __TFM_BOOT_STATUS_H__ */ diff --git a/bl2/src/boot_record.c b/bl2/src/boot_record.c new file mode 100644 index 0000000000..e11059ac84 --- /dev/null +++ b/bl2/src/boot_record.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include "boot_record.h" +#include "tfm_boot_status.h" +#include "target.h" +#include <stdint.h> +#include <string.h> + +/*! + * \var shared_memory_init_done + * + * \brief Indicates whether shared memory area was already initialized. + * + */ +static uint32_t shared_memory_init_done; + +/*! + * \def SHARED_MEMORY_UNINITIALZED + * + * \brief Indicates that shared memory is uninitialized. + */ +#define SHARED_MEMORY_UNINITIALZED (0u) + +/*! + * \def SHARED_MEMORY_INITIALZED + * + * \brief Indicates that shared memory was already initialized. + */ +#define SHARED_MEMORY_INITIALZED (1u) + +enum shared_memory_err_t +boot_add_data_to_shared_area(uint8_t major_type, + uint8_t minor_type, + size_t size, + const uint8_t *data) +{ + struct shared_data_tlv_entry tlv_entry = {0}; + struct shared_data_tlv_header *tlv_header; + uint8_t *next_tlv; + uintptr_t tlv_end, offset; + + tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE; + + /* Check whether first time to call this function. If does then initialise + * shared data area. + */ + if (shared_memory_init_done == SHARED_MEMORY_UNINITIALZED) { + memset((void *)BOOT_TFM_SHARED_DATA_BASE, 0, BOOT_TFM_SHARED_DATA_SIZE); + tlv_header->tlv_magic = SHARED_DATA_TLV_INFO_MAGIC; + tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE; + shared_memory_init_done = SHARED_MEMORY_INITIALZED; + } + + /* Check whether TLV entry is already added. + * Get the boundaries of TLV section + */ + tlv_end = BOOT_TFM_SHARED_DATA_BASE + tlv_header->tlv_tot_len; + offset = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE; + + /* Iterates over the TLV section looks for the same entry if found then + * returns with error: SHARED_MEMORY_OVERWRITE + */ + for(; offset < tlv_end; offset += tlv_entry.tlv_len) { + tlv_entry = *((struct shared_data_tlv_entry *)offset); + if (tlv_entry.tlv_major_type == major_type && + tlv_entry.tlv_minor_type == minor_type ) { + return SHARED_MEMORY_OVERWRITE; + } + } + + /* Add TLV entry */ + tlv_entry.tlv_major_type = major_type; + tlv_entry.tlv_minor_type = minor_type; + tlv_entry.tlv_len = SHARED_DATA_ENTRY_SIZE(size); + + /* Verify overflow of shared area */ + if ((tlv_header->tlv_tot_len + tlv_entry.tlv_len) > + BOOT_TFM_SHARED_DATA_SIZE){ + return SHARED_MEMORY_OVERFLOW; + } + + next_tlv = (uint8_t *)tlv_header + tlv_header->tlv_tot_len; + memcpy(next_tlv, &tlv_entry, SHARED_DATA_ENTRY_HEADER_SIZE); + + next_tlv += SHARED_DATA_ENTRY_HEADER_SIZE; + memcpy(next_tlv, data, size); + + tlv_header->tlv_tot_len = tlv_header->tlv_tot_len + tlv_entry.tlv_len; + + return SHARED_MEMORY_OK; +} |