Menor implementação de AES para microcontroladores?

38

Alguém pode recomendar uma implementação pequena e gratuita do AES-128 Rijndael para microcontroladores. Idealmente, para o PIC18, embora uma implementação geral em C seja útil.

Compilando a implementação do axTLS para o PIC18 e criptografar / descriptografar um bloco requer 6KB de ROM e 750b de RAM.

Compilar rijndael-alg-fst.c para PIC18 e criptografar / descriptografar um bloco requer 28 KB de ROM e 0.5 KB de RAM.

Compilar o AES de 8 bits de Brian Gladman para PIC18 e criptografar / descriptografar um bloco requer 19 KB de ROM e 190 bytes de RAM.

Existem variantes específicas de PIC melhor otimizadas disponíveis?

(requisitos atualizados de RAM para a versão axTLS)

Toby Jaffey
fonte
1
Isso é para bootloader?
Daniel Grillo
Não, é para um aplicativo de rede
Toby Jaffey
O microchip possui uma implementação para dsPIC e PIC 24, que possui um tamanho de código de 3.018 bytes, mas só tinha criptografia, sem descriptografia. Adivinhar que isso não serve para você.
Kellenjb
@Kellenjb Interessante, mas eu estou procurando algo pequeno para 8 micros bit
Toby Jaffey
1
@mikeselectricstuff Sim, ele precisa ser AES. Estou tentando interoperar com um sistema existente usando o AES-128. Estou interessado em qualquer pequena implementação do AES, mas atualmente estou direcionando o PIC18. Estou usando o compilador HiTech Pro picc18.
precisa saber é o seguinte

Respostas:

19

Gostaria de saber como você conseguiu 7,5 kB de uso de RAM com o axTLS. Observando o código, todo o contexto é armazenado nesta estrutura:

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;

O tamanho dessa estrutura é 2 + 2 + 4 * 15 * 8 + 16 = 504. Não vejo variáveis ​​globais no aes.c, as variáveis ​​automáticas são todas pequenas, portanto o uso da pilha também é razoável. Então, para onde vão 7,5kB? Talvez você esteja tentando usar a biblioteca inteira em vez de apenas extrair a implementação do AES dela?

De qualquer forma, essa implementação parece bem simples. Prefiro seguir esse código e tentar otimizá-lo. Sei que pode ser complicado, mas aprender os detalhes do AES pode ajudá-lo a estimar pelo menos o uso mínimo absoluto de RAM.

Atualização: Eu apenas tentei compilar esta biblioteca no IA-32 Linux e escrever um simples teste de criptografia CBC AES-128. Obteve os seguintes resultados (o primeiro número é o hexadecimal do comprimento da seção):

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

São apenas 660 bytes de .bss (declarei AES_CTX como uma variável global). A maioria dos .data é ocupada por IV e chave. Não incluo .text aqui, pois você obterá resultados totalmente diferentes no PIC (as seções de dados devem ter quase o mesmo tamanho nas duas arquiteturas).

Pintores de código
fonte
Eu interpretei errado por um fator de 10 na versão do axTLS. Você está certo. Mas, eu ainda estou interessado em versões mais eficientes de AES ...
Toby Jaffey
5
Eficiente em termos de tamanho ou velocidade? Quais são as restrições, na verdade? Lembre-se de que as bibliotecas menores provavelmente serão mais lentas - se você examinar o código-fonte das bibliotecas maiores (em termos de seção de código), a maior parte do inchaço deve-se a matrizes constantes pré-calculadas.
Código Pintores
1
Em termos de pegada de RAM e ROM. A velocidade não é um problema, mas pretendo incluir muitas funcionalidades em um dispositivo pequeno.
Toby Jaffey
14

Sei que essa pergunta é um pouco antiga, mas recentemente tive que pesquisá-la quando estou implementando o AES128 em um PIC16 e um 8051, e também fiquei curioso sobre essa questão.

Eu usei algo como isto: http://cs.ucsb.edu/~koc/cs178/projects/JT/aes.c e meu uso de memória ram é de algumas centenas de bytes e o tamanho binário é menor que 3kb de ROM.

Meu melhor conselho é ler na página da Wikipedia http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation e entender os diferentes modos, por exemplo, como o AES no modo OFB meio que utiliza o modo ECB como um componente básico. Além disso, o XOR'ing (no modo OFB) o torna uma operação simétrica; portanto, criptografar / descriptografar é a mesma função que também economiza espaço.

Quando entendi como o AES realmente funcionava, eu poderia implementá-lo em C e testá-lo com a especificação NIST ** (faça isso! Muito código encontrado on-line é defeituoso) e apenas implemente o que eu absolutamente precisava.

Consegui encaixar o AES128 em um 8051, juntamente com outros firmware de RF, fazendo essa personalização e otimização. O uso da RAM (para todo o sistema) caiu de ~ 2,5kb para pouco menos de 2kb, o que significa que não precisamos atualizar para um 8051 com SRAM de 4kb, mas poderíamos continuar usando a versão SRAM de 2kb mais barata.

