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

《STM32MPU安全启动》②MP15从BootRom启动FSBL(TF-A BL2)

[复制链接]
小萝卜啦啦啦 发布时间:2024-11-30 19:25
BootRom启动FSBL(TF-A BL2)是MP15启动的第一次跳转,对应到第一篇文章的这个图
: D8 R# l+ U* g2 W0 b* k
5.png
5 a: b5 ?5 ^3 v8 U
我是按从头到尾的流程来写的,和官方视频会有一些差异
4 L, L5 q! v7 B/ @

/ ~+ i; Z( {) G# n
一、第一步:生成秘钥对
9 J/ [% u; z4 `5 z: p# }
首先说一下官方是提供了PC端上位机工具的(名字叫KeyGen_tool,这个工具在STM32CubeProgrammer是自带的),其中加密方式使用ECDSA 256加密算法,椭圆曲线提供P-256 NIST、Brainpool 256 T1这两种,我们可以自行选择
9 a2 `: M! W) X6 y
4 c& \5 t+ B: G; }
我们需要在PC上生成PB key和PV key,最后我们还要计算PB key的hash值(简称PKH)(使用SHA-256计算hash)

# ~  z- a5 ^- p/ @8 L
! Z0 u$ K6 U8 A( J& H4 l4 j
使用ST的工具生成的话,PKH是直接提供二进制的文件,这样我们就不需要自己再做转换了,下一步的烧录可以直接用

9 d' r5 X( d% ~2 }! i; x) B/ _
' p' i+ k" L7 o5 |. g
6.png

4 p9 q8 K/ U7 K. h! }& d
具体如何使用KeyGen,我这边就不赘述了,大家看下面这个视频

8 @! k% D; Y" @- F$ A2 H
[media=x,500,375]【【STM32MPU 安全启动线上课程】2.1.2 MP15x SecureBootROM 如何使能】 【精准空降到 03:14】 https://www.bilibili.com/video/B ... 43b6b7afd3cc3&t=194[/media]
; H' J, N: T! \. l. y  g% }& g

9 r# m" A/ q& a# ^% g' `
( S- `8 _- `; O
二、第二步:编程OTP区数据

: ~2 z  \, A: Y: m+ x. }
刚才第一步生成了一个PKH,他是要被写入到芯片的OTP中的,存放到OTP的第24-31字中

1 `3 m2 f8 u5 P
具体如何写入的操作这里就不展开了,可以看一下这个视频

; `/ t4 {6 s+ ~9 Q0 v- }, R- D
[media=x,500,375]【【STM32MPU 安全启动线上课程】2.1.2 MP15x SecureBootROM 如何使能】 【精准空降到 07:02】 https://www.bilibili.com/video/B ... 43b6b7afd3cc3&t=422[/media]

