你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32将移植 SBSFU 到 STM32G070过程分享

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:02
01前言
5 r0 j4 J- s) B% `+ U客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。- Y9 \. I3 @0 f+ s
- N; C$ u& f  k+ w1 p; T4 {

. l) F: X8 j! q2 K$ @  X( K2 B02基于STM32G070和STM32G071的SBSFU 实现差异7 w# \  Y1 C6 t, C- J( ~3 x
在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。
) j( u) J3 O! q  J% T1 D5 Y& m( O" u6 Y* \. z6 c1 X$ }1 V
STM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?) {- ^3 v+ K" i7 l
+ u& \( w1 x8 ]( ]: ?0 i
微信图片_20231211140158.jpg

  P  J. ]' y& v
2 }* E% M6 o& y. P+ W
图1.STM32G0 的 SBSFU 安全实现
# g0 u  G3 h* U3 m
9 |( a2 S1 s* N' N% e  ^
如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。
$ x- F% n& G% m( h& i( p" L- Y! b
微信图片_20231211140155.jpg

( b6 x, Y6 n, K3 j0 z1 `5 \
图2.STM32G0 内存安全映射(运行 SBSFU 时)
: O  P6 x! D3 {" X& b# I
  J( H4 ~7 L& Q  x$ s
回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗? 6 o. }% x1 @$ ?, z

7 O4 O! B3 g( o$ A- e3 ?我们再来看下对于安全启动而言, 它需要实现哪些基本功能?
1 A$ O- N' a4 j3 \" j( I, y- A& I  a5 S1> 不可更改不可绕过的一段启动代码+ B$ }- @( g' I( w6 T
2> 每次复位必先执行安全启动代码
8 Y: V% P  O) p/ q; Y3> 验证系统配置的完整性6 W6 S" @) {5 B. X6 }  C, r
    • 时钟配置
( s2 u% ~3 Q+ P% F  y) X* g    • 寄存器配置
' u; m' {/ [& p, m% E, ?    • 存储器保护设置, …." F. P5 s" {+ y8 L; F; p. o, x* ^: e
4> 启动信任根服务& z0 L3 z  d8 B* i1 p/ E
    • 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改) ; Y& O: \/ \* Q: s" [
8 q  n' g% r- Z" S
这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如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 功能的。
5 @% \3 }" Z  l2 e4 u, A
- a4 u4 J  H+ W. D9 z. ^+ K1 E
微信图片_20231211140151.jpg

# |/ Q4 H9 i- q: l# X1 A
图3.STM32F4 的 SBSFU 安全实现
. S; S* b1 o+ f" L& ~% J8 s: h
$ c, g  y) l# y% P+ S* |8 c
如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。, @5 u% z5 t/ \& i5 W% [

* [/ y; y6 T" P3 G; h
微信图片_20231211140148.jpg

/ I$ ]& K" d" W5 F: ]
图4.STM32F4 的 SBSFU 内存映射
* ^3 t$ j$ H; O  B+ v" \

9 E" a9 D( E, P* l8 d7 X) |到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行!
/ R/ }- @( r3 j4 Z# P9 m
0 f4 D% h# C. r在确立了大方向后, 我们接下来看具体如何实现。
  I* |! G3 g, R- f1 M5 y' o& k7 l3 n4 m, T0 Q2 ?
03开始移植( ]- N( W3 b( S' e& b* V! n
第一步 : 确保原始工程运行正常5 o; W, V! d$ {- D+ E  i9 X' u
从 ST 官网上下载最新了 SBSFU 包(v2.6.1),打开STM32CubeExpansion_SBSFU_V2.6.1\Projects\NUCLEO-G071RB\Applications\2_Images目录,其下有三个工程,2_Images_SECoreBin(后续简称 SECoreBin 工程),2_Images_SBSFU(后续简称 SBSFU 工程),2_Images_UserApp(后续简称 UserApp 工程)。使用对应 IDE 按顺序依次编译, 然后将 SBSFU 工程生成的 bin 文件烧录到 NUCLEO-G071RB板内,打开 Tera Term 串口终端, 通过 Tera Term 烧录 APP 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。 ( [3 J5 i  R; q+ s! ?: N
( \% j5 I" f7 `- |
第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭7 f* S* R& V0 Q2 [* E
打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :* V% a# c. [; j+ S

) U9 d2 ]2 T8 Q- Q# R! b+ n
微信图片_20231211140145.jpg
2 l# R0 p8 p0 M3 F' N# u& O" Q1 s
0 U$ `6 q" P+ @9 y7 |
重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。 9 f3 t! J9 b. A# F1 L1 c8 }
. j& `" i6 g8 u) z) d. A( |+ P
至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。
! B" e6 a3 t( |+ O6 E
% a- ~4 l* m) b8 U9 Y第三步 : 移植到 STM32G070RB
; N/ r4 ~3 C% R4 W首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。
  U/ W  l4 U2 m4 V4 {% ?
; i/ W) q& X8 g( H" \# F0 W以 Keil 为例 :$ ~$ w9 Y: B+ K: M
微信图片_20231211140142.jpg
- P! Y4 ]( i2 ^) |$ L
图5.device 选择 STM32G070RBTx

! i# l7 U0 p/ U6 N4 t

0 K4 |+ G# k# w6 b6 }
微信图片_20231211140139.jpg

3 S  R4 Q/ ?' `" q
图6.C++编译宏修改
% o- z* M0 F* ?/ J; |) c# J

- C. g- F+ q: i5 s* rSTM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 :
- t! m- M' x& s  P8 p& r/ D" ?# O: w- O' G
打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :2 k: J5 [# S) M) `; l6 U

$ x' G) B) P4 e' x7 \6 M( Y
微信图片_20231211140136.jpg

7 K+ P4 |8 I9 \4 [  S6 \
图7.STM32CubeIDE 下的 device 修改
4 A" S- n$ B! {3 f% H
! B) |# D# Z  Q1 R" `
修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:' E3 M3 G+ D2 Q# g+ ?
& P1 S/ W1 o6 S6 N7 S
微信图片_20231211140132.jpg
$ X& J) W" z4 M0 q! M5 n
图8.STM32CubeIDE 的 MCU 配置

9 F7 m* v" f7 R; u: J

/ r. {6 A3 C3 e% U# W' l0 ~" Q  k由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。 4 A3 p3 d: @6 j) t0 p
, f( v2 v$ e( ^7 I
至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。
1 t# a8 o4 x3 p2 ~

; K* W  g8 N6 `) a! P3 Q! V6 |1 a$ e: A首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :: t3 q; u+ V3 \1 b5 A, f8 s
3 K! T8 W/ L/ H$ Z
微信图片_20231211140129.jpg
7 A, {5 l8 Y  X/ }/ o5 K' F, j. E. B- r3 j$ k0 ^
原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :: [" B0 @3 l5 t) y
& t8 q/ T) {' ~; L. L; b0 `
在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:% X6 C: ^, i; X) K0 `5 h3 ^

, ^. g1 g* B5 X* S& N& o" c
微信图片_20231211140125.jpg
9 b; T! k! {1 `& g! u 微信图片_20231211140121.jpg
6 j# }2 l) z2 R" ~1 W  Z, |8 c8 E' g1 w& H2 L9 Y. k
如上红色部分即为修改处。
0 }0 A& W8 ^: Q; L4 m+ V; g6 h; P# ~1 S
至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。( @: A, _7 R; B1 X$ u7 o

# u6 F, _. Q# s2 _" [

, v% D* ~: r/ b$ h% ^- l04测试安全保护特性
# v. ~8 S9 ^7 L$ ]. d当程序跳入到 APP 后,显示如下界面
6 |$ Q3 ^- D3 C, w) \+ N7 |% u
# X2 `* M! a# M0 ?4 m/ f
微信图片_20231211140118.jpg
5 G* H5 p5 S2 h4 j' ~. T- f  Z8 N
图9.测试主界面
! W$ j& Y' W, R% w% \& g2 r

* C* K7 I2 o( t3 c6 ]& X; Z% [; r# c- i, j3 B0 n
当选择 2 Test Protection :Secure User Memory 时,结果会出错 :/ _1 `7 N9 n0 ~% N

8 f5 [1 C+ m! |  T: d  \7 Z: K5 \, H
微信图片_20231211140114.jpg

# c. Q" P% c/ p
图10.测试保护

/ E' w. j) K8 _' u8 R
0 y" n3 z/ ^; s5 F' D) W$ U
很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:2 t  p7 R& h6 n0 u0 I! Q# O

; L. s- z9 p% }+ E! x9 I
微信图片_20231211140111.jpg 4 e3 j7 r2 r# e1 ]  |
微信图片_20231211140108.jpg
4 ^" y. m, x- k% Z! r5 x
4 T6 }4 L3 X3 p原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。0 w9 _& e6 s" w& |; p
" m5 Q+ A1 W0 u$ x
首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:5 H9 L# k: q" |% K
, f1 f2 ]5 Y. ?8 y
微信图片_20231211140041.jpg 9 {9 ^% q4 f. Z

2 O. I% q5 v& D$ N5 J- j同样的尝试读取密钥:  {# ^! d5 b8 ^: X3 o  P! ^
2 p. j, C8 w0 W; z& q
微信图片_20231211140036.jpg
) e# {3 ]2 m: f+ w% h" J
图11.UserApp 尝试读取密钥
* |: d% n+ @- F

; X1 X% D3 {' G4 U0 k! v
测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。 ( V6 z1 ]/ d3 C* ]% K

& O" ^( ?$ l" \0 ?$ Q仔细查看图 2 的 STM32G071 的 SBSFU 原来实现中,SE Key 是通过 PCROP+Secure User Memory 来保护的,现在换成 STM32G070,原本 Secure User Memory 用来作隔离机制, 现在换成了 MPU, 而原本保护 SE Key 的 PCROP 在 G070 中压根就不存在,于是 SE Key 只剩下 MPU 来保护,因此,我们接下来得着重分析 MPU 对 SE Key 的保护。 ) A# g8 m; X- r- m
$ e( B# }8 K1 y" F1 {
为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:
, f: }/ x+ N/ `* e: f  A7 f' t* a1 I4 I  J3 C
微信图片_20231211135943.jpg
) d4 I7 T' V7 D1 f7 v
微信图片_20231211135940.jpg
7 W9 ?" r4 d5 }
8 H7 R* \+ x, L然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭:   b, C! S( p0 T+ X. N4 }$ X! M

+ ~* \9 N. U1 O% _; t) E3 f如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:) X9 l3 l4 H3 O$ q+ k6 O
5 f) _6 w7 n; o
微信图片_20231211135937.jpg
# p: E% F" ^. F" N4 F7 i3 b
/ x6 Q, l* o- p( e8 e2 F/ H% ]
这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?" K' J$ r9 l) `" v
4 r' ]4 ]7 {" D+ `5 c. {1 h
在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:( R& R; T2 D9 Y. v, l, t2 @! E

; w; U8 I: w( s4 r0 a
微信图片_20231211135933.jpg
3 D* C( }& {- _3 J. Y
图12.UserApp 运行时的 flash 和 RAM 状态
; h8 Z: u5 J$ I# Q

! ?8 m1 ]0 k, t+ ~0 i从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。8 Y( C9 B6 ~9 B. e
. J* o% R0 T  |% B2 y' f3 _6 _4 Y
于是在跳转到 UserApp 的内存函数中配置 MPU:1 I4 u) N6 ^: S- `* L7 e* N, E! \0 r

! S: G  ?* s; @+ Q
微信图片_20231211135929.jpg . [- V( p0 r" b2 Z
微信图片_20231211135926.jpg / v; N8 c$ g( _1 E! q! K) n

. ?8 {4 o$ q, r* o 微信图片_20231211135923.jpg 9 w  o6 D! D4 a; {0 t1 M3 R8 c" D
) v: B2 `& o8 L% A5 U1 N
注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。
# @2 _  l( G0 T; `* B! }% m5 k; N1 k) v$ s" ]& x8 F) O
对应的, 我们在 UserApp 中增加对 Header 的测试函数 :
7 y9 @) U0 e- ?% Z4 l/ \! y0 p9 W
. `; l* n" Q% E
微信图片_20231211135920.jpg & A, {3 w, s! M7 `
; F& g6 f$ v1 Z( x$ J+ r+ _
重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:; L/ a% k: @% N9 Y- K9 t

( I0 V$ |* L0 b% t' V# e
2.jpg
( ]# V% F1 t- O( K9 |" g
图13.测试 SBSFU 的 64K 代码区

& {( v* M; B3 h, N; B8 I. @+ W# Q
* Q& f" W! R; q, s2 n
发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:
/ z, w% ]; r% K) M3 \8 w% e  Y& _; C  {$ L+ d
微信图片_20231211135908.jpg
- Z+ ^1 T! Q! [+ Y
图14.测试 Header 对应的 2K 区域

; R' b' s' X3 _% ~( N4 c, G% O

, j$ J! H( H3 z9 j4 X4 h发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。
" i9 C9 v6 @) G' n  D" O& ]' `. }
# }: f  V% \* }* y  Q最后再恢复之前注释掉的除 MPU 之后的保护。% ]7 o; V: U5 A- d; @9 o

# e$ ?+ C& v/ y1 X) P05后述
/ P( T  O$ U& {. n# J; A* f% M  L& U本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。/ s. V$ N; g( }8 M0 |

. H  k  Z1 N+ [' j如有侵权请联系删除
: `4 }5 p+ w8 Y1 e: P转载自:STM32单片机0 H8 G# C( w1 I5 z5 X" m1 e

8 o+ [8 o' B" y
1 O+ U8 r: k4 n- p! x( p* _1 L- Y
6 O) S3 A' f. u% ?
' V* o! U2 z4 k  H
1 收藏 1 评论1 发布时间:2023-12-11 14:02

举报

1个回答
watershade 回答时间:2023-12-13 10:06:30

不明觉厉,SBSFU还真没有涉猎。看来很多东西不知道。

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版