作者:王力(Neo Wang)
1. 背景介绍:
在TI最新一代JacintoTM 7处理器芯片中,为了保证客户系统安全以及功能隐私,保证应用镜像不被恶意篡改、复制以及删除,TI为每一颗JacintoTM 7 家族的SoC芯片都提供了HS(high security)的芯片类型,其中HS芯片的详细开发流程可参考如下应用手册:
JacintoTM 7 High Security Device Development:https://www.ti.com/lit/an/sprad04/sprad04.pdf
而JTAG作为嵌入式开发过程中必不可少的调试接口,在应用开发以及产品发布阶段,推荐进行不同的处理,从而避免第三方通过JTAG接口对产品系统进行攻击从而造成损失。针对这种考虑,在GP和HS芯片中,JTAG接口具有不同的权限,如下表1所示:
表 1 不同芯片类型中的JTAG状态
芯片类型 |
芯片状态 |
M3 JTAG 状态 |
其它核心JTAG 状态 |
General Purpose (GP) |
GP |
Open |
Open |
High Security (HS) |
HS-FS |
Closed |
Open |
High Security (HS) |
HS-SE |
Closed |
Controlled |
本文旨在介绍并帮助开发人员在HS-SE芯片中实现对JTAG的控制,进而保证产品的安全以及隐私性
2. 测试条件:
DRA821 EVM开发板:https://www.ti.com/tool/J7200XSOMXEVM
DRA821 RTOS SDK8.2:https://www.ti.com/tool/download/PROCESSOR-SDK-RTOS-J7200/08.02.00.05
开发环境:Linux Ubuntu 18.04
值得一提的是,本文基于DRA821 HS-SE芯片进行测试以及介绍,但此方法适用于JacintoTM 7家族其它系列芯片,例如TDA4x系列SoC。
3. JTAG Debug Unlock的两种方法及适用场景
一般来说,JacintoTM 7家族HS-SE系列SoC中,如上表1所示,M3/M4F核心的JTAG默认关闭且不能打开,从而确保DMSC核心的安全,进而保证芯片内部的时钟电源安全。
而对于其它核心,例如R5F/A72/DSP等等,则可以通过JTAG Debug的预加锁/预解锁以及实时解锁两种方案来实现对JTAG的控制。
JTAG Debug的预加锁/预解锁方案通过直接对各个核心镜像的x509证书进行授权,使其在运行时在芯片内部直接进行对JTAG的加锁/解锁,从而实现对JTAG的控制。其适用于能够对镜像进行实时更新的开发环境。
JTAG Debug的实时解锁方案默认对JTAG进行锁死,然后通过外部JTAG口或者TISCI等方式向芯片发送特定的解锁证书,从而实现对指定核心的JTAG进行解锁;芯片下电后,会继续保持JTAG死锁。其适用于对镜像文件更新受限的开发环境。
总的来说,相对于预加锁/解锁方案,实时解锁方案的安全性更高,部署成功后操作更加便捷且高效;相对的,预加锁/解锁方案在前期部署工作上会更加简单。
4. JTAG Debug的预加锁/预解锁方案
所有在HS-SE芯片中执行的binary,都需要对镜像进行签名/加密才可正常运行,具体的流程可以参考应用手册“SPRAD04“中的第二章节。而JTAG Debug的预加锁/预解锁则是在对binary进行签名加密生成x509证书时,通过配置默认的debug extension来设置芯片JTAG Debug的权限。以SBL为例,在 /packages/ti/build/makerules/common.mk文件中,当开发人员执行make sbl_mmcsd_img_hs编译SBL时,会调用下述指令对SBL进行签名并设置debug extension的权限。
其中“DBG_FULL_ENABLE”代表默认将JTAG Debug设置为full,即打开对应核心的所有debug权限,即预解锁。若删除此编译选项,即默认JTAG Debug设置为关闭,即预加锁。
5. JTAG Debug的实时解锁方案
出于安全性考虑,在实时解锁方案中,可以首先默认配置JTAG是锁死状态。以DRA821 SBL为例,在SDK8.2中,在SBL的Makefile中默认会配置x509证书的debug extension并设置其为FULL权限,即MCU1_0 JTAG enable状态,所以需要将其先进行关闭并删除debug extension,改动如下patch所示:
其次,需要在板级配置文件中,设置其为支持外部实时解锁JTAG Debug,其改动如下patch所示:
其中变量allow_jtag_unlock 等于0x5A代表支持外部进行实时的JTAG unlock,同样的,JTAG Debug中其它变量的取值以及对应含义如下图1所示。
图 1 boardcfg中Secure Debug配置中的参量取值及含义
修改完成之后,需要重新编译boardcfg以及SBL等文件:
5.1 JTAG Debug的实时解锁流程:
外部设备通过JTAG来解锁对应核心JTAG调试权限时,首先需要将设计过的且符合ANS.1规则的x509证书传输给DMSC,DMSC会解析此x509证书,并经过校验UID,revision等通过之后,对JTAG Debug进行对应的权限解锁。其大致流程如下图2所示:
图 2 JTAG Debug的实时解锁流程
5.2 创建x509调试证书配置文件:
如5.1中图2所示的,首先要编写一个能够通过DMSC检查,并通过各项UID,revision等校验的x509证书,而在生成证书之前,首先需要按照ANS.1的规则编写一个配置文件。这样才能保证生成的调试证书能够被DMSC正确识别并进行配置。如下所示,为在DRA821中的x509调试证书配置文件模板。
值得注意的是,在不同芯片平台(TDA4x或DRA8x),亦或同一芯片平台的不同UID芯片中,进行不同核心(R5F/A72/DSP)的JTAG Unlock权限配置,开发人员只需对【debug】下的内容进行更改。下面将对【debug】中的四个配置参数含义以及设置原则进行介绍:
a. UID获取
UID是对于每颗芯片的独一无二的标志,在JacintoTM 7家族中,其为256bit的64个16进制数构成。一般来说,获取UID的方法有三种:
- 在UART boot模式下通过MCU UART获取,并经过脚本解析得到。
- 利用dbgauth工具通过命令行获取。
- 利用TISCI在代码中获取TISCI_MSG_GET_SOC_UID
其中第一种方法可参考应用手册“SPRAD04“中的第四章节获取。
其中第二中方法,将在本文5.4小节中介绍。
第三种方法参照TISCI手册。
开发人员只需根据自身开发环境选择其一即可。在获取到UID之后,只需将其替换到 【debug】规则下的deviceUID中即可。
b. DebugType配置原则
DebugType为一个32bit数,其中低16bit数为debug level权限控制,高16bit目前为保留位,默认取全0即可。其中debug level的取值以及对应的含义如图3所示:
图 3 debug level取值及其含义
c. coreDbgEn配置原则
coreDbgEn控制哪些核心的non-secure debug将被打开,以Processor ID的形式列出,以DRA821为例,其内部所有处理器核心的processor ID如下所示:
图 4 DRA821芯片内部处理器核心对应ID取值
d. coreDbgSecEn配置原则
coreDbgSecEn控制哪些核心的secure debug将被打开,以Processor ID的形式列出,以DRA821为例,其内部所有处理器核心的processor ID同样可参照图4所示。
5.3 通过x509配置文件生成x509证书并签名:
开发人员根据需求设计完配置文件后,需要适用openssl来生成对应的x509证书,并适用自己的密钥对此证书进行签名,才能保证此证书能被对应的HS-SE板子验签并解析。
其中“-key”后需要保持和开发人员HS-SE板子中烧写的密钥保持一致;“-out”后的文件即为将生成的x509证书文件;“-config”中即为在本文5.2小节中设计得到的配置文件。
5.4 CCS环境及dbgauth工具搭建:
在使用外部JTAG进行实时解锁JTAG Debug时,需要使用CCS中的组件工具dbgauth。开发人员需要安装CCS,建议安装CCS 9.3及其之后版本:https://www.ti.com/tool/CCSTUDIO
安装完毕后,按照下列步骤来配置环境:
- 针对芯片类型新建CCS configuration并进行launch,完毕后会在~/.ti/<ccs_version>/0/0/BrdDat/目录下有对应的配置文件dat。
- 同样的,安装后dbgauth工具会在<ccs install>/ccs/ccs_base/common/uscif/目录下。
- 需要确认当前版本的dbgauth是支持JacintoTM 7系列SoC的K3架构的:
至此,环境搭建完毕。
5.5 利用证书进行实时JTAG解锁:
基于5.4小节建立的环境,可通过dbgauth工具来获取设备UID,以及实时解锁JTAG等操作。首先需要将5.1小节中编译得到的SBL以及TIFS放到boot media中,确认MCU1_0以及DMSC已经正常运行起来,例如获取UID的命令以及打印为:
此时如果通过CCS直接链接MCU1_0的核心是无法连接的,因为默认的JTAG配置为lock状态。
通过5.3小节中生成的证书进行JTAG解锁的命令及打印为:
执行完上述指令后,JTAG Debug将被打开,可以通过CCS对MCU1_0进行连接。