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

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

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:02
01前言
% e  s8 R; O2 E客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。0 @$ H$ X1 ]: ]# p% v
0 ^" s# {& e/ A- o! h$ N' R- E
6 e/ w3 |$ W6 N9 m4 V2 w. r: F
02基于STM32G070和STM32G071的SBSFU 实现差异
, Z' h  G- u/ M在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。 , l9 F: r. {3 M" x
0 X5 P$ U1 v! n2 A
STM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?7 Y. }% H3 ?7 L# e; [' H
+ W5 o$ Y. _0 G/ d% p9 s2 Z
微信图片_20231211140158.jpg
9 j. _9 \  l' O3 W7 r

5 c; K1 J4 G4 X; y9 U
图1.STM32G0 的 SBSFU 安全实现

2 Z2 r+ W( p" a/ W$ z) E2 C

% a; J+ k! x6 P* [& s, R% q) i如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。
; T8 r( ~9 t. n4 c% i* \$ |' B  [
微信图片_20231211140155.jpg

, g0 }, X- N0 |# i( s1 p
图2.STM32G0 内存安全映射(运行 SBSFU 时)

- J+ V, X2 E6 V6 H9 @/ _* h2 [

: m8 d* y3 s3 t" q- [回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗? 3 Z1 i+ o  U8 N1 q4 {

& x3 H: p! e$ K我们再来看下对于安全启动而言, 它需要实现哪些基本功能?& G- k+ T8 s/ K6 B8 M5 [
1> 不可更改不可绕过的一段启动代码/ [/ R/ G- ~3 W, h) w
2> 每次复位必先执行安全启动代码
* p' s& f; z' R7 K3> 验证系统配置的完整性7 ~% f9 {6 A5 U& W0 |" ~6 l* F
    • 时钟配置: I1 \- S' |: B
    • 寄存器配置% t& ?! m# E. e- a
    • 存储器保护设置, ….
) [9 F! E. P5 E1 P% y4> 启动信任根服务, }, h6 L! A1 M) U) h/ |' A8 k  P
    • 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改) ) y7 x, V5 k& T$ c9 S/ v6 ?# ?' g8 L
! g6 z4 _; a2 W) L
这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如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 功能的。
, c7 J' o6 X1 W
" E7 m0 S- p) J
微信图片_20231211140151.jpg
: `* b. I5 |' L. r# R3 Y
图3.STM32F4 的 SBSFU 安全实现
) y& B: W; q7 B0 v$ P* z8 D: S

/ l8 }+ L: r4 p4 [, j4 X如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。
  X# A- W4 S* d( v, A: R( Y2 `& g) P  r# `0 N
微信图片_20231211140148.jpg
" l6 L% R- c9 t( D) T! p5 ~6 `7 I
图4.STM32F4 的 SBSFU 内存映射
& ]8 Q0 y- q8 v) \" ?, q$ T

, _( r/ }% \* f" }1 D/ T% X3 r到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行! 1 j) j3 C  D3 J0 S* w, w9 O* R7 }

