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

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

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:02
01前言
2 B" w% C3 v; R2 r; ^5 T. E- p" a客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。6 N$ s1 J6 |5 K  ?0 s: Y* ]

( G/ t4 D# R% Y4 L* e7 }: W

5 I7 p; C/ S+ j# B1 S+ o02基于STM32G070和STM32G071的SBSFU 实现差异9 r, ^6 r# E) W- S7 B
在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。 : l7 o5 d% w; n+ X" B

0 P2 @' w% {* ]$ BSTM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?
( Z, \1 |9 D5 |. T8 S
/ Z9 Q8 y" j- `! h& P
微信图片_20231211140158.jpg
% G6 d6 e1 @: W) G4 k( ~) g+ P* M7 R
+ S! u4 O8 b9 `3 k' e% K
图1.STM32G0 的 SBSFU 安全实现

  {9 P! k1 m9 T. E2 z

& M- ]4 z  i; L) D( P5 ^6 L如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。% y% k8 ^8 e) u& S) A2 Z8 ]0 b

( ?0 h) a" g8 s7 `  e; L
微信图片_20231211140155.jpg

2 z" g* l/ v! [' D! J: s
图2.STM32G0 内存安全映射(运行 SBSFU 时)
1 _' Q/ q1 M; H& K% V
9 N% m- p$ Y( B$ a
回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗? ' }5 b7 [# I# q+ d+ \

; c, i* v4 V9 B# \我们再来看下对于安全启动而言, 它需要实现哪些基本功能?
9 f4 t- x5 F/ l3 J1> 不可更改不可绕过的一段启动代码
& ~9 _& ~  v; O2 P  [: b+ n" C2> 每次复位必先执行安全启动代码
0 X/ _2 h' ~& ^7 r3 u( p2 E3> 验证系统配置的完整性6 y1 A5 G  C8 E8 ~+ {
    • 时钟配置
2 n# r! `% f' R* C, g: F9 y8 D1 p    • 寄存器配置# _8 {; w& X; E1 R' p0 F
    • 存储器保护设置, ….' C2 f$ ~9 t, [3 i; i
4> 启动信任根服务7 C" `+ f, b; J, c
    • 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改)
: k' C% P$ l- l. E; C3 `) I: y1 d& q  c0 z
这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如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 功能的。8 W; N' X6 f" {3 ~) r- z, n
1 R3 X' V% p2 J& z5 `* ?  |
微信图片_20231211140151.jpg

. U6 F! y6 b" j+ j' a9 d( |2 ~
图3.STM32F4 的 SBSFU 安全实现
- \6 a. A) y( x: ?8 {% ^% q
% N2 l: z+ e& W- ^; S9 R  M7 u' y
如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。
% B' d0 f3 L& z7 L1 h0 l/ Q' {
, L6 Y: v% A. ]" W5 e% k1 u
微信图片_20231211140148.jpg
. U$ X& y- O1 Z% H1 Z
图4.STM32F4 的 SBSFU 内存映射
" b' _/ U: Z0 `4 v/ D: {) q
" L4 `% v1 L7 W  S* C
到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行! 6 q* X- H7 {- A. R

7 \: g* M5 t& c( a在确立了大方向后, 我们接下来看具体如何实现。
* H* _# c9 a# h7 g8 t% }# U8 t6 f4 i* t) C2 j
03开始移植! I  D- W7 [* I2 [0 E7 d
第一步 : 确保原始工程运行正常4 o0 [$ I* W: T  G1 ?
从 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 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。 5 \4 q5 c2 J, F6 [/ R# Z5 i) f
& X; J' K$ Q! Y( Z  x; j
第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭
$ D3 }+ C- ~/ x. ~1 m* R( v7 @5 t打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :
9 U1 R6 K4 ^; w& V1 N# C% h& N: ^% v, a0 z& P
微信图片_20231211140145.jpg

  P$ {( w4 v8 ]3 D0 P# g. Z

; P" U( P- a5 W+ ?重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。 - b$ `, [7 |4 Q: j5 ?

  d6 x1 q+ \. s5 m0 l' b- M至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。
. L! Y- A- U5 t% X; f
7 y$ ^/ W8 {$ T第三步 : 移植到 STM32G070RB
3 |' L5 _4 w7 T首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。 - C: ?* H0 h! R0 ^

- o( M9 x( G/ l% P2 o: F4 n: l以 Keil 为例 :+ Z$ ~5 t3 m5 X9 J- C
微信图片_20231211140142.jpg

/ f+ c1 _# e. A, Y. b
图5.device 选择 STM32G070RBTx

% W5 l  m3 ^% L5 ^5 e4 I
3 H% k0 A7 _) i: Q! j9 M
微信图片_20231211140139.jpg

( o4 o9 e3 v) D$ W! q
图6.C++编译宏修改

. {" i0 ^" Q& A+ k) R& U* Y

# P5 |! `% n, a* fSTM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 :
$ x" b5 w( U1 J  u8 H1 G
3 b  ^5 p3 C# a, E0 a3 z3 c打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :4 x! p8 N( _  B# E2 t, T7 K4 t0 l
1 b5 ?5 @/ n. p8 q! m7 \/ j
微信图片_20231211140136.jpg

9 I! _  v: {' w7 m
图7.STM32CubeIDE 下的 device 修改

' }7 W# ]7 C) F/ e9 g
( }. y2 A! `: q, c6 a
修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:$ F! U$ }6 \  d
9 j# F2 i* U- `5 n; j+ F
微信图片_20231211140132.jpg
, T3 P+ Z4 A7 o& _* z2 s4 ]
图8.STM32CubeIDE 的 MCU 配置

9 ~; e8 z: }, R% n% A" e3 o6 k

- j+ ^* U" |2 s! t4 X) x0 t4 V由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。
) z& |, n9 c  d. i5 P, z, F! R" b5 k
" W. r7 ]# Y& ^2 {+ ?5 e8 X至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。9 x# O3 ]% q1 X: K
+ j" h; j5 H8 z# ]# n
首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :
, P+ A" c6 {6 p; v7 v
2 t' X$ D' z  ]: k. h- U6 K
微信图片_20231211140129.jpg 8 X6 j" _1 |" q* ?
4 ^8 d0 _1 s1 k( @( ~# @) x
原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :) [* ^8 z. D: O
1 w% y" n* e% u; C, P
在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:
/ S; _) T. X" ?) m$ A) R
3 _, P1 L8 R& |9 I
微信图片_20231211140125.jpg
- C/ @" V) @5 j& X/ f 微信图片_20231211140121.jpg & D  E: `/ z( ~: t

( ~7 e% `3 V. T; B! j" _如上红色部分即为修改处。
( a" W( l2 f) L
8 a! S$ o7 I- i3 I) S7 w6 Q+ |; T至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。* Y; E6 n6 e1 {  R
; F8 F1 ]; H( R: X8 |6 ^

6 l1 {$ Q- K4 V04测试安全保护特性. w8 t& z: i9 r" u
当程序跳入到 APP 后,显示如下界面
3 O& M/ n' T4 \7 v3 s8 D$ a/ q
+ A  ]7 j; q$ Y1 a  }  ]) a$ D+ L1 R
微信图片_20231211140118.jpg

$ X$ L5 I7 L% n% D0 P2 b& _
图9.测试主界面

6 n* @6 @: D" s+ y) g) j7 G4 u% v

' r* ~+ _! H+ L& m
% G: W+ J5 [! N7 M* o$ |
当选择 2 Test Protection :Secure User Memory 时,结果会出错 :
9 g! w1 V3 v# Y  t* G9 J3 e, f& @4 ?
微信图片_20231211140114.jpg

" k. }% ~% C. T7 m. D. e
图10.测试保护

% x* L2 R  U8 ?
* X+ v" I: \( B; r
很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:
0 Q7 z- A* m& X9 X4 K) l; j$ X' Q# O% e: f
微信图片_20231211140111.jpg + N* o$ y5 }. c/ I: a
微信图片_20231211140108.jpg & z0 a5 N  V# \2 h# j' u: R

  {5 I/ Q/ T$ w原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。" x# S7 ]7 I4 v& h6 W

' H8 y" E; {, P首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:
" P% F! [, t. ^+ ?- A8 r0 `8 M- j* W6 H$ Y4 Z& }7 T
微信图片_20231211140041.jpg
  ~+ X7 d3 G; S
' `- k8 e$ j, \: t同样的尝试读取密钥:
1 \4 v8 ]2 Q! C  V4 f( C, Y' D
; |: `* x5 S. `* p* M! B  a
微信图片_20231211140036.jpg

  K$ h/ e2 a+ w' Z' Q! i
图11.UserApp 尝试读取密钥
8 j5 c1 s. t+ J7 K5 O7 u0 i

. v2 J& |' A* N2 W% \' @
测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。
$ i% y. K4 m: j! c6 u6 H
$ P; M0 f0 \; c9 \$ I( p+ b仔细查看图 2 的 STM32G071 的 SBSFU 原来实现中,SE Key 是通过 PCROP+Secure User Memory 来保护的,现在换成 STM32G070,原本 Secure User Memory 用来作隔离机制, 现在换成了 MPU, 而原本保护 SE Key 的 PCROP 在 G070 中压根就不存在,于是 SE Key 只剩下 MPU 来保护,因此,我们接下来得着重分析 MPU 对 SE Key 的保护。 4 m) j+ y$ L: S' j; i- \

+ L5 R1 t- ~9 _$ x- |4 \为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:1 V2 p7 t/ X8 n9 X. ~
1 u, O1 K3 B3 U
微信图片_20231211135943.jpg ) D; @" B: O1 a; z
微信图片_20231211135940.jpg : O' k/ g, E! `; ]3 H2 \
) x/ M3 X8 s2 V3 h* t" W
然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭:
4 R* j7 u" W% w4 x' p! r1 G( z5 o& O' D0 y+ F1 V& O4 w
如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:/ H) E( C* f  D- J2 N
* l1 }$ G1 y- O$ y+ Q/ ?. o
微信图片_20231211135937.jpg
3 U4 b0 ]! P) @4 a7 l
5 z- ?# ^/ F% P3 R' b
这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?
8 E/ h! S: j: \4 d3 {4 s
1 @8 r1 x" v; H2 n在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:; n  e6 Q, S/ X4 {% S1 @
* `2 Z: d" ~. b9 h
微信图片_20231211135933.jpg
$ j* H0 }5 f) I& b  n
图12.UserApp 运行时的 flash 和 RAM 状态

' H+ D" v% d: ]* k% Q  e" ?6 T
+ _( {  a. b6 V3 U, U2 H
从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。7 [8 O1 Z; ^9 R8 f( B# A
( A# r2 s2 s4 A9 B1 v, n# d* t
于是在跳转到 UserApp 的内存函数中配置 MPU:2 ?5 \. _, P1 Q) X% w- i

( }- \0 n- L; V6 R9 v8 v
微信图片_20231211135929.jpg
" T, F- \+ k8 Z0 w
微信图片_20231211135926.jpg
) h0 [, n$ T, K2 v2 r
: F# N; S: r, @3 P 微信图片_20231211135923.jpg   o( ]% C9 P' c3 O5 e1 q

4 g* T  o. z  {: U; s' H# y注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。
* E( T7 q# k$ \2 m, g4 ?) }  l) F* r; u+ e$ U) P9 ~- Z+ z
对应的, 我们在 UserApp 中增加对 Header 的测试函数 :
& T3 _! Q7 x; e0 t" C$ K, m3 C( q) t! |  p, q4 F2 ^
微信图片_20231211135920.jpg
: c" r" ^4 K) K* A# G

) l' ]+ U" H7 ]  s, o重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:/ X5 O& E. r8 F* u" A( q
: p  B' h  D( C$ w! ]: v- N
2.jpg

  Q% v+ ]- m! f( a/ p0 w* s! `
图13.测试 SBSFU 的 64K 代码区
( x" x) Q( Q8 P

  c( v: X# _3 H/ V& V/ d- A; f发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:+ b9 N* O; v) F. t; R
+ _% v1 ^" P& |; E8 I; a( i
微信图片_20231211135908.jpg

* A" i! P- X. `7 l1 b
图14.测试 Header 对应的 2K 区域
! _# [' N) f& b) T) {4 {1 \
5 Y' \3 Y, d" l. ^! ^
发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。
: z! t" |. Q6 M9 v- G, v) t' W* O/ w6 h, R2 c. T
最后再恢复之前注释掉的除 MPU 之后的保护。$ J' W! o' u4 n- c2 A
  f& |3 z) X( B. x, H3 |- Z4 e
05后述
$ h9 y# S+ o( T% \  ~本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。
# h- b. t+ C; V$ G
6 ~; x- c  v; q0 D! L3 u; N0 V2 h如有侵权请联系删除
, e! l5 b" g# f$ `转载自:STM32单片机5 @( [& v8 \$ K/ m$ j3 L( E: ]
7 |+ |6 @4 J$ q8 l% B! G
* M8 p( y' E, G# e- H! ]1 o  k( D; L

' i" ~' u4 u& Y+ z, k9 H. a' h  `$ f$ g$ u; b$ R+ s9 C! \
1 收藏 1 评论1 发布时间:2023-12-11 14:02

举报

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

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

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版