Linux 内核代码是嵌入式的圣经,里面有很多值得大家学习的东西,也有很多"宝藏"。。。。
很多人会觉得 linux 内核很神圣、很难懂,其实不然,譬如今天介绍的 speck 对称加解密算法,新的内核代码已经被删掉,因为它是美国国家安全局 NSA 设计的算法,开源社区的人担心有后门。不过,我们用来做 bootloader 等加密是不需担心它是否真的有后门。很多场合可以代替 AES加密。
原始的内核代码参见:
https://elixir.bootlin.com/linux/v4.18/source/crypto/speck.c
https://elixir.bootlin.com/linux ... lude/crypto/speck.h
包含注释等 N 多代码无关信息,c 文件一共才 307 行,包含了两个位宽版本,而且没啥依赖。
下面这个是我把代码搬到用户空间,写了一个小 main 文件测试的工程:
#include <stdio.h>
#include "speck.h"
static speck64_t speck_ctx;
static uint8_t key96[12] = {0,1,2,3,4,5,6,7,8,9,1,2}; // 密钥
static uint8_t ori[8] = {1,2,3,4,5,6,7,8}; // 原始明文,一个 block 8 字节,正好 64 位
static uint8_t enc[8] = {0}; // 存放加密得到的密文
static uint8_t back[8]= {0}; // 存放再次解密得到的明文
int main(void)
{
crypto_speck64_setkey(&speck_ctx, key96, SPECK64_96_KEY_SIZE); // 第 3 个参数 8 位机版本已删掉,进一步减少开销
crypto_speck64_encrypt(&speck_ctx, enc, ori);
crypto_speck64_decrypt(&speck_ctx, back, enc);
printf("enc: %d %d %d %d %d %d %d %d\n", enc[0], enc[1], enc[2], enc[3], enc[4], enc[5], enc[6], enc[7]);
printf("back: %d %d %d %d %d %d %d %d\n", back[0], back[1], back[2], back[3], back[4], back[5], back[6], back[7]);
return 0;
}
重点来了,以下是最终搬到 8 位机的代码,只保留 64 位版本,不算注释,c 文件只有 70 多行,只是 put_unaligned_le32 和 get_unaligned_le32 这种通用函数里面,为移位加上显式类型转换,防止高位数据丢失而已。
总的来说,几乎没啥改动,内核代码就可以直接搬到 8 位 mcu 运行。