ARMv8-A 系统中的安全
一个安全或可信的操作系统保护着系统中敏感的信息,例如,可以保护用户存储的密码,信用卡等认证信息免受攻击。
安全由以下原则定义:
保密性:保护设备上的敏感信息,防止未经授权的访问。有以下几种方法可以做到,比如密码和加密密钥。
完整性:使用公钥来保护敏感信息防止被修改。
可用性:确保对敏感信息的访问一定是经过授权的,利用固件更新来检测未经授权的访问。
举一个生活中的例子,可信系统存储了移动支付的密码,数字证书等。在开放的系统中,很难实现绝对安全,因为用户可能会下载各种各样的软件到移动设备上,同时也会下载一些恶意代码,这可能会篡改你的系统。
软件和硬件攻击可分为以下几类:
软件攻击:恶意软件攻击通常不需要访问实际的设备,可以利用操作系统或应用程序的漏洞实现远程攻击。
简单的硬件攻击:硬件攻击大部分是非破坏性的攻击,需要拿到实际的物理设备,并使用常见的工具,例如jtag和逻辑探针。
专业的硬件攻击:这种攻击需要复杂而昂贵的工具,如聚焦离子束(FIB)技术或功率分析技术,而且更常用于对付智能卡设备。
TrustZone技术就是专门用来对抗软件攻击的。TrustZone也可以抵御一些简单的硬件攻击。
TrustZone的硬件架构
TrustZone架构为系统设计者提供了一种帮助保护系统的方法。即使是低级别的程序员也应该理解TrustZone的架构设计。
ARM 安全扩展模型允许系统开发人员对硬件设备和软件资源进行分区,以便他们既可以存在于安全子系统的Secure world,也可以存在于其他子系统的Normal world。
ARM 手册中使用 Secure World 和 Non-secure World来指示系统的安全状态。Non-secure World并不意味着有安全漏洞,而是指正常运行的系统,即Normal world。通常情况下,Secure World 和 Non-secure World存在着主从关系。Secure World 的代码只有操作系统通过SMC(Secure Monitor Call )指令调用才可以执行。
Non-secure World 的内存和功能也可以被Secure World 访问
Secure monitor 管理着Secure World 和Non-secure World的切换,类似于操作系统中的上下文环境。确保离开Secure World 时 当前环境被完整保存下来,当处理器再次切换到Secure World 时可以被正确 恢复。
TrustZone是对ARM架构的补充扩展,这意味着一个处理器可以同时运行Secure World 和Non-secure World的代码。如果Secure World 配置了中断外设可用,那么Secure World 和Non-secure World 的代码可以相互调用。
Secure monitor提供了Secure World 和Non-secure World的接口。出于程序的健壮性考虑, Secure monitor的代码应该在禁用中断的上下文执行。编写一个可重入的 Secure monitor会很复杂,而且并不会带来太多的好处。
另外,Secure World 和Non-secure World 程序的执行也可以像操作系统那样执行多任务并行。虽然Secure World 的程序执行时可访问的资源是完全独立于Non-secure World 的,但是两个世界也可以互相让步,以实现多任务并行的效果。
像固件或任何其他系统软件一样,Secure World 的软件必须尽量减少对系统其他部分的影响。例如,Secure World的 代码执行时应避免消耗大量的时间。Non-secure World 中的中断应尽可能快的传递给Normal World,这有助于确保Normal World软件良好的响应性。
内存系统由一个额外的位来划分,这个位叫做NS位。它表示访问的内存是Secure World 还是Non-secure World 。这个位被添加到所有内存系统事务中,包括高速缓存标签和对系统内存和外设的访问。NS位可以为Secure World和Non-secure World 提供不同的物理地址空间。
在Normal World 中运行的软件只能对内存进行Non-secure 的访问。因为在由Normal World产生 的内存事务中,总是把NS位设置为1,而不考虑Normal World 中翻译表中的设置。在Secure World 中运行的软件只进行Secure 的内存访问,但也可以使用翻译表中的NS和NSTable标志对特定的内存进行Non-secure 的访问。
如果对标记为安全的缓存数据进行非安全访问会导致缓存缺失。如果对标记为安全的外部存储器进行非安全访问,通常会向内核返回一个错误响应。
EL3有自己的翻译表,由TTBR0_EL3(Translation Table Base Register )和TCR_EL3(Translation Control Register ) 管理。在安全状态下,只允许stage 1的翻译,没有TTBR1_EL3寄存器。EL1翻译表寄存器在安全状态之间不会被存储,因此TTBR0_EL1、TTBR1_EL1和TCR_EL1的值必须作为Secure monitor上下文切换操作的一部分为每个世界保存和恢复。
这就使得每个世界都有一套本地的转换表。Secure World的映射会被隐藏起来,并受到Normal World 的保护。Secure World 翻译表中包括NS和NSTable位,这决定了是否可以对Secure World 和 Non-secure World的物理地址空间。
Secure 和 Non-secure 的entries 可以在缓存和TLB中共存。在不同的世界之间切换时,缓存不会失效。Normal World只能进行 Non-secure的访问,所以只能命中标记为 Non-secure 的缓存。而Secure World可以产生Secure 和 Non-secure的访问,如果安全状态在访问时发生变化,可能还会有缓存管理。
TLB中的entries 记录了是由那个世界产生的entries 。尽管Non-secure状态永远不能对Secure 的数据进行操作,但Secure World 可以将NS行分配到缓冲区。另外,缓存的启用和禁用在每个异常级别都是不同的。缓存控制对于两个世界来说都是独立的,但对所有的异常级别来说并不是独立的。所以,EL0不能直接启用或禁用缓存,而EL2可以覆盖Non-secure EL1的行为。
Secure World和Non-secure World 的交互
如果你在包含安全服务的系统中编写代码,了解Secure World和Non-secure World 的交互方式对你很有用。一个典型的操作系统都会包含一个轻量的内核或者可信执行环境(TEE)。例如,在Secure World运行加密服务。它可以与Normal World 中的操作系统进行交互,Normal World 可以通过SMC调用访问Secure World。通过这种方式,Normal World 既可以访问Secure World,又不会担心暴露加密的密钥。
一般来讲,开发人员不会与安全扩展组件,TEE,或者可信服务直接交互,而是通过Normal world 提供的API(例如authenticate())访问Secure World。
下图以应用程序调用API的形式展示了Normal world 和Secure World 的交互。API通过系统调用到TrustZone Driver,然后经过 Secure monitor传递给TEE。
这种调用方式会在Secure World和Normal World间频繁传递数据。
例如,在 Secure world 中有一个签名检查器。Normal world可以请求Secure World使用SMC调用来验证下载更新的签名。如果Secure World需要访问Normal world所使用的内存,Secure World可以使用其翻译表描述符中的NS位,以确保它使用Non-secure方式访问来读取数据。
这一点很重要,因为与请求数据相关的内容可能已经在缓存中了,因为Secure World执行的访问都会标记为Non-secure的地址。安全属性可以被认为是一个额外的地址位。如果内核使用安全内存访问来尝试读取数据,它就不会命中已经在缓存中的Non-secure数据。
如果你是一个平时只会和Normal world打交道的程序员,你可以忽略Secure World中发生的事情,因为它的操作对你来说是隐藏的。一个副作用是,中断延迟可能会略有增加。Secure World可以是完全阻塞的,所以如果一个中断发生Secure World中时,这可能会阻塞Normal world的中断。但与一般操作系统的整体延迟相比,可以忽略不计。这种问题给Normal world带来的影响取决于Secure World操作系统的架构设计。
Secure 和Normal worlds 的切换
在ARMv7的安全扩展中,软件使用Monitor mode在Secure 和Non-secure state切换。该模式和Secure state 中其他特权模式是一样的。在ARMv8-A处理器中,AArch32相当于ARMv7-A。
对于ARMv8架构,当EL3使用AArch32时,ARMv8架构相当于ARMv7,以确保完全兼容,安全状态下的所有特权模式被视为处于EL3。
AArch32的安全模型如下图所示。在这种情况下,EL3是AArch32,以提供一个安全的操作系统和监视器。
下图显示了当EL3执行AArch64以提供安全监视器时的安全模型。EL1用于安全操作系统。当EL3使用AArch64时,EL3被用来执行负责在Non-secure state和Secure state之间切换的代码。
为了与AArch32保持一致,Secure state的EL1和EL0具有和Non-secure state的EL1和EL0不同的虚拟地址空间。这使得AArch32 32位架构的运行在Secure state的代码可以在Non-secure state运行的64位操作系统中使用。
当Normal World 执行停止而Secure World的执行开始时,通过执行 Secure Monitor(SMC)指令或通过硬件异常机制(如中断或异步中止)在它们之间进行上下文切换。ARM处理器有两种中断类型:FIQ和IRQ。
在Secure World中也是支持中断的,其原理是将Secure World产生的中断重定向到EL3,并且 和当前的DAIF 字段无关。然而,这些控制只区分了主要的中断类型。IRQ, FIQ, and asynchronous aborts。更详细的控制需要将中断分为 Secure 和Non-secure组。如果要做到这一点,需要GIC的支持,在GIC中有一些特性来支持划分为不同的组。
一个典型的例子是FIQ被用作Secure interrupts,通过在中断控制器内将安全中断源映射为FIQ。同时,相关的外设和中断控制器寄存器必须被标记为只能被安全访问,以防止Normal World重新配置这些中断。
使用安全扩展的实现通常有一个轻量级的可信内核,在Secure World中托管安全服务(例如加密)。一个完整的操作系统在Normal World中运行,并能够使用SMC指令访问安全服务。通过这种方式,Normal World可以访问服务功能,在普通世界中执行的任意代码不会有敏感数据暴露的风险。
集群中的安全问题
集群系统中的每个内核都具有相同的安全特性。集群中任何数量的核心都可以在任何时间点上在Secure World中执行,并且核心能够在世界之间独立过渡。寄存器控制Normal World代码是否可以修改Snoop控制单元(SCU)的设置。同样,在整个集群中分配优先级中断的GIC必须被配置为安全状态。
安全系统还控制调试规定的可用性。你可以为 Normal worlds 和Secure worlds配置独立的硬件调试,如JTAG调试和跟踪控制,这样就不会有关于受信任系统的信息泄露了。你可以通过一个安全外设来控制硬件配置选项,或者你可以硬件连接它们,并使用以下信号来控制它们。
• Secure Privileged Invasive Debug Enable (SPIDEN): JTAG debug.
• Secure Privileged Non-Invasive Debug Enable (SPNIDEN): Trace and Performance Monitor.
总结
TrustZone 是ARM 架构的一个安全扩展模型,可以用在任何ARM处理器中。
Normal world 通过SMC指令访问Secure world。Secure monitor 管理着Normal World和Secure World 的切换。Secure monitor 的代码在禁用中断的上下文执行。
内存系统事务中的NS位表示访问的是Secure World 的内存还是Normal World的内存。Normal World只能对内存进行非安全访问,Secure World 既可以进行安全访问,也可以进行非安全访问,只需要更改NS位即可。
Secure World的翻译表和Non-Secure World的翻译表是独立的,Secure World的翻译表受到Normal World的保护。
ARMv8-A 可以兼容32位和64位TrustZone。当ARMv8-A运行AArch32 TrustZone 时,相当于ARMv7-A。二者区别主要在于EL3的不同,ARMv7-A中EL3 提供Secure Monitor 和Srcure OS,而ARMV8 中,EL3只提供Secure Monitor 。
本文参考
security_in_an_armv8_system_100935_0100_en