Implementasi AES terkecil untuk mikrokontroler?

38

Adakah yang bisa merekomendasikan implementasi AES-128 Rijndael yang kecil dan gratis untuk mikrokontroler. Idealnya, untuk PIC18, meskipun implementasi umum dalam C akan bermanfaat.

Mengkompilasi implementasi axTLS untuk PIC18 dan mengenkripsi / mendekripsi blok memerlukan 6KB ROM dan 750b RAM.

Mengkompilasi rijndael-alg-fst.c untuk PIC18 dan mengenkripsi / mendekripsi blok membutuhkan 28KB ROM dan 0,5KB RAM.

Mengkompilasi AES 8-bit Brian Gladman untuk PIC18 dan mengenkripsi / mendekripsi blok membutuhkan 19KB ROM dan 190 byte RAM.

Apakah ada varian spesifik PIC teroptimalkan yang lebih baik tersedia?

(Persyaratan RAM yang diperbarui untuk versi axTLS)

Toby Jaffey
sumber
1
Apakah ini untuk bootloader?
Daniel Grillo
Tidak, ini untuk aplikasi jaringan
Toby Jaffey
Microchip memiliki implementasi untuk dsPIC dan PIC 24 yang memiliki ukuran kode 3.018 byte, tetapi hanya memiliki enkripsi, tanpa dekripsi. Menebak ini tidak cocok untukmu.
Kellenjb
@Kellenjb Menarik, tapi saya sedang mencari sesuatu yang kecil untuk micros 8 bit
Toby Jaffey
1
@ mikeselectricstuff Ya, itu harus AES. Saya mencoba untuk beroperasi dengan sistem yang ada menggunakan AES-128. Saya tertarik pada implementasi AES kecil, tetapi saya saat ini menargetkan PIC18. Saya menggunakan kompiler HiTech Pro picc18.
Toby Jaffey

Jawaban:

19

Saya bertanya-tanya bagaimana Anda mendapatkan penggunaan RAM 7.5kB dengan axTLS. Melihat kode, semua konteks disimpan dalam struktur ini:

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;

Ukuran struktur ini adalah 2 + 2 + 4 * 15 * 8 + 16 = 504. Saya tidak melihat variabel global di aes.c, variabel otomatis semuanya kecil, jadi penggunaan tumpukan juga masuk akal. Jadi kemana 7.5kB pergi? Mungkin Anda mencoba menggunakan seluruh perpustakaan alih-alih hanya mengekstraksi implementasi AES dari itu?

Bagaimanapun, implementasi ini terlihat sangat sederhana, saya lebih suka tetap berpegang pada kode ini dan mencoba untuk mengoptimalkannya. Saya tahu ini bisa rumit, tetapi mempelajari detail AES dapat membantu Anda setidaknya untuk memperkirakan penggunaan RAM minimum absolut.

Pembaruan: Saya baru saja mencoba untuk mengkompilasi pustaka ini pada IA-32 Linux dan menulis tes enkripsi CBC AES-128 yang sederhana. Mendapat hasil berikut (angka pertama adalah hex panjang bagian):

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

Itu hanya 660 byte .bss (saya telah mendeklarasikan AES_CTX sebagai variabel global). Sebagian besar. Data ditempati oleh IV dan kunci. Saya tidak memasukkan .text di sini, karena Anda akan mendapatkan hasil yang sama sekali berbeda pada PIC (bagian data harus berukuran hampir sama pada kedua arsitektur).

Pelukis Kode
sumber
Saya salah membaca dengan faktor 10 pada versi axTLS. Kamu benar. Tapi, saya masih tertarik dengan versi AES yang lebih efisien ...
Toby Jaffey
5
Efisien dalam hal ukuran atau kecepatan? Apa kendala sebenarnya? Perlu diingat bahwa pustaka yang lebih kecil kemungkinan akan lebih lambat - jika Anda melihat ke dalam kode sumber pustaka yang lebih besar (dalam hal kode bagian), sebagian besar mengasapi adalah karena array konstan yang dihitung sebelumnya.
Pelukis Kode
1
Dalam hal RAM dan footprint ROM. Kecepatan bukan masalah, tapi saya ingin menjejalkan banyak fungsi ke perangkat kecil.
Toby Jaffey
14

Saya tahu pertanyaan ini agak lama, tetapi saya baru-baru ini harus meneliti sendiri karena saya menerapkan AES128 pada PIC16 dan 8051, dan jadi saya ingin tahu tentang pertanyaan ini juga.

Saya telah menggunakan sesuatu seperti ini: http://cs.ucsb.edu/~koc/cs178/projects/JT/aes.c dan penggunaan ram saya adalah beberapa ratus byte dan ukuran biner kurang dari 3kb ROM.

Saran saya yang terbaik adalah membaca di halaman Wikipedia http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation dan memahami mode yang berbeda, misalnya bagaimana AES dalam mode OFB menggunakan mode ECB menggunakan mode ECB sebagai blok bangunan dasar. Juga XOR'ing (dalam mode-OFB) menjadikannya operasi simetris, jadi mengenkripsi / mendekripsi adalah fungsi yang sama yang juga menghemat ruang.

Ketika saya mengerti bagaimana AES benar-benar bekerja, saya bisa mengimplementasikannya dalam C dan kemudian mengujinya terhadap spesifikasi NIST ** (lakukan ini! Banyak kode yang ditemukan online cacat) dan hanya menerapkan apa yang benar-benar saya butuhkan.

