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

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

[复制链接]
小萝卜啦啦啦 发布时间:2024-11-30 19:25
BootRom启动FSBL(TF-A BL2)是MP15启动的第一次跳转,对应到第一篇文章的这个图  E; Q( ~/ Z9 @9 C
5.png

; r9 G5 R6 N$ G5 b. z% R; E4 K4 R
我是按从头到尾的流程来写的,和官方视频会有一些差异

' T8 K/ D4 z0 l+ P5 g
+ ?- h! |+ ~! }
一、第一步:生成秘钥对

% D0 i: P) V( _8 ?+ @( Q
首先说一下官方是提供了PC端上位机工具的(名字叫KeyGen_tool,这个工具在STM32CubeProgrammer是自带的),其中加密方式使用ECDSA 256加密算法,椭圆曲线提供P-256 NIST、Brainpool 256 T1这两种,我们可以自行选择

2 M, @. p# |$ i4 c, H+ a+ e- Z. {% j4 m5 M8 I: `! e
我们需要在PC上生成PB key和PV key,最后我们还要计算PB key的hash值(简称PKH)(使用SHA-256计算hash)
: Z# x# S( E: F5 d; a
1 V; D) X4 g$ g+ [- ?+ p
使用ST的工具生成的话,PKH是直接提供二进制的文件,这样我们就不需要自己再做转换了,下一步的烧录可以直接用
* M, |! ], B# w! U. P; x

- `: `" Z1 c2 g1 K; @
6.png
9 R, ~/ c* o& a, x, w9 ^- ~
具体如何使用KeyGen,我这边就不赘述了,大家看下面这个视频
3 J' J8 g. N8 C  o* D2 l& R1 X9 r
[media=x,500,375]【【STM32MPU 安全启动线上课程】2.1.2 MP15x SecureBootROM 如何使能】 【精准空降到 03:14】 https://www.bilibili.com/video/B ... 43b6b7afd3cc3&t=194[/media]

* B' O2 j4 g" O/ o
5 y% o! z4 G8 }9 p8 P7 D, w& ^& P3 c, R
二、第二步:编程OTP区数据

! X# _0 J1 @. a. c+ \8 V& v7 d4 B
刚才第一步生成了一个PKH,他是要被写入到芯片的OTP中的,存放到OTP的第24-31字中
* q6 m$ W4 l. X: o: g! b
具体如何写入的操作这里就不展开了,可以看一下这个视频
8 e6 c% v* |3 Z1 k2 G: D6 q& E: W( q
[media=x,500,375]【【STM32MPU 安全启动线上课程】2.1.2 MP15x SecureBootROM 如何使能】 【精准空降到 07:02】 https://www.bilibili.com/video/B ... 43b6b7afd3cc3&t=422[/media]

' \! P$ l  C' V+ |3 N+ {) K
  }% a5 f4 i0 D; H8 V2 i* m
这边我就简述一下有几种方法:
, [  U: P+ s$ h3 q; z3 m
方法1:使用STM32CubeProgrammer写入,可以使用命令行 或 GUI界面(作为开发人员,在开发阶段我首选就是GUI)

$ E, H% z+ s! S! H4 _% q
方法2:使用U-Boot,可以使用stm32key command 或 fuse command

8 Y8 X: F& h$ p* F9 |9 j0 a7 [. T
方法3:SSP(Secure Secret Provisioning),这是给代工厂生产时使用的,主要目的时实现在不安全的环境中安全的烧录这些敏感的数据到OTP中,他本质也是一些加密算法和加密硬件(ST有一个类似于身份认证的卡片,用于实现验证),对需要写入的数据做加解密,这样工厂就只能看到加密后的密文,解密后的明文都在ST的工具中执行,是一个黑盒,第三方是无法知道的,这样来实现安全烧录。对这个感兴趣的可以看一下这个视频

0 t7 X0 `: j# e  X3 h
[media=x,500,375]【【STM32MPU 安全启动线上课程】2.4 OTP安全烧录介绍】 https://www.bilibili.com/video/B ... 8fc87a43b6b7afd3cc3[/media]
! }1 q9 q0 R/ Y" r) I/ E" h6 l  @

. {& A! G6 V) `
三、第三步:对TF-A固件签名

% l* V& ~) B+ e6 t: q& y$ p8 j: n
ST也提供了签名用的工具,我们只需要把TF-A的固件、PV Key提供给工具就好,工具会使用PV Key对TF-A固件进行加密计算(加密方式就是我们之前说的ECDSA 256加密算法,2种椭圆曲线自己选择),这样得到的结果就是签名的结果了,可以放到header中。

6 e. \/ b' r$ }% d' \' a
( j6 |0 D+ Z1 v) N2 g& P: z, |
最终你会得到一个经过签名的TF-A固件(他就=header信息+原来的TF-A固件)

! z; \6 ]  {/ H% ^
4 Q# a, n3 K% c! y
当然header里面还会有其他东西,下图是整各header的内容,可以做一些了解,但我这边不会详细展开
% h0 j! m+ v9 q
7.png
+ R" I7 A7 i0 P3 A, {& I5 Q
我们重点需要知道的是header里会储存PB Key(表中的ECDSA public key)、签名信息(表中的Image signature)、椭圆曲线(表中的ECDSA algorithm)
- H5 W+ S. e' ^" s
8.png

7 L+ O- F, ^. U& h! p
还有一个Version number,这个也很重要,是用于防回滚的,我会在下面章节说这个,这里就不说了
- k7 A6 o: j4 R8 F
2 M6 |1 `6 W* u: R5 a" |6 e7 G( G
四、第四步:close device(非必选)

* S7 j3 N8 {  W, k) f2 z
什么是close device?

9 J; `$ d, L' |) ]
要解释这个东西,我们就要了解一下STM32MP15的Product Life Cycle,它覆盖了一个试用MP15的产品从开发、生产、市场问题排查三个阶段,下图为他的状态流程

$ j+ O/ L) A# h+ X  E5 M( K
9.png

