PIC18 轻量加密怎么选:AES 6104 字节 vs XTEA 1950 字节的 ROM 与周期账

8 位机搬 AES 常遇到 Flash 吃紧、一帧跑太久。按 Microchip AN953 的实测数据拆解 AES、XTEA、SKIPJACK 与 PRBS 四种方案的 ROM、RAM 和每字节周期,给出按场景选型的一张表与七步落地。

2026-11-06
PIC18AESXTEASKIPJACK轻量加密ROM占用

一台电池供电的采集终端要把 100 字节参数帧加密后走无线,工程师直接把 PC 上的 AES 例程搬到 8 位机,编译后发现 Flash 被占去一大块;按 AN953 的实测折算,这一帧光加密就要 21.5 万个指令周期,而换成 XTEA 16 轮约 10.8 万,PRBS 不到 1.5 万。结论先给:8 位机上选加密算法,先算 ROM 和每字节周期,再谈安全等级;AN953 的实测里 AES 的 C 版要 6104 字节 ROM、2153 周期/字节,XTEA 16 轮只要 1950 字节、1075 周期/字节,PRBS 汇编版更是 48 字节、22~40 周期/字节——差的是几十倍,不是百分之几。

本文按 Microchip 应用笔记 AN953《Data Encryption Routines for the PIC18》DS00953A 整理,算法参数、资源占用与实测周期均取自该文档的表 7、表 8 与例程;测试平台与编译器版本以原文为准。

一、四种算法先摆上桌

AN953 给 PIC18 准备了四条路:AES、XTEA、SKIPJACK,以及一个用伪随机二进制序列做异或的轻量方案。它们不是同一档次的东西,先看分组、密钥和轮数。

算法分组长度密钥长度轮数/迭代定位
AES(Rijndael)16 字节16 字节10 轮标准算法,互通性最好,代价最高
XTEA8 字节16 字节建议 64,常用 32 或 16代码小、轮数可调,折中首选
SKIPJACK8 字节10 字节(80 位)32 轮密钥偏短,已显老旧
PRBS 异或逐字节流式由反馈抽头与初值决定KeyJump 可调速度优先,安全等级低

AES 是 NIST 在 2000 年 10 月 2 日采纳的标准,用来替代 DES,本实现固定 16 字节分组和 16 字节密钥,因此走 10 轮;手册表 1 同时给出 24 字节密钥 12 轮、32 字节密钥 14 轮的组合。加密流程分五步:密钥扩展、列混合、行移位、S 盒替换、轮密钥加,最后一轮不做列混合。

XTEA 的特点是算法本身极小,安全性靠迭代次数堆出来。作者建议 64 轮用于高安全场合,32 轮“几十年内应该够用”,安全要求低的场合 16 轮就够。SKIPJACK 是 1980 年代 NSA 为政府文档开发的算法,1998 年才解密公开,80 位密钥配 64 位分组,计数器从 1 数到 32 决定轮密钥;密钥偏短,过时的速度会比 AES、XTEA 快。PRBS 则是线性反馈移位寄存器加异或,8 位反馈系统在抽头 8、7、6、1 时是最大长度序列,KeyJump 用来打破规律周期。

二、ROM 与 RAM 的账:最多差 27 倍

先看代码占多少。表 8 给的是纯算法模块的占用,不含待加密数据缓冲区。

算法C 版 ROMC 版 RAM汇编版 ROM汇编版 RAM
PRBS 异或(带 KeyJump)226 字节12 字节48 字节11 字节
XTEA1950 字节38 字节962 字节25 字节
SKIPJACK3616 字节34 字节无无
AES6104 字节33 字节4400 字节45 字节

以 C 版为例,AES 的 6104 字节是 PRBS 226 字节的 27 倍,是 XTEA 1950 字节的 3.1 倍。换成汇编,AES 4400 字节仍是 XTEA 962 字节的 4.6 倍、PRBS 48 字节的 91 倍。如果器件只有 8 KB Flash,AES 的 C 版一下占去约四分之三,留给业务逻辑的空间非常紧。

RAM 反而不是主要矛盾:四种方案都在 11~45 字节之间,真正吃 RAM 的是待加密的数据缓冲和上层协议栈。选型时先卡 ROM,再看 RAM,顺序不要反。

三、周期账:同一颗片子差近 6 倍

表 7 给的是每字节周期数和对应吞吐,C 与汇编分开列。这里的 cycles/byte 指平均到每个明文字节的指令周期,与数据长度、密钥取值和迭代次数都有关系,原表也标注了这些前提。

方案C 加密周期/字节C 解密周期/字节汇编加密周期/字节汇编解密周期/字节
PRBS,KeyJump=192~14692~14622~4022~40
XTEA,16 轮10751280464464
XTEA,32 轮21332194926926
SKIPJACK28122817无无
AES21532940367620~687

几个结论直接能用来做预算。第一,C 与汇编差距巨大:AES 从 2153 降到 367 周期/字节,接近 5.9 倍;XTEA 16 轮从 1075 降到 464,也有 2.3 倍。时间紧的场合,换汇编比换算法更有效。

第二,解密通常比加密慢。AES 的 C 版加密 2153、解密 2940,原因是解密密钥要么现场推导、要么预先算好存起来,原表专门标注了这一项取决于实现方式;XTEA 在 16 轮时加密 1075、解密 1280,差距小一些。

第三,轮数是直接的乘法。XTEA 从 16 轮加到 32 轮,C 版周期从 1075 涨到 2133,几乎翻倍;PRBS 的 KeyJump 从 1 加到 5,汇编版从 22~40 涨到 97~120。安全等级不是免费的,选轮数就是选预算。

