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

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

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:02
01前言
, Q( I. v* `  t: ^6 |' Z客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。
" Y$ m9 x/ n% ^' s* @6 H/ H. D7 t  n$ w: a8 J
; r5 ^' O9 N0 Y9 m" {+ e/ L2 b- ^
02基于STM32G070和STM32G071的SBSFU 实现差异
9 [, i3 a$ N6 N6 k5 F( W5 O在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。 0 h6 j' I+ M4 b( ?$ I8 B# r
5 |3 V+ D" A( G* K1 Y4 ~
STM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?
1 K8 Q* |  j5 n1 w
' r  K  W! N0 l' e2 \6 k
微信图片_20231211140158.jpg
% ~0 y  K5 N' y5 w; M4 s$ [

* Z# B( _* J; u# M
图1.STM32G0 的 SBSFU 安全实现
7 B4 t- ?" a2 \, U7 z* T! \

1 U# W  t: K) |& G9 P如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。# x% D) w% \: F- r) N' J

- s: D4 r5 ]% {$ a3 T4 ?5 Y
微信图片_20231211140155.jpg
7 ~" u! d/ R% m) F0 B. C: l
图2.STM32G0 内存安全映射(运行 SBSFU 时)

% p% Y& x& \4 Q+ ?& J

/ A+ R& C% P/ ?0 @7 `; S; B回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗? / a; d- S. m2 H! W, y7 _
0 g$ [: j' U) w4 _
我们再来看下对于安全启动而言, 它需要实现哪些基本功能?
5 i. L, z# ^- u7 k1> 不可更改不可绕过的一段启动代码- V. |& v, ]. t0 L+ Z( K2 h
2> 每次复位必先执行安全启动代码
$ x0 t( X  d, f: N* H: G# {" `3> 验证系统配置的完整性
  x5 D# o' @* C9 @    • 时钟配置
2 ~3 ~7 Q8 x( Y3 |) ~- @    • 寄存器配置
/ ~8 r" |% S; W! @    • 存储器保护设置, ….
( k: E/ a. w8 ?( F. _4> 启动信任根服务- ?$ b% H4 b5 [( m" S
    • 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改) % q# i, f  h0 y' i" }6 d, N

8 K+ G3 b. j' g& P7 a: E; N# q这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如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 功能的。
6 _8 l! z8 Z1 v: \3 p5 Q+ L; t2 R. v' J' S- c! S2 b! n
微信图片_20231211140151.jpg

8 A' N+ P$ q  m6 u
图3.STM32F4 的 SBSFU 安全实现

7 J3 D* d! K) M4 L5 x% [

, G0 z2 [% f: R+ a如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。( T/ U( J" V) @: e8 F" \! f9 w
, u  U+ L9 z* M1 M, V2 m6 x
微信图片_20231211140148.jpg

4 d/ r# J, `5 G2 ^
图4.STM32F4 的 SBSFU 内存映射

: M1 e. Z0 o. i
. g  U5 U2 Q0 F) V* a. i
到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行! 4 W0 {/ \; L* {' \
2 o/ z  M" G9 s8 E0 g8 I$ f
在确立了大方向后, 我们接下来看具体如何实现。
/ @: m  |1 B  ]; a! S  y1 m6 d8 F: b: t" a% R8 @7 b
03开始移植5 b; t: K  m6 f8 X1 H) h
第一步 : 确保原始工程运行正常
+ P, h7 t( F5 z从 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 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。 / M' y6 p2 C' a  j! i

9 b3 [  X) I# X4 w2 N1 t0 g2 l第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭
" R9 g9 Z1 I& \) Z  B9 r打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :" @1 ?4 I5 h6 y+ Y7 y. f

2 t  L& R" {) q- {# Y8 ^+ i
微信图片_20231211140145.jpg

. s4 F/ Q; g% n) W$ {6 ?
/ @' W! m9 o! G# y+ K
重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。
+ Q, p- @4 k& O$ A3 l; p" c
& C8 B' t& R( ?# i# ]至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。
7 j" v* `- b% j; D, e1 f" e2 I# C8 s' [% V3 D3 K. L9 J
第三步 : 移植到 STM32G070RB3 V7 ~, n# X; d# Y* L+ c( l
首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。 3 I; e) _& k! _; @) m9 G# u

7 \; x0 D. ]; y以 Keil 为例 :6 z: l0 `, z3 x% x9 b+ A
微信图片_20231211140142.jpg

1 X) R( {, L9 B; `1 m3 Z" s, n+ {
图5.device 选择 STM32G070RBTx

5 D9 R1 D& P" F$ j' H$ V. q5 B
4 B: Z: z0 A$ r/ O* K
微信图片_20231211140139.jpg

, f  j# F  i" C0 Y- J
图6.C++编译宏修改

5 [7 F+ C; i; X2 K
1 g0 y6 J, V/ [# r$ C
STM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 :
: w7 F7 Q1 P! V
: G! n; L* y. A9 b; B& h打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :
6 j+ i( K7 M; D5 D6 b3 d- K6 j, c3 K0 U) r
微信图片_20231211140136.jpg

4 s1 j5 Q- |- N% ]& L3 L: q$ a
图7.STM32CubeIDE 下的 device 修改

& o2 ^! V, i/ n% R8 r! D

& B+ Z7 Z8 {; p# A5 x修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:3 f( A3 _. _: Q
5 E9 [9 v. A/ h) @6 d" U+ [
微信图片_20231211140132.jpg

; B. A! j) M( [/ f3 R* Z- _$ l
图8.STM32CubeIDE 的 MCU 配置
; A; R9 R1 l) |* e2 t

4 T+ `7 s% u# c; N由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。 + b9 y# @% ^, U# N6 a

/ q+ u/ u1 s: h至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。! ]! g( L" ?9 L6 K4 M' K4 l

1 Y& }7 ?' h1 O. ?首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :( j1 f- o  T! i3 H3 d  a

: c2 F$ \7 ~! f8 c) ^2 N
微信图片_20231211140129.jpg , L! n! M0 A2 V
& P6 ^) n' T( m/ s' y- w
原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :
" ~& h2 E* [! E2 k& o4 F' F- K1 e
, b; j& G1 l7 c3 u
在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:3 C3 d5 ~2 ~7 u& h. T# p
) E) Q( N2 f: _! n
微信图片_20231211140125.jpg
3 C1 C& ], y9 J6 y( z; h! o 微信图片_20231211140121.jpg
3 V. [$ k  T1 J
5 \3 p" _7 A# U) s0 d4 Y* ^如上红色部分即为修改处。
% Y& B+ w2 k! _* Q) Q7 ~9 v5 F" m) `. H4 R: S
至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。
3 x+ T( v/ B7 E# j: F/ Q& m
$ W) R+ f) }& V* P
3 i1 G/ e: G1 L! T) S# ~: X
04测试安全保护特性) C5 _: b/ Z8 m: d
当程序跳入到 APP 后,显示如下界面: M, N3 l( w& H' |
% G- o. ]9 Z6 z
微信图片_20231211140118.jpg
$ [0 |5 H, L7 o2 {
图9.测试主界面

- A  b6 V3 X% F  \) R/ `- G. K

4 n3 s' c. r/ z% r8 F4 ^3 |; v
' `5 h, H4 g8 U! s+ B
当选择 2 Test Protection :Secure User Memory 时,结果会出错 :
9 R- T/ W+ i2 A7 U3 M) G7 ?1 l  Y0 U# m" T  c7 l( P
微信图片_20231211140114.jpg
, i% Z8 z  B7 P5 H
图10.测试保护
7 \0 O1 B* M0 D+ U5 I( _. ]8 w8 i7 Z# P

" Z: X# Z/ A+ R; ^1 b1 s2 g很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:2 ^$ u- f, C" ]  ]% k: O7 `

) N) }" `) O$ u! }/ U$ N* u
微信图片_20231211140111.jpg 8 i9 \6 l+ B" Z: i* P2 w
微信图片_20231211140108.jpg
# ^6 H1 }4 T  L4 k
8 x  \8 m' f& B# I原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。5 K& ?2 o% a0 X$ q
/ b" D, l6 Z' U8 M
首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:; x0 Y+ c( y* W" E% e! Y
1 T  _/ [. _4 k' V5 q) p
微信图片_20231211140041.jpg + w9 {1 y, V5 w8 P  d4 f* ]+ R% v" c

: ?. N5 [4 {, ~  g0 F8 M/ R4 S同样的尝试读取密钥:
' `2 l' Q5 x& g* H: F* V0 C4 `
, l/ R0 X$ T9 I9 Z' K% `* `
微信图片_20231211140036.jpg

/ p- U; ^5 P3 t6 l5 N+ _
图11.UserApp 尝试读取密钥
* e+ k$ {- `6 I/ O3 S

; N& L4 o3 z: z; q: N7 o' I" b: n
测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。
* ]2 n0 G8 H; G' z( n
2 e: Q; v5 k# j仔细查看图 2 的 STM32G071 的 SBSFU 原来实现中,SE Key 是通过 PCROP+Secure User Memory 来保护的,现在换成 STM32G070,原本 Secure User Memory 用来作隔离机制, 现在换成了 MPU, 而原本保护 SE Key 的 PCROP 在 G070 中压根就不存在,于是 SE Key 只剩下 MPU 来保护,因此,我们接下来得着重分析 MPU 对 SE Key 的保护。
; ^; ^3 h! ~: L/ M$ g! V
; x* g+ f; P( K为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:! b& C; v8 l" ?5 A$ m, I" @
& i) y6 J5 t7 m0 x
微信图片_20231211135943.jpg
- _/ r5 U% `' |8 l
微信图片_20231211135940.jpg
! x5 t9 X* r3 B! d; z
, ~8 R( w+ k  s- ^然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭:
0 Q5 M1 `) c, ~: \7 ?- q/ a
, e  X2 B+ q" ?% d! }' n) H如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:) J# J4 Y# x! v$ |1 ]( P( K7 F

% T3 W' c. b5 O4 ~/ s" V" R
微信图片_20231211135937.jpg " Z0 U( B/ G6 N/ `' A; L
4 A  j& C3 z, |/ x5 A' F
这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?" K; H0 A' J% {- I+ l1 _( t7 |

8 I: M* s( ?% A9 ]) v在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:
: P- q) e$ N# z
0 R, U0 U: M3 g. Z  Z; v
微信图片_20231211135933.jpg

