本节摘要:ARM TrustZone 是移动和嵌入式领域事实上的 TEE 标准。它在一个 CPU 核里引入"安全世界"和"非安全世界"两种执行状态,靠内存控制器的安全位做物理级隔离。本节讲清它的双世界切换机制、为什么开销低、又为什么"全有或全无"的隔离粒度是它的软肋,以及 OP-TEE 这个开源实现的真实定位。
阅读完本节,你应当能够:
智能手机里同时跑着几十个 App,其中可能有恶意的。但你的指纹模板、支付密钥、DRM 解密钥匙,照样能安全地存在手机里——这背后多半就是 TrustZone 在撑。它是 2004 年 ARM 提出来的,思路很直接:与其再加一颗独立的安全芯片(像早期的智能卡),不如在主处理器里硬切出两个世界,一个跑普通系统,一个专门处理高安全事务。
这个设计的诱人之处在于近乎零成本的集成。手机厂商不需要额外加安全芯片,只要 CPU 支持 TrustZone(现在 ARM Cortex-A 系列基本都支持),再配上一个轻量的可信 OS,就能获得硬件级隔离。这也是为什么全球九成以上的高端手机都内置了基于 TrustZone 的 TEE——高通的 QSEE、三星的 Knox、华为的 iTrustee 都是它的实现。
但"零成本"是有代价的。TrustZone 的隔离粒度很粗——整个安全世界是一个整体,里面跑的可信 OS 一旦有漏洞,所有跑在里面的可信应用全暴露。这正是后来 SGX 想解决的问题。
TrustZone 的核心是一个叫"安全状态"的 CPU 模式标志。处理器在任意时刻要么处于安全世界(Secure World),要么处于非安全世界(Normal World)。这个状态位会跟着每一次总线访问传递出去——内存控制器、外设控制器都会检查它,决定这笔访问放不放行。
具体怎么挡?关键在内存系统。每一个内存页表项、每一个外设的访问请求,都带一个"安全属性"。当 CPU 处于非安全状态时,即便你构造出一个指向安全内存的地址,内存控制器也会拒绝——因为它看到这笔访问的"非安全"标记和目标区域的"安全"标记对不上。
这个机制最妙的地方是:它不是靠软件的权限位维持的,而是靠硬件总线的物理信号。普通世界的内核再怎么改页表、提权,也改不了总线上的安全位信号。这就是为什么 TrustZone 能挡住特权软件攻击者——内核被攻陷了,安全世界的数据照样进不去。
两个世界之间怎么交互?靠一条专门的 CPU 指令:SMC(Secure Monitor Call)。当普通世界的客户端应用(CA)要调用可信应用(TA)时,流程大致是:
1. CA 调用 TEE 客户端 API(GP TEE Client API) 2. 客户端库把请求封装,触发 SMC 指令 3. CPU 切到安全监控器(Secure Monitor,运行在 EL3 最高特权级) 4. 安全监控器保存普通世界状态,加载安全世界状态 5. 控制权交给可信 OS,找到对应 TA 并执行 6. TA 把结果通过受控通道返回 7. 安全监控器切回普通世界,结果交还 CA
整个切换在微秒级完成,对上层透明。安全监控器是这条链上最关键的环节——它是两个世界唯一的"门",必须原子且不可中断。它的实现通常极简(几千行代码),目的就是让 TCB 尽量小。
| 切换环节 | 开销来源 | 典型耗时 |
|---|---|---|
| 保存普通世界寄存器 | 上下文存储 | 几百纳秒 |
| 刷新敏感缓存 | 防止跨世界泄露 | 微秒级 |
| 加载安全世界状态 | 上下文恢复 | 几百纳秒 |
| TA 查找与调度 | 可信 OS 内部 | 微秒级 |
⚠️ 常见坑:很多教程把世界切换说成"几乎零开销",这是误导。单次切换确实快,但如果你在热路径里高频调用 TA(比如每处理一个网络包都进一次 TEE 做签名),缓存刷新的累积开销会让吞吐量掉一大截。设计时要把"进 TEE 的次数"当成稀缺资源来规划,能批量就别单次。
安全世界里跑什么?需要一个可信 OS 来管理 TA 的生命周期、提供加密原语和安全存储。最主流的开源实现是 OP-TEE(Open Portable TEE),它已被纳入主流 Linux 发行版。
OP-TEE 的特点:
OP-TEE 的存在大大降低了 TrustZone 的开发门槛。十年前你要做 TrustZone 开发,得拿到芯片厂商的闭源 SDK,签 NDA,门槛极高。现在用 OP-TEE,普通开发者也能在 QEMU 模拟器上跑起一个 TA 的 hello world。
TrustZone 最大的局限是隔离粒度太粗。整个安全世界是"全有或全无"——里面的可信 OS 拥有对全部安全资源的访问权,所有 TA 也都跑在同一个可信 OS 之下。这带来两个问题:
第一,可信 OS 是单点信任。一旦可信 OS 被攻破(比如 OP-TEE 历史上出过的 CVE),所有 TA 都暴露。攻击者拿到可信 OS 权限,就能读取任何 TA 的内存、伪造任何 TA 的调用。这跟 SGX"每个飞地独立、互不影响"的设计形成鲜明对比。
第二,多个互不信任的第三方 TA 难以共存。假设设备上同时有银行 A 的支付 TA 和银行 B 的支付 TA,在 TrustZone 模型下它们共享同一个可信 OS——如果银行 A 的 TA 有漏洞被利用,理论上可能影响银行 B 的 TA。这在 SGX 里不是问题(每个飞地独立地址空间),但在 TrustZone 里是真实风险。
| 维度 | TrustZone | SGX |
|---|---|---|
| 隔离粒度 | 整个安全世界 | 单个应用飞地 |
| TCB 大小 | 大(含整个可信 OS) | 小(仅飞地代码) |
| 多方共存 | 弱(共享可信 OS) | 强(飞地互相隔离) |
| 切换开销 | 低 | 较高 |
| 适合场景 | 移动、嵌入式 | 云、隐私计算 |
💡 关键直觉:TrustZone 适合"设备厂商自己控制全部可信代码"的场景——手机厂商自己写可信 OS、自己装 TA,所有 TA 都是他自己的。这种场景下"全有或全无"不是问题,因为没有互不信任的多方。一旦涉及多方共存(云上多个租户、设备上多个第三方应用),SGX 的细粒度隔离就更合适。
我一般用这几个问题判断该不该上 TrustZone:
四个问题都"是",TrustZone 就是合适的选择。如果第二题答"否"(多方共存),就该考虑 SGX 或更新的 ARM CCA(Confidential Compute Architecture,引入了 Realm 隔离)。
虽然 OP-TEE 开源了,但开发体验并不友好。几个真实的坑:
这些坑意味着 TrustZone 开发的真实成本远高于"调个 API"。评估项目时要把这些隐性成本算进去。
以手机支付为例,看看 TrustZone 怎么串起整个安全链路:
注意签名密钥从头到尾没离开过安全世界——普通世界的 App 只拿到一个签名结果。哪怕手机被 root、支付 App 被逆向,攻击者也拿不到签名密钥。这就是 TrustZone 在移动支付里的核心价值。
下一节看 Intel SGX 怎么把隔离粒度从"整个安全世界"缩小到"单个应用飞地",以及它的远程证明机制为什么让它在云场景大放异彩。

