实战经验 | 移植 SBSFU 到 STM32G070 的过程

发布者:BlissfulDreams最新更新时间:2024-09-12 来源: elecfans关键字:实战经验  移植 手机看文章 扫描二维码
随时随地手机看文章

01

前言


客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。


02

基于STM32G070和STM32G071的SBSFU 实现差异


在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。


STM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?


图1.STM32G0 的 SBSFU 安全实现


如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。


图2.STM32G0 内存安全映射(运行 SBSFU 时)


回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗?


我们再来看下对于安全启动而言, 它需要实现哪些基本功能?

1> 不可更改不可绕过的一段启动代码

2> 每次复位必先执行安全启动代码

3> 验证系统配置的完整性

• 时钟配置

• 寄存器配置

存储器保护设置, ….

4> 启动信任根服务

• 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改)


这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如BOOT_LOCK,它只是”参与”实现了唯一启动入口这个功能。从图 1 可知, 除了BOOT_LOCK,还有 RDP,那么在缺少 BOOT_LOCK 的情况下,RDP 是否也可以实现唯一入口启动的功能。很明显,在 RDP2 时,MCU 的入口是唯一的。也就是说,没有 BOOT_LOCK的参与下,RDP2 一样可以实现安全启动对唯一入口启动的需求。RDP2+WRP 就可以实现安全启动的前两条基本要求。而第三条基本要求,完全是 SBSFU 内的纯软件实现。第四条要求,通过 RDP2+WRP+MPU 也可以实现。其实, 在缺少了 PCROP,BOOT_LOCK 和Secure User Memory 后,STM32G070 的安全特性其实跟 STM32F4 差不多,我们不妨来看下STM32F4 是如何来实现 SBSFU 功能的。


图3.STM32F4 的 SBSFU 安全实现


如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。


图4.STM32F4 的 SBSFU 内存映射


到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行!


在确立了大方向后, 我们接下来看具体如何实现。


03

开始移植


第一步 : 确保原始工程运行正常

从 ST 官网上下载最新了 SBSFU 包(v2.6.1),打开STM32CubeExpansion_SBSFU_V2.6.1ProjectsNUCLEO-G071RBApplications2_Images目录,其下有三个工程,2_Images_SECoreBin(后续简称 SECoreBin 工程),2_Images_SBSFU(后续简称 SBSFU 工程),2_Images_UserApp(后续简称 UserApp 工程)。使用对应 IDE 按顺序依次编译, 然后将 SBSFU 工程生成的 bin 文件烧录到 NUCLEO-G071RB板内,打开 Tera Term 串口终端, 通过 Tera Term 烧录 APP 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。


第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭

打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :



重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。


至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。


第三步 : 移植到 STM32G070RB

首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。


以 Keil 为例 :


图5.device 选择 STM32G070RBTx


图6.C++编译宏修改


STM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 :


打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :


图7.STM32CubeIDE 下的 device 修改


修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:


图8.STM32CubeIDE 的 MCU 配置


由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。


至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。


首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :



原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :


在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:



如上红色部分即为修改处。


至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。


04

测试安全保护特性


当程序跳入到 APP 后,显示如下界面


图9.测试主界面


当选择 2 Test Protection :Secure User Memory 时,结果会出错 :


图10.测试保护


很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:



原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。


首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:



同样的尝试读取密钥:


图11.UserApp 尝试读取密钥


测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。


仔细查看图 2 的 STM32G071 的 SBSFU 原来实现中,SE Key 是通过 PCROP+Secure User Memory 来保护的,现在换成 STM32G070,原本 Secure User Memory 用来作隔离机制, 现在换成了 MPU, 而原本保护 SE Key 的 PCROP 在 G070 中压根就不存在,于是 SE Key 只剩下 MPU 来保护,因此,我们接下来得着重分析 MPU 对 SE Key 的保护。


为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:



然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭:


如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:



这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?


在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:


