2、硬件根信任:QFPROM与硬件熔丝、OEM密钥配置、JTAG安全锁定机制

各位同学,咱们今天聊点硬核的——硬件根信任。说白了,就是芯片出厂时,怎么给它烙上一个“不可伪造的身份”。你想想看,如果连芯片自己都不确定自己是谁,那后面的安全启动、TEE可信执行环境,全都是在沙子上盖楼。

我最早接触高通平台时,也被这些硬件熔丝搞得头大。有一次调试安全启动,死活过不去,最后发现是QFPROM里一个bit没烧对。嗯,从那以后,我对这玩意儿就格外敬畏。

2.1 QFPROM:芯片的“基因锁”

QFPROM,全称是Qualcomm Fuse Programmable Read-Only Memory。你可以把它理解成芯片出厂时自带的一排“一次性开关”。每个开关只能被烧断一次,一旦烧断,就再也回不去了。

为什么叫“硬件根信任”?因为信任的起点就在这里。芯片上电后,PBL(Primary Boot Loader)做的第一件事,就是读取QFPROM里的熔丝状态。这些熔丝决定了:

  • 芯片是否被锁定(比如只能从某个特定存储启动)
  • OEM的公钥哈希值(用来验证后续镜像签名)
  • JTAG调试接口是否永久关闭
  • 安全等级(比如是否允许降级到旧版本)

我在项目中遇到过最坑的事,就是有人把QFPROM里一个“允许调试”的熔丝提前烧断了。结果芯片出了问题,想用JTAG抓波形都抓不了,只能报废。所以,烧熔丝之前,一定要三思。

核心要点:QFPROM是只读一次(OTP)的。一旦编程,不可逆。这是硬件信任锚点的物理基础。

2.2 硬件熔丝:一次性编程的“保险丝”

硬件熔丝,其实就是QFPROM里的一个个bit。每个bit对应一个物理熔丝。编程时,通过施加高电压(通常是1.8V或3.3V以上)把熔丝“烧断”。

熔丝的状态有两种:

状态 物理含义 逻辑值
未编程 熔丝完好,低电阻 0
已编程 熔丝烧断,高电阻 1

你可能会问:“为什么不用EEPROM或者Flash?” 原因很简单——熔丝是物理不可逆的。黑客就算用电子显微镜去观察芯片内部,也只能看到熔丝是断的还是连着的,但无法把它重新接上。这就是硬件安全的第一道防线。

我个人习惯,在量产前会写一个熔丝编程脚本,反复检查要烧写的bit位是否正确。因为一旦烧错,芯片就废了。我曾经见过一个团队,把OEM密钥的哈希值写错了一位,结果整批1000片芯片全部无法启动,损失惨重。

警告:熔丝编程必须在受控环境下进行。建议使用专用的编程器,并配合硬件防篡改机制。千万不要在生产线上用普通工具直接烧写。

2.3 OEM密钥配置:把信任交给厂商

OEM密钥配置,是硬件根信任中最关键的一步。高通芯片出厂时,QFPROM里是空的。OEM(比如小米、三星、或者你所在的公司)拿到芯片后,需要把自己的公钥哈希烧进去。

流程大概是这样的:

  1. 生成密钥对:OEM在安全环境中生成RSA或ECDSA密钥对。
  2. 计算哈希:对公钥进行SHA-256或SHA-384哈希计算。
  3. 烧写熔丝:将哈希值写入QFPROM的指定区域。
  4. 验证:芯片上电后,PBL读取该哈希,与后续镜像签名中的公钥进行比对。

这里有个细节要注意:烧写的不是公钥本身,而是公钥的哈希。为什么?因为公钥可能很长(比如RSA-4096有512字节),而QFPROM空间非常有限。哈希只有32或48字节,省空间。

我建议,密钥生成和烧写过程一定要有物理隔离。最好是在一台不联网的专用机器上操作,操作完成后立即销毁临时文件。你想想看,如果OEM私钥泄露了,那所有使用该密钥签名的设备,安全防线就全垮了。

小技巧:高通平台支持多个OEM密钥槽(通常有4个)。你可以把开发密钥、测试密钥、量产密钥分开存放。量产前,记得把测试密钥对应的熔丝永久锁定。

2.4 JTAG安全锁定机制:把后门焊死

JTAG,全称是Joint Test Action Group。它本来是芯片调试的“后门”。通过JTAG,你可以读取内存、修改寄存器、单步执行代码。对于开发者来说,这是神器。但对于黑客来说,这也是突破口。

所以,量产设备必须把JTAG锁死。高通平台提供了几种锁定方式:

  • 永久锁定:烧写QFPROM中对应的熔丝,JTAG接口物理失效。这是最彻底的方式。
  • 密码锁定:设置一个JTAG解锁密码。只有输入正确密码才能启用JTAG。密码也存储在QFPROM中。
  • 条件锁定:根据芯片状态(比如是否进入TEE)动态启用或禁用JTAG。

我个人更推荐永久锁定。因为密码锁定虽然灵活,但密码本身也可能被暴力破解。我在一个项目中就遇到过,有人用激光探针去读取QFPROM里的JTAG密码……嗯,虽然最后没成功,但想想都后怕。

另外,高通平台还有一个叫“Secure JTAG”的机制。它允许你在不暴露完整调试能力的情况下,进行有限的调试。比如,只允许读取某些安全寄存器的状态,但不允许修改。这个在开发阶段很有用。

避坑指南:我曾经在开发板上忘记锁定JTAG,结果被同事用调试器把整个Flash读了出来。从那以后,我每次烧写量产固件前,都会在脚本里加一行:qfprom_write -field jtag_disable -value 1。养成习惯,能省很多麻烦。

2.5 硬件根信任的完整链路

咱们把整个链路串起来看看:

  1. 芯片上电,PBL从ROM中启动。
  2. PBL读取QFPROM熔丝,获取OEM公钥哈希和JTAG锁定状态。
  3. PBL从BootROM中加载第一级引导镜像(通常是XBL或SBL)。
  4. PBL用QFPROM中的哈希,验证第一级引导镜像的签名。
  5. 验证通过后,控制权移交给第一级引导程序。
  6. 第一级引导程序继续验证后续镜像(如TZ、HLOS等)。

你看,每一步的信任都建立在上一级的基础上。而最底层的信任,就是QFPROM里那几根永远无法恢复的熔丝。这就是“硬件根信任”的含义——信任的根,扎在硬件里,拔不掉。

最后,我想说一句:硬件安全没有银弹。QFPROM、熔丝、JTAG锁定,这些都是基础。但真正决定安全性的,是你在整个生命周期中如何管理这些机制。密钥保管、熔丝编程流程、产线安全……任何一个环节出问题,硬件根信任就形同虚设。

好了,这一章就到这里。下一章咱们聊聊PBL的具体启动流程,看看那几行汇编代码是怎么把整个系统拉起来的。