From c90d310ff3ee329c8b9d01baeb352c91007e4a92 Mon Sep 17 00:00:00 2001 From: Divneil Rai Wadhawan Date: Thu, 9 May 2019 17:05:38 +0530 Subject: [PATCH 1/3] tee-supplicant: add support for accessing custom REE service Signed-off-by: Divneil Rai Wadhawan --- libteec/CMakeLists.txt | 1 + libteec/Makefile | 3 +- libteec/src/ree_service_api.c | 255 +++++++++++ public/ree_service_api.h | 76 ++++ public/tee_client_api.h | 2 + tee-supplicant/CMakeLists.txt | 3 + tee-supplicant/Makefile | 6 +- tee-supplicant/src/optee_msg_supplicant.h | 22 + tee-supplicant/src/tee_service.c | 502 ++++++++++++++++++++++ tee-supplicant/src/tee_service.h | 6 + tee-supplicant/src/tee_service_handle.c | 87 ++++ tee-supplicant/src/tee_service_handle.h | 24 ++ tee-supplicant/src/tee_supplicant.c | 4 + 13 files changed, 988 insertions(+), 3 deletions(-) mode change 100644 => 100755 libteec/CMakeLists.txt mode change 100644 => 100755 libteec/Makefile create mode 100755 libteec/src/ree_service_api.c create mode 100755 public/ree_service_api.h mode change 100644 => 100755 public/tee_client_api.h mode change 100644 => 100755 tee-supplicant/CMakeLists.txt mode change 100644 => 100755 tee-supplicant/Makefile mode change 100644 => 100755 tee-supplicant/src/optee_msg_supplicant.h create mode 100755 tee-supplicant/src/tee_service.c create mode 100755 tee-supplicant/src/tee_service.h create mode 100644 tee-supplicant/src/tee_service_handle.c create mode 100644 tee-supplicant/src/tee_service_handle.h mode change 100644 => 100755 tee-supplicant/src/tee_supplicant.c diff --git a/libteec/CMakeLists.txt b/libteec/CMakeLists.txt old mode 100644 new mode 100755 index 9422eeb9..7ef6a155 --- a/libteec/CMakeLists.txt +++ b/libteec/CMakeLists.txt @@ -24,6 +24,7 @@ set (CFG_TEE_CLIENT_LOG_FILE "/data/tee/teec.log" CACHE STRING "Location of libt set (SRC src/tee_client_api.c src/teec_trace.c + src/ree_service_api.c ) if (CFG_TEE_BENCHMARK) diff --git a/libteec/Makefile b/libteec/Makefile old mode 100644 new mode 100755 index 9f475b89..d1388d86 --- a/libteec/Makefile +++ b/libteec/Makefile @@ -18,7 +18,8 @@ LIB_MAJ_MIN := $(LIB_NAME).$(MAJOR_VERSION).$(MINOR_VERSION) LIB_MAJ_MIN_P := $(LIB_NAME).$(MAJOR_VERSION).$(MINOR_VERSION).$(PATCH_VERSION) TEEC_SRCS := tee_client_api.c \ - teec_trace.c + teec_trace.c \ + ree_service_api.c ifeq ($(CFG_TEE_BENCHMARK),y) TEEC_SRCS += teec_benchmark.c endif diff --git a/libteec/src/ree_service_api.c b/libteec/src/ree_service_api.c new file mode 100755 index 00000000..297e4090 --- /dev/null +++ b/libteec/src/ree_service_api.c @@ -0,0 +1,255 @@ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif +#include + +struct service { + int msgqid; + void *buf; + size_t buf_sz; +}; + +static bool is_param_type_value(uint64_t param_type) +{ + if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT) + return true; + return false; +} + +static bool is_param_type_memref(uint64_t param_type) +{ + if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT) + return true; + return false; +} + +/** + * uuid_to_str() - convert uuid structure to string + * + * Example uuid: 2aa2685c-fba3-44be-a218-fbdafebd639a + * Convert the structure to the string form as above + */ +TEEC_Result uuid_to_str(REEC_UUID *uuid, char *uuid_str, size_t size) +{ + uint32_t i, idx; + + if (!uuid || !uuid_str) + return TEEC_ERROR_BAD_PARAMETERS; + + /* Convert to the uuid string */ + snprintf(uuid_str, size, "%08x-", uuid->timeLow); + idx = strlen(uuid_str); + + snprintf(uuid_str + idx, size - idx, "%04x-", uuid->timeMid); + idx = strlen(uuid_str); + + snprintf(uuid_str + idx, size - idx, + "%04x-", uuid->timeHiAndVersion); + idx = strlen(uuid_str); + + snprintf(uuid_str + idx, size, + "%02x%02x-", uuid->clockSeqAndNode[0], + uuid->clockSeqAndNode[1]); + idx = strlen(uuid_str); + + for (i = 2; i < 8; i++) { + snprintf(uuid_str + idx, size - idx, + "%02x", uuid->clockSeqAndNode[i]); + idx = strlen(uuid_str); + } + + return TEEC_SUCCESS; +} + +TEEC_Result ree_service_init(REEC_UUID *uuid, void **service) +{ + int ret = -1; + size_t size; + FILE *fp = NULL; + char filename[64]; + key_t msgqkey = 0; + TEEC_Result result; + char uuid_str[48]; + + result = uuid_to_str(uuid, uuid_str, sizeof(uuid_str)); + if (result != TEEC_SUCCESS) + return result; + + struct service *s = malloc(sizeof(struct service)); + if (!s) + return -ENOMEM; + + /* Create a file in /data/ */ + snprintf(filename, sizeof(filename), "/data/%s", uuid_str); + fp = fopen(filename, "w"); + if (!fp) { + printf("Failed to create a file for token\n"); + goto err; + } + + size = fwrite(uuid_str, 1, strlen(uuid_str), fp); + if (size != strlen(uuid_str)) { + printf("Failed to write to %s\n", filename); + result = TEEC_ERROR_GENERIC; + goto err; + } + + if (fclose(fp)) { + printf("Failed to commit data to storage\n"); + result = TEEC_ERROR_GENERIC; + goto err; + } + + /* Create a message queue and wait for the msg */ + msgqkey = ftok(filename, 'O'); + if (msgqkey == -1) { + printf("Failed to create a msg queue key (%d: %s)\n", + errno, strerror(errno)); + result = TEEC_ERROR_GENERIC; + goto err; + } + + s->msgqid = msgget(msgqkey, 0600 | IPC_CREAT); + if (s->msgqid == -1) { + printf("Failed to get the msg queue\n"); + result = TEEC_ERROR_GENERIC; + goto err; + } + + *service = s; + + return 0; + +err: + if (s) + free(s); + + return ret; +} + +void ree_service_exit(void *service) +{ + struct service *s = service; + + if (!s) + return; + + if (s->msgqid != -1) { + if (msgctl(s->msgqid, IPC_RMID, NULL) == -1) + printf("Failed to delete msgq, try using ipcrm\n"); + } + + if (s->buf) + free(s->buf); + + free(s); +} + +TEEC_Result ree_rcv_params(void *service, size_t *num_params, + struct tee_params *params) +{ + int ret, idx = 0; + char *buf = NULL, *ptr; + struct service *s = service; + long msg_size[2] = {0}; + size_t size, attr_sz, value_sz, mtype_sz = sizeof(long); + + if (!s || !num_params || !params) + return TEEC_ERROR_BAD_PARAMETERS; + + attr_sz = sizeof(params->attr); + value_sz = sizeof(params->u.value); + + /* The first message will tell the size of buffer */ + ret = msgrcv(s->msgqid, &msg_size, + sizeof(msg_size[1]), OPTEE_MRC_MSG_SEND, 0); + if (ret == -1) { + printf("Failed to get the size of buffer\n"); + goto err; + } + size = msg_size[1]; + s->buf_sz = size; + + buf = calloc(size, 1); + if (!buf) { + printf("Out of memory to receive message\n"); + goto err; + } + + /* The second message will retrive full contents */ + ret = msgrcv(s->msgqid, buf, size - mtype_sz, OPTEE_MRC_MSG_SEND, 0); + if (ret == -1) { + printf("Failed to receive msg\n"); + goto err; + } + + /* Real params start from here: buf + mtype_sz */ + for (ptr = buf + mtype_sz; ptr < buf + size - sizeof(TEEC_Result);) { + + if (is_param_type_value(*(long *)ptr)) { + + memcpy(¶ms[idx].attr, ptr, attr_sz); + ptr += attr_sz; + + memcpy(¶ms[idx].u.value, ptr, value_sz); + ptr += value_sz; + + } else if (is_param_type_memref(*(long *)ptr)) { + + memcpy(¶ms[idx].attr, ptr, attr_sz); + ptr += attr_sz; + + params[idx].u.memref.size = *(size_t *)ptr; + params[idx].u.memref.buffer = ptr + + sizeof(params[idx].u.memref.size); + ptr = (char *)params[idx].u.memref.buffer + + params[idx].u.memref.size; + } + idx++; + if (idx == 4) + break; + } + + s->buf = buf; + *num_params = idx; + return 0; + +err: + if (buf) + free(buf); + return TEEC_ERROR_GENERIC; +} + +TEEC_Result ree_snd_params(void *service, size_t num_params, + struct tee_params *params, int32_t error) +{ + struct service *s = service; + size_t mtype_sz = sizeof(long); + + (void)num_params; + (void)params; + (void)error; + + *(TEEC_Result *)((uint8_t *)s->buf + s->buf_sz - sizeof(TEEC_Result)) = error; + + *((long *)s->buf) = OPTEE_MRC_MSG_RCV; + if (msgsnd(s->msgqid, s->buf, s->buf_sz - mtype_sz, 0) == -1) + printf("Failed to send the response\n"); + + return 0; +} diff --git a/public/ree_service_api.h b/public/ree_service_api.h new file mode 100755 index 00000000..38771e90 --- /dev/null +++ b/public/ree_service_api.h @@ -0,0 +1,76 @@ +#ifndef __REE_SERVICE_H__ +#define __REE_SERVICE_H__ + +/* + * Attributes for struct tee_ioctl_param, selects field in the union + */ +#define TEE_PARAM_ATTR_TYPE_NONE 0 /* parameter not used */ + +/* + * These defines value parameters (struct tee_ioctl_param_value) + */ +#define TEE_PARAM_ATTR_TYPE_VALUE_INPUT 1 +#define TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT 2 +#define TEE_PARAM_ATTR_TYPE_VALUE_INOUT 3 /* input and output */ + +/* + * These defines shared memory reference parameters (struct + * tee_ioctl_param_memref) + */ +#define TEE_PARAM_ATTR_TYPE_MEMREF_INPUT 5 +#define TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT 6 +#define TEE_PARAM_ATTR_TYPE_MEMREF_INOUT 7 /* input and output */ +struct tee_param_memref { + void *buffer; + uint64_t size; +}; + +struct tee_param_value { + uint64_t a; + uint64_t b; + uint64_t c; +}; + +struct tee_params { + uint64_t attr; + union { + struct tee_param_memref memref; + struct tee_param_value value; + } u; +}; + +TEEC_Result uuid_to_str(REEC_UUID *uuid, char *uuid_str, size_t size); +TEEC_Result ree_service_init(REEC_UUID *uuid, void **service); +void ree_service_exit(void *service); +TEEC_Result ree_rcv_params(void *service, size_t *num_params, + struct tee_params *params); +TEEC_Result ree_snd_params(void *service, size_t num_params, + struct tee_params *params, int32_t error); + +/* + * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_GENERIC + */ + +/* + * Open REE Service + * + * [in] param[0].u.value.a OPTEE_MRC_GENERIC_OPEN + * [in] param[0].u.value.b TA instance id + * [out] param[1].u.value.c service handle + */ +#define OPTEE_MRC_GENERIC_SERVICE_START 3 + +/* + * Close REE Service + * + * [in] param[0].u.value.a OPTEE_MRC_GENERIC_CLOSE + * [in] param[0].u.value.b TA instance id + */ +#define OPTEE_MRC_GENERIC_SERVICE_STOP 4 + +/* mtype for message queue message exchange */ +#define OPTEE_MRC_MSG_SEND 1 /* send params to service */ +#define OPTEE_MRC_MSG_RCV 2 /* receive params from service */ + + +#endif diff --git a/public/tee_client_api.h b/public/tee_client_api.h old mode 100644 new mode 100755 index 70e76ae1..44ddab64 --- a/public/tee_client_api.h +++ b/public/tee_client_api.h @@ -270,6 +270,8 @@ typedef struct { uint8_t clockSeqAndNode[8]; } TEEC_UUID; +typedef TEEC_UUID REEC_UUID; + /** * struct TEEC_SharedMemory - Memory to transfer data between a client * application and trusted code. diff --git a/tee-supplicant/CMakeLists.txt b/tee-supplicant/CMakeLists.txt old mode 100644 new mode 100755 index 6f35d848..9ab1d8ec --- a/tee-supplicant/CMakeLists.txt +++ b/tee-supplicant/CMakeLists.txt @@ -26,6 +26,8 @@ set (SRC src/tee_supp_fs.c src/tee_supplicant.c src/teec_ta_load.c + src/tee_service.c + src/tee_service_handle.c ) if (CFG_GP_SOCKETS) @@ -86,6 +88,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE src) target_link_libraries (${PROJECT_NAME} PRIVATE teec + PRIVATE dl PRIVATE optee-client-headers) ################################################################################ diff --git a/tee-supplicant/Makefile b/tee-supplicant/Makefile old mode 100644 new mode 100755 index d206b68e..3c2d107f --- a/tee-supplicant/Makefile +++ b/tee-supplicant/Makefile @@ -18,7 +18,9 @@ TEES_SRCS := tee_supplicant.c \ teec_ta_load.c \ tee_supp_fs.c \ rpmb.c \ - handle.c + handle.c \ + tee_service.c \ + tee_service_handle.c ifeq ($(CFG_GP_SOCKETS),y) @@ -55,7 +57,7 @@ ifeq ($(CFG_TA_TEST_PATH),y) TEES_CFLAGS += -DCFG_TA_TEST_PATH=1 endif TEES_FILE := $(OUT_DIR)/$(PACKAGE_NAME) -TEES_LFLAGS := $(LDFLAGS) -L$(OUT_DIR)/../libteec -lteec +TEES_LFLAGS := $(LDFLAGS) -L$(OUT_DIR)/../libteec -lteec -ldl ifeq ($(CFG_TA_GPROF_SUPPORT),y) TEES_CFLAGS += -DCFG_TA_GPROF_SUPPORT diff --git a/tee-supplicant/src/optee_msg_supplicant.h b/tee-supplicant/src/optee_msg_supplicant.h old mode 100644 new mode 100755 index f91b0b1d..ea50fceb --- a/tee-supplicant/src/optee_msg_supplicant.h +++ b/tee-supplicant/src/optee_msg_supplicant.h @@ -183,6 +183,7 @@ */ #define OPTEE_MSG_RPC_CMD_FTRACE 11 +#define OPTEE_MSG_RPC_CMD_GENERIC 30 /* * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_SOCKET @@ -259,4 +260,25 @@ * End of definitions for messages with .cmd == OPTEE_MSG_RPC_CMD_SOCKET */ +/* + * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_GENERIC + */ + +/* + * Open REE Service + * + * [in] param[0].u.value.a OPTEE_MRC_GENERIC_OPEN + * [in] param[0].u.value.b TA instance id + * [out] param[1].u.value.c service handle + */ +#define OPTEE_MRC_GENERIC_OPEN 1 + +/* + * Close REE Service + * + * [in] param[0].u.value.a OPTEE_MRC_GENERIC_CLOSE + * [in] param[0].u.value.b TA instance id + */ +#define OPTEE_MRC_GENERIC_CLOSE 2 + #endif /*__OPTEE_MSG_SUPPLICANT_H*/ diff --git a/tee-supplicant/src/tee_service.c b/tee-supplicant/src/tee_service.c new file mode 100755 index 00000000..b5ce82f8 --- /dev/null +++ b/tee-supplicant/src/tee_service.c @@ -0,0 +1,502 @@ +/* FIXME: Copyright */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif +#include +#include +#include + +static bool is_param_type_value(uint64_t param_type) +{ + if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT) + return true; + return false; +} + +static bool is_param_type_memref(uint64_t param_type) +{ + if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT) + return true; + return false; +} +static bool is_param_type_value_out(uint64_t param_type) +{ + if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT) + return true; + return false; +} + +static bool is_param_type_memref_out(uint64_t param_type) +{ + if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT || + param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT) + return true; + return false; +} + +/** + * params_to_buffer() - serialize params before send + */ +static TEEC_Result params_to_buffer(size_t num_params, + struct tee_ioctl_param *params, + void **buf, size_t *size) +{ + uint8_t i; + char *buffer; + size_t buf_sz = sizeof(long) + sizeof(TEEC_Result), ctr = sizeof(long); + size_t attr_sz = sizeof(params->attr); + size_t value_sz = sizeof(params->u.value); + + /* Calculate the total size of parameters */ + for (i = 0; i < num_params; i++) { + if (tee_supp_param_is_value(¶ms[i])) + buf_sz += attr_sz + value_sz; + else if (tee_supp_param_is_memref(¶ms[i])) + buf_sz += attr_sz + sizeof(params[i].u.memref.size) + + params[i].u.memref.size; + } + + /* + * Allocate a buffer and fill in the buffer like: + * ------------------------------------------------------ + * | type | + * ------------------------------------------------------ + * | size (in case of memref) | + * ----------------------------------------------------- + * | contents (values, or buffer in case of memref) | + * ----------------------------------------------------- + * | All all params, reserve space to receive TEEC_Result | + * ------------------------------------------------------ + */ + buffer = calloc(buf_sz, 1); + if (!buffer) + return TEEC_ERROR_OUT_OF_MEMORY; + + for (i = 0; i < num_params; i++) { + if (is_param_type_value(params[i].attr)) { + memcpy(buffer + ctr, ¶ms[i].attr, attr_sz); + ctr += attr_sz; + + memcpy(buffer + ctr, ¶ms[i].u.value, value_sz); + ctr += value_sz; + } else if (tee_supp_param_is_memref(¶ms[i])) { + memcpy(buffer + ctr, ¶ms[i].attr, attr_sz); + ctr += attr_sz; + + memcpy(buffer + ctr, ¶ms[i].u.memref.size, + sizeof(params[i].u.memref.size)); + ctr += sizeof(params[i].u.memref.size); + + memcpy(buffer + ctr, tee_supp_param_to_va(params + i), + params[i].u.memref.size); + ctr += params[i].u.memref.size; + } + } + + *buf = buffer; + *size = buf_sz; + return TEEC_SUCCESS; +} + +static TEEC_Result send_msg(size_t num_params, + struct tee_ioctl_param *params, int msgqid, + void **buffer, size_t *sent) +{ + void *buf = NULL; + size_t size; + TEEC_Result result; + long msg_size[2]; + + if (params->attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT) + return TEEC_ERROR_BAD_PARAMETERS; + + result = params_to_buffer(num_params, params, &buf, &size); + if (result != TEEC_SUCCESS) + return result; + + + /* Send the complete message size */ + msg_size[0] = OPTEE_MRC_MSG_SEND; + msg_size[1] = size; + if (msgsnd(msgqid, &msg_size, sizeof(msg_size[1]), 0) == -1) { + EMSG("Failed to send msg with size: %lu\n", size); + result = TEEC_ERROR_GENERIC; + goto err; + } + + /* Send the complete msg */ + *(long *)buf = OPTEE_MRC_MSG_SEND; + if (msgsnd(msgqid, buf, size - sizeof(long), 0) == -1) { + EMSG("Failed to send msg with size: %lu\n", size); + result = TEEC_ERROR_GENERIC; + goto err; + } + + *buffer = buf; + *sent = size; + + return TEEC_SUCCESS; + +err: + if (buf) + free(buf); + return result; +} + +/** + * fill_param() - deserialize buffer to params + */ +static TEEC_Result fill_param(size_t num_params, + struct tee_ioctl_param *params, + void *buf, size_t size) +{ + char *ptr = (char *)buf + sizeof(long); + size_t attr_sz = sizeof(params->attr); + size_t value_sz = sizeof(params->u.value); + size_t idx = 1; + TEEC_Result err = TEEC_SUCCESS; + + if (!is_param_type_value(*ptr)) + return TEEC_ERROR_BAD_PARAMETERS; + + /* If the command processing results in error, send back the same */ + err = *(TEEC_Result *)((uint8_t *)buf + size - sizeof(TEEC_Result)); + if (err != TEEC_SUCCESS) + return err; + + ptr += attr_sz + value_sz; + + for (; ptr < (char*)buf + size && idx < num_params;) { + if (is_param_type_memref_out(*ptr)) { + ptr += attr_sz + sizeof(params[idx].u.memref.size); + memcpy(tee_supp_param_to_va(params + idx), ptr, + params[idx].u.memref.size); + ptr += params[idx].u.memref.size; + } else if (is_param_type_value_out(*ptr)) { + ptr += attr_sz; + memcpy(¶ms[idx].u.value, ptr, value_sz); + ptr += value_sz; + } + else if (is_param_type_memref(*ptr) && + !is_param_type_memref_out(*ptr)) { + ptr += attr_sz; + ptr += (*(uint64_t *)ptr); + ptr += sizeof(params[idx].u.memref.size); + } else if (is_param_type_value(*ptr) && + !is_param_type_value_out(*ptr)) { + ptr += attr_sz + value_sz; + } + idx++; + } + + return TEEC_SUCCESS; +} + +static TEEC_Result rcv_msg(void *buf, size_t size, int msgqid, + size_t num_params, struct tee_ioctl_param *params) +{ + size_t rcvd; + TEEC_Result result = TEEC_SUCCESS; + + /* We just need to fill in the OUT params from the buffer */ + rcvd = msgrcv(msgqid, buf, size - sizeof(long), OPTEE_MRC_MSG_RCV, 0); + if (rcvd == (size_t)-1) { + EMSG("Failed to retrieve message from ree service (%d, %s)\n", + errno, strerror(errno)); + result = TEEC_ERROR_GENERIC; + goto err; + } + + result = fill_param(num_params, params, buf, size); + +err: + if (buf) + free(buf); + + return result; +} + +static TEEC_Result process_dlib_params(void *dl, size_t num_params, + struct tee_ioctl_param *params) +{ + size_t i; + TEEC_Result res = TEEC_SUCCESS; + TEEC_Result (*process_tee_params)(size_t num_params, struct tee_params *params); + struct tee_params tee_params[4]; + + process_tee_params = dlsym(dl, "process_tee_params"); + if (dlerror() != NULL) { + EMSG("no params handling implementation found"); + res = TEEC_ERROR_NOT_IMPLEMENTED; + goto err; + } + + for (i = 0; i < num_params; i++) { + if (is_param_type_value(params[i].attr) & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { + switch (params[i].attr) { + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: + tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; + break; + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: + tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; + break; + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: + tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT; + break; + default: + break; + } + memcpy(&tee_params[i].u.value, ¶ms[i].u.value, sizeof(tee_params[i].u.value)); + } else if (is_param_type_memref(params[i].attr)) { + switch (params[i].attr) { + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: + tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; + break; + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: + tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + break; + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: + tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; + break; + default: + break; + } + tee_params[i].u.memref.buffer = tee_supp_param_to_va(params + i); + tee_params[i].u.memref.size = params[i].u.memref.size; + } + } + + res = process_tee_params(num_params, tee_params); + if (res != TEEC_SUCCESS) { + EMSG("failed to handle the tee params\n"); + res = TEEC_ERROR_GENERIC; + } + + /* Fill back all the values */ + for (i = 0; i < num_params; i++) { + if (is_param_type_value_out(params[i].attr)) + memcpy(¶ms[i].u.value, &tee_params[i].u.value, sizeof(params[i].u.value)); + } + +err: + return res; +} + +static TEEC_Result open_service_msg_queue(struct tee_ioctl_param *params) +{ + key_t msgqkey; + int msgqid, handle; + TEEC_Result res = TEEC_SUCCESS; + char filename[64], uuid_str[48]; + struct service_handle *hdl = NULL; + uint32_t instance_id = params[0].u.value.b; + REEC_UUID *uuid = tee_supp_param_to_va(params + 1); + + DMSG("===== OPTEE_MRC_GENERIC_OPEN === \n"); + + /* Convert to the uuid string */ + res = uuid_to_str(uuid, uuid_str, sizeof(uuid_str)); + if (res != TEEC_SUCCESS) { + EMSG("failed to convert UUID to string"); + goto err; + } + + /* Open the message queue */ + snprintf(filename, sizeof(filename), "/data/%s", uuid_str); + msgqkey = ftok(filename, 'O'); + if (msgqkey == -1) { + EMSG("failed to create a msg queue key"); + res = TEEC_ERROR_GENERIC; + goto err; + } + + msgqid = msgget(msgqkey, 0600); + if (msgqid == -1) { + EMSG("failed to get the msg queue id"); + res = TEEC_ERROR_GENERIC; + goto err; + } + + /* Allocate service info */ + hdl = calloc(1, sizeof(struct service_handle)); + if (!hdl) { + EMSG("out of memory for msgq service info"); + res = TEEC_ERROR_OUT_OF_MEMORY; + goto err; + } + hdl->type = MSGQ_HANDLE; + hdl->u.msgqid = msgqid; + + /* Convert the msgqid to handle */ + handle = service_handle_new(instance_id, hdl); + if (handle < 0) { + EMSG("failed to get msgq service handle"); + res = TEEC_ERROR_GENERIC; + goto err; + } + params[2].u.value.a = handle; + + return res; + +err: + if (hdl) + free(hdl); + return res; +} + +static TEEC_Result open_service_dlib(struct tee_ioctl_param *params) +{ + void *dl_handle; + TEEC_Result res = TEEC_SUCCESS; + char libname[64], uuid_str[48]; + struct service_handle *hdl = NULL; + REEC_UUID *uuid = tee_supp_param_to_va(params + 1); + + printf("========== generic open ======== \n"); + res = uuid_to_str(uuid, uuid_str, sizeof(uuid_str)); + if (res != TEEC_SUCCESS) + return TEEC_ERROR_GENERIC; + + snprintf(libname, sizeof(libname), "/usr/lib/lib%s.so", uuid_str); + dl_handle = dlopen(libname, RTLD_LAZY); + if (!dl_handle) { + printf("Failed to open %s (%s)\n", libname, dlerror()); + return TEEC_ERROR_GENERIC; + } + + /* Allocate service info */ + hdl = calloc(1, sizeof(struct service_handle)); + if (!hdl) { + EMSG("out of memory for dl service info"); + res = TEEC_ERROR_OUT_OF_MEMORY; + goto err; + } + hdl->type = DLIB_HANDLE; + hdl->u.dl = dl_handle; + + /* Get the handle to the service */ + params[2].u.value.a = service_handle_new(params[0].u.value.b, hdl); + printf("========= generic open done (%p) ========== \n", dl_handle); + +err: + return res; +} + +/** + * tee_service_process() - called from tee-supplicant + * This functions finds the service for tee based on UUID + * based on either message queue or dynamic lib. + * o Message queue is useful when we want to directly pass + * some date to CA. + * o Dynamic library interface is useful when we want some + * non-CA specific functionality like network library, + * which is likely not relevant for the TA/CA state machine. + */ +TEEC_Result tee_service_process(size_t num_params, + struct tee_ioctl_param *params) +{ + uint32_t instance_id = params[0].u.value.b; + + switch (params[0].u.value.a) { + case OPTEE_MRC_GENERIC_OPEN: + { + TEEC_Result res = TEEC_SUCCESS; + + /* + * Find if the service is present as message queue + * or as a dynamic library. + * a. Open the uuid as a message queue in r-x mode. + * It will fail if the message queue is not present. + * b. Open the dl with the pre-defined symbols + * One of will pass. + */ + res = open_service_msg_queue(params); + if (res != TEEC_SUCCESS) + res = open_service_dlib(params); + + break; + } + + case OPTEE_MRC_GENERIC_CLOSE: + { + struct service_handle *hdl = NULL; + + DMSG("===== OPTEE_MRC_GENERIC_CLOSE === \n"); + + hdl = service_handle_get(instance_id, params->u.value.c); + if (!hdl) { + EMSG("unregistered handle, no such handle"); + return TEEC_ERROR_GENERIC; + } + + if (hdl->type == DLIB_HANDLE) + dlclose(hdl->u.dl); + + service_handle_put(instance_id, params->u.value.c); + free(hdl); + break; + } + + /* + * Anyother command will be handled by the service + * mtype = 1 (OPTEE_MRC_SEND) - send params to service + * mtype = 2 (OPTEE_MRC_RCV) - receive params from service + */ + default: + { + TEEC_Result result; + size_t sent; + void *buf; + struct service_handle *hdl = NULL; + + DMSG("===== Routing to service === \n"); + + /* + * Get the handle from the instance and route to either + * message queue or to dynamic lib. + */ + hdl = service_handle_get(instance_id, params->u.value.c); + if (!hdl) { + EMSG("unregistered handle, no such handle"); + return TEEC_ERROR_GENERIC; + } + + if (hdl->type == MSGQ_HANDLE) { + result = send_msg(num_params, params, hdl->u.msgqid, &buf, &sent); + if (result != TEEC_SUCCESS) { + EMSG("Failed to send message to the service\n"); + return TEEC_ERROR_GENERIC; + } + + result = rcv_msg(buf, sent, hdl->u.msgqid, num_params, params); + if (result != TEEC_SUCCESS) { + EMSG("Failed to receive response from the service\n"); + return TEEC_ERROR_GENERIC; + } + } else if (hdl->type == DLIB_HANDLE) { + result = process_dlib_params(hdl->u.dl, num_params, params); + } + + break; + } + } + + return TEEC_SUCCESS; +} diff --git a/tee-supplicant/src/tee_service.h b/tee-supplicant/src/tee_service.h new file mode 100755 index 00000000..e6f1e5cb --- /dev/null +++ b/tee-supplicant/src/tee_service.h @@ -0,0 +1,6 @@ +#ifndef __TEE_SERVICE_H__ +#define __TEE_SERVICE_H__ + +TEEC_Result tee_service_process(size_t num_params, + struct tee_ioctl_param *params); +#endif diff --git a/tee-supplicant/src/tee_service_handle.c b/tee-supplicant/src/tee_service_handle.c new file mode 100644 index 00000000..ab5bae5e --- /dev/null +++ b/tee-supplicant/src/tee_service_handle.c @@ -0,0 +1,87 @@ +/* FIXME: Copyright */ + +#include +#include +#include + +#include +#include + +/* TA is identified by this instance */ +struct service_instance { + uint32_t id; + struct handle_db db; + TAILQ_ENTRY(service_instance) link; +}; + +static pthread_mutex_t service_db_mutex = PTHREAD_MUTEX_INITIALIZER; +TAILQ_HEAD(, service_instance) service_instances = + TAILQ_HEAD_INITIALIZER(service_instances); + +static void service_db_lock(void) +{ + pthread_mutex_lock(&service_db_mutex); +} + +static void service_db_unlock(void) +{ + pthread_mutex_unlock(&service_db_mutex); +} + +static struct service_instance *service_instance_find(uint32_t instance_id) +{ + struct service_instance *instance; + + TAILQ_FOREACH(instance, &service_instances, link) { + if (instance->id == instance_id) + return instance; + } + return NULL; +} + +int service_handle_new(uint32_t instance_id, void *ptr) +{ + int handle = -1; + struct service_instance *instance; + + service_db_lock(); + + instance = service_instance_find(instance_id); + if (!instance) { + instance = calloc(1, sizeof(*instance)); + if (!instance) + goto out; + instance->id = instance_id; + TAILQ_INSERT_TAIL(&service_instances, instance, link); + } + + handle = handle_get(&instance->db, ptr); + +out: + service_db_unlock(); + return handle; +} + +void *service_handle_get(uint32_t instance_id, uint32_t handle) +{ + void *ptr = NULL; + struct service_instance *instance; + + service_db_lock(); + instance = service_instance_find(instance_id); + if (instance) + ptr = handle_lookup(&instance->db, handle); + service_db_unlock(); + return ptr; +} + +void service_handle_put(uint32_t instance_id, uint32_t handle) +{ + struct service_instance *instance; + + service_db_lock(); + instance = service_instance_find(instance_id); + if (instance) + handle_put(&instance->db, handle); + service_db_unlock(); +} diff --git a/tee-supplicant/src/tee_service_handle.h b/tee-supplicant/src/tee_service_handle.h new file mode 100644 index 00000000..fef99ce4 --- /dev/null +++ b/tee-supplicant/src/tee_service_handle.h @@ -0,0 +1,24 @@ +/* FIXME: Copyright */ + +#ifndef __TEE_SERVICE_HANDLE_H_ +#define __TEE_SERVICE_HANDLE_H__ + +typedef enum { + MSGQ_HANDLE = 1, + DLIB_HANDLE = 2, +} service_type_t; + +/* Service information to determine which type to invoke */ +struct service_handle { + service_type_t type; + union { + int msgqid; + void *dl; + }u; +}; + +int service_handle_new(uint32_t instance_id, void *ptr); +void *service_handle_get(uint32_t instance_id, uint32_t handle); +void service_handle_put(uint32_t instance_id, uint32_t handle); + +#endif diff --git a/tee-supplicant/src/tee_supplicant.c b/tee-supplicant/src/tee_supplicant.c old mode 100644 new mode 100755 index 8d5c5539..9ab86ce6 --- a/tee-supplicant/src/tee_supplicant.c +++ b/tee-supplicant/src/tee_supplicant.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -626,6 +627,9 @@ static bool process_one_request(struct thread_arg *arg) case OPTEE_MSG_RPC_CMD_FTRACE: ret = prof_process(num_params, params, "ftrace-"); break; + case OPTEE_MSG_RPC_CMD_GENERIC: + ret = tee_service_process(num_params, params); + break; default: EMSG("Cmd [0x%" PRIx32 "] not supported", func); /* Not supported. */ From 1b24dc4d5019c42b4b6970fb3c39a7f0929afc3c Mon Sep 17 00:00:00 2001 From: Divneil Rai Wadhawan Date: Fri, 20 Sep 2019 00:31:26 +0530 Subject: [PATCH 2/3] tee-supplicant: refactored the ree service solution o Added more comments o Renamed following APIs - ree_rcv_params() -> ree_service_rcv() - ree_snd_params() -> ree_service_snd() Signed-off-by: Divneil Rai Wadhawan --- libteec/CMakeLists.txt | 2 +- libteec/Makefile | 6 +- libteec/src/ree_service_api.c | 214 +++++++++++++-------- public/ree_service_api.h | 63 +++--- public/tee_client_api.h | 3 +- tee-supplicant/src/optee_msg_supplicant.h | 11 +- tee-supplicant/src/tee_service.c | 224 ++++++++++++++-------- tee-supplicant/src/tee_service.h | 4 + tee-supplicant/src/tee_service_handle.c | 4 +- tee-supplicant/src/tee_service_handle.h | 8 +- tee-supplicant/src/tee_supplicant.c | 3 +- 11 files changed, 343 insertions(+), 199 deletions(-) diff --git a/libteec/CMakeLists.txt b/libteec/CMakeLists.txt index 7ef6a155..9d57ff02 100755 --- a/libteec/CMakeLists.txt +++ b/libteec/CMakeLists.txt @@ -22,9 +22,9 @@ set (CFG_TEE_CLIENT_LOG_FILE "/data/tee/teec.log" CACHE STRING "Location of libt # Source files ################################################################################ set (SRC + src/ree_service_api.c src/tee_client_api.c src/teec_trace.c - src/ree_service_api.c ) if (CFG_TEE_BENCHMARK) diff --git a/libteec/Makefile b/libteec/Makefile index d1388d86..7750a646 100755 --- a/libteec/Makefile +++ b/libteec/Makefile @@ -17,9 +17,9 @@ LIB_MAJOR := $(LIB_NAME).$(MAJOR_VERSION) LIB_MAJ_MIN := $(LIB_NAME).$(MAJOR_VERSION).$(MINOR_VERSION) LIB_MAJ_MIN_P := $(LIB_NAME).$(MAJOR_VERSION).$(MINOR_VERSION).$(PATCH_VERSION) -TEEC_SRCS := tee_client_api.c \ - teec_trace.c \ - ree_service_api.c +TEEC_SRCS := ree_service_api.c \ + tee_client_api.c \ + teec_trace.c ifeq ($(CFG_TEE_BENCHMARK),y) TEEC_SRCS += teec_benchmark.c endif diff --git a/libteec/src/ree_service_api.c b/libteec/src/ree_service_api.c index 297e4090..148a8bc7 100755 --- a/libteec/src/ree_service_api.c +++ b/libteec/src/ree_service_api.c @@ -1,41 +1,63 @@ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ +#include #include #include #include #include -#include -#include -#include #include +#include +#include #ifndef __aligned #define __aligned(x) __attribute__((__aligned__(x))) #endif #include -struct service { +/* + * Internal structure to represent Message Queue Service. + * struct msgq_service + * @msgqid: Message Queue received from system + * @buf : Buffer associated with service + * @buf_sz: Size of @buf + */ +struct msgq_service { int msgqid; void *buf; size_t buf_sz; }; -static bool is_param_type_value(uint64_t param_type) +/** + * param_type_is_value() - returns true if param type is value + */ +static bool param_type_is_value(uint64_t param_type) { - if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT) + switch(param_type) { + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: return true; - return false; + default: + return false; + } } -static bool is_param_type_memref(uint64_t param_type) +/** + * param_type_is_memref() - returns true if param type is memory reference + */ +static bool param_type_is_memref(uint64_t param_type) { - if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT) + switch (param_type) { + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: return true; - return false; + default: + return false; + } } /** @@ -44,130 +66,153 @@ static bool is_param_type_memref(uint64_t param_type) * Example uuid: 2aa2685c-fba3-44be-a218-fbdafebd639a * Convert the structure to the string form as above */ -TEEC_Result uuid_to_str(REEC_UUID *uuid, char *uuid_str, size_t size) +TEEC_Result uuid_to_str(TEEC_UUID *uuid, char *uuid_str, size_t size) { - uint32_t i, idx; + uint32_t idx; - if (!uuid || !uuid_str) + if (!uuid || !uuid_str || !size) return TEEC_ERROR_BAD_PARAMETERS; /* Convert to the uuid string */ - snprintf(uuid_str, size, "%08x-", uuid->timeLow); - idx = strlen(uuid_str); - - snprintf(uuid_str + idx, size - idx, "%04x-", uuid->timeMid); + snprintf(uuid_str, size, "%08x-%04x-%04x-", + uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion); idx = strlen(uuid_str); - snprintf(uuid_str + idx, size - idx, - "%04x-", uuid->timeHiAndVersion); - idx = strlen(uuid_str); - - snprintf(uuid_str + idx, size, - "%02x%02x-", uuid->clockSeqAndNode[0], - uuid->clockSeqAndNode[1]); - idx = strlen(uuid_str); - - for (i = 2; i < 8; i++) { - snprintf(uuid_str + idx, size - idx, - "%02x", uuid->clockSeqAndNode[i]); - idx = strlen(uuid_str); - } + "%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1], + uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3], + uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5], + uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]); return TEEC_SUCCESS; } -TEEC_Result ree_service_init(REEC_UUID *uuid, void **service) +/** + * ree_service_init() - Initiliaze the Message Queue service + * A Client Application(CA) which wants to service TEE requests + * within its context, can use this API. This API internally + * creates a Message Queue which will listen for data coming + * from tee-supplicant. + * + * Return Value: + * fills in a service handle to uniquely identify this service + * returns TEE_SUCCESS on success, else TEEC_ERROR_ + */ +TEEC_Result ree_service_init(TEEC_UUID *uuid, void **service_hdl) { - int ret = -1; - size_t size; - FILE *fp = NULL; char filename[64]; + char uuid_str[48]; + FILE *fp = NULL; key_t msgqkey = 0; + size_t size; + struct msgq_service *s = NULL; TEEC_Result result; - char uuid_str[48]; + /* Convert UUID structure to string as given by uuidgen */ result = uuid_to_str(uuid, uuid_str, sizeof(uuid_str)); if (result != TEEC_SUCCESS) - return result; + goto err; - struct service *s = malloc(sizeof(struct service)); - if (!s) - return -ENOMEM; + /* + * Allocate the service context. This will uniquely identify + * this service context + */ + s = malloc(sizeof(struct msgq_service)); + if (!s) { + result = TEEC_ERROR_OUT_OF_MEMORY; + goto err; + } - /* Create a file in /data/ */ + /* Set the error code for next file operations */ + result = TEEC_ERROR_ACCESS_DENIED; + + /* + * Create a file in /data/. tee-supplicant must be having + * access to /data folder, otherwise, servicing by REE will fail + */ snprintf(filename, sizeof(filename), "/data/%s", uuid_str); fp = fopen(filename, "w"); if (!fp) { - printf("Failed to create a file for token\n"); + EMSG("Failed to create a file for token"); goto err; } + /* Write the same uuid to the file */ size = fwrite(uuid_str, 1, strlen(uuid_str), fp); if (size != strlen(uuid_str)) { - printf("Failed to write to %s\n", filename); - result = TEEC_ERROR_GENERIC; + EMSG("Failed to write to %s", filename); goto err; } + /* Flush out the data to filesystem */ if (fclose(fp)) { - printf("Failed to commit data to storage\n"); - result = TEEC_ERROR_GENERIC; + EMSG("Failed to commit data to storage"); goto err; } + fp = NULL; /* Create a message queue and wait for the msg */ msgqkey = ftok(filename, 'O'); if (msgqkey == -1) { - printf("Failed to create a msg queue key (%d: %s)\n", + EMSG("Failed to create a msg queue key (%d: %s)", errno, strerror(errno)); - result = TEEC_ERROR_GENERIC; goto err; } s->msgqid = msgget(msgqkey, 0600 | IPC_CREAT); if (s->msgqid == -1) { - printf("Failed to get the msg queue\n"); - result = TEEC_ERROR_GENERIC; + EMSG("Failed to get the msg queue"); goto err; } - *service = s; - - return 0; + *service_hdl = s; + result = TEEC_SUCCESS; /* All good, mark as success */ err: - if (s) + if (fp) + fclose(fp); + if (s && result != TEEC_SUCCESS) free(s); - - return ret; + return result; } -void ree_service_exit(void *service) +/** + * ree_service_exit() - release the service context + * Cleanup the Posix Message Queue from the system + */ +void ree_service_exit(void *service_hdl) { - struct service *s = service; + struct msgq_service *s = service_hdl; if (!s) return; if (s->msgqid != -1) { if (msgctl(s->msgqid, IPC_RMID, NULL) == -1) - printf("Failed to delete msgq, try using ipcrm\n"); + EMSG("Failed to delete msgq, try using ipcrm"); } - if (s->buf) - free(s->buf); - + free(s->buf); free(s); } -TEEC_Result ree_rcv_params(void *service, size_t *num_params, + +/** + * ree_service_rcv() - receive the parameters sent by UTA + */ +TEEC_Result ree_service_rcv(void *service_hdl, size_t *num_params, struct tee_params *params) { - int ret, idx = 0; - char *buf = NULL, *ptr; - struct service *s = service; + char *buf = NULL; + int idx = 0; + char *ptr; + int ret; long msg_size[2] = {0}; - size_t size, attr_sz, value_sz, mtype_sz = sizeof(long); + size_t attr_sz; + size_t mtype_sz = sizeof(long); + size_t size; + size_t value_sz; + struct msgq_service *s = service_hdl; if (!s || !num_params || !params) return TEEC_ERROR_BAD_PARAMETERS; @@ -179,7 +224,7 @@ TEEC_Result ree_rcv_params(void *service, size_t *num_params, ret = msgrcv(s->msgqid, &msg_size, sizeof(msg_size[1]), OPTEE_MRC_MSG_SEND, 0); if (ret == -1) { - printf("Failed to get the size of buffer\n"); + EMSG("Failed to get the size of buffer"); goto err; } size = msg_size[1]; @@ -187,21 +232,21 @@ TEEC_Result ree_rcv_params(void *service, size_t *num_params, buf = calloc(size, 1); if (!buf) { - printf("Out of memory to receive message\n"); + EMSG("Out of memory to receive message"); goto err; } /* The second message will retrive full contents */ ret = msgrcv(s->msgqid, buf, size - mtype_sz, OPTEE_MRC_MSG_SEND, 0); if (ret == -1) { - printf("Failed to receive msg\n"); + EMSG("Failed to receive msg"); goto err; } /* Real params start from here: buf + mtype_sz */ for (ptr = buf + mtype_sz; ptr < buf + size - sizeof(TEEC_Result);) { - if (is_param_type_value(*(long *)ptr)) { + if (param_type_is_value(*(long *)ptr)) { memcpy(¶ms[idx].attr, ptr, attr_sz); ptr += attr_sz; @@ -209,7 +254,7 @@ TEEC_Result ree_rcv_params(void *service, size_t *num_params, memcpy(¶ms[idx].u.value, ptr, value_sz); ptr += value_sz; - } else if (is_param_type_memref(*(long *)ptr)) { + } else if (param_type_is_memref(*(long *)ptr)) { memcpy(¶ms[idx].attr, ptr, attr_sz); ptr += attr_sz; @@ -221,7 +266,7 @@ TEEC_Result ree_rcv_params(void *service, size_t *num_params, params[idx].u.memref.size; } idx++; - if (idx == 4) + if (idx == TEEC_CONFIG_PAYLOAD_REF_COUNT) break; } @@ -235,21 +280,28 @@ TEEC_Result ree_rcv_params(void *service, size_t *num_params, return TEEC_ERROR_GENERIC; } -TEEC_Result ree_snd_params(void *service, size_t num_params, +/** + * ree_service_snd() - send the response back to UTA + */ +TEEC_Result ree_service_snd(void *service_hdl, size_t num_params, struct tee_params *params, int32_t error) { - struct service *s = service; + struct msgq_service *s = service_hdl; size_t mtype_sz = sizeof(long); (void)num_params; (void)params; (void)error; - *(TEEC_Result *)((uint8_t *)s->buf + s->buf_sz - sizeof(TEEC_Result)) = error; + *(TEEC_Result *)((uint8_t *)s->buf + + s->buf_sz - sizeof(TEEC_Result)) = error; *((long *)s->buf) = OPTEE_MRC_MSG_RCV; if (msgsnd(s->msgqid, s->buf, s->buf_sz - mtype_sz, 0) == -1) - printf("Failed to send the response\n"); + EMSG("Failed to send the response"); + + free(s->buf); + s->buf = NULL; return 0; } diff --git a/public/ree_service_api.h b/public/ree_service_api.h index 38771e90..713942ad 100755 --- a/public/ree_service_api.h +++ b/public/ree_service_api.h @@ -1,17 +1,24 @@ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ + #ifndef __REE_SERVICE_H__ #define __REE_SERVICE_H__ +#include +#include + /* * Attributes for struct tee_ioctl_param, selects field in the union */ -#define TEE_PARAM_ATTR_TYPE_NONE 0 /* parameter not used */ +#define TEE_PARAM_ATTR_TYPE_NONE 0 /* parameter not used */ /* * These defines value parameters (struct tee_ioctl_param_value) */ -#define TEE_PARAM_ATTR_TYPE_VALUE_INPUT 1 +#define TEE_PARAM_ATTR_TYPE_VALUE_INPUT 1 #define TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT 2 -#define TEE_PARAM_ATTR_TYPE_VALUE_INOUT 3 /* input and output */ +#define TEE_PARAM_ATTR_TYPE_VALUE_INOUT 3 /* input and output */ /* * These defines shared memory reference parameters (struct @@ -19,18 +26,33 @@ */ #define TEE_PARAM_ATTR_TYPE_MEMREF_INPUT 5 #define TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT 6 -#define TEE_PARAM_ATTR_TYPE_MEMREF_INOUT 7 /* input and output */ +#define TEE_PARAM_ATTR_TYPE_MEMREF_INOUT 7 /* input and output */ + +/* + * struct tee_param_memref + * @buffer: pointer to buffer (contains data based on type (IN/OUT/INOUT) + * @size : size of @buffer + */ struct tee_param_memref { void *buffer; uint64_t size; }; +/* + * struct tee_param_value + */ struct tee_param_value { uint64_t a; uint64_t b; uint64_t c; }; +/* + * struct tee_params + * @attr : MEMREF/INPUT type. It decides what to use from union + * @memref: See struct tee_param_memref + * @vaue : See struct tee_param_value + */ struct tee_params { uint64_t attr; union { @@ -39,38 +61,35 @@ struct tee_params { } u; }; -TEEC_Result uuid_to_str(REEC_UUID *uuid, char *uuid_str, size_t size); -TEEC_Result ree_service_init(REEC_UUID *uuid, void **service); +TEEC_Result uuid_to_str(TEEC_UUID *uuid, char *uuid_str, size_t size); + +TEEC_Result ree_service_init(TEEC_UUID *uuid, void **service); void ree_service_exit(void *service); -TEEC_Result ree_rcv_params(void *service, size_t *num_params, + +TEEC_Result ree_service_rcv(void *service, size_t *num_params, struct tee_params *params); -TEEC_Result ree_snd_params(void *service, size_t num_params, +TEEC_Result ree_service_snd(void *service, size_t num_params, struct tee_params *params, int32_t error); /* - * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_GENERIC + * Start REE Service + * + * [in] param[0].u.value.a OPTEE_MRC_REE_SERVICE_START */ +#define OPTEE_MRC_REE_SERVICE_START 0xFFFFFFF2 /* - * Open REE Service + * Stop REE Service * - * [in] param[0].u.value.a OPTEE_MRC_GENERIC_OPEN - * [in] param[0].u.value.b TA instance id - * [out] param[1].u.value.c service handle + * [in] param[0].u.value.a OPTEE_MRC_REE_SERVICE_STOP */ -#define OPTEE_MRC_GENERIC_SERVICE_START 3 +#define OPTEE_MRC_REE_SERVICE_STOP 0xFFFFFFF3 /* - * Close REE Service - * - * [in] param[0].u.value.a OPTEE_MRC_GENERIC_CLOSE - * [in] param[0].u.value.b TA instance id + * mtype for message queue message exchange. Internal defines for + * service handling. */ -#define OPTEE_MRC_GENERIC_SERVICE_STOP 4 - -/* mtype for message queue message exchange */ #define OPTEE_MRC_MSG_SEND 1 /* send params to service */ #define OPTEE_MRC_MSG_RCV 2 /* receive params from service */ - #endif diff --git a/public/tee_client_api.h b/public/tee_client_api.h index 44ddab64..f59080db 100755 --- a/public/tee_client_api.h +++ b/public/tee_client_api.h @@ -3,6 +3,7 @@ * All rights reserved. * Copyright (c) 2015, Linaro Limited * All rights reserved. + * Copyright (C) 2019 Intel Corporation All Rights Reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -270,8 +271,6 @@ typedef struct { uint8_t clockSeqAndNode[8]; } TEEC_UUID; -typedef TEEC_UUID REEC_UUID; - /** * struct TEEC_SharedMemory - Memory to transfer data between a client * application and trusted code. diff --git a/tee-supplicant/src/optee_msg_supplicant.h b/tee-supplicant/src/optee_msg_supplicant.h index ea50fceb..a459fcd3 100755 --- a/tee-supplicant/src/optee_msg_supplicant.h +++ b/tee-supplicant/src/optee_msg_supplicant.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2016-2017, Linaro Limited * All rights reserved. + * Copyright (C) 2019 Intel Corporation All Rights Reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -183,7 +184,7 @@ */ #define OPTEE_MSG_RPC_CMD_FTRACE 11 -#define OPTEE_MSG_RPC_CMD_GENERIC 30 +#define OPTEE_MSG_RPC_CMD_REE_SERVICE 30 /* * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_SOCKET @@ -265,20 +266,20 @@ */ /* - * Open REE Service + * Open REE Service: To be handled by tee-supplicant * * [in] param[0].u.value.a OPTEE_MRC_GENERIC_OPEN * [in] param[0].u.value.b TA instance id * [out] param[1].u.value.c service handle */ -#define OPTEE_MRC_GENERIC_OPEN 1 +#define OPTEE_MRC_REE_SERVICE_OPEN 0xFFFFFFF0 /* - * Close REE Service + * Close REE Service: To be handled by tee-supplicant * * [in] param[0].u.value.a OPTEE_MRC_GENERIC_CLOSE * [in] param[0].u.value.b TA instance id */ -#define OPTEE_MRC_GENERIC_CLOSE 2 +#define OPTEE_MRC_REE_SERVICE_CLOSE 0xFFFFFFF1 #endif /*__OPTEE_MSG_SUPPLICANT_H*/ diff --git a/tee-supplicant/src/tee_service.c b/tee-supplicant/src/tee_service.c index b5ce82f8..8cbe16a2 100755 --- a/tee-supplicant/src/tee_service.c +++ b/tee-supplicant/src/tee_service.c @@ -1,15 +1,18 @@ -/* FIXME: Copyright */ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ + #include #include #include #include #include +#include +#include #include #include #include -#include -#include #ifndef __aligned #define __aligned(x) __attribute__((__aligned__(x))) @@ -18,37 +21,62 @@ #include #include -static bool is_param_type_value(uint64_t param_type) +/** + * param_type_is_value() - return true if param is value + */ +static bool param_type_is_value(uint64_t param_type) { - if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT) + switch (param_type) { + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: return true; - return false; + default: + return false; + } } -static bool is_param_type_memref(uint64_t param_type) +/** + * param_type_is_memref() - return true if param is memory reference + */ +static bool param_type_is_memref(uint64_t param_type) { - if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT) + switch (param_type) { + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: return true; - return false; + default: + return false; + } } -static bool is_param_type_value_out(uint64_t param_type) + +/** + * param_type_is_value_out() - return true if param is to be filled + */ +static bool param_type_is_value_out(uint64_t param_type) { - if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT) + switch (param_type) { + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: return true; - return false; + default: + return false; + } } -static bool is_param_type_memref_out(uint64_t param_type) +/** + * param_type_is_memref_out() - return true if param is fillable memory ref + */ +static bool param_type_is_memref_out(uint64_t param_type) { - if (param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT || - param_type == TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT) + switch (param_type) { + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: return true; - return false; + default: + return false; + } } /** @@ -58,11 +86,12 @@ static TEEC_Result params_to_buffer(size_t num_params, struct tee_ioctl_param *params, void **buf, size_t *size) { - uint8_t i; char *buffer; - size_t buf_sz = sizeof(long) + sizeof(TEEC_Result), ctr = sizeof(long); + size_t buf_sz = sizeof(long) + sizeof(TEEC_Result); + size_t ctr = sizeof(long); size_t attr_sz = sizeof(params->attr); size_t value_sz = sizeof(params->u.value); + uint8_t i; /* Calculate the total size of parameters */ for (i = 0; i < num_params; i++) { @@ -90,7 +119,7 @@ static TEEC_Result params_to_buffer(size_t num_params, return TEEC_ERROR_OUT_OF_MEMORY; for (i = 0; i < num_params; i++) { - if (is_param_type_value(params[i].attr)) { + if (param_type_is_value(params[i].attr)) { memcpy(buffer + ctr, ¶ms[i].attr, attr_sz); ctr += attr_sz; @@ -115,6 +144,9 @@ static TEEC_Result params_to_buffer(size_t num_params, return TEEC_SUCCESS; } +/** + * send_msg() - send message over message queue + */ static TEEC_Result send_msg(size_t num_params, struct tee_ioctl_param *params, int msgqid, void **buffer, size_t *sent) @@ -136,7 +168,7 @@ static TEEC_Result send_msg(size_t num_params, msg_size[0] = OPTEE_MRC_MSG_SEND; msg_size[1] = size; if (msgsnd(msgqid, &msg_size, sizeof(msg_size[1]), 0) == -1) { - EMSG("Failed to send msg with size: %lu\n", size); + EMSG("Failed to send msg with size: %lu", size); result = TEEC_ERROR_GENERIC; goto err; } @@ -144,7 +176,7 @@ static TEEC_Result send_msg(size_t num_params, /* Send the complete msg */ *(long *)buf = OPTEE_MRC_MSG_SEND; if (msgsnd(msgqid, buf, size - sizeof(long), 0) == -1) { - EMSG("Failed to send msg with size: %lu\n", size); + EMSG("Failed to send msg with size: %lu", size); result = TEEC_ERROR_GENERIC; goto err; } @@ -173,7 +205,7 @@ static TEEC_Result fill_param(size_t num_params, size_t idx = 1; TEEC_Result err = TEEC_SUCCESS; - if (!is_param_type_value(*ptr)) + if (!param_type_is_value(*ptr)) return TEEC_ERROR_BAD_PARAMETERS; /* If the command processing results in error, send back the same */ @@ -181,26 +213,27 @@ static TEEC_Result fill_param(size_t num_params, if (err != TEEC_SUCCESS) return err; + /* Skip the first parameter */ ptr += attr_sz + value_sz; for (; ptr < (char*)buf + size && idx < num_params;) { - if (is_param_type_memref_out(*ptr)) { + if (param_type_is_memref_out(*ptr)) { ptr += attr_sz + sizeof(params[idx].u.memref.size); memcpy(tee_supp_param_to_va(params + idx), ptr, params[idx].u.memref.size); ptr += params[idx].u.memref.size; - } else if (is_param_type_value_out(*ptr)) { + } else if (param_type_is_value_out(*ptr)) { ptr += attr_sz; memcpy(¶ms[idx].u.value, ptr, value_sz); ptr += value_sz; } - else if (is_param_type_memref(*ptr) && - !is_param_type_memref_out(*ptr)) { + else if (param_type_is_memref(*ptr) && + !param_type_is_memref_out(*ptr)) { ptr += attr_sz; ptr += (*(uint64_t *)ptr); ptr += sizeof(params[idx].u.memref.size); - } else if (is_param_type_value(*ptr) && - !is_param_type_value_out(*ptr)) { + } else if (param_type_is_value(*ptr) && + !param_type_is_value_out(*ptr)) { ptr += attr_sz + value_sz; } idx++; @@ -209,6 +242,9 @@ static TEEC_Result fill_param(size_t num_params, return TEEC_SUCCESS; } +/** + * rcv_msg() - receive message from message queue + */ static TEEC_Result rcv_msg(void *buf, size_t size, int msgqid, size_t num_params, struct tee_ioctl_param *params) { @@ -218,7 +254,7 @@ static TEEC_Result rcv_msg(void *buf, size_t size, int msgqid, /* We just need to fill in the OUT params from the buffer */ rcvd = msgrcv(msgqid, buf, size - sizeof(long), OPTEE_MRC_MSG_RCV, 0); if (rcvd == (size_t)-1) { - EMSG("Failed to retrieve message from ree service (%d, %s)\n", + EMSG("Failed to retrieve message from ree service (%d, %s)", errno, strerror(errno)); result = TEEC_ERROR_GENERIC; goto err; @@ -233,15 +269,19 @@ static TEEC_Result rcv_msg(void *buf, size_t size, int msgqid, return result; } -static TEEC_Result process_dlib_params(void *dl, size_t num_params, - struct tee_ioctl_param *params) +/** + * process_dll_params() - process dll parameters + */ +static TEEC_Result process_dll_params(void *dll, size_t num_params, + struct tee_ioctl_param *params) { size_t i; TEEC_Result res = TEEC_SUCCESS; - TEEC_Result (*process_tee_params)(size_t num_params, struct tee_params *params); + TEEC_Result (*process_tee_params)(size_t num_params, + struct tee_params *params); struct tee_params tee_params[4]; - process_tee_params = dlsym(dl, "process_tee_params"); + process_tee_params = dlsym(dll, "process_tee_params"); if (dlerror() != NULL) { EMSG("no params handling implementation found"); res = TEEC_ERROR_NOT_IMPLEMENTED; @@ -249,67 +289,85 @@ static TEEC_Result process_dlib_params(void *dl, size_t num_params, } for (i = 0; i < num_params; i++) { - if (is_param_type_value(params[i].attr) & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { + if (param_type_is_value(params[i].attr) & + TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { switch (params[i].attr) { case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: - tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; + tee_params[i].attr = + TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; break; case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: - tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; + tee_params[i].attr = + TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; break; case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: - tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT; + tee_params[i].attr = + TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT; break; default: break; } - memcpy(&tee_params[i].u.value, ¶ms[i].u.value, sizeof(tee_params[i].u.value)); - } else if (is_param_type_memref(params[i].attr)) { + + memcpy(&tee_params[i].u.value, ¶ms[i].u.value, + sizeof(tee_params[i].u.value)); + } else if (param_type_is_memref(params[i].attr)) { switch (params[i].attr) { case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: - tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; + tee_params[i].attr = + TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; break; case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: - tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + tee_params[i].attr = + TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; break; case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: - tee_params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; + tee_params[i].attr = + TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; break; default: break; } - tee_params[i].u.memref.buffer = tee_supp_param_to_va(params + i); + + tee_params[i].u.memref.buffer = + tee_supp_param_to_va(params + i); tee_params[i].u.memref.size = params[i].u.memref.size; } } + /* Call the dll with the params */ res = process_tee_params(num_params, tee_params); if (res != TEEC_SUCCESS) { - EMSG("failed to handle the tee params\n"); + EMSG("failed to handle the tee params"); res = TEEC_ERROR_GENERIC; } /* Fill back all the values */ for (i = 0; i < num_params; i++) { - if (is_param_type_value_out(params[i].attr)) - memcpy(¶ms[i].u.value, &tee_params[i].u.value, sizeof(params[i].u.value)); + if (param_type_is_value_out(params[i].attr)) + memcpy(¶ms[i].u.value, &tee_params[i].u.value, + sizeof(params[i].u.value)); } err: return res; } +/** + * open_service_msg_queue() - open message queue service + */ static TEEC_Result open_service_msg_queue(struct tee_ioctl_param *params) { + char filename[64]; + char uuid_str[48]; + int msgqid; + int handle; key_t msgqkey; - int msgqid, handle; - TEEC_Result res = TEEC_SUCCESS; - char filename[64], uuid_str[48]; struct service_handle *hdl = NULL; + TEEC_Result res = TEEC_SUCCESS; + TEEC_UUID *uuid = tee_supp_param_to_va(params + 1); uint32_t instance_id = params[0].u.value.b; - REEC_UUID *uuid = tee_supp_param_to_va(params + 1); - DMSG("===== OPTEE_MRC_GENERIC_OPEN === \n"); + DMSG("===== OPTEE_MRC_REE_SERVICE_OPEN === \n"); /* Convert to the uuid string */ res = uuid_to_str(uuid, uuid_str, sizeof(uuid_str)); @@ -361,39 +419,42 @@ static TEEC_Result open_service_msg_queue(struct tee_ioctl_param *params) return res; } -static TEEC_Result open_service_dlib(struct tee_ioctl_param *params) +/** + * open_service_dll() - open dynamic library service + */ +static TEEC_Result open_service_dll(struct tee_ioctl_param *params) { - void *dl_handle; + void *dll_handle; TEEC_Result res = TEEC_SUCCESS; char libname[64], uuid_str[48]; struct service_handle *hdl = NULL; - REEC_UUID *uuid = tee_supp_param_to_va(params + 1); + TEEC_UUID *uuid = tee_supp_param_to_va(params + 1); - printf("========== generic open ======== \n"); + DMSG("========== generic open ======== \n"); res = uuid_to_str(uuid, uuid_str, sizeof(uuid_str)); if (res != TEEC_SUCCESS) return TEEC_ERROR_GENERIC; snprintf(libname, sizeof(libname), "/usr/lib/lib%s.so", uuid_str); - dl_handle = dlopen(libname, RTLD_LAZY); - if (!dl_handle) { - printf("Failed to open %s (%s)\n", libname, dlerror()); + dll_handle = dlopen(libname, RTLD_LAZY); + if (!dll_handle) { + DMSG("Failed to open %s (%s)\n", libname, dlerror()); return TEEC_ERROR_GENERIC; } /* Allocate service info */ hdl = calloc(1, sizeof(struct service_handle)); if (!hdl) { - EMSG("out of memory for dl service info"); + EMSG("out of memory for dll service info"); res = TEEC_ERROR_OUT_OF_MEMORY; goto err; } - hdl->type = DLIB_HANDLE; - hdl->u.dl = dl_handle; + hdl->type = DLL_HANDLE; + hdl->u.dll = dll_handle; /* Get the handle to the service */ params[2].u.value.a = service_handle_new(params[0].u.value.b, hdl); - printf("========= generic open done (%p) ========== \n", dl_handle); + DMSG("========= generic open done (%p) ========== \n", dll_handle); err: return res; @@ -415,7 +476,7 @@ TEEC_Result tee_service_process(size_t num_params, uint32_t instance_id = params[0].u.value.b; switch (params[0].u.value.a) { - case OPTEE_MRC_GENERIC_OPEN: + case OPTEE_MRC_REE_SERVICE_OPEN: { TEEC_Result res = TEEC_SUCCESS; @@ -424,21 +485,21 @@ TEEC_Result tee_service_process(size_t num_params, * or as a dynamic library. * a. Open the uuid as a message queue in r-x mode. * It will fail if the message queue is not present. - * b. Open the dl with the pre-defined symbols + * b. Open the dll with the pre-defined symbols * One of will pass. */ res = open_service_msg_queue(params); if (res != TEEC_SUCCESS) - res = open_service_dlib(params); + res = open_service_dll(params); break; } - case OPTEE_MRC_GENERIC_CLOSE: + case OPTEE_MRC_REE_SERVICE_CLOSE: { struct service_handle *hdl = NULL; - DMSG("===== OPTEE_MRC_GENERIC_CLOSE === \n"); + DMSG("===== OPTEE_MRC_REE_SERVICE_CLOSE === \n"); hdl = service_handle_get(instance_id, params->u.value.c); if (!hdl) { @@ -446,8 +507,8 @@ TEEC_Result tee_service_process(size_t num_params, return TEEC_ERROR_GENERIC; } - if (hdl->type == DLIB_HANDLE) - dlclose(hdl->u.dl); + if (hdl->type == DLL_HANDLE) + dlclose(hdl->u.dll); service_handle_put(instance_id, params->u.value.c); free(hdl); @@ -479,19 +540,22 @@ TEEC_Result tee_service_process(size_t num_params, } if (hdl->type == MSGQ_HANDLE) { - result = send_msg(num_params, params, hdl->u.msgqid, &buf, &sent); + result = send_msg(num_params, params, + hdl->u.msgqid, &buf, &sent); if (result != TEEC_SUCCESS) { - EMSG("Failed to send message to the service\n"); + EMSG("Failed to send msg to the service"); return TEEC_ERROR_GENERIC; } - result = rcv_msg(buf, sent, hdl->u.msgqid, num_params, params); + result = rcv_msg(buf, sent, + hdl->u.msgqid, num_params, params); if (result != TEEC_SUCCESS) { - EMSG("Failed to receive response from the service\n"); + EMSG("Failed to receive msg from the service"); return TEEC_ERROR_GENERIC; } - } else if (hdl->type == DLIB_HANDLE) { - result = process_dlib_params(hdl->u.dl, num_params, params); + } else if (hdl->type == DLL_HANDLE) { + result = process_dll_params(hdl->u.dll, + num_params, params); } break; diff --git a/tee-supplicant/src/tee_service.h b/tee-supplicant/src/tee_service.h index e6f1e5cb..edb8c454 100755 --- a/tee-supplicant/src/tee_service.h +++ b/tee-supplicant/src/tee_service.h @@ -1,3 +1,7 @@ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ + #ifndef __TEE_SERVICE_H__ #define __TEE_SERVICE_H__ diff --git a/tee-supplicant/src/tee_service_handle.c b/tee-supplicant/src/tee_service_handle.c index ab5bae5e..8049efd5 100644 --- a/tee-supplicant/src/tee_service_handle.c +++ b/tee-supplicant/src/tee_service_handle.c @@ -1,4 +1,6 @@ -/* FIXME: Copyright */ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ #include #include diff --git a/tee-supplicant/src/tee_service_handle.h b/tee-supplicant/src/tee_service_handle.h index fef99ce4..cd761fc5 100644 --- a/tee-supplicant/src/tee_service_handle.h +++ b/tee-supplicant/src/tee_service_handle.h @@ -1,11 +1,13 @@ -/* FIXME: Copyright */ +/* + * Copyright (C) 2019 Intel Corporation All Rights Reserved + */ #ifndef __TEE_SERVICE_HANDLE_H_ #define __TEE_SERVICE_HANDLE_H__ typedef enum { MSGQ_HANDLE = 1, - DLIB_HANDLE = 2, + DLL_HANDLE = 2, } service_type_t; /* Service information to determine which type to invoke */ @@ -13,7 +15,7 @@ struct service_handle { service_type_t type; union { int msgqid; - void *dl; + void *dll; }u; }; diff --git a/tee-supplicant/src/tee_supplicant.c b/tee-supplicant/src/tee_supplicant.c index 9ab86ce6..79769e2c 100755 --- a/tee-supplicant/src/tee_supplicant.c +++ b/tee-supplicant/src/tee_supplicant.c @@ -3,6 +3,7 @@ * All rights reserved. * Copyright (c) 2015, Linaro Limited * All rights reserved. + * Copyright (C) 2019 Intel Corporation All Rights Reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -627,7 +628,7 @@ static bool process_one_request(struct thread_arg *arg) case OPTEE_MSG_RPC_CMD_FTRACE: ret = prof_process(num_params, params, "ftrace-"); break; - case OPTEE_MSG_RPC_CMD_GENERIC: + case OPTEE_MSG_RPC_CMD_REE_SERVICE: ret = tee_service_process(num_params, params); break; default: From 10783ba4e8727e680bdbc6f8ae8337105979e033 Mon Sep 17 00:00:00 2001 From: Divneil Rai Wadhawan Date: Fri, 20 Sep 2019 01:25:10 +0530 Subject: [PATCH 3/3] ree_service: added DLL signature o dll signature is added in the header file Signed-off-by: Divneil Rai Wadhawan --- public/ree_service_api.h | 3 +++ tee-supplicant/src/tee_service.c | 14 +++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/public/ree_service_api.h b/public/ree_service_api.h index 713942ad..878ecd03 100755 --- a/public/ree_service_api.h +++ b/public/ree_service_api.h @@ -71,6 +71,9 @@ TEEC_Result ree_service_rcv(void *service, size_t *num_params, TEEC_Result ree_service_snd(void *service, size_t num_params, struct tee_params *params, int32_t error); +/* This has to be implemented by REE service who wants to create a .so */ +TEEC_Result process_tee_params(size_t num_params, struct tee_params *params); + /* * Start REE Service * diff --git a/tee-supplicant/src/tee_service.c b/tee-supplicant/src/tee_service.c index 8cbe16a2..39706034 100755 --- a/tee-supplicant/src/tee_service.c +++ b/tee-supplicant/src/tee_service.c @@ -276,12 +276,16 @@ static TEEC_Result process_dll_params(void *dll, size_t num_params, struct tee_ioctl_param *params) { size_t i; + struct tee_params tee_params[4]; TEEC_Result res = TEEC_SUCCESS; - TEEC_Result (*process_tee_params)(size_t num_params, + /* + * Mimics the signature of process_tee_params. We cannot have 2 same + * declarations + */ + TEEC_Result (*dll_func)(size_t num_params, struct tee_params *params); - struct tee_params tee_params[4]; - process_tee_params = dlsym(dll, "process_tee_params"); + dll_func = dlsym(dll, "process_tee_params"); if (dlerror() != NULL) { EMSG("no params handling implementation found"); res = TEEC_ERROR_NOT_IMPLEMENTED; @@ -335,7 +339,7 @@ static TEEC_Result process_dll_params(void *dll, size_t num_params, } /* Call the dll with the params */ - res = process_tee_params(num_params, tee_params); + res = dll_func(num_params, tee_params); if (res != TEEC_SUCCESS) { EMSG("failed to handle the tee params"); res = TEEC_ERROR_GENERIC; @@ -465,7 +469,7 @@ static TEEC_Result open_service_dll(struct tee_ioctl_param *params) * This functions finds the service for tee based on UUID * based on either message queue or dynamic lib. * o Message queue is useful when we want to directly pass - * some date to CA. + * some data to CA. * o Dynamic library interface is useful when we want some * non-CA specific functionality like network library, * which is likely not relevant for the TA/CA state machine.