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开始,每一级都验证下一级的签名。这就是哈希链校验。

流程大概是这样的:

  1. PBL(只读ROM)验证SBL(Secondary Boot Loader)的签名。PBL里固化了高通公钥哈希(QFPROM里烧录的)。
  2. SBL验证XBL的签名。SBL里包含了设备厂商的公钥。
  3. XBL验证APPSBL的签名。
  4. APPSBL验证Linux内核的签名。

你看,每一级都只信任上一级。只要有一环断了,启动就失败。我曾经调试过一个bug,XBL验证APPSBL时总是失败,最后发现是APPSBL镜像的哈希值在签名时算错了。折腾了两天,就为了一个字节的差异。

关键点:哈希链校验的核心是「度量启动」(Measured Boot)。每一级在加载下一级之前,先计算其哈希值,然后与签名中的哈希值比对。如果一致,说明镜像没被改过。

3.4 签名验证流程:高通平台的具体实现

咱们以RSA-2048 + SHA-256为例,看看高通平台是怎么做签名验证的。代码层面,高通在XBL里用了一个叫boot_verify_image()的函数。

流程如下:

  1. 提取签名和证书:从镜像的尾部(或者特定偏移)提取签名数据块。这个数据块包含签名值、证书链、以及镜像的哈希值。
  2. 解析证书链:高通平台使用X.509证书。从根证书(设备厂商公钥)开始,逐级验证证书的合法性。
  3. 计算镜像哈希:对镜像本身(不包括签名部分)计算SHA-256哈希。
  4. 比对哈希:将计算出的哈希值与签名数据块中的哈希值比对。如果不一致,直接返回失败。
  5. 验证签名:用公钥解密签名,得到解密后的哈希值。与步骤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到内核的每一级都是可信的。签名验证流程虽然看起来复杂,但核心就是「哈希比对 + 公钥解密」。

最后说一句:做安全启动开发,耐心比技术更重要。有时候一个签名验证失败,可能只是因为镜像末尾多了一个换行符。我遇到过最离谱的一次,是签名工具版本不对,生成的签名格式不兼容。所以,遇到问题别慌,从根开始查,一步一步来。