blog
blog copied to clipboard
[armv8-m] TrustZone Tech Description
1. Memory
如果在ARM上启动安全扩展的功能,4GB的内存被划分为安全和非安全两个区域。安全区域还会再次被细分(NSC和S)。
1.1 Secure (S)
ARM TrustZone 技术创建了一个安全的执行环境,使得特定的内存区域和外设只能被安全软件或安全主体访问。这里的“安全地址”指的是那些被指定为只能由安全状态下的软件访问的内存地址或外设地址。“安全事务”则指的是由安全主体(例如处理器的安全模式)发起并针对安全地址的操作。
例如:
- 安全内存区域访问:假设有一个内存区域被配置为安全区域,用于存储敏感数据,如加密密钥或用户个人数据。只有在处理器运行在安全模式(TrustZone的安全状态)时,这些数据才能被访问。如果非安全状态下的代码尝试访问这些安全地址,访问将会被阻止或引发安全异常。
- 安全外设访问:这个安全外设被映射到安全的地址空间内。在某些系统中,特定的外设(如加密处理单元或安全存储设备)可能被配置为只能在安全模式下访问。只有安全软件(例如运行在TrustZone安全环境中的软件)可以与这些外设交互,执行如数据加密、解密或安全认证的操作。
- Secure Boot过程:在设备启动时,引导加载程序可能首先运行在安全模式下,以确保系统的完整性。在这个过程中,它可能会访问存储在安全内存区域的引导代码和配置数据,确保只有验证通过的软件才能被加载和执行。
- 安全事务请求处理:当安全应用程序(例如运行在TrustZone安全环境中的移动支付应用)需要执行事务时,它可能会发起对安全内存或外设的访问请求。这些请求被视为安全事务,因为它们由安全主体发起并且针对的是安全地址。
1.2 Non-Secure Callable (NSC)
在ARMv8-M架构中,NSC(Non-secure Callable)是一种特殊类型的安全内存区域。这种设计主要是为了在保持系统安全性的同时,提供一种从非安全状态(Non-secure state)到安全状态(Secure state)的安全过渡机制。理解这一点,需要先了解ARM TrustZone的一些基本概念:
- 安全状态和非安全状态:ARMv8-M架构支持TrustZone技术,允许处理器在两种状态下运行:安全状态和非安全状态。安全状态用于执行敏感或安全关键的操作,而非安全状态则用于执行普通的应用程序。
- SG(Secure Gateway)指令:SG指令是从非安全状态到安全状态的转换机制。当非安全代码需要调用安全代码时,会使用SG指令跳转到安全状态。
- NSC内存的作用:NSC内存是一种特殊的安全内存区域,它允许存储SG指令。这意味着只有在NSC内存中的SG指令才能被非安全代码执行,从而触发到安全状态的转换。这种设计提高了系统的安全性,因为它限制了非安全代码可以调用的安全函数的范围。
为什么要这么设计?
- 第一,防止意外的安全状态转换:没有NSC内存的话,如果普通安全内存中意外包含了SG指令或与数据共享相关的编码值,那么非安全代码可能会意外地触发到安全状态的转换,这可能导致安全漏洞。
- 第二,控制安全状态的访问:通过限制SG指令只能在NSC内存中执行,安全软件开发者可以精确控制非安全代码可以调用哪些安全函数,增强了安全状态的访问控制。
举一个例子
假设有一个安全函数,用于加密数据,这个函数位于安全状态下执行的代码中。为了让非安全状态下的应用程序能够请求这种加密服务,开发者会在NSC内存中放置一个包含SG指令的小函数或"网关"。当非安全应用程序需要进行加密操作时,它会调用这个NSC内存中的函数。这个函数随后使用SG指令安全地转换到安全状态,并调用实际的加密函数。完成操作后,控制权安全地返回到非安全状态。
以下是一个简化的伪代码示例,展示了如何在ARMv8-M架构下使用NSC内存和SG指令来实现从非安全状态到安全状态的过渡。这个例子包含了一个非安全函数调用安全函数的场景。
首先,定义一个安全函数,这个函数实际上在安全状态下执行,比如一个加密操作:
// 安全状态下的函数
void SecureFunction() {
// 执行一些安全关键的操作,比如加密
}
然后,设置一个NSC区域的“网关”函数。这个函数包含一个SG指令,它允许从非安全状态安全地跳转到安全状态:
// NSC内存中的网关函数
void NSCGateway() {
SG; // SG指令用于从非安全状态跳转到安全状态
SecureFunction(); // 调用安全函数
// 返回非安全状态的指令
}
最后,非安全状态下的代码可以调用这个NSC区域中的网关函数来安全地执行安全状态下的操作:
// 非安全状态下的函数
void NonSecureFunction() {
// 调用NSC区域中的网关函数
NSCGateway();
// 进行其他非安全操作
}
在这个例子中,非安全代码通过调用位于NSC内存中的NSCGateway函数来安全地访问安全函数SecureFunction。这种方式确保了只有预定义的、位于NSC内存中的代码才能触发从非安全状态到安全状态的转换,从而保护了系统的安全性。
在ARM TrustZone中,NSC内存区域通常包含一系列小的分支镶嵌(branch veneers),这些分支镶嵌作为进入点(entry points),参考:https://developer.arm.com/documentation/dui0474/i/CHDBDFBH 。分支镶嵌是一种简短的代码片段,通常用于实现从一个代码区域跳转到另一个代码区域的功能,尤其是当这些区域具有不同的安全级别时(如从非安全状态跳转到安全状态)。
1.3 Non-Secure
在理解TrustZone技术时,重要的是要了解其中的一些关键概念,比如Non-secure addresses和Non-secure transactions。
- 在ARM TrustZone技术中,“Non-secure addresses”指的是那些可以被设备上所有软件访问的内存和外围设备的地址。这意味着这些地址上的资源不受TrustZone安全环境的保护,任何运行在处理器上的软件,无论是安全的还是非安全的,都可以访问这些地址。
- “Non-secure transactions”是指起源于被视为非安全的主体(masters),或者是安全主体但访问非安全地址的操作。换句话说,当一个处理器或设备的部分在非安全模式下运行时,它发起的所有内存或数据交换都被视为非安全交易。这些交易只允许访问非安全地址。
transactions /trænˈzækʃənz/ n. 处理,[图情]会报;汇报(transaction 复数)
TrustZone技术确保非安全交易不能访问安全地址。这是通过硬件和软件的安全配置来实现的,以保证安全区域的数据和操作不会被非安全软件访问。这种访问控制是TrustZone实现安全分隔的关键部分。
如何保证非安全Transaction不可以访问安全地址?
ARM TrustZone通过硬件和软件的协同工作来确保非安全(Non-secure)交易无法访问安全(Secure)地址。这种安全机制的实现涉及多个层面:
-
处理器状态(Processor States):
- ARM处理器在TrustZone技术的帮助下,可以在两种状态下运行:安全状态(Secure state)和非安全状态(Non-secure state)。
- 当处理器处于安全状态时,它可以访问所有资源(包括安全和非安全资源)。但当它处于非安全状态时,只能访问非安全资源。
-
内存和外设的分区:
- 在硬件层面,内存和外围设备的地址空间被分为安全和非安全区域。
- 每个内存地址和外围设备接口都会被标记为安全或非安全。
-
安全监视器(Secure Monitor):
- 安全监视器是TrustZone中的一个关键组件,它充当安全和非安全状态之间的交换机。
- 它确保只有在适当的授权和条件下,处理器才能从非安全状态切换到安全状态。
-
访问控制硬件:
- ARM处理器包含用于监控和控制内存访问的专门硬件,称为内存保护单元(Memory Protection Unit, MPU)或内存管理单元(Memory Management Unit, MMU)。
- 这些硬件单位可以配置特定的规则来阻止非安全状态下的处理器访问安全内存区域。
-
软件支持:
- 操作系统和应用程序也需要被适当设计和配置,以利用TrustZone提供的硬件安全特性。
- 这通常涉及操作系统层面的修改,确保在非安全模式下运行的软件被限制访问安全资源。
通过这种多层次的安全策略,TrustZone确保非安全交易无法访问或影响安全地址,从而为敏感数据和操作提供了一个隔离和保护的环境。这种机制对于构建安全的嵌入式系统和移动设备至关重要,可以有效防止数据泄露和恶意软件攻击。
2. Attribution units (SAU & IDAU)
该机制更像是一个“断言”仲裁机制,根据用户和ARM自身的配置,断定操作是否是安全的。
在ARM TrustZone技术中,SAU(Security Attribution Unit)和IDAU(Implementation Defined Attribution Unit)是两个关键组件,它们协同工作以定义和控制安全(Secure)和非安全(Non-secure)内存及外设的访问权限。以下是它们的详细解释:
- SAU(Security Attribution Unit):
- SAU是一个硬件单元,负责为内存和外围设备区域分配安全属性。
- 它在运行时动态地定义哪些资源是安全的,哪些是非安全的。这意味着SAU可以根据需要调整资源的安全状态,提供灵活的安全配置。
- SAU的配置通常由操作系统或安全监视器负责,它们在系统启动时或在需要时设置SAU的规则。
- IDAU(Implementation Defined Attribution Unit):
- IDAU更多地与特定ARM处理器实现相关,它提供了一个硬件级别的安全属性配置。
- IDAU的配置通常是静态的,由芯片制造商在设计阶段定义,并且在正常运行期间不会改变。
- 它为内存和外设区域提供了一个默认的安全级别,这些级别通常根据芯片设计和预期的安全需求设定。
SAU和IDAU在ARM TrustZone中的协作机制如下:
- 当一个内存访问请求发生时,处理器会同时考虑SAU和IDAU的配置。
- 如果两者中的任何一个将访问的地址标记为“安全”,那么这个访问将被视为是对安全资源的访问。
- 相反,如果SAU和IDAU都将地址标记为“非安全”,那么这个访问则被视为非安全访问。
这种机制确保了即使操作系统或安全监视器在运行时调整SAU配置,芯片制造商在设计阶段设置的基本安全策略也得以保留。这样,TrustZone可以提供既灵活又强大的安全控制手段,适应各种不同的安全需求和应用场景。
可配置性
安全属性单元(SAU)和实现定义属性单元(IDAU)的功能具有非常灵活的可配置性:
SAU的可编程性与MPU的相似性:
当处理器处于安全状态时,SAU是可编程的。这种可编程性允许动态管理安全,适应不同的操作需求。它的编程模型与内存保护单元(MPU)类似,意味着它用于定义和控制内存或资源的访问权限。
SAU的实现是可以由设计师配置的。这意味着在设计一个基于TrustZone技术的系统时,SoC设计师可以根据具体需求来配置SAU。虽然SAU始终存在,但SoC设计师可以定义区域的数量,这些区域决定了哪些内存或资源是安全的,哪些是非安全的。IDAU与SAU的结合使用:
- SoC设计师可以选择使用IDAU来定义一个固定的内存映射,并使用SAU来覆盖某些内存部分的安全属性。
- 一个简单的应用例子是使用IDAU将内存分割成500MB的块,这些块交替设置为安全和非安全内存。
通过这种方式,可以灵活地将系统的内存空间分配给安全或非安全状态,同时保持基础安全策略的一致性。
STM32的设计实例
在STM32中有IDAU和SAU的设计:
根据STM32公司的配置,会有不同的安全仲裁结果
STM32L5/U5系列微控制器(MCU)的内存映射特性,这些微控制器遵循ARM的建议,实现了重复的内存映射:一个用于安全视图(Secure view),另一个用于非安全视图(Non-secure view)。以下是其主要特点:
- 双重内存映射:在STM32L5/U5系列中,每个内存映射区域(如代码、SRAM、外设)被划分为两个子区域。这意味着内部存储器和外设在非安全视图和安全视图中都有各自独立的地址位置。
- 安全和非安全视图:安全视图是只能由处于安全状态的代码访问的内存区域,用于存放敏感数据或执行安全相关的代码。非安全视图则可以由处于非安全状态的代码访问,适用于不涉及敏感信息的常规操作。
- IDAU的作用:在STM32L5/U5系列中,IDAU(Implementation Defined Attribution Unit)被实现用来定义这些区域的安全属性。IDAU的内存映射分区是固定的,由硬件决定,不可配置。
- 内存映射安全属性分区:STM32L5/U5系列的IDAU定义了内存映射的安全属性分区,这决定了哪些区域是安全的,哪些是非安全的。这种分区对于确保系统中的安全操作至关重要,因为它允许安全代码和数据与非安全代码和数据物理
STM32L5/U5有八个SAU(安全属性单元)区域。用户可以通过SAU更改所需的安全配置分区。当TrustZone启用时,SAU默认将所有地址视为安全的:所有内存区域都被视为安全区域。这提供了一种机制,允许用户根据具体应用的需要来动态配置和调整内存区域的安全属性。
举个例子
STM32展示如何通过不同的内存视图来实现对外设的安全访问控制:
一个外围设备(peripheral)在非安全视图中被解码到地址0x4000 0000,而在安全视图中被解码到地址0x5000 0000。这意味着相同的外设可以在两个不同的地址范围内访问,根据其安全状态的不同。根据SAU(安全属性单元)和IDAU(实现定义属性单元)的编程,安全代码通过生成安全交易来访问安全视图中的外设,而非安全代码则在非安全视图中的另一个地址访问同一外设。这种机制允许不同安全级别的代码分别访问相同的硬件资源,但在不同的地址和安全环境下进行。
外设的安全属性是由GTZC(全局信任区配置控制器)或TZSC(信任区安全控制器)定义的。这些控制器决定了哪些外设可以在安全状态下访问,哪些可以在非安全状态下访问。访问是否被授权或拒绝取决于外设的安全属性如何定义。
SAU configuration在STM32中也是有地方配置的:
- STM32U5: Device partition_stm32U575xx.h and partition_stm32U585xx.h
- STM32L5: Device partition_stm32l552xx.h and partition_stm32l562xx.h
The following example CMSIS code shows how the you can configure the SAU for two regions
// Configure SAU using CMSIS
// Configure SAU Region 0
// Start Address 0x00200000
// Limit Address 0x003FFFE0
// Secure non-scure callable
// Use CMSIS to access SAU Region Number Register (SAU_RNR)
// Select region 0
SAU->RNR = (0);
// Set SAU Region Base Address Register (SAU_RBAR)
SAU->RBAR = (0x00200000U & SAU_RBAR_BADDR_Msk);
// Set SAU Region Limit Address Register (SAU_RLAR)
SAU->RLAR = (0x003FFFE0U & SAU_RLAR_LADDR_Msk) | 1U << SAU_RLAR_NSC_Pos)
SAU_RLAR_NSC_Msk) | 1U
// Configure SAU Region 1
// Start Address 0x20200000
// Limit Address 0x203FFFE0
// Non-secure
// Select region 1
SAU->RNR = (1);
// Set SAU Region Base Address Register (SAU_RBAR)
SAU->RBAR = (0x20200000U & SAU_RBAR_BADDR_Msk);
// Set SAU Region Limit Address Register (SAU_RLAR)
SAU->RLAR = (0x203FFFE0U & SAU_RLAR_LADDR_Msk) | 0U << SAU_RLAR_NSC_Pos)
SAU_RLAR_NSC_Msk) | 1U
// Enable SAU
// Use CMSIS to access SAU Control Register (SAU_CTRL)
// Set ENABLE bit[0] to 1
// Set ALLNS bit[1] to 1 All memory is secure when SAU is disabled
SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) &
SAU->SAU_CTRL_ENABLE_Msk) | ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ;
3. Switching between Secure and Non-secure states
ARMv8-M 安全扩展为安全(Secure)和非安全(Non-secure)软件之间提供了直接调用的能力。这是ARMv8-M体系结构的一个重要特性,它极大地增强了在同一处理器上运行安全敏感和常规任务的灵活性和效率。
在ARMv8-M处理器中,为了处理状态转换(即从安全状态到非安全状态,或从非安全状态到安全状态的转换),提供了几个专门的指令。这些指令包括 SG、BXNS 和 BLXNS。它们各自的功能如下:
指令 | 描述 | 用途 |
---|---|---|
SG | Secure Gateway | 用于从非安全状态转换到安全状态。当非安全代码需要调用安全函数时使用此指令,以触发状态切换并执行安全函数。 |
BXNS | Branch and Exchange Non-secure | 用于从安全状态返回到非安全状态。通常在安全函数执行完成后使用,以返回到调用它的非安全代码中。 |
BLXNS | Branch with Link and Exchange Non-secure | 用于从安全状态切换到非安全状态,同时设置返回地址。常用于安全代码需要调用非安全函数,并且预期该函数执行完成后返回到安全代码中继续执行的场景。 |
Note, ARM TrustZone中非安全到安全软件之间的直接API函数调用机制。在这种机制中,如果安全软件入口点的第一条指令是SG(Secure Gateway),且该入口点位于一个非安全可调用的内存位置,那么允许从非安全软件直接调用安全软件的API函数。这里是如何工作的:
3.1 函数调用及异常处理
在ARMv8-M体系结构中,非安全程序调用安全API以及安全程序调用非安全软件的过程及其安全机制,解释为:
非安全程序调用安全API:
- 当非安全程序调用安全API时,该API在完成后通过执行BXNS指令返回到非安全状态。
- 如果非安全程序试图直接跳转(branch)或调用安全程序的地址,而没有使用有效的入口点,将生成一个故障事件(fault event)。
- 在ARMv8-M主线(Mainline)体系结构中,使用SecureFault异常类型来处理这种故障事件。对于ARMv8-M基线(Baseline)体系结构,故障事件fault event由安全状态下的HardFault处理。
ARMv8-M体系结构是专为微控制器和嵌入式设备设计的一种ARM体系结构,它包含两种主要的配置:ARMv8-M Mainline(主线)和ARMv8-M Baseline(基线)。这两种配置主要针对不同的性能和功能需求,让芯片制造商能够根据自己产品的目标市场选择合适的配置。下面是这两种配置的主要区别:
ARMv8-M Mainline(主线):
- 这是一种更高级别的配置,提供了更全面的特性集合,包括更高级的指令集和更强大的性能。
- 它支持完整的TrustZone技术,包括安全和非安全状态之间的切换。
- ARMv8-M Mainline还支持更复杂的中断处理,以及更高级的内存保护功能。
- 这种配置适用于需要更高计算性能和更复杂安全功能的应用,如智能家居设备、工业控制系统等。
ARMv8-M Baseline(基线):
- Baseline配置提供了一组更简化的特性,专为成本敏感和低功耗应用设计。
- 它支持基本的TrustZone功能,但相比Mainline配置来说,功能上更为有限。
- ARMv8-M Baseline通常用于简单的应用,如基本的传感器管理、简单的嵌入式控制器等,这些应用不需要复杂的处理能力或高级安全特性。
总的来说,ARMv8-M体系结构的这两种配置使得ARM处理器能够覆盖从简单低成本的微控制器到需要高级功能和更强处理能力的复杂应用的广泛需求。
安全程序调用非安全软件:
- ARMv8-M安全扩展还允许安全程序调用非安全软件。在这种情况下,安全程序使用BLXNS指令来调用非安全程序。
- 在状态转换过程中,返回地址和一些处理器状态信息被压入安全栈,而链接寄存器(LR)上的返回地址被设置为一个特殊值,称为
FNC_RETURN
。 - 调用的函数地址的最低有效位(LSB)必须是0,以指示这是一个非安全调用。
- 当非安全函数调用安全函数完成后,它通过执行分支到特殊的地址(FNC_RETURN)来结束。
- 这个操作会触发从安全栈中取出真正的返回地址,并自动返回到原先调用该安全函数的非安全函数。
- 这个过程中,安全软件的返回地址被自动隐藏,以保护安全状态下的执行流程和数据。
Note, 在安全函数调用过程中,安全软件可以选择将某些寄存器值作为参数传递给非安全代码。同时,为了保护敏感数据,安全软件会在调用完成前,清除寄存器中的其他安全数据。
3.2 安全状态与工作状态变换
在ARMv8-M体系结构中,状态转换如何通过异常和中断触发,以及这些状态转换如何影响中断处理过程。下面是对这些概念的详细解释:
在ARMv8-M体系结构中,状态转换不仅可以由函数调用触发,还可以由异常和中断引起。每个中断都可以被配置为安全(Secure)或非安全(Non-secure),这由NVIC_ITNS(中断目标非安全寄存器)决定,该寄存器只能在安全世界中编程。当处理器运行非安全或安全代码时,可以发生任何类型的中断,无论是安全的还是非安全的。
如果到达的异常或中断与当前处理器状态相同(即安全中断发生在安全状态,非安全中断发生在非安全状态),则异常处理序列几乎与现有的M系列处理器相同,从而保持低中断延迟。主要的区别发生在非安全中断在执行安全代码时被处理器处理的情况。在这种情况下,处理器会自动将所有安全信息推入安全栈,并从寄存器组中清除这些信息,以避免信息泄露。
所有现有的中断处理特性,如中断嵌套、向量化中断处理和向量表重定位都得到支持。TrustZone技术在ARMv8-M体系结构中保持了现有M系列处理器的低中断延迟特性,尽管由于需要将所有安全内容推入安全栈,从安全到非安全的中断会产生稍微更长的中断延迟。
异常模型的增强也适用于浮点单元中寄存器的懒堆栈处理。懒堆栈用于减少异常序列中的中断延迟,除非中断处理程序也使用FPU,否则可以避免堆栈浮点寄存器。在ARMv8-M体系结构中,同样的概念应用于避免堆栈安全浮点上下文。在安全软件使用FPU且非安全中断处理程序不使用FPU的情况下,可以跳过FPU寄存器的堆栈和解堆栈处理,以提供更快的中断处理序列。
4. Security states of the processor
ARMv8-M体系结构中的安全状态和非安全状态的基本概念,以及安全与非安全软件之间的函数调用和跳转。这些是理解ARM TrustZone技术的核心要素。以下是对这些概念的简化解释:
-
程序地址与处理器安全状态:
- 在ARMv8-M体系结构中,程序地址决定了处理器的安全状态,这可以是安全(Secure)或非安全(Non-secure)。
- 如果处理器在非安全内存中运行程序代码,则处理器处于非安全状态。
- 如果处理器在安全内存中运行程序代码,则处理器处于安全状态。
- 当处理器处于安全状态时,它必须从安全内存中获取指令。
-
安全与非安全软件之间的函数调用和跳转:
- ARMv8-M体系结构允许在安全和非安全软件之间进行函数调用或跳转。
- 然而,为了确保安全性,对从非安全到安全的转换施加了限制。这些限制确保仅当使用有效的安全API入口点从普通世界(Normal world)调用安全代码,或者在从非安全API返回到安全代码时,才能进行状态转换。
这种机制确保了在ARMv8-M体系结构中安全和非安全软件之间的调用和跳转是受控和安全的。通过这种方式,TrustZone技术为在同一处理器上运行安全敏感和常规任务提供了强大的工具,同时确保了整个过程的安全性和正确性。
5. Global TrustZone controller (GTZC)
Global TrustZone Controller(GTZC)是ARM TrustZone技术中的一个关键组件,它在ARM基于TrustZone的微控制器中扮演着重要的角色。GTZC的主要职责和功能包括:
安全区域的管理:
- GTZC负责管理和配置处理器中的安全区域。它决定哪些内存区域和外围设备是安全的,哪些是非安全的。
访问控制:
- 通过GTZC,可以配置不同的访问权限,确保非安全状态下的代码不能访问安全区域的资源,反之亦然。这有助于防止敏感数据的泄露和不当访问。
中断管理:
- GTZC还可以参与到中断的管理中,控制哪些中断是安全的,哪些是非安全的。这确保了在处理器运行安全代码时,只有安全中断能被处理。
配置和监控:
- GTZC允许系统开发者或安全管理员配置和监控安全环境,包括设定安全区域、监控访问违规事件等。
支持多种安全场景:
- 在复杂的系统中,GTZC支持多种安全应用场景,包括数据保护、安全引导、加密操作等。
简而言之,Global TrustZone Controller是实现ARM TrustZone安全功能的关键部件之一,它提供了必要的机制来保护和管理安全和非安全资源,确保系统的整体安全性。通过GTZC,系统可以有效地隔离敏感操作和数据,从而在多任务和多用户环境中维持高度的安全性。