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

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

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:02
01前言
0 O# q' b* a* i客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。
& V) q; w3 @, r$ ?7 x7 N) F2 F$ ^# q( l- i: k8 g/ o* J  M2 o

/ o- R) U; v% h2 V; |2 f02基于STM32G070和STM32G071的SBSFU 实现差异
" {0 E8 T. X# w7 f在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。 + j8 a* n7 \* M) e+ X
; D, `) `6 a0 w# f( J" ~4 Q' g
STM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?
, k& t4 O4 T2 D5 k/ N" L* l+ m8 a& a0 Z+ N+ [7 `4 F9 H+ }2 Q
微信图片_20231211140158.jpg
, s* A% C+ G' {- D

2 P4 s1 |# D: Z& w7 n  x! G
图1.STM32G0 的 SBSFU 安全实现

* C7 K4 }9 C% g  g' f
& H5 Q8 T0 f" A; E7 t
如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。
3 v; m0 x/ S& w( ~
: F; z- V+ @. E8 F: p3 M
微信图片_20231211140155.jpg

3 X; r- f, K8 K2 Y) @6 C) n3 R
图2.STM32G0 内存安全映射(运行 SBSFU 时)
* y# O, \; m1 R; `

! L# Y# _& S8 S4 a* n: v回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗?
# ~: S6 O( T; l4 d; F# U! R5 _2 W2 K' Z
我们再来看下对于安全启动而言, 它需要实现哪些基本功能?" V! a& B. b- B# f) A6 O
1> 不可更改不可绕过的一段启动代码
/ j4 ^* G' x0 T- N+ j- p2> 每次复位必先执行安全启动代码. t. E4 b! _, E: @5 N% n! d
3> 验证系统配置的完整性
$ i* x$ a# }( `9 p* s- X; m! d    • 时钟配置( z; N4 b# I  _+ @: M
    • 寄存器配置8 R! w+ v9 H" k; g
    • 存储器保护设置, …./ N. n8 l" E/ r- H
4> 启动信任根服务$ w  _) W- z2 @* N, u4 N) f7 P; F
    • 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改)
8 p3 W. U& T4 L, o# f: W1 r7 X; c2 T8 R6 Z8 _) p8 h, A
这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如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 功能的。
- ?/ n& }& o8 X5 d8 H3 n. D4 o% E3 m' t% u1 l7 z# i6 A6 |
微信图片_20231211140151.jpg

5 C3 g3 P/ D1 J$ g
图3.STM32F4 的 SBSFU 安全实现

