TEE 架构基础:硬件隔离与软件栈
各位同学,咱们今天聊聊 TEE 的骨架——硬件隔离机制和软件栈。这部分内容,说白了就是搞清楚 TEE 到底是怎么“与世隔绝”的,以及它里面都住了哪些“居民”。
我刚开始接触 TEE 的时候,也觉得很抽象。什么安全世界、普通世界,听着像两个平行宇宙。但等你真正动手做过一次接口适配,就会发现这些概念其实很实在。咱们一步步来拆解。
硬件隔离机制:TrustZone 与 TEE 安全内核
先问大家一个问题:一个 CPU 核心,怎么同时运行两个完全隔离的系统?
答案就是硬件隔离。ARM 的 TrustZone 技术,把物理的 CPU 核心虚拟成了两个“世界”:普通世界(Normal World)和安全世界(Secure World)。这两个世界共享同一个物理核,但通过硬件逻辑彻底隔开。
核心要点:TrustZone 不是软件模拟的,是芯片设计时就固化在总线、内存控制器和 CPU 核里的。普通世界的程序,永远无法直接访问安全世界的内存和寄存器。
我个人习惯把 TrustZone 想象成一栋楼里的两部电梯。普通世界的电梯只能到 1-10 层,安全世界的电梯能到 11-20 层。两部电梯的钥匙(权限)完全不同。你想想看,就算普通世界的电梯里塞满了恶意软件,它也按不了 11 层的按钮——因为硬件上就没给它这个权限。
安全世界与普通世界的切换
这两个世界怎么切换呢?靠一个叫 Monitor Mode 的监控模式。它就像两个世界之间的安检门。当普通世界想调用安全世界的服务时,必须通过一条特殊的指令——SMC(Secure Monitor Call)。
流程大概是这样的:
- 普通世界的程序执行
SMC指令。 - CPU 陷入 Monitor Mode,保存普通世界的上下文。
- Monitor 检查调用是否合法,然后切换到安全世界。
- 安全世界处理请求,返回结果。
- Monitor 恢复普通世界上下文,继续执行。
嗯,这里要注意:Monitor Mode 本身也是运行在安全世界的,但它是最底层的“看门人”。我在项目中遇到过一个问题,就是 SMC 调用太频繁,导致性能急剧下降。后来我们优化了调用频率,把多次小请求合并成一次大请求,才解决了问题。
TEE 安全内核
安全世界里跑的是什么?就是 TEE 安全内核。它不是一个完整的操作系统,而是一个精简的、专门为安全场景设计的微型内核。
常见的 TEE 安全内核有:
- OP-TEE:开源,由 Linaro 维护,社区活跃,我用的最多的就是它。
- Trusty:Google 为 Android 设计的 TEE 内核,闭源。
- QSEE:高通的 TEE 实现,闭源,很多手机都在用。
这些内核的共同特点是:小、专、硬。它们只提供最基本的内存管理、中断处理和线程调度,不提供文件系统、网络协议栈这些“花哨”功能。为什么?因为功能越少,攻击面越小。
避坑指南:我曾经在移植 OP-TEE 到一款新芯片时,发现安全内核总是启动失败。查了三天,最后发现是芯片的 TrustZone 硬件配置寄存器没设置对。所以,做 TEE 适配的第一步,一定是仔细阅读芯片的 TRM(Technical Reference Manual),把 TrustZone 相关的硬件配置搞清楚。
TEE 的软件栈:OS、TA、CA
硬件隔离是地基,软件栈就是上面的房子。TEE 的软件栈分为三层:CA(Client Application)、TEE OS 和 TA(Trusted Application)。
我画了一张图,帮你直观理解这三层的关系:
CA:普通世界的“使者”
CA 运行在普通世界,就是我们常见的 App。比如支付宝、支付的 App 本身就是一个 CA。它负责发起安全请求,但自己不处理敏感数据。
CA 通过 TEE Client API 与安全世界通信。这个 API 是标准化的,主要就几个函数:
TEEC_InitializeContext:初始化 TEE 上下文。TEEC_OpenSession:打开与 TA 的会话。TEEC_InvokeCommand:调用 TA 中的命令。TEEC_CloseSession:关闭会话。
说白了,CA 就是个“跑腿的”。它把数据打包好,通过 SMC 送到安全世界,然后等结果。它自己看不到数据在安全世界里是怎么处理的。
TEE OS:安全世界的“管家”
TEE OS 是安全世界的操作系统内核。它负责管理安全世界里的所有资源:内存、中断、TA 的生命周期等。
TEE OS 的核心职责包括:
- 内存隔离:确保每个 TA 只能访问自己的内存区域。
- 中断管理:处理来自安全外设的中断,比如安全键盘、指纹传感器。
- TA 加载与调度:从安全存储中加载 TA 镜像,并调度执行。
- 密码学服务:提供硬件加速的加解密、签名、哈希等操作。
注意:TEE OS 不是 Linux!它没有进程的概念,只有“会话”和“线程”。一个 TA 可以同时处理多个会话,但每个会话是独立隔离的。我在做性能优化时,就踩过这个坑——以为可以像 Linux 一样开多线程并行处理,结果发现 TEE OS 的线程模型非常受限。
TA:安全世界的“打工人”
TA 是真正干活的。它运行在安全世界,处理敏感数据。比如指纹比对、密钥生成、支付令牌签名等。
TA 的特点:
- 单一职责:一个 TA 通常只做一件事,比如“密钥管理 TA”只负责生成和存储密钥。
- 无网络访问:TA 不能直接访问网络,所有数据必须通过 CA 中转。
- 持久化存储:TA 可以将数据加密后存储到普通世界的文件系统中,但只有 TA 自己能解密。
TA 的开发接口是 TEE Internal API,它提供了:
| API 类别 | 功能 | 常用函数 |
|---|---|---|
| 密码学 | 加解密、签名、哈希 | TEE_AllocateOperation、TEE_AsymmetricSignDigest |
| 存储 | 安全存储数据 | TEE_OpenPersistentObject、TEE_WriteObjectData |
| 时间 | 获取安全时间 | TEE_GetSystemTime |
| 内存管理 | 分配安全内存 | TEE_Malloc、TEE_Free |
嗯,这里要特别说一下安全存储。TA 不能直接写硬盘,它只能通过 TEE OS 提供的接口,把数据加密后存到普通世界的文件里。加密密钥由 TEE OS 管理,普通世界根本拿不到。我曾经帮一个客户排查问题,发现 TA 存储的数据在重启后丢失了。最后定位到是 TA 的存储对象 ID 冲突了——两个 TA 用了相同的 ID,导致数据被覆盖。所以,给 TA 分配存储 ID 时,一定要保证全局唯一。
小结
这一章我们聊了 TEE 的硬件隔离机制和软件栈。TrustZone 提供了物理级别的隔离,TEE 安全内核是安全世界的“大脑”,而 CA、TEE OS、TA 三层架构,则让普通世界和安全世界能够有序协作。
记住一句话:CA 负责“问”,TA 负责“做”,TEE OS 负责“管”,TrustZone 负责“隔”。把这四个角色搞清楚了,TEE 的架构你就掌握了八成。