这张图解释了 TrustZone 开发里最经典的性能陷阱。世界切换本身是微秒级的硬件动作,但每次切换伴随寄存器保存恢复、缓存污染、调度器介入,端到端链路轻松到毫秒级。如果客户端应用每处理一个字节就调用一次安全服务,程序的九成时间花在切换上。因此 TA 接口设计的黄金律是"厚接口、粗粒度":把一批数据连同操作意图打包送进安全世界,在飞地内完成全部计算再整批返回。第 3 章的 CA/TA 交互机制会展开这个主题,这里先埋下伏笔——架构选型不仅看隔离能力,还要看你能否驾驭它的调用模型。
TrustZone 的架构把所有 TA 装进同一个安全世界,这带来一个值得深挖的结构性困境:安全世界是单体。所有可信应用共享同一份内核、同一块内存空间,任何一个 TA 的内存安全漏洞都可能波及整个安全世界——指纹 TA 的一个缓冲区溢出,理论上可以摸到支付 TA 的密钥。这解释了为什么 TrustZone 生态对 TA 代码审查极其严格、为什么安全世界拒绝运行第三方大型代码。缓解手段包括 TA 间的进程隔离(各 TA 独立地址空间,由安全内核强制)、以及把高敏感 TA 下沉到独立的安全处理器。但根本的架构约束仍在:与 SGX "每个飞地互相隔离"的设计相比,TrustZone 用隔离粒度换了实现简洁和生态统一。评估移动方案时,"安全世界里都跑了谁"是必问的问题——世界越挤,风险越高。