【Semidriver E3】BPT & 安全启动 & Secure Dubug

1. 概述

(1)Boot Package 格式

 Boot Package 中包含用户程序, 由以下两部分组成:

①  BPT(Boot Package Table)

• 位于 Boot Package 最前端,包括 Boot Package 的签名信息,各个镜像在 Image 组合中的相对位置,镜像 load 地址,entry 地址,hash 校验信息,PSN 信息;

• ROM 读取上述信息对各个 core 镜像进行验证后启动;
 
• BPT 占用 4096 个 Byte(0x1000)



② 程序镜像组合

• 包含多个 core 的用户程序镜像组合,即 SF core 程序镜像、SP core 程序镜像、SX core 程序镜像、SF core Bootloader 程序镜像,以及 SCB 系统控制块 (System Configuration Block) 的组合;



• 启动设备中的存储方式

在启动设备中,最多允许存在 3 个 Boot Package:Normal Boot Package,Backup Boot Package,Third Try Boot Package,互为冗余。上电后 ROM 选择 PSN(Package Serial Number) 较大并且能够校验通过的 package 启动。注意,并不是所有的启动设备都支持 3 个 Boot Package,具体情况见下表:

启动设备Normal Boot Package
存储地址
Backup Boot Package
存储地址
Third Try Boot Package
存储地址
NOR/Hyper Fla
sh
由SFS指定由SFS指定由SFS指定
eMMCBOOT1分区 offset=0BOOT2分区 offset=0User Areas分区 offset=20kB
SD cardoffset=20kB--
USB/UART无存储--

 

(2)安全启动

上电后固化在芯片中的 ROM 程序会根据 boot pin 的设置从 XSPI/eMMC/SD/UART/USB 等介质中获取下级启动镜像。启动镜像的格式必须满足前述 Boot Package 格式。
ROM 程序验证 BPT 以及每个 core 镜像的流程如下:

①. 计算 BPT 中公钥的 hash(SHA256)并与 ROTPK1 中保存的 hash 对比,如果两者不一致,则启动失败

②. 使用 BPT 中的公钥验证 BPT 中的签名,如果签名验证失败,则启动失败

③. 计算每个 core 镜像 hash,与保存在 BPT 中的 hash 对比,如果不一致则启动失败

④. 上述都成功,则启动 BPT 中所指定的core镜像 

(3)BootROM 控制⽅式

       使⽤ Semidrive 提供的⼯具(atb_signer)对 image 进⾏签名时,设置 
Debug 控制字并填写芯⽚ DeviceID(DID)。当 BootROM 启动成功时,依据控制字打开 Debug。 

(4)Flsah layout



       上图为 HyperFlash 和 NorFlash 的典型的 Flash storage layout,其中 HyperFlash 的 sector size(sector 指 Flash 最小擦除单位)为 256kByte(典型值),NorFlash 的 sector size 为 4kByte(典型值)。为使擦写方便,对 flash 空间时做如下分配:

  • 将 SFS 存放在第 1 个 Sector 的起始地址 0x0 至 0x7F 中占用 128Byte;
  • 将 RFD 存储在第 1 个 Sector,其具体的起始地址为 0xF0-0x1FF,占用 272个Byte,RFD 是用于加密启动的信息,可以查看芯驰的资料或者后续博文;
  • 将第 2 个 Sector 预留为 XSPI training 数据区域;
  • 以第 3 个 sector 为起始,存放 Primary GPT 分区表预留区域(非必须,仅预留,提示GPT 分区表并非必须,如果不使用分区表,该区域可以不预留。),GPT 分区表 Primary 部分占用 17KB 空间,在 HyperFlash 上占用 1 个 sector,在 NorFlash 上占用 5 个 sector 存储。此外,根据 GPT 分区表的格式,也需要在 Flash 尾部需预留空间 17KB 存储 Secondary 分区表。
  • Normal Boot Package、Backup Boot Package、Third Try Boot Package 由 SFS (打包可以指定用户程序地址)中的地址指定,如果按照上图中预留分区表的 Layout 则中 3 个 Boot Package 的存储地址为:
