Platform: Added a Non-Volatile counters service
This patch introduces a new platform service exposing
the non-volatile counters. Secure partitions can use
this secure API to access the initialisation,
increment and read operations on the nv counters,
by setting "TFM_SP_PLATFORM_NV_COUNTER" as a dependency.
Change-Id: Ia564e24417dfd9bb95cc61634dbbea17caa5974c
Signed-off-by: Minos Galanakis <minos.galanakis@arm.com>
diff --git a/docs/user_guides/services/tfm_platform_integration_guide.rst b/docs/user_guides/services/tfm_platform_integration_guide.rst
index db9d00d..767236e 100644
--- a/docs/user_guides/services/tfm_platform_integration_guide.rst
+++ b/docs/user_guides/services/tfm_platform_integration_guide.rst
@@ -73,6 +73,31 @@
An IOCTL request type not supported on a particular platform should return
``TFM_PLATFORM_ERR_NOT_SUPPORTED``
+Non-Volatile counters
+=====================
+
+The Platform Service provides an abstracted service for exposing the NV counters
+to the secure world. The following operations are supported:
+
+- Increment a counter.
+- Read a counter value to a preallocated buffer.
+
+.. code-block:: c
+
+ enum tfm_platform_err_t
+ tfm_platform_nv_counter_increment(uint32_t counter_id);
+
+ enum tfm_platform_err_t
+ tfm_platform_nv_counter_read(uint32_t counter_id,
+ uint32_t size, uint8_t *val);
+
+The range of counters id is defined in :
+``platform/include/tfm_plat_nv_counters.h``
+
+For Level 2,3 isolation implementations, secure partitions in the
+Application Root of Trust, should have ``TFM_SP_PLATFORM_NV_COUNTER`` set as a
+dependency for access to the NV counter API.
+
***************************
Current Service Limitations
***************************
diff --git a/interface/include/psa_manifest/sid.h b/interface/include/psa_manifest/sid.h
index 4e9e440..4b9b8c9 100644
--- a/interface/include/psa_manifest/sid.h
+++ b/interface/include/psa_manifest/sid.h
@@ -45,6 +45,8 @@
#define TFM_SP_PLATFORM_SYSTEM_RESET_VERSION (1U)
#define TFM_SP_PLATFORM_IOCTL_SID (0x00000041U)
#define TFM_SP_PLATFORM_IOCTL_VERSION (1U)
+#define TFM_SP_PLATFORM_NV_COUNTER_SID (0x00000042U)
+#define TFM_SP_PLATFORM_NV_COUNTER_VERSION (1U)
/******** TFM_SP_INITIAL_ATTESTATION ********/
#define TFM_ATTEST_GET_TOKEN_SID (0x00000020U)
diff --git a/interface/include/tfm_platform_api.h b/interface/include/tfm_platform_api.h
index fbbd757..8c9b0db 100644
--- a/interface/include/tfm_platform_api.h
+++ b/interface/include/tfm_platform_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -23,6 +23,9 @@
#define TFM_PLATFORM_API_VERSION_MAJOR (0)
#define TFM_PLATFORM_API_VERSION_MINOR (3)
+#define TFM_PLATFORM_API_ID_NV_READ (1010)
+#define TFM_PLATFORM_API_ID_NV_INCREMENT (1011)
+
/*!
* \enum tfm_platform_err_t
*
@@ -62,6 +65,31 @@
psa_invec *input,
psa_outvec *output);
+/*!
+ * \brief Increments the given non-volatile (NV) counter by one
+ *
+ * \param[in] counter_id NV counter ID.
+ *
+ * \return TFM_PLATFORM_ERR_SUCCESS if the value is read correctly. Otherwise,
+ * it returns TFM_PLATFORM_ERR_SYSTEM_ERROR.
+ */
+enum tfm_platform_err_t
+tfm_platform_nv_counter_increment(uint32_t counter_id);
+
+/*!
+ * \brief Reads the given non-volatile (NV) counter
+ *
+ * \param[in] counter_id NV counter ID.
+ * \param[in] size Size of the buffer to store NV counter value
+ * in bytes.
+ * \param[out] val Pointer to store the current NV counter value.
+ *
+ * \return TFM_PLATFORM_ERR_SUCCESS if the value is read correctly. Otherwise,
+ * it returns TFM_PLATFORM_ERR_SYSTEM_ERROR.
+ */
+enum tfm_platform_err_t
+tfm_platform_nv_counter_read(uint32_t counter_id,
+ uint32_t size, uint8_t *val);
#ifdef __cplusplus
}
diff --git a/interface/include/tfm_veneers.h b/interface/include/tfm_veneers.h
index 5f9c5b6..d2d9207 100644
--- a/interface/include/tfm_veneers.h
+++ b/interface/include/tfm_veneers.h
@@ -112,6 +112,8 @@
/******** TFM_SP_PLATFORM ********/
psa_status_t tfm_platform_sp_system_reset_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_platform_sp_ioctl_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_platform_sp_nv_counter_read_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_platform_sp_nv_counter_increment_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_PLATFORM */
#ifdef TFM_PARTITION_INITIAL_ATTESTATION
diff --git a/platform/include/tfm_plat_nv_counters.h b/platform/include/tfm_plat_nv_counters.h
index 5d63399..3588929 100644
--- a/platform/include/tfm_plat_nv_counters.h
+++ b/platform/include/tfm_plat_nv_counters.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -34,7 +34,9 @@
PLAT_NV_COUNTER_3, /* Used by bootloader */
PLAT_NV_COUNTER_4, /* Used by bootloader */
#endif
- PLAT_NV_COUNTER_MAX
+ PLAT_NV_COUNTER_MAX,
+ PLAT_NV_COUNTER_BOUNDARY = UINT32_MAX /* Fix tfm_nv_counter_t size
+ to 4 bytes */
};
#ifdef __cplusplus
diff --git a/secure_fw/ns_callable/tfm_veneers.c b/secure_fw/ns_callable/tfm_veneers.c
index 697860a..02b0ca4 100644
--- a/secure_fw/ns_callable/tfm_veneers.c
+++ b/secure_fw/ns_callable/tfm_veneers.c
@@ -106,6 +106,8 @@
/******** TFM_SP_PLATFORM ********/
psa_status_t platform_sp_system_reset(psa_invec *, size_t, psa_outvec *, size_t);
psa_status_t platform_sp_ioctl(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t platform_sp_nv_counter_read(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t platform_sp_nv_counter_increment(psa_invec *, size_t, psa_outvec *, size_t);
#endif /* TFM_PARTITION_PLATFORM */
#ifdef TFM_PARTITION_INITIAL_ATTESTATION
@@ -274,6 +276,8 @@
/******** TFM_SP_PLATFORM ********/
TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_system_reset)
TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_ioctl)
+TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_nv_counter_read)
+TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_nv_counter_increment)
#endif /* TFM_PARTITION_PLATFORM */
#ifdef TFM_PARTITION_INITIAL_ATTESTATION
diff --git a/secure_fw/services/platform/platform_sp.c b/secure_fw/services/platform/platform_sp.c
index b17e62e..9756d5d 100644
--- a/secure_fw/services/platform/platform_sp.c
+++ b/secure_fw/services/platform/platform_sp.c
@@ -8,7 +8,20 @@
#include "platform_sp.h"
#include "platform/include/tfm_platform_system.h"
+#include "platform/include/tfm_plat_nv_counters.h"
#include "secure_fw/include/tfm_spm_services_api.h"
+#include "tfm_secure_api.h"
+#include "psa_manifest/pid.h"
+
+#define NV_COUNTER_ID_SIZE sizeof(enum tfm_nv_counter_t)
+#define NV_COUNTER_MAP_SIZE 3
+
+/* Access map using NVCOUNTER_IDX -> tfm_partition-id key-value pairs */
+static const int32_t nv_counter_access_map[NV_COUNTER_MAP_SIZE] = {
+ [PLAT_NV_COUNTER_0] = TFM_SP_STORAGE,
+ [PLAT_NV_COUNTER_1] = TFM_SP_STORAGE,
+ [PLAT_NV_COUNTER_2] = TFM_SP_STORAGE
+ };
#ifdef TFM_PSA_API
#include "psa_manifest/tfm_platform.h"
@@ -22,6 +35,36 @@
typedef enum tfm_platform_err_t (*plat_func_t)(const psa_msg_t *msg);
#endif
+/*
+ * \brief Verifies ownership of a nv_counter resource to a partition id.
+ *
+ * \param[in] nv_counter_no Number of nv_counter as assigned in platform.
+ *
+ * \return true if the calling partition is allowed to access this counter id
+ */
+
+static bool nv_counter_access_grant(int32_t client_id,
+ enum tfm_nv_counter_t nv_counter_no)
+{
+ int32_t req_id;
+
+ /* Boundary check the input argument */
+ if (nv_counter_no >= NV_COUNTER_MAP_SIZE ||
+ nv_counter_no < 0 || nv_counter_no >= PLAT_NV_COUNTER_MAX) {
+ return false;
+ }
+
+ req_id = nv_counter_access_map[nv_counter_no];
+
+ /* NV Counters are indexed from 0 and incremented. A gap in the platform
+ * counter sequence is assigned a zero( invalid ) partition id
+ */
+ if (client_id == req_id && req_id != 0) {
+ return true;
+ }
+ return false;
+}
+
enum tfm_platform_err_t platform_sp_system_reset(void)
{
/* Check if SPM allows the system reset */
@@ -62,6 +105,70 @@
return tfm_platform_hal_ioctl(request, input, output);
}
+enum tfm_platform_err_t
+platform_sp_nv_counter_read(psa_invec *in_vec, uint32_t num_invec,
+ psa_outvec *out_vec, uint32_t num_outvec)
+{
+ enum tfm_plat_err_t err;
+ enum tfm_nv_counter_t counter_id;
+ uint32_t counter_size;
+ int32_t status, client_id;
+
+ if (in_vec[0].len != NV_COUNTER_ID_SIZE ||
+ num_invec != 1 || num_outvec != 1) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+ counter_id = *((enum tfm_nv_counter_t *)in_vec[0].base);
+ counter_size = out_vec[0].len;
+
+ status = tfm_core_get_caller_client_id(&client_id);
+ if (status != (int32_t)TFM_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ if (!nv_counter_access_grant(client_id, counter_id)) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+ err = tfm_plat_read_nv_counter(counter_id, counter_size,
+ (uint8_t *)out_vec[0].base);
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ return TFM_PLATFORM_ERR_SUCCESS;
+}
+
+enum tfm_platform_err_t
+platform_sp_nv_counter_increment(psa_invec *in_vec, uint32_t num_invec,
+ psa_outvec *out_vec, uint32_t num_outvec)
+{
+ enum tfm_plat_err_t err;
+ enum tfm_nv_counter_t counter_id;
+ int32_t client_id, status;
+
+ if (in_vec[0].len != NV_COUNTER_ID_SIZE ||
+ num_invec != 1 || num_outvec != 0) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ status = tfm_core_get_caller_client_id(&client_id);
+ if (status != (int32_t)TFM_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ counter_id = *((enum tfm_nv_counter_t *)in_vec[0].base);
+
+ if (!nv_counter_access_grant(client_id, counter_id)) {
+ 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_SUCCESS;
+}
+
#else /* TFM_PSA_API */
static enum tfm_platform_err_t
@@ -73,6 +180,74 @@
}
static enum tfm_platform_err_t
+platform_sp_nv_counter_ipc(const psa_msg_t *msg)
+{
+ enum tfm_plat_err_t err = TFM_PLAT_ERR_SYSTEM_ERR;
+ size_t in_len = PSA_MAX_IOVEC, out_len = PSA_MAX_IOVEC, num = 0;
+
+ enum tfm_nv_counter_t counter_id;
+ uint8_t counter_val = 0;
+
+ /* Check the number of in_vec filled */
+ while ((in_len > 0) && (msg->in_size[in_len - 1] == 0)) {
+ in_len--;
+ }
+
+ /* Check the number of out_vec filled */
+ while ((out_len > 0) && (msg->out_size[out_len - 1] == 0)) {
+ out_len--;
+ }
+ switch (msg->type) {
+ case TFM_PLATFORM_API_ID_NV_INCREMENT:
+ if (msg->in_size[0] != NV_COUNTER_ID_SIZE ||
+ in_len != 1 || out_len != 0) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ 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 (!nv_counter_access_grant(msg->client_id, counter_id)) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ err = tfm_plat_increment_nv_counter(counter_id);
+ break;
+ case TFM_PLATFORM_API_ID_NV_READ:
+ num = psa_read(msg->handle, 0, &counter_id, msg->in_size[0]);
+
+ if (msg->in_size[0] != NV_COUNTER_ID_SIZE ||
+ in_len != 1 || out_len != 1) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ if (!nv_counter_access_grant(msg->client_id, counter_id)) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+
+ err = tfm_plat_read_nv_counter(counter_id, msg->out_size[0],
+ &counter_val);
+
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+ psa_write(msg->handle, 0, &counter_val, msg->out_size[0]);
+ break;
+ default:
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ break;
+ }
+
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ }
+ return TFM_PLATFORM_ERR_SUCCESS;
+}
+
+static enum tfm_platform_err_t
platform_sp_ioctl_ipc(const psa_msg_t *msg)
{
void *input = NULL;
@@ -147,6 +322,8 @@
psa_reply(msg.handle, PSA_SUCCESS);
break;
case PSA_IPC_CALL:
+ case TFM_PLATFORM_API_ID_NV_READ:
+ case TFM_PLATFORM_API_ID_NV_INCREMENT:
status = (psa_status_t)pfn(&msg);
psa_reply(msg.handle, status);
break;
@@ -154,12 +331,7 @@
psa_reply(msg.handle, PSA_SUCCESS);
break;
default:
- /* FIXME: Should be replaced by a call to psa_panic() when it
- * becomes available.
- */
- while (1) {
- ;
- }
+ psa_panic();
}
}
@@ -167,6 +339,16 @@
enum tfm_platform_err_t platform_sp_init(void)
{
+ /* Initialise the non-volatile counters */
+ enum tfm_plat_err_t err;
+ err = tfm_plat_init_nv_counter();
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+#ifdef TFM_PSA_API
+ psa_panic();
+#else
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+#endif
+ }
#ifdef TFM_PSA_API
psa_signal_t signals = 0;
@@ -178,13 +360,11 @@
} else if (signals & TFM_SP_PLATFORM_IOCTL_SIGNAL) {
platform_signal_handle(TFM_SP_PLATFORM_IOCTL_SIGNAL,
platform_sp_ioctl_ipc);
+ } else if (signals & TFM_SP_PLATFORM_NV_COUNTER_SIGNAL) {
+ platform_signal_handle(TFM_SP_PLATFORM_NV_COUNTER_SIGNAL,
+ platform_sp_nv_counter_ipc);
} else {
- /* FIXME: Should be replaced by a call to psa_panic() when it
- * becomes available.
- */
- while (1) {
- ;
- }
+ psa_panic();
}
}
diff --git a/secure_fw/services/platform/psa_manifest/tfm_platform.h b/secure_fw/services/platform/psa_manifest/tfm_platform.h
index a3ea0c6..77fe4ce 100644
--- a/secure_fw/services/platform/psa_manifest/tfm_platform.h
+++ b/secure_fw/services/platform/psa_manifest/tfm_platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -16,6 +16,7 @@
#define TFM_SP_PLATFORM_SYSTEM_RESET_SIGNAL (1U << (0 + 4))
#define TFM_SP_PLATFORM_IOCTL_SIGNAL (1U << (1 + 4))
+#define TFM_SP_PLATFORM_NV_COUNTER_SIGNAL (1U << (2 + 4))
#ifdef __cplusplus
}
diff --git a/secure_fw/services/platform/tfm_platform.yaml b/secure_fw/services/platform/tfm_platform.yaml
index 726ee16..11fd43d 100644
--- a/secure_fw/services/platform/tfm_platform.yaml
+++ b/secure_fw/services/platform/tfm_platform.yaml
@@ -28,6 +28,14 @@
"non_secure_clients": true,
"minor_version": 1,
"minor_policy": "STRICT"
+ },
+ {
+ "name": "TFM_SP_PLATFORM_NV_COUNTER",
+ "signal": "PLATFORM_SP_NV_COUNTER_SIG",
+ "sid": "0x00000042",
+ "non_secure_clients": false,
+ "version": 1,
+ "version_policy": "STRICT"
}
],
"secure_functions": [
@@ -46,6 +54,20 @@
"non_secure_clients": true,
"version": 1,
"version_policy": "STRICT"
- }
+ },
+ {
+ "name": "TFM_SP_PLATFORM_NV_COUNTER_READ",
+ "signal": "PLATFORM_SP_NV_COUNTER_READ",
+ "non_secure_clients": false,
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "TFM_SP_PLATFORM_NV_COUNTER_INCREMENT",
+ "signal": "PLATFORM_SP_NV_COUNTER_INCREMENT",
+ "non_secure_clients": false,
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ }
]
}
diff --git a/secure_fw/services/platform/tfm_platform_secure_api.c b/secure_fw/services/platform/tfm_platform_secure_api.c
index 19739fb..5206c5d 100644
--- a/secure_fw/services/platform/tfm_platform_secure_api.c
+++ b/secure_fw/services/platform/tfm_platform_secure_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -90,3 +90,80 @@
#endif /* TFM_PSA_API */
}
+__attribute__((section("SFN")))
+enum tfm_platform_err_t
+tfm_platform_nv_counter_increment(uint32_t counter_id)
+{
+#ifdef TFM_PSA_API
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+ psa_handle_t handle = PSA_NULL_HANDLE;
+#endif
+ struct psa_invec in_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+#ifdef TFM_PSA_API
+ 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;
+ }
+#else /* TFM_PSA_API */
+ return
+ (enum tfm_platform_err_t) tfm_platform_sp_nv_counter_increment_veneer(
+ in_vec, 1, (psa_outvec *)NULL, 0);
+#endif /* TFM_PSA_API */
+}
+
+__attribute__((section("SFN")))
+enum tfm_platform_err_t
+tfm_platform_nv_counter_read(uint32_t counter_id,
+ uint32_t size, uint8_t *val)
+{
+#ifdef TFM_PSA_API
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+ psa_handle_t handle = PSA_NULL_HANDLE;
+#endif
+ 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;
+
+#ifdef TFM_PSA_API
+ 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;
+ }
+#else /* TFM_PSA_API */
+ return (enum tfm_platform_err_t) tfm_platform_sp_nv_counter_read_veneer(
+ in_vec, 1, out_vec, 1);
+#endif /* TFM_PSA_API */
+}
diff --git a/secure_fw/services/secure_storage/nv_counters/sst_nv_counters.c b/secure_fw/services/secure_storage/nv_counters/sst_nv_counters.c
index 6d49efa..276a40f 100644
--- a/secure_fw/services/secure_storage/nv_counters/sst_nv_counters.c
+++ b/secure_fw/services/secure_storage/nv_counters/sst_nv_counters.c
@@ -6,27 +6,16 @@
*/
#include "sst_nv_counters.h"
-
-psa_status_t sst_init_nv_counter(void)
-{
- enum tfm_plat_err_t err;
-
- err = tfm_plat_init_nv_counter();
- if (err != TFM_PLAT_ERR_SUCCESS) {
- return PSA_ERROR_GENERIC_ERROR;
- }
-
- return PSA_SUCCESS;
-}
+#include "tfm_platform_api.h"
psa_status_t sst_read_nv_counter(enum tfm_nv_counter_t counter_id,
uint32_t *val)
{
- enum tfm_plat_err_t err;
+ enum tfm_platform_err_t err;
- err = tfm_plat_read_nv_counter(counter_id, SST_NV_COUNTER_SIZE,
- (uint8_t *)val);
- if (err != TFM_PLAT_ERR_SUCCESS) {
+ err = tfm_platform_nv_counter_read(counter_id, SST_NV_COUNTER_SIZE,
+ (uint8_t *)val);
+ if (err != TFM_PLATFORM_ERR_SUCCESS) {
return PSA_ERROR_GENERIC_ERROR;
}
@@ -35,7 +24,7 @@
psa_status_t sst_increment_nv_counter(enum tfm_nv_counter_t counter_id)
{
- enum tfm_plat_err_t err;
+ enum tfm_platform_err_t err;
/* NOTE: tfm_plat_increment_nv_counter returns TFM_PLAT_ERR_MAX_VALUE when
* the counter reaches its maximum value. The current SST
@@ -43,8 +32,8 @@
* moment onwards, the rollback protection can not be achieved based
* on the NV counters.
*/
- err = tfm_plat_increment_nv_counter(counter_id);
- if (err != TFM_PLAT_ERR_SUCCESS) {
+ err = tfm_platform_nv_counter_increment(counter_id);
+ if (err != TFM_PLATFORM_ERR_SUCCESS) {
return PSA_ERROR_GENERIC_ERROR;
}
diff --git a/secure_fw/services/secure_storage/nv_counters/sst_nv_counters.h b/secure_fw/services/secure_storage/nv_counters/sst_nv_counters.h
index 3448413..324b471 100644
--- a/secure_fw/services/secure_storage/nv_counters/sst_nv_counters.h
+++ b/secure_fw/services/secure_storage/nv_counters/sst_nv_counters.h
@@ -31,14 +31,6 @@
#endif
/**
- * \brief Initializes all non-volatile (NV) counters.
- *
- * \return PSA_SUCCESS if the initialization succeeds, otherwise
- * PSA_ERROR_GENERIC_ERROR
- */
-psa_status_t sst_init_nv_counter(void);
-
-/**
* \brief Reads the given non-volatile (NV) counter.
*
* \param[in] counter_id NV counter ID.
diff --git a/secure_fw/services/secure_storage/sst_object_table.c b/secure_fw/services/secure_storage/sst_object_table.c
index 96a8906..2e37a08 100644
--- a/secure_fw/services/secure_storage/sst_object_table.c
+++ b/secure_fw/services/secure_storage/sst_object_table.c
@@ -810,16 +810,6 @@
{
struct sst_obj_table_t *p_table = &sst_obj_table_ctx.obj_table;
-#ifdef SST_ROLLBACK_PROTECTION
- psa_status_t err;
-
- /* Initialize SST NV counters */
- err = sst_init_nv_counter();
- if (err != PSA_SUCCESS) {
- return err;
- }
-#endif
-
/* Initialize object structure */
(void)tfm_memset(&sst_obj_table_ctx, SST_DEFAULT_EMPTY_BUFF_VAL,
sizeof(struct sst_obj_table_ctx_t));
@@ -861,13 +851,6 @@
}
#ifdef SST_ROLLBACK_PROTECTION
- /* Initialize SST NV counters */
- err = sst_init_nv_counter();
- if (err != PSA_SUCCESS) {
- (void)sst_crypto_destroykey();
- return err;
- }
-
/* Authenticate table */
err = sst_object_table_nvc_authenticate(&init_ctx);
if (err != PSA_SUCCESS) {
diff --git a/secure_fw/services/secure_storage/tfm_secure_storage.yaml b/secure_fw/services/secure_storage/tfm_secure_storage.yaml
index 643f21e..d808686 100644
--- a/secure_fw/services/secure_storage/tfm_secure_storage.yaml
+++ b/secure_fw/services/secure_storage/tfm_secure_storage.yaml
@@ -90,6 +90,7 @@
"TFM_ITS_SET",
"TFM_ITS_GET",
"TFM_ITS_GET_INFO",
- "TFM_ITS_REMOVE"
+ "TFM_ITS_REMOVE",
+ "TFM_SP_PLATFORM_NV_COUNTER"
]
}
diff --git a/secure_fw/services/tfm_service_list.inc b/secure_fw/services/tfm_service_list.inc
index 35ad61f..0cda109 100644
--- a/secure_fw/services/tfm_service_list.inc
+++ b/secure_fw/services/tfm_service_list.inc
@@ -150,6 +150,15 @@
.version = 1,
.version_policy = TFM_VERSION_POLICY_STRICT
},
+ {
+ .name = "TFM_SP_PLATFORM_NV_COUNTER",
+ .partition_id = TFM_SP_PLATFORM,
+ .signal = TFM_SP_PLATFORM_NV_COUNTER_SIGNAL,
+ .sid = 0x00000042,
+ .non_secure_client = false,
+ .version = 1,
+ .version_policy = TFM_VERSION_POLICY_STRICT
+ },
#endif /* TFM_PARTITION_PLATFORM */
#ifdef TFM_PARTITION_INITIAL_ATTESTATION
@@ -621,6 +630,13 @@
.msg_queue = {0},
.list = {0},
},
+ {
+ .service_db = NULL,
+ .partition = NULL,
+ .handle_list = {0},
+ .msg_queue = {0},
+ .list = {0},
+ },
#endif /* TFM_PARTITION_PLATFORM */
#ifdef TFM_PARTITION_INITIAL_ATTESTATION
diff --git a/secure_fw/spm/tfm_spm_db.inc b/secure_fw/spm/tfm_spm_db.inc
index d4c85d5..e9b4012 100644
--- a/secure_fw/spm/tfm_spm_db.inc
+++ b/secure_fw/spm/tfm_spm_db.inc
@@ -565,6 +565,7 @@
TFM_ITS_GET_SID,
TFM_ITS_GET_INFO_SID,
TFM_ITS_REMOVE_SID,
+ TFM_SP_PLATFORM_NV_COUNTER_SID,
};
#endif /* TFM_PARTITION_SECURE_STORAGE */
@@ -685,7 +686,7 @@
,
.partition_priority = TFM_PRIORITY(NORMAL),
.partition_init = tfm_sst_req_mngr_init,
- .dependencies_num = 5,
+ .dependencies_num = 6,
.p_dependencies = dependencies_TFM_SP_STORAGE,
},
#endif /* TFM_PARTITION_SECURE_STORAGE */
diff --git a/test/suites/sst/secure/nv_counters/test_sst_nv_counters.c b/test/suites/sst/secure/nv_counters/test_sst_nv_counters.c
index 5a2b4d1..113fb4a 100644
--- a/test/suites/sst/secure/nv_counters/test_sst_nv_counters.c
+++ b/test/suites/sst/secure/nv_counters/test_sst_nv_counters.c
@@ -18,7 +18,11 @@
#define INIT_NV_COUNTERS_VALUE 42
static uint8_t nv_increment_status = ENABLE_INCREMENT;
-static uint32_t test_nv_counters[TOTAL_SST_NV_COUNTERS] = {0};
+static uint32_t test_nv_counters[TOTAL_SST_NV_COUNTERS] = {
+ [0] = INIT_NV_COUNTERS_VALUE,
+ [1] = INIT_NV_COUNTERS_VALUE,
+ [2] = INIT_NV_COUNTERS_VALUE
+ };
static uint32_t get_nv_counter_position(enum tfm_nv_counter_t counter_id)
{
@@ -34,21 +38,6 @@
}
}
-/* Implementation of SST NV counter interfaces defined by sst_nv_counters.h */
-psa_status_t sst_init_nv_counter(void)
-{
- static uint8_t is_init = 0;
-
- if (is_init == 0) {
- test_nv_counters[0] = INIT_NV_COUNTERS_VALUE;
- test_nv_counters[1] = INIT_NV_COUNTERS_VALUE;
- test_nv_counters[2] = INIT_NV_COUNTERS_VALUE;
- is_init = 1;
- }
-
- return PSA_SUCCESS;
-}
-
psa_status_t sst_read_nv_counter(enum tfm_nv_counter_t counter_id,
uint32_t *val)
{