Attest: Generalize boot satus handling
Introduce wrapper structure to simplify the handling of
boot status data.
Change-Id: I4fecbf2b346e4e773a898b6013c0b351bcf5beeb
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/bl2/include/tfm_boot_status.h b/bl2/include/tfm_boot_status.h
index dbcc6ce..f31743b 100644
--- a/bl2/include/tfm_boot_status.h
+++ b/bl2/include/tfm_boot_status.h
@@ -197,6 +197,16 @@
uint16_t tlv_len; /* size of single TLV entry (including this header). */
};
+/**
+ * \struct tfm_boot_data
+ *
+ * \brief Store the data for the runtime SW
+ */
+struct tfm_boot_data {
+ struct shared_data_tlv_header header;
+ uint8_t data[];
+};
+
#define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry)
#define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE)
diff --git a/bl2/src/boot_record.c b/bl2/src/boot_record.c
index 21c1904..263088d 100644
--- a/bl2/src/boot_record.c
+++ b/bl2/src/boot_record.c
@@ -254,26 +254,26 @@
const uint8_t *data)
{
struct shared_data_tlv_entry tlv_entry = {0};
- struct shared_data_tlv_header *tlv_header;
+ struct tfm_boot_data *boot_data;
uint8_t *next_tlv;
uintptr_t tlv_end, offset;
- tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
+ boot_data = (struct tfm_boot_data *)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;
+ boot_data->header.tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
+ boot_data->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;
+ tlv_end = BOOT_TFM_SHARED_DATA_BASE + boot_data->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
@@ -293,18 +293,18 @@
tlv_entry.tlv_len = SHARED_DATA_ENTRY_SIZE(size);
/* Verify overflow of shared area */
- if ((tlv_header->tlv_tot_len + tlv_entry.tlv_len) >
+ if ((boot_data->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;
+ next_tlv = (uint8_t *)boot_data + boot_data->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;
+ boot_data->header.tlv_tot_len += tlv_entry.tlv_len;
return SHARED_MEMORY_OK;
}
diff --git a/secure_fw/core/tfm_boot_data.c b/secure_fw/core/tfm_boot_data.c
index 59aced8..3ec8b8e 100644
--- a/secure_fw/core/tfm_boot_data.c
+++ b/secure_fw/core/tfm_boot_data.c
@@ -39,9 +39,9 @@
void tfm_core_validate_boot_data(void)
{
- struct shared_data_tlv_header *tlv_header;
+ struct tfm_boot_data *boot_data;
- tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
+ boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
/* FixMe: Enhance sanity check of shared memory area, it might be invalid:
* - temporal exposure of RAM to non-secure actors
@@ -49,7 +49,7 @@
* - version mismatch between bootloader and runtime binary
* - etc.
*/
- if (tlv_header->tlv_magic == SHARED_DATA_TLV_INFO_MAGIC) {
+ if (boot_data->header.tlv_magic == SHARED_DATA_TLV_INFO_MAGIC) {
is_boot_data_valid = BOOT_DATA_VALID;
}
}
@@ -62,7 +62,7 @@
uint8_t *ptr;
uint32_t running_partition_idx =
tfm_spm_partition_get_running_partition_idx();
- struct shared_data_tlv_header *tlv_header;
+ struct tfm_boot_data *boot_data;
struct shared_data_tlv_entry tlv_entry;
uintptr_t tlv_end, offset;
uint32_t res;
@@ -88,8 +88,8 @@
}
/* Get the boundaries of TLV section */
- tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
- tlv_end = BOOT_TFM_SHARED_DATA_BASE + tlv_header->tlv_tot_len;
+ boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
+ tlv_end = BOOT_TFM_SHARED_DATA_BASE + boot_data->header.tlv_tot_len;
offset = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE;
/* Add header to output buffer as well */
@@ -97,10 +97,10 @@
args[0] = TFM_ERROR_INVALID_PARAMETER;
return;
} else {
- tlv_header = (struct shared_data_tlv_header *)buf_start;
- tlv_header->tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
- tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE;
- ptr = (uint8_t *)tlv_header + SHARED_DATA_HEADER_SIZE;
+ boot_data = (struct tfm_boot_data *)buf_start;
+ boot_data->header.tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
+ boot_data->header.tlv_tot_len = SHARED_DATA_HEADER_SIZE;
+ ptr = boot_data->data;
}
/* Iterates over the TLV section and copy TLVs with requested major
@@ -121,7 +121,7 @@
tfm_memcpy(ptr, (const void *)offset, tlv_entry.tlv_len);
ptr += tlv_entry.tlv_len;
- tlv_header->tlv_tot_len += tlv_entry.tlv_len;
+ boot_data->header.tlv_tot_len += tlv_entry.tlv_len;
}
}
args[0] = TFM_SUCCESS;
diff --git a/secure_fw/core/tfm_secure_api.h b/secure_fw/core/tfm_secure_api.h
index 696d9cb..50f6357 100644
--- a/secure_fw/core/tfm_secure_api.h
+++ b/secure_fw/core/tfm_secure_api.h
@@ -13,6 +13,7 @@
#include "secure_utilities.h"
#include "tfm_core.h"
#include "tfm_api.h"
+#include "bl2/include/tfm_boot_status.h"
/*!
* \def __tfm_secure_gateway_attributes__
@@ -81,7 +82,8 @@
uint32_t size,
int32_t access);
-extern int32_t tfm_core_get_boot_data(uint8_t major_type, void *ptr,
+extern int32_t tfm_core_get_boot_data(uint8_t major_type,
+ struct tfm_boot_data *boot_data,
uint32_t len);
int32_t tfm_core_sfn_request(const struct tfm_sfn_req_s *desc_ptr);
diff --git a/secure_fw/core/tfm_spm_services.c b/secure_fw/core/tfm_spm_services.c
index 21246d2..7eb6165 100644
--- a/secure_fw/core/tfm_spm_services.c
+++ b/secure_fw/core/tfm_spm_services.c
@@ -156,7 +156,9 @@
}
__attribute__((naked))
-int32_t tfm_core_get_boot_data(uint8_t major_type, void *ptr, uint32_t len)
+int32_t tfm_core_get_boot_data(uint8_t major_type,
+ struct tfm_boot_data *boot_status,
+ uint32_t len)
{
__ASM(
"SVC %0\n"
diff --git a/secure_fw/services/initial_attestation/attestation.h b/secure_fw/services/initial_attestation/attestation.h
index 404fb41..f73ed0f 100644
--- a/secure_fw/services/initial_attestation/attestation.h
+++ b/secure_fw/services/initial_attestation/attestation.h
@@ -10,6 +10,7 @@
#include "psa_initial_attestation_api.h"
#include "tfm_client.h"
+#include "bl2/include/tfm_boot_status.h"
#ifdef __cplusplus
extern "C" {
@@ -34,7 +35,9 @@
* \return Returns error code as specified in \ref psa_attest_err_t
*/
enum psa_attest_err_t
-attest_get_boot_data(uint8_t major_type, void *ptr, uint32_t len);
+attest_get_boot_data(uint8_t major_type,
+ struct tfm_boot_data *boot_data,
+ uint32_t len);
/*!
* \brief Get the ID of the caller thread.
diff --git a/secure_fw/services/initial_attestation/attestation_core.c b/secure_fw/services/initial_attestation/attestation_core.c
index 82e2fd2..92c9e12 100644
--- a/secure_fw/services/initial_attestation/attestation_core.c
+++ b/secure_fw/services/initial_attestation/attestation_core.c
@@ -27,25 +27,38 @@
#define EAT_SW_COMPONENT_NOT_NESTED 0 /* Flat structure */
/*!
- * \var boot_status
+ * \struct attest_boot_data
*
- * \brief Array variable to store the boot status in service's memory.
+ * \brief Contains the received boot status information from bootloader
+ *
+ * \details This is a redefinition of \ref tfm_boot_data to allocate the
+ * appropriate, service dependent size of \ref boot_data.
+ */
+struct attest_boot_data {
+ struct shared_data_tlv_header header;
+ uint8_t data[MAX_BOOT_STATUS];
+};
+
+/*!
+ * \var boot_data
+ *
+ * \brief Store the boot status in service's memory.
*
* \details Boot status comes from the secure bootloader and primarily stored
* on a memory area which is shared between bootloader and SPM.
* SPM provides the \ref tfm_core_get_boot_data() API to retrieve
* the service related data from shared area.
*/
-
-/* Enforcement of 4 byte alignment, which is checked by TF-M SPM */
__attribute__ ((aligned(4)))
-static uint8_t boot_status[MAX_BOOT_STATUS];
+static struct attest_boot_data boot_data;
enum psa_attest_err_t attest_init(void)
{
enum psa_attest_err_t res;
- res = attest_get_boot_data(TLV_MAJOR_IAS, boot_status, MAX_BOOT_STATUS);
+ res = attest_get_boot_data(TLV_MAJOR_IAS,
+ (struct tfm_boot_data *)&boot_data,
+ MAX_BOOT_STATUS);
return res;
}
@@ -136,21 +149,19 @@
uint16_t *tlv_len,
uint8_t **tlv_ptr)
{
- struct shared_data_tlv_header *tlv_header;
struct shared_data_tlv_entry tlv_entry;
uint8_t *tlv_end;
uint8_t *tlv_curr;
- tlv_header = (struct shared_data_tlv_header *)boot_status;
- if (tlv_header->tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
+ if (boot_data.header.tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
return -1;
}
/* Get the boundaries of TLV section where to lookup*/
- tlv_end = (uint8_t *)boot_status + tlv_header->tlv_tot_len;
+ tlv_end = (uint8_t *)&boot_data + boot_data.header.tlv_tot_len;
if (*tlv_ptr == NULL) {
/* At first call set to the beginning of the TLV section */
- tlv_curr = (uint8_t *)boot_status + SHARED_DATA_HEADER_SIZE;
+ tlv_curr = boot_data.data;
} else {
/* Any subsequent call set to the next TLV entry */
tfm_memcpy(&tlv_entry, *tlv_ptr, SHARED_DATA_ENTRY_HEADER_SIZE);
diff --git a/secure_fw/services/initial_attestation/tfm_attestation.c b/secure_fw/services/initial_attestation/tfm_attestation.c
index 186a58c..4dca76a 100644
--- a/secure_fw/services/initial_attestation/tfm_attestation.c
+++ b/secure_fw/services/initial_attestation/tfm_attestation.c
@@ -42,24 +42,23 @@
}
enum psa_attest_err_t
-attest_get_boot_data(uint8_t major_type, void *ptr, uint32_t len)
+attest_get_boot_data(uint8_t major_type,
+ struct tfm_boot_data *boot_data,
+ uint32_t len)
{
enum psa_attest_err_t attest_res = PSA_ATTEST_ERR_SUCCESS;
#ifndef BL2
- struct shared_data_tlv_header *tlv_header;
-
/* Avoid compiler warning due to unused argument */
(void)len;
(void)major_type;
- tlv_header = (struct shared_data_tlv_header *)ptr;
- tlv_header->tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
- tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE;
+ boot_data->header.tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
+ boot_data->header.tlv_tot_len = SHARED_DATA_HEADER_SIZE;
#else
enum tfm_status_e tfm_res;
- tfm_res = tfm_core_get_boot_data(major_type, ptr, len);
+ tfm_res = tfm_core_get_boot_data(major_type, boot_data, len);
if (tfm_res != TFM_SUCCESS) {
attest_res = PSA_ATTEST_ERR_INIT_FAILED;
}