Attest: Add initial attestation prototype
Details:
- implement initial version of API
- implement veneer function and SVC handler
- implement wrapper functions around veneers on S and NS side
- create manifest files and generate new partition defines
- add attestation service to build system
- update linker scripts for ARMCLANG and GNUARM
Change-Id: I987509c6cad08fcd082667bca7dbc9a328ea03de
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index ca71227..798b24d 100755
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -47,6 +47,7 @@
"${INTERFACE_DIR}/src/tfm_audit_api.c"
"${INTERFACE_DIR}/src/tfm_crypto_api.c"
"${INTERFACE_DIR}/src/tfm_platform_api.c"
+ "${INTERFACE_DIR}/src/tfm_initial_attestation_api.c"
"${INTERFACE_DIR}/src/tfm_ns_lock_rtx.c"
)
diff --git a/interface/include/tfm_initial_attestation_veneers.h b/interface/include/tfm_initial_attestation_veneers.h
new file mode 100644
index 0000000..502ab3e
--- /dev/null
+++ b/interface/include/tfm_initial_attestation_veneers.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_INITIAL_ATTESTATION_VENEERS_H__
+#define __TFM_INITIAL_ATTESTATION_VENEERS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "psa_client.h"
+
+/**
+ * \brief Get initial attestation token
+ *
+ * \param[in] in_vec Pointer to in_vec array, which contains input data
+ * to attestation service
+ * \param[in] num_invec Number of elements in in_vec array
+ * \param[in/out] out_vec Pointer out_vec array, which contains output data
+ * to attestation service
+ * \param[in] num_outvec Number of elements in out_vec array
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+enum psa_attest_err_t
+tfm_attest_veneer_get_token(const psa_invec *in_vec, uint32_t num_invec,
+ psa_outvec *out_vec, uint32_t num_outvec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_INITIAL_ATTESTATION_VENEERS_H__ */
diff --git a/interface/src/tfm_initial_attestation_api.c b/interface/src/tfm_initial_attestation_api.c
new file mode 100644
index 0000000..b935f34
--- /dev/null
+++ b/interface/src/tfm_initial_attestation_api.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "psa_initial_attestation_api.h"
+#include "tfm_initial_attestation_veneers.h"
+#include "tfm_ns_lock.h"
+#include "psa_client.h"
+
+enum psa_attest_err_t
+psa_initial_attest_get_token(const uint8_t *challenge_obj,
+ uint32_t challenge_size,
+ uint8_t *token,
+ uint32_t *token_size)
+{
+ psa_invec in_vec[1];
+ psa_outvec out_vec[1];
+
+ in_vec[0].base = challenge_obj;
+ in_vec[0].len = challenge_size;
+
+ out_vec[0].base = token;
+ out_vec[0].len = *token_size;
+
+ return tfm_ns_lock_dispatch((veneer_fn)tfm_attest_veneer_get_token,
+ (uint32_t)in_vec, 1,
+ (uint32_t)out_vec, 1);
+}
diff --git a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
index 3820076..840724a 100644
--- a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
+++ b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
@@ -87,6 +87,11 @@
*(TFM_SP_PLATFORM_ATTR_FN)
}
+ TFM_SP_INITIAL_ATTESTATION +0 ALIGN 32 {
+ *tfm_attest* (+RO)
+ *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
+ }
+
#ifdef TFM_PARTITION_TEST_CORE
TFM_SP_CORE_TEST +0 ALIGN 32 {
*tfm_ss_core_test.* (+RO)
@@ -177,6 +182,13 @@
TFM_SP_PLATFORM_STACK +0 ALIGN 128 EMPTY 0x0400 {
}
+ TFM_SP_INITIAL_ATTESTATION_DATA +0 ALIGN 32 {
+ *tfm_attest* (+RW +ZI)
+ }
+
+ TFM_SP_INITIAL_ATTESTATION_STACK +0 ALIGN 128 EMPTY 0x400 {
+ }
+
#ifdef TFM_PARTITION_TEST_CORE
TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld b/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
index 8eb0502..5598438 100644
--- a/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
+++ b/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
@@ -103,6 +103,9 @@
LONG (LOADADDR(.TFM_SP_PLATFORM_DATA))
LONG (ADDR(.TFM_SP_PLATFORM_DATA))
LONG (SIZEOF(.TFM_SP_PLATFORM_DATA))
+ LONG (LOADADDR(.TFM_SP_INITIAL_ATTESTATION_DATA))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_DATA))
#ifdef TFM_PARTITION_TEST_CORE
LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -149,6 +152,10 @@
LONG (SIZEOF(.TFM_SP_PLATFORM_BSS))
LONG (ADDR(.TFM_SP_PLATFORM_STACK))
LONG (SIZEOF(.TFM_SP_PLATFORM_STACK))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_BSS))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_STACK))
#ifdef TFM_PARTITION_TEST_CORE
LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -250,6 +257,18 @@
Image$$TFM_SP_PLATFORM$$Base = ADDR(.TFM_SP_PLATFORM);
Image$$TFM_SP_PLATFORM$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+ .TFM_SP_INITIAL_ATTESTATION : ALIGN(32)
+ {
+ *tfm_attest*:*(.text*)
+ *tfm_attest*:*(.rodata*)
+ *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
+ . = ALIGN(32);
+ } > FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION$$RO$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$RO$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION);
+
#ifdef TFM_PARTITION_TEST_CORE
.TFM_SP_CORE_TEST : ALIGN(32)
{
@@ -543,6 +562,30 @@
Image$$TFM_SP_PLATFORM_STACK$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_STACK);
Image$$TFM_SP_PLATFORM_STACK$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_STACK) + SIZEOF(.TFM_SP_PLATFORM_STACK);
+ .TFM_SP_INITIAL_ATTESTATION_DATA : ALIGN(32)
+ {
+ *tfm_attest*:*(.data*)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$RW$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA);
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$RW$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_DATA);
+
+ .TFM_SP_INITIAL_ATTESTATION_BSS : ALIGN(32)
+ {
+ *tfm_attest*:*(.bss*)
+ *tfm_attest*:*(COMMON)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$ZI$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS);
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$ZI$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_BSS);
+
+ .TFM_SP_INITIAL_ATTESTATION_STACK : ALIGN(128)
+ {
+ . += 0x0400;
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_STACK$$ZI$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK);
+ Image$$TFM_SP_INITIAL_ATTESTATION_STACK$$ZI$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_STACK);
+
#ifdef TFM_PARTITION_TEST_CORE
.TFM_SP_CORE_TEST_DATA : ALIGN(32)
{
diff --git a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
index 3820076..7c2401c 100644
--- a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
+++ b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
@@ -87,6 +87,11 @@
*(TFM_SP_PLATFORM_ATTR_FN)
}
+ TFM_SP_INITIAL_ATTESTATION +0 ALIGN 32 {
+ *tfm_attest* (+RO)
+ *(TFM_SP_INITIAL_ATTESTATION_PLATFORM_ATTR_FN)
+ }
+
#ifdef TFM_PARTITION_TEST_CORE
TFM_SP_CORE_TEST +0 ALIGN 32 {
*tfm_ss_core_test.* (+RO)
@@ -177,6 +182,13 @@
TFM_SP_PLATFORM_STACK +0 ALIGN 128 EMPTY 0x0400 {
}
+ TFM_SP_INITIAL_ATTESTATION_DATA +0 ALIGN 32 {
+ *tfm_attest* (+RW +ZI)
+ }
+
+ TFM_SP_INITIAL_ATTESTATION_STACK +0 ALIGN 128 EMPTY 0x400 {
+ }
+
#ifdef TFM_PARTITION_TEST_CORE
TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld b/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
index 880dace..b8b9c12 100644
--- a/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
+++ b/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
@@ -103,6 +103,9 @@
LONG (LOADADDR(.TFM_SP_PLATFORM_DATA))
LONG (ADDR(.TFM_SP_PLATFORM_DATA))
LONG (SIZEOF(.TFM_SP_PLATFORM_DATA))
+ LONG (LOADADDR(.TFM_SP_INITIAL_ATTESTATION_DATA))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_DATA))
#ifdef TFM_PARTITION_TEST_CORE
LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -149,6 +152,10 @@
LONG (SIZEOF(.TFM_SP_PLATFORM_BSS))
LONG (ADDR(.TFM_SP_PLATFORM_STACK))
LONG (SIZEOF(.TFM_SP_PLATFORM_STACK))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_BSS))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_STACK))
#ifdef TFM_PARTITION_TEST_CORE
LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -250,6 +257,18 @@
Image$$TFM_SP_PLATFORM$$Base = ADDR(.TFM_SP_PLATFORM);
Image$$TFM_SP_PLATFORM$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+ .TFM_SP_INITIAL_ATTESTATION : ALIGN(32)
+ {
+ *tfm_attest*:*(.text*)
+ *tfm_attest*:*(.rodata*)
+ *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
+ . = ALIGN(32);
+ } > FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION$$RO$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$RO$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION);
+
#ifdef TFM_PARTITION_TEST_CORE
.TFM_SP_CORE_TEST : ALIGN(32)
{
@@ -543,6 +562,30 @@
Image$$TFM_SP_PLATFORM_STACK$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_STACK);
Image$$TFM_SP_PLATFORM_STACK$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_STACK) + SIZEOF(.TFM_SP_PLATFORM_STACK);
+ .TFM_SP_INITIAL_ATTESTATION_DATA : ALIGN(32)
+ {
+ *tfm_attest*:*(.data*)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$RW$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA);
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$RW$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_DATA);
+
+ .TFM_SP_INITIAL_ATTESTATION_BSS : ALIGN(32)
+ {
+ *tfm_attest*:*(.bss*)
+ *tfm_attest*:*(COMMON)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$ZI$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS);
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$ZI$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_BSS);
+
+ .TFM_SP_INITIAL_ATTESTATION_STACK : ALIGN(128)
+ {
+ . += 0x0400;
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_STACK$$ZI$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK);
+ Image$$TFM_SP_INITIAL_ATTESTATION_STACK$$ZI$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_STACK);
+
#ifdef TFM_PARTITION_TEST_CORE
.TFM_SP_CORE_TEST_DATA : ALIGN(32)
{
diff --git a/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct b/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
index 694b050..28de2ac 100755
--- a/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
+++ b/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
@@ -87,6 +87,11 @@
*(TFM_SP_PLATFORM_ATTR_FN)
}
+ TFM_SP_INITIAL_ATTESTATION +0 ALIGN 32 {
+ *tfm_attest* (+RO)
+ *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
+ }
+
#ifdef TFM_PARTITION_TEST_CORE
TFM_SP_CORE_TEST +0 ALIGN 32 {
*tfm_ss_core_test.* (+RO)
@@ -177,6 +182,13 @@
TFM_SP_PLATFORM_STACK +0 ALIGN 128 EMPTY 0x0400 {
}
+ TFM_SP_INITIAL_ATTESTATION_DATA +0 ALIGN 32 {
+ *tfm_attest* (+RW +ZI)
+ }
+
+ TFM_SP_INITIAL_ATTESTATION_STACK +0 ALIGN 128 EMPTY 0x400 {
+ }
+
#ifdef TFM_PARTITION_TEST_CORE
TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld b/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
index 8eb0502..5598438 100644
--- a/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
+++ b/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
@@ -103,6 +103,9 @@
LONG (LOADADDR(.TFM_SP_PLATFORM_DATA))
LONG (ADDR(.TFM_SP_PLATFORM_DATA))
LONG (SIZEOF(.TFM_SP_PLATFORM_DATA))
+ LONG (LOADADDR(.TFM_SP_INITIAL_ATTESTATION_DATA))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_DATA))
#ifdef TFM_PARTITION_TEST_CORE
LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -149,6 +152,10 @@
LONG (SIZEOF(.TFM_SP_PLATFORM_BSS))
LONG (ADDR(.TFM_SP_PLATFORM_STACK))
LONG (SIZEOF(.TFM_SP_PLATFORM_STACK))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_BSS))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_STACK))
#ifdef TFM_PARTITION_TEST_CORE
LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -250,6 +257,18 @@
Image$$TFM_SP_PLATFORM$$Base = ADDR(.TFM_SP_PLATFORM);
Image$$TFM_SP_PLATFORM$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+ .TFM_SP_INITIAL_ATTESTATION : ALIGN(32)
+ {
+ *tfm_attest*:*(.text*)
+ *tfm_attest*:*(.rodata*)
+ *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
+ . = ALIGN(32);
+ } > FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION$$RO$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$RO$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION);
+
#ifdef TFM_PARTITION_TEST_CORE
.TFM_SP_CORE_TEST : ALIGN(32)
{
@@ -543,6 +562,30 @@
Image$$TFM_SP_PLATFORM_STACK$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_STACK);
Image$$TFM_SP_PLATFORM_STACK$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_STACK) + SIZEOF(.TFM_SP_PLATFORM_STACK);
+ .TFM_SP_INITIAL_ATTESTATION_DATA : ALIGN(32)
+ {
+ *tfm_attest*:*(.data*)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$RW$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA);
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$RW$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_DATA);
+
+ .TFM_SP_INITIAL_ATTESTATION_BSS : ALIGN(32)
+ {
+ *tfm_attest*:*(.bss*)
+ *tfm_attest*:*(COMMON)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$ZI$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS);
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$ZI$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_BSS);
+
+ .TFM_SP_INITIAL_ATTESTATION_STACK : ALIGN(128)
+ {
+ . += 0x0400;
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_STACK$$ZI$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK);
+ Image$$TFM_SP_INITIAL_ATTESTATION_STACK$$ZI$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_STACK);
+
#ifdef TFM_PARTITION_TEST_CORE
.TFM_SP_CORE_TEST_DATA : ALIGN(32)
{
diff --git a/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct b/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
index 966a796..dd946fa 100644
--- a/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
+++ b/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
@@ -87,6 +87,11 @@
*(TFM_SP_PLATFORM_ATTR_FN)
}
+ TFM_SP_INITIAL_ATTESTATION +0 ALIGN 32 {
+ *tfm_attest* (+RO)
+ *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
+ }
+
#ifdef TFM_PARTITION_TEST_CORE
TFM_SP_CORE_TEST +0 ALIGN 32 {
*tfm_ss_core_test.* (+RO)
@@ -177,6 +182,13 @@
TFM_SP_PLATFORM_STACK +0 ALIGN 128 EMPTY 0x0400 {
}
+ TFM_SP_INITIAL_ATTESTATION_DATA +0 ALIGN 32 {
+ *tfm_attest* (+RW +ZI)
+ }
+
+ TFM_SP_INITIAL_ATTESTATION_STACK +0 ALIGN 128 EMPTY 0x400 {
+ }
+
#ifdef TFM_PARTITION_TEST_CORE
TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/musca_b1/Device/Source/gcc/musca_s.ld b/platform/ext/target/musca_b1/Device/Source/gcc/musca_s.ld
index bf5796c..4911be0 100644
--- a/platform/ext/target/musca_b1/Device/Source/gcc/musca_s.ld
+++ b/platform/ext/target/musca_b1/Device/Source/gcc/musca_s.ld
@@ -103,6 +103,9 @@
LONG (LOADADDR(.TFM_SP_PLATFORM_DATA))
LONG (ADDR(.TFM_SP_PLATFORM_DATA))
LONG (SIZEOF(.TFM_SP_PLATFORM_DATA))
+ LONG (LOADADDR(.TFM_SP_INITIAL_ATTESTATION_DATA))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_DATA))
#ifdef TFM_PARTITION_TEST_CORE
LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -149,6 +152,10 @@
LONG (SIZEOF(.TFM_SP_PLATFORM_BSS))
LONG (ADDR(.TFM_SP_PLATFORM_STACK))
LONG (SIZEOF(.TFM_SP_PLATFORM_STACK))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_BSS))
+ LONG (ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK))
+ LONG (SIZEOF(.TFM_SP_INITIAL_ATTESTATION_STACK))
#ifdef TFM_PARTITION_TEST_CORE
LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -250,6 +257,18 @@
Image$$TFM_SP_PLATFORM$$Base = ADDR(.TFM_SP_PLATFORM);
Image$$TFM_SP_PLATFORM$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+ .TFM_SP_INITIAL_ATTESTATION : ALIGN(32)
+ {
+ *tfm_attest*:*(.text*)
+ *tfm_attest*:*(.rodata*)
+ *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
+ . = ALIGN(32);
+ } > FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION$$RO$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$RO$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION);
+ Image$$TFM_SP_INITIAL_ATTESTATION$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION);
+
#ifdef TFM_PARTITION_TEST_CORE
.TFM_SP_CORE_TEST : ALIGN(32)
{
@@ -543,6 +562,30 @@
Image$$TFM_SP_PLATFORM_STACK$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_STACK);
Image$$TFM_SP_PLATFORM_STACK$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_STACK) + SIZEOF(.TFM_SP_PLATFORM_STACK);
+ .TFM_SP_INITIAL_ATTESTATION_DATA : ALIGN(32)
+ {
+ *tfm_attest*:*(.data*)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$RW$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA);
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$RW$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_DATA) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_DATA);
+
+ .TFM_SP_INITIAL_ATTESTATION_BSS : ALIGN(32)
+ {
+ *tfm_attest*:*(.bss*)
+ *tfm_attest*:*(COMMON)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$ZI$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS);
+ Image$$TFM_SP_INITIAL_ATTESTATION_DATA$$ZI$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_BSS) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_BSS);
+
+ .TFM_SP_INITIAL_ATTESTATION_STACK : ALIGN(128)
+ {
+ . += 0x0400;
+ } > RAM AT> FLASH
+ Image$$TFM_SP_INITIAL_ATTESTATION_STACK$$ZI$$Base = ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK);
+ Image$$TFM_SP_INITIAL_ATTESTATION_STACK$$ZI$$Limit = ADDR(.TFM_SP_INITIAL_ATTESTATION_STACK) + SIZEOF(.TFM_SP_INITIAL_ATTESTATION_STACK);
+
#ifdef TFM_PARTITION_TEST_CORE
.TFM_SP_CORE_TEST_DATA : ALIGN(32)
{
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 9008f07..7bd047e 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -136,6 +136,7 @@
add_dependencies(${EXE_NAME} tfm_audit)
add_dependencies(${EXE_NAME} tfm_platform)
add_dependencies(${EXE_NAME} tfm_secure_tests)
+ add_dependencies(${EXE_NAME} tfm_attest)
#Set macro definitions for the project.
embedded_set_target_compile_defines(TARGET ${PROJECT_OBJ_LIB} LANGUAGE C DEFINES __thumb2__ __ARM_FEATURE_CMSE=3 TFM_LVL=${TFM_LVL} DAUTH_CHIP_DEFAULT APPEND)
@@ -144,14 +145,14 @@
#The test service veneers may not be referenced in the secure binary so the
#veneer objects are explicitly loaded from the secure tests library.
if(${COMPILER} STREQUAL "ARMCLANG")
- target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit tfm_platform $<TARGET_LINKER_FILE:tfm_secure_tests>\(*veneers.o\) tfm_secure_tests)
+ target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit tfm_platform tfm_attest $<TARGET_LINKER_FILE:tfm_secure_tests>\(*veneers.o\) tfm_secure_tests)
elseif(${COMPILER} STREQUAL "GNUARM")
- target_link_libraries(${EXE_NAME} tfm_secure_tests tfm_crypto tfm_storage tfm_audit tfm_platform)
+ target_link_libraries(${EXE_NAME} tfm_secure_tests tfm_crypto tfm_storage tfm_audit tfm_platform tfm_attest)
else()
message(FATAL_ERROR "unknown compiler" )
endif()
else()
- target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit tfm_platform)
+ target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit tfm_platform tfm_attest)
endif()
@@ -261,6 +262,9 @@
#Add the platform service library target
add_subdirectory(${SECURE_FW_DIR}/services/platform)
+#Add the initial attestation service library target
+add_subdirectory(${SECURE_FW_DIR}/services/initial_attestation)
+
if (LINK_TO_BOTH_MEMORY_REGION)
#Link to primary memory region
set_up_secure_fw_build(S_TARGET ${PROJECT_NAME}
diff --git a/secure_fw/ns_callable/CMakeLists.inc b/secure_fw/ns_callable/CMakeLists.inc
index afba7d5..8b883db 100644
--- a/secure_fw/ns_callable/CMakeLists.inc
+++ b/secure_fw/ns_callable/CMakeLists.inc
@@ -26,7 +26,8 @@
set (SS_NS_CALLABLE_C_SRC "${CMAKE_CURRENT_LIST_DIR}/tfm_sst_veneers.c"
"${CMAKE_CURRENT_LIST_DIR}/tfm_audit_veneers.c"
"${CMAKE_CURRENT_LIST_DIR}/tfm_crypto_veneers.c"
- "${CMAKE_CURRENT_LIST_DIR}/tfm_platform_veneers.c")
+ "${CMAKE_CURRENT_LIST_DIR}/tfm_platform_veneers.c"
+ "${CMAKE_CURRENT_LIST_DIR}/tfm_initial_attestation_veneers.c")
#Append all our source files to global lists.
list(APPEND ALL_SRC_C ${SS_NS_CALLABLE_C_SRC})
diff --git a/secure_fw/ns_callable/tfm_initial_attestation_veneers.c b/secure_fw/ns_callable/tfm_initial_attestation_veneers.c
new file mode 100644
index 0000000..df154d4
--- /dev/null
+++ b/secure_fw/ns_callable/tfm_initial_attestation_veneers.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_initial_attestation_veneers.h"
+#include "secure_fw/services/initial_attestation/attestation.h"
+#include "tfm_secure_api.h"
+#include "tfm_api.h"
+#include "spm_partition_defs.h"
+#include "psa_client.h"
+
+__tfm_secure_gateway_attributes__
+enum psa_attest_err_t
+tfm_attest_veneer_get_token(const psa_invec *in_vec, uint32_t num_invec,
+ psa_outvec *out_vec, uint32_t num_outvec)
+{
+ TFM_CORE_SFN_REQUEST(TFM_SP_INITIAL_ATTESTATION_ID,
+ initial_attest_get_token,
+ in_vec, num_invec,
+ out_vec, num_outvec);
+}
diff --git a/secure_fw/services/initial_attestation/CMakeLists.inc b/secure_fw/services/initial_attestation/CMakeLists.inc
new file mode 100644
index 0000000..7bc1f2a
--- /dev/null
+++ b/secure_fw/services/initial_attestation/CMakeLists.inc
@@ -0,0 +1,69 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#Definitions to compile the "initial_attestation" module.
+#This file assumes it will be included from a project specific cmakefile, and
+#will not create a library or executable.
+#Inputs:
+# MBEDTLS_INSTALL_DIR - directory where mbedtls headers and libraries can be found.
+# TFM_ROOT_DIR - root directory of the TF-M repository.
+#Outputs:
+# Will modify include directories to make the source compile.
+# ALL_SRC_C: C source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+# ALL_SRC_CXX: C++ source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+# ALL_SRC_ASM: assembly source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+# Include directories will be modified by using the include_directories() commands as needed.
+
+#Get the current directory where this file is located.
+set(INITIAL_ATTESTATION_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+#Check input variables
+if (NOT DEFINED ENABLE_INITIAL_ATTESTATION)
+ message(FATAL_ERROR "Incomplete build configuration: ENABLE_INITIAL_ATTESTATION is undefined. ")
+endif()
+
+if (ENABLE_INITIAL_ATTESTATION)
+ if (NOT DEFINED TFM_ROOT_DIR)
+ message(FATAL_ERROR "Please set TFM_ROOT_DIR before including this file.")
+ endif()
+
+ #Append all our source files to global lists.
+ list(APPEND ALL_SRC_C
+ "${INITIAL_ATTESTATION_DIR}/tfm_attestation_secure_api.c"
+ "${INITIAL_ATTESTATION_DIR}/attestation_core.c"
+ )
+
+ #Setting include directories
+ embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE)
+ embedded_include_directories(PATH ${TFM_ROOT_DIR}/interface/include ABSOLUTE)
+ embedded_include_directories(PATH ${TFM_ROOT_DIR}/platform/ext/common ABSOLUTE)
+
+ set(BUILD_CMSIS_CORE Off)
+ set(BUILD_RETARGET Off)
+ set(BUILD_NATIVE_DRIVERS Off)
+ set(BUILD_STARTUP Off)
+ set(BUILD_TARGET_CFG Off)
+ set(BUILD_TARGET_HARDWARE_KEYS Off)
+ set(BUILD_TARGET_NV_COUNTERS Off)
+ set(BUILD_CMSIS_DRIVERS Off)
+ set(BUILD_TIME Off)
+ set(BUILD_UART_STDOUT Off)
+ set(BUILD_FLASH Off)
+ set(BUILD_BOOT_SEED On)
+ set(BUILD_DEVICE_ID On)
+ if(NOT DEFINED PLATFORM_CMAKE_FILE)
+ message (FATAL_ERROR "Platform specific CMake is not defined. Please set PLATFORM_CMAKE_FILE.")
+ elseif(NOT EXISTS ${PLATFORM_CMAKE_FILE})
+ message (FATAL_ERROR "Platform specific CMake \"${PLATFORM_CMAKE_FILE}\" file does not exist. Please fix value of PLATFORM_CMAKE_FILE.")
+ else()
+ include(${PLATFORM_CMAKE_FILE})
+ endif()
+
+else()
+ message(FATAL_ERROR "Build system currently doesn't support selectively disabling of a service.")
+endif()
+
diff --git a/secure_fw/services/initial_attestation/CMakeLists.txt b/secure_fw/services/initial_attestation/CMakeLists.txt
new file mode 100644
index 0000000..1a1ea5f
--- /dev/null
+++ b/secure_fw/services/initial_attestation/CMakeLists.txt
@@ -0,0 +1,41 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_minimum_required(VERSION 3.7)
+
+#Tell cmake where our modules can be found
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../cmake)
+
+#Include common stuff to control cmake.
+include("Common/BuildSys")
+
+#Start an embedded project.
+embedded_project_start(CONFIG "${CMAKE_CURRENT_LIST_DIR}/../../../ConfigDefault.cmake")
+project(tfm_attest LANGUAGES ASM C)
+embedded_project_fixup()
+
+###Some project global settings
+set (INITIAL_ATTESTATION_DIR "${CMAKE_CURRENT_LIST_DIR}")
+get_filename_component(TFM_ROOT_DIR "${INITIAL_ATTESTATION_DIR}/../../.." ABSOLUTE)
+
+###Get the definition of what files we need to build
+set (ENABLE_INITIAL_ATTESTATION ON)
+include(CMakeLists.inc)
+
+if (NOT DEFINED TFM_LVL)
+ message(FATAL_ERROR "Incomplete build configuration: TFM_LVL is undefined.")
+endif()
+
+#Specify what we build (for the initial attestation service, build as a static library)
+add_library(tfm_attest STATIC ${ALL_SRC_ASM} ${ALL_SRC_C})
+embedded_set_target_compile_defines(TARGET tfm_attest LANGUAGE C DEFINES __ARM_FEATURE_CMSE=3 __thumb2__ TFM_LVL=${TFM_LVL})
+
+#Set common compiler and linker flags
+config_setting_shared_compiler_flags(tfm_attest)
+config_setting_shared_linker_flags(tfm_attest)
+
+embedded_project_end(tfm_attest)
diff --git a/secure_fw/services/initial_attestation/attestation.h b/secure_fw/services/initial_attestation/attestation.h
new file mode 100644
index 0000000..2072cb4
--- /dev/null
+++ b/secure_fw/services/initial_attestation/attestation.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __ATTESTATION_H__
+#define __ATTESTATION_H__
+
+#include "psa_initial_attestation_api.h"
+#include "psa_client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Extension of shared data TLVs defined in bl2/include/tfm_boot_status.h */
+#define TLV_MINOR_IAS_BOOT_SEED 0x0f
+#define TLV_MINOR_IAS_DEVICE_ID 0x10
+#define TLV_MINOR_IAS_CHALLENGE 0x11
+#define TLV_MINOR_IAS_CALLER_ID 0x12
+
+/*!
+ * \brief Initialise the initial attestation service during the TF-M boot up
+ * process.
+ *
+ * \return Returns PSA_ATTEST_ERR_SUCCESS if init has been completed,
+ * otherwise error as specified in \ref psa_attest_err_t
+ */
+enum psa_attest_err_t attest_init(void);
+
+/*!
+ * \brief Get initial attestation token
+ *
+ * \param[in] in_vec Pointer to in_vec array, which contains input data
+ * to attestation service
+ * \param[in] num_invec Number of elements in in_vec array
+ * \param[in/out] out_vec Pointer out_vec array, which contains output data
+ * to attestation service
+ * \param[in] num_outvec Number of elements in out_vec array
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+enum psa_attest_err_t
+initial_attest_get_token(const psa_invec *in_vec, uint32_t num_invec,
+ psa_outvec *out_vec, uint32_t num_outvec);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ATTESTATION_H__ */
diff --git a/secure_fw/services/initial_attestation/attestation_core.c b/secure_fw/services/initial_attestation/attestation_core.c
new file mode 100644
index 0000000..c16d4a3
--- /dev/null
+++ b/secure_fw/services/initial_attestation/attestation_core.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <stddef.h>
+#include "psa_initial_attestation_api.h"
+#include "attestation.h"
+#include "secure_utilities.h"
+#include "tfm_api.h"
+#include "tfm_secure_api.h"
+#include "psa_client.h"
+#include "bl2/include/tfm_boot_status.h"
+#include "platform/include/tfm_plat_device_id.h"
+#include "platform/include/tfm_plat_boot_seed.h"
+
+#define MAX_BOOT_STATUS 512
+
+/*!
+ * \var boot_status
+ *
+ * \brief Array variable to 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.
+ */
+
+/* FixMe: Enforcement of 4 byte alignment can be removed as soon as memory type
+ * is configured in the MPU to be normal, instead of device, which
+ * prohibits unaligned access.
+ */
+__attribute__ ((aligned(4)))
+static uint8_t boot_status[MAX_BOOT_STATUS];
+
+enum psa_attest_err_t attest_init(void)
+{
+ enum tfm_status_e res;
+
+ res = tfm_core_get_boot_data(TLV_MAJOR_IAS, boot_status, MAX_BOOT_STATUS);
+ if (res != TFM_SUCCESS) {
+ return PSA_ATTEST_ERR_INIT_FAILED;
+ }
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to look up a specific entry in the shared data
+ * section.
+ *
+ * \param[in] minor_type The identifier of the shared data entry
+ * \param[out] tlv_len Length of the shared data entry
+ * \param[out] tlv_ptr Pointer to the shared data entry
+ *
+ * \return Returns 0 on success. Otherwise, 1.
+ */
+static uint32_t attest_get_tlv(uint8_t minor_type,
+ uint16_t *tlv_len,
+ uint8_t **tlv_ptr)
+{
+ struct shared_data_tlv_header *tlv_header;
+ struct shared_data_tlv_entry *tlv_entry;
+ uintptr_t tlv_end;
+ uintptr_t tlv_curr;
+
+ tlv_header = (struct shared_data_tlv_header *)boot_status;
+ if (tlv_header->tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
+ return 1;
+ }
+
+ /* Get the boundaries of TLV section */
+ tlv_end = (uintptr_t)boot_status + tlv_header->tlv_tot_len;
+ tlv_curr = (uintptr_t)boot_status + SHARED_DATA_HEADER_SIZE;
+
+ /* Iterates over the TLV section and copy TLVs with requested minor
+ * type to the provided buffer.
+ */
+ for(; tlv_curr < tlv_end; tlv_curr += tlv_entry->tlv_len) {
+ tlv_entry = (struct shared_data_tlv_entry *)tlv_curr;
+ if (tlv_entry->tlv_minor_type == minor_type) {
+ *tlv_ptr = (uint8_t *)tlv_entry;
+ *tlv_len = tlv_entry ->tlv_len;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*!
+ * \brief Static function to copy a TLV entry from shared data section to the
+ * attestation token.
+ *
+ * \param[in] tlv_len The length of TLV entry in bytes
+ * \param[in] tlv_ptr Pointer from where to copy the TLV entry
+ * \param[in] token_buf_size Size of token buffer in bytes
+ * \param[out] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns 0 on success. Otherwise, 1.
+ */
+static uint32_t attest_copy_tlv(uint16_t tlv_len,
+ const uint8_t *tlv_ptr,
+ uint32_t token_buf_size,
+ uint8_t *token_buf)
+{
+ struct shared_data_tlv_header *tlv_header;
+ uint8_t *next_tlv = token_buf;
+
+ tlv_header = (struct shared_data_tlv_header *)token_buf;
+ if (tlv_header->tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
+ return 1;
+ }
+
+ if (tlv_header->tlv_tot_len + tlv_len > token_buf_size) {
+ return 1;
+ }
+
+ next_tlv += tlv_header->tlv_tot_len;
+ tlv_header->tlv_tot_len += tlv_len;
+ tfm_memcpy(next_tlv, tlv_ptr, tlv_len);
+
+ return 0;
+}
+
+/*!
+ * \brief Static function to add a TLV entry to the attestation token.
+ *
+ * \param[in] minor_type The identifier of the TLV entry
+ * \param[in] size Size of the TLV entry in bytes
+ * \param[in] data Pointer to the buffer which stores the TLV entry
+ * \param[in] token_buf_size Size of token buffer in bytes
+ * \param[out] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns 0 on success. Otherwise, 1.
+ */
+static uint32_t attest_add_tlv(uint8_t minor_type,
+ uint32_t size,
+ const uint8_t *data,
+ uint32_t token_buf_size,
+ uint8_t *token_buf)
+{
+ struct shared_data_tlv_header *tlv_header;
+ struct shared_data_tlv_entry *tlv_entry;
+ uint8_t *next_tlv = token_buf;
+
+ tlv_header = (struct shared_data_tlv_header *)token_buf;
+ if (tlv_header->tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
+ return 1;
+ }
+
+ if (tlv_header->tlv_tot_len + SHARED_DATA_ENTRY_SIZE(size) >
+ token_buf_size) {
+ return 1;
+ }
+
+ next_tlv += tlv_header->tlv_tot_len;
+ tlv_header->tlv_tot_len += SHARED_DATA_ENTRY_SIZE(size);
+
+ tlv_entry = (struct shared_data_tlv_entry *)next_tlv;
+ tlv_entry->tlv_major_type = TLV_MAJOR_IAS;
+ tlv_entry->tlv_minor_type = minor_type;
+ tlv_entry->tlv_len = SHARED_DATA_ENTRY_SIZE(size);
+
+ next_tlv += SHARED_DATA_ENTRY_HEADER_SIZE;
+ tfm_memcpy(next_tlv, data, size);
+
+ return 0;
+}
+
+/*!
+ * \brief Static function to initalise the token buffer. Add TLV data header to
+ * it.
+ *
+ * \param[in] token_buf_size Size of token buffer in bytes
+ * \param[out] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_init_token(uint32_t token_buf_size, uint8_t *token_buf)
+{
+ struct shared_data_tlv_header *tlv_header;
+
+ if (SHARED_DATA_HEADER_SIZE > token_buf_size) {
+ return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
+ }
+
+ tlv_header = (struct shared_data_tlv_header *)token_buf;
+ tlv_header->tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
+ tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE;
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to add boot status claim to attestation token.
+ *
+ * \param[in] token_buf_size Size of token buffer in bytes
+ * \param[out] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_add_s_ns_sha256_claim(uint32_t token_buf_size, uint8_t *token_buf)
+{
+ uint16_t tlv_len;
+ uint8_t *tlv_ptr;
+ uint32_t res;
+
+ res = attest_get_tlv(TLV_MINOR_IAS_S_NS_SHA256, &tlv_len, &tlv_ptr);
+ if (res != 0) {
+ return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
+ }
+
+ res = attest_copy_tlv(tlv_len, tlv_ptr, token_buf_size, token_buf);
+ if (res != 0) {
+ return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
+ }
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to add boot seed claim to attestation token.
+ *
+ * \param[in] token_buf_size Size of token buffer in bytes
+ * \param[out] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_add_boot_seed_claim(uint32_t token_buf_size, uint8_t *token_buf)
+{
+ /* FixMe: Enforcement of 4 byte alignment can be removed as soon as memory
+ * type is configured in the MPU to be normal, instead of device,
+ * which prohibits unaligned access.
+ */
+ __attribute__ ((aligned(4)))
+ uint8_t boot_seed[BOOT_SEED_SIZE];
+ uint32_t res;
+
+ res = tfm_plat_get_boot_seed(sizeof(boot_seed), boot_seed);
+ if (res != 0) {
+ return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
+ }
+
+ res = attest_add_tlv(TLV_MINOR_IAS_BOOT_SEED,
+ BOOT_SEED_SIZE,
+ boot_seed,
+ token_buf_size,
+ token_buf);
+ if (res != 0) {
+ return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
+ }
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to add device id claim to attestation token.
+ *
+ * \param[in] token_buf_size Size of token buffer in bytes
+ * \param[out] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_add_device_id_claim(uint32_t token_buf_size, uint8_t *token_buf)
+{
+ /* FixMe: Enforcement of 4 byte alignment can be removed as soon as memory
+ * type is configured in the MPU to be normal, instead of device,
+ * which prohibits unaligned access.
+ */
+ __attribute__ ((aligned(4)))
+ uint8_t device_id[DEVICE_ID_MAX_SIZE];
+ uint32_t res;
+ int32_t size;
+
+ size = tfm_plat_get_device_id(sizeof(device_id), device_id);
+ if (size < 0) {
+ return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
+ }
+
+ res = attest_add_tlv(TLV_MINOR_IAS_DEVICE_ID,
+ size,
+ device_id,
+ token_buf_size,
+ token_buf);
+ if (res != 0) {
+ return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
+ }
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to add caller id claim to attestation token.
+ *
+ * \param[in] token_buf_size Size of token buffer in bytes
+ * \param[out] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_add_caller_id_claim(uint32_t token_buf_size, uint8_t *token_buf)
+{
+ uint32_t res;
+ int32_t caller_id;
+
+ res = tfm_core_get_caller_client_id(&caller_id);
+ if (res != 0) {
+ return PSA_ATTEST_ERR_CLAIM_UNAVAILABLE;
+ }
+
+ res = attest_add_tlv(TLV_MINOR_IAS_CALLER_ID,
+ sizeof(int32_t),
+ (uint8_t *)&caller_id,
+ token_buf_size,
+ token_buf);
+ if (res != 0) {
+ return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
+ }
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to add challenge claim to attestation token.
+ *
+ * \param[in] challenge_buf_size Size of challenge object in bytes
+ * \param[in] challenge_buf Pointer to buffer which stores the challenge
+ * object
+ * \param[in] token_buf_size Size of token buffer in bytes
+ * \param[out] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns error code as specified in \ref psa_attest_err_t
+ */
+static enum psa_attest_err_t
+attest_add_challenge_claim(uint32_t challenge_buf_size,
+ const uint8_t *challenge_buf,
+ uint32_t token_buf_size,
+ uint8_t *token_buf)
+{
+ uint32_t res;
+
+ res = attest_add_tlv(TLV_MINOR_IAS_CHALLENGE,
+ challenge_buf_size,
+ challenge_buf,
+ token_buf_size,
+ token_buf);
+ if (res != 0) {
+ return PSA_ATTEST_ERR_TOKEN_BUFFER_OVERFLOW;
+ }
+
+ return PSA_ATTEST_ERR_SUCCESS;
+}
+
+/*!
+ * \brief Static function to retrieve the constructed attestation token's size.
+ *
+ * \param[in] token_buf Pointer to buffer which stores the token
+ *
+ * \return Returns the size of token in bytes
+ */
+static uint32_t attest_get_token_size(const uint8_t *token_buf)
+{
+ struct shared_data_tlv_header *tlv_header;
+
+ tlv_header = (struct shared_data_tlv_header *)token_buf;
+
+ return tlv_header->tlv_tot_len;
+}
+
+/* Initial implementation of attestation service:
+ * - data is TLV encoded
+ * - token is not signed yet
+ * - only fixed set of claims are supported
+ * - external claims are not handled, expect challenge object
+ */
+enum psa_attest_err_t
+initial_attest_get_token(const psa_invec *in_vec, uint32_t num_invec,
+ psa_outvec *out_vec, uint32_t num_outvec)
+{
+ enum tfm_status_e tfm_err;
+ enum psa_attest_err_t attest_err = PSA_ATTEST_ERR_SUCCESS;
+
+ const uint8_t *challenge_buf = (uint8_t *)in_vec[0].base;
+ size_t challenge_buf_size = in_vec[0].len;
+ uint8_t *token_buf = (uint8_t *)out_vec[0].base;
+ size_t *token_buf_size = &(out_vec[0].len);
+
+ if (challenge_buf_size > PSA_INITIAL_ATTEST_MAX_CHALLENGE_SIZE) {
+ return PSA_ATTEST_ERR_INVALID_INPUT;
+ }
+
+ if (challenge_buf_size > 0) {
+ tfm_err = tfm_core_memory_permission_check((void *)challenge_buf,
+ challenge_buf_size,
+ TFM_MEMORY_ACCESS_RO);
+ if (tfm_err != TFM_SUCCESS) {
+ attest_err = PSA_ATTEST_ERR_INVALID_INPUT;
+ goto error;
+ }
+ }
+
+ tfm_err = tfm_core_memory_permission_check(token_buf,
+ *token_buf_size,
+ TFM_MEMORY_ACCESS_RW);
+ if (tfm_err != TFM_SUCCESS) {
+ attest_err = PSA_ATTEST_ERR_INVALID_INPUT;
+ goto error;
+ }
+
+ attest_err = attest_init_token(*token_buf_size, token_buf);
+ if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+ goto error;
+ }
+
+ attest_err = attest_add_s_ns_sha256_claim(*token_buf_size, token_buf);
+ if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+ goto error;
+ }
+
+ attest_err = attest_add_boot_seed_claim(*token_buf_size, token_buf);
+ if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+ goto error;
+ }
+
+ attest_err = attest_add_device_id_claim(*token_buf_size, token_buf);
+ if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+ goto error;
+ }
+
+ if (challenge_buf_size > 0) {
+ attest_err = attest_add_challenge_claim(challenge_buf_size,
+ challenge_buf,
+ *token_buf_size,
+ token_buf);
+ if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+ goto error;
+ }
+ }
+
+ attest_err = attest_add_caller_id_claim(*token_buf_size, token_buf);
+ if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
+ goto error;
+ }
+ /* FixMe: Token should be signed with attestation key */
+
+ *token_buf_size = attest_get_token_size(token_buf);
+
+error:
+ return attest_err;
+}
diff --git a/secure_fw/services/initial_attestation/manifest.yaml b/secure_fw/services/initial_attestation/manifest.yaml
new file mode 100644
index 0000000..319987b
--- /dev/null
+++ b/secure_fw/services/initial_attestation/manifest.yaml
@@ -0,0 +1,37 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+ "name": "INITIAL_ATTESTATION",
+ "type": "TRUSTED",
+ "tfm_partition_name": "TFM_SP_INITIAL_ATTESTATION",
+ "tfm_trusted": true,
+ "priority": "NORMAL",
+ "id": "0x00000103",
+ "entry_point": "main",
+ "stack_size": "0x0400",
+ "heap_size": "0x0400",
+ "tfm_init_symbol": "attest_init",
+ "secure_functions": [
+ {
+ "sfid": "TFM_ATTEST_GET_TOKEN_SFID",
+ "signal": "TFM_ATTEST_GET_TOKEN",
+ "tfm_symbol": "attest_get_token",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "strict"
+ }
+ ],
+ "source_files": [
+ "attestation_core.c"
+ ],
+ "tfm_linker_pattern": [
+ "library_list": [
+ "*tfm_attest*"
+ ]
+ ]
+}
diff --git a/secure_fw/services/initial_attestation/tfm_attestation_secure_api.c b/secure_fw/services/initial_attestation/tfm_attestation_secure_api.c
new file mode 100644
index 0000000..0943de0
--- /dev/null
+++ b/secure_fw/services/initial_attestation/tfm_attestation_secure_api.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "psa_initial_attestation_api.h"
+#include "tfm_initial_attestation_veneers.h"
+#include "secure_utilities.h"
+#include "psa_client.h"
+#include "tfm_secure_api.h"
+#include <string.h>
+
+/* FIXME: If iovec will be supported by SPM then remove the usage of
+ * scratch area.
+ */
+extern uint8_t *tfm_scratch_area;
+
+__attribute__((section("SFN")))
+enum psa_attest_err_t
+psa_initial_attest_get_token(const uint8_t *challenge_obj,
+ uint32_t challenge_size,
+ uint8_t *token,
+ uint32_t *token_size)
+{
+ enum psa_attest_err_t err;
+ psa_invec *in_vec;
+ psa_outvec *out_vec;
+ uint8_t *challenge_buff;
+ uint8_t *token_buff;
+
+ if (tfm_core_set_buffer_area(TFM_BUFFER_SHARE_SCRATCH) != TFM_SUCCESS) {
+ return PSA_ATTEST_ERR_GENERAL;
+ }
+
+ /*
+ * Scratch area layout
+ * -------------------------------------------------------
+ * |in_vec[0] | out_vec[0] | challenge_buff | token_buff |
+ * -------------------------------------------------------
+ */
+
+ in_vec = (psa_invec *)(tfm_scratch_area);
+ out_vec = (psa_outvec *)(in_vec + 1);
+
+ challenge_buff = (uint8_t *)(out_vec + 1);
+ token_buff = (uint8_t *)(challenge_buff + challenge_size);
+
+ /* Copy challenge object to scratch area */
+ tfm_memcpy(challenge_buff, challenge_obj, challenge_size);
+
+
+ in_vec[0].base = challenge_buff;
+ in_vec[0].len = challenge_size;
+
+ out_vec[0].base = token_buff;
+ out_vec[0].len = *token_size;
+
+ err = tfm_attest_veneer_get_token(in_vec, 1, out_vec, 1);
+ if (err != PSA_ATTEST_ERR_SUCCESS) {
+ return err;
+ }
+
+ /* Copy output token to local buffer */
+ tfm_memcpy(token, out_vec[0].base, out_vec[0].len);
+ *token_size = out_vec[0].len;
+
+ return err;
+}
diff --git a/secure_fw/services/tfm_partition_defs.inc b/secure_fw/services/tfm_partition_defs.inc
index 1ef4cf0..a84c54b 100644
--- a/secure_fw/services/tfm_partition_defs.inc
+++ b/secure_fw/services/tfm_partition_defs.inc
@@ -18,22 +18,24 @@
#define TFM_SP_PLATFORM_ID (TFM_SP_BASE + 3)
+#define TFM_SP_INITIAL_ATTESTATION_ID (TFM_SP_BASE + 4)
+
#ifdef TFM_PARTITION_TEST_CORE
-#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 4)
+#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 5)
#endif /* TFM_PARTITION_TEST_CORE */
#ifdef TFM_PARTITION_TEST_CORE
-#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 5)
+#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 6)
#endif /* TFM_PARTITION_TEST_CORE */
#ifdef TFM_PARTITION_TEST_SST
-#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 6)
+#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 7)
#endif /* TFM_PARTITION_TEST_SST */
#ifdef TFM_PARTITION_TEST_SECURE_SERVICES
-#define TFM_SP_SECURE_TEST_PARTITION_ID (TFM_SP_BASE + 7)
+#define TFM_SP_SECURE_TEST_PARTITION_ID (TFM_SP_BASE + 8)
#endif /* TFM_PARTITION_TEST_SECURE_SERVICES */
-#define TFM_MAX_USER_PARTITIONS (8)
+#define TFM_MAX_USER_PARTITIONS (9)
#endif /* __TFM_PARTITION_DEFS_INC__ */
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index 8be6ef9..57dd18f 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -29,6 +29,10 @@
PARTITION_DECLARE(TFM_SP_PLATFORM, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
PARTITION_ADD_INIT_FUNC(TFM_SP_PLATFORM, platform_sp_init);
+/******** TFM_SP_INITIAL_ATTESTATION ********/
+PARTITION_DECLARE(TFM_SP_INITIAL_ATTESTATION, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
+PARTITION_ADD_INIT_FUNC(TFM_SP_INITIAL_ATTESTATION, attest_init);
+
#ifdef TFM_PARTITION_TEST_CORE
/******** TFM_SP_CORE_TEST ********/
PARTITION_DECLARE(TFM_SP_CORE_TEST, SPM_PART_FLAG_SECURE);
diff --git a/secure_fw/services/tfm_sfid_list.inc b/secure_fw/services/tfm_sfid_list.inc
index f2656df..e224dce 100644
--- a/secure_fw/services/tfm_sfid_list.inc
+++ b/secure_fw/services/tfm_sfid_list.inc
@@ -49,6 +49,9 @@
/******** TFM_SP_PLATFORM ********/
{platform_sp_system_reset, TFM_SP_PLATFORM_SYSTEM_RESET_SFID},
+ /******** TFM_SP_INITIAL_ATTESTATION ********/
+ {attest_get_token, TFM_ATTEST_GET_TOKEN_SFID},
+
#ifdef TFM_PARTITION_TEST_CORE
/******** TFM_SP_CORE_TEST ********/
{spm_core_test_sfn, TFM_CORE_TEST_SFN_SFID},
diff --git a/tools/tfm_manifest_list.yaml b/tools/tfm_manifest_list.yaml
index 4363fc3..c06a13e 100644
--- a/tools/tfm_manifest_list.yaml
+++ b/tools/tfm_manifest_list.yaml
@@ -36,14 +36,22 @@
"version_minor": 1
},
{
- "name": "TFM Platform Service",
- "short_name": "TFM_SP_Platform",
- "manifest": "secure_fw/services/platform/manifest.yaml",
- "tfm_extensions": true,
- "version_major": 0,
- "version_minor": 1
- },
- {
+ "name": "TFM Platform Service",
+ "short_name": "TFM_SP_Platform",
+ "manifest": "secure_fw/services/platform/manifest.yaml",
+ "tfm_extensions": true,
+ "version_major": 0,
+ "version_minor": 1
+ },
+ {
+ "name": "TFM Initial Attestation Service",
+ "short_name": "TFM_Init_Attest",
+ "manifest": "secure_fw/services/initial_attestation/manifest.yaml",
+ "tfm_extensions": true,
+ "version_major": 0,
+ "version_minor": 1
+ },
+ {
"name": "TFM Core Test Service",
"short_name": "TFM_Core_Test",
"manifest": "test/test_services/tfm_core_test/manifest.yaml",