工程师笔记|STM32U5带OEM Key保护的RDP降级 引言 通常芯片在其整个生命周期中跟随产品的开发生产可能经历如下几个不同阶段 :2 M1 n/ Q4 M8 {& k6 a% @% pSTM32MCU 的硬件中能够用来进行芯片生命周期管理的最常见的特性就是 RDP(ReadOut Protection)读保护功能。通常 RDP 具有三个级别: 5 h* p7 L3 k6 q4 F9 U • Level0:完全开放,这是芯片出厂的缺省状态 ; I, y0 G# Y* S% O! R • Level1:调试端口可以连接,但无法通过调试端口访问内部 Flash,部分 SRAM 以及其它一些资源,OptionByte 可以修改。Level1 可以降级回 Level0,但会伴随全片擦除。 1 [! T) ^; ?6 O+ W6 U7 u • Level2:调试端口永久关闭,进入这种状态后调试端口完全无法访问,且这种状态无法逆转。 + ?9 |% ], _' y- e8 Y 在 RDP Level1 调试端口依旧可以连接,虽然不能直接读取内部 Flash 的代码和数据,但是可以看到大部分 SRAM 的内容,并且 RDP Level1 允许随意回退到 Level0,并伴随全片擦除。因而从安全角度讲 Level1 这个级别的安全性不够高,因而通常对于调试端口保护我们会推荐使用 RDP Level2,但是 OEM 可能往往不会选择使用这个级别,原因有多方面,其中一部分的顾虑可能来自两方面,一个是 Level2 级别下 OptionByte 无法进行修改,另一个是设置到 Level2级别会影响芯片失效分析。 STM32L5 在 RDP 功能上带来一些改变,首先针对 TrustZone 架构,增加了 Level0.5, a- r% V) B$ V7 x • Level0.5:调试端口可以连接,但是安全测的所有调试功能都被禁止,非安全测的调 试功能依旧可以使用,因此在 RDP Level0.5 可以访问被定义为 NonSecure 的部分资 源,包括片上 Flash,SRAM,部分 CPU 寄存器以及系统外设等 2 ?# v6 J% c' X! N- M * [5 G1 l5 L/ M 另外,STM32L5 的 RDP Level2 不影响 FA,但 OEM 依旧无法在这种状态下进行 RDP 降级或者 OptionByte 修改,依旧有一些局限性。 STM32U5 芯片生命周期管理新特性 STM32U5 在芯片生命周期管理方面在 STM32L5 的基础做了进一步的改进,引入了OEM Key 机制,使得 RDP 的级别状态转换能够通过 OEM 设置的 password 进行保护,一方面能够防止 RDP 任意降级,避免设备被远程攻击注入恶意代码后通过 RDP 降级变砖的风险,另一方面也使得 RDP2 降级成为可能,给产品后期维护带来更多的灵活性。# K. }" a; _" i' n7 \ $ f2 S3 k9 C* q# r) w: T 2.1. STM32U5 RDP 读保护级别状态转换 2.1.1. TrustZone 未使能 TZEN=0 1 p. o8 K2 P# i2 @0 L; u0 ^ 9 D ^$ D+ M m/ u2 Y 芯片出厂缺省状态 TrustZone 没有使能,这时候和往常一样 RDP 依旧具有 3 个级别,如图 1 所示:. [! L- h/ ~! k! e# p Figure 1 STM32U5 TZEN=0 时 RDP 级别及其状态转换 2.1.2. TrustZone 未使能 TZEN=1 当选项字节中的 TZEN 被设置为 1,系统的 TrustZone 功能被使能,此时 RDP 将具有4 个级别,如图 2 所示: Figure 2 STM32U5 TZEN=0 时 RDP 级别及其状态转换 STM32U5 OEM Key 机制 3.1. OEM1Key 与 OEM2Key# ~; K9 L- } }. \! J8 |客户可以自己定义并分别烧写两组 OEM Key,每组 Key 都有 64bit,有效的 Key 值必须是非全 0 或非全 1 的值。* {$ l" e/ P6 D3 F8 z& Y • OEM1Key: ! h$ ^9 f4 J: ` ? g% U1 ? o 用于控制 RDP Level1 到 Level0 的降级- o+ |% V% U, \( _+ Q. [7 J o 一旦写入 OEM1Key,则 OEM1 处于 LOCK 状态,必须首先使用 OEM1Key解锁后才能够进行 RDP 降级。0 ?' F i7 g Y1 V* Q* t% E M o 解锁的过程需要将 OEM1Key 的 64bit 值的两个 32bit 分两次通过 JTAG 或者SWD 端口写入 DBGMCU_DBG_AUTH_HOST 寄存器。 o 如果 OEM1Key 未设置,则 RDP Level1 到 Level0 的降级没有限制9 \: N5 y6 l; }4 K3 @ 2 G. y7 t+ }9 X • OEM2Key: $ K6 J. D& h7 E7 Y& M' k/ F 6 J& g' l! d7 G$ \6 p4 W& L# i o 用于使能并保护 RDP Level2 到 RDP Level1 的降级。只有写入有效的OEM2Key 之后,才有可能进行 RDP Level2 到 RDP Level1,且类似的,降级时必须首先使用 OEM2Key 解锁。 ! F1 N& |) d$ j3 R: n2 }0 P7 b o 在 TZEN=1 情况下 OEM2Key 同时保护 RDP Level1 到 RDP0.5 的降级9 \* c, B$ R% [3 R% u. B o 如果芯片从未写入有效的 OEM2Key,那么 RDP Level2 的效果与旧系列的STM32 的行为一致,无法 FA,无法撤销。 如果芯片设置了 OEM2Key 和 RDP Level2 需要做 FA,则客户需要首先将芯片进行RDP2 解锁降级之后再送交 FA。 3.2. OEM1Key 与 OEM2Key 的设置修改条件 ! ~: r& M) d+ |5 W. s0 U2 [ $ j8 A4 A; ^/ R1 ]( U0 z, N7 z OEM1Key 和 OEM2Key 的设置和修改是有条件的,并非在芯片的所有状态下都允许OEMKey 的设置,表 1 总结了哪些情况下允许对 OEM1Key 和 OEM2Key 进行修改。+ {+ B- K8 c/ p7 P6 z 如何使用 STM32U5 的 OEM Key 功能 " G, P* K) {; J% v7 F: z. C' m4 @- y- Z k3 P9 s3 ?& ?6 @! Q 4.1. 检查 OEMxKey 是否已经设置 $ Q4 o6 h. A' i8 Y - s4 p5 W8 E2 I* g7 H. N5 F. f: o7 ` 由于 OEM Key 并非在任意情况下都允许修改,而且 OEM Key 一旦设置无法撤销,并且会影响 RDP 降级,因而强烈建议在设置 RDP 到非 0 级别之前,首先检查 OEM Key 在所使用的开发板、芯片上是否已经设置。 如果 OEM Key 曾经被设置过,如果不能确认之前设置的 KEY 的值,那么我们建议在RDP 为 Level0 的时候,对 OEM Key 进行重新配置,这样可以保证新设置的 KEY 是自己确认知道的值。 % T( g2 x4 p/ b9 ^* \ & `/ O u. h5 E9 q 如果该芯片尚未设置过 OEM Key,那么可以根据需要选择是否要进行 KEY 的设置。 9 y0 _" A6 T7 s ( m& R. |) r# s [+ Z$ U 检查 OEM Key 是否已经设置过,可以通过查看 FLASH 的 NSSR 寄存器来实现,即可以通过软件代码读取,也可以通过 STM32CubeProgrammer 读取。使用STM32CubeProgrammer 来读取 NSSR 的方法更加简单直接。步骤如图 3 所示 . _( D) F8 G* o+ n • 打开 STM32CubeProgrammer(建议版本 v2.8.0 及以上) • 点击 Connect 连接芯片 2 v7 Q2 J, c+ l4 q1 x: Q$ V • 根据使用的具体芯片在 REG 页面中选择 Device • 在 Search 框中填入 FLASH 并回车,这时候将看到 FLASH 寄存器的内容 - t0 _9 \( x4 H7 S# _- n; J1 }3 J4 e • 点击 FLASH_NSSR 左边小三角,展开 NSSR 寄存器内容 ; Y% L) `$ s: v& e5 g& j# j • 查看 OEM1LOCK,OEM2LOCK bit 的值 : m' Q7 t4 C! `' O/ i& R / L7 X$ U4 ?8 y: K. ]5 E o 1:表示该 KEY 已经设置,在图 3 的例子中 OEM1Key 已经设置5 V5 C' ^3 l+ K# P o 0:表示该 KEY 从未被设置过,在图 3 的例子中 OEM2Key 未设置 Figure 3 通过 STM32CubProgrammer 查看 OEM1/OEM2 Key 设置情况示例 8 H) E3 `3 A5 ]% A# b+ H1 G2 d4.2. 设置 OEM1Key 和 OEM2Key * W# P+ y+ L6 l; U2 |' h1 J & O- v Q/ ]% `! M. ] OEMxKey 的设置是通过操作 Flash 选项字节对应的 OEM Key 寄存器实现的 , j" `4 B$ X: H • OEM1Key:FLASH OEM1 key register 1 & FLASH OEM1 key register 2 • OEM2Key:FLASH OEM2 key register 1 & FLASH OEM2 key register 2这个操作可以通过两种方式实现,一种方法是使用 STM32CubeProgrammer CLI 命令完成,另一种方法是通过软件代码实现。 . e. ]3 k4 Z' b: f* a7 M9 o + L' L3 Z6 G' p2 h, M& x$ d! M3 P7 v: D 注意: 1. OEMxKey 不能设置为全 0 或者全 1 的值 2. OEMx2Key 一旦成功写入,无法通过读取相应的 OptionByte 获取,且在不可修改的RDP Level 将无法重新设置,所以写入的 OEM Key 要确认 Key 保存好并记牢 3. 如果没有成功设置 OEM2Key,则 RDP Level2 无法回退,无法进行 FA 3 j9 B% \( f' |) b' t 4. 如果客户设置了 RDP Level2 并需要对芯片做 FA,则需要客户首先使用 OEM2Key 将芯片解锁并进行 RDP Level2 降级到 RDP level1,否则无法进行失效分析 6 q& z2 v6 h( ?/ _ 5. STM32CubeProgrammer 的版本建议 v2.8.0 或以上 6. STLink FW 需要更新到 V3J8M3 或以上版本,如图 4 所示* Y- {0 r! B" H9 U1 W+ } Figure 4 STLINK FW 版本 4.2.1. 使用 STM32CubeProgrammer CLI * V+ ]+ y5 ?8 ?0 K" |% J- v+ J9 _ 8 D+ u4 Q- g4 N, y 命令设置 OEMxKey $ O# d5 Y) H, Z4 |" l$ F6 X+ S 5 c1 ^- e" K. J 通过STM32CubeProgrammerCLI 命令设置 OEM1/2Key 的示例 : G. \5 `0 I( ^ 以下是通过软件代码设置 OEM1/2Key 的示例,这个例子中我们在 RDP 为 Level0 的条件下设置 OEMxKey。实际使用中代码可以根据实际需求结合 Error! Reference source not found.的内容决定在哪种 RDP 级别下允许修改 OEMxKey。4 T' P6 d, l7 d$ x9 @ 4.3. 使用 OEM Key 解锁并进行 RDP 降级 当 OEM1/2 Key 成功设置之后,对应的 RDP 降级需要配合 OEM1/2 Key 的解锁之后才能够完成。 9 s- Y. Q. H4 B" D2 [& p 注意: 8 J' K0 h5 X' l0 l3 _* ]; W 7 A5 l. O: i. U, c; { (TZEN=0)RDP1 解锁降级到 RDP0 & N/ m% t9 X. _% S+ r' \ 通过 STM32CubeProgrammerCLI 命令使用 OEM1Key 解锁后做 RDP 降级的示例 * o( e0 a1 s9 W; q; g • 方法一:分两步,先 OEM1Key 解锁,后 RDP 降级 |6 g, C& K. v • 方法二:一条命令同时解锁和降级" t/ t* C1 V% Q7 l/ U8 e8 l: U5 v2 u ! W: c; g" y2 d # p6 b3 q! D% @; y# S (TZEN=0)RDP2 解锁降级到 RDP1 ) ^# h- D/ u& C/ u ; h( _( | i: S \+ E$ b0 t2 \& Y 通过 STM32CubeProgrammerCLI 命令使用 OEM2Key 解锁后做 RDP 降级的示例 0 }, y- [6 o) x9 V , {% P& {! N. U) N • OEM2Key 解锁后,硬件将自动把 RDP 降级为 Level1,RDP 的值为 0xFF,不需要额外的命令进行降级( l& o$ a1 r/ S) a* D" M (TZEN=1)RDP1 解锁降级到 RDP06 h% h$ v2 F! M B( u. X& ] 通过 STM32CubeProgrammerCLI 命令使用 OEM1/2Key 解锁后做 RDP 降级的示例(首先需要确认系统能够正常运行到 NonSecure 状态)" p h4 J' b6 W& ?/ N 1 L& ]% m1 X( `3 H" r • 如果仅仅做 RDP Level1 到 Level0 降级,TZEN 保持为 1,这种情况与 TZEN=0 时类似,可以直接使用如下命令完成解锁和降级 4.3.4. TrustZone 使能 (TZEN=1)RDP1 解锁降级到 RDP0.5 通过 STM32CubeProgrammerCLI 命令使用 OEM1/2Key 解锁后做 RDP 降级的示例; Z% J/ M; X7 ]" K6 K 注意: ! U! G) G6 X* s7 q7 u5 z* } 4.3.5. TrustZone 使能% O6 f6 u' `! p4 S' O (TZEN=1)RDP2 解锁降级到 RDP1) U* T( F3 }6 M1 {, Q RDP Level2 解锁降级到 RDP Level1,与 TZEN=0 情况下相同0 C: A; r5 [" f Y4 k7 f; i* V 使用特殊 CHIPID 通常从安全角度考虑,我们会倾向使用一机一密,也就是说比较好的方式是每颗芯片烧写不同的 OEMxKey,但是这样做一方面对 OEMxKey 的管理是一个挑战,另一方面,在 RDP Level2 的时候,由于调试连接已经无法读取任何片上资源,也很难通过通常的芯片 96bit UID 来确定当前的芯片应该对应哪一组 OEM Key。 & L1 T, T1 p% z& T3 B* R: U/ ~4 n' \# n! M: Y: C; B" j, ~# D6 K 针对这个问题,STM32U5 在原有 96bit UID 的基础上,增加了一个 32bit 的特殊CHIPID,这个 CHIPID 存在于硬件的 DBG 单元中,而且即使在 RDP Level2,这个CHIPID 也可以由调试器通过 JTAG/SWD 端口获取。因而 OEM 可以利用这个特殊CHIPID 来简化一机一密的 OEMxKey 烧录过程,同时也可以在需要使用 OEMxKey 解锁的时候轻松读出 CHIPID,然后找到对应的 OEMxKey 进行解锁。 K. `' M! E9 R 32bit CHIPID 可以通过调试端口工具读取,也可以通过代码读取,CHIPID 的地址为0xE0044104。 注意: n) l- L5 P8 k+ f 特殊 CHIPID 可以通过软件代码直接读地址 0xE0044104 获得,也可以通过STM32CubeProgrammerCLI 命令来读取,命令如下:$ s7 K8 o- j3 C3 @2 y % i# ~, ~; Z( y ?. C 运行该命令在 RDP Level1 时将看到类似如下信息,蓝色高亮的部分即为获取的 CHIPID% e J s8 M2 c. x 小结 STM32U5 提供了更灵活的芯片生命周期管理机制,在 STM32L5 的基础上增加了 OEM Key 特性,一方面能够保护 RDP 级别的状态转换,防止任意的回退;另一方面也减 少了 RDP Level2 使用中的局限性和顾虑点,同时还增加了 32bit 特殊 CHIPID,能够方便 地实现在不同芯片上配置不同 OEMxKey 的需求。+ ^( ?. [. R) i |
这个芯片保护很强,很方便啊 |
STM32U5 系列使用 LPBAM 进行功耗优化
【STM32U545】实现CAN数据收发
【我的STM32U5 项目秀】+04-MPU6050在STM32U5上的移植
实战经验 | 基于 STM32U5 创建 USBx_CustomHID 通信
STM32U5 x E-BIKE,记录你的骑行多巴胺
基于STM32U5系列TIMER+DMA+DAC应用经验分享
实战经验 | 基于 STM32U5 片内温度传感器正确测算温度
【文末有礼】新款STM32U5:让便携产品拥有惊艳图效
STM32的CAN FD位定时设置注意事项
【STM32U599】5.聊聊手表菜单