+ x6 {& ?3 t9 Q! j
& y+ O- ^  U9 S+ P! p6 C8 |) _3 R
如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。9 `/ f9 Z) Y# T/ @3 x, N- M) g% I" T

, \/ s) T0 h& ]: Z8 j6 V& q
微信图片_20231211140148.jpg

" O$ {4 ]7 ^- t+ p0 s
图4.STM32F4 的 SBSFU 内存映射
$ C% A2 K& D* a3 m& F. K- R% v. K
2 l. H. s- D" D0 e3 Z* A; r' R( M
到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行! , j! Y" v& Y3 ^
# U% O% }6 O, `1 H0 p$ [
在确立了大方向后, 我们接下来看具体如何实现。
6 Q. b3 J; [$ m! _$ j$ u5 |
& [; z6 r6 D8 e- j5 K" R& C03开始移植
* f3 _, w  j* P0 G4 ]7 l8 j8 n第一步 : 确保原始工程运行正常- \( l% ~' M' q$ a) k- l
从 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 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。 / N: G  b7 P' p, R

( c* w9 [! ]5 E' l# `3 p第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭
, p  u- L* r; A1 Z. j- h! M; U' z打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :
6 w1 }  `. ?* N
* f; G4 J) g" I! l) B
微信图片_20231211140145.jpg

8 b# @) s  {7 G! Z  _% c9 J- w. x

$ S+ L8 t& K  m8 L! b8 X5 z重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。
* x$ `& ^4 W5 ^3 X
+ s) j7 p* c- w- Q  t0 g. h  [至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。
1 b: b1 w' O* i$ I- W7 t3 h
" a+ R" x7 d3 y# i, |第三步 : 移植到 STM32G070RB
  ]. k& I8 z' a3 o! r6 j( C' [首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。 # `& ]+ @, ^7 i
8 M2 T/ S  h# n8 j0 p
以 Keil 为例 :. \8 T  m! c0 N. X3 Z2 s
微信图片_20231211140142.jpg

5 O' j  X/ m+ c5 Y  q
图5.device 选择 STM32G070RBTx

& q# e) _( k/ O
/ f! H0 T9 X+ o% J! i
微信图片_20231211140139.jpg

' L3 T1 X" o3 s* S* D8 }# j+ O
图6.C++编译宏修改

# ]1 i5 }9 i* g  f

( x; n1 E+ f4 D' F7 F* |( R1 }2 m  NSTM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 :
$ a( E6 z% h1 }$ p) b- Z$ R3 ^1 z6 R
打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :/ @  p" e2 [  e6 L* y& k! w0 o8 s3 Z4 e

! \6 ^/ Q! ?3 ~1 K0 M. G
微信图片_20231211140136.jpg
7 t- E# q6 a! n  w6 y; @- e6 h- m
图7.STM32CubeIDE 下的 device 修改

8 J; p- [: t% R4 p
3 V  N' p* O% m* M
修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:
5 B/ I2 A7 U# A0 f, \
  Y; Y8 [6 ]1 f% J2 s  k
微信图片_20231211140132.jpg

# d# [; Z% ?5 u8 K9 t6 i
图8.STM32CubeIDE 的 MCU 配置
8 U- w: b, y- v& X) ^. b2 N

6 j' p! N# v8 o) l由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。
5 r; _) p: Z. E1 ~5 `9 a% r
6 P! l% z/ v9 I/ _' W( @至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。4 Q, v9 }& A# D7 {  H  t" p) |7 g

/ _4 e) v; Q1 W, v首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :* W7 d. I& [' @; O& c. j  f3 x' x" A
) a$ S- e9 W8 C6 {
微信图片_20231211140129.jpg
7 m+ ^# V4 g. T3 d& `% o4 I0 l( m7 i
原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :
) Q& L* c# a4 q! D0 U# Q0 r9 w
8 X. O- W2 l4 H) t, G, ]
在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:
& Z" U; _8 P1 J# ]& @7 @+ |
" s" l* r0 s8 o! {+ n9 J+ D( i+ I/ \
微信图片_20231211140125.jpg
/ o& e  `1 @) y 微信图片_20231211140121.jpg
7 c% D: i7 K6 S+ Q5 O
& P2 Q& M2 D$ o+ ]1 c/ Z如上红色部分即为修改处。
+ [4 ~# c; o3 ~! M7 I
: [+ m" H  U* [* O8 z) Z- `至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。
6 c4 a  c" q% p5 m8 P. g& @6 q( w3 z; S7 I
( B: H7 ~7 Y3 a' `
04测试安全保护特性
2 j* B; j. S7 h# x1 }当程序跳入到 APP 后,显示如下界面
  U6 ?9 L$ A, R$ |* [. ]. G( W8 }$ W9 l6 F* g3 I& |
微信图片_20231211140118.jpg
3 }% O7 c% \' [- P; u( b# [
图9.测试主界面
& C0 M) k2 N5 p' a
% ?8 U- b5 U% i

% e/ H9 C* }: f3 g5 J
当选择 2 Test Protection :Secure User Memory 时,结果会出错 :4 `2 ^- B2 P) |- E$ o8 U' O: W. u* C
3 D: h5 H9 R5 x$ C
微信图片_20231211140114.jpg

2 D5 P* O: Z' M. Q/ z* q. d$ a: o7 w6 j/ ]
图10.测试保护

, J2 D' B5 _8 L, O1 p, P. A+ P

, P2 H$ E/ U, {2 M6 u很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:# y3 o7 g! H* z& [" `0 j

8 ?2 j' V' Z3 w% l
微信图片_20231211140111.jpg 5 t# I7 i8 l8 [! C: }- b
微信图片_20231211140108.jpg
# t  X2 }! I8 P3 _# C% n$ s$ O
5 E7 C2 G) r  ^, ]" R原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。
- V* y+ N$ b7 Q, r: R: O

( H) g" y$ M8 b首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:
# w; h7 E: W% |7 Z) O. g  _( x0 t; B! C' ?+ N
微信图片_20231211140041.jpg
, n  L# h- z, Y$ j# m9 t& V3 k$ C& i
同样的尝试读取密钥:* W9 Z/ L% b6 P2 x3 g5 u4 K& s7 l3 l
2 ]  q0 f' \7 W5 k' U$ J- e
微信图片_20231211140036.jpg

