aboutsummaryrefslogtreecommitdiff
path: root/bl2/src/shared_data.c
diff options
context:
space:
mode:
authorDavid Vincze <david.vincze@arm.com>2022-01-19 10:11:58 +0100
committerDavid Hu <david.hu@arm.com>2022-07-29 11:18:38 +0200
commit8c95d2a30577350dbbb3ace8d9addb15e7cb0670 (patch)
tree64a2418d6488ebf2d5ce9b69ff38ecf8bcc89211 /bl2/src/shared_data.c
parent2e5af6eb005b6c4e9544bc72e8f4200fbc5651a1 (diff)
downloadtrusted-firmware-m-8c95d2a30577350dbbb3ace8d9addb15e7cb0670.tar.gz
Boot: Save the boot measurements of BL2
These measurements are not encoded; they are shared with the measured boot secure partition in a raw format. When these measurements are used, sharing the CBOR encoded measurements from the TLV area is unnecessary. Change-Id: I61d0598123d2be964439d320b8bc7c53b00ec58e Signed-off-by: David Vincze <david.vincze@arm.com>
Diffstat (limited to 'bl2/src/shared_data.c')
-rw-r--r--bl2/src/shared_data.c214
1 files changed, 203 insertions, 11 deletions
diff --git a/bl2/src/shared_data.c b/bl2/src/shared_data.c
index b2f3e4257a..73d0f732a2 100644
--- a/bl2/src/shared_data.c
+++ b/bl2/src/shared_data.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -10,6 +10,23 @@
#include "bootutil/image.h"
#include "flash_map/flash_map.h"
#include "sysflash/sysflash.h"
+#include "mcuboot_config/mcuboot_config.h"
+
+#if defined(CONFIG_TFM_BOOT_STORE_MEASUREMENTS) && !defined(MCUBOOT_MEASURED_BOOT)
+#include <stdio.h>
+#include "boot_hal.h"
+#include "boot_measurement.h"
+#include "bootutil_priv.h"
+#include "psa/crypto.h"
+
+#define MCUBOOT_HASH_ALG PSA_ALG_SHA_256
+#define MCUBOOT_HASH_SIZE (32)
+
+#ifdef MCUBOOT_HW_KEY
+#include "bootutil/crypto/sha256.h"
+#define SIG_BUF_SIZE (MCUBOOT_SIGN_RSA_LEN / 8)
+#endif
+#endif /* CONFIG_TFM_BOOT_STORE_MEASUREMENTS && !MCUBOOT_MEASURED_BOOT */
/* Firmware Update specific macros */
#define TLV_MAJOR_FWU 0x2
@@ -20,11 +37,123 @@
((uint16_t)((sw_module & MODULE_MASK) << 6) | \
(uint16_t)(claim & CLAIM_MASK))
-extern int
-boot_add_data_to_shared_area(uint8_t major_type,
- uint16_t minor_type,
- size_t size,
- const uint8_t *data);
+#ifdef TFM_PARTITION_FIRMWARE_UPDATE
+extern int boot_add_data_to_shared_area(uint8_t major_type,
+ uint16_t minor_type,
+ size_t size,
+ const uint8_t *data);
+#endif /* TFM_PARTITION_FIRMWARE_UPDATE */
+
+
+#if defined(CONFIG_TFM_BOOT_STORE_MEASUREMENTS) && !defined(MCUBOOT_MEASURED_BOOT)
+/**
+ * Collect boot measurement and available associated metadata from the
+ * TLV area of an image.
+ *
+ * @param[in] hdr Pointer to the image header stored in RAM.
+ * @param[in] fap Pointer to the flash area where image is stored.
+ * @param[out] metadata Pointer to measurement metadata structure.
+ * @param[out] measurement_buf Buffer to store the boot measurement.
+ * @param[in] measurement_buf_size As an input value it indicates the size
+ * of the measurement buffer in bytes.
+ *
+ * @return 0 on success; nonzero on failure.
+ *
+ */
+static int collect_image_measurement_and_metadata(
+ const struct image_header *hdr,
+ const struct flash_area *fap,
+ struct boot_measurement_metadata *metadata,
+ uint8_t *measurement_buf,
+ size_t measurement_buf_size)
+{
+ struct image_tlv_iter it;
+ uint32_t off;
+ uint16_t len;
+ uint16_t type;
+#ifdef MCUBOOT_HW_KEY
+ /* Few extra bytes for encoding and for public exponent. */
+ uint8_t key_buf[SIG_BUF_SIZE + 24];
+ bootutil_sha256_context sha256_ctx;
+#endif
+ int rc;
+
+ /* Copy the software version information from the image header. */
+ rc = snprintf(metadata->sw_version, sizeof(metadata->sw_version),
+ "%u.%u.%u+%u",
+ hdr->ih_ver.iv_major,
+ hdr->ih_ver.iv_minor,
+ hdr->ih_ver.iv_revision,
+ hdr->ih_ver.iv_build_num);
+ if ((rc < 0) || (rc >= sizeof(metadata->sw_version))) {
+ return -1;
+ }
+
+ /* Traverse through all of the TLVs for the required items. */
+ rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false);
+ if (rc) {
+ return rc;
+ }
+
+ while (true) {
+ rc = bootutil_tlv_iter_next(&it, &off, &len, &type);
+ if (rc < 0) {
+ return -1;
+ } else if (rc > 0) {
+ break;
+ }
+
+ if (type == IMAGE_TLV_SHA256) {
+ /* Retrieve the image hash (measurement value) from the TLV area. */
+ if (len > measurement_buf_size) {
+ return -1;
+ }
+ rc = LOAD_IMAGE_DATA(hdr, fap, off, measurement_buf, len);
+ if (rc) {
+ return -1;
+ }
+#ifdef MCUBOOT_HW_KEY
+ } else if (type == IMAGE_TLV_PUBKEY) {
+ /* Retrieve the signer ID (hash of PUBKEY) from the TLV area. */
+ if (len > sizeof(key_buf)) {
+ /* Something is wrong with the public key, proceed without
+ * the signer ID.
+ */
+ continue;
+ }
+ rc = LOAD_IMAGE_DATA(hdr, fap, off, key_buf, len);
+ if (rc) {
+ /* Proceed without this piece of data. */
+ continue;
+ }
+
+ /* Calculate the hash of the public key (signer ID). */
+ bootutil_sha256_init(&sha256_ctx);
+ bootutil_sha256_update(&sha256_ctx, key_buf, len);
+ bootutil_sha256_finish(&sha256_ctx, metadata->signer_id);
+#else
+ } else if (type == IMAGE_TLV_KEYHASH) {
+ /* Retrieve the signer ID (hash of PUBKEY) from the TLV area. */
+ if (len != MCUBOOT_HASH_SIZE) {
+ /* Something is wrong with the key hash, proceed without
+ * the signer ID.
+ */
+ continue;
+ }
+ rc = LOAD_IMAGE_DATA(hdr, fap, off,
+ metadata->signer_id, MCUBOOT_HASH_SIZE);
+ if (rc) {
+ /* Proceed without this piece of data. */
+ continue;
+ }
+#endif /* MCUBOOT_HW_KEY */
+ metadata->signer_id_size = MCUBOOT_HASH_SIZE;
+ }
+ }
+
+ return 0;
+}
+#endif /* CONFIG_TFM_BOOT_STORE_MEASUREMENTS && !MCUBOOT_MEASURED_BOOT */
/**
* Add application specific data to the shared memory area between the
@@ -38,16 +167,31 @@ boot_add_data_to_shared_area(uint8_t major_type,
int boot_save_shared_data(const struct image_header *hdr,
const struct flash_area *fap)
{
- uint16_t fwu_minor;
struct image_version image_ver;
const struct flash_area *temp_fap;
uint8_t mcuboot_image_id = 0;
uint8_t i;
+ int32_t rc;
+#ifdef TFM_PARTITION_FIRMWARE_UPDATE
+ uint16_t fwu_minor;
+#endif
+#if defined(CONFIG_TFM_BOOT_STORE_MEASUREMENTS) && !defined(MCUBOOT_MEASURED_BOOT)
+ enum boot_measurement_slot_t slot_id;
+ uint8_t image_hash[MCUBOOT_HASH_SIZE];
+ struct boot_measurement_metadata metadata = {
+ .measurement_type = MCUBOOT_HASH_ALG,
+ .sw_type = "",
+ .sw_version = "",
+ .signer_id = { 0 },
+ .signer_id_size = 0,
+ };
+#endif /* CONFIG_TFM_BOOT_STORE_MEASUREMENTS && !MCUBOOT_MEASURED_BOOT */
if (hdr == NULL || fap == NULL) {
return -1;
}
+ /* Look for the given flash area to determine the image ID. */
for (i = 0; i < MCUBOOT_IMAGE_NUMBER; i++) {
if (flash_area_open(FLASH_AREA_IMAGE_PRIMARY(i),
&temp_fap) != 0) {
@@ -66,10 +210,58 @@ int boot_save_shared_data(const struct image_header *hdr,
image_ver = hdr->ih_ver;
+#ifdef TFM_PARTITION_FIRMWARE_UPDATE
/* Currently hardcode it to 0 which indicates the full image. */
fwu_minor = SET_FWU_MINOR(mcuboot_image_id, SW_VERSION);
- return boot_add_data_to_shared_area(TLV_MAJOR_FWU,
- fwu_minor,
- sizeof(image_ver),
- (const uint8_t *)&image_ver);
+ rc = boot_add_data_to_shared_area(TLV_MAJOR_FWU,
+ fwu_minor,
+ sizeof(image_ver),
+ (const uint8_t *)&image_ver);
+ if (rc) {
+ return rc;
+ }
+#endif /* TFM_PARTITION_FIRMWARE_UPDATE */
+
+#if defined(CONFIG_TFM_BOOT_STORE_MEASUREMENTS) && !defined(MCUBOOT_MEASURED_BOOT)
+ /* Determine the index of the measurement slot. */
+ slot_id = BOOT_MEASUREMENT_SLOT_RT_0 + mcuboot_image_id;
+
+ switch (slot_id) {
+ case BOOT_MEASUREMENT_SLOT_RT_0:
+ strlcpy(metadata.sw_type, "RT_0",
+ sizeof(metadata.sw_type));
+ break;
+ case BOOT_MEASUREMENT_SLOT_RT_1:
+ strlcpy(metadata.sw_type, "RT_1",
+ sizeof(metadata.sw_type));
+ break;
+ case BOOT_MEASUREMENT_SLOT_RT_2:
+ strlcpy(metadata.sw_type, "RT_2",
+ sizeof(metadata.sw_type));
+ break;
+ default:
+ /* Proceed without this piece of data. */
+ break;
+ }
+
+ rc = collect_image_measurement_and_metadata(hdr, fap,
+ &metadata,
+ image_hash,
+ sizeof(image_hash));
+ if (rc) {
+ return rc;
+ }
+
+ /* Save the boot measurement(s) about the runtime image(s).
+ * If there are multiple images, the measurement slot will be extended
+ * with the subsequent measurements.
+ */
+ rc = boot_store_measurement((uint8_t)slot_id, image_hash,
+ sizeof(image_hash), &metadata, false);
+ if (rc) {
+ return rc;
+ }
+#endif /* CONFIG_TFM_BOOT_STORE_MEASUREMENTS && !MCUBOOT_MEASURED_BOOT */
+
+ return 0;
}