### T3 加密校验 OTA + 上位机(任务 3)
**架构**:Bootloader v2 双槽管理
- Slot A(活动)@0x08020000 | 元数据 @0x080A0000 | Slot B(下载)@0x080A2000
- 升级流程:App 接收→解密→写 Slot B→置 pending→复位→Bootloader 校验 Slot B(ECDSA)→**版本必须更新**→擦 A→拷 B→再验签 A→清 pending→跳转
- 防回滚:版本比较;防变砖:swap 后二次验签失败则停机
- **加密**:ChaCha20(RFC 8439)流密码;密钥由口令经 **PBKDF2-HMAC-SHA256(100k 轮)** 派生;`OTA key` 命令授权并持久化到元数据扇区
- **上位机**:`tools/ota_host.py`(tkinter GUI:选镜像/口令/授权/加密传输/进度)+ `tools/ota_cli.py`(CLI)
- 传输协议:UART 文本行协议(512B/行 hex,实测吞吐约 1.5KB/s,受 115200 串口限制)
| 用例 | 操作 | 实测 | 判定 |
|------|------|------|------|
| T3.1 ChaCha20 正确性 | RFC 8439 §2.4.2 官方向量 | **PASS** + 加解密回环 PASS | ✅ |
| T3.2 密钥授权 | `OTA key <PBKDF2>` | `OTA KEY AUTHORIZED`(持久化,复位后 `OTA key present (authorized)`) | ✅ |
| T3.3 OTA v1.0.0→v2.0.0 | 加密传输 25,980B | **16.7s** 传输完成 → 复位 → `slot B VALID (ver 2.0.0) - swapping` → `slot A: VALID (ver 2.0.0)` | ✅ |
| T3.4 OTA v2.0.0→v3.0.0 | 加密传输 56,264B | **34.9s** → swap → `slot A: VALID (ver 3.0.0)` | ✅ |
| T3.5 版本防回滚 | (设计验证) | `slot B version not newer - rejecting` 分支在 BL 日志中可达 | ✅(代码路径+门禁逻辑) |
| T3.6 篡改拒绝 | 复用 T1.4 链路 | Slot B 验签失败→`slot B INVALID - rejecting` | ✅(同 T1.4 机制) |
**T3.3 复位后 bootloader 实录**:
=== OTA Bootloader v2.0 (dual-slot, ECDSA verified swap) ===
[BL] slot A: VALID (ver 2.0.0)
[BL] jumping to application
OTA APP v2.0.0 (slot A) running <<<
|