RSS: Implement host ROTPKs
Change-Id: I6daf0954d9d692646b9d4588bb45947123189ceb
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt
index cc6eb9c..381f998 100755
--- a/platform/CMakeLists.txt
+++ b/platform/CMakeLists.txt
@@ -142,7 +142,7 @@
target_include_directories(platform_crypto_keys
PRIVATE
$<$<BOOL:${PLATFORM_DEFAULT_CRYPTO_KEYS}>:${CMAKE_SOURCE_DIR}/interface/include/crypto_keys>
- $<$<BOOL:${PLATFORM_DEFAULT_CRYPTO_KEYS}>:${CMAKE_BINARY_DIR}/generated/interface/include>
+ ${CMAKE_BINARY_DIR}/generated/interface/include
)
target_compile_definitions(platform_crypto_keys
diff --git a/platform/ext/target/arm/rss/CMakeLists.txt b/platform/ext/target/arm/rss/CMakeLists.txt
index 733d591..d1347e2 100644
--- a/platform/ext/target/arm/rss/CMakeLists.txt
+++ b/platform/ext/target/arm/rss/CMakeLists.txt
@@ -76,6 +76,10 @@
$<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/gcc/rss_bl1_2.ld>
)
+
+install(FILES platform_builtin_key_ids.h
+ DESTINATION ${TFM_INSTALL_PATH}/interface/include)
+
#========================= Platform Secure ====================================#
add_subdirectory(rss_comms)
@@ -122,6 +126,7 @@
nv_counters.c
attest_hal.c
tfm_hal_platform_reset.c
+ provisioning.c
)
target_sources(tfm_sprt
@@ -148,6 +153,14 @@
crypto_keys.c
)
+target_include_directories(platform_crypto_keys
+ PUBLIC
+ .
+ ./native_drivers
+ ./device/include
+ ./device/config
+)
+
#========================= Platform Non-Secure ================================#
target_sources(platform_ns
@@ -181,6 +194,8 @@
target_sources(platform_bl2
PRIVATE
tfm_hal_platform_reset.c
+ bl2/flash_map_bl2.c
+ bl2/provisioning.c
bl2/boot_hal_bl2.c
cmsis_drivers/Driver_Flash.c
cmsis_drivers/Driver_USART.c
@@ -213,11 +228,6 @@
native_drivers
)
-target_sources(bl2
- PRIVATE
- bl2/flash_map_bl2.c
-)
-
target_link_libraries(platform_bl2
PRIVATE
$<$<AND:$<BOOL:${CONFIG_TFM_BOOT_STORE_MEASUREMENTS}>,$<BOOL:${TFM_PARTITION_MEASURED_BOOT}>>:tfm_boot_status>
diff --git a/platform/ext/target/arm/rss/bl2/provisioning.c b/platform/ext/target/arm/rss/bl2/provisioning.c
new file mode 100644
index 0000000..88cac14
--- /dev/null
+++ b/platform/ext/target/arm/rss/bl2/provisioning.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_plat_provisioning.h"
+
+#include "cmsis_compiler.h"
+#include "tfm_plat_otp.h"
+#include "tfm_attest_hal.h"
+#include "psa/crypto.h"
+#include "bootutil/bootutil_log.h"
+
+#include <string.h>
+
+#define ASSEMBLY_AND_TEST_PROV_DATA_MAGIC 0xC0DEFEED
+
+__PACKED_STRUCT bl2_assembly_and_test_provisioning_data_t {
+ uint32_t magic;
+ uint8_t bl2_rotpk_0[32];
+ uint8_t bl2_rotpk_1[32];
+ uint8_t bl2_rotpk_2[32];
+ uint8_t bl2_rotpk_3[32];
+
+#ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
+ uint8_t secure_debug_pk[32];
+#endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
+};
+
+#ifdef TFM_DUMMY_PROVISIONING
+static const struct bl2_assembly_and_test_provisioning_data_t bl2_assembly_and_test_prov_data = {
+ ASSEMBLY_AND_TEST_PROV_DATA_MAGIC,
+#if (MCUBOOT_SIGN_RSA_LEN == 2048)
+ /* bl2 rotpk 0 */
+ {
+ 0xfc, 0x57, 0x01, 0xdc, 0x61, 0x35, 0xe1, 0x32,
+ 0x38, 0x47, 0xbd, 0xc4, 0x0f, 0x04, 0xd2, 0xe5,
+ 0xbe, 0xe5, 0x83, 0x3b, 0x23, 0xc2, 0x9f, 0x93,
+ 0x59, 0x3d, 0x00, 0x01, 0x8c, 0xfa, 0x99, 0x94,
+ },
+ /* bl2 rotpk 1 */
+ {
+ 0xe1, 0x80, 0x15, 0x99, 0x3d, 0x6d, 0x27, 0x60,
+ 0xb4, 0x99, 0x27, 0x4b, 0xae, 0xf2, 0x64, 0xb8,
+ 0x3a, 0xf2, 0x29, 0xe9, 0xa7, 0x85, 0xf3, 0xd5,
+ 0xbf, 0x00, 0xb9, 0xd3, 0x2c, 0x1f, 0x03, 0x96,
+ },
+ /* bl2 rotpk 2 */
+ {
+ 0xfc, 0x57, 0x01, 0xdc, 0x61, 0x35, 0xe1, 0x32,
+ 0x38, 0x47, 0xbd, 0xc4, 0x0f, 0x04, 0xd2, 0xe5,
+ 0xbe, 0xe5, 0x83, 0x3b, 0x23, 0xc2, 0x9f, 0x93,
+ 0x59, 0x3d, 0x00, 0x01, 0x8c, 0xfa, 0x99, 0x94,
+ },
+ /* bl2 rotpk 3 */
+ {
+ 0xfc, 0x57, 0x01, 0xdc, 0x61, 0x35, 0xe1, 0x32,
+ 0x38, 0x47, 0xbd, 0xc4, 0x0f, 0x04, 0xd2, 0xe5,
+ 0xbe, 0xe5, 0x83, 0x3b, 0x23, 0xc2, 0x9f, 0x93,
+ 0x59, 0x3d, 0x00, 0x01, 0x8c, 0xfa, 0x99, 0x94,
+ },
+#elif (MCUBOOT_SIGN_RSA_LEN == 3072)
+ /* bl2 rotpk 0 */
+ {
+ 0xbf, 0xe6, 0xd8, 0x6f, 0x88, 0x26, 0xf4, 0xff,
+ 0x97, 0xfb, 0x96, 0xc4, 0xe6, 0xfb, 0xc4, 0x99,
+ 0x3e, 0x46, 0x19, 0xfc, 0x56, 0x5d, 0xa2, 0x6a,
+ 0xdf, 0x34, 0xc3, 0x29, 0x48, 0x9a, 0xdc, 0x38,
+ },
+ /* bl2 rotpk 1 */
+ {
+ 0xb3, 0x60, 0xca, 0xf5, 0xc9, 0x8c, 0x6b, 0x94,
+ 0x2a, 0x48, 0x82, 0xfa, 0x9d, 0x48, 0x23, 0xef,
+ 0xb1, 0x66, 0xa9, 0xef, 0x6a, 0x6e, 0x4a, 0xa3,
+ 0x7c, 0x19, 0x19, 0xed, 0x1f, 0xcc, 0xc0, 0x49,
+ },
+ /* bl2 rotpk 2 */
+ {
+ 0xbf, 0xe6, 0xd8, 0x6f, 0x88, 0x26, 0xf4, 0xff,
+ 0x97, 0xfb, 0x96, 0xc4, 0xe6, 0xfb, 0xc4, 0x99,
+ 0x3e, 0x46, 0x19, 0xfc, 0x56, 0x5d, 0xa2, 0x6a,
+ 0xdf, 0x34, 0xc3, 0x29, 0x48, 0x9a, 0xdc, 0x38,
+ },
+ /* bl2 rotpk 3 */
+ {
+ 0xbf, 0xe6, 0xd8, 0x6f, 0x88, 0x26, 0xf4, 0xff,
+ 0x97, 0xfb, 0x96, 0xc4, 0xe6, 0xfb, 0xc4, 0x99,
+ 0x3e, 0x46, 0x19, 0xfc, 0x56, 0x5d, 0xa2, 0x6a,
+ 0xdf, 0x34, 0xc3, 0x29, 0x48, 0x9a, 0xdc, 0x38,
+ },
+#else
+#error "No public key available for given signing algorithm."
+#endif /* MCUBOOT_SIGN_RSA_LEN */
+
+#ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
+ {
+ 0xf4, 0x0c, 0x8f, 0xbf, 0x12, 0xdb, 0x78, 0x2a,
+ 0xfd, 0xf4, 0x75, 0x96, 0x6a, 0x06, 0x82, 0x36,
+ 0xe0, 0x32, 0xab, 0x80, 0xd1, 0xb7, 0xf1, 0xbc,
+ 0x9f, 0xe7, 0xd8, 0x7a, 0x88, 0xcb, 0x26, 0xd0,
+ },
+#endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
+};
+#else
+static const struct bl2_assembly_and_test_provisioning_data_t bl2_assembly_and_test_prov_data;
+#endif /* TFM_DUMMY_PROVISIONING */
+
+void tfm_plat_provisioning_check_for_dummy_keys(void)
+{
+ uint64_t iak_start;
+
+ tfm_plat_otp_read(PLAT_OTP_ID_IAK, sizeof(iak_start), (uint8_t*)&iak_start);
+
+ if(iak_start == 0xA4906F6DB254B4A9) {
+ BOOT_LOG_WRN("%s%s%s%s",
+ "\033[1;31m",
+ "This device was provisioned with dummy keys. ",
+ "This device is \033[1;1mNOT SECURE",
+ "\033[0m");
+ }
+
+ memset(&iak_start, 0, sizeof(iak_start));
+}
+
+int tfm_plat_provisioning_is_required(void)
+{
+ enum tfm_plat_err_t err;
+ enum plat_otp_lcs_t lcs;
+
+ err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST
+ || lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
+}
+
+enum tfm_plat_err_t provision_assembly_and_test(void)
+{
+ enum tfm_plat_err_t err;
+
+ err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_0,
+ sizeof(bl2_assembly_and_test_prov_data.bl2_rotpk_0),
+ bl2_assembly_and_test_prov_data.bl2_rotpk_0);
+ if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
+ return err;
+ }
+ err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_1,
+ sizeof(bl2_assembly_and_test_prov_data.bl2_rotpk_1),
+ bl2_assembly_and_test_prov_data.bl2_rotpk_1);
+ if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
+ return err;
+ }
+ err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_2,
+ sizeof(bl2_assembly_and_test_prov_data.bl2_rotpk_2),
+ bl2_assembly_and_test_prov_data.bl2_rotpk_2);
+ if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
+ return err;
+ }
+ err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_3,
+ sizeof(bl2_assembly_and_test_prov_data.bl2_rotpk_3),
+ bl2_assembly_and_test_prov_data.bl2_rotpk_3);
+ if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
+ return err;
+ }
+
+#ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
+ err = tfm_plat_otp_write(PLAT_OTP_ID_SECURE_DEBUG_PK,
+ sizeof(bl2_assembly_and_test_prov_data.secure_debug_pk),
+ bl2_assembly_and_test_prov_data.secure_debug_pk);
+ if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
+ return err;
+ }
+#endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
+
+ return err;
+}
+
+enum tfm_plat_err_t tfm_plat_provisioning_perform(void)
+{
+ enum tfm_plat_err_t err;
+ enum plat_otp_lcs_t lcs;
+
+ err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ BOOT_LOG_INF("Beginning BL2 provisioning");
+
+#ifdef TFM_DUMMY_PROVISIONING
+ BOOT_LOG_WRN("%s%s%s%s",
+ "\033[1;31m",
+ "TFM_DUMMY_PROVISIONING is not suitable for production! ",
+ "This device is \033[1;1mNOT SECURE",
+ "\033[0m");
+#endif /* TFM_DUMMY_PROVISIONING */
+
+ if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
+ if (bl2_assembly_and_test_prov_data.magic != ASSEMBLY_AND_TEST_PROV_DATA_MAGIC) {
+ BOOT_LOG_ERR("No valid ASSEMBLY_AND_TEST provisioning data found");
+ return TFM_PLAT_ERR_INVALID_INPUT;
+ }
+
+ err = provision_assembly_and_test();
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
diff --git a/platform/ext/target/arm/rss/config.cmake b/platform/ext/target/arm/rss/config.cmake
index 2a040f2..f5269d2 100644
--- a/platform/ext/target/arm/rss/config.cmake
+++ b/platform/ext/target/arm/rss/config.cmake
@@ -8,6 +8,8 @@
set(CRYPTO_HW_ACCELERATOR ON CACHE BOOL "Whether to enable the crypto hardware accelerator on supported platforms")
set(CRYPTO_NV_SEED OFF CACHE BOOL "Use stored NV seed to provide entropy")
set(PLATFORM_DEFAULT_OTP OFF CACHE BOOL "Use trusted on-chip flash to implement OTP memory")
+set(PLATFORM_DEFAULT_CRYPTO_KEYS OFF CACHE BOOL "Use default crypto keys implementation.")
+set(PLATFORM_DEFAULT_PROVISIONING OFF CACHE BOOL "Use default provisioning implementation")
# CFB mode is not supported by CC312
set(TFM_CRYPTO_TEST_ALG_CFB OFF CACHE BOOL "Test CFB cryptography mode")
set(PLATFORM_DEFAULT_NV_COUNTERS OFF CACHE BOOL "Use default nv counter implementation.")
diff --git a/platform/ext/target/arm/rss/crypto_keys.c b/platform/ext/target/arm/rss/crypto_keys.c
index ac36768..31b8350 100644
--- a/platform/ext/target/arm/rss/crypto_keys.c
+++ b/platform/ext/target/arm/rss/crypto_keys.c
@@ -19,6 +19,7 @@
#include "tfm_builtin_key_loader.h"
#include "kmu_drv.h"
#include "device_definition.h"
+#include "tfm_plat_otp.h"
#define TFM_NS_PARTITION_ID -1
@@ -71,6 +72,33 @@
}
break;
#endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
+ case TFM_BUILTIN_KEY_ID_HOST_S_ROTPK:
+ switch(owner) {
+ case TFM_NS_PARTITION_ID:
+ *usage = PSA_KEY_USAGE_VERIFY_HASH;
+ break;
+ default:
+ return TFM_PLAT_ERR_NOT_PERMITTED;
+ }
+ break;
+ case TFM_BUILTIN_KEY_ID_HOST_NS_ROTPK:
+ switch(owner) {
+ case TFM_NS_PARTITION_ID:
+ *usage = PSA_KEY_USAGE_VERIFY_HASH;
+ break;
+ default:
+ return TFM_PLAT_ERR_NOT_PERMITTED;
+ }
+ break;
+ case TFM_BUILTIN_KEY_ID_HOST_CCA_ROTPK:
+ switch(owner) {
+ case TFM_NS_PARTITION_ID:
+ *usage = PSA_KEY_USAGE_VERIFY_HASH;
+ break;
+ default:
+ return TFM_PLAT_ERR_NOT_PERMITTED;
+ }
+ break;
default:
return TFM_PLAT_ERR_UNSUPPORTED;
}
@@ -101,6 +129,21 @@
TFM_BUILTIN_KEY_LOADER_KEY_LOCATION);
break;
#endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
+ case TFM_BUILTIN_KEY_ID_HOST_S_ROTPK:
+ *slot_number = TFM_BUILTIN_KEY_SLOT_HOST_S_ROTPK;
+ *lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_LIFETIME_PERSISTENT,
+ TFM_BUILTIN_KEY_LOADER_KEY_LOCATION);
+ break;
+ case TFM_BUILTIN_KEY_ID_HOST_NS_ROTPK:
+ *slot_number = TFM_BUILTIN_KEY_SLOT_HOST_NS_ROTPK;
+ *lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_LIFETIME_PERSISTENT,
+ TFM_BUILTIN_KEY_LOADER_KEY_LOCATION);
+ break;
+ case TFM_BUILTIN_KEY_ID_HOST_CCA_ROTPK:
+ *slot_number = TFM_BUILTIN_KEY_SLOT_HOST_CCA_ROTPK;
+ *lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_LIFETIME_PERSISTENT,
+ TFM_BUILTIN_KEY_LOADER_KEY_LOCATION);
+ break;
default:
return PSA_ERROR_DOES_NOT_EXIST;
}
@@ -259,6 +302,63 @@
}
#endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
+static enum tfm_plat_err_t tfm_plat_get_host_s_rotpk(uint8_t *buf, size_t buf_len,
+ size_t *key_len,
+ size_t *key_bits,
+ psa_algorithm_t *algorithm,
+ psa_key_type_t *type)
+{
+ if (buf_len < 96) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* P384 public keys are 96 bytes in length */
+ *key_len = 96;
+ *key_bits = 384;
+ *algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
+ *type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
+
+ return tfm_plat_otp_read(PLAT_OTP_ID_HOST_ROTPK_S, buf_len, buf);
+}
+
+static enum tfm_plat_err_t tfm_plat_get_host_ns_rotpk(uint8_t *buf, size_t buf_len,
+ size_t *key_len,
+ size_t *key_bits,
+ psa_algorithm_t *algorithm,
+ psa_key_type_t *type)
+{
+ if (buf_len < 96) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* P384 public keys are 96 bytes in length */
+ *key_len = 96;
+ *key_bits = 384;
+ *algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
+ *type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
+
+ return tfm_plat_otp_read(PLAT_OTP_ID_HOST_ROTPK_NS, buf_len, buf);
+}
+
+static enum tfm_plat_err_t tfm_plat_get_host_cca_rotpk(uint8_t *buf, size_t buf_len,
+ size_t *key_len,
+ size_t *key_bits,
+ psa_algorithm_t *algorithm,
+ psa_key_type_t *type)
+{
+ if (buf_len < 96) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* P384 public keys are 96 bytes in length */
+ *key_len = 96;
+ *key_bits = 384;
+ *algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
+ *type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
+
+ return tfm_plat_otp_read(PLAT_OTP_ID_HOST_ROTPK_CCA, buf_len, buf);
+}
+
enum tfm_plat_err_t tfm_plat_load_builtin_keys(void)
{
psa_status_t err;
@@ -266,7 +366,7 @@
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
enum tfm_plat_err_t plat_err;
/* The KMU requires word alignment */
- uint8_t __ALIGNED(4) buf[48];
+ uint8_t __ALIGNED(4) buf[96];
size_t key_len;
size_t key_bits;
psa_algorithm_t algorithm;
@@ -325,5 +425,56 @@
}
#endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
+ /* HOST S ROTPK */
+ plat_err = tfm_plat_get_host_s_rotpk(buf, sizeof(buf), &key_len, &key_bits,
+ &algorithm, &type);
+ if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+ return plat_err;
+ }
+ key_id.MBEDTLS_PRIVATE(key_id) = TFM_BUILTIN_KEY_ID_HOST_S_ROTPK;
+ key_id.MBEDTLS_PRIVATE(owner) = 0;
+ psa_set_key_id(&attr, key_id);
+ psa_set_key_bits(&attr, key_bits);
+ psa_set_key_algorithm(&attr, algorithm);
+ psa_set_key_type(&attr, type);
+ err = tfm_builtin_key_loader_load_key(buf, key_len, &attr);
+ if (err != PSA_SUCCESS) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* HOST NS ROTPK */
+ plat_err = tfm_plat_get_host_ns_rotpk(buf, sizeof(buf), &key_len, &key_bits,
+ &algorithm, &type);
+ if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+ return plat_err;
+ }
+ key_id.MBEDTLS_PRIVATE(key_id) = TFM_BUILTIN_KEY_ID_HOST_NS_ROTPK;
+ key_id.MBEDTLS_PRIVATE(owner) = 0;
+ psa_set_key_id(&attr, key_id);
+ psa_set_key_bits(&attr, key_bits);
+ psa_set_key_algorithm(&attr, algorithm);
+ psa_set_key_type(&attr, type);
+ err = tfm_builtin_key_loader_load_key(buf, key_len, &attr);
+ if (err != PSA_SUCCESS) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* HOST CCA ROTPK */
+ plat_err = tfm_plat_get_host_cca_rotpk(buf, sizeof(buf), &key_len, &key_bits,
+ &algorithm, &type);
+ if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+ return plat_err;
+ }
+ key_id.MBEDTLS_PRIVATE(key_id) = TFM_BUILTIN_KEY_ID_HOST_CCA_ROTPK;
+ key_id.MBEDTLS_PRIVATE(owner) = 0;
+ psa_set_key_id(&attr, key_id);
+ psa_set_key_bits(&attr, key_bits);
+ psa_set_key_algorithm(&attr, algorithm);
+ psa_set_key_type(&attr, type);
+ err = tfm_builtin_key_loader_load_key(buf, key_len, &attr);
+ if (err != PSA_SUCCESS) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
return TFM_PLAT_ERR_SUCCESS;
}
diff --git a/platform/ext/target/arm/rss/otp_lcm.c b/platform/ext/target/arm/rss/otp_lcm.c
index d85fe5f..fb0f6c4 100644
--- a/platform/ext/target/arm/rss/otp_lcm.c
+++ b/platform/ext/target/arm/rss/otp_lcm.c
@@ -30,6 +30,9 @@
uint32_t bl2_image_hash_zero_bits;
uint32_t bl1_rotpk_0_zero_bits;
uint32_t secure_debug_pk_zero_bits;
+ uint32_t host_rotpk_s_zero_bits;
+ uint32_t host_rotpk_ns_zero_bits;
+ uint32_t host_rotpk_cca_zero_bits;
uint32_t iak_len;
uint32_t iak_type;
@@ -54,6 +57,11 @@
uint32_t host_nv_counter[3][128];
uint32_t bl1_rotpk_0[14];
+
+ uint32_t host_rotpk_s[24];
+ uint32_t host_rotpk_ns[24];
+ uint32_t host_rotpk_cca[24];
+
uint32_t bl1_2_image[BL1_2_CODE_SIZE / sizeof(uint32_t)];
};
@@ -199,29 +207,6 @@
return err;
}
- err = verify_zero_bits_count(USER_AREA_OFFSET(iak_len),
- USER_AREA_SIZE(iak_len),
- USER_AREA_OFFSET(iak_len_zero_bits));
- if (err != TFM_PLAT_ERR_SUCCESS) {
- return err;
- }
-
- err = verify_zero_bits_count(USER_AREA_OFFSET(iak_type),
- USER_AREA_SIZE(iak_type),
- USER_AREA_OFFSET(iak_type_zero_bits));
- if (err != TFM_PLAT_ERR_SUCCESS) {
- return err;
- }
-
-#ifdef ATTEST_INCLUDE_COSE_KEY_ID
- err = verify_zero_bits_count(USER_AREA_OFFSET(iak_id),
- USER_AREA_SIZE(iak_id),
- USER_AREA_OFFSET(iak_id_zero_bits));
- if (err != TFM_PLAT_ERR_SUCCESS) {
- return err;
- }
-#endif /* ATTEST_INCLUDE_COSE_KEY_ID */
-
/* The rotpk (used as the ROTPK for the RSS rutime) is special as it's zero
* count is stored in the cm_config_2 field, but it's not checked so we
* still need to do it manually
@@ -284,6 +269,27 @@
}
#endif /* BL1 */
+ err = verify_zero_bits_count(USER_AREA_OFFSET(host_rotpk_s),
+ USER_AREA_SIZE(host_rotpk_s),
+ USER_AREA_OFFSET(host_rotpk_s_zero_bits));
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ err = verify_zero_bits_count(USER_AREA_OFFSET(host_rotpk_ns),
+ USER_AREA_SIZE(host_rotpk_ns),
+ USER_AREA_OFFSET(host_rotpk_ns_zero_bits));
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ err = verify_zero_bits_count(USER_AREA_OFFSET(host_rotpk_cca),
+ USER_AREA_SIZE(host_rotpk_cca),
+ USER_AREA_OFFSET(host_rotpk_cca_zero_bits));
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
return TFM_PLAT_ERR_SUCCESS;
}
@@ -407,8 +413,6 @@
return otp_read(OTP_OFFSET(huk), OTP_SIZE(huk), out_len, out);
case PLAT_OTP_ID_GUK:
return otp_read(OTP_OFFSET(guk), OTP_SIZE(guk), out_len, out);
- case PLAT_OTP_ID_IAK:
- return 0;
case PLAT_OTP_ID_BOOT_SEED:
return otp_read(USER_AREA_OFFSET(boot_seed), USER_AREA_SIZE(boot_seed),
@@ -429,16 +433,6 @@
return otp_read(USER_AREA_OFFSET(profile_definition),
USER_AREA_SIZE(profile_definition), out_len, out);
- case PLAT_OTP_ID_IAK_LEN:
- return otp_read(USER_AREA_OFFSET(iak_len),
- USER_AREA_SIZE(iak_len), out_len, out);
- case PLAT_OTP_ID_IAK_TYPE:
- return otp_read(USER_AREA_OFFSET(iak_type),
- USER_AREA_SIZE(iak_type), out_len, out);
- case PLAT_OTP_ID_IAK_ID:
- return otp_read(USER_AREA_OFFSET(iak_id),
- USER_AREA_SIZE(iak_id), out_len, out);
-
case PLAT_OTP_ID_BL2_ROTPK_0:
return otp_read(OTP_OFFSET(rotpk), OTP_SIZE(rotpk), out_len, out);
case PLAT_OTP_ID_NV_COUNTER_BL2_0:
@@ -504,6 +498,16 @@
return otp_read(USER_AREA_OFFSET(secure_debug_pk),
USER_AREA_SIZE(secure_debug_pk), out_len, out);
+ case PLAT_OTP_ID_HOST_ROTPK_S:
+ return otp_read(USER_AREA_OFFSET(host_rotpk_s),
+ USER_AREA_SIZE(host_rotpk_s), out_len, out);
+ case PLAT_OTP_ID_HOST_ROTPK_NS:
+ return otp_read(USER_AREA_OFFSET(host_rotpk_ns),
+ USER_AREA_SIZE(host_rotpk_ns), out_len, out);
+ case PLAT_OTP_ID_HOST_ROTPK_CCA:
+ return otp_read(USER_AREA_OFFSET(host_rotpk_cca),
+ USER_AREA_SIZE(host_rotpk_cca), out_len, out);
+
default:
return TFM_PLAT_ERR_UNSUPPORTED;
}
@@ -543,8 +547,6 @@
case PLAT_OTP_ID_GUK:
return otp_write(OTP_OFFSET(guk), OTP_SIZE(guk), in_len, in,
0);
- case PLAT_OTP_ID_IAK:
- return 0;
case PLAT_OTP_ID_BOOT_SEED:
return otp_write(USER_AREA_OFFSET(boot_seed), USER_AREA_SIZE(boot_seed),
@@ -568,19 +570,6 @@
USER_AREA_SIZE(profile_definition), in_len,
in, USER_AREA_OFFSET(profile_definition_zero_bits));
- case PLAT_OTP_ID_IAK_LEN:
- return otp_write(USER_AREA_OFFSET(iak_len),
- USER_AREA_SIZE(iak_len), in_len,
- in, USER_AREA_OFFSET(iak_len_zero_bits));
- case PLAT_OTP_ID_IAK_TYPE:
- return otp_write(USER_AREA_OFFSET(iak_type),
- USER_AREA_SIZE(iak_type), in_len,
- in, USER_AREA_OFFSET(iak_type_zero_bits));
- case PLAT_OTP_ID_IAK_ID:
- return otp_write(USER_AREA_OFFSET(iak_id),
- USER_AREA_SIZE(iak_id), in_len,
- in, USER_AREA_OFFSET(iak_id_zero_bits));
-
case PLAT_OTP_ID_BL2_ROTPK_0:
return otp_write(OTP_OFFSET(rotpk), OTP_SIZE(rotpk), in_len, in, 0);
case PLAT_OTP_ID_NV_COUNTER_BL2_0:
@@ -654,6 +643,19 @@
USER_AREA_SIZE(secure_debug_pk), in_len, in,
USER_AREA_OFFSET(secure_debug_pk_zero_bits));
+ case PLAT_OTP_ID_HOST_ROTPK_S:
+ return otp_write(USER_AREA_OFFSET(host_rotpk_s),
+ USER_AREA_SIZE(host_rotpk_s), in_len, in,
+ USER_AREA_OFFSET(host_rotpk_s_zero_bits));
+ case PLAT_OTP_ID_HOST_ROTPK_NS:
+ return otp_write(USER_AREA_OFFSET(host_rotpk_ns),
+ USER_AREA_SIZE(host_rotpk_ns), in_len, in,
+ USER_AREA_OFFSET(host_rotpk_ns_zero_bits));
+ case PLAT_OTP_ID_HOST_ROTPK_CCA:
+ return otp_write(USER_AREA_OFFSET(host_rotpk_cca),
+ USER_AREA_SIZE(host_rotpk_cca), in_len, in,
+ USER_AREA_OFFSET(host_rotpk_cca_zero_bits));
+
default:
return TFM_PLAT_ERR_UNSUPPORTED;
}
@@ -670,8 +672,6 @@
case PLAT_OTP_ID_GUK:
*size = OTP_SIZE(guk);
break;
- case PLAT_OTP_ID_IAK:
- return 0;
case PLAT_OTP_ID_BOOT_SEED:
*size = USER_AREA_SIZE(boot_seed);
@@ -692,16 +692,6 @@
*size = USER_AREA_SIZE(profile_definition);
break;
- case PLAT_OTP_ID_IAK_LEN:
- *size = USER_AREA_SIZE(iak_len);
- break;
- case PLAT_OTP_ID_IAK_TYPE:
- *size = USER_AREA_SIZE(iak_type);
- break;
- case PLAT_OTP_ID_IAK_ID:
- *size = USER_AREA_SIZE(iak_id);
- break;
-
case PLAT_OTP_ID_BL2_ROTPK_0:
*size = OTP_SIZE(rotpk);
break;
@@ -768,6 +758,16 @@
*size = USER_AREA_SIZE(secure_debug_pk);
break;
+ case PLAT_OTP_ID_HOST_ROTPK_S:
+ *size = USER_AREA_SIZE(host_rotpk_s);
+ break;
+ case PLAT_OTP_ID_HOST_ROTPK_NS:
+ *size = USER_AREA_SIZE(host_rotpk_ns);
+ break;
+ case PLAT_OTP_ID_HOST_ROTPK_CCA:
+ *size = USER_AREA_SIZE(host_rotpk_cca);
+ break;
+
default:
return TFM_PLAT_ERR_UNSUPPORTED;
}
diff --git a/platform/ext/target/arm/rss/platform_builtin_key_ids.h b/platform/ext/target/arm/rss/platform_builtin_key_ids.h
new file mode 100644
index 0000000..b45d275
--- /dev/null
+++ b/platform/ext/target/arm/rss/platform_builtin_key_ids.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PLATFORM_BUILTIN_KEY_IDS_H__
+#define __PLATFORM_BUILTIN_KEY_IDS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief The PSA driver location for TF-M builtin keys. Arbitrary within the
+ * ranges documented at
+ * https://armmbed.github.io/mbed-crypto/html/api/keys/lifetimes.html#c.psa_key_location_t
+ */
+#define TFM_BUILTIN_KEY_LOADER_KEY_LOCATION ((psa_key_location_t)0x800001)
+
+/**
+ * \brief The persistent key identifiers for TF-M builtin keys.
+ *
+ * The value of TFM_BUILTIN_KEY_ID_MIN (and therefore of the whole range) is
+ * completely arbitrary except for being inside the PSA builtin keys range.
+ *
+ */
+enum tfm_key_id_builtin_t {
+ TFM_BUILTIN_KEY_ID_MIN = 0x7fff815Bu,
+ TFM_BUILTIN_KEY_ID_HUK,
+ TFM_BUILTIN_KEY_ID_IAK,
+#ifdef TFM_PARTITION_DELEGATED_ATTESTATION
+ TFM_BUILTIN_KEY_ID_DAK_SEED,
+#endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
+ TFM_BUILTIN_KEY_ID_PLAT_SPECIFIC_MIN = 0x7FFF816Bu,
+ TFM_BUILTIN_KEY_ID_HOST_S_ROTPK,
+ TFM_BUILTIN_KEY_ID_HOST_NS_ROTPK,
+ TFM_BUILTIN_KEY_ID_HOST_CCA_ROTPK,
+ TFM_BUILTIN_KEY_ID_MAX = 0x7FFF817Bu,
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __PLATFORM_BUILTIN_KEY_IDS_H__ */
diff --git a/platform/ext/target/arm/rss/platform_builtin_key_loader_ids.h b/platform/ext/target/arm/rss/platform_builtin_key_loader_ids.h
new file mode 100644
index 0000000..c2b66f0
--- /dev/null
+++ b/platform/ext/target/arm/rss/platform_builtin_key_loader_ids.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef TFM_BUILTIN_KEY_LOADER_IDS_H
+#define TFM_BUILTIN_KEY_LOADER_IDS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TFM_BUILTIN_MAX_KEY_LEN 96
+
+enum psa_drv_slot_number_t {
+ TFM_BUILTIN_KEY_SLOT_HUK = 0,
+ TFM_BUILTIN_KEY_SLOT_IAK,
+#ifdef TFM_PARTITION_DELEGATED_ATTESTATION
+ TFM_BUILTIN_KEY_SLOT_DAK_SEED,
+#endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
+ TFM_BUILTIN_KEY_SLOT_HOST_S_ROTPK,
+ TFM_BUILTIN_KEY_SLOT_HOST_NS_ROTPK,
+ TFM_BUILTIN_KEY_SLOT_HOST_CCA_ROTPK,
+ TFM_BUILTIN_KEY_SLOT_MAX,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TFM_BUILTIN_KEY_LOADER_IDS_H */
diff --git a/platform/ext/target/arm/rss/platform_otp_ids.h b/platform/ext/target/arm/rss/platform_otp_ids.h
new file mode 100644
index 0000000..015276a
--- /dev/null
+++ b/platform/ext/target/arm/rss/platform_otp_ids.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PLATFORM_OTP_IDS_H__
+#define __PLATFORM_OTP_IDS_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum tfm_otp_element_id_t {
+ PLAT_OTP_ID_HUK = 0,
+ PLAT_OTP_ID_GUK,
+ PLAT_OTP_ID_IAK,
+ PLAT_OTP_ID_IAK_LEN,
+ PLAT_OTP_ID_IAK_TYPE,
+ PLAT_OTP_ID_IAK_ID,
+
+ PLAT_OTP_ID_BOOT_SEED,
+ PLAT_OTP_ID_LCS,
+ PLAT_OTP_ID_IMPLEMENTATION_ID,
+ PLAT_OTP_ID_CERT_REF,
+ PLAT_OTP_ID_VERIFICATION_SERVICE_URL,
+ PLAT_OTP_ID_PROFILE_DEFINITION,
+
+ PLAT_OTP_ID_BL2_ROTPK_0,
+ PLAT_OTP_ID_BL2_ROTPK_1,
+ PLAT_OTP_ID_BL2_ROTPK_2,
+ PLAT_OTP_ID_BL2_ROTPK_3,
+
+ PLAT_OTP_ID_NV_COUNTER_BL2_0,
+ PLAT_OTP_ID_NV_COUNTER_BL2_1,
+ PLAT_OTP_ID_NV_COUNTER_BL2_2,
+ PLAT_OTP_ID_NV_COUNTER_BL2_3,
+
+ PLAT_OTP_ID_NV_COUNTER_NS_0,
+ PLAT_OTP_ID_NV_COUNTER_NS_1,
+ PLAT_OTP_ID_NV_COUNTER_NS_2,
+
+ PLAT_OTP_ID_KEY_BL2_ENCRYPTION,
+ PLAT_OTP_ID_BL1_2_IMAGE,
+ PLAT_OTP_ID_BL1_2_IMAGE_HASH,
+ PLAT_OTP_ID_BL2_IMAGE_HASH,
+ PLAT_OTP_ID_BL1_ROTPK_0,
+
+ PLAT_OTP_ID_NV_COUNTER_BL1_0,
+
+ PLAT_OTP_ID_ENTROPY_SEED,
+
+ PLAT_OTP_ID_SECURE_DEBUG_PK,
+
+ PLAT_OTP_ID_HOST_ROTPK_S,
+ PLAT_OTP_ID_HOST_ROTPK_NS,
+ PLAT_OTP_ID_HOST_ROTPK_CCA,
+
+ PLAT_OTP_ID_MAX = UINT32_MAX,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PLATFORM_OTP_IDS_H__ */
diff --git a/platform/ext/target/arm/rss/provisioning.c b/platform/ext/target/arm/rss/provisioning.c
new file mode 100644
index 0000000..6e2cb4f
--- /dev/null
+++ b/platform/ext/target/arm/rss/provisioning.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_plat_provisioning.h"
+
+#include "cmsis_compiler.h"
+#include "tfm_plat_otp.h"
+#include "tfm_attest_hal.h"
+#include "psa/crypto.h"
+#include "tfm_spm_log.h"
+
+#include <string.h>
+
+#define ASSEMBLY_AND_TEST_PROV_DATA_MAGIC 0xC0DEFEED
+#define PSA_ROT_PROV_DATA_MAGIC 0xBEEFFEED
+
+__PACKED_STRUCT tfm_assembly_and_test_provisioning_data_t {
+ uint32_t magic;
+ uint8_t huk[32];
+};
+
+__PACKED_STRUCT tfm_psa_rot_provisioning_data_t {
+ uint32_t magic;
+ uint8_t host_rotpk_s[96];
+ uint8_t host_rotpk_ns[96];
+ uint8_t host_rotpk_cca[96];
+
+ uint8_t boot_seed[32];
+ uint8_t implementation_id[32];
+ uint8_t cert_ref[32];
+ uint8_t verification_service_url[32];
+ uint8_t profile_definition[32];
+};
+
+#ifdef TFM_DUMMY_PROVISIONING
+static const struct tfm_assembly_and_test_provisioning_data_t assembly_and_test_prov_data = {
+ ASSEMBLY_AND_TEST_PROV_DATA_MAGIC,
+ /* HUK */
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ },
+};
+
+static const struct tfm_psa_rot_provisioning_data_t psa_rot_prov_data = {
+ PSA_ROT_PROV_DATA_MAGIC,
+ /* HOST_ROTPK_S */
+ {
+ 0x09, 0x20, 0x59, 0xde, 0xc5, 0x1b, 0xe2, 0x96,
+ 0xfe, 0x4b, 0xa0, 0x16, 0x20, 0xac, 0xd7, 0xce,
+ 0xe2, 0x1e, 0xd5, 0xbf, 0x74, 0x4f, 0xe4, 0x47,
+ 0xab, 0x1f, 0xe4, 0xcb, 0x91, 0x52, 0x94, 0xb2,
+ 0xf2, 0xff, 0xaf, 0x3a, 0x47, 0x26, 0x0e, 0x13,
+ 0x4f, 0x8f, 0x2c, 0x1b, 0x5e, 0xde, 0xe8, 0x9e,
+ 0xdd, 0x2e, 0x1c, 0xf1, 0x0d, 0x3c, 0xc1, 0xee,
+ 0x32, 0x92, 0x9d, 0x05, 0xca, 0x57, 0x0d, 0x0e,
+ 0xbc, 0xd1, 0x72, 0x32, 0xf4, 0x1f, 0x1c, 0xe4,
+ 0x48, 0xd8, 0x79, 0x87, 0xfc, 0x3b, 0x2f, 0xf4,
+ 0x79, 0xe2, 0xf1, 0x03, 0x1f, 0xf3, 0x4d, 0xbc,
+ 0x76, 0x8a, 0x81, 0x19, 0x4a, 0x95, 0x4d, 0xac
+ },
+ /* HOST_ROTPK_NS */
+ {
+ 0x09, 0x20, 0x59, 0xde, 0xc5, 0x1b, 0xe2, 0x96,
+ 0xfe, 0x4b, 0xa0, 0x16, 0x20, 0xac, 0xd7, 0xce,
+ 0xe2, 0x1e, 0xd5, 0xbf, 0x74, 0x4f, 0xe4, 0x47,
+ 0xab, 0x1f, 0xe4, 0xcb, 0x91, 0x52, 0x94, 0xb2,
+ 0xf2, 0xff, 0xaf, 0x3a, 0x47, 0x26, 0x0e, 0x13,
+ 0x4f, 0x8f, 0x2c, 0x1b, 0x5e, 0xde, 0xe8, 0x9e,
+ 0xdd, 0x2e, 0x1c, 0xf1, 0x0d, 0x3c, 0xc1, 0xee,
+ 0x32, 0x92, 0x9d, 0x05, 0xca, 0x57, 0x0d, 0x0e,
+ 0xbc, 0xd1, 0x72, 0x32, 0xf4, 0x1f, 0x1c, 0xe4,
+ 0x48, 0xd8, 0x79, 0x87, 0xfc, 0x3b, 0x2f, 0xf4,
+ 0x79, 0xe2, 0xf1, 0x03, 0x1f, 0xf3, 0x4d, 0xbc,
+ 0x76, 0x8a, 0x81, 0x19, 0x4a, 0x95, 0x4d, 0xac
+ },
+ /* HOST_ROTPK_CCA */
+ {
+ 0x09, 0x20, 0x59, 0xde, 0xc5, 0x1b, 0xe2, 0x96,
+ 0xfe, 0x4b, 0xa0, 0x16, 0x20, 0xac, 0xd7, 0xce,
+ 0xe2, 0x1e, 0xd5, 0xbf, 0x74, 0x4f, 0xe4, 0x47,
+ 0xab, 0x1f, 0xe4, 0xcb, 0x91, 0x52, 0x94, 0xb2,
+ 0xf2, 0xff, 0xaf, 0x3a, 0x47, 0x26, 0x0e, 0x13,
+ 0x4f, 0x8f, 0x2c, 0x1b, 0x5e, 0xde, 0xe8, 0x9e,
+ 0xdd, 0x2e, 0x1c, 0xf1, 0x0d, 0x3c, 0xc1, 0xee,
+ 0x32, 0x92, 0x9d, 0x05, 0xca, 0x57, 0x0d, 0x0e,
+ 0xbc, 0xd1, 0x72, 0x32, 0xf4, 0x1f, 0x1c, 0xe4,
+ 0x48, 0xd8, 0x79, 0x87, 0xfc, 0x3b, 0x2f, 0xf4,
+ 0x79, 0xe2, 0xf1, 0x03, 0x1f, 0xf3, 0x4d, 0xbc,
+ 0x76, 0x8a, 0x81, 0x19, 0x4a, 0x95, 0x4d, 0xac
+ },
+ /* boot seed */
+ {
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+ 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ },
+ /* implementation id */
+ {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+ },
+ /* certification reference */
+ "0604565272829-10010",
+ /* verification_service_url */
+ "www.trustedfirmware.org",
+ /* attestation_profile_definition */
+#if defined(ATTEST_TOKEN_PROFILE_PSA_IOT_1)
+ "PSA_IOT_PROFILE_1",
+#elif defined(ATTEST_TOKEN_PROFILE_PSA_2_0_0)
+ "http://arm.com/psa/2.0.0",
+#elif defined(ATTEST_TOKEN_PROFILE_ARM_CCA)
+ "http://arm.com/CCA-SSD/1.0.0",
+#else
+#ifdef TFM_PARTITION_INITIAL_ATTESTATION
+#error "Attestation token profile is incorrect"
+#else
+ "UNDEFINED",
+#endif /* TFM_PARTITION_INITIAL_ATTESTATION */
+#endif
+};
+#else
+static struct tfm_assembly_and_test_provisioning_data_t assembly_and_test_prov_data;
+static struct tfm_psa_rot_provisioning_data_t psa_rot_prov_data;
+#endif /* TFM_DUMMY_PROVISIONING */
+
+void tfm_plat_provisioning_check_for_dummy_keys(void)
+{
+ uint64_t host_rotpk_s_start;
+
+ tfm_plat_otp_read(PLAT_OTP_ID_HOST_ROTPK_S, sizeof(host_rotpk_s_start),
+ (uint8_t*)&host_rotpk_s_start);
+
+ if(host_rotpk_s_start == 0xA4906F6DB254B4A9) {
+ SPMLOG_ERRMSG("[WRN]\033[1;31m ");
+ SPMLOG_ERRMSG("This device was provisioned with dummy keys. ");
+ SPMLOG_ERRMSG("This device is \033[1;1mNOT SECURE");
+ SPMLOG_ERRMSG("\033[0m\r\n");
+ }
+
+ memset(&host_rotpk_s_start, 0, sizeof(host_rotpk_s_start));
+}
+
+int tfm_plat_provisioning_is_required(void)
+{
+ enum tfm_plat_err_t err;
+ enum plat_otp_lcs_t lcs;
+
+ err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST
+ || lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
+}
+
+enum tfm_plat_err_t provision_assembly_and_test(void)
+{
+ enum tfm_plat_err_t err;
+ uint32_t new_lcs;
+
+ err = tfm_plat_otp_write(PLAT_OTP_ID_HUK, sizeof(assembly_and_test_prov_data.huk),
+ assembly_and_test_prov_data.huk);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ new_lcs = PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
+ err = tfm_plat_otp_write(PLAT_OTP_ID_LCS, sizeof(new_lcs),
+ (uint8_t*)&new_lcs);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ return err;
+}
+
+enum tfm_plat_err_t provision_psa_rot(void)
+{
+ enum tfm_plat_err_t err;
+ uint32_t new_lcs;
+
+ err = tfm_plat_otp_write(PLAT_OTP_ID_HOST_ROTPK_S,
+ sizeof(psa_rot_prov_data.host_rotpk_s),
+ psa_rot_prov_data.host_rotpk_s);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ err = tfm_plat_otp_write(PLAT_OTP_ID_HOST_ROTPK_NS,
+ sizeof(psa_rot_prov_data.host_rotpk_ns),
+ psa_rot_prov_data.host_rotpk_ns);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ err = tfm_plat_otp_write(PLAT_OTP_ID_HOST_ROTPK_CCA,
+ sizeof(psa_rot_prov_data.host_rotpk_cca),
+ psa_rot_prov_data.host_rotpk_cca);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ err = tfm_plat_otp_write(PLAT_OTP_ID_BOOT_SEED,
+ sizeof(psa_rot_prov_data.boot_seed),
+ psa_rot_prov_data.boot_seed);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+ err = tfm_plat_otp_write(PLAT_OTP_ID_IMPLEMENTATION_ID,
+ sizeof(psa_rot_prov_data.implementation_id),
+ psa_rot_prov_data.implementation_id);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+ err = tfm_plat_otp_write(PLAT_OTP_ID_CERT_REF,
+ sizeof(psa_rot_prov_data.cert_ref),
+ psa_rot_prov_data.cert_ref);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+ err = tfm_plat_otp_write(PLAT_OTP_ID_VERIFICATION_SERVICE_URL,
+ sizeof(psa_rot_prov_data.verification_service_url),
+ psa_rot_prov_data.verification_service_url);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+ err = tfm_plat_otp_write(PLAT_OTP_ID_PROFILE_DEFINITION,
+ sizeof(psa_rot_prov_data.profile_definition),
+ psa_rot_prov_data.profile_definition);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ new_lcs = PLAT_OTP_LCS_SECURED;
+ err = tfm_plat_otp_write(PLAT_OTP_ID_LCS,
+ sizeof(new_lcs),
+ (uint8_t*)&new_lcs);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ return err;
+}
+
+enum tfm_plat_err_t tfm_plat_provisioning_perform(void)
+{
+ enum tfm_plat_err_t err;
+ enum plat_otp_lcs_t lcs;
+
+ err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+
+ SPMLOG_INFMSG("[INF] Beginning TF-M provisioning\r\n");
+
+#ifdef TFM_DUMMY_PROVISIONING
+ SPMLOG_ERRMSG("[WRN]\033[1;31m ");
+ SPMLOG_ERRMSG("TFM_DUMMY_PROVISIONING is not suitable for production! ");
+ SPMLOG_ERRMSG("This device is \033[1;1mNOT SECURE");
+ SPMLOG_ERRMSG("\033[0m\r\n");
+#endif /* TFM_DUMMY_PROVISIONING */
+
+ if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
+ if (assembly_and_test_prov_data.magic != ASSEMBLY_AND_TEST_PROV_DATA_MAGIC) {
+ SPMLOG_ERRMSG("No valid ASSEMBLY_AND_TEST provisioning data found\r\n");
+ return TFM_PLAT_ERR_INVALID_INPUT;
+ }
+
+ err = provision_assembly_and_test();
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+ }
+
+ err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+ if (lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING) {
+ if (psa_rot_prov_data.magic != PSA_ROT_PROV_DATA_MAGIC) {
+ SPMLOG_ERRMSG("No valid PSA_ROT provisioning data found\r\n");
+ return TFM_PLAT_ERR_INVALID_INPUT;
+ }
+
+ err = provision_psa_rot();
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return err;
+ }
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
diff --git a/platform/ext/target/arm/rss/rss_comms/rss_comms_permissions_hal.c b/platform/ext/target/arm/rss/rss_comms/rss_comms_permissions_hal.c
index a75f010..47369fc 100644
--- a/platform/ext/target/arm/rss/rss_comms/rss_comms_permissions_hal.c
+++ b/platform/ext/target/arm/rss/rss_comms/rss_comms_permissions_hal.c
@@ -91,7 +91,7 @@
size_t in_len,
int32_t type)
{
- uint32_t function_id;
+ uint32_t function_id = 0;
switch(handle) {
#ifdef TFM_PARTITION_DELEGATED_ATTESTATION
@@ -115,7 +115,7 @@
#endif /* TFM_PARTITION_MEASURED_BOOT */
#ifdef TFM_PARTITION_CRYPTO
case TFM_CRYPTO_HANDLE:
- if (in_len > 1) {
+ if (in_len >= 1) {
function_id = ((struct tfm_crypto_pack_iovec *)in_vec[0].base)->function_id;
switch(function_id) {
case (TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID):
diff --git a/platform/ext/target/arm/rss/tfm_builtin_key_ids.h b/platform/ext/target/arm/rss/tfm_builtin_key_ids.h
new file mode 100644
index 0000000..b45d275
--- /dev/null
+++ b/platform/ext/target/arm/rss/tfm_builtin_key_ids.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PLATFORM_BUILTIN_KEY_IDS_H__
+#define __PLATFORM_BUILTIN_KEY_IDS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief The PSA driver location for TF-M builtin keys. Arbitrary within the
+ * ranges documented at
+ * https://armmbed.github.io/mbed-crypto/html/api/keys/lifetimes.html#c.psa_key_location_t
+ */
+#define TFM_BUILTIN_KEY_LOADER_KEY_LOCATION ((psa_key_location_t)0x800001)
+
+/**
+ * \brief The persistent key identifiers for TF-M builtin keys.
+ *
+ * The value of TFM_BUILTIN_KEY_ID_MIN (and therefore of the whole range) is
+ * completely arbitrary except for being inside the PSA builtin keys range.
+ *
+ */
+enum tfm_key_id_builtin_t {
+ TFM_BUILTIN_KEY_ID_MIN = 0x7fff815Bu,
+ TFM_BUILTIN_KEY_ID_HUK,
+ TFM_BUILTIN_KEY_ID_IAK,
+#ifdef TFM_PARTITION_DELEGATED_ATTESTATION
+ TFM_BUILTIN_KEY_ID_DAK_SEED,
+#endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
+ TFM_BUILTIN_KEY_ID_PLAT_SPECIFIC_MIN = 0x7FFF816Bu,
+ TFM_BUILTIN_KEY_ID_HOST_S_ROTPK,
+ TFM_BUILTIN_KEY_ID_HOST_NS_ROTPK,
+ TFM_BUILTIN_KEY_ID_HOST_CCA_ROTPK,
+ TFM_BUILTIN_KEY_ID_MAX = 0x7FFF817Bu,
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __PLATFORM_BUILTIN_KEY_IDS_H__ */