From 56f22e55a9c0bfdd58252c6136ad6d1503d457da Mon Sep 17 00:00:00 2001 From: Divneil Rai Wadhawan Date: Wed, 8 May 2019 19:15:45 +0530 Subject: [PATCH 1/3] core: add a new pta to support any ree service for TA o Following new APIs have been added for TA to access REE service - TEE_OpenREESession() - TEE_CloseREESession() - TEE_InvokeREECommand() These APIs use the same infrastructure as the Global Platform APIs, however, the first param of array TEE_Param[0] is reserved for internal use o 4 commands are reserved and should not be used explicity by TA - OPTEE_MRC_GENERIC_OPEN : Internal usage - OPTEE_MRC_GENERIC_CLOSE : Internal usage - OPTEE_MRC_GENERIC_SERVICE_START: Need to be implemented by REE service. Sent as part of session open. - OPTEE_MRC_GENERIC_SERVICE_STOP : Need to be implemented by REE service. Sent as part of session close. Signed-off-by: Divneil Rai Wadhawan --- core/arch/arm/tee/pta_generic.c | 287 ++++++++++++++++++++++++++ core/arch/arm/tee/sub.mk | 1 + core/include/optee_rpc_cmd.h | 15 ++ lib/libutee/include/pta_generic.h | 16 ++ lib/libutee/include/tee_api.h | 15 ++ lib/libutee/include/tee_api_defines.h | 1 + lib/libutee/include/tee_api_types.h | 10 + lib/libutee/sub.mk | 3 +- lib/libutee/tee_api_ree_service.c | 134 ++++++++++++ 9 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 core/arch/arm/tee/pta_generic.c mode change 100644 => 100755 core/include/optee_rpc_cmd.h create mode 100644 lib/libutee/include/pta_generic.h create mode 100644 lib/libutee/tee_api_ree_service.c diff --git a/core/arch/arm/tee/pta_generic.c b/core/arch/arm/tee/pta_generic.c new file mode 100644 index 00000000000..f2b4321c9a9 --- /dev/null +++ b/core/arch/arm/tee/pta_generic.c @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2018, Intel Corporation + */ + +#include +#include +#include +#include +#include +#include + +static uint32_t get_instance_id(struct tee_ta_session *sess) +{ + return sess->ctx->ops->get_instance_id(sess->ctx); +} + +static inline bool is_param_memref(uint32_t param_types, uint32_t idx) +{ + uint32_t ptype = TEE_PARAM_TYPE_GET(param_types, idx); + + if ((ptype == TEE_PARAM_TYPE_MEMREF_INPUT) || + (ptype == TEE_PARAM_TYPE_MEMREF_OUTPUT) || + (ptype == TEE_PARAM_TYPE_MEMREF_INOUT)) + return true; + return false; +} + +static inline bool is_param_out(uint32_t param_types, uint32_t idx) +{ + uint32_t ptype = TEE_PARAM_TYPE_GET(param_types, idx); + + if ((ptype == TEE_PARAM_TYPE_VALUE_OUTPUT) || + (ptype == TEE_PARAM_TYPE_VALUE_INOUT) || + (ptype == TEE_PARAM_TYPE_MEMREF_OUTPUT) || + (ptype == TEE_PARAM_TYPE_MEMREF_INOUT)) + return true; + return false; +} + +static inline bool is_param_value(uint32_t param_types, uint32_t idx) +{ + uint32_t ptype = TEE_PARAM_TYPE_GET(param_types, idx); + if (ptype == TEE_PARAM_TYPE_VALUE_INPUT || + ptype == TEE_PARAM_TYPE_VALUE_OUTPUT || + ptype == TEE_PARAM_TYPE_VALUE_INOUT) + return true; + + return false; +} + +static inline bool is_param_none(uint32_t param_types, uint32_t idx) +{ + if (TEE_PARAM_TYPE_GET(param_types, idx) == TEE_PARAM_TYPE_NONE) + return true; + return false; +} + +static void *alloc_transient_shm(size_t size, struct mobj **mobj) +{ + paddr_t p; + void *va; + + *mobj = thread_rpc_alloc_payload(size); + if (!*mobj) + return NULL; + + if (mobj_get_pa(*mobj, 0, 0, &p)) + goto err; + + if (!ALIGNMENT_IS_OK(p, uint64_t)) + goto err; + + va = mobj_get_va(*mobj, 0); + if (!va) + goto err; + + return va; + +err: + thread_rpc_free_payload(*mobj); + return NULL; +} + +static void free_transient_shm(struct mobj *mobj) +{ + thread_rpc_free_payload(mobj); +} + +static void *prepare_memref_params(TEE_Param *param, uint32_t param_type, + bool cached, struct mobj **mobj, + struct thread_param *tpm) +{ + void *va = NULL; + size_t size = param->memref.size; + + if (cached) + va = tee_fs_rpc_cache_alloc(size, mobj); + else + va = alloc_transient_shm(size, mobj); + if (!va) + return NULL; + + switch (param_type) { + case TEE_PARAM_TYPE_MEMREF_INPUT: + tpm[0] = THREAD_PARAM_MEMREF(IN, *mobj, 0, size); + memcpy(va, param->memref.buffer, size); + break; + case TEE_PARAM_TYPE_MEMREF_OUTPUT: + tpm[0] = THREAD_PARAM_MEMREF(OUT, *mobj, 0, size); + break; + case TEE_PARAM_TYPE_MEMREF_INOUT: + tpm[0] = THREAD_PARAM_MEMREF(INOUT, *mobj, 0, size); + break; + default: + goto err; + } + + return va; + +err: + if (!cached) + free_transient_shm(*mobj); + return NULL; +} + +static TEE_Result find_ree_service(void *sess_ctx, uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + void *va; + struct mobj *mobj; + TEE_Result res = TEE_SUCCESS; + struct thread_param tpm[3]; + uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_VALUE_OUTPUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + if (exp_pt != param_types) + return TEE_ERROR_BAD_PARAMETERS; + + /* Prepare RPC params for opening REE session */ + memset(&tpm, 0, sizeof(tpm)); + + tpm[0] = THREAD_PARAM_VALUE(IN, OPTEE_MRC_GENERIC_OPEN, (uint64_t)sess_ctx, 0); + + /* Allocate memory for passing UUID */ + va = tee_fs_rpc_cache_alloc(params[0].memref.size, &mobj); + if (!va) + return TEE_ERROR_OUT_OF_MEMORY; + + tpm[1] = THREAD_PARAM_MEMREF(OUT, mobj, 0, params[0].memref.size); + memcpy(va, params[0].memref.buffer, params[0].memref.size); + + tpm[2] = THREAD_PARAM_VALUE(OUT, 0, 0, 0); + + res = thread_rpc_cmd(OPTEE_RPC_CMD_GENERIC, 3, tpm); + if (res == TEE_SUCCESS) + params[1].value.a = tpm[2].u.value.a; + + return res; +} + +/* + * Trusted Application Entry Points + */ + +static TEE_Result pta_generic_open_session(uint32_t param_types __unused, + TEE_Param params[TEE_NUM_PARAMS] __unused, + void **sess_ctx) +{ + struct tee_ta_session *s; + + /* Check that we're called from a TA */ + s = tee_ta_get_calling_session(); + if (!s) + return TEE_ERROR_ACCESS_DENIED; + + *sess_ctx = (void *)(vaddr_t)get_instance_id(s); + + return TEE_SUCCESS; +} + +static void pta_generic_close_session(void *sess_ctx __unused) +{ + return; +} + +static TEE_Result pta_generic_invoke_command(void *sess_ctx, + uint32_t cmd_id, uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + TEE_Result res = TEE_SUCCESS; + struct mobj *mobj[THREAD_RPC_MAX_NUM_PARAMS - 1]; + void *va[THREAD_RPC_MAX_NUM_PARAMS - 1]; + struct thread_param tpm[THREAD_RPC_MAX_NUM_PARAMS]; + uint8_t i; + bool cache_allocated = false; + int32_t idx = 0, msg_params_count = 1; + + /* Find the REE service if it's available */ + if (cmd_id == OPTEE_MRC_GENERIC_OPEN) + return find_ree_service(sess_ctx, param_types, params); + + /* The first parameter has to be input value */ + if (!is_param_value(param_types, 0)) + return TEE_ERROR_BAD_PARAMETERS; + + /* Prepare RPC params */ + memset(tpm, 0, sizeof(tpm)); + + /* params[0].value.a: handle to the service */ + tpm[0] = THREAD_PARAM_VALUE(IN, cmd_id, (uint64_t)sess_ctx, params[0].value.a); + + /* + * Allocate a cached buffer for first memref and for subsequent memrefs + * allocate a transient buffer which will be freed after this call. + */ + for (i = 1; i < THREAD_RPC_MAX_NUM_PARAMS; i++) { + if (is_param_none(param_types, i)) + break; + + msg_params_count++; + + if (is_param_memref(param_types, i)) { + va[idx] = prepare_memref_params(¶ms[i], + TEE_PARAM_TYPE_GET(param_types, i), + cache_allocated ? false: true, + &mobj[idx], &tpm[i]); + if (!va[idx]) { + res = TEE_ERROR_OUT_OF_MEMORY; + goto err; + } + + cache_allocated = true; + idx++; + } else { + switch (TEE_PARAM_TYPE_GET(param_types, i)) { + case TEE_PARAM_TYPE_VALUE_INPUT: + tpm[i] = THREAD_PARAM_VALUE(IN, params[i].value.a, params[i].value.b, 0); + break; + case TEE_PARAM_TYPE_VALUE_OUTPUT: + tpm[i] = THREAD_PARAM_VALUE(OUT, params[i].value.a, params[i].value.b, 0); + break; + case TEE_PARAM_TYPE_VALUE_INOUT: + tpm[i] = THREAD_PARAM_VALUE(INOUT, params[i].value.a, params[i].value.b, 0); + break; + } + } + } + + res = thread_rpc_cmd(OPTEE_RPC_CMD_GENERIC, + msg_params_count, tpm); + if (res != TEE_SUCCESS) + goto err; + + /* Fill in OUT and INOUT params from relevant parameters */ + idx = 0; + for (i = 0; i < msg_params_count; i++) { + if (is_param_memref(param_types, i)) { + idx++; + + if (!is_param_out(param_types, i)) + continue; + + memcpy(params[i].memref.buffer, + va[idx - 1], params[i].memref.size); + } else { + if (!is_param_out(param_types, i)) + continue; + params[i].value.a = tpm[i].u.value.a; + params[i].value.b = tpm[i].u.value.b; + } + } + +err: + while (idx && --idx) + free_transient_shm(mobj[idx]); + + return res; +} + +pseudo_ta_register(.uuid = PTA_GENERIC_UUID, .name = "generic", + .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT, + .open_session_entry_point = pta_generic_open_session, + .close_session_entry_point = pta_generic_close_session, + .invoke_command_entry_point = pta_generic_invoke_command); diff --git a/core/arch/arm/tee/sub.mk b/core/arch/arm/tee/sub.mk index e8b07ee4c8d..2ea1076bcdd 100644 --- a/core/arch/arm/tee/sub.mk +++ b/core/arch/arm/tee/sub.mk @@ -3,6 +3,7 @@ srcs-$(CFG_ARM32_core) += arch_svc_a32.S srcs-$(CFG_ARM64_core) += arch_svc_a64.S srcs-$(CFG_CACHE_API) += svc_cache.c srcs-y += arch_svc.c +srcs-y += pta_generic.c else srcs-y += svc_dummy.c endif diff --git a/core/include/optee_rpc_cmd.h b/core/include/optee_rpc_cmd.h old mode 100644 new mode 100755 index 03f80323119..9305db1544a --- a/core/include/optee_rpc_cmd.h +++ b/core/include/optee_rpc_cmd.h @@ -148,6 +148,21 @@ */ #define OPTEE_RPC_CMD_BENCH_REG 20 +/* Generic REE Service commands */ + +/* + * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_GENERIC + */ + +/* + * The first parameter is reserved and filled as + * + * [in] param[0].u.value.a cmd + * [in] param[0].u.value.b TA instance id + * [out] param[0].u.value.c REE service handle + */ +#define OPTEE_RPC_CMD_GENERIC 30 + /* * Definition of protocol for command OPTEE_RPC_CMD_FS */ diff --git a/lib/libutee/include/pta_generic.h b/lib/libutee/include/pta_generic.h new file mode 100644 index 00000000000..d1c223d446c --- /dev/null +++ b/lib/libutee/include/pta_generic.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2018, Intel Corporation + */ + +#ifndef __PTA_GENERIC_H__ +#define __PTA_GENERIC_H__ + +#define PTA_GENERIC_UUID { 0xfeca9a1d, 0x5ff0, 0x4204, { \ + 0xb4, 0x83, 0x34, 0x86, 0x23, 0x71, 0x2d, 0xc9 } } + +#define OPTEE_MRC_GENERIC_OPEN 1 +#define OPTEE_MRC_GENERIC_CLOSE 2 +#define OPTEE_MRC_GENERIC_SERVICE_START 3 +#define OPTEE_MRC_GENERIC_SERVICE_STOP 4 +#endif diff --git a/lib/libutee/include/tee_api.h b/lib/libutee/include/tee_api.h index 76170ddc9ab..9540f2e24dd 100644 --- a/lib/libutee/include/tee_api.h +++ b/lib/libutee/include/tee_api.h @@ -70,6 +70,21 @@ TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, TEE_Param params[TEE_NUM_PARAMS], uint32_t *returnOrigin); +TEE_Result TEE_OpenREESession(REE_UUID *destination, + uint32_t cancellationRequestTimeout, + uint32_t paramTypes, + REE_Param params[REE_NUM_PARAMS], + TEE_REESessionHandle *session, + uint32_t *returnOrigin); + +void TEE_CloseREESession(TEE_REESessionHandle session); + +TEE_Result TEE_InvokeREECommand(TEE_REESessionHandle session, + uint32_t cancellationRequestTimeout, + uint32_t commandID, uint32_t paramTypes, + REE_Param params[REE_NUM_PARAMS], + uint32_t *returnOrigin); + /* System API - Cancellations */ bool TEE_GetCancellationFlag(void); diff --git a/lib/libutee/include/tee_api_defines.h b/lib/libutee/include/tee_api_defines.h index c71108adaf4..758990e24f1 100644 --- a/lib/libutee/include/tee_api_defines.h +++ b/lib/libutee/include/tee_api_defines.h @@ -445,6 +445,7 @@ /* Not specified in the standard */ #define TEE_NUM_PARAMS 4 +#define REE_NUM_PARAMS TEE_NUM_PARAMS /* TEE Arithmetical APIs */ diff --git a/lib/libutee/include/tee_api_types.h b/lib/libutee/include/tee_api_types.h index 0b232172f4e..7d74e7eeebf 100644 --- a/lib/libutee/include/tee_api_types.h +++ b/lib/libutee/include/tee_api_types.h @@ -26,6 +26,8 @@ typedef struct { uint8_t clockSeqAndNode[8]; } TEE_UUID; +typedef TEE_UUID REE_UUID; + /* * The TEE_Identity structure defines the full identity of a Client: * - login is one of the TEE_LOGIN_XXX constants @@ -57,12 +59,20 @@ typedef union { } value; } TEE_Param; +typedef TEE_Param REE_Param; + /* * The type of opaque handles on TA Session. These handles are returned by * the function TEE_OpenTASession. */ typedef struct __TEE_TASessionHandle *TEE_TASessionHandle; +/* + * The type of opaque handles on TA Session. These handles are returned by + * the function TEE_OpenREESession. + */ +typedef struct __TEE_REESessionHandle *TEE_REESessionHandle; + /* * The type of opaque handles on property sets or enumerators. These * handles are either one of the pseudo handles TEE_PROPSET_XXX or are diff --git a/lib/libutee/sub.mk b/lib/libutee/sub.mk index 708e648a520..e0e48271aa0 100644 --- a/lib/libutee/sub.mk +++ b/lib/libutee/sub.mk @@ -14,7 +14,7 @@ srcs-y += tee_api_panic.c srcs-y += tee_tcpudp_socket.c srcs-y += tee_socket_pta.c srcs-y += tee_system_pta.c - +srcs-y += tee_api_ree_service.c ifeq ($(CFG_TA_MBEDTLS_MPI),y) srcs-y += tee_api_arith_mpi.c @@ -23,4 +23,5 @@ srcs-y += tee_api_arith_mpa.c endif endif #ifneq ($(sm),ldelf) + subdirs-y += arch/$(ARCH) diff --git a/lib/libutee/tee_api_ree_service.c b/lib/libutee/tee_api_ree_service.c new file mode 100644 index 00000000000..0449b01b322 --- /dev/null +++ b/lib/libutee/tee_api_ree_service.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2018, Intel Corporation + */ + +#include +#include +#include +#include + + +struct __TEE_REESessionHandle { + uint64_t handle; + TEE_TASessionHandle session; +}; + +TEE_Result TEE_OpenREESession(REE_UUID *destination, + uint32_t cancellationRequestTimeout, + uint32_t paramTypes, + REE_Param params[REE_NUM_PARAMS], + TEE_REESessionHandle *ree_session, + uint32_t *returnOrigin) +{ + TEE_Param *pparams, iparam = {0}; + TEE_UUID pta_generic = PTA_GENERIC_UUID; + TEE_Result result = TEE_SUCCESS; + TEE_REESessionHandle rsess; + TEE_Param init_params[REE_NUM_PARAMS]; + uint32_t init_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_VALUE_OUTPUT, + TEE_PARAM_TYPE_NONE, + TEE_PARAM_TYPE_NONE); + + if (!destination || !ree_session || !returnOrigin) + return TEE_ERROR_BAD_PARAMETERS; + + rsess = TEE_Malloc(sizeof(*rsess), TEE_MALLOC_FILL_ZERO); + if (!rsess) + return TEE_ERROR_OUT_OF_MEMORY; + + /* Open a session on the custom PTA */ + result = TEE_OpenTASession(&pta_generic, 0, 0, NULL, + &rsess->session, NULL); + if (result != TEE_SUCCESS) { + MSG("Failed to open session on REE\n"); + goto err; + } + + /* Construct the init parameters */ + memset(init_params, 0, sizeof(init_params)); + init_params[0].memref.buffer = destination; + init_params[0].memref.size = sizeof(REE_UUID); + result = TEE_InvokeTACommand(rsess->session, 0, OPTEE_MRC_GENERIC_OPEN, + init_param_types, init_params, returnOrigin); + if (result != TEE_SUCCESS) { + MSG("Failed to find the ree service\n"); + goto err; + } + rsess->handle = init_params[1].value.a; + + /* Indicate to the ree service to do any pre setup */ + if (params) + pparams = params; + else + pparams = &iparam; + + pparams->value.a = rsess->handle; + paramTypes = (paramTypes & ~0xF) | TEE_PARAM_TYPE_VALUE_INPUT; + result = TEE_InvokeTACommand(rsess->session, cancellationRequestTimeout, + OPTEE_MRC_GENERIC_SERVICE_START, paramTypes, + pparams, returnOrigin); + if (result != TEE_SUCCESS) { + DMSG("Failed to initialize REE service\n"); + goto err; + } + + *ree_session = rsess; + + return TEE_SUCCESS; + +err: + if (rsess) { + TEE_CloseTASession(rsess->session); + TEE_Free(rsess); + } + return result; +} + +void TEE_CloseREESession(TEE_REESessionHandle ree_session) +{ + TEE_Result result; + TEE_Param param; + uint32_t paramTypes = TEE_PARAM_TYPE_VALUE_INPUT; + + param.value.a = ree_session->handle; + result = TEE_InvokeTACommand(ree_session->session, 0, + OPTEE_MRC_GENERIC_SERVICE_STOP, paramTypes, + ¶m, NULL); + if (result != TEE_SUCCESS) + MSG("Failed to close the REE service\n"); + + param.value.a = ree_session->handle; + result = TEE_InvokeTACommand(ree_session->session, 0, + OPTEE_MRC_GENERIC_CLOSE, paramTypes, + ¶m, NULL); + if (result != TEE_SUCCESS) + MSG("Failed to close the session\n"); + + TEE_CloseTASession(ree_session->session); +} + +TEE_Result TEE_InvokeREECommand(TEE_REESessionHandle ree_session, + uint32_t cancellationRequestTimeout, + uint32_t commandID, uint32_t paramTypes, + TEE_Param params[TEE_NUM_PARAMS], + uint32_t *returnOrigin) +{ + TEE_Param *pParam; + TEE_Param iparam; + + /* The first parameter is reserved for internal usage */ + if (params) + pParam = ¶ms[0]; + else + pParam = &iparam; + + pParam->value.a = ree_session->handle; + paramTypes = (paramTypes & ~0xF) | TEE_PARAM_TYPE_VALUE_INPUT; + + return TEE_InvokeTACommand(ree_session->session, + cancellationRequestTimeout, + commandID, paramTypes, + pParam, returnOrigin); +} From 62b53c9c31f99dd89b0442721b06712473603e02 Mon Sep 17 00:00:00 2001 From: Divneil Rai Wadhawan Date: Mon, 16 Sep 2019 23:36:13 +0530 Subject: [PATCH 2/3] core: refactored custom REE support o renamed pta_generic.* to pta_ree_service.* o Replace _GENERIC with _REE_SERVICE o Moved REE function definitons to - tee_api_extensions.h o Moved REE declarations to - tee_api_types_extensions.h Signed-off-by: Divneil Rai Wadhawan --- .../tee/{pta_generic.c => pta_ree_service.c} | 78 +++++++++++++------ core/arch/arm/tee/sub.mk | 2 +- core/include/optee_rpc_cmd.h | 9 ++- lib/libutee/include/pta_generic.h | 16 ---- lib/libutee/include/pta_ree_service.h | 16 ++++ lib/libutee/include/tee_api.h | 15 ---- lib/libutee/include/tee_api_defines.h | 1 - lib/libutee/include/tee_api_extensions.h | 26 +++++++ lib/libutee/include/tee_api_types.h | 10 --- .../include/tee_api_types_extensions.h | 15 ++++ lib/libutee/tee_api_ree_service.c | 41 ++++++---- 11 files changed, 148 insertions(+), 81 deletions(-) rename core/arch/arm/tee/{pta_generic.c => pta_ree_service.c} (79%) delete mode 100644 lib/libutee/include/pta_generic.h create mode 100644 lib/libutee/include/pta_ree_service.h create mode 100644 lib/libutee/include/tee_api_extensions.h create mode 100644 lib/libutee/include/tee_api_types_extensions.h diff --git a/core/arch/arm/tee/pta_generic.c b/core/arch/arm/tee/pta_ree_service.c similarity index 79% rename from core/arch/arm/tee/pta_generic.c rename to core/arch/arm/tee/pta_ree_service.c index f2b4321c9a9..48356284b9d 100644 --- a/core/arch/arm/tee/pta_generic.c +++ b/core/arch/arm/tee/pta_ree_service.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -15,45 +15,73 @@ static uint32_t get_instance_id(struct tee_ta_session *sess) return sess->ctx->ops->get_instance_id(sess->ctx); } +/** + * is_param_memref() - return true if parameter is memory reference + */ static inline bool is_param_memref(uint32_t param_types, uint32_t idx) { uint32_t ptype = TEE_PARAM_TYPE_GET(param_types, idx); - if ((ptype == TEE_PARAM_TYPE_MEMREF_INPUT) || - (ptype == TEE_PARAM_TYPE_MEMREF_OUTPUT) || - (ptype == TEE_PARAM_TYPE_MEMREF_INOUT)) + switch (ptype) { + case TEE_PARAM_TYPE_MEMREF_INPUT: + case TEE_PARAM_TYPE_MEMREF_OUTPUT: + case TEE_PARAM_TYPE_MEMREF_INOUT: return true; + + default: + break; + } + return false; } +/** + * is_param_out() - return true if parameter can be filled by REE (output) + */ static inline bool is_param_out(uint32_t param_types, uint32_t idx) { uint32_t ptype = TEE_PARAM_TYPE_GET(param_types, idx); - if ((ptype == TEE_PARAM_TYPE_VALUE_OUTPUT) || - (ptype == TEE_PARAM_TYPE_VALUE_INOUT) || - (ptype == TEE_PARAM_TYPE_MEMREF_OUTPUT) || - (ptype == TEE_PARAM_TYPE_MEMREF_INOUT)) + switch (ptype) { + case TEE_PARAM_TYPE_VALUE_OUTPUT: + case TEE_PARAM_TYPE_VALUE_INOUT: + case TEE_PARAM_TYPE_MEMREF_OUTPUT: + case TEE_PARAM_TYPE_MEMREF_INOUT: return true; + + default: + break; + } + return false; } +/** + * is_param_value() - returns true if parameter is value + */ static inline bool is_param_value(uint32_t param_types, uint32_t idx) { uint32_t ptype = TEE_PARAM_TYPE_GET(param_types, idx); - if (ptype == TEE_PARAM_TYPE_VALUE_INPUT || - ptype == TEE_PARAM_TYPE_VALUE_OUTPUT || - ptype == TEE_PARAM_TYPE_VALUE_INOUT) + + switch (ptype) { + case TEE_PARAM_TYPE_VALUE_INPUT: + case TEE_PARAM_TYPE_VALUE_OUTPUT: + case TEE_PARAM_TYPE_VALUE_INOUT: return true; + default: + break; + } + return false; } +/** + * is_param_none() - if the parameter has nothing to send/receive to REE + */ static inline bool is_param_none(uint32_t param_types, uint32_t idx) { - if (TEE_PARAM_TYPE_GET(param_types, idx) == TEE_PARAM_TYPE_NONE) - return true; - return false; + return (TEE_PARAM_TYPE_GET(param_types, idx) == TEE_PARAM_TYPE_NONE); } static void *alloc_transient_shm(size_t size, struct mobj **mobj) @@ -154,7 +182,7 @@ static TEE_Result find_ree_service(void *sess_ctx, uint32_t param_types, tpm[2] = THREAD_PARAM_VALUE(OUT, 0, 0, 0); - res = thread_rpc_cmd(OPTEE_RPC_CMD_GENERIC, 3, tpm); + res = thread_rpc_cmd(OPTEE_RPC_CMD_REE_SERVICE, 3, tpm); if (res == TEE_SUCCESS) params[1].value.a = tpm[2].u.value.a; @@ -165,7 +193,7 @@ static TEE_Result find_ree_service(void *sess_ctx, uint32_t param_types, * Trusted Application Entry Points */ -static TEE_Result pta_generic_open_session(uint32_t param_types __unused, +static TEE_Result pta_ree_service_open_session(uint32_t param_types __unused, TEE_Param params[TEE_NUM_PARAMS] __unused, void **sess_ctx) { @@ -181,12 +209,16 @@ static TEE_Result pta_generic_open_session(uint32_t param_types __unused, return TEE_SUCCESS; } -static void pta_generic_close_session(void *sess_ctx __unused) +/** + * pta_ree_service_close_session() - close the session of calling TA + * TODO: Seems like okay to do, but, a discussion is required. + */ +static void pta_ree_service_close_session(void *sess_ctx __unused) { return; } -static TEE_Result pta_generic_invoke_command(void *sess_ctx, +static TEE_Result pta_ree_service_invoke_command(void *sess_ctx, uint32_t cmd_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { @@ -225,7 +257,7 @@ static TEE_Result pta_generic_invoke_command(void *sess_ctx, if (is_param_memref(param_types, i)) { va[idx] = prepare_memref_params(¶ms[i], TEE_PARAM_TYPE_GET(param_types, i), - cache_allocated ? false: true, + cache_allocated ? false : true, &mobj[idx], &tpm[i]); if (!va[idx]) { res = TEE_ERROR_OUT_OF_MEMORY; @@ -249,7 +281,7 @@ static TEE_Result pta_generic_invoke_command(void *sess_ctx, } } - res = thread_rpc_cmd(OPTEE_RPC_CMD_GENERIC, + res = thread_rpc_cmd(OPTEE_RPC_CMD_REE_SERVICE, msg_params_count, tpm); if (res != TEE_SUCCESS) goto err; @@ -282,6 +314,6 @@ static TEE_Result pta_generic_invoke_command(void *sess_ctx, pseudo_ta_register(.uuid = PTA_GENERIC_UUID, .name = "generic", .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT, - .open_session_entry_point = pta_generic_open_session, - .close_session_entry_point = pta_generic_close_session, - .invoke_command_entry_point = pta_generic_invoke_command); + .open_session_entry_point = pta_ree_service_open_session, + .close_session_entry_point = pta_ree_service_close_session, + .invoke_command_entry_point = pta_ree_service_invoke_command); diff --git a/core/arch/arm/tee/sub.mk b/core/arch/arm/tee/sub.mk index 2ea1076bcdd..719f32d42ee 100644 --- a/core/arch/arm/tee/sub.mk +++ b/core/arch/arm/tee/sub.mk @@ -3,7 +3,7 @@ srcs-$(CFG_ARM32_core) += arch_svc_a32.S srcs-$(CFG_ARM64_core) += arch_svc_a64.S srcs-$(CFG_CACHE_API) += svc_cache.c srcs-y += arch_svc.c -srcs-y += pta_generic.c +srcs-y += pta_ree_service.c else srcs-y += svc_dummy.c endif diff --git a/core/include/optee_rpc_cmd.h b/core/include/optee_rpc_cmd.h index 9305db1544a..4654e463c47 100755 --- a/core/include/optee_rpc_cmd.h +++ b/core/include/optee_rpc_cmd.h @@ -155,13 +155,18 @@ */ /* + * We can only send 4 parameters to the Normal World via RPC. Since, for + * custom REE service, we need to send command information to REE service. + * So, sending this command information consumes 1 parameter, and it is + * always sent as using params[0] + * * The first parameter is reserved and filled as * - * [in] param[0].u.value.a cmd + * [in] param[0].u.value.a Command for REE service * [in] param[0].u.value.b TA instance id * [out] param[0].u.value.c REE service handle */ -#define OPTEE_RPC_CMD_GENERIC 30 +#define OPTEE_RPC_CMD_REE_SERVICE 30 /* * Definition of protocol for command OPTEE_RPC_CMD_FS diff --git a/lib/libutee/include/pta_generic.h b/lib/libutee/include/pta_generic.h deleted file mode 100644 index d1c223d446c..00000000000 --- a/lib/libutee/include/pta_generic.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * Copyright (c) 2018, Intel Corporation - */ - -#ifndef __PTA_GENERIC_H__ -#define __PTA_GENERIC_H__ - -#define PTA_GENERIC_UUID { 0xfeca9a1d, 0x5ff0, 0x4204, { \ - 0xb4, 0x83, 0x34, 0x86, 0x23, 0x71, 0x2d, 0xc9 } } - -#define OPTEE_MRC_GENERIC_OPEN 1 -#define OPTEE_MRC_GENERIC_CLOSE 2 -#define OPTEE_MRC_GENERIC_SERVICE_START 3 -#define OPTEE_MRC_GENERIC_SERVICE_STOP 4 -#endif diff --git a/lib/libutee/include/pta_ree_service.h b/lib/libutee/include/pta_ree_service.h new file mode 100644 index 00000000000..de30fd6705b --- /dev/null +++ b/lib/libutee/include/pta_ree_service.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ + +#ifndef __PTA_REE_SERVICE_H__ +#define __PTA_REE_SERVICE_H__ + +#define PTA_GENERIC_UUID { 0xfeca9a1d, 0x5ff0, 0x4204, { \ + 0xb4, 0x83, 0x34, 0x86, 0x23, 0x71, 0x2d, 0xc9 } } + +#define OPTEE_MRC_GENERIC_OPEN 0xFFFFFFF0 +#define OPTEE_MRC_GENERIC_CLOSE 0xFFFFFFF1 +#define OPTEE_MRC_GENERIC_SERVICE_START 0xFFFFFFF2 +#define OPTEE_MRC_GENERIC_SERVICE_STOP 0xFFFFFFF3 +#endif diff --git a/lib/libutee/include/tee_api.h b/lib/libutee/include/tee_api.h index 9540f2e24dd..76170ddc9ab 100644 --- a/lib/libutee/include/tee_api.h +++ b/lib/libutee/include/tee_api.h @@ -70,21 +70,6 @@ TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session, TEE_Param params[TEE_NUM_PARAMS], uint32_t *returnOrigin); -TEE_Result TEE_OpenREESession(REE_UUID *destination, - uint32_t cancellationRequestTimeout, - uint32_t paramTypes, - REE_Param params[REE_NUM_PARAMS], - TEE_REESessionHandle *session, - uint32_t *returnOrigin); - -void TEE_CloseREESession(TEE_REESessionHandle session); - -TEE_Result TEE_InvokeREECommand(TEE_REESessionHandle session, - uint32_t cancellationRequestTimeout, - uint32_t commandID, uint32_t paramTypes, - REE_Param params[REE_NUM_PARAMS], - uint32_t *returnOrigin); - /* System API - Cancellations */ bool TEE_GetCancellationFlag(void); diff --git a/lib/libutee/include/tee_api_defines.h b/lib/libutee/include/tee_api_defines.h index 758990e24f1..c71108adaf4 100644 --- a/lib/libutee/include/tee_api_defines.h +++ b/lib/libutee/include/tee_api_defines.h @@ -445,7 +445,6 @@ /* Not specified in the standard */ #define TEE_NUM_PARAMS 4 -#define REE_NUM_PARAMS TEE_NUM_PARAMS /* TEE Arithmetical APIs */ diff --git a/lib/libutee/include/tee_api_extensions.h b/lib/libutee/include/tee_api_extensions.h new file mode 100644 index 00000000000..8be465edb1c --- /dev/null +++ b/lib/libutee/include/tee_api_extensions.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ + +#ifndef __TEE_API_EXTENSIONS_H__ +#define __TEE_API_EXTENSIONS_H__ + +/* System API - Internal Client API to invoke custom REE service */ + +TEE_Result TEE_OpenREESession(TEE_UUID *destination, + uint32_t cancellationRequestTimeout, + uint32_t paramTypes, + TEE_Param params[TEE_NUM_PARAMS], + ree_session_handle *session, + uint32_t *returnOrigin); + +void TEE_CloseREESession(ree_session_handle session); + +TEE_Result TEE_InvokeREECommand(ree_session_handle session, + uint32_t cancellationRequestTimeout, + uint32_t commandID, uint32_t paramTypes, + TEE_Param params[TEE_NUM_PARAMS], + uint32_t *returnOrigin); + +#endif diff --git a/lib/libutee/include/tee_api_types.h b/lib/libutee/include/tee_api_types.h index 7d74e7eeebf..0b232172f4e 100644 --- a/lib/libutee/include/tee_api_types.h +++ b/lib/libutee/include/tee_api_types.h @@ -26,8 +26,6 @@ typedef struct { uint8_t clockSeqAndNode[8]; } TEE_UUID; -typedef TEE_UUID REE_UUID; - /* * The TEE_Identity structure defines the full identity of a Client: * - login is one of the TEE_LOGIN_XXX constants @@ -59,20 +57,12 @@ typedef union { } value; } TEE_Param; -typedef TEE_Param REE_Param; - /* * The type of opaque handles on TA Session. These handles are returned by * the function TEE_OpenTASession. */ typedef struct __TEE_TASessionHandle *TEE_TASessionHandle; -/* - * The type of opaque handles on TA Session. These handles are returned by - * the function TEE_OpenREESession. - */ -typedef struct __TEE_REESessionHandle *TEE_REESessionHandle; - /* * The type of opaque handles on property sets or enumerators. These * handles are either one of the pseudo handles TEE_PROPSET_XXX or are diff --git a/lib/libutee/include/tee_api_types_extensions.h b/lib/libutee/include/tee_api_types_extensions.h new file mode 100644 index 00000000000..fa3bfab9a5a --- /dev/null +++ b/lib/libutee/include/tee_api_types_extensions.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ + +#ifndef __TEE_API_TYPES_EXTENSIONS_H__ +#define __TEE_API_TYPES_EXTENSIONS_H__ + +/* + * The type of opaque handles on TA Session. These handles are returned by + * the function TEE_OpenREESession. + */ +typedef struct __ree_session_handle *ree_session_handle; + +#endif diff --git a/lib/libutee/tee_api_ree_service.c b/lib/libutee/tee_api_ree_service.c index 0449b01b322..d3a2d8dea7e 100644 --- a/lib/libutee/tee_api_ree_service.c +++ b/lib/libutee/tee_api_ree_service.c @@ -1,31 +1,46 @@ -// SPDX-License-Identifier: BSD-2-Clause +/* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2018, Intel Corporation + * Copyright (C) 2019 Intel Corporation All Rights Reserved */ #include +#include #include -#include +#include +#include #include - -struct __TEE_REESessionHandle { +struct __ree_session_handle { uint64_t handle; TEE_TASessionHandle session; }; -TEE_Result TEE_OpenREESession(REE_UUID *destination, +/** + * TEE_OpenREESession() - open the REE session + * The API finds the REE service (either Message Queue or Dynamic Library + * based) based on the @destination UUID. There are 2 commands issued to + * tee-supplicant. + * + * o One is via TEE_OpenTASession(), where tee-supplicant establish + * communication channel with the REE service + * + * o Second is via TEE_InvokeTACommand(), where tee-supplicant uses the + * established communication mechanism to inform REE service that TA + * is from now will be requesting its service. REE service in response + * to that can initialize itself for handling the requests. + */ +TEE_Result TEE_OpenREESession(TEE_UUID *destination, uint32_t cancellationRequestTimeout, uint32_t paramTypes, - REE_Param params[REE_NUM_PARAMS], - TEE_REESessionHandle *ree_session, + TEE_Param params[TEE_NUM_PARAMS], + ree_session_handle *ree_session, uint32_t *returnOrigin) { TEE_Param *pparams, iparam = {0}; TEE_UUID pta_generic = PTA_GENERIC_UUID; TEE_Result result = TEE_SUCCESS; - TEE_REESessionHandle rsess; - TEE_Param init_params[REE_NUM_PARAMS]; + ree_session_handle rsess; + TEE_Param init_params[TEE_NUM_PARAMS]; uint32_t init_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE, @@ -49,7 +64,7 @@ TEE_Result TEE_OpenREESession(REE_UUID *destination, /* Construct the init parameters */ memset(init_params, 0, sizeof(init_params)); init_params[0].memref.buffer = destination; - init_params[0].memref.size = sizeof(REE_UUID); + init_params[0].memref.size = sizeof(TEE_UUID); result = TEE_InvokeTACommand(rsess->session, 0, OPTEE_MRC_GENERIC_OPEN, init_param_types, init_params, returnOrigin); if (result != TEE_SUCCESS) { @@ -86,7 +101,7 @@ TEE_Result TEE_OpenREESession(REE_UUID *destination, return result; } -void TEE_CloseREESession(TEE_REESessionHandle ree_session) +void TEE_CloseREESession(ree_session_handle ree_session) { TEE_Result result; TEE_Param param; @@ -109,7 +124,7 @@ void TEE_CloseREESession(TEE_REESessionHandle ree_session) TEE_CloseTASession(ree_session->session); } -TEE_Result TEE_InvokeREECommand(TEE_REESessionHandle ree_session, +TEE_Result TEE_InvokeREECommand(ree_session_handle ree_session, uint32_t cancellationRequestTimeout, uint32_t commandID, uint32_t paramTypes, TEE_Param params[TEE_NUM_PARAMS], From 062d46026333212e53fb18e9f3aed15d4028774d Mon Sep 17 00:00:00 2001 From: Divneil Rai Wadhawan Date: Thu, 19 Sep 2019 05:08:33 +0530 Subject: [PATCH 3/3] core: refactored the custom REE service infrastructure o Added more comments o Removed _GENERIC_ in missed places o Some generic cleanup Signed-off-by: Divneil Rai Wadhawan --- core/arch/arm/tee/pta_ree_service.c | 121 ++++++++++++++++++-------- core/include/optee_rpc_cmd.h | 3 +- lib/libutee/include/pta_ree_service.h | 10 +-- lib/libutee/sub.mk | 1 - lib/libutee/tee_api_ree_service.c | 61 +++++++++---- 5 files changed, 134 insertions(+), 62 deletions(-) diff --git a/core/arch/arm/tee/pta_ree_service.c b/core/arch/arm/tee/pta_ree_service.c index 48356284b9d..5a9005e1fc9 100644 --- a/core/arch/arm/tee/pta_ree_service.c +++ b/core/arch/arm/tee/pta_ree_service.c @@ -1,6 +1,6 @@ -// SPDX-License-Identifier: BSD-2-Clause +/* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2018, Intel Corporation + * Copyright (C) 2019 Intel Corporation All Rights Reserved */ #include @@ -27,12 +27,9 @@ static inline bool is_param_memref(uint32_t param_types, uint32_t idx) case TEE_PARAM_TYPE_MEMREF_OUTPUT: case TEE_PARAM_TYPE_MEMREF_INOUT: return true; - default: - break; + return false; } - - return false; } /** @@ -48,12 +45,9 @@ static inline bool is_param_out(uint32_t param_types, uint32_t idx) case TEE_PARAM_TYPE_MEMREF_OUTPUT: case TEE_PARAM_TYPE_MEMREF_INOUT: return true; - default: - break; + return false; } - - return false; } /** @@ -68,12 +62,9 @@ static inline bool is_param_value(uint32_t param_types, uint32_t idx) case TEE_PARAM_TYPE_VALUE_OUTPUT: case TEE_PARAM_TYPE_VALUE_INOUT: return true; - default: - break; + return false; } - - return false; } /** @@ -84,6 +75,12 @@ static inline bool is_param_none(uint32_t param_types, uint32_t idx) return (TEE_PARAM_TYPE_GET(param_types, idx) == TEE_PARAM_TYPE_NONE); } +/** + * alloc_transient_shm() - allocate buffer with RPC call scope + * Allocates a buffer whose lifetime is the RPC call. The buffer + * gets freed once the call returns the data is filled back to + * the UTA buffer. + */ static void *alloc_transient_shm(size_t size, struct mobj **mobj) { paddr_t p; @@ -110,18 +107,25 @@ static void *alloc_transient_shm(size_t size, struct mobj **mobj) return NULL; } +/** + * free_transient_shm() - free the transient buffer + */ static void free_transient_shm(struct mobj *mobj) { thread_rpc_free_payload(mobj); } +/** + * prepare_memref_params() - fill the shared buffers if required + */ static void *prepare_memref_params(TEE_Param *param, uint32_t param_type, bool cached, struct mobj **mobj, struct thread_param *tpm) { - void *va = NULL; size_t size = param->memref.size; + void *va = NULL; + /* Allocate shared buffer to be sent over to REE over RPC */ if (cached) va = tee_fs_rpc_cache_alloc(size, mobj); else @@ -129,16 +133,23 @@ static void *prepare_memref_params(TEE_Param *param, uint32_t param_type, if (!va) return NULL; + /* + * Prepare buffers as per their direction + * INPUT : Filled by TEE and to be interpreted by REE + * OUTPUT: Empty buffer sent by TEE to be filled by REE + * INPUT : Filled by TEE and overwritten by REE + */ switch (param_type) { case TEE_PARAM_TYPE_MEMREF_INPUT: - tpm[0] = THREAD_PARAM_MEMREF(IN, *mobj, 0, size); + *tpm = THREAD_PARAM_MEMREF(IN, *mobj, 0, size); memcpy(va, param->memref.buffer, size); break; case TEE_PARAM_TYPE_MEMREF_OUTPUT: - tpm[0] = THREAD_PARAM_MEMREF(OUT, *mobj, 0, size); + *tpm = THREAD_PARAM_MEMREF(OUT, *mobj, 0, size); break; case TEE_PARAM_TYPE_MEMREF_INOUT: - tpm[0] = THREAD_PARAM_MEMREF(INOUT, *mobj, 0, size); + *tpm = THREAD_PARAM_MEMREF(INOUT, *mobj, 0, size); + memcpy(va, param->memref.buffer, size); break; default: goto err; @@ -152,27 +163,36 @@ static void *prepare_memref_params(TEE_Param *param, uint32_t param_type, return NULL; } +/** + * find_ree_service() - find if expected REE service is alive + */ static TEE_Result find_ree_service(void *sess_ctx, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { - void *va; struct mobj *mobj; - TEE_Result res = TEE_SUCCESS; struct thread_param tpm[3]; + TEE_Result res = TEE_SUCCESS; uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); + void *va; if (exp_pt != param_types) return TEE_ERROR_BAD_PARAMETERS; /* Prepare RPC params for opening REE session */ - memset(&tpm, 0, sizeof(tpm)); + memset(tpm, 0, sizeof(tpm)); - tpm[0] = THREAD_PARAM_VALUE(IN, OPTEE_MRC_GENERIC_OPEN, (uint64_t)sess_ctx, 0); + /* + * Fill in the command ID. This will be handled by tee-supplicant to + * find if the REE service identified by UUID (params[0].memref) is + * available to service the UTA calls. + */ + tpm[0] = THREAD_PARAM_VALUE(IN, + OPTEE_MRC_REE_SERVICE_OPEN,(uint64_t)sess_ctx, 0); - /* Allocate memory for passing UUID */ + /* Prepare to fill in REE service UUID */ va = tee_fs_rpc_cache_alloc(params[0].memref.size, &mobj); if (!va) return TEE_ERROR_OUT_OF_MEMORY; @@ -180,6 +200,7 @@ static TEE_Result find_ree_service(void *sess_ctx, uint32_t param_types, tpm[1] = THREAD_PARAM_MEMREF(OUT, mobj, 0, params[0].memref.size); memcpy(va, params[0].memref.buffer, params[0].memref.size); + /* tee-supplicant will return a handle to REE service */ tpm[2] = THREAD_PARAM_VALUE(OUT, 0, 0, 0); res = thread_rpc_cmd(OPTEE_RPC_CMD_REE_SERVICE, 3, tpm); @@ -193,6 +214,9 @@ static TEE_Result find_ree_service(void *sess_ctx, uint32_t param_types, * Trusted Application Entry Points */ +/** + * pta_ree_service_open_session() - open the session for the calling UTA + */ static TEE_Result pta_ree_service_open_session(uint32_t param_types __unused, TEE_Param params[TEE_NUM_PARAMS] __unused, void **sess_ctx) @@ -211,27 +235,32 @@ static TEE_Result pta_ree_service_open_session(uint32_t param_types __unused, /** * pta_ree_service_close_session() - close the session of calling TA - * TODO: Seems like okay to do, but, a discussion is required. + * TODO: Seems like okay to do, but, a discussion is required. If doing + * nothing is okay, this callback needs to be deleted. */ static void pta_ree_service_close_session(void *sess_ctx __unused) { return; } +/** + * pta_ree_service_invoke_command() - invoke the custom REE command + */ static TEE_Result pta_ree_service_invoke_command(void *sess_ctx, uint32_t cmd_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { - TEE_Result res = TEE_SUCCESS; + bool cache_allocated = false; + int32_t idx = 0; + int32_t msg_params_count = 1; struct mobj *mobj[THREAD_RPC_MAX_NUM_PARAMS - 1]; - void *va[THREAD_RPC_MAX_NUM_PARAMS - 1]; struct thread_param tpm[THREAD_RPC_MAX_NUM_PARAMS]; + TEE_Result res = TEE_SUCCESS; uint8_t i; - bool cache_allocated = false; - int32_t idx = 0, msg_params_count = 1; + void *va[THREAD_RPC_MAX_NUM_PARAMS - 1]; /* Find the REE service if it's available */ - if (cmd_id == OPTEE_MRC_GENERIC_OPEN) + if (cmd_id == OPTEE_MRC_REE_SERVICE_OPEN) return find_ree_service(sess_ctx, param_types, params); /* The first parameter has to be input value */ @@ -242,18 +271,24 @@ static TEE_Result pta_ree_service_invoke_command(void *sess_ctx, memset(tpm, 0, sizeof(tpm)); /* params[0].value.a: handle to the service */ - tpm[0] = THREAD_PARAM_VALUE(IN, cmd_id, (uint64_t)sess_ctx, params[0].value.a); + tpm[0] = THREAD_PARAM_VALUE(IN, cmd_id, + (uint64_t)sess_ctx, params[0].value.a); /* * Allocate a cached buffer for first memref and for subsequent memrefs * allocate a transient buffer which will be freed after this call. */ for (i = 1; i < THREAD_RPC_MAX_NUM_PARAMS; i++) { + /* Reached end of params */ if (is_param_none(param_types, i)) break; msg_params_count++; + /* + * If the parameter is memref, then prepare it based on the + * direction of data. + */ if (is_param_memref(param_types, i)) { va[idx] = prepare_memref_params(¶ms[i], TEE_PARAM_TYPE_GET(param_types, i), @@ -269,20 +304,29 @@ static TEE_Result pta_ree_service_invoke_command(void *sess_ctx, } else { switch (TEE_PARAM_TYPE_GET(param_types, i)) { case TEE_PARAM_TYPE_VALUE_INPUT: - tpm[i] = THREAD_PARAM_VALUE(IN, params[i].value.a, params[i].value.b, 0); + tpm[i] = THREAD_PARAM_VALUE(IN, + params[i].value.a, + params[i].value.b, 0); break; case TEE_PARAM_TYPE_VALUE_OUTPUT: - tpm[i] = THREAD_PARAM_VALUE(OUT, params[i].value.a, params[i].value.b, 0); + tpm[i] = THREAD_PARAM_VALUE(OUT, + params[i].value.a, + params[i].value.b, 0); break; case TEE_PARAM_TYPE_VALUE_INOUT: - tpm[i] = THREAD_PARAM_VALUE(INOUT, params[i].value.a, params[i].value.b, 0); + tpm[i] = THREAD_PARAM_VALUE(INOUT, + params[i].value.a, + params[i].value.b, 0); + break; + default: + /* Warning fix */ break; } } } - res = thread_rpc_cmd(OPTEE_RPC_CMD_REE_SERVICE, - msg_params_count, tpm); + /* Send the command to Normal World */ + res = thread_rpc_cmd(OPTEE_RPC_CMD_REE_SERVICE, msg_params_count, tpm); if (res != TEE_SUCCESS) goto err; @@ -292,6 +336,11 @@ static TEE_Result pta_ree_service_invoke_command(void *sess_ctx, if (is_param_memref(param_types, i)) { idx++; + /* + * If the param is memref and not OUTPUT, then REE is + * not expected to modify the data content, so, not + * copying it + */ if (!is_param_out(param_types, i)) continue; @@ -312,7 +361,7 @@ static TEE_Result pta_ree_service_invoke_command(void *sess_ctx, return res; } -pseudo_ta_register(.uuid = PTA_GENERIC_UUID, .name = "generic", +pseudo_ta_register(.uuid = PTA_REE_SERVICE_UUID, .name = "REE Service", .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT, .open_session_entry_point = pta_ree_service_open_session, .close_session_entry_point = pta_ree_service_close_session, diff --git a/core/include/optee_rpc_cmd.h b/core/include/optee_rpc_cmd.h index 4654e463c47..66326b7eb0d 100755 --- a/core/include/optee_rpc_cmd.h +++ b/core/include/optee_rpc_cmd.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright (c) 2016-2017, Linaro Limited + * Copyright (C) 2019 Intel Corporation All Rights Reserved */ #ifndef __OPTEE_RPC_CMD_H @@ -151,7 +152,7 @@ /* Generic REE Service commands */ /* - * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_GENERIC + * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_REE_SERVICE */ /* diff --git a/lib/libutee/include/pta_ree_service.h b/lib/libutee/include/pta_ree_service.h index de30fd6705b..28753d28a4f 100644 --- a/lib/libutee/include/pta_ree_service.h +++ b/lib/libutee/include/pta_ree_service.h @@ -6,11 +6,11 @@ #ifndef __PTA_REE_SERVICE_H__ #define __PTA_REE_SERVICE_H__ -#define PTA_GENERIC_UUID { 0xfeca9a1d, 0x5ff0, 0x4204, { \ +#define PTA_REE_SERVICE_UUID { 0xfeca9a1d, 0x5ff0, 0x4204, { \ 0xb4, 0x83, 0x34, 0x86, 0x23, 0x71, 0x2d, 0xc9 } } -#define OPTEE_MRC_GENERIC_OPEN 0xFFFFFFF0 -#define OPTEE_MRC_GENERIC_CLOSE 0xFFFFFFF1 -#define OPTEE_MRC_GENERIC_SERVICE_START 0xFFFFFFF2 -#define OPTEE_MRC_GENERIC_SERVICE_STOP 0xFFFFFFF3 +#define OPTEE_MRC_REE_SERVICE_OPEN 0xFFFFFFF0 +#define OPTEE_MRC_REE_SERVICE_CLOSE 0xFFFFFFF1 +#define OPTEE_MRC_REE_SERVICE_START 0xFFFFFFF2 +#define OPTEE_MRC_REE_SERVICE_STOP 0xFFFFFFF3 #endif diff --git a/lib/libutee/sub.mk b/lib/libutee/sub.mk index e0e48271aa0..b813a470439 100644 --- a/lib/libutee/sub.mk +++ b/lib/libutee/sub.mk @@ -23,5 +23,4 @@ srcs-y += tee_api_arith_mpa.c endif endif #ifneq ($(sm),ldelf) - subdirs-y += arch/$(ARCH) diff --git a/lib/libutee/tee_api_ree_service.c b/lib/libutee/tee_api_ree_service.c index d3a2d8dea7e..ec0fa7fd01c 100644 --- a/lib/libutee/tee_api_ree_service.c +++ b/lib/libutee/tee_api_ree_service.c @@ -10,6 +10,11 @@ #include #include +/* + * struct __ree_session_handle + * @handle : maintains the handle of REE service + * @session: session handle of REE PTA + */ struct __ree_session_handle { uint64_t handle; TEE_TASessionHandle session; @@ -36,12 +41,13 @@ TEE_Result TEE_OpenREESession(TEE_UUID *destination, ree_session_handle *ree_session, uint32_t *returnOrigin) { - TEE_Param *pparams, iparam = {0}; - TEE_UUID pta_generic = PTA_GENERIC_UUID; - TEE_Result result = TEE_SUCCESS; ree_session_handle rsess; - TEE_Param init_params[TEE_NUM_PARAMS]; - uint32_t init_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_Param *pparams; + TEE_Param iparam = {0}; + TEE_UUID ree_pta = PTA_REE_SERVICE_UUID; + TEE_Result result = TEE_SUCCESS; + TEE_Param uuid_params[TEE_NUM_PARAMS]; + uint32_t uuid_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); @@ -53,27 +59,31 @@ TEE_Result TEE_OpenREESession(TEE_UUID *destination, if (!rsess) return TEE_ERROR_OUT_OF_MEMORY; - /* Open a session on the custom PTA */ - result = TEE_OpenTASession(&pta_generic, 0, 0, NULL, - &rsess->session, NULL); + /* Open a session on the REE PTA */ + result = TEE_OpenTASession(&ree_pta, 0, 0, NULL, &rsess->session, NULL); if (result != TEE_SUCCESS) { MSG("Failed to open session on REE\n"); goto err; } - /* Construct the init parameters */ - memset(init_params, 0, sizeof(init_params)); - init_params[0].memref.buffer = destination; - init_params[0].memref.size = sizeof(TEE_UUID); - result = TEE_InvokeTACommand(rsess->session, 0, OPTEE_MRC_GENERIC_OPEN, - init_param_types, init_params, returnOrigin); + /* Find the REE service identified by "destination" UUID */ + memset(uuid_params, 0, sizeof(uuid_params)); + uuid_params[0].memref.buffer = destination; + uuid_params[0].memref.size = sizeof(TEE_UUID); + result = TEE_InvokeTACommand(rsess->session, 0, + OPTEE_MRC_REE_SERVICE_OPEN, uuid_param_types, + uuid_params, returnOrigin); if (result != TEE_SUCCESS) { MSG("Failed to find the ree service\n"); goto err; } - rsess->handle = init_params[1].value.a; + rsess->handle = uuid_params[1].value.a; - /* Indicate to the ree service to do any pre setup */ + /* + * The API allows NULL params to be sent in OpenSession, however, it is + * mandatory to send non-NULL params in the TEE_InvokeTACommand, so, + * sending a zero'ed out params in case caller sends in NULL parameter + */ if (params) pparams = params; else @@ -82,7 +92,7 @@ TEE_Result TEE_OpenREESession(TEE_UUID *destination, pparams->value.a = rsess->handle; paramTypes = (paramTypes & ~0xF) | TEE_PARAM_TYPE_VALUE_INPUT; result = TEE_InvokeTACommand(rsess->session, cancellationRequestTimeout, - OPTEE_MRC_GENERIC_SERVICE_START, paramTypes, + OPTEE_MRC_REE_SERVICE_START, paramTypes, pparams, returnOrigin); if (result != TEE_SUCCESS) { DMSG("Failed to initialize REE service\n"); @@ -101,29 +111,41 @@ TEE_Result TEE_OpenREESession(TEE_UUID *destination, return result; } +/** + * TEE_CloseREESession() - close the session on REE service + */ void TEE_CloseREESession(ree_session_handle ree_session) { TEE_Result result; TEE_Param param; uint32_t paramTypes = TEE_PARAM_TYPE_VALUE_INPUT; + /* Inform the REE service, that TA is wants to close its instance */ param.value.a = ree_session->handle; result = TEE_InvokeTACommand(ree_session->session, 0, - OPTEE_MRC_GENERIC_SERVICE_STOP, paramTypes, + OPTEE_MRC_REE_SERVICE_STOP, paramTypes, ¶m, NULL); if (result != TEE_SUCCESS) MSG("Failed to close the REE service\n"); + /* + * Inform the tee-supplicant to close the communication + * channel with REE service + */ param.value.a = ree_session->handle; result = TEE_InvokeTACommand(ree_session->session, 0, - OPTEE_MRC_GENERIC_CLOSE, paramTypes, + OPTEE_MRC_REE_SERVICE_CLOSE, paramTypes, ¶m, NULL); if (result != TEE_SUCCESS) MSG("Failed to close the session\n"); + /* Close the session on REE PTA */ TEE_CloseTASession(ree_session->session); } +/** + * TEE_InvokeREECommand() - invoke custom REE command + */ TEE_Result TEE_InvokeREECommand(ree_session_handle ree_session, uint32_t cancellationRequestTimeout, uint32_t commandID, uint32_t paramTypes, @@ -139,6 +161,7 @@ TEE_Result TEE_InvokeREECommand(ree_session_handle ree_session, else pParam = &iparam; + /* Override the first param with REE handle information */ pParam->value.a = ree_session->handle; paramTypes = (paramTypes & ~0xF) | TEE_PARAM_TYPE_VALUE_INPUT;