微控制器的最小 AES 实现?

电器工程 图片 加密
2022-01-02 06:24:07

任何人都可以为微控制器推荐一个小的、免费的 AES-128 Rijndael 实现。理想情况下,对于 PIC18,尽管 C 中的通用实现会很有用。

为 PIC18编译axTLS 实现并加密/解密一个块需要 6KB ROM 和 750b RAM。

为 PIC18编译rijndael-alg-fst.c并加密/解密一个块需要 28KB ROM 和 0.5KB RAM。

为 PIC18编译Brian Gladman 的 8 位 AES并加密/解密一个块需要 19KB 的 ROM 和 190 字节的 RAM。

是否有更好优化的 PIC 特定变体可用?

(更新了 axTLS 版本的 RAM 要求)

4个回答

我想知道您是如何使用 axTLS 获得 7.5kB 的 RAM 使用量的。查看代码,所有上下文都存储在这个结构中:

typedef struct aes_key_st 
{
    uint16_t rounds;
    uint16_t key_size;
    uint32_t ks[(AES_MAXROUNDS+1)*8];
    uint8_t iv[AES_IV_SIZE];
} AES_CTX;

这个结构体的大小是2 + 2 + 4 * 15 * 8 + 16 = 504。我在aes.c中没有看到全局变量,自动变量都很小,所以堆栈使用也是合理的。那么7.5kB去哪儿了?也许您正在尝试使用整个库而不是仅仅从中提取 AES 实现?

无论如何,这个实现看起来很简单,我宁愿坚持这段代码并尝试优化它。我知道这可能很棘手,但学习 AES 细节至少可以帮助您估计绝对最小 RAM 使用量。

更新:我刚刚尝试在 IA-32 Linux 上编译这个库并编写一个简单的 CBC AES-128 加密测试。得到以下结果(第一个数字是截面长度十六进制):

 22 .data         00000028  0804a010  0804a010  00001010  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 23 .bss          00000294  0804a040  0804a040  00001038  2**5
                  ALLOC

这只是 .bss 的 660 字节(我已将 AES_CTX 声明为全局变量)。大多数 .data 被 IV 和 key 占用。我在这里不包括 .text ,因为你会在 PIC 上得到完全不同的结果(两种架构上的数据部分应该几乎相同)。

我知道这个问题有点老了,但我最近不得不自己研究它,因为我正在 PIC16 和 8051 上实现 AES128,所以我也对这个问题很好奇。

我用过这样的东西:http ://cs.ucsb.edu/~koc/cs178/projects/JT/aes.c 我的内存使用量是几百字节,二进制大小小于 3kb ROM。

我最好的建议是阅读维基百科页面http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation 并了解不同的模式,例如 OFB 模式中的 AES 如何利用 ECB 模式作为基本构建块。此外,XOR'ing(在 OFB 模式下)使其成为对称操作,因此加密/解密是相同的功能,也可以节省空间。

当我了解 AES 的真正工作原理时,我可以在 C 中实现它,然后根据 NIST 规范进行测试**(这样做!网上找到的很多代码都有缺陷),并且只实现我绝对需要的东西。

通过进行这种定制和优化,我能够将 AES128 与其他一些 RF 固件一起安装在 8051 上。RAM 使用量(整个系统)从约 2.5kb 下降到略低于 2kb,这意味着我们不必升级到具有 4kb SRAM 的 8051,但可以继续使用更便宜的 2kb SRAM 版本。

** 测试向量在附录 F 中:http ://csrc.nist.gov/publications/nistpubs/800-38a/addendum-to-nist_sp800-38A.pdf

编辑:

终于在 Github 上拿到了代码:https ://github.com/kokke/tiny-AES-c

我已经针对大小进行了一些优化。为 ARM 编译时的 GCC 大小输出:

$ arm-none-eabi-gcc -O2 -c aes.c -o aes.o
$ size aes.o
   text    data     bss     dec     hex filename
   1024       0     204    1228     4cc aes.o

所以资源使用现在是 1KB 代码,204 字节 RAM。

我不记得如何为 PIC 构建,但如果 8 位 AVR Atmel Mega16 与 PIC 类似,则资源使用情况为:

$ avr-gcc -Wall -Wextra -mmcu=atmega16 -O2 -c aes.c -o aes.o
$ avr-size aes.o
   text    data     bss     dec     hex filename
   1553       0     198    1751     6d7 aes.o

所以 1.5K 代码和 198 字节 RAM。

我最近采用了 axTLS 实现并尽可能地缩小它。您可以轻松地自己生成 S-box,并为自己节省数百字节。

static uint8_t aes_sbox[256];   /** AES S-box  */
static uint8_t aes_isbox[256];  /** AES iS-box */
void AES_generateSBox(void)
{
    uint32_t t[256], i;
    uint32_t x;
    for (i = 0, x = 1; i < 256; i ++)
    {
        t[i] = x;
        x ^= (x << 1) ^ ((x >> 7) * 0x11B);
    }

    aes_sbox[0] = 0x63;
    for (i = 0; i < 255; i ++)
    {
        x = t[255 - i];
        x |= x << 8;
        x ^= (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7);
        aes_sbox[t[i]] = (x ^ 0x63) & 0xFF;
    }
    for (i = 0; i < 256;i++)
    {
         aes_isbox[aes_sbox[i]]=i;
    }
}

您可以在以下网址获得完整的源代码:http ://ccodeblog.wordpress.com/2012/05/25/aes-implementation-in-300-lines-of-code/

我一直在用 C 语言进行实现,仅 AES-128,称为aes-min,具有 MIT 许可证。它针对具有少量 RAM/ROM 的小型微处理器(例如 8 位)。

它具有可选的动态密钥调度计算,以减少内存需求(避免需要在 RAM 中完全扩展密钥调度)。