第二章:信任链基础——信任根(RoT)、信任链传递机制、高通PBL与SBL详解
各位同学,今天我们聊点硬核的。信任链,说白了就是「谁可以相信谁」的问题。你想想看,一个芯片上电后,第一行代码是谁执行的?它凭什么值得信任?这就是信任根要回答的事。
我在做车载安全方案时,经常遇到客户问:「我的代码明明加密了,为什么还被攻破?」答案往往出在信任链的某个环节断了。今天我们就把它彻底讲透。
2.1 信任根(Root of Trust, RoT)
信任根,是整个安全体系的基石。它必须是硬件级别的、不可篡改的。为什么?因为软件可以被改写,但硬件熔丝一旦烧断,神仙也改不了。
核心要点:信任根必须满足三个条件——不可伪造、不可篡改、不可绕过。
在高通SA8155上,信任根固化在PBL(Primary Boot Loader)中。PBL存储在芯片内部的ROM里,出厂即固定。嗯,这里要注意:ROM里的代码是只读的,任何外部攻击都无法修改它。
我个人习惯把信任根比作「芯片的出生证明」。你拿到一颗芯片,它自带的PBL就是它的身份。如果这个身份被伪造了,后面所有校验都是白搭。
2.1.1 信任根的物理实现
- 一次性可编程存储器(OTP):用于存储公钥哈希、芯片唯一ID等关键信息。烧断后不可恢复。
- 硬件安全模块(HSM):提供真随机数生成、密钥派生等密码学服务。
- 安全熔丝(eFuse):控制调试接口、JTAG等敏感功能的开关。
我在项目中遇到过一件事:某款车机因为OTP烧录时电压不稳,导致公钥哈希写入错误,整批芯片报废。所以,烧录信任根时一定要做校验回读,别省这一步。
2.2 信任链传递机制
信任链传递,说白了就是「一级验一级」。PBL验证SBL,SBL验证ABL,ABL验证OS。每一级都只信任上一级签名的代码。
为什么会这样设计?因为ROM空间有限,放不下完整的操作系统。只能放一个最小的引导程序,由它去加载更大的程序。但问题来了——你怎么知道加载的程序是安全的?
我的经验:信任链传递的核心是「逐级签名验证」。每一级加载下一级之前,必须用上一级的公钥验证下一级的数字签名。签名通过,才执行。
你想想看,如果PBL验证SBL时跳过了签名检查,那攻击者只要替换掉SBL,整个系统就沦陷了。所以,高通在设计时强制要求:PBL必须验证SBL的签名,且签名算法使用RSA-2048或ECDSA。
2.2.1 信任链的典型流程
- 上电复位:CPU从ROM地址0x0开始执行PBL代码。
- PBL初始化:配置时钟、内存控制器、安全引擎。
- PBL读取SBL:从eMMC或UFS中读取SBL镜像到SRAM。
- PBL验证SBL:使用OTP中存储的公钥验证SBL的数字签名。
- PBL跳转到SBL:验证通过后,将控制权交给SBL。
- SBL继续验证下一级:重复上述过程,直到OS启动。
我曾经调试过一个启动失败的问题,发现是SBL镜像的签名算法版本不匹配。PBL用的是RSA-2048,但SBL签名时用了RSA-4096。嗯,这种低级错误,排查起来真的很头疼。
2.3 高通PBL详解
PBL(Primary Boot Loader),也叫一级引导程序。它存储在芯片内部的Boot ROM中,容量通常只有几十KB。别小看这点空间,它承载了整个安全体系的起点。
2.3.1 PBL的主要职责
| 功能 | 说明 |
|---|---|
| 硬件初始化 | 配置CPU、时钟、内存控制器等基础硬件 |
| 安全启动校验 | 验证SBL的数字签名和完整性 |
| 调试接口控制 | 根据eFuse状态决定是否开放JTAG/SWD |
| 回滚保护 | 检查SBL版本号,防止降级攻击 |
我记得有一次,客户反馈说芯片无法进入下载模式。排查后发现,PBL检测到eFuse中「安全启动使能位」被置位,直接禁用了所有调试接口。这就是PBL的「铁面无私」——一旦安全策略生效,谁也别想绕过。
避坑指南:我曾经见过有人试图通过修改PBL来绕过安全校验。但PBL在ROM里,物理上不可写。唯一的办法是更换芯片。所以,别打PBL的主意,它动不了。
2.4 高通SBL详解
SBL(Secondary Boot Loader),二级引导程序。它比PBL大得多,通常有几百KB,存储在eMMC或UFS的特定分区中。SBL负责加载ABL(Application Boot Loader)或直接加载OS。
2.4.1 SBL的启动流程
- PBL跳转到SBL:此时SBL已经在SRAM中,且通过了签名验证。
- SBL初始化DDR:配置DDR控制器,将自身从SRAM拷贝到DDR中运行。
- SBL加载设备树:读取设备树配置,初始化外设(如UART、I2C、SPI)。
- SBL验证ABL:使用PBL传递的公钥验证ABL的签名。
- SBL跳转到ABL:验证通过后,将控制权交给ABL。
你想想看,SBL比PBL复杂得多,它要处理各种外设初始化、内存配置、分区表解析。这也意味着它的攻击面更大。所以,高通的SBL做了很多安全加固:
- 地址随机化:SBL在DDR中的加载地址每次随机变化,防止固定地址攻击。
- 栈保护:使用栈金丝雀(Stack Canary)防止栈溢出。
- 权限分离:SBL运行在EL3(异常级别3),ABL运行在EL2,OS运行在EL1。权限逐级降低。
我的建议:如果你在开发基于SA8155的板子,一定要检查SBL的版本号。高通会定期发布安全更新,修复SBL中的漏洞。别用旧版本,否则你的信任链可能从SBL这里断掉。
2.5 信任链的完整示例
我们来看一个实际的信任链验证流程。假设你有一台基于SA8155的车机,上电后发生了什么:
1. CPU上电,从ROM 0x0开始执行PBL
2. PBL读取eFuse状态:
- 安全启动使能位 = 1
- 调试接口使能位 = 0
3. PBL从eMMC分区0读取SBL镜像(256KB)
4. PBL使用OTP中的RSA公钥验证SBL签名
5. 签名验证通过,PBL跳转到SBL入口
6. SBL初始化DDR,从eMMC分区1读取ABL镜像(1MB)
7. SBL使用PBL传递的公钥验证ABL签名
8. 签名验证通过,SBL跳转到ABL入口
9. ABL加载Linux内核,并验证内核签名
10. 内核启动,系统正常运行
如果第4步签名验证失败,PBL会进入「安全错误」状态,直接死循环。这时候你连串口都看不到任何输出。嗯,我第一次遇到这种情况时,还以为板子坏了,折腾了半天才发现是SBL镜像被改过。
关键点:信任链的每一环都必须严格验证。只要有一环跳过,整个安全体系就形同虚设。
2.6 常见问题与避坑指南
最后,我总结几个我在项目中踩过的坑,希望能帮你少走弯路:
- OTP烧录失败:烧录公钥哈希时,一定要做回读校验。我曾经因为烧录器接触不良,导致哈希值写入错误,整批芯片报废。
- 签名算法不匹配:PBL和SBL使用的签名算法必须一致。高通默认用RSA-2048,但有些定制版本可能改了。检查清楚再签名。
- 版本号回滚:攻击者可能用旧版本的SBL替换新版本,利用已知漏洞。PBL会检查SBL的版本号,如果低于当前版本,拒绝启动。
- 调试接口未关闭:量产时一定要烧断eFuse关闭JTAG。否则攻击者可以通过调试接口读取内存,绕过信任链。
好了,这一章的内容就到这里。信任链是安全启动的骨架,理解了它,后面的TEE、密钥管理等内容才能顺理成章。下一章我们聊聊高通的安全启动模式——有哪些模式?怎么配置?咱们到时候细说。