0 F6 b4 z5 v. H
图11.UserApp 尝试读取密钥
0 p- ]0 @' ?6 h* M

* S6 A! o' ~1 o% w9 Y8 h. N
测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。
7 C/ g  i  X3 V$ g7 p, ~# u# T% h% W, ~  D& 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 的保护。
2 s9 E$ W, H( J4 l5 ~5 |" U6 v" o/ t' Z  }) ^" A5 A1 S
为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:3 w6 V2 A. q" }0 g4 H- p' m
- [9 W/ r: `; A$ h% E& O
微信图片_20231211135943.jpg 5 k5 e; f# @+ k1 m% y* X+ s# _
微信图片_20231211135940.jpg
# m  P8 o3 g$ Q
, O" A6 M1 c$ u, ]2 b" `- I然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭: 3 w1 ^. }! ?9 h) v
' S) n, f8 X" O: V! h- m6 g& ^
如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:
+ i7 q  r0 a9 {0 Z  g+ |
9 F5 U% I! g( x1 Q0 @
微信图片_20231211135937.jpg , U6 j% i$ v5 E( n6 Z9 C' j

: i4 `( _0 I9 m' S这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?2 r0 _+ \& L/ Y/ L
( X- P& z  H! l% u1 W
在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:% ~; `( R3 s2 O. Y* }1 D
! ~" z, g, z+ N
微信图片_20231211135933.jpg

& Q# ]$ d) ?9 G; {
图12.UserApp 运行时的 flash 和 RAM 状态
& M: f; l! T* _& p
. Y! R2 P) i- B6 [: j6 L  x* [
从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。
2 r1 T$ G, P9 D, I% \$ G
: r  K9 Z" s& T; P* ?% f7 S
于是在跳转到 UserApp 的内存函数中配置 MPU:
  j5 C) P' ~  ]- |" W, b8 e6 z1 T0 C* D5 C/ m
微信图片_20231211135929.jpg
! E9 L2 h/ h. \4 i3 v
微信图片_20231211135926.jpg % @: `. x! t& Z  r; |

- N* j) r' r9 d3 f 微信图片_20231211135923.jpg   O/ `, M' {$ y( M* u- Y0 z
! l0 \! ?+ q5 f0 i# O
注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。
& @5 q/ v* t. }' S# N0 m6 [
) T- ^- l- d1 o+ C' H( Z4 }: U对应的, 我们在 UserApp 中增加对 Header 的测试函数 :* ]' a: N( z. x( j. j% f1 b
# e) [4 `9 G( k- W
微信图片_20231211135920.jpg 3 M0 B( ^0 G0 o7 l  n, }" D# {

8 H% ?, x  Z% @5 n4 Q" e# }& f重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:
9 K: R% c  s, F0 t; @
. u6 {! F  z, ?' H
2.jpg
" z7 I. e" z/ t' \7 q/ p# n  x& P' W
图13.测试 SBSFU 的 64K 代码区
8 h. i4 |9 Y$ x, S  [- ?5 V+ J

* Y/ _' l" [: U1 v+ R发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:2 q" u& S4 y# t4 s
1 a) l0 @8 }6 g
微信图片_20231211135908.jpg

, b! u& @! l4 W6 ~+ a0 @
图14.测试 Header 对应的 2K 区域
. E. d) J' F6 V: |" V, Q& W6 o3 d
) O0 F) k" \* S8 T5 N5 Y2 T
发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。
9 Z6 M7 {7 [' T" b( s3 X0 I7 N3 G7 }8 S
最后再恢复之前注释掉的除 MPU 之后的保护。
  R' B6 k, V# U  z8 e, b# C
0 Z) Q' l: T- V, M9 R! z05后述
# s7 ^( e( a) |6 J1 y1 u$ }本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。, A1 s, L! R3 g8 [5 m; [1 \
8 b4 {) j- O; t1 _' I$ K/ R& ~
如有侵权请联系删除
; p3 u6 Z( r% u$ e$ g8 L6 g/ i0 D转载自:STM32单片机" R' `' J9 F8 p# j! q: {

# |" b1 B; B. @0 V# T. f* X* R( l- r/ w: z4 `
% y, T) R, B) i" H
& q0 y, k4 H3 F* ~8 M2 j7 \
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 手机版