** Os vetores de teste estão no Apêndice F em: http://csrc.nist.gov/publications/nistpubs/800-38a/addendum-to-nist_sp800-38A.pdf

EDITAR:

Finalmente recebi o código no Github: https://github.com/kokke/tiny-AES-c

Otimizei um pouco o tamanho. Saída de tamanho do GCC quando compilada para ARM:

$ 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

Portanto, o uso de recursos agora é um código de 1 KB, 204 bytes de RAM.

Não me lembro de como criar para o PIC, mas se o AVR Atmel Mega16 de 8 bits for semelhante ao PIC, o uso de recursos será:

$ 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

Então, código de 1.5K e 198 bytes de RAM.

Morten Jensen
fonte
Eu me pergunto como uma implementação que eu fiz em 2001 seria empilhável. Não gera as caixas S; eles são estáticos.
Kaz
6

Recentemente, peguei a implementação do axTLS e trabalhei em reduzi-la o máximo que pude. Você pode gerar as S-boxes facilmente e economizar algumas centenas de bytes.

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;
    }
}

Você pode obter a fonte completa em: http://ccodeblog.wordpress.com/2012/05/25/aes-implementation-in-300-lines-of-code/

Andrew
fonte
Você conhece suas coisas, Andrew. Votado. : D
Alex
3

Eu tenho feito uma implementação em C, somente AES-128, chamada aes-min , com licença MIT. Ele tem como alvo pequenos microprocessadores (por exemplo, 8 bits) com pouca RAM / ROM.

Possui cálculo de agendamento de teclas on-the-fly opcional para reduzir os requisitos de memória (evitando a necessidade de agendamento de teclas expandido completo na RAM).

Craig McQueen
fonte
1

Você pode achar essa implementação interessante. É de um criptografário AVR de código aberto.

Você pode encontrar algumas informações e estatísticas gerais (desatualizadas) sobre tamanho e desempenho do código aqui .

AES:

Informações AES

Eu só brinquei com a fonte SHA-1 dessa lib, então não posso comentar sobre o AES.

Rev1.0
fonte
0

O menor AES128 que escrevi para a série PIC pode ser executado em 900 instruções e 42 bytes de RAM. Eu mesmo o uso na série PIC12, mas também é possível o PIC10F206 :-).

Não posso divulgar o código da minha empresa, mas escrevi em ASM para a série PIC10-12-16. A criptografia ocupa 444 bytes de código, incluindo a tabela de pesquisa de 256 bytes, esse código também inclui a função de carregamento de chave, que é de cerca de 25 bytes.

Gostaria de dar todos os conselhos para verificar o documento da AES e implementá-lo você mesmo! A maioria das implementações é muito ruim e usa muito ram e rom.

Também implementei o AES128 para o dsPIC e o PIC24 e uso cerca de 70% menos espaço de código em comparação com a lib do microchip e meu código também é um pouco mais rápido. Números de implementação dsPIC e PIC24:

"A criptografia leva cerca de 2995 ciclos. 79,10uS a 40 MIPS, 197.75uS a 16 MIPS"

"O DecKeySetup leva cerca de 567 ciclos. 14.20uS a 40 MIPS, 35.43uS a 16 MIPS"

"A descriptografia leva cerca de 3886 ciclos. 97,15 uS a 40 MIPS, 242,88 uS a 16 MIPS"

"O tamanho total do código é 1050 Palavras, incluindo tabelas."

A beleza do núcleo do PIC24 é que algumas instruções são de 32 bits e isso facilita muito a vida da criação de uma pequena implementação do AES128, meu código usa todas as instruções de 32 bits disponíveis e está completamente em operação de 32 bits para que eu possa portar o código rapidamente para PIC32 ou outros processadores de 32 bits.

AES é muito simples de implementar, apenas a maioria das pessoas nem tenta!

Veja o link: http://www.cs.bc.edu/~straubin/cs381-05/blockciphers/rijndael_ingles2004.swf

PaulHolland
fonte
É de código aberto? Você pode postar o código?
21411 Toby Jaffey
2
@Paul - Bem-vindo ao Engingeering elétrico! Sua resposta é interessante e encorajadora, mas não é realmente útil sem mais detalhes. 900 instruções provavelmente poderiam caber em um bloco de código! Por favor, veja o link "editar" abaixo da resposta para melhorá-lo.
21711 Kevin Vermeer
@PaulHolland ótimas notícias, onde está o código?
19411 Frank
2
@ Paul - Você estaria recebendo uma pilha de votos em vez dos votos negativos que você tem atualmente se explicasse como o escreveu e publicou o código! Se você não puder publicar o código por motivos de licença, pelo menos explique como o escreveu e como Joby poderia ser paralelo ao seu trabalho.
21711 Kevin Vermeer