diff --git a/core/include/optee_rpc_cmd.h b/core/include/optee_rpc_cmd.h index 2dc4d082b47..624d5b2ac49 100644 --- a/core/include/optee_rpc_cmd.h +++ b/core/include/optee_rpc_cmd.h @@ -139,6 +139,11 @@ */ #define OPTEE_RPC_CMD_FTRACE 11 +/* + * tee-supplicant plugin command, see definition of protocol below + */ +#define OPTEE_RPC_CMD_SUPP_PLUGIN 12 + /* * Register timestamp buffer in the linux kernel optee driver * @@ -349,4 +354,35 @@ /* End of definition of protocol for command OPTEE_RPC_CMD_SOCKET */ +/* + * Definition of protocol for command OPTEE_RPC_CMD_SUPP_PLUGIN + */ + +/* + * Invoke tee-supplicant's plugin. + * + * [in] value[0].a OPTEE_RPC_SUPP_PLUGIN_INVOKE + * [in] value[0].b uuid.d1 + * [in] value[0].c uuid.d2 + * [in] value[1].a uuid.d3 + * [in] value[1].b uuid.d4 + * [in] value[1].c cmd for plugin + * [in] value[2].a sub_cmd for plugin + * [out] value[2].b length of the outbuf (memref[3]), if out is needed. + * [in/out] memref[3] buffer holding data for plugin + * + * UUID serialized into octets: + * b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 + * d1 | d2 | d3 | d4 + * + * The endianness of words d1, d2, d3 and d4 must be little-endian. + * d1 word contains [b3 b2 b1 b0] + * d2 word contains [b7 b6 b5 b4] + * d3 word contains [b11 b10 b9 b8] + * d4 word contains [b15 b14 b13 b12] + */ +#define OPTEE_RPC_SUPP_PLUGIN_INVOKE 0 + +/* End of definition of protocol for command OPTEE_RPC_CMD_SUPP_PLUGIN */ + #endif /*__OPTEE_RPC_CMD_H*/ diff --git a/core/include/tee/tee_supp_plugin_rpc.h b/core/include/tee/tee_supp_plugin_rpc.h new file mode 100644 index 00000000000..996e00f07af --- /dev/null +++ b/core/include/tee/tee_supp_plugin_rpc.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2020, Open Mobile Platform LLC + */ + +#ifndef TEE_SUPP_PLUGIN_RPC_H +#define TEE_SUPP_PLUGIN_RPC_H + +#include +#include +#include + +TEE_Result tee_invoke_supp_plugin_rpc(const TEE_UUID *uuid, uint32_t cmd, + uint32_t sub_cmd, void *buf, size_t len, + size_t *outlen); + +#endif /* TEE_SUPP_PLUGIN_RPC_H */ diff --git a/core/pta/system.c b/core/pta/system.c index 4da87f73af2..8e331beeedd 100644 --- a/core/pta/system.c +++ b/core/pta/system.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2018-2019, Linaro Limited * Copyright (c) 2020, Arm Limited. + * Copyright (c) 2020, Open Mobile Platform LLC */ #include @@ -25,6 +26,8 @@ #include #include #include +#include +#include #include static unsigned int system_pnum; @@ -283,6 +286,30 @@ static TEE_Result system_get_tpm_event_log(uint32_t param_types, return res; } +static TEE_Result system_supp_plugin_invoke(uint32_t param_types, + TEE_Param params[TEE_NUM_PARAMS]) +{ + uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_MEMREF_INOUT, + TEE_PARAM_TYPE_VALUE_OUTPUT); + TEE_Result res = TEE_ERROR_GENERIC; + size_t outlen = 0; + + if (exp_pt != param_types) + return TEE_ERROR_BAD_PARAMETERS; + + res = tee_invoke_supp_plugin_rpc(params[0].memref.buffer, /* uuid */ + params[1].value.a, /* cmd */ + params[1].value.b, /* sub_cmd */ + params[2].memref.buffer, /* data */ + params[2].memref.size, /* in len */ + &outlen); + params[3].value.a = (uint32_t)outlen; + + return res; +} + static TEE_Result open_session(uint32_t param_types __unused, TEE_Param params[TEE_NUM_PARAMS] __unused, void **sess_ctx __unused) @@ -321,6 +348,8 @@ static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id, return system_dlsym(uctx, param_types, params); case PTA_SYSTEM_GET_TPM_EVENT_LOG: return system_get_tpm_event_log(param_types, params); + case PTA_SYSTEM_SUPP_PLUGIN_INVOKE: + return system_supp_plugin_invoke(param_types, params); default: break; } diff --git a/core/tee/sub.mk b/core/tee/sub.mk index 39e680b5bb5..4879f401849 100644 --- a/core/tee/sub.mk +++ b/core/tee/sub.mk @@ -45,3 +45,4 @@ endif #CFG_WITH_USER_TA,y srcs-y += uuid.c srcs-y += tee_ta_enc_manager.c +srcs-y += tee_supp_plugin_rpc.c \ No newline at end of file diff --git a/core/tee/tee_supp_plugin_rpc.c b/core/tee/tee_supp_plugin_rpc.c new file mode 100644 index 00000000000..fe362c3a9a7 --- /dev/null +++ b/core/tee/tee_supp_plugin_rpc.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2020, Open Mobile Platform LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TEE_Result tee_invoke_supp_plugin_rpc(const TEE_UUID *uuid, uint32_t cmd, + uint32_t sub_cmd, void *buf, size_t len, + size_t *outlen) +{ + TEE_Result res = TEE_ERROR_GENERIC; + struct thread_param params[THREAD_RPC_MAX_NUM_PARAMS]; + uint32_t uuid_words[4] = { }; + void *va = NULL; + struct mobj *mobj = NULL; + + /* + * sizeof 'TEE_UUID' and array 'uuid_words' must be same size, + * because 'tee_uuid_to_octets()' is used to copy variable + * with one type to another. + * + * Array 'uuid_words' is used just for convenient work with + * 'TEE_UUID' as with uint32_t values. + */ + COMPILE_TIME_ASSERT(sizeof(TEE_UUID) == sizeof(uuid_words)); + + if (!uuid || (len && !buf) || (!len && buf)) + return TEE_ERROR_BAD_PARAMETERS; + + if (len) { + mobj = thread_rpc_alloc_payload(len); + if (!mobj) { + EMSG("can't create mobj for plugin data"); + return TEE_ERROR_OUT_OF_MEMORY; + } + + va = mobj_get_va(mobj, 0); + if (!va) { + EMSG("can't get va from mobj"); + goto out; + } + + memcpy(va, buf, len); + } + + tee_uuid_to_octets((uint8_t *)uuid_words, uuid); + + params[0] = THREAD_PARAM_VALUE(IN, OPTEE_RPC_SUPP_PLUGIN_INVOKE, + uuid_words[0], uuid_words[1]); + params[1] = THREAD_PARAM_VALUE(IN, uuid_words[2], uuid_words[3], cmd); + params[2] = THREAD_PARAM_VALUE(INOUT, sub_cmd, 0, 0); + params[3] = THREAD_PARAM_MEMREF(INOUT, mobj, 0, len); + + res = thread_rpc_cmd(OPTEE_RPC_CMD_SUPP_PLUGIN, 4, params); + + if (outlen) + *outlen = params[2].u.value.b; + + if (len && outlen && *outlen) + memcpy(buf, va, *outlen <= len ? *outlen : len); + +out: + if (len) + thread_rpc_free_payload(mobj); + + return res; +} diff --git a/lib/libutee/include/pta_system.h b/lib/libutee/include/pta_system.h index c5df748af62..a23f60b8e81 100644 --- a/lib/libutee/include/pta_system.h +++ b/lib/libutee/include/pta_system.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright (c) 2018-2019, Linaro Limited + * Copyright (c) 2020, Open Mobile Platform LLC */ #ifndef __PTA_SYSTEM_H #define __PTA_SYSTEM_H @@ -189,4 +190,15 @@ */ #define PTA_SYSTEM_GET_TPM_EVENT_LOG 12 +/* + * Invoke a tee-supplicant's plugin + * + * [in] memref[0] uuid of the plugin (TEE_UUID) + * [in] value[1].a command for the plugin + * [in] value[1].b sub_command for the plugin + * [in/out] memref[2] additional data for the plugin + * [out] value[3].a output length of data + */ +#define PTA_SYSTEM_SUPP_PLUGIN_INVOKE 13 + #endif /* __PTA_SYSTEM_H */ diff --git a/lib/libutee/include/tee_internal_api_extensions.h b/lib/libutee/include/tee_internal_api_extensions.h index 76960b0e5b5..78b0e39f07e 100644 --- a/lib/libutee/include/tee_internal_api_extensions.h +++ b/lib/libutee/include/tee_internal_api_extensions.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright (c) 2014, STMicroelectronics International N.V. + * Copyright (c) 2020, Open Mobile Platform LLC */ #ifndef TEE_INTERNAL_API_EXTENSIONS_H @@ -62,4 +63,19 @@ TEE_Result tee_unmap(void *buf, size_t len); */ TEE_Result tee_uuid_from_str(TEE_UUID *uuid, const char *s); +/* + * tee_invoke_supp_plugin() - invoke a tee-supplicant's plugin + * @uuid: uuid of the plugin + * @cmd: command for the plugin + * @sub_cmd: subcommand for the plugin + * @buf: data [for/from] the plugin [in/out] + * @len: length of the input buf + * @outlen: pointer to length of the output data (if they will be used) + * + * Return TEE_SUCCESS on success or TEE_ERRROR_* on failure. + */ +TEE_Result tee_invoke_supp_plugin(const TEE_UUID *uuid, uint32_t cmd, + uint32_t sub_cmd, void *buf, size_t len, + size_t *outlen); + #endif diff --git a/lib/libutee/tee_system_pta.c b/lib/libutee/tee_system_pta.c index 775fbe2daf1..6c35045951b 100644 --- a/lib/libutee/tee_system_pta.c +++ b/lib/libutee/tee_system_pta.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2019, Linaro Limited + * Copyright (c) 2020, Open Mobile Platform LLC */ #include @@ -76,3 +77,35 @@ TEE_Result tee_unmap(void *buf, size_t len) return res; } + +TEE_Result tee_invoke_supp_plugin(const TEE_UUID *uuid, uint32_t cmd, + uint32_t sub_cmd, void *buf, size_t len, + size_t *outlen) +{ + TEE_Result res = TEE_SUCCESS; + uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_MEMREF_INOUT, + TEE_PARAM_TYPE_VALUE_OUTPUT); + TEE_Param params[TEE_NUM_PARAMS] = { }; + + if (!uuid || (len && !buf) || (!len && buf)) + return TEE_ERROR_BAD_PARAMETERS; + + params[0].memref.buffer = (void *)uuid; + params[0].memref.size = sizeof(TEE_UUID); + params[1].value.a = cmd; + params[1].value.b = sub_cmd; + params[2].memref.buffer = buf; + params[2].memref.size = len; + + res = invoke_system_pta(PTA_SYSTEM_SUPP_PLUGIN_INVOKE, param_types, + params); + if (res) + EMSG("Invoke tee-supplicant's plugin failed: %#"PRIx32, res); + + if (outlen) + *outlen = params[3].value.a; + + return res; +}