4、SPC与安全启动:安全处理器、启动链与签名验证
好,咱们今天聊聊全志A64上这个有点神秘的东西——SPC。说白了,它就是一颗藏在主芯片内部的小脑袋,专门负责安全相关的事务。我刚开始接触全志平台时,也纳闷过:为什么非要单独搞个处理器?后来踩了几个坑才明白,这玩意儿太重要了。
4.1 SPC(安全处理器)到底是什么?
SPC,全称是Security Processor Controller。你可以把它理解成一个独立的小CPU。它有自己的ROM、SRAM,甚至有自己的加密引擎。主CPU(也就是Cortex-A53)跑Android或Linux,SPC则默默地在后台处理密钥、签名验证这些敏感操作。
为什么要分开?你想想看,如果主CPU被攻破了,攻击者就能随意读取密钥。但SPC和主CPU是物理隔离的,主CPU根本访问不到SPC内部的敏感数据。我在一个项目中就遇到过,客户担心密钥被逆向工程,我直接告诉他们:只要SPC的隔离机制没被绕过,密钥就是安全的。
SPC的核心职责:
- 管理芯片的硬件唯一密钥(HUK)
- 执行安全启动链的签名验证
- 提供真随机数生成(TRNG)
- 保护安全存储区域(如efuse)
4.2 安全启动链:从BROM到系统
全志A64的安全启动,是一条环环相扣的链条。每一级都要验证下一级的签名,只要有一环断了,启动就失败。嗯,这里要注意,这个链条是单向的,不能回退。
链条大致是这样的:
- BROM(一级启动):芯片上电后,BROM最先运行。它固化在芯片内部,无法修改。BROM会检查SPC是否正常,然后加载下一级。
- SPL(二级启动):BROM从存储介质(比如SD卡、eMMC)中读取SPL。SPL必须经过签名,否则BROM拒绝执行。
- U-Boot(三级启动):SPL验证U-Boot的签名,通过后才加载。
- 系统内核(四级启动):U-Boot验证内核镜像的签名,然后启动系统。
我记得有一次调试,发现SPL死活加载不了U-Boot。查了半天,原来是签名时用的密钥和BROM里烧录的密钥不匹配。这种问题最头疼,因为BROM的密钥是出厂时烧死的,改不了。只能重新生成签名。
个人经验: 开发阶段建议先关闭安全启动,等所有功能调通后再开启。否则每次修改都要重新签名,非常浪费时间。我习惯在U-Boot里加一个开关,调试时跳过签名验证。
4.3 签名验证流程:到底怎么验的?
签名验证,说白了就是「用公钥解签名,算哈希,比对」。但全志的实现有一些细节需要注意。
流程大致如下:
- 加载镜像文件(比如SPL.bin)
- 从镜像中提取签名数据和公钥
- 用公钥解密签名,得到哈希值A
- 对镜像内容计算哈希,得到哈希值B
- 比对A和B,一致则通过,否则拒绝启动
这里有个关键点:公钥从哪里来?全志A64的做法是,把公钥的哈希值烧录到efuse中。SPC在验证时,会先检查镜像携带的公钥是否与efuse中的哈希匹配。这样可以防止攻击者替换公钥。
避坑指南: 我曾经犯过一个错误——把公钥哈希烧录错了位置。结果芯片直接变砖,因为BROM发现公钥不匹配,连SPL都不加载。后来我学乖了,每次烧录efuse前,都会用全志提供的工具先模拟验证一遍。
4.4 实际开发中的注意事项
如果你要在全志A64上开启安全启动,有几个点必须注意:
| 项目 | 说明 | 我的建议 |
|---|---|---|
| 密钥管理 | 私钥必须严格保护,泄露就全完了 | 使用HSM(硬件安全模块)存储私钥 |
| efuse烧录 | 一次性烧录,不可逆 | 先在小批量板上验证,再大规模烧录 |
| 签名工具 | 全志提供dragonSN等工具 | 建议写脚本自动化签名流程 |
| 调试接口 | 安全启动开启后,JTAG等接口会被禁用 | 保留一个物理开关,调试时断开efuse供电 |
嗯,说到调试接口,我记得有个项目,客户要求量产时必须禁用JTAG。结果有台设备出了问题,想调试都进不去。最后只能拆芯片,用编程器读Flash。从那以后,我都在设计板上留一个「调试跳线」,生产时再断开。
4.5 总结一下
SPC和安全启动,是全志A64安全体系的基石。没有它,你的设备就像没锁门的房子。虽然配置起来有点麻烦,但一旦跑通,就能有效防止固件被篡改、逆向工程这些攻击。
我个人习惯是:开发阶段先不开启安全启动,用普通启动流程调通所有功能。等硬件稳定了,再一步步加上签名验证。千万别一上来就烧efuse,否则出了问题只能换芯片。
下一章,我会讲讲U-Boot的移植和定制。到时候咱们再聊怎么让U-Boot跑得更快、更稳。