aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hu <david.hu@arm.com>2019-07-02 15:24:33 +0800
committerDavid Hu <david.hu@arm.com>2019-07-04 16:13:20 +0800
commitf9f77ff5a2fd15a503d75da40db05c060f5ee12a (patch)
treee9a1c480e94702a03b09c79505acfdcf8c8623a6
parent5ff8dbf63964925ff213310e91fe814348c5f43f (diff)
downloadtrusted-firmware-m-f9f77ff5a2fd15a503d75da40db05c060f5ee12a.tar.gz
Twincpu: Update PSA client call common handler implementations
Update PSA client call common handler according to latest implementations on master branch. Update the calling from RPC and secure services accordingly. Change-Id: I0dd11e566607645bf25ecdf25fe75b7fb6bb715b Signed-off-by: David Hu <david.hu@arm.com>
-rw-r--r--secure_fw/core/ipc/include/tfm_psa_client_call.h19
-rw-r--r--secure_fw/core/ipc/tfm_psa_client_call.c63
-rw-r--r--secure_fw/core/ipc/tfm_rpc.c10
-rw-r--r--secure_fw/core/ipc/tfm_svcalls.c3
4 files changed, 61 insertions, 34 deletions
diff --git a/secure_fw/core/ipc/include/tfm_psa_client_call.h b/secure_fw/core/ipc/include/tfm_psa_client_call.h
index 5928fa810d..564bfc3a1d 100644
--- a/secure_fw/core/ipc/include/tfm_psa_client_call.h
+++ b/secure_fw/core/ipc/include/tfm_psa_client_call.h
@@ -58,16 +58,19 @@ psa_status_t tfm_psa_connect(uint32_t sid, uint32_t minor_version,
*
* \param[in] handle Service handle to the established connection,
* \ref psa_handle_t
- * \param[in] in_vec Array of input psa_invec structures.
+ * \param[in] inptr Array of input psa_invec structures.
* \ref psa_invec
- * \param[in] in_len Number of input psa_invec structures.
+ * \param[in] in_num Number of input psa_invec structures.
* \ref psa_invec
- * \param[in] out_vec Array of output psa_outvec structures.
+ * \param[in] outptr Array of output psa_outvec structures.
* \ref psa_outvec
- * \param[in] out_len Number of outut psa_outvec structures.
+ * \param[in] out_num Number of outut psa_outvec structures.
* \ref psa_outvec
* \param[in] ns_caller If 'non-zero', call from non-secure client.
* Or from secure client.
+ * \param[in] privileged Privileged mode or unprivileged mode:
+ * \ref TFM_PARTITION_UNPRIVILEGED_MODE
+ * \ref TFM_PARTITION_PRIVILEGED_MODE
*
* \retval PSA_SUCCESS Success.
* \retval "Does not return" The call is invalid, one or more of the
@@ -75,13 +78,13 @@ psa_status_t tfm_psa_connect(uint32_t sid, uint32_t minor_version,
* \arg An invalid handle was passed.
* \arg The connection is already handling a request.
* \arg An invalid memory reference was provided.
- * \arg in_len + out_len > PSA_MAX_IOVEC.
+ * \arg in_num + out_num > PSA_MAX_IOVEC.
* \arg The message is unrecognized by the RoT
* Service or incorrectly formatted.
*/
-psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *in_vec,
- size_t in_len, psa_outvec *out_vec, size_t out_len,
- int32_t ns_caller);
+psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *inptr,
+ size_t in_num, psa_outvec *outptr, size_t out_num,
+ int32_t ns_caller, uint32_t privileged);
/**
* \brief handler for \ref psa_close.
diff --git a/secure_fw/core/ipc/tfm_psa_client_call.c b/secure_fw/core/ipc/tfm_psa_client_call.c
index 63cad46dc4..4ed86269b5 100644
--- a/secure_fw/core/ipc/tfm_psa_client_call.c
+++ b/secure_fw/core/ipc/tfm_psa_client_call.c
@@ -49,6 +49,7 @@ psa_status_t tfm_psa_connect(uint32_t sid, uint32_t minor_version,
{
struct tfm_spm_service_t *service;
struct tfm_msg_body_t *msg;
+ psa_handle_t connect_handle;
/* It is a fatal error if the RoT Service does not exist on the platform */
service = tfm_spm_get_service_by_sid(sid);
@@ -57,6 +58,15 @@ psa_status_t tfm_psa_connect(uint32_t sid, uint32_t minor_version,
}
/*
+ * Create connection handle here since it is possible to return the error
+ * code to client when creation fails.
+ */
+ connect_handle = tfm_spm_create_conn_handle(service);
+ if (connect_handle == PSA_NULL_HANDLE) {
+ return PSA_CONNECTION_BUSY;
+ }
+
+ /*
* It is a fatal error if the caller is not authorized to access the RoT
* Service.
*/
@@ -73,9 +83,10 @@ psa_status_t tfm_psa_connect(uint32_t sid, uint32_t minor_version,
}
/* No input or output needed for connect message */
- msg = tfm_spm_create_msg(service, PSA_NULL_HANDLE, PSA_IPC_CONNECT,
+ msg = tfm_spm_create_msg(service, connect_handle, PSA_IPC_CONNECT,
ns_caller, NULL, 0, NULL, 0, NULL);
if (!msg) {
+ /* Have no enough resource to create message */
return PSA_CONNECTION_BUSY;
}
@@ -88,9 +99,9 @@ psa_status_t tfm_psa_connect(uint32_t sid, uint32_t minor_version,
return PSA_SUCCESS;
}
-psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *in_vec,
- size_t in_len, psa_outvec *out_vec, size_t out_len,
- int32_t ns_caller)
+psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *inptr,
+ size_t in_num, psa_outvec *outptr, size_t out_num,
+ int32_t ns_caller, uint32_t privileged)
{
psa_invec invecs[PSA_MAX_IOVEC];
psa_outvec outvecs[PSA_MAX_IOVEC];
@@ -99,7 +110,7 @@ psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *in_vec,
int i;
/* It is a fatal error if in_len + out_len > PSA_MAX_IOVEC. */
- if (in_len + out_len > PSA_MAX_IOVEC) {
+ if (in_num + out_num > PSA_MAX_IOVEC) {
tfm_panic();
}
@@ -110,13 +121,22 @@ psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *in_vec,
tfm_panic();
}
- /* It is a fatal error if an invalid memory reference was provide. */
- if (tfm_memory_check((void *)in_vec, in_len * sizeof(psa_invec),
- ns_caller) != IPC_SUCCESS) {
+ /*
+ * Read client invecs from the wrap input vector. It is a fatal error
+ * if the memory reference for the wrap input vector is invalid or not
+ * readable.
+ */
+ if (tfm_memory_check((void *)inptr, in_num * sizeof(psa_invec),
+ ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
tfm_panic();
}
- if (tfm_memory_check(out_vec, out_len * sizeof(psa_outvec),
- ns_caller) != IPC_SUCCESS) {
+ /*
+ * Read client outvecs from the wrap output vector and will update the
+ * actual length later. It is a fatal error if the memory reference for
+ * the wrap output vector is invalid or not read-write.
+ */
+ if (tfm_memory_check((void *)outptr, out_num * sizeof(psa_outvec),
+ ns_caller, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
tfm_panic();
}
@@ -124,22 +144,26 @@ psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *in_vec,
tfm_memset(outvecs, 0, sizeof(outvecs));
/* Copy the address out to avoid TOCTOU attacks. */
- tfm_memcpy(invecs, in_vec, in_len * sizeof(psa_invec));
- tfm_memcpy(outvecs, out_vec, out_len * sizeof(psa_outvec));
+ tfm_memcpy(invecs, inptr, in_num * sizeof(psa_invec));
+ tfm_memcpy(outvecs, outptr, out_num * sizeof(psa_outvec));
/*
- * It is a fatal error if an invalid payload memory reference
- * was provided.
+ * For client input vector, it is a fatal error if the provided payload
+ * memory reference was invalid or not readable.
*/
- for (i = 0; i < in_len; i++) {
+ for (i = 0; i < in_num; i++) {
if (tfm_memory_check((void *)invecs[i].base, invecs[i].len,
- ns_caller) != IPC_SUCCESS) {
+ ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
tfm_panic();
}
}
- for (i = 0; i < out_len; i++) {
+ /*
+ * For client output vector, it is a fatal error if the provided payload
+ * memory reference was invalid or not read-write.
+ */
+ for (i = 0; i < out_num; i++) {
if (tfm_memory_check(outvecs[i].base, outvecs[i].len,
- ns_caller) != IPC_SUCCESS) {
+ ns_caller, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
tfm_panic();
}
}
@@ -149,7 +173,7 @@ psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *in_vec,
* Service or incorrectly formatted.
*/
msg = tfm_spm_create_msg(service, handle, PSA_IPC_CALL, ns_caller, invecs,
- in_len, outvecs, out_len, out_vec);
+ in_num, outvecs, out_num, outptr);
if (!msg) {
/* FixMe: Need to implement one mechanism to resolve this failure. */
tfm_panic();
@@ -163,7 +187,6 @@ psa_status_t tfm_psa_call(psa_handle_t handle, const psa_invec *in_vec,
/* FixMe: Need to refine failure process here. */
tfm_panic();
}
-
return PSA_SUCCESS;
}
diff --git a/secure_fw/core/ipc/tfm_rpc.c b/secure_fw/core/ipc/tfm_rpc.c
index 7a2e9b73b3..44c5fa783f 100644
--- a/secure_fw/core/ipc/tfm_rpc.c
+++ b/secure_fw/core/ipc/tfm_rpc.c
@@ -7,11 +7,10 @@
#include <stdint.h>
#include <stdio.h>
-
-#include "tfm_utils.h"
-
-#include "tfm_rpc.h"
+#include "spm_api.h"
#include "tfm_psa_client_call.h"
+#include "tfm_rpc.h"
+#include "tfm_utils.h"
static const struct tfm_rpc_ops_t *rpc_ops_ptr = NULL;
@@ -45,7 +44,8 @@ psa_status_t tfm_rpc_psa_call(const struct client_call_params_t *params,
TFM_ASSERT(params != NULL);
return tfm_psa_call(params->handle, params->in_vec, params->in_len,
- params->out_vec, params->out_len, ns_caller);
+ params->out_vec, params->out_len, ns_caller,
+ TFM_PARTITION_UNPRIVILEGED_MODE);
}
void tfm_rpc_psa_close(const struct client_call_params_t *params,
diff --git a/secure_fw/core/ipc/tfm_svcalls.c b/secure_fw/core/ipc/tfm_svcalls.c
index e33884851f..3f7b4a7875 100644
--- a/secure_fw/core/ipc/tfm_svcalls.c
+++ b/secure_fw/core/ipc/tfm_svcalls.c
@@ -121,7 +121,8 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
out_num = ((psa_invec *)args[2])->len;
}
- return tfm_psa_call(handle, inptr, in_num, outptr, out_num, ns_caller);
+ return tfm_psa_call(handle, inptr, in_num, outptr, out_num, ns_caller,
+ privileged);
}
void tfm_svcall_psa_close(uint32_t *args, int32_t ns_caller)