TrustZone是ARM针对消费电子设备设计的一种硬件架构,其目的是为消费电子产品构建一个安全框架来抵御各种可能的攻击。TrustZone在概念上将SoC的硬件和软件资源划分为安全(Secure World)和非安全(Normal World)两个世界,所有需要保密的操作在安全世界执行(如指纹识别、密码处理、数据加解密、安全认证等),其余操作在非安全世界执行(如用户操作系统、各种应用程序等),安全世界和非安全世界通过一个名为Monitor Mode的模式进行转换。框架如下图所示:
处理器架构上,TrustZone将每个物理核虚拟为两个核,一个非安全核(Non-secure Core, NS Core),运行非安全世界的代码;和另一个安全核(Secure Core),运行安全世界的代码。非安全核只能看到非安全世界的系统资源。而安全核可以看到所有的系统资源。
两个虚拟的核以基于时间片的方式运行,根据需要实时占用物理核,并通过Monitor Mode在安全世界和非安全世界之间切换,类似同一CPU下的多应用程序环境,不同的是多应用程序环境下操作系统实现的是进程间切换,而Trustzone下的Monitor Mode实现了同一CPU上两个操作系统间的切换。
TrustZone总体上以AMBA3 AXI总线为基础,针对不同的应用场景设计了各种安全组件,芯片厂商根据具体的安全需求,选择不同的安全组件来构建他们的TrustZone实现。
其中主要的组件有:
必选组件:
AMBA3 AXI总线,安全机制的基础设施
虚拟化的ARM Core,虚拟安全和非安全核
TZPC (TrustZone Protection Controller),根据需要控制外设的安全特性
TZASC (TrustZone Address Space Controller),对内存进行安全和非安全区域划分和保护
可选组件:
TZMA (TrustZone Memory Adapter),片上ROM或RAM安全区域和非安全区域的划分和保护
AXI-to-APB bridge,桥接APB总线,配合TZPC使APB总线外设支持TrustZone安全特性
2.1总线设计TrustZone 在系统总线上针对每一个信道的读写增加了一个额外的控制信号位,这个控制位叫做Non-Secure或者NS位,是AMBA3 AXI总线针对TrustZone作出的最重要、最核心的扩展设计。
这个控制信号针对读和写分别叫做ARPORT[1]和AWPORT[1]:
ARPROT[1]: 用于读操作(Read transaction), 低表示Secure, 高表示Non-Secure
AWPROT[1]: 用于写操作(Write transaction), 低表示Secure,高表示Non-Secure
总线上的所有主设备(master)在发起新的操作(transaction)时会设置这些信号,总线或从设备(slave)上解析模块会对主设备发起的信号进行辨识,来确保主设备发起的操作在安全上没有违规。
例如:硬件设计上,所有非安全世界的主设备(Non-Secure masters)在操作时必须将信号的NS位置高,而NS位置高又使得其无法访问总线上安全世界的从设备(Secure Slaves),简单来说就是对非安全世界主设备发出的地址信号进行解码时在安全世界中找不到对应的从设备,从而导致操作失败。
2.2处理器设计
TrustZone中,每个物理处理器核被虚拟为一个安全核(Secure)和一个非安全核(Non-Secure),安全核运行安全世界的代码,非安全核运行除安全世界外的其它代码。由于安全世界和非安全世界的代码采用时间片机制轮流运行在同一个物理核上,相应的节省了一个物理处理器核
2.3中断模型设计
基于TrustZone的处理器有三套异常向量表:
一套用于非安全世界,
一套用于安全世界,
还有一套用于Monitor模式。
与之前非TrustZone的处理器不同的是,这三套中断向量表的基地址在运行时可以通过CP15的寄存器VBAR(Vector Base Address Register)进行修改。
复位时,安全世界的中断向量表由处理器的输入信号VINITHI决定,没有设置时为0x00000000,有设置时为0xFFFF0000;非安全世界和Monitor模式的中断向量表默认没有设置,需要通过软件设置后才能使用。
默认情况下,IRQ和FIQ异常发生后系统直接进入Monitor模式,由于IRQ是绝大多数环境下最常见的中断源,因此ARM建议配置IRQ作为非 安全世界的中断源,FIQ作为安全世界的中断源。
当处理器运行在非安全世界时,IRQ直接进入非安全世界的处理函数;如果处理器运行在安全世界,当IRQ发生时,会先进入到Monitor模式,然后跳到非安全世界的IRQ处理函数执行
将IRQ设置为非安全世界的中断源时系统IRQ的切换见下图:
2.4 系统模式的切换
基于TrustZone的系统有三种状态,安全世界、非安全世界和用于二者切换的Monitor Mode。
协处理器CP15的寄存器SCR(Secure Configuration Register)有一个NS位用于指示当前处理器位于哪一个世界,该寄存器在非安全世界是不能访问的。当CPU处于Monitor Mode时,无论NS位是0还是1,处理器都是在安全世界运行代码。因此Monitor Mode下总是安全世界,但如果此时NS为1,访问CP15的其它寄存器获取到的是其在非安全世界的值。
非安全世界到Monitor模式的切换
处理器从非安全世界进入Monitor Mode的操作由系统严格控制,而且所有这些操作在Monitor Mode看来都属于异常。
从非安全世界到Monitor Mode的操作可通过以下方式触发:
软件执行SMC (Secure Monitor Call)指令
硬件异常机制的一个子集(换而言之,并非所有硬件异常都可以触发进入Monitor Mode),包括:
IRQ
FIQ
external Data Abort
external Prefetch Abort
Monitor Mode内执行的代码依赖于具体的实现,其功能类似于进程切换,不同的是这里是不同模式间CPU状态切换。
软件在Monitor Mode下先保存当前世界的状态,然后恢复下一个世界的状态。操作完成后以从异常返回的方式开始运行下一个世界的代码。
为什么安全模式和非安全模式不能直接切换?
非安全世界无权访问CP15的SCR寄存器,所以无法通过设置NS来直接切换到安全世界,只能先转换到Monitor Mode,再到安全世界。
如果软件运行在安全世界(非Monitor Mode)下,通过将CP15的NS位置1,安全世界可以直接跳转到非安全世界,由于此时CPU的流水线和寄存器还遗留了安全世界的数据和设置,非安全模式下的应用可以获取到这些数据,会有极大的安全风险。因此,只建议在Monitor Mode下通过设置NS位来切换到非安全模式。
综上,安全世界和非安全世界不存在直接的切换,所有切换操作都通过Monitor Mode来执行。
下图展现了安全世界和非安全世界之间的切换方式:
2.5隔离机制
1) 内存隔离机制
这里的内存指外部的DDR和片上的ROM以及SRAM,其隔离和保护通过总线组件TZASC和TZMA的设置来实现。
TZASC (TrustZone Address Space Controller)
TZASC可以把外部DDR分成多个区域,每个区域可以单独配置为安全或非安全区域,非安全世界的代码和应用只能访问非安全区域。TZASC只能用于内存设备,不适合用于配置块设备,如Nand Flash。
TZMA (TrustZone Memory Adapter)
TZMA可以把片上ROM和SRAM隔离出安全和非安全区域。TZMA最大可以将片上存储的低2MB配置为安全区域,其余部分配置为非安全区域。大小划分上,片上安全区域可以在芯片出厂前设置为固定大小,或运行时通过TZPC动态配置。TZMA使用上有些限制,其不适用于外部内存划分,而且也只能配置一个安全区域。
在外设上,基于APB总线的设备不支持AXI总线的NS控制信号,所以AXI到APB总线需要AXI-to-APB bridge设备连接,除此之外,还需要TZPC (TrustZone Protection Controller) 来向APB总线上的设备提供类似AXI上的NS控制信号。
由于TZPC可以在运行时动态设置,这就决定了外设的安全特性是动态变化的,例如键盘平时可以作为非安全的输入设备,在输入密码时可以配置为安全设备,只允许安全世界访问。
整个系统内存和外设隔离机制示意图
AMBA3 AXI总线机制隔离出安全世界和非安全世界,但这是系统启动之后的事情。如何确保系统本身是安全的呢?这就涉及到系统启动的过程。
系统上电复位后,先从安全世界开始执行。安全世界会对非安全世界的bootloader进行验证,确保非安全世界执行的代码经过授权而没有被篡改过。然后非安全世界的bootloader会验证校验加载非安全世界的OS,完成整个系统的启动。
安全引导方案将密码检查添加到安全世界引导的每个阶段。这个过程的目的是维护所有安全软件镜像的完整性执行,以防止任何未经授权或恶意修改软件运行。
3.1 Cryptographic signature protocol(加密签名协议)
大多数加密协议的应用是基于公钥签名的协议算法,如RSA-PSS (Rivest, Shamir和Adleman )。在这些协议中,受信任的供应商使用它们的私钥(PrK)生成他们希望部署的代码签名,并将其与软件一起推送到设备上二进制文件。设备包含供应商的公钥(PuK),可用验证二进制文件没有被修改,并且它是由受信任的供应商来提供。PuK不需要保密,但需要以某种方式存储在设备中。这就意味着它不能被攻击者的PUK代替。
3.2 Chain of trust(信任链)
安全引导过程实现了信任链,用一个隐式的信任组件启动。每个其他组件都可以在执行之前进行身份验证。信任链所有权可以在每个阶段发生变化,属于设备OEM商的PUK可能用于对第一个引导加载程序进行身份验证。但是,安全世界的二进制镜像可能包含了第二个用于认证要加载的应用的PUK。做为信任的根,必须位于SoC ROM中。SoC ROM
是系统中唯一不能被轻易修改和替代的组件。存储用于信任根的PuK可能会有问题,将其嵌入到on-SoC 的ROM中意味着所有设备使用相同的PuK,这个可能是脆弱的对于class-break attacks攻击,如果Prk 被偷或者被成功的逆向破解。SOC上的OTP(One-Time-Programmable)硬件,可以被用于存储独一无二的值在每个SOC设备生产期间。这使得一些不同的PuK值存储在单个类设备中,降低了class break attacks风险攻击。
Note:
OTP存储器可能消耗相当多的硅面积,因此存储的位数就是有限的。RSA PuK 超过1024个比特位。这对于OTP存储来说太大。然而,PUK通常不是保密的它可以被存储在off-SoC中。可以提供一个PUK加密过的哈希值存储到on-SoC的OTP中。哈希值(通常256个比特)比PUK本身要小的多。并且可以在运行期间认证PUK的值。
3.3 On-SoC Secure world or Off-SoC Secure world
最简单的防御shack attacks攻击的手段是让安全世界的资源在on-SOC内存中运行。如果代码和数据从来不暴露在SOC包的外部,那么修改和窥探数据的值将变的非常困难。一个物理攻击在SOC包中是更困难的比连接一个逻辑探头到PCB板的某个引脚。安全引导代码通常负责加载代码到on-SoC 内存中。它是至关重要的对于认证的顺序来避免给攻击者提供一个打开窗口的机会。假设运行代码和所需的加密哈希已经处于安全的on-SoC内存中,在用加密的方式被认证之前,二进制镜像或者PUK 被校验应该拷贝到一个安全的地方。攻击者可以修改镜像当拷贝开始到完成的这个时间窗口内。