9 ~! d, ^8 {( l  B. Z* v2 o4 o' }; i; t) _在确立了大方向后, 我们接下来看具体如何实现。
/ N; J  I; q, x, E4 W: m) U: m8 I& ?8 k5 i. g5 u) K) U
03开始移植$ X( Y0 c- ?" b2 H
第一步 : 确保原始工程运行正常
" O/ ]3 u- ]& V# y& o0 N& A从 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 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。 6 t: n% y' I2 e: L

9 B' u% N- }( n第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭$ i& d, F* H) P
打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :
% }2 h$ n$ a9 \9 }4 C4 J4 E/ I/ t( O+ N5 O7 O) S0 s( j
微信图片_20231211140145.jpg

1 [. \$ t  D: W  N
4 L. o7 N- ^2 ?3 Q, ]5 J
重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。 " }6 u% r+ g# u+ M4 L' l

1 |# b2 }  N; u. Z至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。
% f" m' j, ?' N0 q: s$ z( n) }5 v/ v, |
第三步 : 移植到 STM32G070RB
9 ^9 r  W  A. L3 h4 R, w- z0 q! E6 m- g首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。
4 P! @, d- b+ j' F1 @9 L; l( f  ~- F
/ Z1 U' K' P2 E$ |. e9 X. h: _4 K; {以 Keil 为例 :
: g* B/ f1 r' C
微信图片_20231211140142.jpg
. F: o+ M# ?5 I( S
图5.device 选择 STM32G070RBTx
! Z* D& f# b% _4 z1 r" q. U1 `

# F( n2 ~3 U% }
微信图片_20231211140139.jpg

# ?% ?: g( V$ V: T# d5 Q
图6.C++编译宏修改
+ I  n3 @0 E5 Y" H0 R/ U4 C6 f! X

% g5 a+ v- l2 k3 t6 J  q: [STM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 : ! d# s& Q% I# R4 U
: O; B! w5 i( X) S2 O7 j
打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :
* a& c) x# x5 B; N% f! A9 J: o- K" x% m
微信图片_20231211140136.jpg
( g+ N4 w$ V" ?* V
图7.STM32CubeIDE 下的 device 修改
% ], G# C' e  c) T$ H; Z

9 |1 q1 J& `  v! ~: ]; _修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:
. d$ a) C0 J. x' U" a9 j: _; @5 M) J5 v6 u% _+ V
微信图片_20231211140132.jpg

$ e7 A& G2 H- s2 W7 K' ^3 L0 y: ]7 Y/ W
图8.STM32CubeIDE 的 MCU 配置

: _/ f8 o0 v$ X0 ]5 Z
% y  `; {1 G, ?9 |8 ?/ x7 Z( M# ~" W
由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。
" B6 [, g- P, h: f
) v- J3 H, S, J5 A0 T至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。' G! }. t! s! U3 q
0 T( z5 M# z1 H$ v7 {( X3 k' s& F
首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :
: [1 r+ y3 K9 e: R" t( I  m$ t: [& f
微信图片_20231211140129.jpg 2 U- V+ B: a% ]/ @; q! P0 [
, S, y% c3 L( i
原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :6 @, a/ w( W- H7 ^8 w. {3 x

0 a/ {0 M9 b6 E9 h' p; `$ S在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:
* g6 r: c, h: U8 H  T$ g, f" c
  C$ N: z4 z' |6 J
微信图片_20231211140125.jpg
9 V: G, v, |% n, Z4 C 微信图片_20231211140121.jpg
3 H( h0 p7 w* q+ h
' Q2 J7 T2 z' h$ v如上红色部分即为修改处。 / u7 ^7 }: [2 C) a
7 C% f. e+ J. b! b4 |
至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。* X  Y! Z' n3 W3 l/ m- B
) x. r+ W: p! @) F4 i

$ ^: \8 e- B( e1 k+ N04测试安全保护特性/ ]6 L6 M3 _! ^4 u# v1 q
当程序跳入到 APP 后,显示如下界面
/ ^# f! N. E- @$ u1 c
7 o2 y7 d) f+ n
微信图片_20231211140118.jpg
" p! L% |& M) j6 w
图9.测试主界面
0 I; F: e5 L, p

  t! R) L+ r- s; r! ^) s8 L
: ?1 n& \* ~5 _1 L  x1 f" \1 Q
当选择 2 Test Protection :Secure User Memory 时,结果会出错 :  c* g; R; [# W7 p/ B* `. X! n" K5 H

  U" e2 X: B: ~/ a0 L7 s
微信图片_20231211140114.jpg

4 G% Q+ [# P6 F# d1 \
图10.测试保护

8 U7 ?: }. t& e+ o, M1 i0 g7 l9 C" @
+ W1 N( {. S, N8 V
很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:$ q. w5 {+ }' k, m) t

* b% \1 \/ ?6 K6 i( {* d7 @
微信图片_20231211140111.jpg
) K7 \/ t/ c2 P, o& S+ O 微信图片_20231211140108.jpg ' @( U; t: r6 j, a, a- k8 S
5 d" V1 @% u! h+ ]& T! c4 K' }5 f
原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。# Q0 r2 V+ C9 f- x9 G
  f1 U2 ?% X9 f. f% D
首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:
7 L; m- Q* y/ o  y5 d9 T  j' v: U) d
微信图片_20231211140041.jpg ! i5 c1 l$ `& B/ E% |' W$ I
+ T+ N% j  Q9 T2 @
同样的尝试读取密钥:
) y% ]+ }! I5 q' j0 ?/ k' ?& X4 w3 l5 R, e; M- ?
微信图片_20231211140036.jpg

/ @0 }% p* E. Z" d, t
图11.UserApp 尝试读取密钥
0 l$ x& p+ J# F$ c5 t1 Z

1 a6 s+ z: Z0 g7 K
测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。 ) D( U& [8 w. ]0 N3 O) N, J9 |

% ?# b  L9 x4 G) k2 z仔细查看图 2 的 STM32G071 的 SBSFU 原来实现中,SE Key 是通过 PCROP+Secure User Memory 来保护的,现在换成 STM32G070,原本 Secure User Memory 用来作隔离机制, 现在换成了 MPU, 而原本保护 SE Key 的 PCROP 在 G070 中压根就不存在,于是 SE Key 只剩下 MPU 来保护,因此,我们接下来得着重分析 MPU 对 SE Key 的保护。 - I$ \  {; u3 s8 g$ Q4 `: I

3 n% p. `; B: R% |4 l为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:$ s* s# a# F+ ?! y9 l" e6 u/ C1 q
( u& t& F: H6 E+ w2 T
微信图片_20231211135943.jpg
  {  O$ |' z- s% w; @
微信图片_20231211135940.jpg 9 N) o; _# y+ |

: c# Q7 F) d5 g- \6 P9 l然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭:
6 s0 ?4 r( ?8 h# a1 E( x- W. {6 I0 Y, j! x
如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:
+ k8 @5 }- z4 a/ O: J) H2 e2 }9 C% [2 v' j# ~* B, _* [6 w1 x
微信图片_20231211135937.jpg & g: l4 x! V3 A0 r* ]/ S8 b9 G3 u5 W

- a3 D5 e8 a3 v, [# _这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?
" ^/ ^4 ?1 d; E- R& s( q
  }0 E2 c) D7 E) Z$ d在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:
5 _3 w  U$ L% j* Z5 c  r0 A' v" i9 z- ]' E& Q% K6 N
微信图片_20231211135933.jpg
! K* J: m9 c+ a# ^+ `/ u
图12.UserApp 运行时的 flash 和 RAM 状态

! j! c4 {6 S4 s
0 s. |. r0 y; i5 u7 ?8 R0 J4 ~
从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。4 r) |0 e% ]5 ]9 A2 Z3 V. {
/ U6 d. [1 x' O5 a" i
于是在跳转到 UserApp 的内存函数中配置 MPU:
8 @: X1 f, X) w: T5 W# C7 I! B! h1 g; `% a; n
微信图片_20231211135929.jpg
9 X$ f/ u5 }1 {; o: h
微信图片_20231211135926.jpg # y! b) x- E: \. u1 ]/ G- h) h% m
1 L$ y1 t5 T) @. T9 Q& Z
微信图片_20231211135923.jpg
% q# X6 k( c; X( z/ ?6 b. K4 _
注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。   r4 I& ?+ I0 u1 D) L7 @! ^( _0 y3 j
7 l5 F6 B6 m+ G! l- [
对应的, 我们在 UserApp 中增加对 Header 的测试函数 :
5 Y/ @) d/ z) P
4 ^- H% \* ^: m
微信图片_20231211135920.jpg
5 g/ f, h7 ~! U( d

) N, [8 n& t6 T2 i& O- n; \" D重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:
; z! c  x2 S9 |4 d2 x7 R( O, G0 n; g: V* r
2.jpg

4 y: q- o( ~3 c8 e# v! d
图13.测试 SBSFU 的 64K 代码区
9 p$ e3 n0 s# u
* g' C; a. N9 y! M
发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:9 ~, i+ r" U, y5 u$ p' `2 O7 Y
! R' G2 J! e( _1 ~# |! ^6 o0 O
微信图片_20231211135908.jpg
/ y/ K7 A, ~: Y6 J2 C" T
图14.测试 Header 对应的 2K 区域
( M1 S; e: v3 O) l: z& `
( b. C8 n0 T4 G0 ~, u0 X
发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。
$ B) x: p0 Q6 S* S) A7 o
& F0 Q5 O! t& r1 f1 {最后再恢复之前注释掉的除 MPU 之后的保护。) @! A4 ~3 L+ t7 G- c. T
9 C7 ?) s' X, N$ D3 q: k9 Y7 A
05后述
- y- S" l# O) b( I) O- X. Y本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。3 z1 ?1 I0 \" t$ ~; Q
; A8 y( V8 w/ k
如有侵权请联系删除( {* @# @: y3 [, e/ _
转载自:STM32单片机
; S5 s  V9 ~& t  K" I# d2 r1 z) R; z" h3 Q- D1 M2 j

  |# `4 [0 v3 o: ~
+ e9 Y5 K! |9 b
+ V" u0 c3 \( |+ |% m: C  r2 r
赞 1 收藏 1 评论1 发布时间:2023-12-11 14:02

举报

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

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

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版