AOSP Framework & Internals
5 min read

Trusty TEE

Learn about Trusty TEE.

Why the Linux Kernel is Not Secure Enough

Android handles extremely sensitive data every time a user unlocks their phone. It manages cryptographic keys, processes biometric fingerprint scans, and verifies lock screen passwords. Standard operating systems rely entirely on their kernel to protect memory and isolate processes. But treating the main Linux kernel as the ultimate security authority creates a massive single point of failure.

If an attacker discovers a privilege escalation exploit and roots the device, the Linux kernel falls completely under their control. A compromised kernel can read any memory address and bypass any software restriction. Every secret stored in standard system memory becomes instantly visible to the attacker. Android requires a security model where even a rooted kernel cannot access critical keys. This requirement drives the need for a completely separate physical execution space.

The Hardware Split: Secure and Non-Secure Worlds

To survive a kernel compromise, the device needs a physical boundary. Android uses a hardware-enforced Trusted Execution Environment (TEE) to create this separation. Most Android devices implement this using ARM TrustZone technology. TrustZone partitions the CPU execution state and physical memory into two distinct zones. The standard Android OS runs in the Non-Secure World, often called the Rich Execution Environment (REE). The security-critical code runs in the Secure World.

Hardware logic enforces this partition strictly. The Android OS literally cannot read or modify memory assigned to the Secure World, even if it tries with root privileges. When the CPU executes in the Non-Secure World, any attempt to access Secure World memory triggers a hardware exception. This physical barrier ensures that a compromised Android OS remains trapped on its side of the fence.

The following flowchart illustrates how TrustZone physically separates the operating systems while sharing the same underlying processor. This visualization helps clarify why a kernel exploit cannot cross the boundary. Notice how the CPU acts as the strict enforcer between the two worlds.

The diagram shows that the Android OS and Trusty OS never communicate directly. All interactions must pass through the shared CPU hardware. But hardware separation alone is not enough to perform cryptographic operations.

Inside Trusty OS and Trusted Applications

Hardware isolation alone only provides an empty vault. The device needs software running inside the Secure World to manage secrets and perform cryptographic math. Manufacturers can choose different commercial TEE operating systems, but Google provides an open-source reference implementation called Trusty. Pixel phones rely heavily on Trusty. Trusty OS is a minimal, highly secure microkernel with a deliberately small attack surface.

Trusty handles basic memory management, process scheduling, and secure communication for the programs running inside it. Engineers call these programs Trusted Applications (TAs). TAs are specialized applets typically written in C, C++, or Rust. Instead of the Android OS handling cryptographic operations itself, it asks a TA to do the work. For example, the KeyMint TA generates keys, while the Gatekeeper TA verifies the user PIN.

The manufacturer cryptographically signs these TAs, and the device bootloader locks them into the Secure World during startup. But getting the TAs into the secure vault is only half the battle.

Common Mistake: A frequent misconception is that the Android OS encrypts data directly. In reality, Android passes data to a TA, and the TA performs the encryption inside the Secure World using keys that the Android OS cannot see.

The normal OS still needs a way to talk to these isolated programs. This data exchange requires a specialized communication path.

Crossing the Boundary

Because Android and Trusty exist in separate hardware worlds, they cannot simply call each other's functions. Android user-space processes still need a way to ask TAs to encrypt data or verify a fingerprint. They require a specialized Inter-Process Communication (IPC) mechanism that bridges the physical divide without compromising memory isolation. This communication relies on a careful choreography of hardware and software.

The following sequence diagram maps the exact execution path when Android communicates with a Trusty TA. This visualizes the hardware context switch required to cross the security boundary. Pay attention to how the Secure Monitor acts as the gatekeeper for the context switch.

The process begins when an Android Hardware Abstraction Layer (HAL) process opens a special character device. This device is typically "/dev/trusty-ipc-dev0". The HAL writes its command payload into this device node. The Linux kernel contains a specific Trusty driver that intercepts this write operation. The driver then executes a Secure Monitor Call (SMC) assembly instruction.

The SMC instruction halts the Linux kernel and triggers a hardware context switch. A CPU suspend operation pauses the Non-Secure World and wakes up the Secure Monitor, a highly privileged piece of firmware. This monitor inspects the request and passes control to the Trusty kernel. Trusty reads the message, routes it to the correct TA, and waits for a response. Once the TA finishes processing, the entire chain runs in reverse.

This careful choreography allows Android to request secure operations without ever seeing the secret keys or compromising the hardware barrier. The architecture ensures that even a fully compromised Linux kernel can only send valid IPC requests to the Secure World, never extract the secrets stored within it. Even if the entire Android operating system is compromised, the device still protects its most sensitive data.