From: Javier González <javier(a)javigon.com>
Hi,
Here's the proposal I described the other day. The goal is to provide
support for kernel submodules. I encountered some challenges that I
would like to discuss with you:
- Command and parameters: In the patchset Jens sent, all ommunication
with the TEE is opaque. This is good for user space but not for kernel
submodules. I propose adding a tee_cmd and tee_parameters. The value
is opaque and can be flourished by the TEE if necessary.
- Command list: If we want kernel submodules to use the TEE as they use
TPM we need a list of commands that all (most) TEEs would support. We
need to have this discussion and maybe bring more parties to it.
Probably Global Platform's use cases are a good place to start.
- Session: I miss the concept of a session. The responsability is very
similar to tee_filp. I would suggest to change the name to tee_session.
I believe that it makes it more clear.
- Position: I like sec-hw :) But we need to bring at least another piece
of secure hardware to this location in order to motivate a new
submodule. TPM is the most obvious. We would then need to move all
into /drivers/sec-hw/?? I assume your do not like trustzone since it
is very specific for some of you - is tee good? I did not want to
send a patch without discussing the naming first.
Finally, regarding the process: is sending patches, discussing, and then
applying to github a process you all fell comfortable with? Suggestions
are welcome.
Best,
Javier
Javier González (1):
tee: add tee operations for kernel submodules
drivers/sec-hw/tee.c | 175 +++++++++++++++++++++++++++++++++++++++--
drivers/sec-hw/tee_private.h | 14 ++++
include/linux/sec-hw/tee.h | 98 ++++++++++++++++++++++-
include/linux/sec-hw/tee_drv.h | 11 ---
4 files changed, 279 insertions(+), 19 deletions(-)
--
1.9.1
Hi,
In this patch I've tried to summarize the recent discussion. I've defined
the needed ioctls and a brief description of how the other relevant
syscalls are used.
Regards,
Jens
Signed-off-by: Jens Wiklander <jens.wiklander(a)linaro.org>
---
Documentation/ioctl/ioctl-number.txt | 1 +
include/linux/sechw/tee.h | 154 +++++++++++++++++++++++++++++++++++
2 files changed, 155 insertions(+)
create mode 100644 include/linux/sechw/tee.h
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 8136e1f..a04c139 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -301,6 +301,7 @@ Code Seq#(hex) Include File Comments
0xA3 80-8F Port ACL in development:
<mailto:tlewis@mindspring.com>
0xA3 90-9F linux/dtlk.h
+0xA4 00-1F linux/sechw/tee.h Generic TEE driver
0xAB 00-1F linux/nbd.h
0xAC 00-1F linux/raw.h
0xAD 00 Netfilter device in development:
diff --git a/include/linux/sechw/tee.h b/include/linux/sechw/tee.h
new file mode 100644
index 0000000..0c44d5d
--- /dev/null
+++ b/include/linux/sechw/tee.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __TEE_H
+#define __TEE_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * This file describes the API provided by the generic TEE driver to user
+ * space
+ */
+
+#define TEE_GENDRV_MAJOR_VERSION 1
+#define TEE_GENDRV_MINOR_VERSION 0
+
+/**
+ * struct tee_version - TEE versions
+ * @gendrv_major_version: Generic TEE driver major version
+ * @gendrv_minor_version: Generic TEE driver minor version
+ * @specdrv_major_version: Specific TEE driver major version
+ * @specdrv_minor_version: Specific TEE driver minor version
+ * @tee_api_major_version: Specific TEE API major version
+ * @tee_api_minor_version: Specific TEE API minor version
+ * @tee_os_major_version: Secure OS major version
+ * @tee_os_minor_version: Secure OS minor version
+ * @tee_api_uuid: Specific TEE API uuid
+ * @tee_os_uuid: Secure OS uuid
+ *
+ * Identifies the generic TEE driver, the specific TEE driver, which API
+ * is used to communicate with the Secure OS and the Secure OS itself.
+ *
+ * Unused fields are zeroed.
+ */
+struct tee_version {
+ uint32_t gendrv_major_version;
+ uint32_t gendrv_minor_version;
+ uint32_t specdrv_major_version;
+ uint32_t specdrv_minor_version;
+ uint32_t tee_api_major_version;
+ uint32_t tee_api_minor_version;
+ uint32_t tee_os_major_version;
+ uint32_t tee_os_minor_version;
+ uint8_t tee_api_uuid[16];
+ uint8_t tee_os_uuid[16];
+};
+
+/**
+ * struct tee_cmd_data - Opaque command argument
+ * @buf_ptr: A __user pointer to a command buffer
+ * @buf_len: Length of the buffer above
+ *
+ * Opaque command data which is passed on to the specific driver. The command
+ * buffer doesn't have to reside in shared memory.
+ */
+struct tee_cmd_data {
+ uint64_t buf_ptr;
+ uint64_t buf_len;
+};
+
+/**
+ * struct tee_shm_alloc_data - Shared memory allocate argument
+ * @size: Size of shared memory to allocate
+ * @flags: Flags to/from allocation, currently zero
+ * @fd: File descriptor of the shared memory
+ */
+struct tee_shm_alloc_data {
+ uint64_t size;
+ uint32_t flags;
+ int32_t fd;
+};
+
+/**
+ * struct tee_mem_share_data - share user space memory with Secure OS
+ * @ptr: A __user pointer to memory to share
+ * @size: Size of the memory to share
+ * @flags: Flags to/from sharing, currently set to zero by caller
+ * @pad: Padding, set to zero by caller
+ */
+struct tee_mem_share_data {
+ uint64_t ptr;
+ uint64_t size;
+ uint32_t flags;
+ uint32_t pad;
+};
+
+#define TEE_IOC_MAGIC 0xa4
+#define TEE_IOC_BASE 0
+
+#define _TEE_IOR(nr, size) _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + (nr), size)
+#define _TEE_IOWR(nr, size) _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + (nr), size)
+
+/**
+ * TEE_IOC_VERSION - query version of drivers and secure OS
+ *
+ * Takes a tee_version struct and returns with the version numbers filled in.
+ */
+#define TEE_IOC_VERSION _TEE_IOR(0, struct tee_version)
+
+/**
+ * TEE_IOC_CMD - pass a command to the specific TEE driver
+ *
+ * Takes tee_cmd_data struct which is passed to the specific TEE driver.
+ */
+#define TEE_IOC_CMD _TEE_IOR(1, struct tee_cmd_data)
+
+/**
+ * TEE_IOC_SHM_ALLOC - allocate shared memory
+ *
+ * Allocates shared memory between the user space process and secure OS.
+ * The returned file descriptor is used to map the shared memory into user
+ * space. The shared memory is freed when the descriptor is closed and the
+ * memory is unmapped.
+ */
+#define TEE_IOC_SHM_ALLOC _TEE_IOWR(2, struct tee_shm_alloc_data)
+
+/**
+ * TEE_IOC_MEM_SHARE - share a portion of user space memory with secure OS
+ *
+ * Shares a portion of user space memory with secure OS.
+ */
+#define TEE_IOC_MEM_SHARE _TEE_IOWR(3, struct tee_mem_share_data)
+
+/**
+ * TEE_IOC_MEM_UNSHARE - unshares a portion shared user space memory
+ *
+ * Unshares a portion of previously shared user space memory.
+ */
+#define TEE_IOC_MEM_UNSHARE _TEE_IOWR(4, struct tee_mem_share_data)
+
+/*
+ * Five syscalls are used when communicating with the generic TEE driver.
+ * open(): opens the device associated with the driver
+ * ioctl(): as described above operating on the file descripto from open()
+ * close(): two cases
+ * - closes the device file descriptor
+ * - closes a file descriptor connected to allocated shared memory
+ * mmap(): maps shared memory into user space
+ * munmap(): unmaps previously shared memory
+ */
+
+#endif /*__TEE_H*/
--
1.9.1
So to get started with the IOCTL's needed between TEE clients in user
space and the generic driver. Have the different use cases in back of
your mind when thinking about this.
Here are three IOC's needed. What else?
IOCTL's:
TEE_IOC_CMD
TEE_IOC_SHM_ALLOC
TEE_IOC_SHM_FREE
--
Regards,
Joakim B
Hi,
First email on this newly created list. Hopefully everyone receives this
email.
So, during the call we had last week we decided to focus on finding the
necessary interfaces between user space and the kernel driver(s).
Just to get some kind of nomenclature I suggest:
- user space client: The one communicating with the kernel driver.
- generic driver: The one communicating with both user space and the
specific driver.
- specific driver: The one communicating with the generic driver and
secure monitor.
I.e: user space client <-> generic driver <-> specific driver <-> monitor
The suggestion from me and Jens is as depicted in [1] and this is based
on the feedback we have had from all of you. Our suggestion basically
says that you will use 4 different syscalls from user space to the
kernel.
open: Obviously needed to be able to talk with the device.
Corresponds to: file_operations.open(...)
close: Same here, needed.
Corresponds to: file_operations.release(...)
cmd: This is a generic "cmd" instead of having specific GlobalPlatform
commands. Which means that it's up to user space client to encapsulate
eventual sub-command for the TEE solution it communicates with. For
example GlobalPlatforms context, session etc, invoke command are
more or less GP specific.
Corresponds to: file_operations.unlocked_ioctl(...)
mmap: Since you need to map memory.
Corresponds to: file_operations.mmap(...)
The generic driver implements the file_operations stated above. It also
exports a shared memory functions to be used by specific drivers in the
Linux kernel and from user space clients.
What is happening in the specific driver is implementation defined. Just
to give some example we have put down what would be needed in OP-TEE.
The idea was also to only expose one device (the generic driver). But
that wouldn't be visible until the specific driver(s) has been loaded.
So, when the probe is being called in the specific driver, it registers
itself to the generic driver and then the generic driver will register
the miscdevice so that user space clients can open the communication
with the driver.
In the image [1], we have also shown tee-supplicant. That is mostly to
show that this is just another client talking to a TEE. What is
happening is implementation defined and it's up to user space and the
specific driver to implement a feature like that.
So, what do you say, what is your initial feedback?
[1] https://drive.google.com/file/d/0B21cwcg8lOaJMWRmN05qUXVBSkk/view
--
Regards,
Joakim B