6.11. JTAG 解锁
在安全方案中,芯片使能安全启动之后,可通过 eFuse 关闭 JTAG, 防止攻击者通过 JTAG 控制芯片和窃取芯片中的敏感信息。然而在实际应用中可能会遇到一些需要使用 JTAG 调试的场景,即需要将关闭的 JTAG 重新打开。
JTAG 安全解锁的作用是提供一种安全的方法,在不影响芯片的安全等级的情况下, 让合法的用户可以重新打开芯片的 JTAG 接口。
6.11.1. JTAG 关闭和打开
在芯片内部,JTAG 调试模块与外部调试器的通信由几个主要信号连接实现。
这里的 JTAG 信号是:
TMS
TRST
TDI
TDO
将其中的 TDO 关闭,可以实现关闭外部调试器的 JTAG 调试功能。本芯片通过烧录 eFuse 的安全配置区域 JTAG_DIS 位进行关闭。
要重新打开 JTAG,可通过另外一个来自寄存器的设置信号来重新使能 TDO 信号。具体如下图所示。
当JTAG_UNLOCK被设置为1时,不管 eFuse 中的 JTAG DIS 被设置为什么值,都会保证 TDO 有效。
6.11.2. 开关的安全性
eFuse JTAG DIS 被设置为1之后,JTAG 立刻关闭。由于 eFuse 比特无法被重新设置为0, 因此 JTAG_DIS 信号一直生效,每次重新上电,JTAG 总是默认关闭。
重新打开 JTAG 由 JTAG_UNLOCK 信号控制,该信号由 SID 模块的 JTAG_UNLOCK 寄存器比特位控制, 因此重新打开 JTAG 的安全性,取决于 JTAG_UNLOCK 比特位的安全性。
JTAG_UNLOCK 比特位具有一个特性:该比特位设置为1时,解锁 JTAG,但是仅有 SID 模块寄存器中的 BROM_PRIV_LOCK 为0时,JTAG_UNLOCK 才会有效。如果 BROM_PRIV_LOCK 为1,则 JTAG_UNLOCK 位设置为1, 也无法解锁 JTAG。
BROM_PRIV_LOCK 有一个特点,一旦被设置为1,就无法清零,只有系统复位才可以清零。 在系统复位时,BROM 会被运行。BROM 跳出之前,会主动设置 BROM_PRIV_LOCK=1。 即保证只有 BROM 程序可以设置 BROM_PRIV_LOCK 和 JTAG_UNLOCK 位。
通过上述的配置,将重新打开 JTAG 的权力放在 BROM 之中。BROM 在升级模式下,通过 USB/UART 命令的方式, 对外部的解锁 JTAG 命令进行安全性校验,校验通过,则设置 JTAG_UNLOCK 对 JTAG 进行解锁。
在安全启动使能的情况下,BROM :
不能通过 USB/UART READ/WRITE 命令对寄存器进行读写
所有 BROM 执行的程序,都需要经过安全校验(包括 PBP 程序,如果使能了安全启动,PBP 必须是加密的)
BROM 在跳转任何其他程序之前,必须先设置 BROM_PRIV_LOCK 特权位
通过上述措施,保证在 BROM 阶段,JTAG 无法被其他程序打开。
6.11.3. 解锁的安全验证
在 BROM 升级模式下,可通过 USB/UART 命令,让 BROM 执行 JTAG 解锁。具体流程如下:
通过 USB/UART 命令,读取芯片中的 CHIP DATA(包含了 CHIP ID 等信息),保存为二进制文件
主机端需要使用RSA 私钥,对读取到的 CHIP DATA二进制文件进行签名,生成签名后的 JTAG 解锁文件(具体格式参考后面的描述)
通过 USB JTAG_UNLOCK 命令,发送 JTAG 解锁文件给 BROM
BROM 验证通过后,执行 JTAG 解锁
输入的解锁文件格式: