本帖最后由 STM新闻官 于 2023-10-18 18:37 编辑
一、引言
STM32 MCU 中较新的产品系列例如 STM32L5、STM32U5 采用了 ARM Cortex V8M 的 CM33 内核,并引入了 TrustZone 概念。在此基础上,从内核到存储器再到外设等设计了完整的支持 TrustZone 架构的系统隔离机制。
在新的 TrustZone 架构下,软件的开发由原来的单一工程,变成了 Secure 安全和 NonSecure 非安全两个工程的联合开发,系统上电首先从 Secure 工程开始运行,完成必要初始化之后跳转至 NonSecure 工程运行,之后 NonSecure 工程还可以通过调用 Secure 工程经由 NSC(Secure NonSecure Callable)区提供的 API 调用 Secure 工程的函数。
由于此时系统的所有资源,包括 Memory、外设等等都区分了安全和非安全属性,而CPU 也区分安全和非安全运行状态,其对应的安全或非安全代码及其使用的数据都需要有相应的存储空间存放,且该存储空间需要具有相同的安全或者非安全属性,否则代码无法正常运行。因此,在 TrustZone 架构下首先需要针对不同物理区间做地址安排及相应安全属性的正确配置。对于 V8M 内核来说,这涉及到 SAU/IDAU 的配置,且取指令与取数据可能有不同的访问规则,同时指令以及数据是否能够从 memory 中正确取得,除了和 SAU/IDAU 的配置有关以外,还与 Memory 自身的安全属性配置有关。
本文将对 SAU/IDAU 配置,Memory 的自身安全属性配置,以及内核访问指令与数据时的安全访问规则加以阐述,希望可以帮助相关开发者更好地理解 V8M TrustZone 的架构以及在 STM32 中的实现,同时,还会列举一些与 memory 的 TrustZone 安全配置相关的常见问题及分析方法,给开发者做参考。
二、CM33 内核的安全扩展
CM33 内核使用 AHB5 总线,具有可选安全扩展(Security Extension)功能。使能安全扩展的内核则支持 V8M TrustZone 架构,此时 AHB5 总线上将携带安全访问标记信号(HNONSEC),这个标记将指示当前访问的 Transaction 是安全访问还是非安全访问,总线上的从设备需要识别这个标记信号,根据 Transaction 携带的安全、非安全权限信息,决定是否允许最终的物理访问。 内核的安全扩展除了总线携带的安全标记信号以外,还包括 CPU 本身的安全/非安全运行状态,有对应安全/非安全状态的 CPU 寄存器(例如各自的 stack pointer MSP 和PSP),中断等等。CPU 可以在安全和非安全状态之间切换,这个切换可能来自于函数调用,也可能由中断触发,如图 1 所示。
▲ 图1.CM33 内核的安全状态及其切换本文内容将主要集中在内核在不同安全状态下对资源的访问权限和规则方面。
三、内核的 SAU 与 IDAU
SAU 是 CM33 内核的单元,负责内核对地址的安全访问控制。IDAU 同样作为内核安全访问控制的一部分,与 SAU 共同作用,只不过 IDAU 是芯片厂商实现的独立接口,其行为由芯片厂商的设计决定。 CM33 带 TrustZone 的内核所访问的任何地址在 SAU 和 IDAU 看来都具有其安全属性,地址安全属性可能是下面三种中的一种: 图 2 显示了这三种类型的的地址在出现 NS 到 S 的函数调用时的作用。
▲ 图2. S,NS,NSC 三种类型地址
1. IDAU
IDAU 是 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 默认该地址范围具为非安全地址。
2. SAU
SAU 是内核中用来动态配置某段地址安全属性的单元,类似于 MPU,最多可以定义 8个 region,region 及其配置可以动态修改(除非设置了 lock),但是 SAU 寄存器只能由Secure Privilege code 进行修改。SAU 上电默认的状态是“未使能”,此时 SAU 单元默认所有地址都具有安全属性,因此只有安全状态的 CPU 能够进行地址访问,当然上电默认CPU 也处于安全状态,所以上电复位时一定只能运行安全代码。需要通过安全代码进行相关配置,在系统中划分出非安全属性的地址区域后,才能开始运行非安全代码。
在 STM32 CubeFW 软件包的 TrustZone Template 工程中通常我们会看到一个与TrustZone 有关的配置文件,文件名类似 partition_xxxx.h,这个文件里面会包含 SAU 的配置,中断的 Target 配置等等。先来说说 SAU 的配置的几种用例。 - Case1:上电缺省效果,即不使能 SAU,且 SAU 默认所有地址为 S 这种配置下,SAU 认为所有地址都是 S 属性的,所以 NS 代码一定无法运行。
- Case3: 使能 SAU,并根据需要配置不同属性的 region。
SAU 最多可以配置 8 个 region 的安全属性,8 个 region 都没有覆盖到的地址范围,SAU默认都是 S 安全的,无需额外配置,所以配置 region 的时候只能设置某个 region 的属性为NSC 或者 NS。如果使能了 SAU,那么某个地址的安全属性就由 IDAU 和 SAU 共同决定,已经被 IDAU 配置为 S 属性的地址,不能通过 SAU region 定义为 NS,这样的 SAU region是无效的,所以简单地说,有效的 SAU region 定义只有两种:[color=rgba(0, 0, 0, 0.9)]为了让系统能够运行非安全代码,通常我们至少需要配置下面几个 SAU region,来分别指定 flash 中的 NSC secure API 入口区、NS code 区、SRAM 中的 NS rw data 区、外设寄存器 NS 地址别名区等。 Flash NSC 地址范围,例如:Flash NS 地址范围,例如: SRAM NS 地址范围,例如: 外设寄存器 NS 地址别名范围,例如:外部 Memory NS 地址范围 (如果需要用到外部 memory 以地址映射方式访问),例如:另外可能还需要将 0x0BF90000 到 0x0BFA08FFF 的区域设为 NS(具体地址范围请参考实际 STM32 型号的参考手册),其中可能包括类似 OTP 以及 device 的 flash information block等内容,flash driver 可能需要读取该区域。其他为可选,可根据实际需要进行配置,例如 NS system Bootloader 区。不使用的region,只需要在该头文件中保持对应的 SAU_INIT_REGIONx 定义为 0 即可。SAU 的配置可由下面这段代码完成。▼▼▼
微信推文篇幅有限,《STM32 TrustZone 开发调试技巧 — 地址安全区及资源安全属性配置》全文点击此处,下载手册
更多TrustZone技术内容,欢迎大家上STM32单片机B站观看《STM32 MCU TrustZone培训课程》。(PC端点击蓝字观看)
|