Platform: Add NS NV counters
Add a configurable amount of NS NV counters (up to 3), and expose them
to the NS caller.
Change-Id: I8adda25c1fae49c4dae36ccb562360f45ecbfc0a
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/config/check_config.cmake b/config/check_config.cmake
index 2730889..58e0f2f 100644
--- a/config/check_config.cmake
+++ b/config/check_config.cmake
@@ -82,6 +82,7 @@
tfm_invalid_config(OTP_NV_COUNTERS_RAM_EMULATION AND NOT (PLATFORM_DEFAULT_OTP OR PLATFORM_DEFAULT_NV_COUNTERS))
tfm_invalid_config(PLATFORM_DEFAULT_NV_COUNTERS AND NOT PLATFORM_DEFAULT_OTP_WRITEABLE)
tfm_invalid_config(TFM_DUMMY_PROVISIONING AND NOT PLATFORM_DEFAULT_OTP_WRITEABLE)
+tfm_invalid_config(TFM_NS_NV_COUNTER_AMOUNT GREATER 3)
####################### Firmware Update Parttion ###############################
diff --git a/config/config_default.cmake b/config/config_default.cmake
index 6d7e097..398339c 100755
--- a/config/config_default.cmake
+++ b/config/config_default.cmake
@@ -80,6 +80,7 @@
set(CRYPTO_HW_ACCELERATOR OFF CACHE BOOL "Whether to enable the crypto hardware accelerator on supported platforms")
set(OTP_NV_COUNTERS_RAM_EMULATION OFF CACHE BOOL "Enable OTP/NV_COUNTERS emulation in RAM. Has no effect on non-default implementations of the OTP and NV_COUNTERS")
+set(TFM_NS_NV_COUNTER_AMOUNT 0 CACHE STRING "How many NS NV counters are enabled")
set(PLATFORM_DEFAULT_BL1 ON CACHE STRING "Whether to use default BL1 or platform-specific one")
diff --git a/interface/src/tfm_platform_func_api.c b/interface/src/tfm_platform_func_api.c
index 3ef0c86..df566ec 100644
--- a/interface/src/tfm_platform_func_api.c
+++ b/interface/src/tfm_platform_func_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -50,3 +50,35 @@
(uint32_t)output, (uint32_t)outlen);
}
+enum tfm_platform_err_t
+tfm_platform_nv_counter_increment(uint32_t counter_id)
+{
+ struct psa_invec in_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+ return (enum tfm_platform_err_t) tfm_ns_interface_dispatch(
+ (veneer_fn)tfm_platform_sp_nv_counter_increment_veneer,
+ (uint32_t)in_vec, 1,
+ (uint32_t)NULL, 0);
+}
+
+enum tfm_platform_err_t
+tfm_platform_nv_counter_read(uint32_t counter_id,
+ uint32_t size, uint8_t *val)
+{
+ struct psa_invec in_vec[1];
+ struct psa_outvec out_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+ out_vec[0].base = val;
+ out_vec[0].len = size;
+
+ return (enum tfm_platform_err_t) tfm_ns_interface_dispatch(
+ (veneer_fn)tfm_platform_sp_nv_counter_read_veneer,
+ (uint32_t)in_vec, 1,
+ (uint32_t)out_vec, 1);
+}
diff --git a/interface/src/tfm_platform_ipc_api.c b/interface/src/tfm_platform_ipc_api.c
index 0c1edf4..072e243 100644
--- a/interface/src/tfm_platform_ipc_api.c
+++ b/interface/src/tfm_platform_ipc_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -27,7 +27,7 @@
if (status < PSA_SUCCESS) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
} else {
- return (enum tfm_platform_err_t) status;
+ return (enum tfm_platform_err_t)status;
}
}
@@ -72,7 +72,67 @@
if (status < PSA_SUCCESS) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
} else {
- return (enum tfm_platform_err_t) status;
+ return (enum tfm_platform_err_t)status;
}
}
+enum tfm_platform_err_t
+tfm_platform_nv_counter_increment(uint32_t counter_id)
+{
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+ psa_handle_t handle = PSA_NULL_HANDLE;
+ struct psa_invec in_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+ handle = psa_connect(TFM_SP_PLATFORM_NV_COUNTER_SID,
+ TFM_SP_PLATFORM_NV_COUNTER_VERSION);
+ if (handle <= 0) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ status = psa_call(handle, TFM_PLATFORM_API_ID_NV_INCREMENT,
+ in_vec, 1, (psa_outvec *)NULL, 0);
+
+ psa_close(handle);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+}
+
+enum tfm_platform_err_t
+tfm_platform_nv_counter_read(uint32_t counter_id,
+ uint32_t size, uint8_t *val)
+{
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+ psa_handle_t handle = PSA_NULL_HANDLE;
+ struct psa_invec in_vec[1];
+ struct psa_outvec out_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+ out_vec[0].base = val;
+ out_vec[0].len = size;
+
+ handle = psa_connect(TFM_SP_PLATFORM_NV_COUNTER_SID,
+ TFM_SP_PLATFORM_NV_COUNTER_VERSION);
+ if (handle <= 0) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ status = psa_call(handle, TFM_PLATFORM_API_ID_NV_READ,
+ in_vec, 1, out_vec, 1);
+
+ psa_close(handle);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+}
diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt
index 7fad26a..89bd2a6 100755
--- a/platform/CMakeLists.txt
+++ b/platform/CMakeLists.txt
@@ -248,4 +248,5 @@
$<$<BOOL:${FORWARD_PROT_MSG}>:FORWARD_PROT_MSG=${FORWARD_PROT_MSG}>
$<$<BOOL:${TFM_CODE_SHARING}>:CODE_SHARING>
$<$<OR:$<CONFIG:Debug>,$<CONFIG:relwithdebinfo>>:ENABLE_HEAP>
+ PLATFORM_NS_NV_COUNTERS=${TFM_NS_NV_COUNTER_AMOUNT}
)
diff --git a/platform/ext/accelerator/cc312/otp_cc312.c b/platform/ext/accelerator/cc312/otp_cc312.c
index dae765f..282965c 100644
--- a/platform/ext/accelerator/cc312/otp_cc312.c
+++ b/platform/ext/accelerator/cc312/otp_cc312.c
@@ -240,6 +240,16 @@
#endif /* PLATFORM_DEFAULT_BL1 */
#endif /* BL1 */
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ uint8_t ns_nv_counter_0[64];
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ uint8_t ns_nv_counter_1[64];
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ uint8_t ns_nv_counter_2[64];
+#endif
+
uint8_t secure_debug_pk[32];
};
};
@@ -726,6 +736,22 @@
#endif /* PLATFORM_DEFAULT_BL1 */
#endif /* BL1 */
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ case PLAT_OTP_ID_NV_COUNTER_NS_0:
+ return otp_read(otp->ns_nv_counter_0,
+ sizeof(otp->ns_nv_counter_0), out_len, out);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ case PLAT_OTP_ID_NV_COUNTER_NS_1:
+ return otp_read(otp->ns_nv_counter_1,
+ sizeof(otp->ns_nv_counter_1), out_len, out);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ case PLAT_OTP_ID_NV_COUNTER_NS_2:
+ return otp_read(otp->ns_nv_counter_2,
+ sizeof(otp->ns_nv_counter_2), out_len, out);
+#endif
+
case PLAT_OTP_ID_ENTROPY_SEED:
return TFM_PLAT_ERR_UNSUPPORTED;
@@ -947,6 +973,22 @@
#endif /* PLATFORM_DEFAULT_BL1 */
#endif /* BL1 */
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ case PLAT_OTP_ID_NV_COUNTER_NS_0:
+ return otp_write(otp->ns_nv_counter_0,
+ sizeof(otp->ns_nv_counter_0), in_len, in, NULL);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ case PLAT_OTP_ID_NV_COUNTER_NS_1:
+ return otp_write(otp->ns_nv_counter_1,
+ sizeof(otp->ns_nv_counter_1), in_len, in, NULL);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ case PLAT_OTP_ID_NV_COUNTER_NS_2:
+ return otp_write(otp->ns_nv_counter_2,
+ sizeof(otp->ns_nv_counter_2), in_len, in, NULL);
+#endif
+
case PLAT_OTP_ID_ENTROPY_SEED:
return TFM_PLAT_ERR_UNSUPPORTED;
@@ -1055,6 +1097,22 @@
#endif /* PLATFORM_DEFAULT_BL1 */
#endif
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ case PLAT_OTP_ID_NV_COUNTER_NS_0:
+ *size = sizeof(otp->ns_nv_counter_0);
+ break;
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ case PLAT_OTP_ID_NV_COUNTER_NS_1:
+ *size = sizeof(otp->ns_nv_counter_1);
+ break;
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ case PLAT_OTP_ID_NV_COUNTER_NS_2:
+ *size = sizeof(otp->ns_nv_counter_2);
+ break;
+#endif
+
case PLAT_OTP_ID_ENTROPY_SEED:
return TFM_PLAT_ERR_UNSUPPORTED;
diff --git a/platform/ext/common/template/flash_otp_nv_counters_backend.h b/platform/ext/common/template/flash_otp_nv_counters_backend.h
index 61f9d8d..14d156f 100644
--- a/platform/ext/common/template/flash_otp_nv_counters_backend.h
+++ b/platform/ext/common/template/flash_otp_nv_counters_backend.h
@@ -55,6 +55,16 @@
uint8_t bl1_nv_counter_0[16];
#endif /* BL1 */
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ uint8_t ns_nv_counter_0[64];
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ uint8_t ns_nv_counter_1[64];
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ uint8_t ns_nv_counter_2[64];
+#endif
+
uint8_t entropy_seed[64];
uint8_t secure_debug_pk[32];
diff --git a/platform/ext/common/template/nv_counters.c b/platform/ext/common/template/nv_counters.c
index 7294f62..41648ef 100644
--- a/platform/ext/common/template/nv_counters.c
+++ b/platform/ext/common/template/nv_counters.c
@@ -140,6 +140,19 @@
return read_nv_counter_otp(PLAT_OTP_ID_NV_COUNTER_BL1_0, size, val);
#endif /* BL1 */
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ case (PLAT_NV_COUNTER_NS_0):
+ return read_nv_counter_otp(PLAT_OTP_ID_NV_COUNTER_NS_0, size, val);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ case (PLAT_NV_COUNTER_NS_1):
+ return read_nv_counter_otp(PLAT_OTP_ID_NV_COUNTER_NS_1, size, val);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ case (PLAT_NV_COUNTER_NS_2):
+ return read_nv_counter_otp(PLAT_OTP_ID_NV_COUNTER_NS_2, size, val);
+#endif
+
default:
return TFM_PLAT_ERR_UNSUPPORTED;
}
@@ -245,6 +258,20 @@
case (PLAT_NV_COUNTER_BL1_0):
return set_nv_counter_otp(PLAT_OTP_ID_NV_COUNTER_BL1_0, value);
#endif /* BL1 */
+
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ case (PLAT_NV_COUNTER_NS_0):
+ return set_nv_counter_otp(PLAT_OTP_ID_NV_COUNTER_NS_0, value);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ case (PLAT_NV_COUNTER_NS_1):
+ return set_nv_counter_otp(PLAT_OTP_ID_NV_COUNTER_NS_1, value);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ case (PLAT_NV_COUNTER_NS_2):
+ return set_nv_counter_otp(PLAT_OTP_ID_NV_COUNTER_NS_2, value);
+#endif
+
default:
return TFM_PLAT_ERR_UNSUPPORTED;
}
diff --git a/platform/ext/common/template/otp_flash.c b/platform/ext/common/template/otp_flash.c
index 54df5a1..4b834d6 100644
--- a/platform/ext/common/template/otp_flash.c
+++ b/platform/ext/common/template/otp_flash.c
@@ -50,67 +50,80 @@
size_t out_len, uint8_t *out)
{
switch (id) {
- case PLAT_OTP_ID_HUK:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, huk), out_len, out);
- case PLAT_OTP_ID_IAK:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, iak), out_len, out);
- case PLAT_OTP_ID_IAK_LEN:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, iak_len), out_len, out);
- case PLAT_OTP_ID_IAK_TYPE:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, iak_type), out_len, out);
- case PLAT_OTP_ID_IAK_ID:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, iak_id), out_len, out);
+ case PLAT_OTP_ID_HUK:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, huk), out_len, out);
+ case PLAT_OTP_ID_IAK:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, iak), out_len, out);
+ case PLAT_OTP_ID_IAK_LEN:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, iak_len), out_len, out);
+ case PLAT_OTP_ID_IAK_TYPE:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, iak_type), out_len, out);
+ case PLAT_OTP_ID_IAK_ID:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, iak_id), out_len, out);
- case PLAT_OTP_ID_BOOT_SEED:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, boot_seed), out_len, out);
- case PLAT_OTP_ID_LCS:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, lcs), out_len, out);
- case PLAT_OTP_ID_IMPLEMENTATION_ID:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, implementation_id), out_len, out);
- case PLAT_OTP_ID_HW_VERSION:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, hw_version), out_len, out);
- case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, verification_service_url), out_len, out);
- case PLAT_OTP_ID_PROFILE_DEFINITION:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, profile_definition), out_len, out);
+ case PLAT_OTP_ID_BOOT_SEED:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, boot_seed), out_len, out);
+ case PLAT_OTP_ID_LCS:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, lcs), out_len, out);
+ case PLAT_OTP_ID_IMPLEMENTATION_ID:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, implementation_id), out_len, out);
+ case PLAT_OTP_ID_HW_VERSION:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, hw_version), out_len, out);
+ case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, verification_service_url), out_len, out);
+ case PLAT_OTP_ID_PROFILE_DEFINITION:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, profile_definition), out_len, out);
#ifdef BL2
- case PLAT_OTP_ID_BL2_ROTPK_0:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_rotpk_0), out_len, out);
- case PLAT_OTP_ID_BL2_ROTPK_1:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_rotpk_1), out_len, out);
- case PLAT_OTP_ID_BL2_ROTPK_2:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_rotpk_2), out_len, out);
- case PLAT_OTP_ID_BL2_ROTPK_3:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_rotpk_3), out_len, out);
+ case PLAT_OTP_ID_BL2_ROTPK_0:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_rotpk_0), out_len, out);
+ case PLAT_OTP_ID_BL2_ROTPK_1:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_rotpk_1), out_len, out);
+ case PLAT_OTP_ID_BL2_ROTPK_2:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_rotpk_2), out_len, out);
+ case PLAT_OTP_ID_BL2_ROTPK_3:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_rotpk_3), out_len, out);
- case PLAT_OTP_ID_NV_COUNTER_BL2_0:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_0), out_len, out);
- case PLAT_OTP_ID_NV_COUNTER_BL2_1:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_1), out_len, out);
- case PLAT_OTP_ID_NV_COUNTER_BL2_2:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_2), out_len, out);
- case PLAT_OTP_ID_NV_COUNTER_BL2_3:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_3), out_len, out);
+ case PLAT_OTP_ID_NV_COUNTER_BL2_0:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_0), out_len, out);
+ case PLAT_OTP_ID_NV_COUNTER_BL2_1:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_1), out_len, out);
+ case PLAT_OTP_ID_NV_COUNTER_BL2_2:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_2), out_len, out);
+ case PLAT_OTP_ID_NV_COUNTER_BL2_3:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_3), out_len, out);
#endif /* BL2 */
#ifdef BL1
- case PLAT_OTP_ID_BL1_ROTPK_0:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_rotpk_0), out_len, out);
+ case PLAT_OTP_ID_BL1_ROTPK_0:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_rotpk_0), out_len, out);
- case PLAT_OTP_ID_NV_COUNTER_BL1_0:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_nv_counter_0), out_len, out);
+ case PLAT_OTP_ID_NV_COUNTER_BL1_0:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_nv_counter_0), out_len, out);
#endif /* BL1 */
- case PLAT_OTP_ID_ENTROPY_SEED:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, entropy_seed), out_len, out);
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ case PLAT_OTP_ID_NV_COUNTER_NS_0:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, ns_nv_counter_0), out_len, out);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ case PLAT_OTP_ID_NV_COUNTER_NS_1:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, ns_nv_counter_1), out_len, out);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ case PLAT_OTP_ID_NV_COUNTER_NS_2:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, ns_nv_counter_2), out_len, out);
+#endif
- case PLAT_OTP_ID_SECURE_DEBUG_PK:
- return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, secure_debug_pk), out_len, out);
+ case PLAT_OTP_ID_ENTROPY_SEED:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, entropy_seed), out_len, out);
- default:
- return TFM_PLAT_ERR_UNSUPPORTED;
+ case PLAT_OTP_ID_SECURE_DEBUG_PK:
+ return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, secure_debug_pk), out_len, out);
+
+ default:
+ return TFM_PLAT_ERR_UNSUPPORTED;
}
}
@@ -210,6 +223,19 @@
return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_nv_counter_0), in_len, in);
#endif /* BL1 */
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ case PLAT_OTP_ID_NV_COUNTER_NS_0:
+ return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, ns_nv_counter_0), in_len, in);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ case PLAT_OTP_ID_NV_COUNTER_NS_1:
+ return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, ns_nv_counter_1), in_len, in);
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ case PLAT_OTP_ID_NV_COUNTER_NS_2:
+ return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, ns_nv_counter_2), in_len, in);
+#endif
+
case PLAT_OTP_ID_ENTROPY_SEED:
return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, entropy_seed), in_len, in);
@@ -235,89 +261,105 @@
size_t *size)
{
switch (id) {
- case PLAT_OTP_ID_HUK:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->huk);
- break;
- case PLAT_OTP_ID_IAK:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->iak);
- break;
- case PLAT_OTP_ID_IAK_LEN:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->iak_len);
- break;
- case PLAT_OTP_ID_IAK_TYPE:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->iak_type);
- break;
- case PLAT_OTP_ID_IAK_ID:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->iak_id);
- break;
+ case PLAT_OTP_ID_HUK:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->huk);
+ break;
+ case PLAT_OTP_ID_IAK:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->iak);
+ break;
+ case PLAT_OTP_ID_IAK_LEN:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->iak_len);
+ break;
+ case PLAT_OTP_ID_IAK_TYPE:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->iak_type);
+ break;
+ case PLAT_OTP_ID_IAK_ID:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->iak_id);
+ break;
- case PLAT_OTP_ID_BOOT_SEED:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->boot_seed);
- break;
- case PLAT_OTP_ID_LCS:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->lcs);
- break;
- case PLAT_OTP_ID_IMPLEMENTATION_ID:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->implementation_id);
- break;
- case PLAT_OTP_ID_HW_VERSION:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->hw_version);
- break;
- case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->verification_service_url);
- break;
- case PLAT_OTP_ID_PROFILE_DEFINITION:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->profile_definition);
- break;
+ case PLAT_OTP_ID_BOOT_SEED:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->boot_seed);
+ break;
+ case PLAT_OTP_ID_LCS:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->lcs);
+ break;
+ case PLAT_OTP_ID_IMPLEMENTATION_ID:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->implementation_id);
+ break;
+ case PLAT_OTP_ID_HW_VERSION:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->hw_version);
+ break;
+ case PLAT_OTP_ID_VERIFICATION_SERVICE_URL:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->verification_service_url);
+ break;
+ case PLAT_OTP_ID_PROFILE_DEFINITION:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->profile_definition);
+ break;
#ifdef BL2
- case PLAT_OTP_ID_BL2_ROTPK_0:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_rotpk_0);
- break;
- case PLAT_OTP_ID_BL2_ROTPK_1:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_rotpk_1);
- break;
- case PLAT_OTP_ID_BL2_ROTPK_2:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_rotpk_2);
- break;
- case PLAT_OTP_ID_BL2_ROTPK_3:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_rotpk_3);
- break;
+ case PLAT_OTP_ID_BL2_ROTPK_0:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_rotpk_0);
+ break;
+ case PLAT_OTP_ID_BL2_ROTPK_1:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_rotpk_1);
+ break;
+ case PLAT_OTP_ID_BL2_ROTPK_2:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_rotpk_2);
+ break;
+ case PLAT_OTP_ID_BL2_ROTPK_3:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_rotpk_3);
+ break;
- case PLAT_OTP_ID_NV_COUNTER_BL2_0:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_nv_counter_0);
- break;
- case PLAT_OTP_ID_NV_COUNTER_BL2_1:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_nv_counter_1);
- break;
- case PLAT_OTP_ID_NV_COUNTER_BL2_2:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_nv_counter_2);
- break;
- case PLAT_OTP_ID_NV_COUNTER_BL2_3:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_nv_counter_3);
- break;
+ case PLAT_OTP_ID_NV_COUNTER_BL2_0:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_nv_counter_0);
+ break;
+ case PLAT_OTP_ID_NV_COUNTER_BL2_1:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_nv_counter_1);
+ break;
+ case PLAT_OTP_ID_NV_COUNTER_BL2_2:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_nv_counter_2);
+ break;
+ case PLAT_OTP_ID_NV_COUNTER_BL2_3:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl2_nv_counter_3);
+ break;
#endif /* BL2 */
#ifdef BL1
- case PLAT_OTP_ID_BL1_ROTPK_0:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl1_rotpk_0);
- break;
+ case PLAT_OTP_ID_BL1_ROTPK_0:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl1_rotpk_0);
+ break;
- case PLAT_OTP_ID_NV_COUNTER_BL1_0:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl1_nv_counter_0);
- break;
+ case PLAT_OTP_ID_NV_COUNTER_BL1_0:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl1_nv_counter_0);
+ break;
#endif /* BL1 */
- case PLAT_OTP_ID_ENTROPY_SEED:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->entropy_seed);
- break;
+#if (PLATFORM_NS_NV_COUNTERS > 0)
+ case PLAT_OTP_ID_NV_COUNTER_NS_0:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->ns_nv_counter_0);
+ break;
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 1)
+ case PLAT_OTP_ID_NV_COUNTER_NS_1:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->ns_nv_counter_1);
+ break;
+#endif
+#if (PLATFORM_NS_NV_COUNTERS > 2)
+ case PLAT_OTP_ID_NV_COUNTER_NS_2:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->ns_nv_counter_2);
+ break;
+#endif
- case PLAT_OTP_ID_SECURE_DEBUG_PK:
- *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->secure_debug_pk);
- break;
+ case PLAT_OTP_ID_ENTROPY_SEED:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->entropy_seed);
+ break;
- default:
- return TFM_PLAT_ERR_UNSUPPORTED;
+ case PLAT_OTP_ID_SECURE_DEBUG_PK:
+ *size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->secure_debug_pk);
+ break;
+
+ default:
+ return TFM_PLAT_ERR_UNSUPPORTED;
}
return TFM_PLAT_ERR_SUCCESS;
diff --git a/platform/include/tfm_plat_nv_counters.h b/platform/include/tfm_plat_nv_counters.h
index 1be2651..5a5da55 100644
--- a/platform/include/tfm_plat_nv_counters.h
+++ b/platform/include/tfm_plat_nv_counters.h
@@ -26,6 +26,10 @@
#include <stdint.h>
#include "tfm_plat_defs.h"
+#ifndef PLATFORM_NS_NV_COUNTERS
+#define PLATFORM_NS_NV_COUNTERS 0
+#endif
+
enum tfm_nv_counter_t {
PLAT_NV_COUNTER_PS_0 = 0, /* Used by PS service */
PLAT_NV_COUNTER_PS_1, /* Used by PS service */
@@ -38,6 +42,11 @@
PLAT_NV_COUNTER_BL1_0, /* Used by bootloader */
+ /* NS counters must be contiguous */
+ PLAT_NV_COUNTER_NS_0, /* Used by NS */
+ PLAT_NV_COUNTER_NS_1, /* Used by NS */
+ PLAT_NV_COUNTER_NS_2, /* Used by NS */
+
PLAT_NV_COUNTER_MAX,
PLAT_NV_COUNTER_BOUNDARY = UINT32_MAX /* Fix tfm_nv_counter_t size
to 4 bytes */
diff --git a/platform/include/tfm_plat_otp.h b/platform/include/tfm_plat_otp.h
index 40d1afb..825614d 100644
--- a/platform/include/tfm_plat_otp.h
+++ b/platform/include/tfm_plat_otp.h
@@ -40,6 +40,10 @@
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,
diff --git a/secure_fw/partitions/platform/platform_sp.c b/secure_fw/partitions/platform/platform_sp.c
index 4dfce2e..b0d60eb 100644
--- a/secure_fw/partitions/platform/platform_sp.c
+++ b/secure_fw/partitions/platform/platform_sp.c
@@ -57,6 +57,15 @@
return TFM_PLATFORM_ERR_NOT_SUPPORTED;
}
#endif
+ case PLAT_NV_COUNTER_NS_0:
+ case PLAT_NV_COUNTER_NS_1:
+ case PLAT_NV_COUNTER_NS_2:
+ /* TODO how does this interact with the ns_ctx extension? */
+ if (client_id < 0) {
+ return TFM_PLATFORM_ERR_SUCCESS;
+ } else {
+ return TFM_PLATFORM_ERR_NOT_SUPPORTED;
+ }
default:
return TFM_PLATFORM_ERR_NOT_SUPPORTED;
}
@@ -105,6 +114,9 @@
if (status != (int32_t)TFM_SUCCESS) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
}
+ if (client_id < 0) {
+ counter_id += PLAT_NV_COUNTER_NS_0;
+ }
if (nv_counter_permissions_check(client_id, counter_id, true)
!= TFM_PLAT_ERR_SUCCESS) {
@@ -138,14 +150,17 @@
}
counter_id = *((enum tfm_nv_counter_t *)in_vec[0].base);
+ if (client_id < 0) {
+ counter_id += PLAT_NV_COUNTER_NS_0;
+ }
if (nv_counter_permissions_check(client_id, counter_id, false)
!= TFM_PLAT_ERR_SUCCESS) {
- return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
}
err = tfm_plat_increment_nv_counter(counter_id);
if (err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
}
return TFM_PLATFORM_ERR_SUCCESS;
@@ -187,11 +202,14 @@
}
num = psa_read(msg->handle, 0, &counter_id, msg->in_size[0]);
-
if (num != msg->in_size[0]) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
}
+ if (msg->client_id < 0) {
+ counter_id += PLAT_NV_COUNTER_NS_0;
+ }
+
if (nv_counter_permissions_check(msg->client_id, counter_id, false)
!= TFM_PLATFORM_ERR_SUCCESS) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
@@ -210,6 +228,10 @@
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
}
+ if (msg->client_id < 0) {
+ counter_id += PLAT_NV_COUNTER_NS_0;
+ }
+
if (nv_counter_permissions_check(msg->client_id, counter_id, true)
!= TFM_PLATFORM_ERR_SUCCESS) {
return TFM_PLATFORM_ERR_SYSTEM_ERROR;
diff --git a/secure_fw/partitions/platform/tfm_platform.yaml b/secure_fw/partitions/platform/tfm_platform.yaml
index 2efa02b..a0d3972 100644
--- a/secure_fw/partitions/platform/tfm_platform.yaml
+++ b/secure_fw/partitions/platform/tfm_platform.yaml
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -30,7 +30,7 @@
{
"name": "TFM_SP_PLATFORM_NV_COUNTER",
"sid": "0x00000042",
- "non_secure_clients": false,
+ "non_secure_clients": true,
"version": 1,
"version_policy": "STRICT"
}
@@ -55,14 +55,14 @@
{
"name": "TFM_SP_PLATFORM_NV_COUNTER_READ",
"signal": "PLATFORM_SP_NV_COUNTER_READ",
- "non_secure_clients": false,
+ "non_secure_clients": true,
"minor_version": 1,
"minor_policy": "STRICT"
},
{
"name": "TFM_SP_PLATFORM_NV_COUNTER_INCREMENT",
"signal": "PLATFORM_SP_NV_COUNTER_INCREMENT",
- "non_secure_clients": false,
+ "non_secure_clients": true,
"minor_version": 1,
"minor_policy": "STRICT"
}