A kernel TEE party
A processor with TrustZone support can run in two modes, often termed the secure and non-secure worlds. The secure world can be given exclusive access to memory, devices, and more; those resources are inaccessible when running in the non-secure mode. A hardware trap mechanism is used to transition between the two worlds. The secure-world code, thus, looks a lot like an innermost kernel, protected from the Linux kernel, that has a limited set of security-relevant tasks to perform.
The secure world gains control first at boot time, allowing it to set up access to the rest of its resources and configure the environment for the non-secure kernel. This would also be the time to implement a secure-boot mechanism, if desired, ensuring that the non-secure kernel carries an acceptable signature. A number of functions can be implemented in the secure-world code. For example, cryptographic keys can be stored there, inaccessible to the rest of the system, but usable by the secure world to generate signatures. Naturally, there is interest in using the secure world to implement digital rights management mechanisms and other unpleasant things. Like most of these technologies, TrustZone can be used to ensure a user's control over their computer or to take it away.
The code running in the secure world is often called the "trusted execution environment", or TEE (as opposed to the non-secure "rich execution environment" or REE). As befits the ARM world, there are a lot of TEEs out there, each with its own interface to the kernel. The purpose of the generic TEE subsystem is to settle on one kernel-side interface for TEEs, with a standard communication mechanism for talking to them. To that end, it creates two sets of devices: /dev/teeN, and /dev/teeprivN. The former set allows user space to make requests of the TEE, while the latter is there for "supplicant" processes that provide services to the TEE.
A process needing a TEE service opens the appropriate device, then issues a series of ioctl() calls. The available commands include TEE_IOC_SHM_ALLOC to allocate a range of memory shared between the process and the TEE, TEE_IOC_INVOKE to call a function inside the TEE, and more. For each call, the TEE generates some sort of results which are passed back to the calling process. For the /dev/teepriv interfaces, the calls go the other way; when the TEE needs a user-space service (the contents of a file on disk, say), it will send a request to the waiting supplicant process via this interface.
The generic TEE code is, for the most part, a wrapper layer that turns user-space ioctl() calls into calls to the low-level driver. That driver will have registered itself, providing a tee_driver_ops structure with its operations. The biggest exception relates to the handling of shared-memory segments, which involves a certain amount of complexity. There is a fairly elaborate reference-counting mechanism that, for example, tracks the references created by every parameter passed into a TEE operation; that ensures that the memory is not freed while references still exist.
The low-level driver code is charged with communicating between the generic TEE layer and the actual TEE implementation. Much of this code is concerned with formatting requests as expected by the TEE and low-level communications. Shared memory is also an issue at this level, since mapping memory that the TEE can access requires cooperation with the TEE itself.
The generic TEE subsystem patches come with a driver for one TEE, an open-source implementation called OP-TEE. This system, developed by STMicroelectronics and Linaro, provides a simple operating-system kernel meant to run in the secure world. OP-TEE is meant to be the substrate on which TEEs are created; those wanting to learn more can have a look at this design document. There is also an OP-TEE "hello world" application giving an idea of what secure-world code looks like.
All of this structure is intended to build things like the OP-TEE secure
data path (recently presented at
Linaro Connect), the purpose of which is to enable Android devices to play
protected content without letting the end users actually get their hands on
it. But a free TEE environment should also make it easy to develop
less user-hostile secure services as free software. Once the generic TEE
patches are merged (something that seems like it should happen sometime
this year), we'll have a standard interface for providing and using such
services.
Index entries for this article | |
---|---|
Security | Hardware |