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

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

[复制链接]
STMCU小助手 发布时间:2023-12-11 14:02
01前言
+ y3 j6 H9 d$ P客户使用 STM32G070RBT6 给海外用户开发产品,由于当地新需求,产品需要增加安全启动的功能。但是由于 X-Cube-SBSFU 包提供的示例中,只有基于 STM32G071 的示例。客户因此询问该怎么移植。本文将讲解这个移植过程。
* d# O  \* j  i$ x7 n. n1 b* S* Z% q0 P" c' r. @- D$ x7 O

% ~) P/ {7 o) Q, G, N02基于STM32G070和STM32G071的SBSFU 实现差异3 O: T' e. l9 ~2 e9 ~: |
在正式讲解之前,我们首先来看一看 STM32G070 和 STM32G071 的 SBSFU 实现差异。
( l9 c! S3 _  s. M3 B% A2 l5 Q. ]3 j4 T
STM32G070 是一个 value line 产品,首先,我们要意识到,有一些安全特性,相比于STM32G071,它是没有的,比如:PCROP,BOOT_LOCK 和 Secure User Memory。那么,缺少了这些安全特性的 STM32G070,是否还能实现安全启动的功能呢 ? 答案是肯定的。我们先来看 PCROP,BOOT_LOCK,以及 Secure User Memory 在 STM32G071 上的 SBSFU 实现中所扮演的角色是什么?
3 G+ L" @6 B3 N! v& P0 R. I' v# u8 V. y7 \
微信图片_20231211140158.jpg
; \# y$ r8 S$ ~
3 Z: U- K3 g8 G1 K. v* ?
图1.STM32G0 的 SBSFU 安全实现

- v( m, X5 m8 m* j; P: M/ n

# A5 m! @6 q: [* m  a- _8 u9 l如上图,在 STM32G071 中,在安全启动的实现中,BOOT_LOCK 用来参与实现唯一启动入口,Secure User Memory 则用来参与实现信任根。PCROP 在安全固件升级实现中用来与MPU 配合实现密钥的安全存储,同时在安全升级过程中涉及到一些密钥的加解密操作,借助于Secure User Memory 和 MPU 的功能, 将 App 与 SBSFU 本身实现完美隔离。
* c) _4 H0 e9 n
6 M$ J- M0 I! _7 ^+ R2 D% J: b
微信图片_20231211140155.jpg
& E% K1 T% }2 Y6 b$ `' L, C- A
图2.STM32G0 内存安全映射(运行 SBSFU 时)
- h: {+ f7 L/ `" q0 A+ X+ {
) K6 d  Q) h, y7 ]# V4 i, F0 D
回到当前问题,一旦 BOOT_LOCK,PCROP,以及 Secure User Memory 缺少的情况下,这些功能还能实现吗?
6 v. x7 g4 s( _7 D# Q" i0 h4 s3 D- N3 i4 ~  F
我们再来看下对于安全启动而言, 它需要实现哪些基本功能?
% D6 E9 i$ G) s2 x1> 不可更改不可绕过的一段启动代码
! C& ?4 i1 T0 P2> 每次复位必先执行安全启动代码! f+ }9 x7 ~8 T
3> 验证系统配置的完整性
+ x+ n$ n9 B1 x  h2 p1 B# E    • 时钟配置0 T! g; K; k& P" F* F! x
    • 寄存器配置
