[armv8-m] TrustZone Tech Overview
carloscn opened this issue · 0 comments
本文不涉及Trustzone的技术实现,根据Trustzone的设计讲述Trustzone的技术背景、技术概述和技术应用。
在Trustzone的技术背景中,我们阐述为什么要使用Trustzone技术;在技术概述中主要讲述Trustzone最基本的设计模型以及和Cortex-A的Trustzone的异同;技术应用中主要讲述基于Trustzone我们能做什么丰富的应用。
1. Trustzone技术背景
如果你是关心安全的开发者,我相信拿到armv8-m的架构肯定会问,armv8-m从芯片层级考虑安全的话,肯定首要是trustzone的技术,那么armv8-m的trustzone技术到底怎么考察安全性:
- 内存隔离
- 跳转安全state限制
- 预防SG指令的滥用(Inadvertent SG instruction in binary data)
- 虚假的函数和异常返回值的状态
- 预防在secure内存中的溢出问题
- 调试的权限管理设计
1.1 内存隔离
将内存分为安全内存和非安全内存是TrustZone的一项重要特性,其主要目的包括:
- 隔离敏感数据: TrustZone允许将敏感数据存储在安全内存中,而将非敏感数据存储在非安全内存中。这样,敏感数据在处理器的安全区域内受到保护,不容易被恶意软件或非授权的应用程序访问和泄露。
- 执行安全代码: 安全内存还用于存储安全性相关的代码,如加密和认证算法,以及安全启动代码。这些代码在非安全内存中不可见,从而提供了一种方式来执行和保护安全关键操作。
- 隔离不受信任的应用: 非安全内存用于存储不受信任的应用程序和操作系统组件。TrustZone通过硬件隔离确保这些应用程序和组件无法直接访问安全内存中的敏感数据或安全代码。
- 防止侧信道攻击: 通过将安全内存隔离,TrustZone有助于防止侧信道攻击,如缓存侧信道攻击和时序侧信道攻击,因为非安全的应用程序无法直接观察或干扰安全内存中的操作。
- 提供硬件支持: TrustZone利用ARM处理器的硬件支持,确保内存分区的强制执行。这是硬件级别的隔离,不容易被绕过。
1.2 跳转安全state限制
在ARM TrustZone环境中,SG指令和NSC内存属性的设计确保非安全态(Non-secure)到安全态(Secure)的分支(branch)只能在有效的入口点(valid entry points)上发生,从而限制和控制了跨越TrustZone边界的跳转。我们拆分这几个概念:
-
SG指令(Secure Gateway Instruction): SG指令是用于在Non-secure态切换到Secure态的特殊指令。这个指令只能被受信任的代码和服务调用,并通常用于安全的上下文切换。SG指令的设计确保只有在受信任的入口点处才能执行此指令,防止非安全代码随意切换到安全态。
-
NSC内存属性(Non-Secure Callable Memory Attribute): NSC内存是指在ARM TrustZone中用于存储非安全态代码和数据的内存区域。NSC内存属性是一种标记或属性,用于标识哪些内存区域包含非安全代码。这些内存区域只能包含在受信任的入口点处执行的代码。
-
有效的入口点(Valid Entry Points): 有效的入口点指的是那些受信任的、经过验证和授权的位置,这些位置是允许进行从Non-secure到Secure态的切换的地方。这些入口点通常包括受信任的启动代码、安全服务或受信任的应用程序。
因此,SG指令和NSC内存属性的设计确保非安全态到安全态的分支只能在经过验证的、受信任的入口点上执行。这就限制了从非安全环境到安全环境的跳转,只有在确保受信任的方式下才能进行。这有助于确保TrustZone的安全隔离得到维护,防止不受信任的代码或操作绕过安全性控制。这是TrustZone的一项关键安全特性,有助于确保安全的上下文切换和安全的代码执行。
1.3 预防SG指令的滥用
上面介绍SG指令是用于在Non-secure态切换到Secure态的特殊指令,如果SG指令被滥用可能会造成安全问题。在二进制数据中(通常是在应用程序或固件的二进制代码中),可能会不经意地包含了SG(Secure Gateway)指令,这个不经意的行为导致,在TrustZone环境中从Non-Secure State(非安全态)切换到Secure State(安全态),并执行安全代码(视为严重的安全问题)。这意味着非受信任的代码或应用程序可能尝试执行这个指令,试图切换到Secure State,从而干扰或绕过TrustZone的安全隔离。
通常,不经意的SG指令可能是由于编译器错误、代码混淆问题或其他不当的操作而引入的。为了确保系统的安全性,需要定期审查二进制数据,以检测并纠正这类问题。此外,ARM TrustZone的设计要求在硬件和软件层面都要有正确的配置和实施,以确保不经意的SG指令不会引发安全风险。其中NSC内存属性就是一个重要的检测机制,在执行前会进行NSC内存属性检查,以确保在非安全区域调用了SG指令是真实有效的指令。
ARM TrustZone设计中,检测SG(Secure Gateway)指令没有被滥用是通过硬件和软件协同来实现的,以确保指令的正确用途和限制不被滥用。以下是一些方法和机制来检测SG指令没有被滥用:
-
硬件级别的权限控制: ARM TrustZone支持硬件级别的权限控制,其中访问Secure态的代码和资源必须经过硬件授权。这包括对SG指令的执行权限。硬件会验证是否允许执行SG指令,如果没有正确的权限,将不允许执行。
-
受信任的入口点: SG指令只能在受信任的入口点处执行。这些入口点通常由受信任的启动代码、安全服务或受信任的应用程序提供。硬件确保SG指令只在这些合法的入口点处执行,以防止滥用。
-
硬件栈保护: ARM TrustZone可以通过硬件栈保护措施来确保在切换到Secure态时保护堆栈的一致性和完整性,防止栈溢出等问题。
这些机制和方法结合起来确保了SG指令不会被滥用。通过硬件和软件的协同工作,ARM TrustZone提供了一个严格的安全框架,以保护敏感的安全操作和数据。这有助于防止非受信任的代码或操作绕过TrustZone的安全隔离。
当然ARM还做了一些其他的操作,例如,对于函数返回值及状态用一些虚假值来替换,一方面隐藏了非安全视角调用过程的追踪,一方面一定程度上还检测了SG指令的滥用。
1.4 伪造返回地址
"Faking of a return address when calling a Secure API" 意味着当在调用一个安全API(Application Programming Interface,应用程序编程接口)时,存在可能伪造返回地址的风险。这个问题涉及到在ARM TrustZone环境中的一个安全性问题,通常与栈溢出或函数调用相关。
- 安全API调用: 在ARM TrustZone环境中,安全API通常是由安全的代码提供的,用于执行敏感操作或提供受保护的服务。这些API允许非安全环境的代码(Non-Secure World)请求安全环境(Secure World)执行某些操作。
- 返回地址: 在函数调用中,返回地址是在函数调用之后控制流将返回的位置。与ARMv7m一致,ARMv8m中procedure call中返回地址, 02_ARMv7-M_编程模型与模式 存储在R14-link register(LR) 寄存器中。而ARMv8m考虑安全问题,SG指令执行时的返回状态存储: 当SG指令在执行时,它会将函数的返回状态存储在链接寄存器(Link Register,LR)的最低有效位(Least Significant Bit,LSB)中。这个返回状态通常是一个标志位,用于指示函数是从安全态还是非安全态被调用的。当函数返回时,系统会检查LR中的最低有效位,以验证函数是否按照预期的状态返回。这个检查是为了确保Secure API函数(通常是从Non-Secure环境调用的)不会返回到一个伪造的返回地址,该地址指向Secure环境中的代码。
- 伪造返回地址: "Faking of a return address" 意味着攻击者可能尝试伪造或篡改在调用安全API时存储在栈上的返回地址。这可能导致控制流在不受信任的位置上恢复执行,而不是按照正常的执行流程返回到调用者所期望的位置。ARMv8m通过在LR中存储返回状态,并在返回时检查它,系统可以确保Secure API函数不会被诱导返回到一个伪造的地址,该地址可能包含恶意代码或试图绕过TrustZone的安全隔离的代码。
这种设计也是有考虑的,例如x86架构把指令的返回地址要放在栈上,而不是单独弄个寄存器。
x86/x64 cpu里确实有一个return stack buffer, 不过对汇编指令不可见,用来做跳转预测,长度有限(我看过一些架构的白皮书,好像通常是16个?),线程调用栈超过了长度就会导致预测失败(正常情况下,绝大部分预测都很准的)。intel/amd在很早的架构里就实现了这个优化的,arm也有类似的实现。
intel最新的一轮漏洞和这个有关系 Post-barrier Return Stack Buffer Predictions / CVE-2022-26373 /...
这样会把地址存储在这个问题的出现通常涉及到栈溢出攻击或其他安全漏洞,其中攻击者试图修改栈上的数据,包括返回地址,以便执行恶意代码或绕过TrustZone的安全隔离。
为了防止这种问题,ARM TrustZone的设计通常包括硬件和软件的措施:
- 硬件栈保护:硬件可以实施栈保护机制,以确保栈上的数据不易被篡改,从而保护返回地址。
- 栈溢出检测:软件可以实施栈溢出检测机制,以捕获和报告任何栈溢出事件。
- 权限控制:只有具有适当权限的代码才能调用安全API,这有助于确保只有受信任的代码能够访问并修改返回地址。
1.5 使用FNC_RETURN机制获取地址从而控制代码执行路径
ARMv7架构没有FNC_RETURN机制,这部分是ARMv8-M新引入的机制。
"Attempting to switch to the Secure side using FNC_RETURN (function return code)" 意味着尝试使用FNC_RETURN(函数返回代码)来切换到安全环境的行为。这个问题涉及到ARM TrustZone中的一个安全性问题,其中FNC_RETURN通常用于函数返回并控制执行流。
- FNC_RETURN(函数返回代码): FNC_RETURN通常是一个用于在函数返回时设置返回状态的代码或值。它指示函数应该如何返回,并在返回后控制执行流。
- 尝试切换到安全环境: "Attempting to switch to the Secure side" 意味着在函数返回时,有尝试将执行流从非安全态(Non-Secure World)切换到安全态(Secure World)的行为。这通常是通过函数返回的方式来实现的,以控制执行流程。
ret = non_secure_call_api(xxx); // FNC_RETURN 可以读取寄存器的值,如果正常ret返回的值是0那么进入非安全的一个分支(预期)。但是攻击者通过修改FNC_RETURN让函数进入do_secure_functions()的函数,那么处理器进入到安全状态,达到攻击者的要求。
if (ret == 0) {
do_non_secure_function();
} else {
do_secure_functions();
}
这个问题可能涉及到尝试滥用FNC_RETURN来实现非受信任代码或非受信任环境试图切换到安全环境的情况。这种行为可能导致绕过TrustZone的安全隔离,从而引发安全风险。为了防止这种问题,ARM TrustZone通常实施了硬件和软件的安全措施:
使用BLXNS指令来确保存在有效的返回堆栈,并防止恶意的非安全代码尝试使用FNC_RETURN机制切换处理器到安全代码,从而导致安全软件崩溃。使用BLXNS指令: 是为了在从不可返回的安全代码切换到非安全环境时确保安全性。这个指令用于切换到非安全态,并确保存在有效的返回堆栈。这个返回堆栈可以在需要时用于进入错误处理程序。相当于ARM多了一道检查。我们可以这么理解,从软件角度,我们只能使用ret == xxx
的方式来检查返回值,但是C语言提取ret的之前,这部分是从LR中拿到的值,可能已经被攻击者修改了。而执行BLXNS指令时,硬件会自动被LR给入栈到安全世界的MSP或者PSP堆栈中,然后被FUC_RETURN赋值给LR,传递到非安全世界。那么这样,非安全世界,既看不到刚才安全世界执行时通用寄存器的值,也看不到从自己这里返回后,安全世界下面要执行的指令的地址,接着安全世界从MSP或PSP堆栈中继续执行。非安全世界里的代码执行完成后,返回安全世界,使用的跳转指令是普通的BX,目标地址是FNC_RETURN。硬件识别到这个动作后,会自动从安全世界的堆栈,把真正的LR赋值给到PC值,然后软件再从安全堆栈里恢复之前用到的通用寄存器值,继续往下执行。
从非安全世界,调用安全世界的代码,无需软件和硬件做太多事情,因为非安全世界,没有什么秘密的上下文,需要对安全世界隐瞒的。直接按照TZ架里要求的跳转到NSC,non-secure callabler区域,先执行一条SG指令,再执行其后的跳转指令,到S区域里函数实现的地方去执行就可以了。从非安全世界带来的LR,在安全世界仍然可见;并且在返回时,赋值给PC来做跳转回非安全世界1。
1.6 假的异常EXC_RETURN
ARMv7架构原本就有EXC_RETURN这个机制,是异常返回后的地址信息。
"Faking of EXC_RETURN (exception return code) to return to Secure state illegally" 意味着尝试伪造EXC_RETURN(异常返回代码)以非法返回到安全状态。这个问题涉及到ARM TrustZone中的一个安全性问题,其中EXC_RETURN通常用于控制从异常处理程序返回到不同的执行状态。
- EXC_RETURN(异常返回代码): EXC_RETURN是一个特殊的值,通常在异常处理程序中使用,以指示异常处理程序应该如何返回到不同的执行状态。这个值包括信息,例如返回到异常处理程序的地址、控制模式和堆栈状态等。
- 非法返回到安全状态: "return to Secure state illegally" 意味着尝试从非安全状态返回到安全状态,而这个操作是未经授权的或非法的。在ARM TrustZone中,安全状态和非安全状态应该受到明确的控制和隔离,不应该随意切换或返回。
这个问题可能涉及到尝试滥用EXC_RETURN值以非法方式返回到安全状态的情况,而这可能导致绕过TrustZone的安全隔离,从而引发安全风险。
为了防止这种问题,ARM TrustZone通常实施了硬件和软件的安全措施:
- 非安全中断的发生: 当安全代码正在执行时,如果发生了一个非安全中断,处理器会自动将一个签名值(signature value)添加到当前的安全栈帧中。
- 安全栈帧签名: 这个签名值是一个安全栈帧的一部分,用于标识栈帧是否已被修改或干扰。签名值的生成通常基于栈帧的内容,包括返回地址和其他关键信息。
- 异常返回时的签名检查: 当非安全软件试图使用异常返回(exception return)指令来切换到安全环境时,处理器会执行签名检查。它将检查安全栈帧中的签名值是否与栈帧内容一致,以确保栈帧未被篡改。
- 检测非法切换: 如果签名检查失败,即签名值与栈帧内容不匹配,处理器将检测到非法切换尝试,因为非安全软件试图非法切换到安全环境。这将触发错误处理或其他相应的安全措施。
总之,这个机制通过在非安全中断期间添加签名值到安全栈帧,并在异常返回时执行签名检查,帮助检测非安全软件试图非法切换到安全环境的行为。这有助于维护ARM TrustZone的安全性,确保只有受信任的代码能够执行和返回到安全环境。
这部分可以参考:https://www.sciencedirect.com/topics/engineering/secure-stack
1.7 堆栈溢出
"Attempt to create stack overflow in Secure software" 意味着尝试在安全软件中创建堆栈溢出。堆栈溢出是一种常见的安全漏洞,通常涉及到在程序的执行期间,将过多的数据写入堆栈(stack)中,导致溢出并可能覆盖了堆栈中存储的关键数据或控制信息。
在ARM TrustZone或任何其他安全架构中,安全软件的堆栈安全性至关重要。堆栈溢出可能导致以下问题:
- 破坏程序的完整性: 堆栈溢出可以导致程序的崩溃或异常终止,从而破坏了程序的完整性。
- 潜在的安全风险: 如果堆栈溢出覆盖了存储在堆栈上的关键数据,可能会导致潜在的安全风险,如信息泄露、远程代码执行或拒绝服务攻击。
- 绕过安全隔离: 在安全架构中,堆栈溢出可能被攻击者用来绕过安全隔离,使得恶意代码能够进入安全环境。
关于ARMv8-M主流和基线子配置中的Secure堆栈指针的堆栈限制特性,以及对于堆栈溢出的处理。具体来说:
- Secure堆栈指针的堆栈限制: 在ARMv8-M主流和基线子配置中,实施了针对Secure堆栈指针的堆栈限制特性。这意味着系统可以检测和处理Secure堆栈的溢出情况。当Secure堆栈达到其限制时,会引发堆栈溢出异常。
- 异常处理程序: 当堆栈溢出异常发生时,异常处理程序会被触发,以确保适当的处理。这可能包括记录异常、中断执行流程并采取必要的纠正措施,以维护系统的安全性。
- 调试方面的安全性: 这段描述还提到了在调试方面处理安全性要求。这可能包括确保调试工具和过程不会威胁系统的安全性,或者确保调试过程受到适当的安全控制和监控。
2. Trustzone技术概述
Trustzone对于ARMv8m是一个可选的安全扩展。从应用角度,trustzone并不是一个新东西,和cortex-a中trustzone目的和作用是一致的。在和A核的trustzone设计上一样,处理器有安全和非安全两种状态,非安全的状态仅可以访问非安全的内存,而安全状态具有最高权限,无论是安全还是非安全的内存都可以访问。
相比于ARMv8-A的Trustzone,ARMv8-M TrustZone技术针对ARMv8-M架构设计,考虑了小型、能效高的系统的需求。这意味着TrustZone技术在设计上注重在能耗较低的嵌入式系统中实现安全性,以满足各种小型设备和资源有限的应用场景的需求。
在ARM Cortex-A处理器中,TrustZone技术使用内存映射方式来实现Secure和Normal两个世界的分割。这意味着在内存映射中存在Secure世界和Normal世界的不同地址空间,用于存储相应的数据和代码。这种方式允许对两个世界进行物理分割,从而实现安全隔离;在Cortex-A处理器中,当发生异常时,如中断或陷阱,TrustZone技术会自动进行Secure和Normal两个世界之间的切换。这意味着当从Normal世界进入Secure世界或反之时,处理器会自动调用相应的异常处理代码,而不需要显式的切换指令。
这种方式与ARMv8-M架构中的TrustZone技术有所不同,后者通常使用特殊的指令(SG)来执行Secure和Non-Secure之间的切换,而不依赖于内存映射方式。
而且在M核心中,在执行安全函数(Secure function)时,仍然可以为非安全中断(Non-secure interrupts)提供服务。这意味着当处理器处于安全执行状态时,它仍然能够响应和处理非安全中断,确保系统的可靠性和响应性。这一特性对于ARM TrustZone技术的实际应用非常重要,因为它允许系统在执行安全操作的同时,仍然能够处理来自非安全环境的中断请求。在许多微控制器应用中,实时处理、确定性行为和低中断延迟是重要的要求。这对于确保系统实时性至关重要。安全操作可以包括处理安全数据、密钥管理、加密和其他关键的安全任务,而非安全中断可能包括用户应用程序的请求、外部设备的事件等。
ARMv8-M架构引入了一种机制,允许在安全状态(Secure state)和非安全状态(Non-secure state)之间共享寄存器组。这种机制的好处在于能够实现更高的功耗效率,使得ARMv8-M实现的功耗水平接近较早版本的ARM架构,如ARMv6-M和ARMv7-M。
由于ARMv8-M架构中状态切换的低开销,Secure(安全)和Non-secure(非安全)软件能够频繁地进行互动。这在一些应用场景中非常常见,特别是当安全固件包含了软件库,如图形用户界面(GUI)固件或通信协议栈。在这些情况下,状态切换的低开销非常重要,因为它允许安全和非安全软件之间快速切换和互动,同时保持系统的安全性。这有助于实现复杂的功能,如图形界面和通信,而不会引入过多的性能开销。
ARMv8-M的安全、非安全以及Thread和Handler模式是正交(orthogonal)的关系。(v8架构中Thread模式也有特权和非特权模式)。
Trustzone被启动的时候,系统默认上电就是安全状态,而Trustzone被禁止之后,系统就处于非安全状态。ARM trustzone在芯片层级也没有办法大包大揽, 例如对于加解密算法就无法支持。
在ARM trustzone中,以下模块起到至关重要的作用:
- Secure Boot Loader
- Secret keys
- Flash programming support
- High value assets
Secure (Trusted) and Non-secure (Non-trusted) 程序互相配合进行工作,Non-secure应用不可以直接访问划分为安全属性的资源。如果想要访问则需要通过特定的API进行访问。因此,在API统筹以及使用,可以在上层应用中增加认证、许可等逻辑。
3. Trustzone技术应用
有很多的安全应用可以依赖TrustZone技术,这一节只是列举一些经典应用可以考虑和Trustzone结合。
- 通信保护
- 数据保护
- 固件保护
- 操作保护
- 防篡改保护 (Tamper)
- Secure Boot
由于TrustZone技术是ARMv8-M芯片唯一的安全屏障Trustzone没有办法满足所有的安全需求,因此就需要和其他软件或者硬件安全机制互相配合。例如:
通信保护机制中需要大量的加解密算法,而trustzone并无法直接提供这些算法。因此可以使用硬件或者软件的两种手段。使用硬件对加解密加速可以直接把硬件的处理和安全总线进行连接,让整个硬件模块都处于安全环境;使用软件则可以把通信协议栈以及加解密算法库放入安全控件。
很多微控制器已经内置了USB和Bluetooth的硬件协议栈,Trustzone技术可以防止一些攻击通过Secure API调用的中间层绕过检查。
对于IoT的设备,TrustZone技术也可以与用于先进微控制器的附加保护功能一起使用,以满足下一代物联网(IoT)产品的需求。例如,为物联网应用开发的微控制器可以包含一系列安全功能。
在物联网应用中,安全性是至关重要的,因为这些设备可能涉及到敏感数据、远程通信以及与其他设备的交互。以下是TrustZone技术与物联网微控制器安全功能结合使用的一些示例:
- 阻止不可信应用直接访问安全敏感资源;
- 确保刷入的固件是被检查的;
- 防止逆向工程;
- 在软件层存储敏感数据。
无线通信设备, 在其他应用场景中,例如具有经过认证的内置无线协议栈的无线系统芯片(SoC),TrustZone技术可以保护标准化的操作,如无线通信行为。