STM32 TrustZone 开发调试技巧 | 地址安全区及资源安全属性配置 一、引言# ]# C: j9 M! Y( e2 }STM32 MCU 中较新的产品系列例如 STM32L5、STM32U5 采用了 ARM Cortex V8M 的 CM33 内核,并引入了 TrustZone 概念。在此基础上,从内核到存储器再到外设等设计了完整的支持 TrustZone 架构的系统隔离机制。# l" {' U; \0 o* l4 S; w. y 在新的 TrustZone 架构下,软件的开发由原来的单一工程,变成了 Secure 安全和 NonSecure 非安全两个工程的联合开发,系统上电首先从 Secure 工程开始运行,完成必要初始化之后跳转至 NonSecure 工程运行,之后 NonSecure 工程还可以通过调用 Secure 工程经由 NSC(Secure NonSecure Callable)区提供的 API 调用 Secure 工程的函数。6 [! B5 V! q$ w Z - Y2 u- z" d+ o 由于此时系统的所有资源,包括 Memory、外设等等都区分了安全和非安全属性,而CPU 也区分安全和非安全运行状态,其对应的安全或非安全代码及其使用的数据都需要有相应的存储空间存放,且该存储空间需要具有相同的安全或者非安全属性,否则代码无法正常运行。因此,在 TrustZone 架构下首先需要针对不同物理区间做地址安排及相应安全属性的正确配置。对于 V8M 内核来说,这涉及到 SAU/IDAU 的配置,且取指令与取数据可能有不同的访问规则,同时指令以及数据是否能够从 memory 中正确取得,除了和 SAU/IDAU 的配置有关以外,还与 Memory 自身的安全属性配置有关。 本文将对 SAU/IDAU 配置,Memory 的自身安全属性配置,以及内核访问指令与数据时的安全访问规则加以阐述,希望可以帮助相关开发者更好地理解 V8M TrustZone 的架构以及在 STM32 中的实现,同时,还会列举一些与 memory 的 TrustZone 安全配置相关的常见问题及分析方法,给开发者做参考。 ) H1 f" ?# \9 i- i7 U- b g4 O 二、CM33 内核的安全扩展 CM33 内核使用 AHB5 总线,具有可选安全扩展(Security Extension)功能。使能安全扩展的内核则支持 V8M TrustZone 架构,此时 AHB5 总线上将携带安全访问标记信号(HNONSEC),这个标记将指示当前访问的 Transaction 是安全访问还是非安全访问,总线上的从设备需要识别这个标记信号,根据 Transaction 携带的安全、非安全权限信息,决定是否允许最终的物理访问。 W7 e t1 k8 R& |7 R 内核的安全扩展除了总线携带的安全标记信号以外,还包括 CPU 本身的安全/非安全运行状态,有对应安全/非安全状态的 CPU 寄存器(例如各自的 stack pointer MSP 和PSP),中断等等。CPU 可以在安全和非安全状态之间切换,这个切换可能来自于函数调用,也可能由中断触发,如图 1 所示。 ▲ 图1.CM33 内核的安全状态及其切换 8 x, m( ]6 ^/ B0 G; B9 c" t本文内容将主要集中在内核在不同安全状态下对资源的访问权限和规则方面。 三、内核的 SAU 与 IDAU SAU 是 CM33 内核的单元,负责内核对地址的安全访问控制。IDAU 同样作为内核安全访问控制的一部分,与 SAU 共同作用,只不过 IDAU 是芯片厂商实现的独立接口,其行为由芯片厂商的设计决定。 7 {9 M/ y$ W6 W k& V CM33 带 TrustZone 的内核所访问的任何地址在 SAU 和 IDAU 看来都具有其安全属性,地址安全属性可能是下面三种中的一种: S - Secure: 纯粹 Secure 地址,只能由安全代码访问,不应放置 SG(Secure Gate)入口指令,不允许 NS 代码直接函数调用。 NSC - Secure NonSecure Callable:特殊的 Secure 地址,依旧是 Secure 属性,但是可以放置 SG 指令,作为 NS 调用 S 函数的入口地址。& G/ l- D! g: {+ B: w# y9 M NS - NonSecure:NonSecure 地址。 9 |+ j& O; J6 v# f2 b! ~ 图 2 显示了这三种类型的的地址在出现 NS 到 S 的函数调用时的作用。 ▲ 图2. S,NS,NSC 三种类型地址 1. IDAUIDAU 是 SOC 对地址安全属性的缺省静态配置,无论是否使能 SAU,IDAU 上电都生效。表 1 是一个 IDAU 缺省配置下地址安全属性的示例(具体的定义请参考对应 STM32MCU 型号参考手册的说明)。表中给出了 IDAU 对不同地址段的缺省属性配置,这里标成淡蓝色的三类区域存在地址别名,也就是说相同的物理资源可以通过两套不同的地址进行访问,例如片上 Flash Bank,既可以通过 0x08xxxxxx 地址访问,也可以通过 0x0Cxxxxxx 的地址访问,但是访问效果可能不同,比如内核访问 0x08000000 地址时,IDAU 会认定访问的是 NS 地址,而当内核访问 0x0C000000 时,IDAU 认为访问的是安全地址。类似的对于片上 SRAM 和外设也一样,从 0x2xxxxxxx 访问 SRAM,IDAU 会认为是安全地址,同样的物理区域,从 0x3xxxxxxx 就会被认为访问的是非安全地址;从 0x4xxxxxxx 访问外设寄存器,IDAU 会认为是安全地址,同样的外设寄存器,如果从 0x5xxxxxxx 访问,就会被 IDAU认定访问的是非安全地址。对于外部 Memory 映射的地址,不存在地址别名,且 IDAU 默认该地址范围具为非安全地址。 SAU 是内核中用来动态配置某段地址安全属性的单元,类似于 MPU,最多可以定义 8个 region,region 及其配置可以动态修改(除非设置了 lock),但是 SAU 寄存器只能由Secure Privilege code 进行修改。SAU 上电默认的状态是“未使能”,此时 SAU 单元默认所有地址都具有安全属性,因此只有安全状态的 CPU 能够进行地址访问,当然上电默认CPU 也处于安全状态,所以上电复位时一定只能运行安全代码。需要通过安全代码进行相关配置,在系统中划分出非安全属性的地址区域后,才能开始运行非安全代码。' M. a K) x% `8 p, S5 W SAU 的配置 4 W, y' j- F5 W Q' r 在 STM32 CubeFW 软件包的 TrustZone Template 工程中通常我们会看到一个与TrustZone 有关的配置文件,文件名类似 partition_xxxx.h,这个文件里面会包含 SAU 的配置,中断的 Target 配置等等。先来说说 SAU 的配置的几种用例。 Case1:上电缺省效果,即不使能 SAU,且 SAU 默认所有地址为 S 这种配置下,SAU 认为所有地址都是 S 属性的,所以 NS 代码一定无法运行。 IDAU 认为是 NS 的地址范围:SAU 可以从中定义出 NS 或者 NSC 区,其余没被SAU region 覆盖的地址都是 S 地址。! u4 z7 k% B4 E9 {- u IDAU 认为是 NSC 的地址范围:SAU 可以从中定义 NSC 区域,确认 NSC 的实际范围,其余没被 SAU region 覆盖的地址都是 S 地址。 为了让系统能够运行非安全代码,通常我们至少需要配置下面几个 SAU region,来分别指定 flash 中的 NSC secure API 入口区、NS code 区、SRAM 中的 NS rw data 区、外设寄存器 NS 地址别名区等。 Flash NSC 地址范围,例如:5 `) N$ l) Q3 t% z 其他为可选,可根据实际需要进行配置,例如 NS system Bootloader 区。不使用的region,只需要在该头文件中保持对应的 SAU_INIT_REGIONx 定义为 0 即可。" u: Y: Q4 O- N& V) l( K ▼▼▼ 点击按钮下载《STM32 TrustZone 开发调试技巧 — 地址安全区及资源安全属性配置》全文。 |