Saya dapat memuat AES128 pada 8051 bersama dengan beberapa firmware RF lainnya dengan melakukan penyesuaian dan pengoptimalan ini. Penggunaan RAM (untuk keseluruhan sistem) turun dari ~ 2.5kb menjadi tepat di bawah 2kb, artinya kita tidak perlu memutakhirkan ke 8051 dengan SRAM 4kb, tetapi tetap menggunakan versi SRAM 2kb yang lebih murah.

** Vektor Uji ada dalam Apendiks F di: http://csrc.nist.gov/publications/nistpubs/800-38a/addendum-to-nist_sp800-38A.pdf

EDIT:

Akhirnya mendapatkan kode di Github: https://github.com/kokke/tiny-AES-c

Saya telah mengoptimalkan sedikit untuk ukuran. Output ukuran GCC saat dikompilasi untuk 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

Jadi penggunaan sumber daya sekarang kode 1KB, 204 byte RAM.

Saya tidak ingat bagaimana membangun untuk PIC, tetapi jika 8bit AVR Atmel Mega16 sama seperti PIC, penggunaan sumber daya adalah:

$ 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

Jadi, kode 1,5 K dan RAM 198 byte.

Morten Jensen
sumber
Saya bertanya-tanya bagaimana implementasi yang saya buat pada tahun 2001 akan menumpuk. Itu tidak menghasilkan S-box; mereka statis.
Kaz
6

Saya baru-baru ini mengambil implementasi axTLS dan berusaha mengecilkannya sebanyak mungkin. Anda dapat dengan mudah membuat S-box sendiri dan menghemat beberapa ratus byte.

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

Anda dapat memperoleh sumber lengkap di: http://ccodeblog.wordpress.com/2012/05/25/aes-implementation-in-300-lines-of-code/

Andrew
sumber
Anda tahu barang-barang Anda, Andrew. Terpilih. : D
Alex
3

Saya telah melakukan implementasi di C, AES-128 saja, disebut aes-min , dengan lisensi MIT. Ini menargetkan mikroprosesor kecil (misalnya 8-bit) dengan sedikit RAM / ROM.

Ini memiliki perhitungan jadwal kunci on-the-fly opsional untuk mengurangi kebutuhan memori (menghindari kebutuhan jadwal kunci yang diperluas penuh dalam RAM).

Craig McQueen
sumber
1

Anda mungkin menemukan implementasi ini menarik. Ini dari open source AVR crypto-libary.

Anda dapat menemukan beberapa informasi umum dan statistik tentang ukuran kode dan kinerja di sini .

AES:

Informasi AES

Saya hanya bermain-main dengan sumber SHA-1 dari lib itu, jadi saya tidak bisa mengomentari AES.

Rev1.0
sumber
0

AES128 terkecil yang saya tulis untuk seri PIC dapat berjalan dalam 900 instruksi dan 42 byte RAM. Saya menggunakannya sendiri pada seri PIC12 tetapi PIC10F206 juga memungkinkan :-).

Saya tidak dapat mengungkapkan kode karena itu dari perusahaan saya tetapi saya menulisnya dalam bentuk asm untuk seri PIC10-12-16. Enkripsi membutuhkan 444 byte kode termasuk tabel lookup 256 byte, kode ini juga menyertakan fungsi load kunci yaitu sekitar 25 byte.

Saya akan semua menyarankan untuk memeriksa kertas AES dan mengimplementasikannya sendiri! Sebagian besar implementasi sangat buruk dan menggunakan banyak ram dan rom.

Saya juga menerapkan AES128 untuk dsPIC dan PIC24 dan menggunakan sekitar 70% lebih sedikit ruang kode dibandingkan dengan lib microchip dan kode saya juga sedikit lebih cepat. nomor implementasi dsPIC dan PIC24:

"Enkripsi membutuhkan sekitar 2995 siklus. 79.10uS @ 40 MIPS, 197.75uS @ 16 MIPS"

"DecKeySetup membutuhkan sekitar 567 siklus. 14.20uS @ 40 MIPS, 35.43uS @ 16 MIPS"

"Dekripsi membutuhkan sekitar 3886 siklus. 97.15uS @ 40 MIPS, 242.88uS @ 16 MIPS"

"Total ukuran kode adalah 1050 Kata termasuk tabel."

Keindahan tentang inti PIC24 adalah bahwa beberapa instruksi adalah 32 bit dan ini membuat hidup jauh lebih mudah untuk membangun implementasi AES128 kecil, kode saya menggunakan semua instruksi 32 bit yang tersedia dan benar-benar 32 bit dalam operasi sehingga saya dapat port kode dengan cepat untuk PIC32 atau cpu 32 bit lainnya.

AES sangat sederhana untuk diimplementasikan hanya kebanyakan orang tidak mencoba!

Lihat tautannya: http://www.cs.bc.edu/~straubin/cs381-05/blockciphers/rijndael_ingles2004.swf

PaulHolland
sumber
Apakah ini open source? Bisakah Anda memposting kode?
Toby Jaffey
2
@ Paul - Selamat Datang di Electrical Engingeering! Jawaban Anda menarik dan membesarkan hati, tetapi itu tidak benar-benar berguna tanpa lebih detail. 900 instruksi mungkin dapat ditampung dalam blok kode! Silakan lihat tautan "edit" di bawah jawaban untuk memperbaikinya.
Kevin Vermeer
@PaulHolland berita bagus, di mana kodenya?
Frank
2
@ Paul - Anda akan mendapatkan setumpuk upvotes alih-alih downvote yang Anda miliki jika Anda menjelaskan bagaimana Anda menulisnya dan memposting kode! Jika Anda tidak dapat memposting kode karena alasan lisensi, setidaknya jelaskan bagaimana Anda menulisnya dan bagaimana Joby dapat memparalelkan pekerjaan Anda.
Kevin Vermeer