aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMingyang Sun <mingyang.sun@arm.com>2021-03-17 17:58:33 +0800
committerMingyang Sun <mingyang.sun@arm.com>2021-03-22 15:05:16 +0800
commit453ad40c80eb64c6c9f86ddcf2b513a3ed372291 (patch)
tree4d22d820f17877a3f0a37eb7b7091f029ef66804
parent062594f65de20bc8c1878cbd530af27030735da8 (diff)
downloadtrusted-firmware-m-453ad40c80eb64c6c9f86ddcf2b513a3ed372291.tar.gz
SPM: Implement version check for stateless service
Encode the service version and stateless indicator into stateless handle, validate the stateless handle indicator, version and index before using. Change-Id: Id5f388f938a758803863958dfbb0c0011c2e1f04 Signed-off-by: Mingyang Sun <mingyang.sun@arm.com>
-rw-r--r--interface/include/psa_manifest/sid.h.template2
-rw-r--r--secure_fw/spm/cmsis_psa/spm_ipc.c4
-rw-r--r--secure_fw/spm/cmsis_psa/spm_ipc.h33
-rw-r--r--secure_fw/spm/ffm/spm_psa_client_call.c21
-rw-r--r--tools/tfm_parse_manifest_list.py17
5 files changed, 61 insertions, 16 deletions
diff --git a/interface/include/psa_manifest/sid.h.template b/interface/include/psa_manifest/sid.h.template
index bc478a57ec..e188d62b7b 100644
--- a/interface/include/psa_manifest/sid.h.template
+++ b/interface/include/psa_manifest/sid.h.template
@@ -29,7 +29,7 @@ extern "C" {
{% endif %}
{% if partition.manifest.psa_framework_version > 1.0 and service.connection_based == false %}
{% set str = service.name + "_HANDLE" %}
-#define {{"%-58s"|format(str)}} ({{"%d"|format(service.stateless_handle)}}U)
+#define {{"%-58s"|format(str)}} ({{"%s"|format(service.stateless_handle)}}U)
{% endif %}
{% endfor %}
{% endif %}
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index 0a32695ffb..3c20fedeaa 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -753,14 +753,14 @@ uint32_t tfm_spm_init(void)
/* Populate the p_service of stateless_service_ref[] */
if (service_db[i].connection_based == false) {
- for (j = 0; j < STATIC_HANDLE_VALUE_LIMIT; j++) {
+ for (j = 0; j < STATIC_HANDLE_NUM_LIMIT; j++) {
if (stateless_service_ref[j].sid == service_db[i].sid) {
stateless_service_ref[j].p_service = &service[i];
break;
}
}
/* Stateless service not found in tracking table */
- if (j >= STATIC_HANDLE_VALUE_LIMIT) {
+ if (j >= STATIC_HANDLE_NUM_LIMIT) {
tfm_core_panic();
}
}
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h
index dd029115e1..dc0fd1f0a7 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -29,11 +29,34 @@
#define TFM_CONN_HANDLE_MAX_NUM 16
-/* Set a minimum for client handle. Reserve small values for static handle. */
-#define STATIC_HANDLE_VALUE_LIMIT 32
-#define CLIENT_HANDLE_VALUE_MIN (STATIC_HANDLE_VALUE_LIMIT + 1)
-#define IS_STATIC_HANDLE(h) ((h) > 0 && \
- (h) <= STATIC_HANDLE_VALUE_LIMIT)
+/*
+ * Set a number limit for stateless handle.
+ * Valid handle must be positive, set client handle minimum value to 1.
+ */
+#define STATIC_HANDLE_NUM_LIMIT 32
+#define CLIENT_HANDLE_VALUE_MIN 1
+
+#define STAIC_HANDLE_IDX_BIT_WIDTH 8
+#define STAIC_HANDLE_IDX_MASK \
+ (uint32_t)((1UL << STAIC_HANDLE_IDX_BIT_WIDTH) - 1)
+#define GET_INDEX_FROM_STATIC_HANDLE(handle) \
+ (uint32_t)(((handle) & STAIC_HANDLE_IDX_MASK) - 1)
+
+#define STAIC_HANDLE_VER_BIT_WIDTH 8
+#define STAIC_HANDLE_VER_OFFSET 8
+#define STAIC_HANDLE_VER_MASK \
+ (uint32_t)((1UL << STAIC_HANDLE_VER_BIT_WIDTH) - 1)
+#define GET_VERSION_FROM_STATIC_HANDLE(handle) \
+ (uint32_t)(((handle) >> STAIC_HANDLE_VER_OFFSET) & STAIC_HANDLE_VER_MASK)
+
+#define STAIC_HANDLE_INDICATOR_OFFSET 30
+/*
+ * A valid static handle must have indicator bit set, have a positive index,
+ * 1 <= index <= STATIC_HANDLE_NUM_LIMIT.
+ */
+#define IS_VALID_STATIC_HANDLE(handle) \
+ (((handle) & (1UL << STAIC_HANDLE_INDICATOR_OFFSET)) && \
+ (GET_INDEX_FROM_STATIC_HANDLE(handle) < STATIC_HANDLE_NUM_LIMIT))
#define SPM_INVALID_PARTITION_IDX (~0U)
diff --git a/secure_fw/spm/ffm/spm_psa_client_call.c b/secure_fw/spm/ffm/spm_psa_client_call.c
index 6fbc34672f..28f5987df8 100644
--- a/secure_fw/spm/ffm/spm_psa_client_call.c
+++ b/secure_fw/spm/ffm/spm_psa_client_call.c
@@ -15,6 +15,9 @@
#include "tfm_nspm.h"
#include "ffm/spm_error_base.h"
+#define GET_STATELESS_SERVICE(index) (stateless_service_ref[index].p_service)
+#define GET_STATELESS_SID(index) (stateless_service_ref[index].sid)
+
extern struct stateless_service_tracking_t stateless_service_ref[];
uint32_t tfm_spm_client_psa_framework_version(void)
@@ -132,7 +135,7 @@ psa_status_t tfm_spm_client_psa_call(psa_handle_t handle, int32_t type,
struct tfm_msg_body_t *msg;
int i, j;
int32_t client_id;
- uint32_t sid;
+ uint32_t sid, version, index;
/* It is a PROGRAMMER ERROR if in_len + out_len > PSA_MAX_IOVEC. */
if ((in_num > PSA_MAX_IOVEC) ||
@@ -148,9 +151,11 @@ psa_status_t tfm_spm_client_psa_call(psa_handle_t handle, int32_t type,
}
/* Allocate space from handle pool for static handle. */
- if (IS_STATIC_HANDLE(handle)) {
- service = stateless_service_ref[(uint32_t)handle-1].p_service;
- sid = stateless_service_ref[(uint32_t)handle-1].sid;
+ if (IS_VALID_STATIC_HANDLE(handle)) {
+ index = GET_INDEX_FROM_STATIC_HANDLE(handle);
+ service = GET_STATELESS_SERVICE(index);
+ sid = GET_STATELESS_SID(index);
+
/*
* It is a PROGRAMMER ERROR if the caller is not authorized to access
* the RoT Service.
@@ -160,6 +165,12 @@ psa_status_t tfm_spm_client_psa_call(psa_handle_t handle, int32_t type,
TFM_PROGRAMMER_ERROR(ns_caller, PSA_ERROR_CONNECTION_REFUSED);
}
+ version = GET_VERSION_FROM_STATIC_HANDLE(handle);
+
+ if (tfm_spm_check_client_version(service, version) != SPM_SUCCESS) {
+ TFM_PROGRAMMER_ERROR(ns_caller, PSA_ERROR_PROGRAMMER_ERROR);
+ }
+
conn_handle = tfm_spm_create_conn_handle(service, client_id);
if (!conn_handle) {
@@ -301,7 +312,7 @@ void tfm_spm_client_psa_close(psa_handle_t handle, bool ns_caller)
}
/* It is a PROGRAMMER ERROR if called with a stateless handle. */
- if (IS_STATIC_HANDLE(handle)) {
+ if (IS_VALID_STATIC_HANDLE(handle)) {
TFM_PROGRAMMER_ERROR(ns_caller, PROGRAMMER_ERROR_NULL);
}
diff --git a/tools/tfm_parse_manifest_list.py b/tools/tfm_parse_manifest_list.py
index d4a0d80ec7..cfc6bfcbde 100644
--- a/tools/tfm_parse_manifest_list.py
+++ b/tools/tfm_parse_manifest_list.py
@@ -231,12 +231,23 @@ def process_stateless_services(partitions, static_handle_max_num):
# Auto-allocate stateless handle
for i in range(0, static_handle_max_num):
- if reordered_stateless_list[i] == None:
+ if reordered_stateless_list[i] == None and len(stateless_services) > 0:
service = stateless_services.pop(0)
service['stateless_handle'] = i + 1
reordered_stateless_list[i] = service
- if len(stateless_services) == 0:
- break
+ """
+ Encode stateless flag and version into stateless handle
+ bit 30: stateless handle indicator
+ bit 15-8: stateless service version
+ bit 7-0: stateless handle index
+ """
+ if reordered_stateless_list[i] != None:
+ stateless_handle_value = reordered_stateless_list[i]['stateless_handle']
+ stateless_flag = 1 << 30
+ stateless_handle_value |= stateless_flag
+ stateless_version = (reordered_stateless_list[i]['version'] & 0xFF) << 8
+ stateless_handle_value |= stateless_version
+ reordered_stateless_list[i]['stateless_handle'] = '0x%08x' % stateless_handle_value
return reordered_stateless_list