Arm处理器软件开发与安全技术详解
1. 软件场景概述
在软件开发中,存在多种不同的场景。此前的软件开发展示大多集中在场景1,即软件仅在一个安全域(非安全世界)中运行。实际上,场景1的软件开发步骤同样适用于场景2、3和5。以下是不同场景的相关介绍:
-
参数传递与返回值
| 寄存器 | 输入参数 | 返回值 |
| — | — | — |
| R0 | 第一个输入参数 | 函数返回值 |
| R1 | 第二个输入参数 | –, 或返回值(64位结果) |
| R2 | 第三个输入参数 | – |
| R3 | 第四个输入参数 | – |
-
寄存器保存要求
| 寄存器 | 函数调用行为 |
| — | — |
| R0–R3, R12, S0–S15 | 调用者保存寄存器 — 这些寄存器的内容可能会被函数改变。调用函数的汇编代码可能需要保存这些寄存器的值,以便后续操作使用。 |
| R4–R11, S16–S31 | 被调用者保存寄存器 — 这些寄存器的内容必须由函数保留。如果函数需要使用这些寄存器进行处理,需要将其保存到栈中,并在函数返回前恢复。 |
| R14 (LR) | 如果函数包含“BL”或“BLX”指令(即调用另一个函数),链接寄存器的值需要保存到栈中。因为执行“BL”或“BLX”时,LR的值会被覆盖。 |
| R13 (SP), R15 (PC) | 不应用于正常处理 |
2. 具体软件场景分析
-
场景1:Armv8 - M系统未实现TrustZone
软件开发过程与传统的Armv6 - M和Armv7 - M Cortex - M处理器几乎相同,没有安全和非安全状态的分离,通过调试连接,软件开发人员可以完全了解系统。不过,从Armv6 - M/Armv7 - M项目迁移到基于Armv8 - M的系统时,需要考虑以下软件代码的更改:
- MPU配置代码更改 :由于内存保护单元(MPU)的编程模型发生变化,使用MPU的代码需要更新。
- hOS代码更改 :由于EXC_RETURN代码值的定义发生变化,操作系统需要更改。软件开发人员应选择能够在非安全状态下运行的操作系统版本。如果使用的是Cortex - M33处理器(或其他Armv8 - M主线处理器),操作系统可以利用栈限制检查功能,使系统更加健壮。
- 位带功能移除 :Cortex - M3和Cortex - M4处理器上的可选位带功能在Armv8 - M处理器中不可用。
- 向量表地址 :与Cortex - M0、Cortex - M0 +、Cortex - M3和Cortex - M4处理器不同,Armv8 - M处理器的初始向量表地址可以非零。
对于大多数应用代码,只需进行少量软件代码更改。由于调试组件(如断点单元、数据监视点单元、ETM)发生了各种变化,开发工具需要更新到支持Armv8 - M架构的版本。 -
场景2:不使用安全世界的非安全软件开发
软件开发人员需要更新与场景1相同的软件区域。此外,还可能会注意到以下差异:
- 禁用安全固件的可选API :在非安全软件初始化开始时,非安全软件可能需要调用安全API,告知安全软件不使用安全世界软件。这允许安全世界向非安全软件释放更多硬件资源(如SRAM和外设)。此外,这个安全API通过设置应用中断和复位控制寄存器(AIRCR)中的BFHFNMINS位,将NMI、HardFault和BusFault异常目标设置为非安全状态。需要注意的是,这是可选的,因为这个安全API可能不可用。
- 内存映射 :包含安全程序和安全资源的内存范围不可访问。
除此之外,这种系统上的软件开发与使用Armv6 - M和Armv7 - M处理器时非常相似。 -
场景3:使用安全世界的非安全软件开发
软件开发人员需要更新与场景1相同的软件区域。此外,还会有以下变化:
- 利用安全API :应用程序可以通过可用的安全API利用各种功能。
- 使用支持Trusted Firmware - M的RTOS :如果软件使用RTOS,所使用的RTOS需要支持Trusted Firmware - M集成,或者如果芯片的安全世界使用其他安全软件解决方案,则需要支持其他安全固件。
- 故障处理和分析 :由于NMI、HardFault和BusFault异常目标为安全状态,非安全软件无法直接访问这些功能。为了让非安全软件开发人员了解软件问题,一些安全固件提供了在发生HardFault或BusFault异常时报告错误的机制。当ETM/MTB指令跟踪可用时,可以在指令跟踪中观察到HardFault/BusFault之前执行的非安全操作。因此,软件开发人员可以使用ETM/MTB指令跟踪分析故障事件。软件开发人员还可以在非安全世界中启用MemManage Fault和UsageFault,以便在非安全调试环境中诊断触发这些故障异常的错误条件。如果未启用非安全MemManage Fault和UsageFault,这些故障事件将升级为安全HardFault。 -
场景5:不使用非安全世界的安全软件开发
软件开发人员需要更新与场景1相同的软件区域。唯一的区别是,如果使用RTOS,所选的RTOS变体需要支持安全世界,而不是非安全世界。
3. 安全软件开发概述
3.1 安全软件开发简介
许多使用物联网微控制器的软件开发人员可能只在非安全世界中创建应用程序。通过安全固件提供的应用程序编程接口(API)访问各种安全功能,他们可以在项目中实现强大的安全功能,而无需深入了解TrustZone。然而,很多软件开发人员会参与安全软件项目,因此有必要了解使用TrustZone编程的原理。安全软件开发涉及多个方面,包括安全与非安全软件的分离、相关技术支持以及开发平台的考虑等。
3.2 安全与非安全软件的分离
当使用TrustZone技术时,安全和非安全软件项目是分别编译和链接的,各自有自己的引导代码和C库。安全软件开发人员通常需要创建一个非安全项目,以测试双方之间的交互。许多工具链支持多项目工作区功能,允许同时开发和调试多个项目。
当创建安全项目后,安全软件开发人员需要向非安全软件开发人员提供以下文件,以便非安全项目可以访问安全API:
- 安全API的函数原型(即头文件)。
- 仅提供API地址信息的导出库(即地址符号,链接非安全项目时链接器工具需要这些信息)。
需要注意的是:
- 安全和非安全项目可以使用不同的工具链创建,因为参数和结果传递的方法在Arm架构的过程调用标准中是标准化的。
- 必须先生成安全项目,再编译和链接非安全项目,以便在非安全项目的链接阶段可以使用安全项目链接阶段生成的导出库。
如果安全代码需要调用非安全函数,非安全代码首先需要通过安全API将非安全函数的指针传递到安全世界。安全API会验证函数指针是否指向非安全地址,然后在需要时执行该函数指针。
4. 相关技术支持
4.1 Cortex - M安全扩展(CMSE)
为了辅助安全软件开发,Arm引入了一系列C编译器支持功能,称为Cortex - M安全扩展(CMSE)。它是Armv8 - M安全扩展的一部分,在多个工具链中得到支持,包括Arm Compiler 6、gcc、IAR™Embedded Workbench® for ARM等。因此,安全软件代码可以在不同的工具链之间移植。
4.2 Trusted Firmware - M
为了帮助电子行业应对安全挑战,Arm在2017年宣布了平台安全架构(PSA)倡议,并启动了Trusted Firmware - M(TF - M)项目。该项目为在设备中使用Cortex® - M处理器的硅供应商提供参考安全固件,具有许多不同的安全功能。
4.3 开发平台考虑
一些Cortex - M23和Cortex - M33设备可能未实现TrustZone安全扩展。对于支持TrustZone的设备,安全世界可能被锁定(即无法修改安全世界,调试功能仅限于非安全世界)。因此,想要创建自己的安全软件解决方案的软件开发人员需要确保所使用的硬件平台支持安全软件开发,并且可能需要确保硬件平台提供合适的调试认证功能,以保护开发的安全软件。
此外,TrustZone只是硬件平台可用的安全功能之一。如果微控制器或SoC提供一系列硬件安全功能,如安全存储、真随机数发生器(TRNG)、加密引擎等,可以进一步增强物联网应用的安全性。需要注意的是,TrustZone本身不能保护系统免受各种物理攻击。软件开发人员应始终与设备制造商核实设备的安全功能,以确保设备支持物理保护功能。
5. TrustZone技术细节
5.1 处理器状态
当实现TrustZone时,处理器可以处于安全或非安全状态。与之前的Armv6 - M和Armv7 - M架构类似,Armv8 - M处理器在执行异常处理程序(处理模式)时处于特权状态。当处理器在线程模式下执行(即不在处理模式下)时,根据CONTROL寄存器中nPRIV位的值,处理器可以处于特权或非特权状态。
简单来说:
- 处理器执行安全内存中的代码时处于安全状态。
- 处理器执行非安全内存中的代码时处于非安全状态。
不过,在非安全状态向安全状态转换时,即非安全代码调用安全API时,存在一个例外情况。
处理器从复位启动时,在安全特权线程模式下执行。系统启动后,安全状态转换会在以下情况下发生:
- 安全代码分支到非安全应用代码以启动非安全世界。
- 非安全应用调用安全API,并在API执行任务后返回非安全世界。
- 安全函数调用非安全函数,并在函数执行任务后返回安全世界。
- 非安全代码执行期间发生安全中断/异常事件,异常进入和返回时都会发生状态转换。
- 安全代码执行期间发生非安全中断/异常事件,异常进入和返回时都会发生状态转换。
- 安全和非安全异常处理程序之间存在尾链。
- 非安全代码执行期间发生复位。
理论上,在调试会话中,当处理器停止时,调试器可以更改处理器的安全状态。但为了避免处理器恢复指令执行或调试器单步执行下一条指令时发生安全违规,程序计数器也需要更改,以使软件执行地址的安全属性与处理器状态匹配。
5.2 内存分离
内存空间划分为安全和非安全范围由安全属性单元(SAU)和实现定义属性单元(IDAU)处理。SAU是Armv8 - M处理器的一部分,IDAU是芯片/SoC设计人员设计的特定于设备的硬件单元,与处理器紧密耦合。
SAU和IDAU协同工作:对于每次地址查找,会比较SAU和IDAU的结果,并选择较高的安全级别;除非IDAU查找结果表明该地址免于安全检查。豁免地址范围通常用于具有安全意识的调试组件,或者非安全访问不会构成任何安全风险的地方(如CoreSight™ ROM表)。
Cortex - M23和Cortex - M33处理器中的SAU可以配置为支持0、4或8个可编程SAU区域,而IDAU最多可以支持256个区域。作为安全初始化过程的一部分,安全初始化程序包括对SAU进行编程,并且如果设备供应商使IDAU的配置可编程,则可能还需要对IDAU进行编程。
使IDAU可编程的常见原因是,尽管它允许处理器包含很少或没有SAU区域,但仍然允许通过软件设置安全区域的NSC(非安全可调用)属性。例如,如果设备没有SAU区域,并且安全分区内存映射完全由IDAU处理,则IDAU需要可编程,以便软件可以控制NSC区域的位置和大小。
在基于TrustZone的系统中配置内存分区的另一个方面是设置系统级安全管理硬件,如内存保护控制器(MPCs)和外设保护控制器(PPCs)。这些单元虽然也是用于资源分区,但与SAU和IDAU的操作方式不同:
- SAU和IDAU定义4GB地址空间如何划分为安全和非安全区域。
- MPCs和PPCs定义每个内存页或每个外设是否可以从安全或非安全地址别名访问。
使用MPC和PPC方法,可以管理大量内存页或外设资源的目标安全域,即使处理器的SAU和IDAU区域有限。这避免了运行时动态更改地址分区(即重新编程SAU和IDAU),因为这可能导致软件复杂性并容易出错,例如,当地址分区更改时,从非安全软件传递到安全软件的指针可能会意外地从非安全切换到安全。
为了确保系统安全,安全软件开发人员必须确保安全软件使用的资源位于安全地址范围内,包括:
- 安全固件代码
- 安全数据内存(包括栈和堆内存)
- 安全向量表
- 安全外设
这样,非安全软件就无法直接访问这些安全资源。此外,在创建为非安全软件提供服务的安全API时,软件开发人员必须格外小心。
Arm处理器软件开发与安全技术详解
6. 安全API设计考虑
在创建为非安全软件提供服务的安全API时,需要进行多方面的设计考虑,以保障系统的安全性和稳定性。以下是一些关键的设计要点:
-
参数验证
:对从非安全软件传递过来的参数进行严格验证,确保其合法性和安全性。例如,检查指针是否指向合法的非安全地址,数值是否在合理范围内等。
-
访问控制
:明确安全API对安全资源的访问权限,只允许必要的访问操作。避免非安全软件通过安全API过度访问安全资源,导致安全漏洞。
-
错误处理
:设计完善的错误处理机制,当出现异常情况时,能够及时、准确地进行处理,并向非安全软件返回合适的错误信息。
-
性能优化
:在保证安全性的前提下,尽量优化安全API的性能,减少不必要的开销,提高系统的整体运行效率。
7. 安全软件开发流程
安全软件开发需要遵循一定的流程,以确保软件的安全性和可靠性。以下是一个典型的安全软件开发流程:
1.
需求分析
:明确安全软件的功能需求和安全需求,确定软件的应用场景和目标。
2.
设计阶段
:根据需求分析的结果,进行软件的架构设计和模块划分。设计安全与非安全软件的交互方式,确定安全API的接口规范。
3.
编码实现
:使用合适的工具链和编程语言进行代码编写。遵循安全编程规范,确保代码的安全性。
4.
测试验证
:对安全软件进行全面的测试,包括功能测试、安全测试、性能测试等。验证安全API的正确性和安全性,检查安全与非安全软件的交互是否正常。
5.
部署上线
:将经过测试验证的安全软件部署到目标硬件平台上。确保硬件平台支持安全软件开发,并提供必要的安全保护功能。
6.
维护更新
:定期对安全软件进行维护和更新,修复发现的安全漏洞和问题,增强软件的安全性和稳定性。
下面是这个流程的mermaid格式流程图:
graph LR
A[需求分析] --> B[设计阶段]
B --> C[编码实现]
C --> D[测试验证]
D --> E[部署上线]
E --> F[维护更新]
8. 安全软件开发的最佳实践
为了开发出高质量的安全软件,还需要遵循一些最佳实践:
-
使用安全的编程规范
:遵循行业公认的安全编程规范,如CERT C Coding Standard等,避免常见的安全漏洞,如缓冲区溢出、空指针引用等。
-
进行代码审查
:定期进行代码审查,发现和纠正潜在的安全问题。可以采用同行评审、自动化代码审查工具等方式。
-
加密敏感数据
:对敏感数据进行加密处理,确保数据在传输和存储过程中的安全性。可以使用对称加密算法或非对称加密算法。
-
定期更新安全库
:及时更新使用的安全库和框架,以获取最新的安全补丁和功能增强。
-
培训开发人员
:对开发人员进行安全培训,提高他们的安全意识和编程技能。
9. 总结
本文详细介绍了Arm处理器软件开发的不同场景,包括Armv8 - M系统未实现TrustZone、不使用安全世界的非安全软件开发、使用安全世界的非安全软件开发以及不使用非安全世界的安全软件开发等。同时,深入探讨了安全软件开发的相关技术,如Cortex - M安全扩展(CMSE)、Trusted Firmware - M等,以及TrustZone的技术细节,包括处理器状态和内存分离。
在安全软件开发过程中,需要注意安全与非安全软件的分离,遵循一定的开发流程和最佳实践,确保软件的安全性和可靠性。此外,还需要考虑开发平台的安全性和硬件安全功能的支持,以应对各种安全挑战。通过合理运用这些技术和方法,可以开发出高质量、高安全性的软件,满足不同应用场景的需求。
以下是一个总结表格,对比不同软件场景的特点:
| 软件场景 | 主要特点 | 代码更改要点 |
| — | — | — |
| Armv8 - M系统未实现TrustZone | 与传统Armv6 - M和Armv7 - M类似,无安全状态分离 | MPU配置、hOS代码、位带功能、向量表地址更改 |
| 不使用安全世界的非安全软件开发 | 类似场景1,有禁用安全固件API和内存映射差异 | 同场景1,可选禁用安全固件API |
| 使用安全世界的非安全软件开发 | 可利用安全API,需特定RTOS支持,有故障处理差异 | 同场景1,利用安全API,特定RTOS,故障处理 |
| 不使用非安全世界的安全软件开发 | 类似场景1,RTOS需支持安全世界 | 同场景1,RTOS支持安全世界 |
超级会员免费看
3024

被折叠的 条评论
为什么被折叠?



