打印
[应用相关]

发现 STM32 防火墙的安全配置

[复制链接]
658|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
前言
STM32 防火墙( Firewall) 能够构建一个与其它代码隔离的带有数据存储的可信任代码区域, 结合 RDPWRP 以及 PCROP
可用来保护安全敏感的算法。 在
STM32 Cube 固件库参考代码里提供了几个不同的防火墙配置。 那么问题来了, 什么是
STM32 防火墙的应该使用的安全配置呢? 本文以 STM32 参考手册为基础,以最大化安全为目标,来探索发现 STM32 防火墙
的推荐配置。
  

使用特权

评论回复
沙发
盗铃何须掩耳|  楼主 | 2021-12-27 10:22 | 只看该作者
STM32 防火墙介绍
STM32 防火墙保护特定代码/数据不被保护区域之外的执行所访问。代码和数据位于 Flash 存储器中,也可以位于 SRAM1 中。
可选择配置的防火墙的三个保护段如下:
 代码段( Flash)
 数据段( Flash)
 易失数据段( SRAM1) , 可被配置为可执行
防火墙配置激活后, 对受保护代码的访问必须唯一的通过调用门( Call gate) 进行。 防火墙外设监听 AMBA 总线,任何不通
过调用门的访问,将导致系统重启。

Figure 1 防火墙的连接
不同于 STM32 上的 ARM MPU 技术,防火墙激活后,将一直保持激活状态,直至下次系统复位。

使用特权

评论回复
板凳
盗铃何须掩耳|  楼主 | 2021-12-27 10:23 | 只看该作者
防火墙的调用门
防火墙的调用门由三个字组成,位于 Flash 中的代码段以及配置成非共享且可执行的 SRAM1 数据段, 开始地址的前三个 32
位。
 第 1 字: 虚设。总是处于关闭状态。用于保护指令预取造成的对调用门的访问。
 第 2 和第 3 字: 总是处于打开状态。
为了打开防火墙,代码必须跳到调用门的第 2 字执行,且第 2 字和第 3 字的执行不能被中断,否则会导致系统重启。
防火墙的状态图
防火强的配置激活后,处于关闭(Close)状态。在关闭状态下,对受保护区域的访问将被禁止。 跳到防火墙的调用门处执行,
则防火墙打开(open) 。 在防火墙打开状态下,若防火墙控制寄存器(FW_CR)的 Prearm( FPA) 位依然为 0,跳转至非保护
代码将导致系统重启。 将防火墙控制寄存器的 Prearm 位设置成 1,这时任何对非保护代码的访问将导致防火墙进入关闭
( close) 但激活状态。

Figure 2 防火墙的状态转换


使用特权

评论回复
地板
盗铃何须掩耳|  楼主 | 2021-12-27 10:26 | 只看该作者
STM32 防火墙例程
一个 STM32 防火墙的实例可在 CubeMX 固件包里找到。 例如:
STM32Cube\Repository\STM32Cube_FW_L4_V1.6.0\Projects\STM32L476RG-Nucleo\Examples\FIREWALL
工程文件支持 IAR Keil 开发环境,含有两个目录:
FIREWALL_VolatileData_Executable
FIREWALL_VolatileData_Shared

读者可使用 IAR 或者 Keil 打开这两个例子进行编译以及运行。
例程防火墙配置引出的疑问
例程在激活防火墙时使用了不同的配置, 演示了防火墙外设的灵活性与不同的安全性, 具有很好的学习用途,但是在实际应
用中,为最大化安全考虑,我们究竟应该去应用哪一种配置 呢?
配置一: 仅配置保护 SRAM1 中的数据,且将 SRAM1 的数据配置成可执行且非共享。 注意没有对 Flash 的任何地
方配置保护。


/* No protected code segment (length set to 0) */
fw_init.CodeSegmentStartAddress = 0x0;
fw_init.CodeSegmentLength = 0;
/* No protected non-volatile data segment (length set to 0) */
fw_init.NonVDataSegmentStartAddress = 0x0;
fw_init.NonVDataSegmentLength = 0;
/* Protected volatile data segment (in SRAM1 memory) start address and length */
fw_init.VDataSegmentStartAddress = 0x2000F100;
fw_init.VDataSegmentLength = 3840; /* 0xF00 bytes */
/* The protected volatile data segment can be executed */
fw_init.VolatileDataExecution = FIREWALL_VOLATILEDATA_EXECUTABLE;
/* The protected volatile data segment is not shared with non-protected
application code */
fw_init.VolatileDataShared = FIREWALL_VOLATILEDATA_NOT_SHARED;
配置二: 保护 Flash 里的代码和数据,以及 SRAM1 中的数据。 SRAM1 中的数据被配置为不可执行,但可共享。
/* Protected code segment start address and length */
fw_init.CodeSegmentStartAddress = 0x08010000;
fw_init.CodeSegmentLength = 512; /* 0x200 bytes */
/* Protected non-volatile data segment (in FLASH memory) start address and length */
fw_init.NonVDataSegmentStartAddress = 0x080FF000;
fw_init.NonVDataSegmentLength = 256; /* 0x100 bytes */
/* Protected volatile data segment (in SRAM1 memory) start address and length */
fw_init.VDataSegmentStartAddress = 0x20000000;
fw_init.VDataSegmentLength = 576; /* 0x240 bytes */
/* The protected volatile data segment can't be executed */
fw_init.VolatileDataExecution = FIREWALL_VOLATILEDATA_NOT_EXECUTABLE;
/* The protected volatile data segment is shared with non-protected
application code */
fw_init.VolatileDataShared = FIREWALL_VOLATILEDATA_SHARED;