HyperFlash存储地址NorFlash存储地址NorFlash
Normal Boot Package0xC0000(SFS指定)0x7000(SFS指定)
Backup Boot Package0x4C0000(SFS指定)0x407000(SFS指定)
Third Try Boot Package0x8C0000(SFS指定)0x807000(SFS指定)

 

2. 环境准备
需准备如下软硬件:

• Lauterbach Trace32 调试器 for arm

• E3 参考板(其上的 E3 芯⽚位于开发模式)。

• 芯驰 SDToolBox,各个⼯具的使⽤⼿册集成在⼯具包中,双击⼯具包中的 Help 图标可以查看相关应⽤的使⽤说明,fuse 相关操作在⼿册第七章:SDFuseTool 使⽤说明。

• atb_signer:safety/securityimage 签名⼯具。

签名命令(注意 未签名的 bin 文件命名和拷贝到相同路径下,以及用户私钥的路径,此签名未涉及到 uuid & ctl ,详细看下文介绍
sign_tool_e3\atb_signer_win\atb_signer.exe sign --v 2 --sec_ver 0x1234 --dgst sha256 --rcp key=sign_tool_e3\atb_signer\keys\TestRSA2048_ossl.pem --iib core=0 type=0x0 image=E3_ref_gateway_E3430.bin to=0x006A0000  entry=0x006A0000 --psn 0x04 --of E3_ref_gateway_E3430.signed

key=sign_tool_e3\atb_signer\keys\TestRSA2048_ossl.pem

• ⼀个⽤⼾私钥(例如⼀个 rsa2048 的私钥,可使⽤ Openssl ⽣成)。




• ⼀个 8 字节的数做为芯⽚的 DID (在签名⼯具中叫 UUID,在芯⽚ fuse 中叫 DID) : 0x12345678abcdef88 (由客⼾⾃⾏烧写)



• ⼀个 8 字节的数做为芯⽚的 UID : 0x12345678abcdef88 (芯⽚出⼚应该已经烧写完成,这里这是举个例子)


 
• ⼀个 8 字节的数做为芯⽚的 debugkey : 0x746573746b657930 (ascii:’testkey0’) (由客⼾⾃⾏烧写)




3. 安全启动

完成以上的准备条件后,启用这一步骤,实现 BootROM 对 image 进行验签,也就是 BootROM 安全启动。

(1) 烧写 eFuse ,使能 PROD



(2) 对 image 进行打包(详细看 https://www.wpgdadatong.com.cn/blog/detail/72667)

打包用户的 image 可以通过以上博文的链接进行替换 gpio 的例程进行打包,也可以使用之前的打包的 PAC 作为 USB 下载的底包,在下载时替换 boot0~boot2 为用户签过名的 bin 文件即可。

例如下图:将用户签过名的 bin 替换下载底包的 boot0~boot1 即可(这里打包只设置了两个 boot)



4. Secure Dubug

原理:
Debugger 发出请求--->芯⽚回复出 UID--->⽤⼾根据 UID 找到对应的 key 并将 key ⽤ Debugger 回复给芯
⽚--->芯⽚匹配 key 成功后开启 debug 接⼝。

(1)第一种情况,只使能 efuse PROD

经过上述步骤芯⽚已⽆法连接调试器,以 E3_ref_gateway_E3640、⾮ xip 为例,下⾯构建包含 DID 和Debug 控制码的 image 来使 ROM 开启 Debug 接⼝ 。

① 直接打包用户程序到 USB 下载底包

此时需要调试,在打包时需要加入 uuid & ctl (efuse 烧写了 DID 需要在打包加入 uuid, 保持一致);



② 签名用户 bin 文件替换 USB 底包 boot0~boot2

修改签名工具所用的命令(添加 uuid & ctl ctl=ffffffffffffffff uuid=7856341288efcdab):

sign_tool_e3\atb_signer_win\atb_signer.exe sign --v 2 --sec_ver 0x1234 --dgst sha256 --rcp key=sign_tool_e3\atb_signer\keys\TestRSA2048_ossl.pem --iib core=0 type=0x0 image=E3_ref_gateway_E3430.bin to=0x006A0000  entry=0x006A0000 ctl=ffffffffffffffff uuid=7856341288efcdab --psn 0x04 --of E3_ref_gateway_E3430.signed



③ 根据以上步骤可以实现调试功能

(2)第二种情况,在第一种基础的基础上,efuse 使能 SDBG_MODE

使能 SDBG_MODE 后,劳德巴赫无法直接 attach 上去,需要更改 secure debug attach 脚本,
在此之前确认好,secure debug 秘钥已经烧录在 efuse 上,签名也按照上面操作步骤实现了,接下来需要用以下脚本实现 attach:

; ------------------------------------------------------------------------------
; @Title: Example for manual JTAG access, Debugger in DOWN Mode
; @Description:
;This script reads out the IDCODE of an ARM7 core when the debugger is in
;DOWN mode.
;Detailed knowledge about JTAG is required to use manual JTAG control signals!
;Tested on an ARM7 target board.
; @Keywords: idcode
; @Author: PEG
; @Props: Template
; @Copyright: (C) 1989-2014 Lauterbach GmbH, licensed for use with TRACE32(R) on
; ------------------------------------------------------------------------------
; $Id: example1.cmm 6982 2023-02-22 11:10:17Z kjmal $
; @Copyright: Semidrive semiconductor
; @Title: Semidrive Secure Debug (Challenge & Response) logic.
; The debugger is in DOWN mode, the JTAG driver is tristated.
area
SYStem.CPU CortexR5
SYStem.CONFIG.apbaccessport 0
SYStem.CONFIG.apbap1.base 0x2000
SYStem.CONFIG.debugaccessport 0
SYStem.CONFIG.debugap1.base 0x2000
SYStem.CONFIG.COREDEBUG.Base 0xF2081000
;taishan
;SYStem.CONFIG.COREDEBUG.Base 0xF0a01000
;taishanl
;SYStem.CONFIG.COREDEBUG.Base 0xF0a01000
;taishanll
SYStem.Option.TRST OFF
SYStem.JtagClock 1MHz
JTAG.PIN ENable
; enable JTAG output driver
JTAG.SHIFTTMS 1 1 1 1 1
; soft reset of the JTAG interface, goto Test-Logic Reset state
JTAG.SHIFTTMS 0 1 1 0 0
; goto Shift-IR state
JTAG.SHIFTREG 1 1 1 1
; shift in UID instruction
JTAG.SHIFTTMS 1 1 0 0
; goto Shift-DR state
JTAG.SHIFTREG %long 0x0 0x0
; shift in 64bit dummy code. shift out our uid
PRINT JTAG.SHIFT()
; print the UID
JTAG.SHIFTTMS 1 1 0 0
; goto Shift-DR state
JTAG.SHIFTREG %long 0x74657374 0x6b657930
; shift in the corresponding key .shift out our uid
PRINT JTAG.SHIFT()
JTAG.SHIFTTMS 1 1 1 1 1
; goto Test-Logic Reset state
JTAG.SHIFTTMS 0 1 0 0
; goto Shift-DR state
JTAG.SHIFTREG %long 0x0
; shift our IDCODE
PRINT JTAG.SHIFT()
JTAG.PIN Disable
; Disable JTAG output driver
SYStem.Mode Attach
;attach
ENDDO



Secure Debug 需要在 JTAG  模式下进行调试,先使用 e3_attach.cmm attach 之后,再使用上面的 secure debug  脚本进行安全调试。



注意:
JTAG 引脚在 EB 里面不要配置,配置后连接不上,无法调试。

5. 参考资料

芯驰官网技术参考资料

6. 后续博文系列

(1)【Semidriver E3】efuse 数据生成

(2)【Semidriver E3】efuse 数据烧写

等等

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论