/ F) Q- I( ~6 d$ O) ^
我们就看C/F系列产品就好,其他系列都不支持安全启动,那也就没有close device这个操作了

# }- ^$ ^8 g" @; d
1 _) f& ]' p( d& a1 p5 P
UNDER_PROVISIONING状态时SSP时会经历的,我们开发阶段可以忽略
, ?+ s- n  l; F7 k* f  U' c% K/ r

) v9 C* u. q+ g% J' O" r9 A( W
那么对于我们开发来说就只有3种状态了:LOCK、UNLOCK、RMA
& _- H/ a: P( J7 W

- X0 W# I' O8 O2 F3 a1 Z) z
接下来我就描述一下这3种状态的具体含义

2 p. A- l5 p4 r- Y5 [
1.UNLOCK:出厂的默认状态,当产品为这个状态时,安全启动的业务都会执行,但是即使固件校验不通过,也会启动下一级的固件,可以用于早期调试阶段,这样旧不用每次都对固件签名,节省工作量
3 }: S( Q( i3 r0 L
2:LOCK:UNLOCK的设备可以经过close device变成LOCK状态,在这个状态下会严格执行安全启动业务,校验不通过,就不会执行下一级的固件,并且各种调试接口都会被关闭。这个一般就是在生产阶段做的,生产好后的产品都是LOCK状态
7 ?7 U" e) J( g
3:RMA:用于处理市场问题时使用,刚才说了LOCK阶段所有调试都会关闭,那么有问题的产品回来后,研发人员如何排查问题呢?RMA状态就是在这个时候用的,我们可以使用密码,让固件进入RMA状态,此时我们就可以使用JTAG调试了
8 D- H% U0 i% \6 i: c5 W
11.png

3 E* @0 ]0 q, @. s4 \# c
还有一张图展示这三者的关系,虽然名字换成了open与close,但是是同一个意思
; r- w6 E( G1 n/ N  h- V
10.png
0 x2 Y6 u1 Z( O# ^

( m0 ^# ?1 r0 Y
设备当前是否为open或close,是根据OTP中的一个flag来决定的,也就是说,我们close device的这个动作的本质就是往OTP中写入一个数据(图里也说了,如果OTP中没有数据的话,并且在没有干扰或错误的情况下完成了初始化OTP,设备就会处于open状态,这就是刚才说的出厂默认为UNLOCKJ)
3 s& P# [' ?7 L" ]2 ~! M
8 \& W5 U, b( c
五、第五步:运行时如何验证

% b- U, w5 l8 t6 E6 I
简单流程如下图所示

+ ]& i  y4 K9 T% y
2.png

' S, P4 x3 S. k0 h7 y) V  Y
1.上电后运行ROM Code,也就是BootRom,当要跳转到TF-A时,他会先加载FT-F的分区(这里面有2个东西,一个是TF-A固件代码,还有一个是TF-A的header,这个就是完成签名后的固件)

5 o* x- I* S) G8 s7 y9 n
3.png

/ ?& W" |. x2 _6 [7 m
2.在芯片的OTP区中有PB key的hash值,还有一个version(这个用于防回滚,配合header中Version number实现的,他的具体机制后面会讲)
4 X+ W  }  p) Z3 L/ U3 R5 T0 n3 ~& i8 X
4.png
% {: h2 y0 c* m4 Y& @1 o
3.
4 `. w( k4 C/ {' K6 v% h" |& ]( T
3.1 验证PB Key是否有效

7 n! `, Y3 E& t
        在header中有一个信息就是PB key,可以算出他的hash值,现在我们就可以用OTP中的hash值和header中的做个对比,看看是否一致,验证PB key是否有效。

# n7 o# O9 z. F0 n/ Q
3.2 验证image是否有效

# l  O) ^1 v0 T
        如果PB Key有效,就可以开始验证TF-A固件,用PB key对TF-A固件代码进行ECDAS 256计算,和header中的Image signature作对比,验证固件是否被篡改(当然,如果设备为UNLOCK,即使验证失败,固件也会被启动)

. n, H& @) W5 ?1 t  A
3.3 防回滚机制
% ~* ?% J! C) k* d; n: r
        下面有防回滚机制,这里不展开说
6 ^4 B0 L8 G  p% h
5.png

; Z- d' w  j& v; w! C
% Z2 j! C2 T1 e: N) S
六、防回滚机制