使用特权

评论回复
5
盗铃何须掩耳|  楼主 | 2021-12-27 10:28 | 只看该作者
防火墙配置分析
SRAM1 的共享 Vs. 非共享
用户手册 RM0351 中提到若一段 SRAM1 被防火墙设置为共享(VDS=1), 则该区域总是可被访问,而不用去管防火墙是打开,
关闭还是没有激活。 同时,
SRAM1 中的数据可被执行, 而不需要激活防火墙更不需要打开防火墙。 换言之,共享区域其实
是不在防火墙的保护之下。 因此,为保护
SRAM1 中的敏感数据,我们应该避免使用共享配置, 也就是 VDS 应当是 0  


Figure 3 RM0351 中关于防火强的易失数据段配置成可共享
SRAM1 中的执行 Vs. 非执行
用户手册 RM0351 中提到,若 SRAM1 被配置成非共享(VDS=0)且可执行(VDE=1), 防火墙的调用门序列需要先被执行。这里
有几层含义,一是这段代码已经处于防火墙的保护之下; 二是这段代码可被调用门中的代码调用; 三是这段代码可以是调用
门(参考调用门的描述) 。 前面我们提到防火墙打开后,保护区域之内的执行可以访问保护区域之内的代码以及数据。换言
之, 这里的 SRAM1 执行的代码是可以访问 Flash 里受防火墙保护的代码和数据。 SRAM1 中的代码是可变 的, 为避免不确
定性, 一般情况下我们应当避免 SRAM1 运行的代码访问 受保护的 Flash 代码和数据,也就是建议将 SRAM1 中配置成非执
行。

Figure 4 RM0351 中关于防火强的易失数据段配置成可执行


使用特权

评论回复
6
盗铃何须掩耳|  楼主 | 2021-12-27 10:29 | 只看该作者
是否应该配置 Flash 的数据段( Non-volatile data
前面的例程配置一仅配置了 SRAM1。然而用户手册 RM0351 中提到, Flash 里的数据段未被定义,则 FW_CR 寄存器可在任
意时刻进行修改,而不用管 防火墙是打开还是关闭。  


Figure 5 RM0351 中关于防火强控制寄存器的动态配置方式的描述
也就是说, 防火墙相比较 MPU 的优势“ 配置有效直到系统复位” ,在这种配置下不再存在了。例如在例程“ 配置一” 里,
SRAM1 的代码配置成可执行非共享,受防火墙保护。然而在防火墙设置好且处于关闭状态后,我们依然可以通过保护区域之
外这样的代码将该保护去掉,例如将它配置后再次改成可执行且共享。
__HAL_FIREWALL_VOLATILEDATA_SHARED_ENABLE();


使用特权

评论回复
7
盗铃何须掩耳|  楼主 | 2021-12-27 10:30 | 只看该作者
推荐的防火墙配置
综合前面的例子和分析,为最大化安全考虑,我们推荐使用防火墙 时使用以下典型配置。 它配置了三个保护段, Flash 中的
代码和数据,
SRAM1 中数据; SRAM1 中数据配置成不可共享且不可执行。 同时要注意修改编译器链接文件将三块受保护的
代码和数据分别放置到相应的下列定义的区域
(Region)里。 链接文件, 对 IAR .icf 文件, 对 MDK .sct 文件。
/* Protected code segment start address and length */
fw_init.CodeSegmentStartAddress = FW_CODE_START_ADDRESS;
fw_init.CodeSegmentLength = FW_CODE_LENGTH;
/* Protected non-volatile data segment (in FLASH memory) start address and length */
fw_init.NonVDataSegmentStartAddress = FW_DATA_START_ADDRESS;
fw_init.NonVDataSegmentLength = FW_DATA_LENGTH;
/* Protected volatile data segment (in SRAM1 memory) start address and length */
fw_init.VDataSegmentStartAddress = FW_VDATA_START_ADDRESS;
fw_init.VDataSegmentLength = FW_VDATA_LENGTH;
/* The protected volatile data segment can't be executed */
fw_init.VolatileDataExecution = FIREWALL_VOLATILEDATA_NOT_EXECUTABLE;
/* The protected volatile data segment is not shared with non-protected
application code */
fw_init.VolatileDataShared = FIREWALL_VOLATILEDATA_NOT_SHARED;
因为控制寄存器 FW_CR,包括 Prearm 位、 共享执行、 设置,只能在防火墙打开时才能修改, 因此在推荐配置下, 典型的调
用门代码执行序列应如下:
  


 清除 Prearm 位 ( FPA)
 执行安全算法
 清除所有中间数据
 清除 CPU 寄存器信息
 设置 Prearm 位 (FPA)
 退出保护区域
结论
本文根据 STM32 参考手册, 提出了一个 STM32 防火墙的安全配置, 可在实际 STM32 防火墙的案例中直接应用。也可以利
用本文加深对
STM32 防火墙功能的理解。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

376

帖子

0

粉丝