《TrustZone for Armv8-A》阅读笔记
参考文档:《TrustZone for Armv8-A》
1 Overview
异常模型Exception Model将ARM分为:安全和非安全部分。
非安全部分包括:NS.EL0、NS.EL1、NS.EL2;安全部分包括:EL3、S.EL2(ARMv8.4新增)、S.EL1、S.EL0。
MMU主要工作就是进行虚拟地址到物理地址转换。MMU主要包括TLB和TCU。TCU包括DVM、PTW等等。
TLB缓存页表项;Table Walk Unit进行项查找。
2 What is TrustZone?
TrustZone讲一个CPU分成两个执行环境:REE(Rich Execution Environment)和TEE(Trusted Execution Environment),也即非安全世界和安全世界。
3 TrustZone in the processor
3.1 安全状态
EL0、EL1、EL2都存在安全和非安全两种状态。EL3一直处于安全状态。
3.2 安全状态切换
无论从安全切换到非安全,还是非安全切换到安全都需要经过EL3。
如下从NS.EL1切换到S.EL1流程图:
- Rich OS通过FIQ或者SMC异常进入EL3。
- EL3中执行对应的异常处理函数,并进行SCR_EL3.NS位设置1->0;保存非安全寄存器状态;恢复安全寄存器状态。
- 从异常处理中退出并将CPU从EL3切换到S.EL1。
3.3 虚拟地址空间
TTBR是Translation Table Base Register的意思,
TTBR0_EL1/TTBR1_EL1:EL1 OS使用的用户转换页表基地址和内核转换页表基地址。
TTBR0_EL2/TTBR1_EL2:EL2 Hypervisor OS使用的转换页表基地址。
TTBR0_EL3:EL3仅有Stage 1转换页表基地址。
VTTBR_EL2:虚拟化场景下页表转换Stage 2基地址。
如下框图中系统存在多个虚拟地址空间:
- NS.EL0/1 Guest OS虚拟地址空间,使用Guest OS Tables,TTBRn_EL1;如果存在EL2,则需要NS.EL2 IPA地址空间,使用Virtualization Tables,VTTBR_EL2。
- NS.EL2 VMM虚拟地址空间,使用Hypervisor Tables,TTBR0_EL2。
- S.EL0/1TOS虚拟地址空间。
不同地址空间NS.EL1:0x8000和S.EL1:0x8000是两套独立的地址空间中地址,CPU在安全空间必须使用S.EL1页表转换,在非安全空间必须使用NS.EL1页表转换。
3.4 物理地址空间
物理地址空间分为两部分:安全和非安全。
在非安全世界,虚拟地址被转换到非安全物理地址。这意味着,非安全世界的软件仅能看到非安全资源。
在安全世界,软件可以访问所有非安全和安全物理地址空间。
3.5 数据、指令和缓存
3.6 TLB
3.7 SMC异常
执行SMC产生SMC异常进入EL3。SMC被用于从EL3 Firmware或者TEE中请求服务。SMC dispatcher将SMC请求发送给Firmware(PSCI)或者TOS处理。
3.8 安全虚拟化
直到ARMv8.3都没有支持S.EL2,EL3运行Firmware处理PSCI以及Secure Monitor。S.EL0/1运行TOS。
ARMv8.4开始增加了S.EL2,运行Secure Partition Manager。将Platform firmware工作移到S.EL1进行处理。
4 System architecture
一个基于TrustZone系统组成:
4.1 TrustZone相关IP
必选组件:
- AMBA3 AXI总线:安全机制基础设施。
- ARMv8A Core El2:虚拟安全和非安全核。
- TZASC(TrustZone Address Space Controller):将内存分成多个区域,每个区域可以单独配置为安全或非安全区域。只能用于内存设备,不能用于块设备。
- TZPC(TrustZone Protection Controller):根据需要控制外设安全特性。
可选组件:
- TZMA(TrusztZone Memory Adapter):将片上RAM和ROM分成不同安全和非安全区域。
- AXI-to-APB bridge:桥接APB总线,配合TZPC使APB总线外设支持TrustZone安全特性。
4.2 总线从设备:peripherals and memories
4.3 Enforcing isolation
主控告知访问权限,内存系统决定是否允许访问。
内存系统权限检查一般是通过互联总线。比如NIC-400可以设置如下属性:
- 安全:仅安全访问可以通过,互联总线对非安全访问产生异常,非安全访问不会抵达设备。
- 非安全:仅非安全访问可以通过,互联总线对安全访问产生异常,安全访问不会抵达设备。
- 启动可配置:系统初始化时可以配置设备为安全或非安全。默认是安全。
- TrustZone aware:互联总线允许所有访问通过,连接的设备自身负责隔离。
对于DDR,需要将整个区域划分为若干安全和非安全区域。通过TZASC可实现:
仅有安全访问可以配置TZASC的寄存器。比如TZC-400可以支持9个区域的配置。
4.4 总线主设备
A系列处理器都是TrustZone aware的,每次总线访问发送争取的安全状态。但还存在一些非处理器的总线主控,比如GPU、DMA等。
因此将总线主控分为两种:
- TrustZone aware:每次总线访问都能提供合适安全信息。
- Non-TrustZone aware:此类主设备访问总显示无法提供安全信息、或每次都是同样安全信息。
对于Non-Trusted-aware需要采取的措施有:
- 设计时固定地址:给设备固定的访问地址。
- 可配逻辑单元:为主设备访问添加安全信息逻辑单元。
- SMMU:对于一个可信主设备,SMMU可以向安全状态下的MMU一样处理。
4.5 R和M系列处理器安全
R和M系列处理器不支持两种安全状态,意味着他们无法控制可访问物理地址空间。
往往这些处理器仅需访问单一的物理地址空间。
大部分被配置成安全访问。
4.6 中断
GIC支持TrustZone,每个中断源,即GIC规格中的INTID,可被配置成如下一种中断组:
- Group 0:安全中断,即FIQ。
- Secure Group 1:安全中断,IRQ或者FIQ。
- Non-secure Group 1:非安全中断,IRQ或者FIQ。
可以通过GIC[D|R]_IGROUP[D|R]和GIC[D|R]_IGRPMODR<n>寄存器来配置中断类型。这些寄存器仅在安全状态下可配置。
安全中断仅能被安全访问修改;非安全总线访问读取安全中断寄存器返回全0。
EL3软件处理Group 0中断,Secure Group 1中断被S.EL1/2软件处理。
4.6 中断处理
处理器包括两种中断异常:IRQ和FIQ。
GIC产生何种中断异常取决于:中断所属中断组和处理器当前安全状态。
中断组 | 安全状态 | 中断异常类型 | 处理者 |
Group 0 | Secure | FIQ | EL3 Firmware |
Non-secure | |||
Secure Group 1 | Secure | IRQ | TOS |
Non-secure | FIQ | EL3 Firmware | |
Non-secure Group 1 | Secure | FIQ | EL3 Firmware |
Non-secure | IRQ | Linux |
如下图Non-secure和Secure各有一个IRQ vector,EL3有一个FIQ vector;并且SCR_EL3.FIQ=1、SCR_EL3.IRQ=0。左边中断表示发生在非安全世界,右边表示发生在安全世界。
- Group 0中断无论发生在Secure还是Non-secure,都产生FIQ,在EL3处理。
- Secure Group 1发生在Secure状态中断为IRQ,由S.EL1处理。
- Secure Group 1发生在Non-secure状态中断为FIQ,由EL3处理。
- Non-secure Group 1发生在Secure状态中断为FIQ,由EL3处理。
- Non-secure Group 1发生在Non-secure状态中断为IRQ,由NS.EL1处理。
4.7 调试、跟踪和调优
不同的用户有不同的调试需求,可以通过如下信号配置:
- DBGEN:顶层调试总开关,控制所有状态调试。
- SPIDEN:安全调试开关,控制安全状态调试。
三种使用场景:
- 芯片开发人员:DBGEN=1和SPIDEN=1,完全外部调试功能。
- OEM开发:DBGEN1但SPIDEN=0,仅可在非安全状态调试。
- 产品发布:DBGEN0和SPIDEN=0,禁止安全和非安全调试。应用程序仍可调试。
4.8 其他设备
一个实际TrustZone系统中还需要包括如下设备:
- OTP或者EFuses
- Non-volatile counter
- Trusted RAM和Trusted ROM
5 Software architecture
5.1 Top-level software architecture
一个典型的基于TrustZone系统软件调用栈关系图:
安全世界的Trusted OS提供一系列安全服务,比如key管理或DRM。非安全世界应用需要使用这些服务,但是又无法直接使用。通过使用一些库中API来获取这些能力,比如libDRM.so。
这些库和Trusted service之间通信往往通过message queue或者Mailbox。他们之间通信所用内存往往被称为WSM(World Shared Memory)。这些内存必须能够被Trusted service和库访问,这就意味着这些内存是非安全内存。
应用通过库发送一个请求到Mailbox或message queue,然后出发内核中TrustZone驱动。
TrustZone驱动负责和TEE部分交互,包括为message queue申请内存和注册这些内存。由于安全和非安全运行在两个虚拟地址空间,所以无法通过虚拟地址进行通信。
TrustZone驱动通过调用SMC进入安全状态,控制权通过EL3的Secure Monitor传递到TEE中的TOS。TOS从message queue内存中获取内容个Trusted service进行处理。
- Trusting the message:由于message是从非安全世界传递的,所以需要安全世界需要对这些内容进行一些认证。
- Scheduling:对于PSCI类型快速处理并且不频繁请求,进入EL3处理完后退出到非安全状态。对于一些需要TOS处理的任务,不能被非安全中断打断,避免造成安全服务不可用。
- OP-TEE:OP-TEE内核运行在S.EL1,可信应用运行在S.EL0。
非安全世界的App一般不直接使用TEE Client API,而是中间Service API提供一类服务。TEE Client API和内核中OP-TEE驱动交互,OP-TEE驱动SMC处理底层和OP-TEE内核的通信。
EL3 Firmware/Secure Monitor做SMC处理,根据需要将安全请求发送到OP-TEE内核处理。
5.2 和非安全虚拟化交互
对于一个虚拟化执行环境,SMC被用来访问Firmware函数和可信服务。但是虚拟机并不希望VM直接进行低功耗管理。
所以Hypervisor截获EL1发送的CMC,然后检查请求是给Firmware还是TrustedService的。如果请求是Firmware服务,那么Hypervisor模拟Firmware进行处理。对于TrustedService则转发给EL3进行处理。
5.3 启动和信任链
Boot ROM代码是系统启动后运行的第一份代码,比较小而简单,主要工作是从Flash中加载并验证二级启动代码。我们认为boot ROM代码是安全可信的。
二级启动代码进行平台系统初始化,比如初始化DDR控制器。并且进行加载和验证安全和非安全镜像,比如TEE或者UEFI/UBoot。
如果系统从小核SCP启动,启动流程图如下:
- 首先SCP从内部ROM启动。
- SCP加载镜像,启动A系列处理器。
- A系列处理器从外部Flash中读取二级启动镜像,并启动。
- 二级启动镜像加载TEE和UEFI。
5.4 启动失败措施
下面给出各阶段启动失败建议措施:
- 二级启动:如果验证失败,意味着启动不安全或者功能有误。这种错误是不允许的,停止启动进程。
- TEE:TEE失败表示,安全服务受限。非安全世界仍然可以使用。
- 非安全Firmware或Rich OS:允许启动,但是不允许使用TEE服务。
5.5 Trusted Firmware
Trusted Firmware提供了满足ARM安全规格的参考代码,包括TBBR(Trusted Board Boot Requirements)和SMCC。
SMC Dispatcher:处理非安全世界的SMC请求,决定哪些SMC由Trusted Firmware在EL3处理,哪些转发给TEE进行处理。
Trusted Firmware处理PSCI任务、或者SOC相关工作。
6. 实例介绍
6.1 加密文件系统
- 对用户进行认证后,加密后文件系统key被读到片内安全内存中,并使用存在OTP中的Private key对其进行解密和验证。
- 解密后的文件系统key被提供给加解密引擎寄存器或者存储控制器中。
- 后续对文件系统的存取使用写入的key进行加解密。
上述操作都是在安全状态进行的,所有文件系统key不会暴露给非安全软件。
6.2 OTA固件更新
主要流程如下:
- OEM厂家使用私钥对镜像进行签名。
- 镜像在非安全状态下被下载,并请求安全世界去安装固件。
- 安全世界中使用Public key hash校验Public key。
- 安全世界软件对镜像验签,至此表示镜像合法。
- 然后安全世界开始安装固件。
- 升级成功则递增non-volatile counter,可以检测到回滚操作。