图12.UserApp 运行时的 flash 和 RAM 状态


从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。


于是在跳转到 UserApp 的内存函数中配置 MPU:



注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。


对应的, 我们在 UserApp 中增加对 Header 的测试函数 :



重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:


图13.测试 SBSFU 的 64K 代码区


发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:


图14.测试 Header 对应的 2K 区域


发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。


最后再恢复之前注释掉的除 MPU 之后的保护。


05

后述


本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。


关键字:实战经验  移植 引用地址:实战经验 | 移植 SBSFU 到 STM32G070 的过程

上一篇:你应该知道的STM32F04x单片机时钟切换教程
下一篇:应用笔记 | STM32WB基于Custom Template实现客户定制BLE私有协议

推荐阅读最新更新时间:2026-03-23 10:32

用户手册|X-CUBE-SBSFU STM32Cube扩展包入门
引言 本用户手册介绍了如何开始使用X-CUBE-SBSFU STM32Cube扩展包。 X-CUBE-SBSFU安全启动和安全固件更新解决方案使STM32微控制器内部固件可升级到新版本,添加新功能,和纠正潜在问题。升级过程是以安全的方式进行,以防未经授权的更新,并阻止访问设备上的机密数据。 安全启动(可信根服务)是一种不可变代码,总是在系统复位后执行,它检查STM32静态保护、激活STM32运行时保护、然后在每次执行前验证应用程序代码的真实性和完整性,以确保无效或恶意代码无法运行。 安全固件更新应用通过使用Ymodem协议的UART接口接收固件映像,检查其真实性,并在安装代码之前检查其完整性。固件更新可更新整
[单片机]
用户手册|X-CUBE-<font color='red'>SBSFU</font> STM32Cube扩展包入门
实战经验 | Keil、IAR、CubeIDE 中变量不被初始化方法
01 前言 有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如 Bootloader 跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作做总结,分别介绍使用 Keil,IAR 和 CubeIDE 的操作方法,本文中所用芯片为STM32G431RBT6。 02 IAR 实现变量不初始化方法 IAR 实现相对简单,直接使用“__no_init”这个关键字即可,也就是在变量前面进行修饰: 为了验证是否执行成功,可以考虑周期性让系统复位,看变量的变化,比如下面的示例程序让系统周期复位,会发现每次 Test_NoInit 数据
[单片机]
<font color='red'>实战经验</font> | Keil、IAR、CubeIDE 中变量不被初始化方法
STM32H5 DA证书链实战经验
01 前言 本文是上文 《STM32H5 DA 之初体验(带 TrustZone)》的后续之作。倘若你还没有阅读此文,那么建议你先阅读下,然后再回过头来阅读本文。 之前我们已经讲过了如何通过 DA 认证来回退芯片产品状态,或者重新打开调试口,这样开发人员在芯片为 Closed 状态下时仍可以调试芯片。在这个 DA 认证过程中,有使用到两个东西:证书和私钥,它与之前已经预配置到芯片内部的 obk 文件是对应的关系。也就是说, 如果你已经预配置了芯片, 但对应的私钥文件或者证书丢失或忘记保存了, 那么此芯片多半是无法再还原了, 除非你找到对应的私钥和证书。 私钥是如何来的 ? 如上文所述, 是通过 TPC 工具生成的, 如下所示
[单片机]
STM32H5 DA证书链<font color='red'>实战经验</font>
实战经验 | TouchGFX 控件附加 ClickListener 功能的方法介绍
01 引言 TouchGFX 是专用于 STM32 的图形界面设计软件,可用来低成本开发优秀的图形界面,TouchGFX 现已变的越来越流行。为了帮助客户更加深入地理解和使用 TouchGFX ,本文介绍了 TouchGFX Designer 中的 Mixin 功能,从基础示例 Button Example 出发,为文本框控件添加 ClickListener (Mixin 功能中的一项),并对源代码进行简单剖析。期望能帮助客户更深入地理解 STM32 TouchGFX 的相关功能。 02 TouchGFX ClickListener 模板的使用 2.1. C++模板编程基础 在示例介绍之前
[单片机]
<font color='red'>实战经验</font> | TouchGFX 控件附加 ClickListener 功能的方法介绍
51单片机程序及调试步骤实战经验
我刚参加工作的时候,用的是stc 51单片机的,51单片机不像stm32那样可以通过st-link在keil上面在线仿真。 有时候出现bug的时候,非常难找问题,要一段一段屏蔽然后测试。 在刚开始接触开发的时候,我非常不习惯用在线仿真,大概是因为没用过。 记得有一次进了一家公司做行车记录仪,用的台产GRAIN的单片机。 那时候基本上没什么资料,就一个dada sheet和demo程序。 在开发之前,老大安排了给我一个任务,就是把这个仿真环境先给搭起来。 相当于是他们原厂没有的东西,让我去搞定,这个芯片是基于Fa626TE core的32位控制器。 网上的资料太少了,光是测试搭建这个环境花了半个多月,最后还没搭建出来。
[单片机]
2018 年将打响 AI 战争,7 条实战经验帮你战胜恐惧
编者按: 不管是对科技巨头还是对创业公司,人工智能可以说是移动互联网时代以来最大的一个机遇。但是,人工智能同时也是让大多数人感到非常困惑的一项新技术,对它的发展现状和未来都非常迷惑。为了消除人们对人工智能的迷惑,本文首先将简单介绍人工智能的一些发展现状,接着会重点罗列几个不同行业的不同企业顺应和利用人工智能潮流的7条实战经验,看人工智能是如何帮助他们在竞争中脱颖而出的。希望这篇文章能让你知道如何才能更好地顺应人工智能浪潮并最大程度地从中受益。 不久前的一个周一上午,马斯克在Twitter上发布了自己对第三次世界大战将如何开始的预测:“真正有可能引发第三次世界大战的,是AI(人工智能)”。 马斯克的这个警告是针对俄罗斯总统普京上周五
[安防电子]
做几年无线射频实战经验分享
 差不多算起来做无线射频(RF)也有几年吧,在这我也和大家分享一下实战经验吧,个人文采不是很好,写得不好还请大家不要见笑。 一、硬件:    1、PCB板,如果你想过认证最好是做4层板,以我多年的经验一般你做4层板加滤波器,2次谐波和3次谐波是很容易过的。注意:过认证最好是要做到+/-5dbm余量,因为是仪器的差别嘛!如果不过认证那些就无所谓了。还有考虑布线,直线,不要用90度走线,建议:一般用45度角或弧线! 2、元器件用料,我们就在用料上面选错过,就是在电子城买的那种料,然后故障不断。选用差的电容,它会漏电,导致耗电非常之大,如果你是做低功耗,电池使用周期长,在这你一定注意,一旦用差的电容,后果不堪设想,你要找是那
[单片机]
步进电机驱动的设计、选型实战经验总结
步进电机是一种作为控制用的特种电机, 它的旋转是以固定的角度(称为"步距角")一步一步运行的, 其特点是没有积累误差(精度为100%), 所以广泛应用于各种开环控制。步进电机的运行要有一电子装置进行驱动, 这种装置就是步进电机驱动器, 它是把控制系统发出的脉冲信号转化为步进电机的角位移, 或者说: 控制系统每发一个脉冲信号, 通过驱动器就使步进电机旋转一步距角。所以步进电机的转速与脉冲信号的频率成正比。所以,控制步进脉冲信号的频率,可以对电机精确调速;控制步进脉冲的个数,可以对电机精确定位目的。步进电机通过细分驱动器的驱动,其步距角变小了,如驱动器工作在10细分状态时,其步距角只为‘电机固有步距角‘的十分之一,也就是说:‘当驱动器
[嵌入式]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved