4 ---------------------------------------------------------------------------
5 Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
9 The redistribution and use of this software (with or without changes)
10 is allowed without the payment of fees or royalties provided that:
12 1. source code distributions include the above copyright notice, this
13 list of conditions and the following disclaimer;
15 2. binary distributions include the above copyright notice, this list
16 of conditions and the following disclaimer in their documentation;
18 3. the name of the copyright holder is not used to endorse products
19 built using this software without specific written permission.
23 This software is provided 'as is' with no explicit or implied warranties
24 in respect of its properties, including, but not limited to, correctness
25 and/or fitness for purpose.
26 ---------------------------------------------------------------------------
29 This is an AES implementation that uses only 8-bit byte operations on the
30 cipher state (there are options to use 32-bit types if available).
32 The combination of mix columns and byte substitution used here is based on
33 that developed by Karl Malbrain. His contribution is acknowledged.
36 /* This version derived by Mark Tillotson 2012-01-23, tidied up, slimmed down
37 and tailored to 8-bit microcontroller abilities and Arduino datatypes.
39 The s-box and inverse s-box were retained as tables (0.5kB PROGMEM) but all
40 the other transformations are coded to save table space. Many efficiency
41 improvments to the routines mix_sub_columns() and inv_mix_sub_columns()
42 (mainly common sub-expression elimination).
44 Only the routines with precalculated subkey schedule are retained (together
45 with set_key() - this does however mean each AES object takes 240 bytes of
48 The CBC routines side-effect the iv argument (so that successive calls work
51 All the encryption and decryption routines work with plain == cipher for
52 in-place encryption, note.
57 /* functions for finite field multiplication in the AES Galois field */
59 /* code was modified by george spanos <spaniakos@gmail.com>
68 static const byte s_fwd [0x100] PROGMEM =
70 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
71 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
72 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
73 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
74 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
75 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
76 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
77 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
78 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
79 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
80 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
81 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
82 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
83 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
84 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
85 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
88 static const byte s_inv [0x100] PROGMEM =
90 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
91 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
92 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
93 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
94 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
95 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
96 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
97 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
98 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
99 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
100 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
101 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
102 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
103 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
104 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
105 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
108 // times 2 in the GF(2^8)
109 #define f2(x) ((x) & 0x80 ? (x << 1) ^ WPOLY : x << 1)
110 #define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
112 static byte s_box (byte x)
114 // return fwd_affine (pgm_read_byte (&inv [x])) ;
115 return pgm_read_byte (& s_fwd [x]) ;
119 static byte is_box (byte x)
121 // return pgm_read_byte (&inv [inv_affine (x)]) ;
122 return pgm_read_byte (& s_inv [x]) ;
126 static void xor_block (byte * d, byte * s)
128 for (byte i = 0 ; i < N_BLOCK ; i += 4)
130 *d++ ^= *s++ ; // some unrolling
137 static void copy_and_key (byte * d, byte * s, byte * k)
139 for (byte i = 0 ; i < N_BLOCK ; i += 4)
141 *d++ = *s++ ^ *k++ ; // some unrolling
148 // #define add_round_key(d, k) xor_block (d, k)
152 static void shift_sub_rows (byte st [N_BLOCK])
154 st [0] = s_box (st [0]) ; st [4] = s_box (st [4]) ;
155 st [8] = s_box (st [8]) ; st [12] = s_box (st [12]) ;
158 st [1] = s_box (st [5]) ; st [5] = s_box (st [9]) ;
159 st [9] = s_box (st [13]) ; st [13] = s_box (tt) ;
161 tt = st[2] ; st [2] = s_box (st [10]) ; st [10] = s_box (tt) ;
162 tt = st[6] ; st [6] = s_box (st [14]) ; st [14] = s_box (tt) ;
165 st [15] = s_box (st [11]) ; st [11] = s_box (st [7]) ;
166 st [7] = s_box (st [3]) ; st [3] = s_box (tt) ;
169 static void inv_shift_sub_rows (byte st[N_BLOCK])
171 st [0] = is_box (st[0]) ; st [4] = is_box (st [4]);
172 st [8] = is_box (st[8]) ; st [12] = is_box (st [12]);
175 st [13] = is_box (st [9]) ; st [9] = is_box (st [5]) ;
176 st [5] = is_box (st [1]) ; st [1] = is_box (tt) ;
178 tt = st [2] ; st [2] = is_box (st [10]) ; st [10] = is_box (tt) ;
179 tt = st [6] ; st [6] = is_box (st [14]) ; st [14] = is_box (tt) ;
182 st [3] = is_box (st [7]) ; st [7] = is_box (st [11]) ;
183 st [11] = is_box (st [15]) ; st [15] = is_box (tt) ;
186 /* SUB COLUMNS PHASE */
188 static void mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
193 for (byte i = 0 ; i < N_BLOCK ; i += N_COL)
196 byte b = st [j] ; j = (j+N_COL) & 15 ;
197 byte c = st [k] ; k = (k+N_COL) & 15 ;
198 byte d = st [l] ; l = (l+N_COL) & 15 ;
199 byte a1 = s_box (a), b1 = s_box (b), c1 = s_box (c), d1 = s_box (d) ;
200 byte a2 = f2(a1), b2 = f2(b1), c2 = f2(c1), d2 = f2(d1) ;
201 dt[i] = a2 ^ b2^b1 ^ c1 ^ d1 ;
202 dt[i+1] = a1 ^ b2 ^ c2^c1 ^ d1 ;
203 dt[i+2] = a1 ^ b1 ^ c2 ^ d2^d1 ;
204 dt[i+3] = a2^a1 ^ b1 ^ c1 ^ d2 ;
208 static void inv_mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
210 for (byte i = 0 ; i < N_BLOCK ; i += N_COL)
216 byte a2 = f2(a1), b2 = f2(b1), c2 = f2(c1), d2 = f2(d1) ;
217 byte a4 = f2(a2), b4 = f2(b2), c4 = f2(c2), d4 = f2(d2) ;
218 byte a8 = f2(a4), b8 = f2(b4), c8 = f2(c4), d8 = f2(d4) ;
219 byte a9 = a8 ^ a1,b9 = b8 ^ b1,c9 = c8 ^ c1,d9 = d8 ^ d1 ;
220 byte ac = a8 ^ a4,bc = b8 ^ b4,cc = c8 ^ c4,dc = d8 ^ d4 ;
222 dt[i] = is_box (ac^a2 ^ b9^b2 ^ cc^c1 ^ d9) ;
223 dt[(i+5)&15] = is_box (a9 ^ bc^b2 ^ c9^c2 ^ dc^d1) ;
224 dt[(i+10)&15] = is_box (ac^a1 ^ b9 ^ cc^c2 ^ d9^d2) ;
225 dt[(i+15)&15] = is_box (a9^a2 ^ bc^b1 ^ c9 ^ dc^d2) ;
229 /******************************************************************************/
232 byte ar_iv[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 };
234 memcpy(iv+8,ar_iv,8);
252 /******************************************************************************/
254 byte AES::set_key (byte key [], int keylen)
261 keylen = 16; // 10 rounds
266 keylen = 24; // 12 rounds
271 keylen = 32; // 14 rounds
278 hi = (round + 1) << 4 ;
279 copy_n_bytes (key_sched, key, keylen) ;
282 for (byte cc = keylen, rc = 1 ; cc < hi ; cc += N_COL)
284 for (byte i = 0 ; i < N_COL ; i++)
285 t[i] = key_sched [cc-4+i] ;
290 t[0] = s_box (t[1]) ^ rc ;
291 t[1] = s_box (t[2]) ;
292 t[2] = s_box (t[3]) ;
296 else if (keylen == 32 && (cc & 31) == 16)
298 for (byte i = 0 ; i < 4 ; i++)
299 t[i] = s_box (t[i]) ;
301 byte tt = cc - keylen ;
302 for (byte i = 0 ; i < N_COL ; i++)
303 key_sched [cc + i] = key_sched [tt + i] ^ t[i] ;
308 /******************************************************************************/
312 for (byte i = 0 ; i < KEY_SCHEDULE_BYTES ; i++)
317 /******************************************************************************/
319 void AES::copy_n_bytes (byte * d, byte * s, byte nn)
323 *d++ = *s++ ; // some unrolling
333 /******************************************************************************/
335 byte AES::encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK])
339 byte s1 [N_BLOCK], r ;
340 copy_and_key (s1, plain, (byte*) (key_sched)) ;
342 for (r = 1 ; r < round ; r++)
345 mix_sub_columns (s2, s1) ;
346 copy_and_key (s1, s2, (byte*) (key_sched + r * N_BLOCK)) ;
348 shift_sub_rows (s1) ;
349 copy_and_key (cipher, s1, (byte*) (key_sched + r * N_BLOCK)) ;
356 /******************************************************************************/
358 byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK])
362 xor_block (iv, plain) ;
363 if (encrypt (iv, iv) != SUCCESS)
365 copy_n_bytes (cipher, iv, N_BLOCK) ;
372 /******************************************************************************/
374 byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block)
378 xor_block (iv, plain) ;
379 if (encrypt (iv, iv) != SUCCESS)
381 copy_n_bytes (cipher, iv, N_BLOCK) ;
388 /******************************************************************************/
390 byte AES::decrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK])
395 copy_and_key (s1, plain, (byte*) (key_sched + round * N_BLOCK)) ;
396 inv_shift_sub_rows (s1) ;
398 for (byte r = round ; --r ; )
401 copy_and_key (s2, s1, (byte*) (key_sched + r * N_BLOCK)) ;
402 inv_mix_sub_columns (s1, s2) ;
404 copy_and_key (cipher, s1, (byte*) (key_sched)) ;
411 /******************************************************************************/
413 byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK])
418 copy_n_bytes (tmp, cipher, N_BLOCK) ;
419 if (decrypt (cipher, plain) != SUCCESS)
421 xor_block (plain, iv) ;
422 copy_n_bytes (iv, tmp, N_BLOCK) ;
429 /******************************************************************************/
431 byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block)
436 copy_n_bytes (tmp, cipher, N_BLOCK) ;
437 if (decrypt (cipher, plain) != SUCCESS)
439 xor_block (plain, iv) ;
440 copy_n_bytes (iv, tmp, N_BLOCK) ;
447 /*****************************************************************************/
449 void AES::set_IV(unsigned long long int IVCl){
451 memcpy(iv+8,&IVCl,8);
455 /******************************************************************************/
463 /******************************************************************************/
469 /******************************************************************************/
471 void AES::set_size(int sizel){
476 /******************************************************************************/
478 void AES::get_IV(byte *out){
480 memcpy(out+8,&IVC,8);
483 /******************************************************************************/
485 void AES::calc_size_n_pad(int p_size){
486 int s_of_p = p_size - 1;
487 if ( s_of_p % N_BLOCK == 0){
490 size = s_of_p + (N_BLOCK-(s_of_p % N_BLOCK));
495 /******************************************************************************/
497 void AES::padPlaintext(void* in,byte* out)
500 for (int i = size-pad; i < size; i++){;
501 out[i] = arr_pad[pad - 1];
505 /******************************************************************************/
507 bool AES::CheckPad(byte* in,int lsize){
508 if (in[lsize-1] <= 0x0f){
509 int lpad = (int)in[lsize-1];
510 for (int i = lsize - 1; i >= lsize-lpad; i--){
511 if (arr_pad[lpad - 1] != in[i]){
521 /******************************************************************************/
523 void AES::printArray(byte output[],bool p_pad)
526 uint8_t loops = size/N_BLOCK;
527 uint8_t outp = N_BLOCK;
528 for (j = 0; j < loops; j += 1){
529 if (p_pad && (j == (loops - 1)) ) { outp = N_BLOCK - pad; }
530 for (i = 0; i < outp; i++)
532 printf_P(PSTR("%c"),output[j*N_BLOCK + i]);
535 printf_P(PSTR("\n"));
538 /******************************************************************************/
540 void AES::printArray(byte output[],int sizel)
542 for (int i = 0; i < sizel; i++)
544 printf_P(PSTR("%x"),output[i]);
546 printf_P(PSTR("\n"));
550 /******************************************************************************/
552 void AES::do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits, byte ivl [N_BLOCK]){
553 calc_size_n_pad(size_p);
554 byte plain_p[get_size()];
555 padPlaintext(plain,plain_p);
556 int blocks = get_size() / N_BLOCK;
557 set_key (key, bits) ;
558 cbc_encrypt (plain_p, cipher, blocks, ivl);
561 /******************************************************************************/
563 void AES::do_aes_encrypt(byte *plain,int size_p,byte *cipher,byte *key, int bits){
564 calc_size_n_pad(size_p);
565 byte plain_p[get_size()];
566 padPlaintext(plain,plain_p);
567 int blocks = get_size() / N_BLOCK;
568 set_key (key, bits) ;
569 cbc_encrypt (plain_p, cipher, blocks);
572 /******************************************************************************/
574 void AES::do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits, byte ivl [N_BLOCK]){
576 int blocks = size_c / N_BLOCK;
578 cbc_decrypt (cipher,plain, blocks, ivl);
581 /******************************************************************************/
583 void AES::do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits){
585 int blocks = size_c / N_BLOCK;
587 cbc_decrypt (cipher,plain, blocks);
591 /******************************************************************************/
593 #if defined(AES_LINUX)
594 double AES::millis(){
595 gettimeofday(&tv, NULL);
596 return (tv.tv_sec + 0.000001 * tv.tv_usec);