2. ARMv9架构演进与安全扩展概览

RME 是 ARMv9.4 引入的一套安全扩展,说白了就是给机密计算铺路的。我刚开始接触这个模块时,第一反应是「又来一套安全模型?」——毕竟之前有 TrustZone,有 S-EL2,有 Secure EL2 的虚拟化。但深入看下去才发现,RME 解决了一个根本问题:谁有权访问我的数据。

传统 TrustZone 里,Secure World 的代码可以访问所有 Normal World 的内存。这在某些场景下是合理的,但在云端、边缘计算场景里,你根本不想让宿主机或 Hypervisor 看到你的应用数据。RME 就是为此设计的。

2.1 RME 的架构目标

RME 的核心目标其实就三个:

  • 隔离:在硬件层面把 Realm 和其他执行环境彻底隔开
  • 可验证:Realm 的启动和运行状态可以被远程证明
  • 最小化 TCB:Trusted Computing Base 只包含 Realm 自身和硬件

我记得有一次和客户讨论机密计算方案,对方问:「我用 TrustZone 做隔离不行吗?」我当时的回答是:TrustZone 的 Secure World 本身就是一个超级特权层,它能看到所有 Normal World 的数据。你想想看,如果你的应用跑在 Normal World,而 Secure World 的代码有 bug,那数据就全暴露了。RME 引入的 Realm 是一个独立于 Secure World 和 Normal World 的第三世界,连 EL3 的 Monitor 都不能直接访问 Realm 的内存。

RME 的四个世界(Four Worlds)

  • Normal World:Rich OS、Hypervisor、普通应用
  • Secure World:TEE、安全服务、可信应用
  • Realm World:机密计算应用、机密 VM
  • Root World:EL3 Monitor、RMM(Realm Management Monitor)

这里要注意,Root World 是 RME 新增的概念。它运行在 EL3,负责管理 Realm 的生命周期。但 Root World 也不能直接读取 Realm 的内存——它只能通过 RMM 接口来操作,而且所有操作都会被硬件审计。

2.2 Realm 的概念

Realm 是什么?我习惯把它理解成一个「硬件级机密容器」。它不是一个进程,也不是一个虚拟机,而是一个由硬件保护的计算环境。

每个 Realm 有自己独立的地址空间、页表、中断控制器配置。Realm 里的代码和数据,在物理内存层面是被加密的——用的是芯片内置的内存加密引擎。即使攻击者能物理访问内存条,看到的也是一堆密文。

我曾经在调试一个 RME 原型系统时,遇到过一个坑:Realm 的页表必须由 RMM 来管理,你不能像普通 Linux 那样直接写页表。RMM 会检查每个页表条目,确保不会映射到其他 Realm 或 Secure World 的内存。这个检查是硬件强制执行的,软件绕不过去。

Realm 的关键属性

  • 每个 Realm 有唯一的 Realm ID
  • Realm 的内存由 GPT(Granule Protection Table)保护
  • Realm 的启动由 RMM 负责,启动过程可被远程证明
  • Realm 之间完全隔离,不能互相访问

2.3 Granule Protection Table (GPT)

GPT 是 RME 的核心硬件机制。它本质上是一张物理内存粒度的权限表,粒度是 4KB(一个 granule)。每个 granule 都有一个 2-bit 的权限字段,定义了这个 granule 属于哪个世界:

GPT 权限值 所属世界 可访问者
0b00 Any World 所有世界都可访问
0b01 Realm World 仅 Realm World 可访问
0b10 Secure World 仅 Secure World 可访问
0b11 Root World 仅 Root World 可访问

嗯,这里要注意:GPT 的检查是在系统级做的,不是只在某个异常级别。也就是说,即使你跑在 EL3,如果 GPT 标记某个 granule 属于 Realm World,EL3 的代码也读不了它。这个设计很关键——它防止了 Root World 的恶意代码窃取 Realm 数据。

我刚开始看 GPT 时,觉得它和 Stage-2 页表有点像。但实际区别很大:Stage-2 页表是软件可配置的,而 GPT 的配置是一次性写入后锁定的。RMM 在启动时配置好 GPT,然后就把配置寄存器锁死,后续任何软件都不能修改。这保证了隔离的不可绕过性。

GPT 配置的注意事项

我曾经在项目中遇到过一个问题:GPT 的配置必须在 RMM 启动阶段完成,一旦进入运行阶段,GPT 寄存器就被硬件锁定。如果你在启动时漏配了某个内存区域,后续想补配是不可能的。所以,启动时的 GPT 配置必须覆盖所有物理内存,否则未配置的区域默认会被标记为「不可访问」,导致系统崩溃。

2.4 RME 的启动流程

RME 的启动流程比传统 ARM 启动复杂不少。我把它拆成几个关键阶段:

  1. Boot ROM 阶段:芯片上电,Boot ROM 执行,加载 RMM 镜像到 Root World 的受保护内存
  2. RMM 初始化:RMM 配置 GPT,锁定配置寄存器,初始化 Realm 调度器
  3. Realm 创建:Normal World 的 Hypervisor 通过 RMM 接口请求创建 Realm
  4. Realm 测量:RMM 对 Realm 的初始状态进行哈希测量,生成度量值
  5. Realm 运行:RMM 切换到 Realm World,执行 Realm 代码

这里有个细节值得注意:Realm 的创建请求是从 Normal World 发起的,但 Normal World 不能直接访问 Realm 的内存。那 Realm 的镜像怎么加载?答案是:Normal World 把镜像数据放在一块共享内存里,RMM 负责把数据拷贝到 Realm 的受保护内存中。拷贝完成后,RMM 会清空共享内存,防止数据残留。

我记得在调试启动流程时,遇到过一个问题:Realm 的度量值和我预期的对不上。后来发现是 RMM 在拷贝镜像时,对内存做了对齐填充,导致哈希值变了。解决方案是在 Realm 镜像里显式指定填充策略,让度量过程可复现。

RME 启动流程的关键点

  • GPT 配置必须在 RMM 初始化阶段完成,且一旦锁定不可修改
  • Realm 的度量值包含:Realm 镜像哈希、RMM 版本、平台证书
  • 度量值可以通过远程证明协议发送给挑战者,验证 Realm 是否可信
  • RMM 本身也是可信的,它的度量值在启动时由 Boot ROM 记录

下面这张图展示了 RME 的启动流程和世界切换关系:

RME 启动流程与四世界关系 Normal World Rich OS / Hypervisor Secure World TEE / 安全服务 Realm World 机密计算应用 Root World RMM / EL3 Monitor ① 请求创建 Realm ② 分配内存 ③ 配置 GPT RMM 初始化与 Realm 创建流程 1. RMM 加载 → 2. GPT 配置并锁定 → 3. 接收 Realm 创建请求 4. 拷贝镜像 → 5. 度量 Realm → 6. 切换到 Realm World Realm 运行阶段 GPT 硬件保护 / 内存加密 / 远程证明

从这张图可以看出,RME 的启动不是线性的,而是多世界协作的过程。Normal World 发起请求,Root World 负责管理,Realm World 负责执行。Secure World 在这个流程里基本不参与——这也是 RME 的设计哲学:把机密计算和传统安全服务解耦。

最后说一个我踩过的坑:在调试 RME 启动时,如果 GPT 配置错了,系统会直接挂掉,而且没有任何错误日志。因为 GPT 的访问违例是硬件触发的同步异常,而 RMM 在启动阶段还没有注册异常处理函数。所以,GPT 配置代码一定要经过严格测试,最好在模拟器上先跑一遍。