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

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

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:02
01前言
. d0 L1 K+ T. b" X* [1 E6 h客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。
; n0 e% H& I6 c$ \) v6 S6 ?( S. j5 i' K, _& U' Q

! b6 @- Y( u2 s: b: o  Q' D02基于STM32G070和STM32G071的SBSFU 实现差异
. y4 D0 \* ?" X  l" V( P在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。 6 G0 x. m) m, n; b) C" o; T! G
) u$ \3 l2 V. Y* `! e
STM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?
, {! U* V( n* ^3 {. k& O3 B9 B4 a1 c/ T5 z- r: B, T1 A
微信图片_20231211140158.jpg
/ n) @! O8 d; M, }* D0 l
* A  Q9 B& W( [( R3 O' V
图1.STM32G0 的 SBSFU 安全实现

' U! j( U- @0 T! j8 f
/ E) ^' o2 S. F
如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。8 L9 m$ D4 `; z% L$ U, \& ]1 E# [
- C1 k4 O5 w. u" o! b
微信图片_20231211140155.jpg
# m! j( {- T9 D' u  y
图2.STM32G0 内存安全映射(运行 SBSFU 时)
9 {. k. v0 N- U7 Q9 i

  H' O" \# F7 z8 I8 Y, s7 c0 Z回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗?
4 X' e9 _) u  R* a+ M  j8 j  Q" e# W3 {1 {% L% k$ U
我们再来看下对于安全启动而言, 它需要实现哪些基本功能?# a7 S7 x6 j' D4 x
1> 不可更改不可绕过的一段启动代码' w. f% a7 d! P. ]% f: D- E: L. B5 X6 C
2> 每次复位必先执行安全启动代码! _  Z( H: e4 g2 y# p" X# p
3> 验证系统配置的完整性
. Z4 A- b6 V7 h6 `/ T    • 时钟配置
9 a4 G. p( t& m8 ~: C9 Y4 ~    • 寄存器配置
. j& W" m1 O6 C0 A( ^$ L( x9 h    • 存储器保护设置, ….$ h6 ?+ n/ R5 X0 f; w+ \
4> 启动信任根服务+ ~0 m  _* w" h
    • 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改) 0 e1 S& G" x& p) W6 o
1 y9 l' m4 c* C4 g; X
这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如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 功能的。: E$ K) F: p, c: w/ _; e4 R
) p$ L+ H0 A, |2 w  O
微信图片_20231211140151.jpg
. I2 x; T. N; M% i7 E- U5 [
图3.STM32F4 的 SBSFU 安全实现

% c5 G- V/ V3 i  g) {+ m
& [+ v9 n$ v5 G/ ~/ `
如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。9 y- i$ d/ }& q4 Q. `  h) L# X0 K6 }% m
5 ~7 J  Z) x) W; A
微信图片_20231211140148.jpg

" O! d) M" z+ p( O. Z5 {
图4.STM32F4 的 SBSFU 内存映射
& s5 z7 Y* ^. K& U' a/ W
4 d, r; ]5 [; q, X) K4 O, M
到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行! ) U+ b0 R) q$ Y
9 f, u- K( R  E5 J5 z# e/ {  _
在确立了大方向后, 我们接下来看具体如何实现。& Q) m# e3 C. T; l* l( N0 k
4 K, d$ P4 O+ [' b: F. h& _
03开始移植/ J6 U  o9 o+ x& h5 d% L: a! b& d
第一步 : 确保原始工程运行正常# g, i* A* W) h: ]; U; _) h! @
从 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 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。 7 ^/ [3 r1 e" W$ f, t" o
* @7 f1 S# u3 G) {
第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭
7 P1 w$ I3 \1 R- a打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :
5 o* |) T4 z* f; D  i: u6 L! I. ^- E% X  x0 X
微信图片_20231211140145.jpg

; I, A; H2 t; p2 i& z: M. g+ o

- }; {" E& l4 U* @8 q$ y重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。
6 N7 P4 s) G1 i0 I: e- z- b, N
$ q$ e8 O) c, m% H至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。 ' U; e# _% Y8 V% y+ G( G. F: g

- S3 }1 L8 r  X- |5 ]第三步 : 移植到 STM32G070RB
# t2 u, S" P, }6 x首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。
# o) A$ C2 k# g8 l$ i% h) F0 c
7 Q0 M* ~  f- O% U) |  a6 B以 Keil 为例 :  K( T5 x2 @6 j0 |$ w
微信图片_20231211140142.jpg
6 Q" Z+ q- _& R% V) b3 d
图5.device 选择 STM32G070RBTx

: w* N1 U$ H* p
7 s" v2 k; J  l7 X1 r4 a
微信图片_20231211140139.jpg

9 ^  C8 C3 C2 s( P# Q. R
图6.C++编译宏修改

& C9 N7 ~- _8 z9 n% Y
/ o: x, m5 C* S' c# L
STM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 :
2 O/ J- s* c8 b. V8 a% t
( P# u" u8 A, |" c+ b打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :" Y8 \, `( V3 X% e8 D0 O- C$ g
% k& o" `2 k& w. d8 D% ^
微信图片_20231211140136.jpg

8 q3 _" ^, V5 o9 n& T/ [" R
图7.STM32CubeIDE 下的 device 修改

# _* h) p2 \  U+ l

2 U; q; h2 z( W4 m修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:
9 \( j# v" ?/ `" ~+ v- R4 n  f" f+ ?0 H8 ~0 F6 s4 e" ^
微信图片_20231211140132.jpg
4 T9 `8 a" y% c# G1 ~0 x
图8.STM32CubeIDE 的 MCU 配置
  y, z% ?+ U! e4 G

  k' G. n9 t$ ]6 t! k由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。
! Y9 o5 J4 ~& d+ e# a+ r9 j% j
' w  o* x( h, v! u$ u4 A4 p. Z$ x至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。8 x; l4 x, Q/ b  M
! E& Y" ]/ Y2 V' e4 t5 p
首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :! c8 u, b0 [6 K4 U6 t" l
7 J# P8 X. b1 P2 l& u0 F
微信图片_20231211140129.jpg   N; ^- N; d. S# t
! }/ v# T4 L, S/ W4 P
原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :
" r3 Y# B1 {1 l' m% r( ]% A
) v1 A' P" P3 R0 L1 _) ~$ g
在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:
  `4 m, i: W0 s. U- J: i$ X! F: e/ R9 P/ j( o# H9 R5 K
微信图片_20231211140125.jpg
9 ^9 s5 I" }7 ?' T0 t 微信图片_20231211140121.jpg
# D2 o& G4 h1 T& @( N
' J, r  q! R( }$ \) [9 t如上红色部分即为修改处。
. v& T) K: G5 C* Z; Y# x. h  F" I4 J9 |( F
至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。8 d2 i5 b( x2 @3 V
5 t6 H+ a( q9 X# q. F

8 Y3 k$ Z, q6 a; b/ v* X$ e3 k" n04测试安全保护特性6 z5 Z3 h( @* S( M& j0 w+ r
当程序跳入到 APP 后,显示如下界面
- p/ Y! v! U6 a8 j: R
+ ~! X* N" P+ E2 q
微信图片_20231211140118.jpg

/ q2 `& R8 ~; e7 n
图9.测试主界面
! J% D/ P) c0 G9 h

+ l$ o. w" r; t5 w' H) J0 N+ R
, H/ Z% x! k. f; V
当选择 2 Test Protection :Secure User Memory 时,结果会出错 :; c& ]3 {$ |) s- h) m% m" u  V

) J4 `: U- w$ ^- ]# G9 Z
微信图片_20231211140114.jpg

' E9 j1 \. H$ ^0 ^% J# A
图10.测试保护
' v6 H' C" o' L% V% W/ X5 L% E
' T$ s$ }" O- |: A  K* P
很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:
. j, A) t$ L% E9 z% V8 X# }1 {1 i5 s8 U5 X& R+ Q1 ]& u/ _
微信图片_20231211140111.jpg
! r3 t; A# r% H: l( D. B 微信图片_20231211140108.jpg
2 v9 r! s0 H# o  m8 M1 X- B
$ s( ]7 t8 z- L: `; G1 W* U7 g原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。
% m- \% C5 u3 Z# z) E2 Z. y8 Q

; i+ N& Z1 ^: b) o) {首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:
" a% J8 b, \. S. y2 x
8 r+ _9 M2 r* H/ {' u! \0 X9 `
微信图片_20231211140041.jpg 1 d  q& X3 f' _

& b& m# j) p6 E: |' T; H同样的尝试读取密钥:
& Q  y8 P$ R7 k4 @8 t' [
4 P- {5 u& W" S( d# l6 y
微信图片_20231211140036.jpg

% g) g5 D! Z% K& q) U
图11.UserApp 尝试读取密钥

* x' u. N1 D6 j( x0 l

( ]' N, E% t- K& A, H6 p: J
测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。 $ ?9 i( S7 F* |
5 w/ m' G, v" l- D) O5 `
仔细查看图 2 的 STM32G071 的 SBSFU 原来实现中,SE Key 是通过 PCROP+Secure User Memory 来保护的,现在换成 STM32G070,原本 Secure User Memory 用来作隔离机制, 现在换成了 MPU, 而原本保护 SE Key 的 PCROP 在 G070 中压根就不存在,于是 SE Key 只剩下 MPU 来保护,因此,我们接下来得着重分析 MPU 对 SE Key 的保护。 2 d) J2 h# {5 e) e  w" |8 d$ }

  h6 K5 N+ y$ y9 E+ `% s) v为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:
9 ^" t3 e1 S  }% C( [0 s6 l0 r5 P" z- U: A
微信图片_20231211135943.jpg & L% z0 s% u3 m* d
微信图片_20231211135940.jpg
9 Y" ]# u' q$ m  T8 O, l$ U
: l, a$ r) |, L; e% m% f7 w+ k, E2 ?然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭:
5 u( r" B  ~6 P& X: T& [" m1 n4 n5 G5 V2 Q. ]/ V! R5 C* ?
如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:4 B+ B) R6 w* L8 x
& R+ l# ~4 q5 O1 ~, I' y: ]6 O
微信图片_20231211135937.jpg
% z4 N7 G1 `* T9 q6 \
! C5 I1 h1 Z- g* \- Q' ^
这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?
" D, Y# q/ f+ K9 Y
6 d6 J4 c( l5 W  \) R9 W8 i# I在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:$ j4 y  Y! O( f

& `" g0 l- A9 \0 L8 v$ n9 ^
微信图片_20231211135933.jpg
+ [2 ], o! e# X3 V+ o9 Y
图12.UserApp 运行时的 flash 和 RAM 状态

; ?6 ~7 C2 E! W7 z5 y; d$ ?8 S

. P: h% P1 `1 T$ Z& c' `  O从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。
2 w) W+ j2 g. [
: |$ H' e7 k: y- H8 h
于是在跳转到 UserApp 的内存函数中配置 MPU:) \7 o1 l8 b& t! d

  l& x/ V" s  o, q& [" a7 S
微信图片_20231211135929.jpg
$ h0 I0 {4 J1 j) L
微信图片_20231211135926.jpg 3 W0 a" g3 h0 y1 S9 P- A& m

4 P% A8 Z4 D% E- z+ O) G 微信图片_20231211135923.jpg
4 V6 G6 n; O5 @  J5 A7 J$ v6 Z( K4 p
; Y/ t4 f; g5 o: X注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。
0 ~2 a* D0 R7 z
" ^2 }5 P. j: B9 F- }7 J/ r对应的, 我们在 UserApp 中增加对 Header 的测试函数 :/ S% y8 a, M6 Z

" t8 f  n  G; \
微信图片_20231211135920.jpg
  k/ |/ T5 z% X! x# ?; c, N) L

2 w! S: o" ]8 q6 e7 T; N2 C重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:
! ]& T+ }! z! P) t. Q- U. J) _+ }6 n1 d6 ?* R+ {) h# W
2.jpg
! s5 i9 u8 {& m; ~/ _8 |( E/ B! l, K
图13.测试 SBSFU 的 64K 代码区
( b8 }1 `# I  L' L' ]8 `: F3 Z: p' a

, x* G' n. f/ Z发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:' j; a# O6 [* ~5 c% L4 [% a

! T3 B( a7 R# v1 O2 T
微信图片_20231211135908.jpg

& [' U7 Q+ h$ f; J- ?/ H
图14.测试 Header 对应的 2K 区域
" t) z8 a0 ?! x- g) }: b

9 `' y0 H2 H1 s8 j" L- B3 x发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。 # L# F3 M9 G6 n
$ Z+ X* I  E$ j) t# H4 {( Z6 L
最后再恢复之前注释掉的除 MPU 之后的保护。
" t$ m3 D: B: V$ [! N
5 {, p  i( r6 u# p/ q: D05后述
. D+ ^7 V3 e2 {$ a$ b7 G本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。
* |) W5 p( |* X0 w3 z3 a( `: K  z( d8 _
如有侵权请联系删除
6 Y7 ]0 b% l- H/ J. O0 I5 s转载自:STM32单片机
0 A6 m$ a& Z" S; `; b) f- P
$ @; o3 _2 y" k5 G+ O
  }' P$ v- {- W9 y' U/ E7 f: ?2 @  @2 r$ A5 z
: X* {6 s) A  ^6 i
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 手机版