Attest: Handle discrepancy in tlv_len definitions
The definition of the 'tlv_len' field in the shared boot data entry
header differs in upstream MCUboot repo and in its TF-M fork.
In the upstream repo the 'tlv_len' only covers the length of the payload
but not the size of the entry header. But in the TF-M fork the 'tlv_len'
covers the size of entry header and payload together. This discrepancy
is distinguished during the shared boot data processing based on which
MCUboot version is used along with TF-M runtime.
Change-Id: I0cc4b2a2e6c53d125514b1da7e44be474abdd9e4
Signed-off-by: David Vincze <david.vincze@linaro.org>
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 38a0bb2..216c92a 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -153,18 +153,22 @@
endif()
config_setting_shared_compiler_flags(${PROJECT_OBJ_LIB})
-if(NOT DEFINED TARGET_NV_COUNTERS_ENABLE)
+if (NOT DEFINED TARGET_NV_COUNTERS_ENABLE)
set(TARGET_NV_COUNTERS_ENABLE OFF)
endif()
-if(TARGET_NV_COUNTERS_ENABLE)
+if (TARGET_NV_COUNTERS_ENABLE)
embedded_set_target_compile_defines(TARGET ${PROJECT_OBJ_LIB} LANGUAGE C DEFINES TFM_NVCOUNTERS_ENABLE APPEND)
endif()
-if(BOOT_DATA_AVAILABLE)
+if (BOOT_DATA_AVAILABLE)
embedded_set_target_compile_defines(TARGET ${PROJECT_OBJ_LIB} LANGUAGE C DEFINES BOOT_DATA_AVAILABLE APPEND)
endif()
+if (LEGACY_TFM_TLV_HEADER)
+ embedded_set_target_compile_defines(TARGET ${PROJECT_OBJ_LIB} LANGUAGE C DEFINES LEGACY_TFM_TLV_HEADER APPEND)
+endif()
+
if (NOT DEFINED CORE_TEST)
message(FATAL_ERROR "Incomplete build configuration: CORE_TEST is undefined.")
elseif(CORE_TEST)
diff --git a/secure_fw/partitions/initial_attestation/CMakeLists.inc b/secure_fw/partitions/initial_attestation/CMakeLists.inc
index b0c18c1..f525000 100644
--- a/secure_fw/partitions/initial_attestation/CMakeLists.inc
+++ b/secure_fw/partitions/initial_attestation/CMakeLists.inc
@@ -62,6 +62,10 @@
set_property(SOURCE ${ATTEST_C_SRC} APPEND PROPERTY COMPILE_DEFINITIONS INCLUDE_COSE_KEY_ID)
endif()
+if (LEGACY_TFM_TLV_HEADER)
+ set_property(SOURCE ${ATTEST_C_SRC} APPEND PROPERTY COMPILE_DEFINITIONS LEGACY_TFM_TLV_HEADER)
+endif()
+
#Inform the user about attestation service features selected based on the cmake flags
message("The Initial Attestation service compile configuration is as follows:")
message("- ATTEST_INCLUDE_OPTIONAL_CLAIMS: ${ATTEST_INCLUDE_OPTIONAL_CLAIMS}")
diff --git a/secure_fw/partitions/initial_attestation/attestation_core.c b/secure_fw/partitions/initial_attestation/attestation_core.c
index f5059b9..e0df017 100644
--- a/secure_fw/partitions/initial_attestation/attestation_core.c
+++ b/secure_fw/partitions/initial_attestation/attestation_core.c
@@ -209,13 +209,18 @@
} else {
/* Any subsequent call set to the next TLV entry */
(void)tfm_memcpy(&tlv_entry, *tlv_ptr, SHARED_DATA_ENTRY_HEADER_SIZE);
+#ifdef LEGACY_TFM_TLV_HEADER
tlv_curr = (*tlv_ptr) + tlv_entry.tlv_len;
+#else
+ tlv_curr = (*tlv_ptr) + SHARED_DATA_ENTRY_HEADER_SIZE
+ + tlv_entry.tlv_len;
+#endif
}
/* Iterates over the TLV section and returns the address and size of TLVs
* with requested module identifier
*/
- for (; tlv_curr < tlv_end; tlv_curr += tlv_entry.tlv_len) {
+ while (tlv_curr < tlv_end) {
/* Create local copy to avoid unaligned access */
(void)tfm_memcpy(&tlv_entry, tlv_curr, SHARED_DATA_ENTRY_HEADER_SIZE);
if (GET_IAS_MODULE(tlv_entry.tlv_type) == module) {
@@ -224,6 +229,11 @@
*tlv_len = tlv_entry.tlv_len;
return 1;
}
+#ifdef LEGACY_TFM_TLV_HEADER
+ tlv_curr += tlv_entry.tlv_len;
+#else
+ tlv_curr += (SHARED_DATA_ENTRY_HEADER_SIZE + tlv_entry.tlv_len);
+#endif
}
return 0;
@@ -287,7 +297,7 @@
uint8_t tlv_id;
int32_t found;
uint32_t cnt = 0;
- uint8_t module;
+ uint8_t module = 0;
QCBOREncodeContext *cbor_encode_ctx = NULL;
UsefulBufC encoded = NULLUsefulBufC;
@@ -296,7 +306,18 @@
/* Starting from module 1, because module 0 contains general claims which
* are not related to SW module(i.e: boot_seed, etc.)
*/
- for (module = 1; module < SW_MAX; ++module) {
+ /* TODO: When TF-M's MCUboot fork is used as the bootloader
+ * (LEGACY_TFM_TLV_HEADER is defined) it uses different SW module
+ * identifiers in the shared data entry headers than the upstream
+ * MCUboot. This is a workaround to be able to get all the claims
+ * of every SW components, until this discrepancy is handled properly.
+ */
+#ifdef LEGACY_TFM_TLV_HEADER
+ module = 1;
+#else
+ module = 0;
+#endif
+ for ( ; module < SW_MAX; ++module) {
/* Indicates to restart the look up from the beginning of the shared
* data section
*/
@@ -318,7 +339,10 @@
}
encoded.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
- encoded.len = tlv_len - SHARED_DATA_ENTRY_HEADER_SIZE;
+ encoded.len = tlv_len;
+#ifdef LEGACY_TFM_TLV_HEADER
+ encoded.len -= SHARED_DATA_ENTRY_HEADER_SIZE;
+#endif
QCBOREncode_AddEncoded(cbor_encode_ctx, encoded);
}
}
@@ -359,7 +383,10 @@
found = attest_get_tlv_by_id(BOOT_SEED, &tlv_len, &tlv_ptr);
if (found == 1) {
claim_value.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
- claim_value.len = tlv_len - SHARED_DATA_ENTRY_HEADER_SIZE;
+ claim_value.len = tlv_len;
+#ifdef LEGACY_TFM_TLV_HEADER
+ claim_value.len -= SHARED_DATA_ENTRY_HEADER_SIZE;
+#endif
} else {
/* If not found in boot status then use callback function to get it
* from runtime SW
@@ -486,7 +513,10 @@
found = attest_get_tlv_by_id(SECURITY_LIFECYCLE, &tlv_len, &tlv_ptr);
if (found == 1) {
claim_value.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
- claim_value.len = tlv_len - SHARED_DATA_ENTRY_HEADER_SIZE;
+ claim_value.len = tlv_len;
+#ifdef LEGACY_TFM_TLV_HEADER
+ claim_value.len -= SHARED_DATA_ENTRY_HEADER_SIZE;
+#endif
res = get_uint(claim_value.ptr, claim_value.len, &slc_value);
if (res) {
return PSA_ATTEST_ERR_GENERAL;
@@ -604,7 +634,10 @@
found = attest_get_tlv_by_id(HW_VERSION, &tlv_len, &tlv_ptr);
if (found == 1) {
claim_value.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
- claim_value.len = tlv_len - SHARED_DATA_ENTRY_HEADER_SIZE;
+ claim_value.len = tlv_len;
+#ifdef LEGACY_TFM_TLV_HEADER
+ claim_value.len -= SHARED_DATA_ENTRY_HEADER_SIZE;
+#endif
} else {
/* If not found in boot status then use callback function to get it
* from runtime SW
diff --git a/secure_fw/spm/init/tfm_boot_data.c b/secure_fw/spm/init/tfm_boot_data.c
index ee4466e..0dc3124 100644
--- a/secure_fw/spm/init/tfm_boot_data.c
+++ b/secure_fw/spm/init/tfm_boot_data.c
@@ -142,6 +142,7 @@
uint8_t *ptr;
struct shared_data_tlv_entry tlv_entry;
uintptr_t tlv_end, offset;
+ size_t next_tlv_offset;
#endif /* BOOT_DATA_AVAILABLE */
#ifndef TFM_PSA_API
uint32_t running_partition_idx =
@@ -216,23 +217,27 @@
/* Iterates over the TLV section and copy TLVs with requested major
* type to the provided buffer.
*/
- for (; offset < tlv_end; offset += tlv_entry.tlv_len) {
+ for (; offset < tlv_end; offset += next_tlv_offset) {
/* Create local copy to avoid unaligned access */
(void)tfm_core_util_memcpy(&tlv_entry,
(const void *)offset,
SHARED_DATA_ENTRY_HEADER_SIZE);
+#ifdef LEGACY_TFM_TLV_HEADER
+ next_tlv_offset = tlv_entry.tlv_len;
+#else
+ next_tlv_offset = SHARED_DATA_ENTRY_HEADER_SIZE + tlv_entry.tlv_len;
+#endif
if (GET_MAJOR(tlv_entry.tlv_type) == tlv_major) {
/* Check buffer overflow */
- if (((ptr - buf_start) + tlv_entry.tlv_len) > buf_size) {
+ if (((ptr - buf_start) + next_tlv_offset) > buf_size) {
args[0] = (uint32_t)TFM_ERROR_INVALID_PARAMETER;
return;
}
(void)tfm_core_util_memcpy(ptr, (const void *)offset,
- tlv_entry.tlv_len);
-
- ptr += tlv_entry.tlv_len;
- boot_data->header.tlv_tot_len += tlv_entry.tlv_len;
+ next_tlv_offset);
+ ptr += next_tlv_offset;
+ boot_data->header.tlv_tot_len += next_tlv_offset;
}
}
#endif /* BOOT_DATA_AVAILABLE */