3、数字签名原理:RSA/ECDSA算法在高通平台的应用、哈希链校验、签名验证流程
好,咱们今天聊聊数字签名。这东西在安全启动里,说白了就是「信任的凭证」。你想想看,芯片上电后,怎么知道它要执行的代码是合法的?不是黑客塞进去的恶意程序?答案就是数字签名。
我在高通的平台上折腾安全启动好几年了,踩过不少坑。今天就把RSA和ECDSA这两种主流算法在高通平台上的应用,以及背后的哈希链校验、签名验证流程,给你掰开了揉碎了讲清楚。
3.1 为什么需要数字签名?
先问个问题:高通芯片从PBL(Primary Boot Loader)开始,一路加载到APPSBL(Application Subsystem Boot Loader),再到Linux内核。这中间每一级都要保证「没有被篡改」。怎么保证?
靠的就是数字签名。签名者(通常是设备厂商,比如小米、三星)用私钥对镜像签名,芯片内部固化的公钥来验证。公钥能解开签名,说明镜像确实是私钥持有者签发的,没被改过。
我遇到过最典型的案例:有人想刷第三方ROM,结果签名不对,高通芯片直接拒绝启动,卡在「9008紧急下载模式」。这就是签名验证在起作用。
3.2 RSA vs ECDSA:高通平台怎么选?
高通平台同时支持RSA和ECDSA。但两者有本质区别,我列个表给你看:
| 特性 | RSA | ECDSA |
|---|---|---|
| 密钥长度 | 2048位(常用)、4096位 | 256位(P-256)、384位(P-384) |
| 签名大小 | 256字节(2048位) | 64字节(P-256) |
| 计算速度 | 签名慢、验证快 | 签名快、验证稍慢 |
| 安全性 | 成熟、广泛 | 同等安全强度下密钥更短 |
| 高通平台支持 | 全系列支持 | 较新平台(如SM8450之后)原生支持 |
我个人习惯:如果是老平台(比如骁龙660、845),老老实实用RSA-2048。新平台比如骁龙8 Gen 2,我建议用ECDSA P-384。为什么?因为高通在XBL(eXtensible Boot Loader)里对ECDSA做了硬件加速,验证速度比RSA快不少。
3.3 哈希链校验:一环扣一环
高通安全启动的核心思想是「信任链」。从PBL开始,每一级都验证下一级的签名。这就是哈希链校验。
流程大概是这样的:
- PBL(只读ROM)验证SBL(Secondary Boot Loader)的签名。PBL里固化了高通公钥哈希(QFPROM里烧录的)。
- SBL验证XBL的签名。SBL里包含了设备厂商的公钥。
- XBL验证APPSBL的签名。
- APPSBL验证Linux内核的签名。
你看,每一级都只信任上一级。只要有一环断了,启动就失败。我曾经调试过一个bug,XBL验证APPSBL时总是失败,最后发现是APPSBL镜像的哈希值在签名时算错了。折腾了两天,就为了一个字节的差异。
关键点:哈希链校验的核心是「度量启动」(Measured Boot)。每一级在加载下一级之前,先计算其哈希值,然后与签名中的哈希值比对。如果一致,说明镜像没被改过。
3.4 签名验证流程:高通平台的具体实现
咱们以RSA-2048 + SHA-256为例,看看高通平台是怎么做签名验证的。代码层面,高通在XBL里用了一个叫boot_verify_image()的函数。
流程如下:
- 提取签名和证书:从镜像的尾部(或者特定偏移)提取签名数据块。这个数据块包含签名值、证书链、以及镜像的哈希值。
- 解析证书链:高通平台使用X.509证书。从根证书(设备厂商公钥)开始,逐级验证证书的合法性。
- 计算镜像哈希:对镜像本身(不包括签名部分)计算SHA-256哈希。
- 比对哈希:将计算出的哈希值与签名数据块中的哈希值比对。如果不一致,直接返回失败。
- 验证签名:用公钥解密签名,得到解密后的哈希值。与步骤3计算的哈希值比对。如果一致,验证通过。
这里有个细节:高通平台支持「哈希树」(Hash Tree)模式。对于大镜像(比如几MB的APPSBL),不会对整个镜像算一个哈希,而是分成多个块,每个块算一个哈希,再把这些哈希组成一棵树。这样做的目的是:如果某个块损坏了,只需要重新下载那个块,不用整个镜像重来。
小技巧:我在调试签名验证时,经常用高通提供的qsectools工具来手动签名和验证。命令大概是这样的:
# 生成RSA密钥对
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
# 使用高通的签名工具
qsectools sign -i boot.img -o boot_signed.img -k private.pem
# 验证签名
qsectools verify -i boot_signed.img -k public.pem
3.5 避坑指南:我踩过的几个坑
做高通安全启动开发,有几个坑你一定要注意:
- 密钥长度不匹配:我曾经把RSA-2048的密钥用在只支持RSA-1024的旧平台上,结果验证一直失败。后来查文档才发现,那个平台的硬件加速器只支持1024位。
- 哈希算法不一致:签名时用了SHA-256,但验证时默认用了SHA-1。高通平台默认是SHA-256,但有些旧镜像用的是SHA-1。一定要确认清楚。
- 证书链顺序:高通要求证书链的顺序是「从叶子证书到根证书」。我见过有人把顺序搞反了,结果验证失败。
- QFPROM熔丝:高通芯片的根公钥哈希是烧录在QFPROM里的,一旦烧录就无法修改。所以量产前一定要确认公钥哈希是正确的。我有个同事,量产前发现公钥哈希算错了,结果整批芯片都得报废...嗯,那场面,挺惨的。
重要提醒:千万不要在生产环境中使用测试密钥!我见过有人把测试密钥(比如testkey.pem)直接用在量产设备上,结果被黑客拿到了私钥,整个产品线的安全启动形同虚设。一定要用HSM(硬件安全模块)生成和管理生产密钥。
3.6 总结
数字签名在高通安全启动里,就是「信任的基石」。RSA和ECDSA各有优劣,选哪个取决于平台和性能要求。哈希链校验保证了从PBL到内核的每一级都是可信的。签名验证流程虽然看起来复杂,但核心就是「哈希比对 + 公钥解密」。
最后说一句:做安全启动开发,耐心比技术更重要。有时候一个签名验证失败,可能只是因为镜像末尾多了一个换行符。我遇到过最离谱的一次,是签名工具版本不对,生成的签名格式不兼容。所以,遇到问题别慌,从根开始查,一步一步来。