aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamas Ban <tamas.ban@arm.com>2018-09-18 08:09:45 +0100
committerTamas Ban <tamas.ban@arm.com>2018-12-05 16:04:49 +0100
commita9de4a6e9caecc6b1f9be038016686149eefa9f9 (patch)
tree435770d6bf3ac2f65aef1328f7f9d2d97aee5980
parent361e5a837f3ceffa40ec4b4217eec032ffe215e3 (diff)
downloadtrusted-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.txt5
-rw-r--r--bl2/ext/mcuboot/bl2_main.c1
-rw-r--r--bl2/ext/mcuboot/bootutil/src/loader.c17
-rw-r--r--bl2/include/boot_record.h54
-rw-r--r--bl2/include/tfm_boot_status.h86
-rw-r--r--bl2/src/boot_record.c96
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;
+}