OP-TEE: A Practical Trusted Execution Environment on ARM TrustZone
1.
Introduction:
ARM TrustZone provides the hardware mechanisms required to isolate security-critical code from a rich operating system running on the same Cortex-A processor. While this isolation is robust, TrustZone itself does not define how Secure world software should be structured or how interactions with the Non-Secure world should be managed.
In Linux-based systems, Secure world code must handle multiple concurrent requests, validate inputs originating from untrusted software, manage memory safely, and expose stable entry points. Implementing these responsibilities directly on top of TrustZone quickly leads to ad-hoc designs that are difficult to scale, audit, and maintain.
OP-TEE
addresses this gap by providing a Trusted Execution Environment that
runs in the Secure world and builds on TrustZone primitives. It
defines a clear execution model and software architecture that allows
Secure services to be deployed alongside Linux while preserving
hardware-enforced isolation.
2. What Problem OP-TEE Solves:
TrustZone establishes a separation boundary but leaves software policy largely undefined. Without a structured runtime, Secure world code must directly handle world switching, context management, memory validation, and concurrency. As systems grow more complex, this approach becomes fragile and error-prone.
Linux applications often require access to secure services such as key storage, cryptographic operations, or device identity. Allowing each service to implement its own Secure world logic leads to duplicated code paths and inconsistent security assumptions. A unified Secure world runtime is needed to centralize these responsibilities.
OP-TEE provides this runtime. It offers a standardized environment in which multiple secure services can coexist, share core functionality, and expose controlled interfaces to the Non-Secure world. This shifts complexity away from individual Secure services and into a common, auditable framework.
3.
OP-TEE Execution Model
OP-TEE executes entirely in the Secure world and relies on TrustZone world switching to handle requests from the Non-Secure world. Linux remains responsible for scheduling applications and managing normal system resources, while OP-TEE services requests that require access to Secure memory or peripherals.
Interaction between worlds is coarse-grained. Requests are explicitly marshaled, validated, and processed before control returns to the Non-Secure world. This model aligns with the cost of world switching and avoids treating the Secure world as an extension of the normal operating system.
OP-TEE presents itself as a single Secure OS instance that hosts multiple secure applications. This allows Secure services to share common infrastructure such as memory management and threading, while remaining isolated from each other.
Fig. 1 OP-TEE executing in the Secure world alongside a Linux-based Non-Secure world.
4.
OP-TEE Secure World Architecture
Internally, OP-TEE is structured as a small operating system. The OP-TEE core is responsible for low-level tasks such as thread management, Secure world scheduling, memory allocation, and request dispatch. It also enforces security checks on all incoming requests from the Non-Secure world.
Trusted Applications (TAs) run on top of the OP-TEE core. Each TA implements a specific secure service and executes within its own isolated context. The OP-TEE core mediates access to shared resources and ensures that TAs cannot interfere with each other.
This separation reduces the trusted computing base of individual services. TAs focus on application-specific logic, while the OP-TEE core handles interaction with TrustZone mechanisms and Non-Secure software.
5.
Communication Between Normal World and OP-TEE
Communication between Linux and OP-TEE follows a controlled, message-based model. User-space applications in Linux do not interact with the Secure world directly. Instead, requests pass through a kernel driver that provides a defined entry point into the Secure world.
Shared memory is typically used to exchange request parameters and results. OP-TEE validates all memory references to ensure that buffers originate from permitted Non-Secure regions and do not overlap Secure memory. This prevents accidental or malicious misuse of Secure world privileges.
All communication ultimately results in a Secure Monitor Call, which transfers execution into the Secure world. OP-TEE processes the request and returns control to Linux once the operation is complete.
Fig.2 Request flow from a Linux application to OP-TEE through the kernel and Secure Monitor.
6.
Practical Usage Example: OP-TEE Request Flow:
A common use of OP-TEE is to expose a narrowly scoped secure service to Linux applications while keeping sensitive logic and data confined to the Secure world. This interaction follows a well-defined request–response model built around sessions, commands, and shared parameters.
From the Non-Secure world, a Linux application acts as a client. It opens a session to a Trusted Application (TA) identified by a UUID and invokes commands by passing a small, fixed set of parameters. The client never executes Secure world code directly and never accesses Secure memory.
The following excerpt illustrates a typical client-side flow, based on the OP-TEE hello_world example. The application initializes a context, opens a session to a TA, and invokes a command that operates on input data.
TEEC_Context ctx; TEEC_Session sess; TEEC_Operation op; uint32_t err_origin;
TEEC_InitializeContext(NULL, &ctx);
TEEC_LOGIN_PUBLIC, NULL, NULL, &err_origin);
TEEC_NONE, TEEC_NONE, TEEC_NONE); op.params[0].value.a = 42;
TEEC_FinalizeContext(&ctx); |
On the Secure world side, the Trusted Application implements a small set of entry points defined by the OP-TEE TA interface. All requests from the Non-Secure world arrive through a single command dispatcher, which validates parameters and performs the requested operation.
TEE_Result TA_InvokeCommandEntryPoint(uint32_t cmd_id, uint32_t param_types, TEE_Param params[4]) { switch (cmd_id) { case TA_CMD_PROCESS: params[0].value.a++; return TEE_SUCCESS; default: return TEE_ERROR_NOT_SUPPORTED; } } |
Although this example is intentionally simple, it demonstrates the core OP-TEE execution model. Linux applications request services using explicit commands and well-defined parameters. The Secure world validates all inputs, performs the operation using Secure memory and resources, and returns only the result. At no point does the Non-Secure world gain visibility into Secure world state.
This
same pattern is used for more realistic services such as
cryptographic operations, device identity handling, and firmware
verification. The key difference lies in what the Trusted Application
does internally, not in how it is invoked. By standardizing this
interaction model, OP-TEE allows Secure services to remain small,
auditable, and isolated, while Linux continues to handle the
complexity of the overall system.
7.
Conclusion
OP-TEE demonstrates how ARM TrustZone hardware mechanisms can be transformed into a practical and maintainable Secure world environment for Linux-based systems. By centralizing Secure world responsibilities into a dedicated runtime, OP-TEE enables embedded systems to expose security-critical services without unnecessarily expanding the trusted computing base.
For embedded Linux developers and platform architects, OP-TEE provides a clean, auditable, and scalable foundation for building secure services on modern ARM SoCs.