四、安全边界:一位错,整块废

除了 PRBS 异或,AES、XTEA、SKIPJACK 都是分组算法:解密前只要有一个比特出错,整个分组就会解成乱码。手册例 9 给了很直观的数字——明文 0x0102030405060708090A0B0C0D0E0F 加密后是 0x0A940BB5416EF045F1C39458C653EA5A,把最低字节异或 0x01 后再解密,得到的是 0xF0FDF04AD3AFED45BB676E5B3B1685CD,原来的数据完全找不回来。

所以块加密之后一定要加完整性校验:在块内嵌一个校验字节或验证字段,解密后先校验再使用;校验失败就丢弃整帧、请求重传,而不是把乱码送进业务逻辑。手册还提到一个反向用法——故意在密文里引入可预期的错误,攻击者不知道规则,即使拿到算法和密钥也解不对;这能提高门槛,但不能替代密钥管理。

密钥本身才是根。AES 模块允许把解密密钥预置在代码里,也允许用函数现场推导;两种方式各有风险,前者省时间但密钥就躺在 Flash 里,后者多花周期但可以用器件唯一信息参与推导。手册的原话是:只要密钥不公开,AES、SKIPJACK、XTEA 都算安全;密钥一旦公开,数据就裸奔。

五、按场景选:一张表落地

场景约束首选依据
电池供电,每秒多帧,只防误读Flash 小于 4 KB,功耗优先PRBS 汇编版48 字节 ROM,22~40 周期/字节
无线参数帧,要抗抓包,Flash 8~16 KB一帧百字节级,实时性中等XTEA 16 轮汇编版962 字节 ROM,464 周期/字节
与服务器或上位机互通,必须标准算法协议规定 AES,Flash 充足AES 汇编版4400 字节 ROM,367 周期/字节
老系统沿用 80 位密钥只能兼容 SKIPJACKSKIPJACK C 版3616 字节 ROM,2812 周期/字节

手册的总结与这张表一致:速度优先、安全要求低就选 PRBS;不计成本要最高安全就选 XTEA 32 轮以上或 AES;代码大小、速度和安全三者要平衡,就选 XTEA 16 轮。这句话放在今天仍然成立,尤其是 Flash 只有几 KB 的老平台。

六、落地时的五个细节

七、七步落地与验证

  1. 定安全等级:只是防误读,还是要抗抓包、防篡改,先写清楚。
  2. 算帧长与频率:单帧字节数乘以每秒帧数,得到每秒要处理的字节数。
  3. 算周期预算:用表 7 的 cycles/byte 乘总字节数,和主循环剩余周期对比。
  4. 卡 ROM:用表 8 的数值加上缓冲区与协议栈,确认不超过 Flash 的七成。
  5. 选实现:时间紧上汇编,要可维护选 C;两者不要混着调同一份数据。
  6. 加校验:块内嵌校验字节,解密后先验后用,失败即丢帧重传。
  7. 实测:用固定明文与固定密钥跑一遍,比对密文与周期数,确认与预算一致。
/* XTEA 单分组:64 位数据、128 位密钥;16 轮为例,32/64 轮改循环上限 */
#define DELTA 0x9E3779B9UL

void xtea_encode_block(uint32_t *v, const uint32_t *key)
{
    uint32_t sum = 0;
    uint8_t  i;

    for (i = 0; i < 16; i++) {
        v[0] += ((v[1] << 4 ^ v[1] >> 5) + v[1]) ^ (sum + key[sum & 0x03]);
        sum  += DELTA;
        v[1] += ((v[0] << 4 ^ v[0] >> 5) + v[0]) ^ (sum + key[(sum >> 11) & 0x03]);
    }
}

调用时每处理完 8 字节就重新进入一次函数,sum 从 0 开始,密钥指针保持只读;不要为了省事把 sum 做成静态变量跨块复用,那会把上一块的中间状态带进下一块,解密端如果按标准流程实现就对不上。

八、六个现场排查

现象根因改法
加密后长度对,解密全是乱码密钥或 sum 没按块重置每块从 sum=0、密钥首地址开始
只有最后一小段解错明文没补齐到分组长度按 16 字节(AES)或 8 字节(XTEA)填充
偶发整帧校验失败无线链路误码,块加密放大成整块报废加校验与重传,必要时降低单帧长度
周期比预算多一倍用了 C 版且开了高优化等级以外的调试选项对比表 7,时间敏感路径换汇编
Flash 不够选了 AES C 版换 XTEA 16 轮,ROM 从 6104 降到 1950
换密钥后老设备解不开密钥长度或轮数与对端不一致把算法、轮数、填充规则写进协议版本号

一句话总结:8 位机的加密选型是道算术题——先用 cycles/byte 乘帧长算时间,再用 ROM 占用卡 Flash,最后才看安全等级;XTEA 16 轮是多数场景的平衡点,PRBS 适合只求快的场合,AES 留给必须与外部系统互通的项目。

还想接着看:单片机固件加密与代码保护实战指南、EEPROM 数据可靠性保护设计、PIC18 查表与程序存储器读写。

本文基于 Microchip 应用笔记 AN953《Data Encryption Routines for the PIC18》DS00953A 技术资料整理优化。

需要定制开发?

沧州艾诺威电子 — 国家高新技术企业,20+项国家专利
嵌入式系统开发 · 物联网方案 · AI智能硬件 · 一站式交付

立即微信咨询

电话:13930711029 | 邮箱:tech@czinv.com | 24小时内响应