2 v0 ]0 a# M/ t+ v8 i/ S+ o1 g* H0 y5 w# ?; T# d
这边我就简述一下有几种方法:
+ m/ w% W8 ~( t2 P* n
方法1:使用STM32CubeProgrammer写入,可以使用命令行 或 GUI界面(作为开发人员,在开发阶段我首选就是GUI)

! ]( W/ N! I: Y+ O" S
方法2:使用U-Boot,可以使用stm32key command 或 fuse command

! o7 b* D' p- H9 `- J% g1 d
方法3:SSP(Secure Secret Provisioning),这是给代工厂生产时使用的,主要目的时实现在不安全的环境中安全的烧录这些敏感的数据到OTP中,他本质也是一些加密算法和加密硬件(ST有一个类似于身份认证的卡片,用于实现验证),对需要写入的数据做加解密,这样工厂就只能看到加密后的密文,解密后的明文都在ST的工具中执行,是一个黑盒,第三方是无法知道的,这样来实现安全烧录。对这个感兴趣的可以看一下这个视频

, A& M. T+ S2 x: r5 P. s- N
[media=x,500,375]【【STM32MPU 安全启动线上课程】2.4 OTP安全烧录介绍】 https://www.bilibili.com/video/B ... 8fc87a43b6b7afd3cc3[/media]
8 ]* Y% Z) [' M* V' M! Y

: d- n& A# q3 ~- P6 N' j! p  i
三、第三步:对TF-A固件签名
8 V3 L5 l4 j& n& d6 b* I
ST也提供了签名用的工具,我们只需要把TF-A的固件、PV Key提供给工具就好,工具会使用PV Key对TF-A固件进行加密计算(加密方式就是我们之前说的ECDSA 256加密算法,2种椭圆曲线自己选择),这样得到的结果就是签名的结果了,可以放到header中。

; i, `4 O- I. u) e: v3 v* n; B0 ~, c* J# U
最终你会得到一个经过签名的TF-A固件(他就=header信息+原来的TF-A固件)

4 X% z  j) }, f+ [& I* w3 J# B" s! \0 Q
当然header里面还会有其他东西,下图是整各header的内容,可以做一些了解,但我这边不会详细展开

" n. _) P% z8 `: L
7.png
. W' s9 w: f' N' ~
我们重点需要知道的是header里会储存PB Key(表中的ECDSA public key)、签名信息(表中的Image signature)、椭圆曲线(表中的ECDSA algorithm)

( j3 G+ M- ?0 I& k4 _8 O3 {
8.png

2 P; m+ c* a- L5 x+ H
还有一个Version number,这个也很重要,是用于防回滚的,我会在下面章节说这个,这里就不说了

# Y# z; x# K, c2 l- E7 I
7 E5 p9 H9 X/ }, [, H% e3 u
四、第四步:close device(非必选)
% T; L4 P0 i* v4 s0 |
什么是close device?
4 D' E4 h$ r2 ]
要解释这个东西,我们就要了解一下STM32MP15的Product Life Cycle,它覆盖了一个试用MP15的产品从开发、生产、市场问题排查三个阶段,下图为他的状态流程

, C0 u- K' r9 D. B7 w) x+ v. ?
9.png
7 {( v, O$ U5 Y/ Q7 g1 n) E0 `
我们就看C/F系列产品就好,其他系列都不支持安全启动,那也就没有close device这个操作了
, y# d+ N$ P& a: e& c, }

6 K  e  e; [$ e% ?2 K
UNDER_PROVISIONING状态时SSP时会经历的,我们开发阶段可以忽略
/ W6 h6 [6 u" L5 `+ h: a0 F2 v

0 w  Z7 X& @- R0 @
那么对于我们开发来说就只有3种状态了:LOCK、UNLOCK、RMA
2 ~8 f3 q+ ~$ ]" \7 _

3 ^4 n# C4 R$ q" D2 S! y
接下来我就描述一下这3种状态的具体含义
* w7 F  M; [/ r' Y3 }; p
1.UNLOCK:出厂的默认状态,当产品为这个状态时,安全启动的业务都会执行,但是即使固件校验不通过,也会启动下一级的固件,可以用于早期调试阶段,这样旧不用每次都对固件签名,节省工作量

& H3 }3 ^+ G4 @& Z; ^8 ]$ n
2:LOCK:UNLOCK的设备可以经过close device变成LOCK状态,在这个状态下会严格执行安全启动业务,校验不通过,就不会执行下一级的固件,并且各种调试接口都会被关闭。这个一般就是在生产阶段做的,生产好后的产品都是LOCK状态
* j0 |6 S7 Q" Q2 ?
3:RMA:用于处理市场问题时使用,刚才说了LOCK阶段所有调试都会关闭,那么有问题的产品回来后,研发人员如何排查问题呢?RMA状态就是在这个时候用的,我们可以使用密码,让固件进入RMA状态,此时我们就可以使用JTAG调试了

, ?9 Y# }! W1 o% n
11.png

+ Y2 f1 [; b! R4 {: e7 J' g
还有一张图展示这三者的关系,虽然名字换成了open与close,但是是同一个意思
! E% \3 o/ ?7 F  K0 |# V
10.png
+ _" |0 u/ O' v+ U8 L" h7 \" y$ k

6 Z) c' H1 E; Z. `# ~! a
设备当前是否为open或close,是根据OTP中的一个flag来决定的,也就是说,我们close device的这个动作的本质就是往OTP中写入一个数据(图里也说了,如果OTP中没有数据的话,并且在没有干扰或错误的情况下完成了初始化OTP,设备就会处于open状态,这就是刚才说的出厂默认为UNLOCKJ)

' y: `6 O3 N4 M$ ~, w- i/ b& m% T& m1 U1 Q3 h2 L, z
五、第五步:运行时如何验证
0 C& M7 ^! J5 ~& R8 ?
简单流程如下图所示

* i  ?( p+ v* p6 N6 Y
2.png

) I; I% W% Q* t* `; |2 @
1.上电后运行ROM Code,也就是BootRom,当要跳转到TF-A时,他会先加载FT-F的分区(这里面有2个东西,一个是TF-A固件代码,还有一个是TF-A的header,这个就是完成签名后的固件)

, D" `) R5 M, D% \
3.png
0 {5 M: j8 z/ C7 X. Z" h( \$ L
2.在芯片的OTP区中有PB key的hash值,还有一个version(这个用于防回滚,配合header中Version number实现的,他的具体机制后面会讲)
' |! z. e6 b) |4 i- B0 P( d% ~& F
4.png
: W" y# Q7 A1 S8 y: M5 t/ V
3.

) u" f6 U/ f, `* e7 B* @$ J- @
3.1 验证PB Key是否有效

' H, |6 h9 `8 F
        在header中有一个信息就是PB key,可以算出他的hash值,现在我们就可以用OTP中的hash值和header中的做个对比,看看是否一致,验证PB key是否有效。
! A( P8 s6 h+ F
3.2 验证image是否有效
( G) t. [$ Y( r& M$ h6 f
        如果PB Key有效,就可以开始验证TF-A固件,用PB key对TF-A固件代码进行ECDAS 256计算,和header中的Image signature作对比,验证固件是否被篡改(当然,如果设备为UNLOCK,即使验证失败,固件也会被启动)
3 a& w+ Y9 V- Q% V8 @3 @% X0 u# [& e
3.3 防回滚机制
$ B7 I# N+ B9 a3 _. ]( S: d
        下面有防回滚机制,这里不展开说

0 Y4 R9 i1 J# i8 m0 c8 l
5.png
6 o$ F' f- H& \6 V2 y9 O6 h/ T" A
5 S$ Z* u6 Y5 Z! ?- Z! w$ Z
六、防回滚机制

- q3 s! N( s. a! U
刚才说了在OTP中会有一个version,TF-A的固件中也有一个version,他俩配合实现防回滚

: S5 _9 o* f' ~5 a* J
7 i" o: x( }' K0 p0 ^" {
其中OTP的是一个单向计数器,也就是说这玩意儿他只能++,看了一下header中的version,有32bit,也足够大,不管怎么++,也肯定够用了
  J4 w. r( X. _! v( l5 S. W
2 X" \: ^7 J- N3 t  f
当OTP中的version比header里的高,那么这个固件就不会被启动,这就是触发了防回滚的机制
# b5 A; m6 g. d; U7 E' l; x5 t
! n' O, o4 a0 n' a' b5 _
如果我想退回到旧版本的固件应该怎么办?可以重新生成一个新的带签名的固件,但是header中的version写大一点,比OTP中的大,这样就可以达到目的啦
) ?4 t4 [  v/ Y2 j4 W
8 \* F! n: [/ \; n6 I* L6 s
七、疑问与思考
' s4 Q: G# }% j0 }' T7 v9 N: [

& A& {0 r! f1 j: b) K. b' n这里我有几个疑问
- X0 h4 B8 c% X- F: [$ A1:既然保存在OTP中的UNLOCK与LOCK判定相关的数据这么重要,那么在LOCK后,我们应该是无法再次改写OTP了(这不是废话吗,这么明显的漏洞ST肯定堵住了),我想知道ST是否还做了其他的保护措施,例如给芯片一些干扰,让他读取到错误数据后,是否会阴差阳错的进入到UNLOCK状态?还有我直接磨芯片是否可以实现篡改OTP数据实现攻击?(有些产品使用单片机,会把关键数据储存到片内flash,有些攻击就是直接磨芯片,飞线直接读写flash)
0 i6 W# W" H/ Y+ `4 }+ G7 @. _2.LOCK与RMA之间relock最多就3次?为什么要这样设计?超过3次就永远锁死芯片?万一有一些玄学问题,需要反复LOCK与RMA之间切换该怎么办?
; Y+ y. P6 A' z  `3.如果我header中的version不小心写成了0xFFFFFFFF,是不是这颗芯片就废了?因为OTP中的version无法再++了; O8 F' K4 r' G: J6 m1 M) R. V
4.OTP中的version是在什么时候增加的?是当TF=A固件成功运行后,直接把OTP中的version加到和header中的version一致?
0 z3 E6 j+ ~" r4 H+ H. p8 W5。我如果生成新的TF-A固件,但是header中的version还是和上一个可以正常运行的固件的版本一样,那设备会怎么样呢?会正常启动吗?还是说有一些什么其他机制来做判断  n. I1 X) J! i; d2 J* j

% k2 ^4 T: E8 H8 z0 h8 T9 Y- d
0 H# n; Q2 K2 l
" S$ a! H9 B1 K6 ^
8 C- _8 m1 \  D# }0 z. y
赞 收藏 评论0 发布时间:2024-11-30 19:25

举报

0个回答

所属标签

相似技术帖

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