1. 嵌入式设备密码算法选型与资源评估
选型任务与约束建模
假设目标 MCU 为 Cortex-M0+ 内核,主频 48 MHz,Flash 64 KB,SRAM 8 KB,无 AES/SM4 硬件加速单元,无 DSP 指令,仅有 32 位单周期乘法器。安全需求为:对 256 字节以内的控制指令帧做机密性保护,密钥生命周期内加密次数不超过 10⁴ 次,要求抗软件侧信道能力达到“基本防护”级别,且固件升级后剩余 Flash 不低于 12 KB、SRAM 不低于 2 KB。
选型不能只看“算法是否安全”,必须把安全强度、RAM/ROM 占用、指令周期、代码复杂度、侧信道风险放在同一张量化表里比较。下面先建立评估维度,再给出三种候选算法的实测口径与估算方法。
候选算法资源画像
在无硬件加速的 32 位 MCU 上,三种算法的典型实现特征如下:
- AES-128:分组 128 bit,密钥 128 bit。查表法实现需要 256 B 的 S 盒和 256 B 的逆 S 盒(若需解密),轮密钥扩展需 176 B。加密 16 B 数据约 1.2–2.5 k 指令周期(查表法,无 T 表)。
- SM4:分组 128 bit,密钥 128 bit。S 盒 256 B,系统参数 FK 与固定参数 CK 共 64 B,轮密钥 128 B。加密 16 B 数据约 1.5–3.0 k 指令周期,与 AES 查表法接近,但 S 盒结构不同。
- ChaCha20:流密码,密钥 256 bit,nonce 96 bit,计数器 32 bit。无 S 盒,仅需 16 个 32 位状态字和少量常量,RAM 占用极低。加密 64 B 数据约 2.0–4.0 k 指令周期,但可按字节流输出,无需分组填充。
关键判断:如果 MCU 没有 AES 硬件加速,AES 和 SM4 的查表法都会把 S 盒常驻 Flash,运行时从 Flash 取表;ChaCha20 则完全避免查表,RAM 和 Flash 占用更小,但密钥长度和轮数带来更多指令周期。
量化评估表与选型决策
下表以 256 字节控制帧、加密 10⁴ 次为统一口径,给出估算值。表中“周期/字节”为查表法或纯软件实现的典型区间,实际值随编译器优化、是否展开轮函数、是否使用 T 表而变化。
| 指标 | AES-128 查表法 | SM4 查表法 | ChaCha20 |
|---|---|---|---|
| 密钥长度 | 128 bit | 128 bit | 256 bit |
| 分组/流模式 | 128 bit 分组 | 128 bit 分组 | 流密码 |
| Flash 常量占用 | S 盒 256 B + 逆 S 盒 256 B + 轮密钥 176 B ≈ 688 B | S 盒 256 B + FK/CK 64 B + 轮密钥 128 B ≈ 448 B | 常量约 64 B + 状态 64 B ≈ 128 B |
| RAM 峰值占用 | 约 300–500 B(含轮密钥、状态、栈) | 约 250–450 B | 约 150–250 B |
| 周期/字节(估算) | 75–160 | 95–190 | 125–250 |
| 256 B 加密周期 | 约 19.2k–41.0k | 约 24.3k–48.6k | 约 32.0k–64.0k |
| 10⁴ 次总周期 | 约 1.92×10⁸–4.10×10⁸ | 约 2.43×10⁸–4.86×10⁸ | 约 3.20×10⁸–6.40×10⁸ |
| 48 MHz 下 10⁴ 次耗时 | 约 4.0–8.5 s | 约 5.1–10.1 s | 约 6.7–13.3 s |
| 侧信道基本防护 | 查表法有缓存/功耗泄漏风险,需加掩码或随机化 | 同 AES,S 盒访问模式需防护 | 无查表,天然更易做常量时间实现 |
| 代码复杂度 | 中,需处理轮密钥扩展与逆变换 | 中,轮函数结构固定 | 低,状态更新规则统一 |
上表为教学估算口径,不是实测数据。实际选型时应在目标板卡上跑基准测试,记录
DWT->CYCCNT 或定时器差值,并测量 .text、.rodata、.bss 段大小。资源评估的实测方法
把估算变成可复现结论,需要三个动作:
- Flash 占用测量:编译后查看 map 文件,分别记录算法代码段、常量表段、轮密钥段。若使用 GCC,可用
arm-none-eabi-size -A firmware.elf查看各段大小。 - RAM 峰值测量:在算法入口和出口读取栈指针,差值加上静态缓冲区即为峰值。也可用
__heap_end__ - __stack_pointer估算剩余栈空间。 - 周期测量:使能 DWT 周期计数器,在加密前后读取
DWT->CYCCNT,对 256 B 数据重复 100 次取平均,再乘以 10⁴ 得到总周期。
/* 周期测量示例:Cortex-M0+ 无 DWT,可用 SysTick 或 TIM 替代 */
volatile uint32_t t0, t1, cycles;
t0 = TIM2->CNT;
aes128_encrypt(frame, 256, key, out);
t1 = TIM2->CNT;
cycles = (t1 - t0) & 0xFFFF;
/* 注意:TIM2 为 16 位时需处理溢出,建议用 32 位定时器或累计溢出次数 */
选型结论与依据
在本例约束下,推荐 ChaCha20 作为首选,理由如下:
- Flash 常量占用最小,约 128 B,远低于 AES 的 688 B 和 SM4 的 448 B,满足剩余 Flash ≥ 12 KB 的硬约束。
- RAM 峰值最低,约 150–250 B,为协议栈和其他任务留出更多空间。
- 无 S 盒查表,天然更容易实现常量时间代码,侧信道“基本防护”成本最低。
- 流密码无需分组填充,256 B 控制帧可直接按字节输出,协议处理更简单。
若系统必须兼容国密标准,则选 SM4;若已有 AES 硬件加速或需要与上位机 AES 生态互通,则选 AES-128。三者在本例的 48 MHz MCU 上,10⁴ 次加密耗时均在 4–14 s 量级,不构成实时性瓶颈,因此资源占用和侧信道风险成为决定性因素。
快速执行清单
- 确认 MCU 是否有 AES/SM4 硬件加速;有则优先用硬件,无则进入软件选型。
- 统计剩余 Flash 和 SRAM 硬下限,作为筛选条件。
- 按上表估算三种算法的常量占用、RAM 峰值和总周期。
- 若侧信道“基本防护”是硬需求,优先选无查表算法或准备掩码方案。
- 在目标板卡上实测
.text/.rodata/.bss和周期计数,用实测值替换估算值。 - 最终选型必须同时满足资源下限、安全需求和实时性上限,三者缺一不可。