示例成品 · 平台演示,按左边这组点选真跑出来的
先说结论:**当前会话里我没收到可读的附件内容**,不能假装打开 `v2.3.1-secure-boot.bin` 和 `test_log_20240515.txt` 报真实代码行号。但按你给的现象——“签名全到位、错误被吞、ARM TrustZone、ECDSA-P256”——问题大概率不是“没签名”,而是**验签失败后没有停机,错误在返回路径上被吞了**。
这版固件先别发。
---
## 直接可用的排查
### 1. 查验证入口:找所有 ECDSA-P256 验签调用点
```bash
grep -n "ecdsa_verify\|mbedtls_ecdsa_verify\|wc_ecc_verify\|verify_signature\|auth_mod_verify" -R .
```
重点看每个调用点有没有这种“吞错误”结构:
```c
ret = ecdsa_verify(...);
if (ret != 0) {
log_error("verify failed");
// 这里必须有:return ret; 或 panic(); 或 goto fail;
}
return AUTH_OK;
```
如果上面没有 `return ret`、`panic()`、`halt()`,就是错误被吞。
TrustZone 下还有一个硬要求:**验签失败必须在 Secure World 停机**,不能把状态返回给 Normal World 继续跑。查一下验证代码是否真的跑在 Secure World,失败状态有没有被普通世界覆盖或忽略。
---
### 2. 查错误传播:日志里是不是“失败后继续 boot”
```bash
grep -n "ERR\|WARN\|verify\|auth\|signature\|jump\|boot\|panic\|halt" test_log_20240515.txt
```
如果日志里出现类似:
```text
[ERR] ecdsa verify failed
[INFO] boot continue
[INFO] jump to app
```
那基本实锤:**验签失败被记录,但没有阻断启动**。
---
## ECDSA-P256 额外注意
- 签名格式是 `raw r||s` 还是 `DER`,必须和验证代码一致。
- P256 常见验签失败点:`raw 64 字节` 被当 `DER` 解析,或反过来的格式混用。
- 公钥必须来自 OTP/eFuse 或不可变安全存储,不能从待验证镜像里读出来;否则签名全到位也没意义。
可以用 OpenSSL 先验证签名本身是否有效:
```bash
openssl dgst -sha256 -verify pubkey.pem -signature sig.bin payload.bin
```
- 如果这步失败:签名数据本身有问题。
- 如果这步通过:问题集中在验签调用点的返回值处理。
---
## 负面测试:确认安全启动是否失效
```bash
cp v2.3.1-secure-boot.bin bad.bin
dd if=/dev/zero of=bad.bin bs=1 seek=0x1000 count=1 conv=notrunc
# 刷入 bad.bin
```
预期:设备立即停机,日志记录验签失败。
如果设备仍然正常启动:**验签失败没有被阻断,安全启动形同虚设。**
---
## 修复要求
失败处理要满足你给的策略“立即停机、记录不阻断”,代码应类似:
```c
if (ret != 0) {
sec_log(ret); /* 非阻塞记录 */
sec_halt(); /* 立即停机 */
}
return ret;
```
不要出现这种:
```c
if (ret != 0) {
sec_log(ret);
}
return 0;
```
---
## 要真实行号,需要你补两个输出
把这两个命令的结果贴出来,我就能继续给你定位到具体文件和行号:
```bash
grep -n "ecdsa_verify\|mbedtls_ecdsa_verify\|verify_signature\|auth_mod_verify" -R .
```
```bash
grep -n "ERR\|WARN\|verify\|auth\|signature\|jump\|boot\|panic\|halt" test_log_20240515.txt
```
如果你愿意把相关源码片断或日志第一处异常前后 30 行贴出来,我可以继续给出带真实代码行号的定位报告。
点左边「开工 · 直接出成品」,出一份你自己的版本(文字免费)