diff options
author | David Hu <david.hu@arm.com> | 2019-07-02 15:24:33 +0800 |
---|---|---|
committer | David Hu <david.hu@arm.com> | 2019-07-04 16:13:20 +0800 |
commit | f9f77ff5a2fd15a503d75da40db05c060f5ee12a (patch) | |
tree | e9a1c480e94702a03b09c79505acfdcf8c8623a6 | |
parent | 5ff8dbf63964925ff213310e91fe814348c5f43f (diff) | |
download | trusted-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.h | 19 | ||||
-rw-r--r-- | secure_fw/core/ipc/tfm_psa_client_call.c | 63 | ||||
-rw-r--r-- | secure_fw/core/ipc/tfm_rpc.c | 10 | ||||
-rw-r--r-- | secure_fw/core/ipc/tfm_svcalls.c | 3 |
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) |