aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Wiklander2016-10-21 02:23:24 -0500
committerJérôme Forissier2017-10-05 04:16:04 -0500
commit27888d73d156d4862c07effce7c8c2455774768b (patch)
tree1d20d274c65eadf690f916824497534edf61c8c3
parentf761a27c454030131678a3c175fdf8876e95f59c (diff)
downloadti-optee-client-27888d73d156d4862c07effce7c8c2455774768b.tar.gz
ti-optee-client-27888d73d156d4862c07effce7c8c2455774768b.tar.xz
ti-optee-client-27888d73d156d4862c07effce7c8c2455774768b.zip
tee_client_api: register user memory
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com> Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org> Reviewed-by: Igor Opaniuk <igor.opaniuk@linaro.org> Reviewed-by: Joakim Bech <joakim.bech@linaro.org> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
-rw-r--r--libteec/include/linux/tee.h31
-rw-r--r--libteec/src/tee_client_api.c106
-rw-r--r--public/tee_client_api.h3
3 files changed, 113 insertions, 27 deletions
diff --git a/libteec/include/linux/tee.h b/libteec/include/linux/tee.h
index 8f6c1a4e..f19b2b4c 100644
--- a/libteec/include/linux/tee.h
+++ b/libteec/include/linux/tee.h
@@ -49,6 +49,7 @@
49#define TEE_MAX_ARG_SIZE 1024 49#define TEE_MAX_ARG_SIZE 1024
50 50
51#define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */ 51#define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */
52#define TEE_GEN_CAP_REG_MEM (1 << 2)/* Supports registering shared memory */
52 53
53/* 54/*
54 * TEE Implementation ID 55 * TEE Implementation ID
@@ -145,6 +146,36 @@ struct tee_ioctl_shm_register_fd_data {
145 struct tee_ioctl_shm_register_fd_data) 146 struct tee_ioctl_shm_register_fd_data)
146 147
147/** 148/**
149 * struct tee_ioctl_shm_register_data - Shared memory register argument
150 * @addr: [in] Start address of shared memory to register
151 * @length: [in/out] Length of shared memory to register
152 * @flags: [in/out] Flags to/from registration.
153 * @id: [out] Identifier of the shared memory
154 *
155 * The flags field should currently be zero as input. Updated by the call
156 * with actual flags as defined by TEE_IOCTL_SHM_* above.
157 * This structure is used as argument for TEE_IOC_SHM_REGISTER below.
158 */
159struct tee_ioctl_shm_register_data {
160 __u64 addr;
161 __u64 length;
162 __u32 flags;
163 __s32 id;
164};
165
166/**
167 * TEE_IOC_SHM_REGISTER - Register shared memory
168 *
169 * Registers shared memory between the user space process and secure OS.
170 *
171 * Returns a file descriptor on success or < 0 on failure
172 *
173 * The shared memory is unregisterred when the descriptor is closed.
174 */
175#define TEE_IOC_SHM_REGISTER _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
176 struct tee_ioctl_shm_register_data)
177
178/**
148 * struct tee_ioctl_buf_data - Variable sized buffer 179 * struct tee_ioctl_buf_data - Variable sized buffer
149 * @buf_ptr: [in] A __user pointer to a buffer 180 * @buf_ptr: [in] A __user pointer to a buffer
150 * @buf_len: [in] Length of the buffer above 181 * @buf_len: [in] Length of the buffer above
diff --git a/libteec/src/tee_client_api.c b/libteec/src/tee_client_api.c
index f30dad53..698092b7 100644
--- a/libteec/src/tee_client_api.c
+++ b/libteec/src/tee_client_api.c
@@ -29,8 +29,8 @@
29#include <fcntl.h> 29#include <fcntl.h>
30#include <limits.h> 30#include <limits.h>
31#include <pthread.h> 31#include <pthread.h>
32#include <stdbool.h>
33#include <stdio.h> 32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h> 34#include <string.h>
35#include <sys/ioctl.h> 35#include <sys/ioctl.h>
36#include <sys/mman.h> 36#include <sys/mman.h>
@@ -63,7 +63,8 @@ static void teec_mutex_unlock(pthread_mutex_t *mu)
63 pthread_mutex_unlock(mu); 63 pthread_mutex_unlock(mu);
64} 64}
65 65
66static int teec_open_dev(const char *devname, const char *capabilities) 66static int teec_open_dev(const char *devname, const char *capabilities,
67 uint32_t *gen_caps)
67{ 68{
68 struct tee_ioctl_version_data vers; 69 struct tee_ioctl_version_data vers;
69 int fd; 70 int fd;
@@ -93,6 +94,7 @@ static int teec_open_dev(const char *devname, const char *capabilities)
93 } 94 }
94 } 95 }
95 96
97 *gen_caps = vers.gen_caps;
96 return fd; 98 return fd;
97err: 99err:
98 close(fd); 100 close(fd);
@@ -113,6 +115,21 @@ static int teec_shm_alloc(int fd, size_t size, int *id)
113 return shm_fd; 115 return shm_fd;
114} 116}
115 117
118static int teec_shm_register(int fd, void *buf, size_t size, int *id)
119{
120 int shm_fd;
121 struct tee_ioctl_shm_register_data data;
122
123 memset(&data, 0, sizeof(data));
124 data.addr = (uintptr_t)buf;
125 data.length = size;
126 shm_fd = ioctl(fd, TEE_IOC_SHM_REGISTER, &data);
127 if (shm_fd < 0)
128 return -1;
129 *id = data.id;
130 return shm_fd;
131}
132
116TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *ctx) 133TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *ctx)
117{ 134{
118 char devname[PATH_MAX]; 135 char devname[PATH_MAX];
@@ -123,10 +140,13 @@ TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *ctx)
123 return TEEC_ERROR_BAD_PARAMETERS; 140 return TEEC_ERROR_BAD_PARAMETERS;
124 141
125 for (n = 0; n < TEEC_MAX_DEV_SEQ; n++) { 142 for (n = 0; n < TEEC_MAX_DEV_SEQ; n++) {
143 uint32_t gen_caps;
144
126 snprintf(devname, sizeof(devname), "/dev/tee%zu", n); 145 snprintf(devname, sizeof(devname), "/dev/tee%zu", n);
127 fd = teec_open_dev(devname, name); 146 fd = teec_open_dev(devname, name, &gen_caps);
128 if (fd >= 0) { 147 if (fd >= 0) {
129 ctx->fd = fd; 148 ctx->fd = fd;
149 ctx->reg_mem = gen_caps & TEE_GEN_CAP_REG_MEM;
130 return TEEC_SUCCESS; 150 return TEEC_SUCCESS;
131 } 151 }
132 } 152 }
@@ -635,20 +655,29 @@ TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm)
635 s = shm->size; 655 s = shm->size;
636 if (!s) 656 if (!s)
637 s = 8; 657 s = 8;
638 658 if (ctx->reg_mem) {
639 fd = teec_shm_alloc(ctx->fd, s, &shm->id); 659 fd = teec_shm_register(ctx->fd, shm->buffer, s, &shm->id);
640 if (fd < 0) 660 if (fd < 0)
641 return TEEC_ERROR_OUT_OF_MEMORY; 661 return TEEC_ERROR_OUT_OF_MEMORY;
642 662 shm->registered_fd = fd;
643 shm->shadow_buffer = mmap(NULL, s, PROT_READ | PROT_WRITE, MAP_SHARED, 663 shm->shadow_buffer = NULL;
644 fd, 0); 664 } else {
645 close(fd); 665 fd = teec_shm_alloc(ctx->fd, s, &shm->id);
646 if (shm->shadow_buffer == (void *)MAP_FAILED) { 666 if (fd < 0)
647 shm->id = -1; 667 return TEEC_ERROR_OUT_OF_MEMORY;
648 return TEEC_ERROR_OUT_OF_MEMORY; 668
669 shm->shadow_buffer = mmap(NULL, s, PROT_READ | PROT_WRITE,
670 MAP_SHARED, fd, 0);
671 close(fd);
672 if (shm->shadow_buffer == (void *)MAP_FAILED) {
673 shm->id = -1;
674 return TEEC_ERROR_OUT_OF_MEMORY;
675 }
676 shm->registered_fd = -1;
649 } 677 }
678
650 shm->alloced_size = s; 679 shm->alloced_size = s;
651 shm->registered_fd = -1; 680 shm->buffer_allocated = false;
652 return TEEC_SUCCESS; 681 return TEEC_SUCCESS;
653} 682}
654 683
@@ -694,19 +723,36 @@ TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm)
694 if (!s) 723 if (!s)
695 s = 8; 724 s = 8;
696 725
697 fd = teec_shm_alloc(ctx->fd, s, &shm->id); 726 if (ctx->reg_mem) {
698 if (fd < 0) 727 shm->buffer = malloc(s);
699 return TEEC_ERROR_OUT_OF_MEMORY; 728 if (!shm->buffer)
729 return TEEC_ERROR_OUT_OF_MEMORY;
700 730
701 shm->buffer = mmap(NULL, s, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 731 fd = teec_shm_register(ctx->fd, shm->buffer, s, &shm->id);
702 close(fd); 732 if (fd < 0) {
703 if (shm->buffer == (void *)MAP_FAILED) { 733 free(shm->buffer);
704 shm->id = -1; 734 shm->buffer = NULL;
705 return TEEC_ERROR_OUT_OF_MEMORY; 735 return TEEC_ERROR_OUT_OF_MEMORY;
736 }
737 shm->registered_fd = fd;
738 } else {
739 fd = teec_shm_alloc(ctx->fd, s, &shm->id);
740 if (fd < 0)
741 return TEEC_ERROR_OUT_OF_MEMORY;
742
743 shm->buffer = mmap(NULL, s, PROT_READ | PROT_WRITE,
744 MAP_SHARED, fd, 0);
745 close(fd);
746 if (shm->buffer == (void *)MAP_FAILED) {
747 shm->id = -1;
748 return TEEC_ERROR_OUT_OF_MEMORY;
749 }
750 shm->registered_fd = -1;
706 } 751 }
752
707 shm->shadow_buffer = NULL; 753 shm->shadow_buffer = NULL;
708 shm->alloced_size = s; 754 shm->alloced_size = s;
709 shm->registered_fd = -1; 755 shm->buffer_allocated = true;
710 return TEEC_SUCCESS; 756 return TEEC_SUCCESS;
711} 757}
712 758
@@ -717,13 +763,19 @@ void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *shm)
717 763
718 if (shm->shadow_buffer) 764 if (shm->shadow_buffer)
719 munmap(shm->shadow_buffer, shm->alloced_size); 765 munmap(shm->shadow_buffer, shm->alloced_size);
720 else if (shm->buffer) 766 else if (shm->buffer) {
721 munmap(shm->buffer, shm->alloced_size); 767 if (shm->registered_fd >= 0) {
722 else if (shm->registered_fd >= 0) 768 if (shm->buffer_allocated)
769 free(shm->buffer);
770 close(shm->registered_fd);
771 } else
772 munmap(shm->buffer, shm->alloced_size);
773 } else if (shm->registered_fd >= 0)
723 close(shm->registered_fd); 774 close(shm->registered_fd);
724 775
725 shm->id = -1; 776 shm->id = -1;
726 shm->shadow_buffer = NULL; 777 shm->shadow_buffer = NULL;
727 shm->buffer = NULL; 778 shm->buffer = NULL;
728 shm->registered_fd = -1; 779 shm->registered_fd = -1;
780 shm->buffer_allocated = false;
729} 781}
diff --git a/public/tee_client_api.h b/public/tee_client_api.h
index a9d8a052..f37886df 100644
--- a/public/tee_client_api.h
+++ b/public/tee_client_api.h
@@ -35,6 +35,7 @@ extern "C" {
35 35
36#include <stdint.h> 36#include <stdint.h>
37#include <stddef.h> 37#include <stddef.h>
38#include <stdbool.h>
38#include <limits.h> 39#include <limits.h>
39 40
40/* 41/*
@@ -253,6 +254,7 @@ typedef uint32_t TEEC_Result;
253typedef struct { 254typedef struct {
254 /* Implementation defined */ 255 /* Implementation defined */
255 int fd; 256 int fd;
257 bool reg_mem;
256} TEEC_Context; 258} TEEC_Context;
257 259
258/** 260/**
@@ -294,6 +296,7 @@ typedef struct {
294 size_t alloced_size; 296 size_t alloced_size;
295 void *shadow_buffer; 297 void *shadow_buffer;
296 int registered_fd; 298 int registered_fd;
299 bool buffer_allocated;
297} TEEC_SharedMemory; 300} TEEC_SharedMemory;
298 301
299/** 302/**