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

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

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:02
01前言
: Z! h/ g" R# A5 p- U4 G客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。4 C1 o7 m. e! y3 r7 d5 h( q) [
" G$ S) p8 i6 M! R& u! b

+ d+ d! ~1 e+ v" G) h02基于STM32G070和STM32G071的SBSFU 实现差异
* ~- p  d  Z. E# D9 I在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。 1 _6 J4 [% w% q9 B# \& F

$ U$ \0 S# ]7 I1 H( T4 bSTM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?+ `0 u; p" R, l( L9 Y, n' ?. c
- _- l! e( t. T, v9 v
微信图片_20231211140158.jpg
$ G; z: a" ]- U2 t1 z, ^: v! y* K* M* J  [5 q

6 G3 @- r" O+ d8 H% l; ]$ E2 v7 o
图1.STM32G0 的 SBSFU 安全实现
( t$ Z9 F. K# ~( h
: w  d6 h( t  ~% Q! h% H" Y
如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。, {: y* o! a' f& z, b' j) d! N
4 S! e- g" v- C% k8 r
微信图片_20231211140155.jpg

$ O. O3 u" t, E  R
图2.STM32G0 内存安全映射(运行 SBSFU 时)
& N. ]+ N# i; Y' V7 D

5 r- o' u  h+ ~2 b# X) U' O回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗?
+ S- b$ G& g3 U8 W# D# A5 ?- [9 h* k8 H8 c9 {
我们再来看下对于安全启动而言, 它需要实现哪些基本功能?
6 Y& j+ [8 P) O( v1> 不可更改不可绕过的一段启动代码! j0 U0 D: P% z5 b9 Q3 b$ G, O! p- g
2> 每次复位必先执行安全启动代码
. ?( i) Q$ h: Y. }% y: K- a7 F3> 验证系统配置的完整性
0 M( t" l/ f% x% a7 ]- y: Q    • 时钟配置
" [9 p! i; X  U; q    • 寄存器配置9 V' W$ }2 e, K0 Q' G* d
    • 存储器保护设置, ….
" t3 c* y! e; w6 e4> 启动信任根服务1 a3 y5 I  v6 G/ d4 |% i9 Y
    • 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改) 4 S6 a; L7 x0 n; Z' r5 v

3 p0 {" F# e$ z4 K, Y* `$ e这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如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 功能的。
* H  N3 y( _2 v1 y& Q6 j) w4 c% O1 b/ q" V* e% b+ @' d
微信图片_20231211140151.jpg

, W5 Q3 F( S: t
图3.STM32F4 的 SBSFU 安全实现
! ~$ [* C% n, V  k3 Z

- u. r! [& _' ^2 @; b如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。
( U8 u7 b) u+ ^+ R. R1 ~! e  q! y, E$ Q5 \% q
微信图片_20231211140148.jpg
4 \, Y) }8 m; i+ u
图4.STM32F4 的 SBSFU 内存映射
4 y1 h3 {) [9 L+ Z1 G4 d

( f: D! s2 z, a% E. I到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行! + F5 {4 c9 n& u$ I" A/ ?
. I& |! T. f5 p! F
在确立了大方向后, 我们接下来看具体如何实现。/ ~" y4 J8 x" o: X3 C! `3 b. P+ f
2 {$ ^* `& u/ ]. C) U; x% E3 m
03开始移植
  a  e- C  q7 z  H第一步 : 确保原始工程运行正常
  j6 d4 c1 a/ Y& J从 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 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。 , p' Z1 Y2 j8 M# m; Z6 u" _

; r+ G- P5 n4 D" p3 s" F3 A' _第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭
. D, _' X2 |+ V. ~  t打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :1 q' k. T- F& ]( E- z& W( d

5 X7 F) e+ T- z0 K$ W! e/ A7 d; h
微信图片_20231211140145.jpg

9 Y% l! ~) Z0 o
6 {% Q! k% F' a7 d% E4 H
重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。 - Q) m7 D& g/ S$ y& _

8 _; M; W0 \3 i( @+ c至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。
3 I1 m% I- Q1 K; j" w4 L
3 d4 V/ O5 w" M# r9 ]' Y第三步 : 移植到 STM32G070RB
* b3 g( G; t: k% _. m& z首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。 ( N' a- K9 j* ]2 S5 T
: x% i8 r. M0 V# C/ D% y8 ?& Q+ F( g
以 Keil 为例 :. a. e* C% ~0 v# Y
微信图片_20231211140142.jpg

1 Z4 C+ j" `5 {9 D3 f* A& R
图5.device 选择 STM32G070RBTx
1 u7 s3 Q4 _/ c5 h5 F- Q# P
8 W7 N7 [( ^5 L2 R, N+ A/ L# {
微信图片_20231211140139.jpg
6 P6 }! |. @3 _: C' I
图6.C++编译宏修改

% G$ P+ o# ]* C/ U7 i% F

7 v, k, r4 t; \8 ISTM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 : 8 [9 ~" @% o2 t& p, Y" _
) D- Y* [% g4 N. x4 K; w, H
打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :
0 }& `0 S8 s. O: q0 x' H% @8 p. b; Z( W/ o/ p
微信图片_20231211140136.jpg
1 m* t7 s! L* P0 L
图7.STM32CubeIDE 下的 device 修改
2 p2 l& Q1 {4 Y' Z

7 m* \2 u& P8 s修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:2 H4 s. r  c/ ~
& H  s: {+ Q  w. J) }
微信图片_20231211140132.jpg
) C  n# E3 |. l# ?+ U# J. G
图8.STM32CubeIDE 的 MCU 配置

9 n1 G, P; L! |8 B! G  [
' [% B- a3 e+ \6 T
由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。
1 E( ~% L5 G' j% i9 G- T" e7 y# W7 v) [& @
至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。
$ B5 T6 w1 G- w+ u2 T6 u" K) Q

* F4 P9 [2 L, k5 C' e8 B% R2 r首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :; W. f* S6 I  Y& A8 C/ R6 @6 }
' g9 y4 B! H" c  U- t& X' `% \* y! e
微信图片_20231211140129.jpg
2 [8 H% P1 i2 S: f" y& D( G. P# \/ _0 q
原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :% d7 b2 s3 Q$ `+ T
& i7 n2 D* G6 k+ B
在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:
5 O4 c1 G9 ?$ p5 m% R- D9 w- z! ?+ |" t& x% f  F2 v  a
微信图片_20231211140125.jpg . b, Q1 O; X) E# L) E0 f2 F
微信图片_20231211140121.jpg
1 |' }, m) Z, o9 r/ S0 w' a
, O+ ~; n8 \* v* G4 L% X如上红色部分即为修改处。
" c6 R# @& Z( ?" c8 f8 L' H% i+ _7 l8 j# I% F7 O
至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。
# w2 j: A8 @! \# A' j1 N! [, J8 p3 M5 z. W0 P7 Y

! \9 {- G& B2 X04测试安全保护特性
2 E* j1 A8 n4 X2 ?当程序跳入到 APP 后,显示如下界面: s9 ^' l% z0 @

$ E, c9 W$ x! y2 L8 k6 ^
微信图片_20231211140118.jpg
1 s& f9 d3 W7 t) |; ~8 Y
图9.测试主界面
- R* P  m3 T) y6 u0 E

, Q9 @5 m, y" n& j4 Z! @" f: d. W8 m1 G
当选择 2 Test Protection :Secure User Memory 时,结果会出错 :+ X9 L" A7 Q: b
' X7 J5 h7 R  A% C
微信图片_20231211140114.jpg
6 A) i/ W8 U9 f2 A
图10.测试保护

! n! I1 D% \; h$ A5 q, Q% ^
. k  ?  ]# q: n7 g1 i
很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:
5 u$ q# U! a  k3 m$ F2 y! z* T
' f3 ~+ X+ D! u1 F3 i' }, M9 |
微信图片_20231211140111.jpg 8 A3 V: ]3 ~" |
微信图片_20231211140108.jpg
3 o3 f1 U$ q1 y- v0 Z9 u2 a+ E, ?, H
原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。
! _. R( C3 H/ n6 b6 Z; ]& m

- `: _+ o, d- e+ }+ j  [首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:3 A, M' y& `) G, g* }

$ s* d  D& y) n+ S
微信图片_20231211140041.jpg
+ v3 f" z, b$ `* M  N& r
" _: X) c# |) l  I2 L同样的尝试读取密钥:1 Y2 b6 b6 D, k, a- _
/ y  l) }' o2 V. P/ X1 x% T: R5 D
微信图片_20231211140036.jpg

" ^: a, [% @) v" I$ ^: O# ]
图11.UserApp 尝试读取密钥
4 `8 u+ \+ Y% d; S4 o

- b: g: c$ i# I* D" {& `4 i% w
测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。
3 Q" p* p! ]9 a4 `  S* ~
5 J6 G4 z5 i  m- F仔细查看图 2 的 STM32G071 的 SBSFU 原来实现中,SE Key 是通过 PCROP+Secure User Memory 来保护的,现在换成 STM32G070,原本 Secure User Memory 用来作隔离机制, 现在换成了 MPU, 而原本保护 SE Key 的 PCROP 在 G070 中压根就不存在,于是 SE Key 只剩下 MPU 来保护,因此,我们接下来得着重分析 MPU 对 SE Key 的保护。 + f/ L, i. g9 u5 ^4 V* `) B

" G4 z2 w6 o' Z; r# ?+ S为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:, P- D5 O- c0 D2 b  K

' h; }- U8 L  |9 d, z1 G+ b. R' l$ E
微信图片_20231211135943.jpg 2 Y/ {- G5 X, G4 q  g
微信图片_20231211135940.jpg   M& O; x3 b# v, w
8 q$ ~9 H# L/ j( i- z! R
然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭: 7 j5 n& A0 E% q1 R% _: L
8 T; x  }% X- B
如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:& M* J7 v1 e! L& M/ d0 V
. b% J- V4 Y) f- t' H
微信图片_20231211135937.jpg - b5 F9 U% e% V( W. t! x6 p
8 E/ y0 x6 {8 W; B+ ]3 I9 b
这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?4 {& P: a: l$ w0 h, Y
! L% V- X' k; Y4 o7 Q
在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:  b& ?! P0 G$ t( f

9 P1 [5 g* w8 l. F; ?
微信图片_20231211135933.jpg
  }' q5 _1 I; w) d- Z
图12.UserApp 运行时的 flash 和 RAM 状态

$ F. q6 I2 w% F. M& t8 O
- c. A+ ^& i# y& b
从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。# c2 ^: w! p  C
8 j, `" h: F% x+ g& U. M8 d! s. z
于是在跳转到 UserApp 的内存函数中配置 MPU:% Q% v3 G1 m, F
4 Q) ]7 C( |3 g, [( j& Q2 }% V) {
微信图片_20231211135929.jpg 2 v, z/ s* b9 g
微信图片_20231211135926.jpg
( Q. t4 t2 l+ E+ y, E- g  V# N  A
+ G- M: w2 x0 ^9 w 微信图片_20231211135923.jpg ' B3 J( ~9 [' q2 }$ R

: l! }3 s2 H2 G3 T& j& l+ k9 |注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。
' T2 ]2 K# K* c! `( V( y% s/ J+ C8 f5 k9 k0 |: f9 C4 [# H) h2 @
对应的, 我们在 UserApp 中增加对 Header 的测试函数 :
4 ~8 s: l' n& L7 |0 J' b' u8 w1 U7 r0 N0 N$ s- E0 R0 \1 V
微信图片_20231211135920.jpg 5 B. m9 f, W0 e5 i

& b7 a  T$ e4 M$ u# J重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:2 F( C+ e0 x6 b' Z9 t# d+ Q
* {' |) o# j+ V  L
2.jpg

! z! G* I6 k; i* v$ k4 h
图13.测试 SBSFU 的 64K 代码区

# C# z( y6 n9 K; X  k% ?3 y1 E

9 N: ]0 V9 `' w$ [- O" s( T- ]* ?发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:
# `$ z! y& M5 d3 `1 U+ `5 A. v- ]3 X' ^
微信图片_20231211135908.jpg
4 V+ v+ E) M$ u- I' ]
图14.测试 Header 对应的 2K 区域
+ R* }: X' a7 z# _0 `/ T+ f

! c5 N: @" i/ a$ [9 J发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。
8 W8 }& ~+ {& P6 X, |" i' g; ^( s" [0 [- w! Z
最后再恢复之前注释掉的除 MPU 之后的保护。- Q4 W; x( K6 ?" f7 T; _6 p
/ H, P) o) U- h  M
05后述
% f( _; A& S6 C3 a& P! M本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。
- b; a# I$ F5 w% o8 m. u! q
6 ^0 s2 ?/ M& n4 b5 Y如有侵权请联系删除" y- q3 w1 p2 ]/ ~4 y: {: }4 T
转载自:STM32单片机6 r  i0 _" ?. z. t$ A/ O7 n# W( ^
+ {2 y# ]+ K& y2 L( s
! [5 d6 b$ A  B5 I- r1 b

/ o* @4 G) W& _9 \8 W* q, _9 x4 P1 M- y% K5 J! {( M: q
1 收藏 1 评论1 发布时间:2023-12-11 14:02

举报

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

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

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版