3. 安全世界与非安全世界:物理内存与虚拟内存的隔离、安全监控器(Monitor Mode)的作用、世界切换的触发条件
在 TrustZone 架构中,系统被划分为两个独立的执行环境:安全世界(Secure World)与非安全世界(Normal World)。这种划分不仅仅是逻辑上的,更是在硬件层面实现了物理内存与虚拟内存的严格隔离。本章将深入剖析这两种世界的隔离机制、安全监控器(Monitor Mode)的核心作用,以及世界切换的触发条件与流程。
3.1 物理内存与虚拟内存的隔离机制
TrustZone 通过硬件扩展实现了对系统总线的安全控制。在物理内存层面,系统总线上的每个内存访问事务都携带一个额外的 NS(Non-Secure)位,用于标识该访问是否来自安全世界。
3.1.1 物理内存隔离:TZASC 与 TZMA
ARM 提供了两种主要的硬件组件来实现物理内存的区域划分:
- TZASC(TrustZone Address Space Controller):用于将外部 DRAM 划分为多个安全区域和非安全区域。每个区域可以独立配置访问权限。
- TZMA(TrustZone Memory Adapter):用于保护片上 SRAM,通常用于存放安全世界的关键代码和数据。
| 特性 | TZASC | TZMA |
|---|---|---|
| 保护目标 | 外部 DRAM | 片上 SRAM |
| 区域粒度 | 可配置(通常 4KB 对齐) | 固定区域(由 SoC 设计决定) |
| 配置方式 | 通过安全世界寄存器编程 | 硬件引脚或 eFuse 配置 |
| 典型用途 | 安全存储、安全帧缓冲 | 安全监控器代码、密钥存储 |
关键概念:非安全世界的任何访问,无论来自 CPU 还是 DMA 设备,只要目标地址被 TZASC/TZMA 标记为安全区域,都会触发 安全异常(Secure Fault),从而防止数据泄露。
3.1.2 虚拟内存隔离:页表项的 NS 位
在虚拟内存层面,TrustZone 利用了 ARM 架构中页表描述符的 NS(Non-Secure)位。当安全世界进行虚拟地址到物理地址的转换时,页表中的 NS 位决定了该物理页是否可以被非安全世界访问。
- 安全世界页表:可以映射安全物理内存和非安全物理内存。当映射非安全内存时,页表项中的 NS 位被置 1。
- 非安全世界页表:只能映射非安全物理内存。即使页表项中的 NS 位被置 0,硬件也会强制将其视为非安全访问。
实践要点:在驱动开发中,安全世界驱动如果需要与非安全世界共享数据缓冲区,必须在页表中将对应的物理页标记为 NS 位,否则非安全世界无法访问该缓冲区。
3.2 安全监控器(Monitor Mode)的作用
安全监控器(Monitor Mode)是 TrustZone 架构中一个特殊的 CPU 模式,它独立于安全世界和非安全世界,拥有最高的执行权限。监控器模式是连接两个世界的桥梁,负责处理所有世界切换的上下文保存与恢复。
3.2.1 监控器模式的核心职责
- 上下文切换:保存当前世界的寄存器状态(包括通用寄存器、系统控制协处理器寄存器、中断控制器状态等),恢复目标世界的寄存器状态。
- 安全策略执行:验证世界切换请求的合法性,防止非安全世界非法调用安全服务。
- 中断路由:根据中断的安全属性(FIQ/IRQ),将中断路由到正确的世界处理。
- 异常处理:处理安全监控器调用(SMC)指令触发的异常。
| CPU 模式 | 特权级别 | 可访问内存 | 主要用途 |
|---|---|---|---|
| Monitor Mode | 最高(PL3) | 所有物理内存 | 世界切换、安全策略 |
| Secure Supervisor (SVC) | 高(PL1) | 安全内存 + 共享内存 | 安全操作系统内核 |
| Normal Supervisor (SVC) | 高(PL1) | 非安全内存 | 非安全操作系统内核 |
| User Mode | 低(PL0) | 用户空间内存 | 应用程序执行 |
3.2.2 监控器模式的进入与退出
进入监控器模式只有两种途径:
- 执行 SMC(Secure Monitor Call)指令:这是软件主动触发世界切换的标准方式。
- 硬件异常:包括 FIQ(快速中断请求)、外部中止(External Abort)等,当这些异常被配置为路由到监控器模式时。
安全警告:监控器模式的代码必须经过严格的形式化验证和侧信道攻击防护。任何监控器模式的漏洞都可能导致整个 TrustZone 安全体系崩溃,因为攻击者可以控制世界切换逻辑,绕过所有安全隔离。
3.3 世界切换的触发条件与流程
世界切换是 TrustZone 安全模型的核心操作。切换过程必须保证原子性和安全性,防止在切换过程中发生数据泄露或状态破坏。
3.3.1 触发条件分类
| 触发类型 | 具体条件 | 方向 | 典型场景 |
|---|---|---|---|
| SMC 指令 | 软件执行 SMC #0 | 双向 | 非安全世界调用安全服务 |
| FIQ 中断 | 安全中断被触发 | 非安全 → 安全 | 安全定时器、安全 DMA 完成 |
| IRQ 中断 | 非安全中断被触发 | 安全 → 非安全 | 安全世界处理完关键任务后返回 |
| 外部中止 | 非安全访问安全内存 | 非安全 → 安全 | 安全异常处理 |
| 系统调用 | 安全世界主动请求切换 | 安全 → 非安全 | 安全驱动完成服务后返回 |
3.3.2 世界切换的完整流程
以非安全世界通过 SMC 调用安全服务为例,世界切换的典型流程如下:
- 非安全世界准备:客户端应用(CA)通过驱动接口发起 SMC 调用,将调用参数放入约定的寄存器(如 R0-R5)。
- 执行 SMC 指令:CPU 进入 Monitor Mode,硬件自动保存当前世界的部分状态(如 SPSR_mon、LR_mon)。
- 监控器上下文保存:监控器代码保存非安全世界的完整上下文(通用寄存器、系统寄存器、中断状态等)到安全内存中的上下文存储区。
- 安全策略检查:监控器验证 SMC 调用号、参数合法性,确认非安全世界是否有权限调用该安全服务。
- 恢复安全世界上下文:从安全内存中加载安全世界的上下文,包括栈指针、页表基址、中断控制器状态等。
- 切换到安全世界:修改 SCR(Secure Configuration Register)中的 NS 位为 0,执行异常返回指令(ERET),CPU 进入安全世界。
- 安全世界处理:安全操作系统分发 SMC 请求到对应的可信应用(TA)或安全驱动,执行安全服务。
- 返回流程:安全世界处理完成后,再次执行 SMC 指令,监控器执行反向的上下文切换,恢复非安全世界状态。
性能优化:频繁的世界切换会带来显著的性能开销(通常每次切换需要数百个 CPU 周期)。在驱动开发中,应尽量将多个安全服务请求合并为一次 SMC 调用,减少上下文保存/恢复的次数。
3.4 世界切换的硬件支持:SCR 与 MVBAR
世界切换的硬件基础依赖于两个关键寄存器:
- SCR(Secure Configuration Register):位于系统控制协处理器 CP15 中,控制当前世界的安全状态、中断路由策略等。
- MVBAR(Monitor Vector Base Address Register):指定监控器模式的异常向量表基地址,确保世界切换代码的入口点固定且安全。
驱动开发关键点:在初始化安全监控器时,必须正确设置 MVBAR 指向安全内存中的监控器代码。如果 MVBAR 指向非安全内存,攻击者可以通过修改非安全内存中的异常向量表来劫持世界切换流程。
/* 安全监控器初始化代码示例(汇编) */
.section .monitor_text, "ax"
.globl monitor_init
monitor_init:
/* 设置监控器异常向量表基地址 */
LDR R0, =monitor_vector_table
MCR p15, 0, R0, c12, c0, 1 /* 写入 MVBAR */
/* 配置 SCR 寄存器 */
MRC p15, 0, R0, c1, c1, 0 /* 读取 SCR */
ORR R0, R0, #0x1 /* 设置 NS 位为 0(安全世界) */
ORR R0, R0, #0x10 /* 设置 FIQ 路由到 Monitor Mode */
BIC R0, R0, #0x100 /* 清除 AW 位(异步中止路由) */
MCR p15, 0, R0, c1, c1, 0 /* 写入 SCR */
/* 启用监控器模式的中断处理 */
CPS #0x16 /* 切换到 Monitor Mode */
MSR CPSR_c, #0xD6 /* 设置 I 和 F 位,禁用 IRQ/FIQ */
BX LR