01前言 本文档通过一个动手实验, 详细演示了如何在 STM32H563 上运行一个 OEMiROT 的功能. 旨在针对那些 OEM 想自己实现一个基于 STM32H563 上的 iROT 功能而又不知如何开始的开发者. 02准备工作 . B9 O% O# j; [# ?6 D2 V( q3 O : L; [! d0 k2 c8 L, r7 l- p 软件包 : STM32Cube_FW_H5_V1.1.0 7 Z$ J' D0 c1 s 工具:- A- T+ Y- Y) O1 M! l0 B • STM32CubeProgrammer v2.14.0 • Tera Term 串口终端显示 • Trust Package Creator(安装 STM32CubeProgrammer 时一并安装, 注意勾选)/ H' |" K: Q6 M% ?3 z , ]2 R% m6 M/ T+ h$ F' ?% S $ p9 G1 g) H @9 `4 K8 H+ r IDE: STM32CubeIDE v1.13.0 5 G ~. ~4 W5 l! Z 03烧录 OEMiROT 固件并运行! [7 d# t) w. ~ 3.1. 脚本环境配置板编程基础3 B6 J) P/ b, ` 本动手实验基于 STM32CubeH5 固件包, 此包必须位于一个没有中文且没有空格的路径下, 于是我们将此包拷贝到 C:\workspace 目录, 在此包路径 \STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\ROT_Provisioning 目录下有一个 env.bat 文件, 用文本编辑器(如记事本)打开此文件: 1 A1 a. b$ U6 Z% N5 t" F ( q. A: }% i. B4 X' e$ e& O 检查上面两行, STM32CubeProgrammer_CLI.exe, 以及 STM32TrustedPackageCreator_CLI.exe 这两个工具的安装路径是否跟你电脑中的安装路径符 合, 如果不符, 则需要进行相应的修改.+ i6 O9 v- V% w3 |6 C" R 3.2. 运行 OEMiROT 预配置(provisioning)脚本" T5 u1 q' e( [8 [( @1 e9 | 再进入到 cube 包下的目录 STM32Cube_FW_H5_V1.1.0\Projects\NUCLEOH563ZI\ROT_Provisioning\OEMiROT 目录下, 有一个名为 provisioning.bat 的脚本, 双击运行它: 9 m( s9 }3 L- b# E 如上图, 系统会自动打开一个 DOS 命令终端窗口, 在此动手实验过程中, 如无特别说明, 此窗口将一直保持, 我们将通过此窗口的提示信息进行每一步的操作.9 Z; N( E; E5 K* M3 [9 H % V" z* w/ Y: }& j. y2 t) d+ T0 p; u) d: r5 y 如上图, 信息提示我们打开TrustedPackageCreator 工具, 生成 OEMiROT_Config.obk 文件. 3.3. 生成 OEMiROT_Config.obk* Q: c) w3 `; r2 b6 i/ o; m, i 打开 TrustedPackageCreator 工具:. l3 @' e) f6 i7 k1 {- F8 ? % |: V, R+ \8 M1 [+ l3 k- }0 G ( u6 k* h" i3 R( M" h. |4 O7 H: D ! W5 H u9 k- X; ~% P# M 如上图, 在最左边 ①处点击 “H5”, 然后在②处选项”OBKey”, 接下来在③处选择STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\ROT_Provisioning\OEMiROT\Config 目录下的 OEMiRoT_Config.xml 文件, 此文件为生成 OEMiROT 对应 obk 文件的配置文档. 然后下面会显示 3 个密钥对, 从上到下分别为 :9 E- n' k; Z" M4 s, X9 ? • OEMiRoT_Authentication_S.pem: Secure APP 对应的认证密钥(使用公钥) y* Z8 z; P- m, ? • OEMiRoT_Authentication_NS.pem: Non Secure APP 对应的认证密钥(使用公钥) • OEMiRoT_Encryption.pem : Secure APP+Non Secure APP 固件加密密钥对应的解包密钥(使用私钥) & H! C" X( ?$ w% l - |6 L) b# N! ]9 M- g) w, k 这三个密钥其实都是成对的, 即公钥私钥对. 位于 Keys 目录下. STM32CubeH5 包下已经自带了默认的密钥对, 如果你不想使用默认的, 则可以点击上图中的4中的 “Regenerate” 重新生成这三个密钥对. 一旦重新生成, 则需要注意保存这三个密钥对.2 N, a- _8 v; z( S" i8 ]- T 接下来就要生成 OEMiROT 对应的 obk 文件了, 在右边的输出路径下, 选择一个路径, 比如Binary 目录. 最后点击生成. 则将在 Binary 目录下生成 OEMiRoT_Config.obk 文件.: c3 ]$ k$ d' g4 Z 3.4. 生成 DA 对应的 obk 文件: E+ P% I6 c: n& c* l3 v 回到脚本终端窗口, 输入回车键 :8 M! B1 V1 s# t1 |1 t 2 M; C u4 f) ] 如上图, 提示你通过 TPC 工具生成 DA_Config.obk 文件. 有关如何生成 DA_Config.obk 文件,之前已有其它文档讲述, 且 STM32CubeH5 包下STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\ROT_Provisioning\DA\Binary 此目录中已经有现存的 DA 对应的 obk 文件, 其对应的私钥和证书分别位于上一级目录下的 Keys 目录和 Certificates 目录下, 这些文件均可直接使用, 所以这里不再重复讲述它们的生成过程.9 m1 q3 T' g2 [$ [1 L1 z7 ` b 直接按下回车键..3 K- k% G# T" y5 x 9 i) R5 }# |" o, _6 G 3.5. 编译 OEMiROT_Boot 工程3 }. | u5 B. F 6 B( P6 c" b/ ]5 @ K* I- U2 [& m( W7 }6 U! F/ P: C v/ Z, E$ X- |! {$ R% u6 j 如上图, 提示用户打开 OEMiROT_Boot 工程并编译.; V" ~; O0 f( W) A: ~5 e 0 m6 x5 t0 z: G3 ]( L" p6 U 6 _8 Y9 ?! x7 e4 D, T) P 于是用 STM32CubeIDE 打开工程, 路径为: STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\Applications\ROT\OEMiROT_Boot\STM32CubeIDE 目录下, 编译过后,会在工程下的 Binary 目录下生成 OEMiROT_Boot.bin 文件.: y/ l3 J1 c% y7 |1 c$ \ # ~0 }9 V( b/ l: u ; o* f6 v" e* G6 W% g 再回到终端窗口按下回车键… 4 R i+ [" k0 _0 w, R5 ?5 w% U 3.6. 编译 OEMiROT_Appli_TrustZone 工程8 C( ^9 h. X: Q! B+ p% e + ]4 l- l3 [$ U 用 STM32CubeIDE 打开工程: STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\Applications\ROT\OEMiROT_Appli_TrustZone\STM32CubeIDE" |1 J% w6 Q9 U; H, [ 6 J6 F a0 q( i4 j7 |2 X 此工程下有两个子工程 : * k0 D/ _! }. l4 q( c* n |: I' { 9 Q0 m9 m& f# f3 e- C) K% v6 G ( \0 t4 g0 k* G, Y) K 如上图所示, 先编译 Secure 工程, 再编译 NonSecure 工程. 编译通过后, postbuild 脚本会在Binary 目录下生成原始 bin 文件和加密后的固件. 9 i: g+ T$ y# I: C2 B4 h$ @ ! y# w0 ~1 C$ @: t j 原始 bin 文件是用来初始安装的, 而加密后的固件是用来做升级的. 加密和签名过程正是postbuild 脚本来实现的, 其对应的固件加密密钥是此次编译过程中脚本随机产生的密钥. 此密钥会通过 3.3 节中所产生的 OEMiRoT_Encryption.pem 对应的公钥来进行打包并放入 header 中.而签名所用的私钥并正是 3.3 节中所产生的 OEMiRoT_Authentication_S.pem 私钥, 它对应Secure 工程签名, OEMiRoT_Authentication_NS.pem 则对应 Non Secure 工程签名.4 C K3 C9 d) H2 {( u 3.7. 手动生成加密且签名的映像文件(可选)6 k: _( \/ k8 T, t, v 除了通过 postbuild 脚本来自动生成固件加密且签名的映像文件外, 你也可以通过手动的方式来生成它.如下图, 我们可通过 TPC 手动将原始 bin 文件加密且签名. # X# v' O" o7 h& b* @1 Z/ v. ^ / Y5 @/ D4 T! v2 Y: { 1 s0 e9 a0 P4 ~+ O' G9 U) N 如上图, 打开 TPC, 左边①处选择 “H5”, 然后在②处选择”Image Gen”, 在③处输入配置文件 : STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\ROT_Provisioning\OEMiROT\Images\ OEMiROT_S_Code_Image.xml. 然后在Firmware area size 处保持默认的 0x6000, version :1.0.0, Firmware binary input file 处导入S App 生成的明文固件映像. Image Out File 处即可生成的加密且签名的固件。加密的密钥是随机的, 它通过打包进 header 中, 如之前描述. 这就是手动生成加密且签名的固件映像方法. 由于App 工程的 postbuild 脚本会自动完成, 所以, 这一步骤并不是必须的.7 n$ j7 ^' X3 \9 K 2 L( w$ G b7 q9 Y+ b 0 v+ }$ r/ F0 j# {) e- N 此外需要注意地是, 在 STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\ROT_Provisioning\OEMiROT\Images 目录下还有其它几个用来手动生成加密签名映像的配置文件, 如下图所示 : ; `8 j$ R3 l1 y, h* \! q" N) Q$ o . C7 z9 o" g. o. }9 I2 e) H 通过这几个文件名, 顾名思义, 分别对应着 Secure App 的固件, 数据, NonSecure App 的固件,数据映像, 如果需要手动生成这四种加密且签名的映像文件, 则通过 TPC 手动导入对应的 xml配置文件. 在 Firmware binary input file 输入原始 bin 文件, 在 Image Out File 处输入导出文件, 然后点击 Generate Image, 生成最终的加密且签名的映像文件(如rot_tz_s_app_enc_sign.hex, 或者 rot_tz_ns_app_enc_sign.hex)., K: X. N0 }0 O; y' B 2 `: q) ]3 ?( m! X4 ~ 3.8. 生成加密签名的数据映像(可选) 回到终端窗口按下回车键, 如下所示 : 3 ~4 q c: u2 |! \" ?+ R 9 H5 B8 m& Q: K T4 C" ~ - W- }& C) f: Y 提示我们通过 TPC 手动生成加密数据映像. 工程中默认是未定义任何 Data image 的(flash_layout.h 头文件):) g2 p2 ]* N: I8 q 4 A# |! `- b* a+ F" I( Y+ A; P: U 因此, 此步骤默认我们是可以跳过. 如果工程中此宏修改成 1, 则需要手动通过 TPC 来生成加密的数据映像. 方法类似于 3.6 节的手动生成环节, 只不过配置文件换成 xxx_Data_Image.xml. - a. N2 ?/ D t3 R! j - q0 b9 H- `! r% i) t$ e 这一步骤, 我们直接在终端窗口中按下回车键… % @6 U" |: g! }. v! l * f4 N0 N2 g% d/ C4 B/ z* J M, o 接下来再次提示生成 NS APP 对应的 Data Image, 同理, 在工程中默认宏中是没有配置的, 因此直接按下回车键… / e( j/ u! H8 |0 G3 U! n6 m# N& n 3.9. 预配置(provisioning)( u5 E: k4 o, X) P; Q, _ % j% e+ ~+ N/ G$ U# j$ ]: C* i * r7 q) M h* n I" i+ P 9 B% P3 o F9 R) G* s7 o 在做预配置之前, 提示你是否已将 BOOT0 引脚拉低. 确认 NUCLEO-H563ZI 板上的 BOOT0引脚没有连到 VDD(CN4 的 BOT0 引脚未接任何东西即可). 确认后按下回车键… 5 A: h, d" A# R( j! N 如上图, 这此过程中, 脚本会自动烧录 boot, S APP, NS APP 三个 bin 文件, 以及配置 option bytes, 接下来提示你输入芯片最终的 product state, 这里我们输入”CLOSED”…(千万别设置为 LOCKED 状态!)' F0 m3 ^. r. b, b& n2 f( @( b 1 A8 V6 C* \( ]0 X9 _6 e ; G9 H) I9 |' P- p4 p 如上图所示, 在此过程中, 脚本会先将芯片的 product state 切换到 provisioning 状态, 然后再做预配置, 这里会预配置 OEMiROT 的 obk 文件,以及 DA 的 obk 文件, 然后最终将芯片的product state 设置为你上一步输入的最终芯片状态. 最后系统提供已完成. 到这一步, 脚本的整个流程结束. 接下来, 我们验证下烧录后的芯片是否工作正常.7 \- t$ W* ?! Z3 A. Y& \0 H& P) x 3.10.检查程序运行状态; U* J# m* h+ C1 o, ~9 h5 A, s. x) r 打开 Tera Term, 设置串口波特率为 115200 bps, 然后复位板子, 查看打印信息… ! a: w! q; E$ B k: x6 O 如上图所示, 当打印信息显示 User App #A 时, 表示 NS APP 已经运行成功, 所有程序运行结果均正常! , v6 X8 H3 K; h R9 ^. v 04固件更新. X* H# e" P O9 V+ l4 U( M 接下来, 我们将演示通过 NS APP 触发程序跳转到内置的 bootloader 中, 并通过串口下载新的加密固件, 复位后并安装它.- S7 n+ J& U# ?1 F / x" e8 q9 v4 r- h 4.1. 修改代码, 并重新编译工程3 {0 {' C2 }& A o 打开 NS APP 的工程, 在 main.c 文件中将 NS APP 的版本号从 “A”改成”B”:6 R% I- t2 |6 R% I1 v # x8 b/ G6 ]" V2 E7 ]5 b- w2 l ' `# {& r) T3 S2 u# D5 }* { 7 p) |1 J, @" b) C5 S 然后重新编译 NS APP 工程. 8 q; l4 B; f/ [- {% t7 X3 z8 T 0 n l6 V2 A. X3 D Postbuild 脚本将重新生成 S APP 和 NS APP 的加密固件 :) A; b. D3 S9 }0 ~+ C5 }, N ( n( v; p- k: |, |, z6 o# O 2 i% s$ W5 F7 b! q2 j 如上图所示, 这四个文件均将重新生成.' w9 f* s& y- S5 G, y & K; y% P! o0 Q ' y8 A$ ], p$ W! k2 b! h K" B. t# ^ 接下来我们将升级 APP 固件.8 e1 D8 ~/ x0 N7 N+ V7 b! t5 i $ ?) M" u5 r* O6 B, O$ d8 W 4 |/ q2 w% {/ d% q 4.2. 跳转到 loader 程序6 X8 G( X: N5 }7 y6 [( t2 S $ H5 B" |9 I/ o+ y. ~7 y8 A6 q4 \ 在串口终端中我们输入”1”:& c5 s5 l% d. e; G, d4 [7 m 8 P& I, e$ ]5 u, w5 I0 `% w6 N 如上图所示, 输入 1 后, 程序跳转到芯片内置的 bootloader 中.1 m) S; K" n/ G( g7 V 断开 Tera Term 的串口连接 :4 S3 v2 A7 p8 T/ v( u$ W" ^ 6 n' _+ ~. L* Q 4.3. 通过 STM32CubeProgrammer 下载新固件( {+ [9 r4 N' G) Y 打开 STM32CubeProgrammer, 并通过串口模式连接芯片: 3 _7 @6 X$ F) y* @9 `" r - ^8 f5 a; s9 W# l6 P' p' { % M6 S9 t% i2 h# m/ W& A 将新生成 NS APP 的加密后的固件 rot_tz_ns_app_enc_sign.hex 拖入到STM32CubeProgrammer 中 : . N$ K- q( j& m4 Y ! T+ |0 ?; Y3 l' x0 L 7 a3 |9 I6 t# K7 K9 L+ y 如上图点击下载. 4 _) p/ C# z5 u% T# ` 同样的, 也可以将 S APP 的加密固件 rot_tz_s_app_enc_sign.hex 拖入STM32CubeProgrammer 中并下载 : 下载成功后, 断开 STM32CubeProgrammer 的串口连接, 并使 Tera Term 重新连接串口 , 然后再重启 NUCLEO-H563ZI 板, 于是可以看到如下打印信息 : $ }9 I, e' M+ Y0 g1 s* Q 6 E" ~: D# S% Q% x* o ) A4 B2 q7 W& U4 [ 如上图所示, NS APP 的版本打印信息从 “A”已经改成”B”了, 这说明固件(加密且签名的)已经更新成功.' e3 M4 {6 Z$ o, V! P! ? 05还原 5.1. DA 回退# s4 A+ C g) J( _& n/ ~7 I 打开 STM32CubeProgrammer, 采用 ST-Link 模式, 在未连接的情况下,在左边选择盾牌图标, 然后再选择”DA”选项卡, 再点 Discover 按键…. 界面变成如下所示 : " L5 k9 n2 a5 P, x4 A2 d 如上图所示, 第一个红框内输入 DA 私钥文件 : 5 R/ r q; H2 @3 N, P6 q& P STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\ROT_Provisioning\DA\Keys\key_1_root.pem, 6 G; z; s) G' [) o 第二个红模式内输入证书 : STM32Cube_FW_H5_V1.1.0\Projects\NUCLEO-H563ZI\ROT_Provisioning\DA\Certificates\ cert_root.b64 然后击点 continue 按键, 然后界面变成如下所示 :8 A2 {- F8 `. U5 |9 h . v% d. M2 m. P' I& @' M5 G 8 E6 s( N! F5 n$ n# Z; y5 U / D/ a1 }2 k0 H6 {7 a- O5 j6 a 如上图所示, 在左边选择”Full Regression”, 然后再点击 Execute 按键… ; K0 k$ e7 o" V 然后如上图所示, DA 回退成功. 此时,查看 option bytes 值 , product state 已经变成Open(0xED), TZEN 依然使能(TZEN=0xB4) : o% J) L% S# W/ F K4 g u ) I/ W9 [- l+ @# k 5 b" Y0 t7 a+ u# c; u5 e7 i; W5 e : x* @, T; ^0 w" a 5.2. 关闭 trustzone 如果需要也可以将 TZEN 关闭(TZEN=0xC3, 可直接修改, 这点与U5必须伴随 RDP回退操作不同), 这样芯片就完成恢复成原始状态了. 6 I: [* j! {4 S: [6 q/ l 6 q9 _3 w2 v- Z 转载自: STM32单片机 如有侵权请联系删除 2 T! s; G5 t$ E( C2 b |
值得收藏