" L: C* \$ C! ~2 D, [$ b
图12.UserApp 运行时的 flash 和 RAM 状态

- n0 P% _* R* E1 ~/ h  i
/ @3 T9 K$ Q4 ~: |$ K; J" j0 B
从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。
( x6 z& X+ o; E9 a/ p- C

' T4 _1 J3 M6 e# h" C于是在跳转到 UserApp 的内存函数中配置 MPU:
5 l: [$ ]6 k1 @+ j0 C. N5 [( v, V& D3 D, ]7 b) k
微信图片_20231211135929.jpg : b: b0 X  }1 g, Z: F$ L. h  ?
微信图片_20231211135926.jpg 0 N1 P- d7 l( C5 ?7 T, |
& \) Y& f- E/ ~: F
微信图片_20231211135923.jpg 6 D% Q9 u8 d5 l  G, \
3 B; M5 S3 [; g; a
注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。
+ D) g2 B) w2 v9 f8 v' t
. V! `$ _% o/ j9 F对应的, 我们在 UserApp 中增加对 Header 的测试函数 :5 h- k/ o/ S2 l/ G! [

2 G0 L6 V, ^" g  k% k) j. }% \. v5 W
微信图片_20231211135920.jpg 5 X1 R7 M% }" A1 S
  b. C" e$ @* J" I6 C1 i
重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:0 x: q4 I/ |0 O1 L  m

! s" n. ~2 n& _1 z$ [$ X
2.jpg
  i# w- F2 h* o0 N/ t
图13.测试 SBSFU 的 64K 代码区
' B* {2 C$ s, Z8 }% G4 f8 i3 K

( j  S0 a9 @2 F! K* }" l  i9 q发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:
# |2 j  O% q  L% `$ Z" K/ O' L. p( }# T% p; P# ~! O) V0 o; A
微信图片_20231211135908.jpg
+ ^7 @5 y& _5 I
图14.测试 Header 对应的 2K 区域

* e0 `7 F( v" u2 A0 o6 a5 \! j

$ `5 M1 _6 K6 I5 t( k发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。 / S* z% s! u3 y. L1 f! d# k; T

: K$ N- w/ B5 ~3 H9 e$ o& v7 R最后再恢复之前注释掉的除 MPU 之后的保护。# _$ a3 ?3 _8 M

4 H6 u' O" N" A05后述! J% V! |, \) D
本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。
7 v" j" d7 C; |2 q+ D  P5 c  I& e
8 g0 A, z; w& Y如有侵权请联系删除
  v: Q- P$ i* ^% m) x' s转载自:STM32单片机
3 |1 w! `6 C1 E: D1 K" \& M" t3 E1 Y+ o7 Y- B; V% _" y
. J$ y3 o0 C. Z. o6 Y; B$ g
+ ]% \# `1 x( r' T0 ]4 e

" w; s7 f% G* Q: Y# @# o
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 手机版