1、TrustZone 基础概念

各位同学,咱们今天聊聊 TrustZone 的基础。说实话,这玩意儿刚出来的时候,我也觉得不就是个硬件开关嘛。后来踩了坑才发现,它背后的设计哲学,远比想象中精妙。

ARM TrustZone 技术概述

TrustZone 是 ARM 在 ARMv6 架构之后引入的一种硬件安全扩展。说白了,它不是在软件层面打补丁,而是从芯片的 总线层面 就做了隔离。

我习惯把 TrustZone 理解成「一个芯片,两个世界」。这两个世界共享同一个物理 CPU 核心,但在逻辑上完全独立。你想想看,普通操作系统跑在「非安全世界」,而敏感操作——比如密钥管理、指纹比对——放在「安全世界」。即使非安全世界的 Linux 内核被攻破了,攻击者也摸不到安全世界的一根毛。

核心思想: TrustZone 不是虚拟化,而是「硬件强制隔离」。虚拟化靠软件 Hypervisor 隔离,TrustZone 靠硬件总线信号隔离。后者更底层,也更难绕过。

我记得 2015 年做第一个 TEE 项目时,客户问我:「TrustZone 和普通 Secure Monitor 有啥区别?」我当时画了张图给他——嗯,就是下面这张。

TrustZone 双世界架构 非安全世界 (Normal World) Rich OS (Linux) 用户 App 非安全驱动 / 外设 NS bit = 1 只能访问非安全内存/外设 安全世界 (Secure World) TEE OS (OP-TEE) 安全 TA 安全外设 (Key/OTP/RNG) NS bit = 0 可访问安全+非安全内存 Monitor 模式 — 世界切换的入口 SMC 调用 ⚠ 两个世界共享 CPU 核心,但内存和外设通过硬件 NS bit 隔离。Monitor 是唯一的切换通道。

安全世界与非安全世界隔离原理

隔离是怎么做到的?关键在于 NS bit(Non-Secure bit)。

ARM 在系统总线上增加了一根信号线,叫 NS。每个内存访问、每个外设访问,都会带上这个 NS 信号。硬件上,内存控制器、中断控制器、DMA 控制器都会检查这个信号。

  • NS=1:非安全访问。只能访问标记为「非安全」的内存和外设。
  • NS=0:安全访问。可以访问所有资源——包括安全和非安全区域。

你想想看,这意味着什么?安全世界是「特权」的,它能看到一切。非安全世界是「受限」的,它只能看到自己被允许看到的东西。这种设计,我称之为「单向透明」——安全世界对非安全世界透明,反过来不行。

避坑指南: 我曾经在一个项目中,把安全内存的配置写错了,导致非安全世界的 DMA 控制器直接读走了密钥。原因就是 NS bit 没配对。记住:外设也要配 NS 属性,不只是内存。

隔离的另一个层面是 中断隔离。ARM 引入了 FIQ(快速中断)和 IRQ(普通中断)的区分。安全世界用 FIQ,非安全世界用 IRQ。这样,即使非安全世界的中断被恶意屏蔽,安全世界的中断依然能准时到达。

隔离维度 非安全世界 安全世界
内存 只能访问非安全内存 可访问安全 + 非安全内存
外设 只能访问非安全外设 可访问安全 + 非安全外设
中断 IRQ FIQ
异常向量 非安全异常向量表 安全异常向量表
缓存/TLB 非安全标记 安全标记

Monitor 模式与 SMC 指令

两个世界怎么切换?靠 Monitor 模式。

Monitor 模式是 ARM 架构中一个特殊的 CPU 模式,优先级最高。它既不属于安全世界,也不属于非安全世界——它是「门卫」。

触发 Monitor 模式的方式只有两种:

  1. SMC 指令(Secure Monitor Call)——软件主动调用。
  2. 硬件异常——比如 FIQ、外部中止等。

SMC 指令是啥?说白了就是一个特殊的汇编指令。非安全世界执行 SMC #0,CPU 就会陷入 Monitor 模式。Monitor 保存当前世界的上下文,加载目标世界的上下文,然后切换过去。

// 非安全世界调用 SMC 示例(ARMv8 AArch64)
// x0 = 功能ID, x1-x6 = 参数
mov x0, #0xC5000000      // 标准服务调用
mov x1, #0x01            // 参数1
smc #0                   // 触发 Monitor 模式

// 执行到这里时,已经回到非安全世界
// x0 中保存返回值

注意: SMC 调用是有开销的。每次切换需要保存/恢复几十个寄存器,还要刷 TLB 和缓存。我实测过,一次 SMC 调用大约需要 1-5 微秒。如果你的业务逻辑频繁调用 SMC,性能会很难看。

Monitor 模式下的代码通常叫 Secure Monitor 或 ATF(ARM Trusted Firmware)。它负责:

  • 管理世界切换的上下文
  • 处理 SMC 请求的路由
  • 管理电源状态(比如 CPU 休眠唤醒时的世界恢复)

我记得第一次写 Secure Monitor 时,犯了个低级错误——在 Monitor 模式下开了中断。结果世界切换过程中被中断打断,上下文全乱了。嗯,这里要注意:Monitor 模式下必须关中断,这是铁律。

关键总结: TrustZone 的隔离不是靠软件,而是靠硬件总线信号 NS bit。Monitor 模式是唯一的切换通道,SMC 是唯一的调用入口。理解这三者的关系,后面学国密算法在 TEE 里的应用才能顺起来。