(参考资料:TrustZone for V8-A. pdf,来源ARM DEVELOPER官网)
TEE(Trusted Execution Environment,可信执行环境)是用于执行敏感代码和处理敏感数据的独立安全区域;以ARM TrustZone为例,TEE和普通执行环境(REE)通过硬件和软件的结合实现隔离和保护。TEE在移动终端领域主要用于移动支付(微信、支付宝)、数字版权保护、生物识别(指纹、虹膜、人脸)等。
1 ARMv7 和 ARMv8 架构
1)ARMv7 架构
1.1)PL0 (USR):用户模式,最低特权级别。
1.2)PL1 (SVC/ABT/IRQ/FIQ/UND/SYS):内核模式,较高特权级别,包括多个异常模式。
- SVC (Supervisor Call):管理模式。
- ABT (Abort):数据或预取中止异常。
- IRQ (Interrupt Request):中断请求。
- FIQ (Fast Interrupt Request):快速中断请求。
- UND (Undefined Instruction):未定义指令。
- SYS (System):系统模式,运行系统级软件。
1.3)Hyp:虚拟化扩展,支持 Hypervisor 模式。
1.4)Monitor:TrustZone 安全监控模式,用于安全世界和正常世界的切换。
2)ARMv8 架构
2.1)EL0 (Exception Level 0):用户模式,等同于 ARMv7 的 PL0。
2.2)EL1 (Exception Level 1):内核模式,等同于 ARMv7 的 PL1。
2.3)EL2 (Exception Level 2):虚拟化模式,等同于 ARMv7 的 Hyp。
2.4)EL3 (Exception Level 3):安全监控模式,等同于 ARMv7 的 Monitor。
3)对应关系
通过以上机制和结构,ARM TrustZone 能够有效地在硬件上实现安全世界和正常世界的隔离,从而提高系统的整体安全性。
2 TrustZone技术
1)概述
ARM TrustZone 是一种系统级的安全架构,最早在 ARMv6K 中引入,并且在 v7、v8和v9中得到了支持。TrustZone 提供两个执行环境,并通过硬件强制实现它们之间的隔离:Normal World正常世界和Secure World安全世界。
正常世界:运行复杂的操作系统(例如 Linux)和丰富的软件堆栈,包括大量的应用程序和可能存在的虚拟机监控程序。尽管可以采取措施增强其安全性,但由于其攻击面较大,更容易受到攻击。
安全世界:运行较小且简单的软件堆栈,通常称为可信执行环境(TEE)。TEE 包含若干提供关键管理等功能的可信服务,由轻量级内核托管;由于其攻击面较小,因而减少了被攻击的可能性。
2)安全状态切换
在 ARM TrustZone 中,处理器支持两个安全状态:安全和非安全状态,如下图所示状态之间的切换通过安全监控调用(Secure Monitor Call,SMC)指令和硬件机制(如 AXI 总线的 NS 位)完成。
2.1)状态切换步骤示例
- 进入更高的异常级别需要一个异常,通常这个异常会是FIQ(快速中断请求)或SMC(安全监控调用)异常。
- 在适当的异常向量处进入EL3,在EL3中运行的软件会切换SCR_EL3.NS位。
- 异常返回操作将处理器从EL3带回到S.EL1。
2.2)SMC异常执行
为了标准化接口,Arm 提供了 SMC 调用约定(DEN0028)和电源状态协调接口规范(DEN0022)。这些规范阐明了如何使用 SMC 请求服务。在 EL1 执行 SMC 可以被捕获到 EL2;在任何安全状态下,SMC 指令在 EL0 都不可用。
3)硬件组件支持
· AXI 总线安全位(NS):用于区分总线上的安全和非安全事务。
· TZASC(TrustZone Address Space Controller)和 TZMA(TrustZone Memory Adapter):为内存管理单元(MMU)增加安全位以区分安全和非安全的内存地址访问,每种状态下的虚拟地址转换表是独立的,每一条页表标识符包含安全状态位表示被映射的内存属于安全还是非安全内存,确保安全和非安全数据的隔离。
· TZPC(TrustZone Protection Controller):区分哪些外设是安全设备,哪些是非安全设备。
· TZIC(TrustZone Interrupt Controller):根据配置判断中断类型,确保非安全态无法获取。
4)虚拟地址和资源隔离
TrustZone 通过虚拟化和资源隔离技术实现安全。
4.1)非安全状态
非安全状态下,仅可看到非安全的资源和访问地址。
4.2)安全状态
安全状态下,可以访问安全和非安全的地址空间。
4.3)Secure EL2
S.EL2 通常托管一个安全分区管理器(SPM)而不是一个完整的管理程序,SPM 允许创建隔离的分区,这些分区无法看到其他分区的资源。系统可以有多个包含可信内核及其可信服务的分区,也可以创建一个分区来容纳平台固件,从而无需在 EL3 运行该代码。
启用 Secure EL2
当支持 S.EL2 时,是否启用 S.EL2 由 SCR_EL3.EEL2 位控制。
0:禁用 S.EL2,行为与不支持 S.EL2 的处理器相同。
1:启用 S.EL2。
安全状态下的二级转换
与一级表不同,二级表项中没有 NS 位,对于给定的 IPA 空间,所有转换结果要么是安全的物理地址要么是非安全的物理地址,这由寄存器位控制。通常非安全 IPA 转换为非安全 PA,而安全 IPA 转换为安全 PA。
3 系统架构
1)从设备强制隔离
TrustZone 有时被称为slave-enforce保护系统,主设备发出其访问的安全性信号,内存系统决定是否允许访问。那么内存系统的检查是如何完成的呢?
在大多数现代系统中,内存系统的检查由互连(interconnect)完成。例如Arm 的 NIC-400 允许系统设计人员为每个连接的从设备指定:
- 安全:如上图所示只有安全访问才会传递到蓝色标识设备。互连会对所有非安全访问生成故障,而不向设备传递访问请求。
- 非安全:只有非安全访问才会传递到设备。互连会对所有安全访问生成故障,而不向设备传递访问请求。
- 引导时可配置:系统初始化软件可以将设备配置为安全或非安全,默认是安全。
- 支持TrustZone:互连允许所有访问通过,连接的设备必须实现隔离。
如上图所示,这种方法对于较大的内存如芯片外 DDR,TrustZone 地址空间控制器(TZASC)类似于内存保护单元(MPU),允许将设备的地址空间分割成多个区域。每个区域可以指定为安全或非安全,控制 TZASC 的寄存器仅供安全访问。Arm TZC-400 是一个 TZASC 的例子,支持多达九个区域。
注意:芯片外内存比芯片内内存安全性低,因为攻击者更容易读取或修改其内容;芯片内内存更安全,但成本更高且容量有限。我们必须在成本、可用性和安全性之间找到平衡,决定哪些资产放在芯片外内存和哪些资产需要保存在芯片内存时要小心。
2)总线主设备
大多数现代 SoC 还包含非处理器总线主设备,例如 GPU 和 DMA 控制器,像从设备一样,我们可以将系统中的主设备大致分为两组:
2.1)支持 TrustZone
一些主设备像处理器一样,伴随每次总线访问提供安全状态信息。例如按照 Arm SMMUv3 规范构建的系统 MMU(SMMU)。
2.2)不支持 TrustZone
这些主设备通常在其总线访问中不提供安全信息,或总是发送相同的值:
设计时固定:如果主设备只需要访问单个物理地址空间,系统设计人员可以通过固定适当的信号来限制其访问的地址空间。
可配置逻辑:提供逻辑以将安全信息添加到主设备的总线访问中,安全软件可以在引导时使用这些寄存器来设置连接的主设备访问的安全性。这会覆盖主设备自己提供的值,仍然只允许主设备访问单个物理地址空间,但比固定方法更灵活。
SMMU:对于受信任的主设备,SMMU 的行为像安全状态下的 MMU,包括转换表项中的 NS 位,控制访问哪个物理地址空间。
3)中断管理
通用中断控制器(GIC)支持TrustZone,每个中断源被分配到三个组中的一个:
• Group 0:安全中断,FIQ信号;用于由EL3固件处理的中断,与低级系统管理函数相关。
• Secure Group 1:安全中断,IRQ或FIQ信号;用于所有其他安全中断源,通常由S.EL1或S.EL2软件处理。
• Non-secure Group 1:非安全中断,IRQ或FIQ信号。
这由软件通过写入GIC[D|R]_IGROUPR<n>和GIC[D|R]_IGRPMODR<n>寄存器控制,配置不是静态的,软件可以在运行时更新分配:
- 对于配置为安全的INTID,只有总线安全访问可以修改状态和配置,对应于安全中断的寄存器字段在非安全总线访问时读取为0。
- 对于配置为非安全的INTID,安全和非安全总线访问都可以修改状态和配置。
如何配置异常路由控制,上图展示了一种可能的配置。另一个常见的选项是,在安全状态下将FIQ路由到EL1,可信操作系统将FIQ视为向固件或非安全状态让步的请求,这种中断路由的方法使得可信操作系统有机会以受控方式退出。
4)测试模式
现代Arm系统包括广泛的功能来支持调试和性能分析,关于测试模式功能,考虑到一个新SoC的开发,所有调试功能都应该被启用。当芯片出货到OEM时,他们仍然需要调试非安全状态软件堆栈,但OEM可能会被禁止调试安全状态的代码,仅为应用程序开发者提供一些调试功能,同时限制硅提供商和OEM调试代码的能力。
启用不同调试、跟踪和性能分析功能的信号包括:
- DBGEN:最高级的侵入式调试使能,控制两个安全状态下的外部调试。
- SPIDEN:安全侵入式调试使能,控制安全状态下的外部调试能力。
示例如下:
- 芯片设计者的早期开发:DGBEN==1和SPIDEN==1,启用完整的外部调试;
- OEM的产品开发:DBGEN==1,启用非安全状态下的外部调试;SPIDEN==0,禁用安全状态下的调试;
- 出货产品:DGBEN==0 和 SPIDEN==0,禁用两个安全状态下的外部调试,仍然可以调试应用程序。
如上图所示,通常会使用e-fuses或认证模块来连接这些信号,通过在制造过程中烧毁保险丝,可以永久禁用测试模式。
4 软件架构
- 在安全状态下的TEE托管诸如密钥管理或数字版权管理(DRM)之类的服务,会使用由用户空间库提供的高级API,该库处理与可信服务的通信,类似于图形API如何从底层GPU提供抽象。
- 服务库与可信服务之间的通信通常使用内存中的消息队列或邮箱来处理,有时候使用“World Shared Memory”(WSM)来描述用于这种通信的内存,这些队列必须位于两组软件都能看到的内存中,即非安全内存。
- 服务库将请求或请求放置在邮箱中,然后调用内核空间中的驱动程序,驱动程序负责与可信执行环境(TEE)进行低级交互,包括为消息队列分配内存并将其注册到TEE中。安全世界与正常世界在不同的虚拟地址空间中运行,因此它们不能使用虚拟地址进行通信。
- 驱动程序通常使用SMC调用安全状态,控制会通过EL3安全监视器传递到TEE中的可信内核。内核调用所请求的服务,然后可以从队列中读取请求。
1)OP-TEE
OP-TEE(Open Portable Trusted Execution Environment)是一个开放源代码的可信执行环境(TEE)实现,它旨在提供安全和隔离的执行环境,以保护关键数据和执行敏感操作。
1.1)OP-TEE的架构
- Trusted OS Kernel: OP-TEE的核心部分是运行在安全状态下的可信操作系统内核,提供一个受保护的环境用于执行安全应用程序和服务。
- TEE Client API: 为正常世界提供了一个高级API,使应用程序能够与TEE进行通信,而不需要了解底层的TrustZone技术细节;这些API允许应用程序发送请求到安全世界,执行敏感操作并接收返回结果。
- Secure Monitor: 在ARM平台上,OP-TEE使用EL3层的Secure Monitor作为安全世界和非安全世界之间的中介,通过SMC来处理从非安全状态到安全状态的调用。
- TEE Core Services: 包括安全存储、加密服务、密钥管理、数字版权管理(DRM)、安全认证等核心服务,这些服务由TEE内核提供并受到严格的安全控制。
- Communication Channels: OP-TEE使用消息队列或邮箱等通信机制,用于在安全世界和非安全世界之间传递数据和请求。
1.2)工作机制
OP-TEE内核在S.EL1中运行,托管在S.EL0中的可信应用程序通过TEE内部API与OP-TEE内核进行通信。TEE内部API是由GlobalPlatform组织开发的标准API。
如上图所示,在非安全状态下,内核空间中有一个低级OP-TEE驱动程序,这个驱动程序负责处理与OP-TEE内核的低级通信;在非安全用户空间(EL0)中,有一个实现另一个GlobalPlatform API的用户空间库;TEE客户端API是应用程序用来访问可信应用程序或服务的接口;Tee-supplicant处理由OP-TEE支持且需要一定程度富操作系统交互的服务例如安全存储。
2)可信启动
只有我们信任在启动运行的所有软件组件,才能信任软件组件,下图显示了简化的信任链:
- 第一个运行的代码是引导ROM,必须隐式信任引导ROM,因为没有更早的引导阶段来验证其内容。引导ROM代码通常简单,主要功能是从闪存加载和验证第二阶段引导代码。
- 第二阶段引导代码执行平台的系统初始化,如为片外DRAM设置内存控制器;此代码还负责加载和验证将在安全和非安全状态下运行的映像,包括在安全状态下加载TEE和在非安全状态下加载高级固件如UEFI。
3)可信固件
可信固件是Armv8-A设备的开源安全世界软件的参考实现,为SoC开发者和OEM提供符合相关Arm规范(包括TBBR和SMCC)的参考可信代码库。
如上图所示为可信固件组件图,SMC调度程序处理传入的SMC,SMC调度程序识别应由可信固件在EL3处理的SMC,以及应转发给可信执行环境的SMC。可信固件还提供处理Arm系统IP(如互联)的代码,包括SoC特定的电源管理功能。