4 A3 [& M2 _" q/ z- @# n- f8 o    • 存储器保护设置, ….
4 q! {5 e/ E' |; x- H: @# K4> 启动信任根服务& ]; t2 T* ]3 M% ]
    • 通过密码学算法与密钥,校验 App 的完整性与合法性(来源可信,未经篡改)
! y% V! [7 b2 p( r+ W. z9 u% x3 B  p& Z% o& y' y( F
这里需要注意地是,上面提到的某一项安全属性也只是参与实现某一项功能,比如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 功能的。
+ G0 W* K5 |( D  g2 ]& i+ h$ _; x2 x
微信图片_20231211140151.jpg
  o% `3 X+ ?/ ~$ A% x
图3.STM32F4 的 SBSFU 安全实现
1 A* N; `- W. W! J# c

; K+ B" h  ?. X6 O: W" l' F如上图所示,在 STM32F4 中,借助于 RDPL2,WRP,MPU 就实现了 SBSFU 的全部功能。
4 t2 H( v5 R% X3 X9 i- s" K/ B
, J/ Z+ @% X3 A% t
微信图片_20231211140148.jpg
+ k6 L) K, F$ f& R
图4.STM32F4 的 SBSFU 内存映射
! @, v* u% k- U

# k$ N6 w6 H) O- X! v! z" R. U到这里,我们完全可以确信,在缺少了 BOOT_LOCK,PCROP 和 Secure User Memory这些安全特性之后,STM32G070 完全可以按照 STM32F4 实现 SBSFU 的方式来进行!
( {1 f+ ?$ E% H$ k) Z  ~3 R1 O; \+ J8 {# H8 H4 ~& Z
在确立了大方向后, 我们接下来看具体如何实现。
; ~# A( T3 a6 `: x* r9 E$ S7 j
  v, R* E9 G/ ^! A03开始移植
. C  M! E4 f0 Q+ t* `+ j0 X7 n9 `" U第一步 : 确保原始工程运行正常* [1 r2 i. f$ d2 S5 p
从 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 进去。目的是首先确认原始工程一切运行正常。接下来就开始修改了。 % j3 R2 N6 Q; x4 \3 ^' n6 A6 @7 q( \6 v

5 D+ q3 C6 B6 b' _% g第二步 : 将与 BOOT_LOCK, PCROP, Secure User Memory 相关的宏全部关闭" F, v: `8 S' O% x4 U: Q3 m% p
打开 SBSFU 工程的 app_sfu.h 头文件,找到并关闭下面三个宏 :
( v- u7 b! m, U' K' U1 X% o$ ~: Y3 Z/ k1 v- w
微信图片_20231211140145.jpg
6 p3 H  g$ j: Z1 d! J+ i# Z5 h

; G- }( Q+ N& ~  }0 R# O重新依次编译 SBCoreBin,SBSFU,UserApp 三个工程,并重新测试通过。
5 c3 J2 N9 Z" S0 V+ Q/ m4 L, h9 z2 d3 o
至此, NUCLEO-G071RB 板上运行的是移除了 BOOT_LOCK, PCROP,Secure User Memory 三个安全特性后的 SBSFU 程序,这个原理上与 STM32G070 上原则上是一致的。接下来就是要移植到 NUCLEO-G070RB 板上了,剩下的就只有 STM32G070 与 STM32G071 的非安全特性方面的差异了。
% l. s6 X4 h+ |6 ~2 |6 b- _2 x6 w" t
第三步 : 移植到 STM32G070RB
; G1 z% G  O8 z9 f, E, f首先得准备下一块 NUCLEO-G070RB 板。接着将三个工程 SBCoreBin,SBSFU,UserApp 的 device 修改成目标 MCU STM32G070RB,然后将三个工程的 C++预定义宏STM32G071xx 修改成 STM32G070xx。 ; v$ X8 D  a4 l

/ r" V  J: \. K以 Keil 为例 :
) K3 F( {) v1 b; w4 t
微信图片_20231211140142.jpg
: V, p5 j! v1 g, B. l. r% h
图5.device 选择 STM32G070RBTx
" l1 C" |* F1 y" B( i$ x
' ~" A' D$ ~0 J0 ?( N$ P
微信图片_20231211140139.jpg

6 d* L8 k* I; Q  K
图6.C++编译宏修改

/ q0 O! w! C* [! I0 ?/ H
' C, b7 }% H3 }8 l
STM32CubeIDE 工程的 device 配置比较难修改,因为它原本是灰色的,不允许修改。但我们使用 UE 打开.cproject 一样可以强制修改 : & \0 T9 Q& w4 v/ v3 _0 t) m
: j% A$ T" G8 s9 ~; m/ l
打开对应的.cproject 文件,搜索关键字 G071,将以下几处替换成 G070(修改两处) :3 P/ f+ `$ l+ y8 s0 k

" u( D4 G# o6 x( R* {4 F
微信图片_20231211140136.jpg
6 Y! ^0 ]% j0 Y0 a) w0 K
图7.STM32CubeIDE 下的 device 修改
0 C; L' s0 @4 T  l* a% r% `

+ R" j, L$ P. Z8 U$ H修改完后,打开 STM32CubeIDE 工程,在其 MCU 和 Board 的配置也会有相应的变化:9 M1 w4 _& J$ a- r
. |0 ~( ^0 x& Z, J
微信图片_20231211140132.jpg

  r2 u  w9 q- x, s& p/ n
图8.STM32CubeIDE 的 MCU 配置

! n( B1 I/ c: M1 j. N# s6 ~
8 k. \: X/ V& V9 D0 b% y! Y
由此可见,在 STM32CubeIDE 工程的 MCU 配置也可以做相应的修改了。这是一个小技巧。
4 J# d! C! D5 ]% f  B9 n
; v" J6 d4 D0 h; O0 y, D1 O至此,三个工程的工程配置都做完了相应修改。接下来的就是代码方面的修改了。8 @, k9 `1 K% E* G

0 q% k. A2 I- W- M4 v& D首先 STM32G070 的时钟树是没有 PLLQ 输出的,因此,在 SBSFU 和 UserApp 这两个工程内找到 SystemClock_Config()函数,注释掉 PLLQ 的设置,如下所示 :1 \5 S& n0 _1 i5 `

* k, C' Q) K5 I
微信图片_20231211140129.jpg
( \/ a2 N# m- S. P# D( }- H$ o- j( h! o# ~) Y" `
原先 STM32G071 的工程中的打印信息是通过 LPUART1 对应的 PA2,PA3 打印的,换成NUCLEO-G070RB 板后,其引脚虽仍然是 PA2,PA3 引脚用来串口打印,但是 STM32G070中是没有 LPUART1 这个外设的,需要换成 USART2,因此,其对应的代码修改如下 :
$ i8 ?( x) ]1 B3 n" Q
2 y+ {* s" m* K$ E1 x! J& u8 _3 E
在 SBSFU 工程中, 打开 sfu_low_level.h 头文件 , 和 UserApp 工程的 com.h 头文件中:$ a! g' j2 ^+ h0 S/ @% g% P
0 V$ y' p* K' }4 I3 b' z/ @
微信图片_20231211140125.jpg
8 O; k4 z* I- S5 v  B# d5 h) H 微信图片_20231211140121.jpg 7 W. W1 o# r. K0 @7 m, Q; `1 V

) ~/ ]$ C! ]( }' N如上红色部分即为修改处。
5 W; e4 y7 Z) O) S- B! L4 ^4 H  }. D+ t; ~1 F' P! e
至此,代码部分全部修改完成。重新按顺序依次编译 SBCoreBin,SBSFU,UserApp 三个工程,将 SBSFU 工程首先烧录到 NUCLEO-G070RB 板,然后通过串口终端,按提示,用 YModern 协议将 UserApp 对应的.sfu 文件烧录进去。整个流程都可以正常运行的。这说明软件框架基本已经 OK。接下来运行下 APP 中各种安全测试。
  o5 N4 e" L: x5 k: L
1 J) D& o' F3 a+ m# I8 Z( d
$ l) I! x  J* ]* @+ C
04测试安全保护特性
( k" ]6 e. a$ ~1 M& M3 l当程序跳入到 APP 后,显示如下界面
2 N7 X/ \4 Q5 n! X" `( @9 \0 D4 f" x
微信图片_20231211140118.jpg
1 i9 L( J; u/ u
图9.测试主界面

& o+ P$ O4 o* h) v

1 }* |9 a9 V+ @% I  I! P' `* J; ]! e  O, j$ F: ]7 E
当选择 2 Test Protection :Secure User Memory 时,结果会出错 :
* }, t2 `* t) [: X% S% R3 q- d: v1 f; p; K' Q* L8 J4 q
微信图片_20231211140114.jpg

1 G, u2 V6 ]: {. P) e
图10.测试保护
' E( x6 e5 Y8 p. b
1 Q8 A4 F  _" |* Q6 T
很明显,这里需要修改下,因为 STM32G070 是没有 Secure User Memory 的。查看其对应代码:
4 g# A4 }: ^( [
1 S- d# {# Q3 R5 D5 i
微信图片_20231211140111.jpg 4 j6 j/ A+ N. S2 [4 t7 _
微信图片_20231211140108.jpg
# v7 b8 }' t3 o: B* b
4 Z3 v. h  C: F原来 UserApp 是测试直接读取保存在 SECoreBin 内的密钥数据, 测试是否能读出。结果发现是可以的,因此,保护效果是出问题了。
4 h, \; G$ D! M. ^

* x4 Z" L. {" D首先我们修改下此函数,由于 STM32G070 中 Secure User Memory 是不存在的, 此函数叫 TEST_PROTECTIONS_RunSecUserMem_CODE()已经不再合适, 依照 STM32F4 的SBSFU 实现,将此函数换成 TEST_PROTECTIONS_RunSE_CODE()函数:
9 ]3 O: r  D1 v. Q& t1 J$ A0 I7 N5 S/ s" T9 R4 v! y2 @
微信图片_20231211140041.jpg
! b6 [; ^6 \; }6 o+ R  o1 j- u" L8 T, ]( A& x6 G4 `/ `
同样的尝试读取密钥:
7 o4 @2 y' c* b0 z! a, m* Y1 g) B6 ^5 \
微信图片_20231211140036.jpg

" \" e& k+ P& Z! l# x5 a
图11.UserApp 尝试读取密钥
* N- L' _  y, _- E

" I" [( p! t# S5 N
测试结果可想而知, 肯定是可以读取的。于是得查看下为什么可以。 8 [4 N4 n) R* s& ^
, M* T! D) s. _  Y, K% ~2 V
仔细查看图 2 的 STM32G071 的 SBSFU 原来实现中,SE Key 是通过 PCROP+Secure User Memory 来保护的,现在换成 STM32G070,原本 Secure User Memory 用来作隔离机制, 现在换成了 MPU, 而原本保护 SE Key 的 PCROP 在 G070 中压根就不存在,于是 SE Key 只剩下 MPU 来保护,因此,我们接下来得着重分析 MPU 对 SE Key 的保护。 / m+ C" P6 F7 o
: u1 s/ F3 c. a$ i- f
为了方便调试,我们首先得将除 MPU 以外的所有保护通通关闭,只剩下 MPU 保护。于是在 SBSFU 工程中,在 app_sfu.h 头文件中,将以下宏通通注释掉:
, {% M# }$ D% J9 v/ Y2 e
2 z- R  V, G( S8 u$ s
微信图片_20231211135943.jpg
4 M# d& b5 c- O1 P7 k* H6 s
微信图片_20231211135940.jpg
+ e2 O) g0 p$ a& x5 L, I- u8 L. N5 W1 j& q4 o
然后开始调试。在调试过程中,发现程序在从 SBSFU 跳转到 UserApp 之前,在代码中特意将 MPU 关闭:
" F" r6 V, L) d0 x# T
8 [4 x6 p: T+ N6 Z4 `如在 sfu_low_level_security.c 源文件中的内存函数 SFU_LL_SECU_ActivateSecUser()中有这么一行代码:
( V( U5 A( k1 z! Y. I1 f
( o" e5 L9 H) Z- l; X
微信图片_20231211135937.jpg . P0 b7 J, w) P- E  i) L) S2 E' x1 Y

+ t3 T2 l+ ^! V这就是为什么 UserApp 中仍然可以直接读取密钥的原因了。很明显,接下来我们需要将 SEKey 用 MPU 保护起来。但在这之前,我们得首先弄清楚,当程序跳转到 UserApp 后,Flash 和Ram 该如何设置 MPU 保护?
' Y3 S8 G3 O; d3 l  {+ n- E5 a( K
在 UM2262 中, 有提到当程序跳转到 UserApp 后 flash 和 RAM 的状态:- ^1 ]9 i) t4 {* D4 T; m1 [9 O' X

: a3 q$ Z% n& |6 p. O
微信图片_20231211135933.jpg

- ]- Q( c' h- s) m$ F5 R( J1 ]6 f$ e
图12.UserApp 运行时的 flash 和 RAM 状态

' B" G: N  M' H7 K4 J- T

8 ^# H" E3 _  E9 e) m( `& ]% e从上图可以看出,原本 Secure User Memory 保护的区域,我们得使用 MPU 来替代实现相应功能,包含 SBSFU 整个代码和 Slot#1 内的 header 信息。这也就是在代码跳转到 UserApp之前需要做的事情。而黄色对应的 SRAM 区别已经擦除,当程序跳转到 UserApp 后其实已经没必要再保护。
7 K2 i7 V6 q/ ]* a2 ^& q  O+ v' x
/ r- I# B; w) B5 j& Q/ a% ]) ^$ ]+ a+ {
于是在跳转到 UserApp 的内存函数中配置 MPU:, Q1 |& r2 n" d  U) t' y( Z% M! u

. _& g. e9 G4 ]8 k8 e
微信图片_20231211135929.jpg ) ~8 ]6 h- Q& v
微信图片_20231211135926.jpg . V& R9 u: I  ]8 `. m

. I3 Q  o5 b8 g9 p8 r 微信图片_20231211135923.jpg
% M& x$ Y3 z/ h& x
6 ?) z* r$ h3 t6 y8 v注意这里是一个内存函数,它所调用的所有子函数也都是内存函数。在这个函数中我们将SBSFU 所在的 64K Flash,再加上 2K 的 Active Slot 的 header 信息保护起来。内存 RAM 我们并没有配置保护,因为跳转到 UserApp 后它就完全开放,且内容已经清空。   c6 }4 K# }; J/ b4 o; p$ p# |

0 k8 w% g3 h; x, ?" X$ q% C- E对应的, 我们在 UserApp 中增加对 Header 的测试函数 :0 }/ K5 Q. S$ r

8 d- s0 R  j. H* U. x. r: v9 d
微信图片_20231211135920.jpg
. J& M+ z9 N; {- \& ~) l5 \) H& w9 y

5 q0 F( ?( e, ~$ r# c+ v4 P9 O" ^重新烧录程序,当程序运行后,选择 2 进行 protection 测试,然后再选择 2,测试访问SBSFU 所有的 64K 区域:1 t0 |. f: i4 v$ l* R$ Z6 @
9 P6 P6 S+ N. o5 J4 m  C
2.jpg
  ~$ e, C& A( m
图13.测试 SBSFU 的 64K 代码区

4 R2 B0 V. g# q1 {

% c5 z0 R  g2 f, w, C/ Q/ E发现会一直卡住, 这说明 MPU 对整个 SBSFU 64K 区域的保护已经生效。同样的,选择’3’测试 header 所在区域:
7 k0 A# G6 n: d" _! F: o1 Y& z! i) _4 I: x/ Q
微信图片_20231211135908.jpg

' [, W) ~) N: W  f* k9 Z7 t- ?
图14.测试 Header 对应的 2K 区域

! N. J) `- m8 Y& Q+ i2 r# d( ~
$ u8 U) ?  h2 y9 w
发现程序读取 0x0801 0000 地址时会一直卡住,这说明 MPU 对 header 的保护也已经生效。然后再测试了下其它选项,包含下载新固件,还有其它默认的一些安全特性,基本都是OK 的。这说明整个程序基本已经 OK。
# e0 i" e7 P2 V2 f' m. s- C# Y
3 |" l, C; h% `! _: i最后再恢复之前注释掉的除 MPU 之后的保护。4 `. v3 y  L& K# v6 R" [/ q
8 q3 k% I, G7 }. R
05后述
& ^7 Z+ g4 p8 j4 ?" B2 V* S8 I本文旨在通过一个相对容易的移植, 让读者对 SBSFU 的移植过程有一个大概了解以起到参考和示范作用。
  J! O4 v+ D! U5 S2 L2 M) x8 k
如有侵权请联系删除& }( m% a" k+ f% [
转载自:STM32单片机
2 F5 _' H: D  j+ x; R  m
- w) U" Q  j: v, G, q
$ T, T: _. l8 \( Z4 O9 v
3 _8 Y/ v. G) ]2 b9 ]8 i& @- E# C1 Q) f: J4 ~  `. t# }8 O3 n
赞 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 手机版