$ R  A2 |/ G: x  z  D
刚才说了在OTP中会有一个version,TF-A的固件中也有一个version,他俩配合实现防回滚

$ c5 O' J% z- J" f7 h' L) w
9 }; W. v. u! ^. w1 k
其中OTP的是一个单向计数器,也就是说这玩意儿他只能++,看了一下header中的version,有32bit,也足够大,不管怎么++,也肯定够用了
0 y. O8 r5 o! ~# F* ?

4 C! F4 n3 y# o8 k1 x5 o
当OTP中的version比header里的高,那么这个固件就不会被启动,这就是触发了防回滚的机制
7 J. m- i  F0 g: ?! z$ r. d

, {3 C* _( V; r9 n/ `
如果我想退回到旧版本的固件应该怎么办?可以重新生成一个新的带签名的固件,但是header中的version写大一点,比OTP中的大,这样就可以达到目的啦

' z7 Q8 `' m3 J  g# r2 P5 V4 u4 K0 d4 v: A. Z% [! X. Y9 y
七、疑问与思考

  y3 u5 ^% d3 `' T2 |; `+ H  ?2 v

7 b$ P2 o" l$ @8 h, \) S这里我有几个疑问/ K  x* Q7 L0 B& F, W7 C' t
1:既然保存在OTP中的UNLOCK与LOCK判定相关的数据这么重要,那么在LOCK后,我们应该是无法再次改写OTP了(这不是废话吗,这么明显的漏洞ST肯定堵住了),我想知道ST是否还做了其他的保护措施,例如给芯片一些干扰,让他读取到错误数据后,是否会阴差阳错的进入到UNLOCK状态?还有我直接磨芯片是否可以实现篡改OTP数据实现攻击?(有些产品使用单片机,会把关键数据储存到片内flash,有些攻击就是直接磨芯片,飞线直接读写flash)0 X8 L8 g; \1 N6 X9 o: a% Z+ h, j5 |& n
2.LOCK与RMA之间relock最多就3次?为什么要这样设计?超过3次就永远锁死芯片?万一有一些玄学问题,需要反复LOCK与RMA之间切换该怎么办?
" V' d. \8 f; _8 H* T3.如果我header中的version不小心写成了0xFFFFFFFF,是不是这颗芯片就废了?因为OTP中的version无法再++了3 L! B! Y, I" ?3 @  {! y3 [
4.OTP中的version是在什么时候增加的?是当TF=A固件成功运行后,直接把OTP中的version加到和header中的version一致?" m; X4 c  w; Z# N, i& i
5。我如果生成新的TF-A固件,但是header中的version还是和上一个可以正常运行的固件的版本一样,那设备会怎么样呢?会正常启动吗?还是说有一些什么其他机制来做判断
* g0 ?3 [% J$ t8 m+ {5 M8 i

  J/ b! _. G+ p0 e- J; p4 r; x' Y; V( Z1 n9 i- V, R* a

9 j, }* H( a+ ?+ o' j! z
- q& \: ^  ?$ d) T
赞 收藏 评论0 发布时间:2024-11-30 19:25

举报

0个回答

所属标签

相似技术帖

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