]> AND Private Git Repository - Cipher_code.git/blob - Arduino/libraries/AES-master/AES.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
aze
[Cipher_code.git] / Arduino / libraries / AES-master / AES.cpp
1 #include "AES.h"
2
3 /*
4  ---------------------------------------------------------------------------
5  Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
6
7  LICENSE TERMS
8
9  The redistribution and use of this software (with or without changes)
10  is allowed without the payment of fees or royalties provided that:
11
12   1. source code distributions include the above copyright notice, this
13      list of conditions and the following disclaimer;
14
15   2. binary distributions include the above copyright notice, this list
16      of conditions and the following disclaimer in their documentation;
17
18   3. the name of the copyright holder is not used to endorse products
19      built using this software without specific written permission.
20
21  DISCLAIMER
22
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  ---------------------------------------------------------------------------
27  Issue 09/09/2006
28
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).
31
32  The combination of mix columns and byte substitution used here is based on
33  that developed by Karl Malbrain. His contribution is acknowledged.
34  */
35
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.
38
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).
43
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 
46    RAM, alas)
47
48    The CBC routines side-effect the iv argument (so that successive calls work
49    together correctly).
50
51    All the encryption and decryption routines work with plain == cipher for
52    in-place encryption, note.
53
54 */
55
56
57 /* functions for finite field multiplication in the AES Galois field    */
58
59 /* code was modified by george spanos <spaniakos@gmail.com>
60  * 16/12/14
61  */
62
63 // GF(2^8) stuff
64
65 #define WPOLY   0x011B
66 #define DPOLY   0x008D
67
68 static const byte s_fwd [0x100] PROGMEM =
69 {
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,
86 } ;
87
88 static const byte s_inv [0x100] PROGMEM =
89 {
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,
106 } ;
107
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))
111
112 static byte s_box (byte x)
113 {
114   //  return fwd_affine (pgm_read_byte (&inv [x])) ;
115   return pgm_read_byte (& s_fwd [x]) ;
116 }
117
118 // Inverse Sbox
119 static byte is_box (byte x)
120 {
121   // return pgm_read_byte (&inv [inv_affine (x)]) ;
122   return pgm_read_byte (& s_inv [x]) ;
123 }
124
125
126 static void xor_block (byte * d, byte * s)
127 {
128   for (byte i = 0 ; i < N_BLOCK ; i += 4)
129     {
130       *d++ ^= *s++ ;  // some unrolling
131       *d++ ^= *s++ ;
132       *d++ ^= *s++ ;
133       *d++ ^= *s++ ;
134     }
135 }
136
137 static void copy_and_key (byte * d, byte * s, byte * k)
138 {
139   for (byte i = 0 ; i < N_BLOCK ; i += 4)
140     {
141       *d++ = *s++ ^ *k++ ;  // some unrolling
142       *d++ = *s++ ^ *k++ ;
143       *d++ = *s++ ^ *k++ ;
144       *d++ = *s++ ^ *k++ ;
145     }
146 }
147
148 // #define add_round_key(d, k) xor_block (d, k)
149
150 /* SUB ROW PHASE */
151
152 static void shift_sub_rows (byte st [N_BLOCK])
153 {
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]) ;
156
157   byte tt = st [1] ;
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) ;
160
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) ;
163
164   tt = st[15] ;
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) ;
167 }
168
169 static void inv_shift_sub_rows (byte st[N_BLOCK])
170 {
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]);
173
174   byte tt = st[13] ;
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) ;
177
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) ;
180
181   tt = st [3] ;
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) ;
184 }
185
186 /* SUB COLUMNS PHASE */
187
188 static void mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
189 {
190   byte j = 5 ;
191   byte k = 10 ;
192   byte l = 15 ;
193   for (byte i = 0 ; i < N_BLOCK ; i += N_COL)
194     {
195       byte a = st [i] ;
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 ;
205     }
206 }
207
208 static void inv_mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
209 {
210   for (byte i = 0 ; i < N_BLOCK ; i += N_COL)
211     {
212       byte a1 = st [i] ;
213       byte b1 = st [i+1] ;
214       byte c1 = st [i+2] ;
215       byte d1 = st [i+3] ;
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 ;
221       
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) ;
226     }
227 }
228
229 /******************************************************************************/
230
231 AES::AES(){
232         byte ar_iv[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 };
233         memcpy(iv,ar_iv,8);
234         memcpy(iv+8,ar_iv,8);
235         arr_pad[0] = 0x01;
236         arr_pad[1] = 0x02;
237         arr_pad[2] = 0x03;
238         arr_pad[3] = 0x04;
239         arr_pad[4] = 0x05;
240         arr_pad[5] = 0x06;
241         arr_pad[6] = 0x07;
242         arr_pad[7] = 0x08;
243         arr_pad[8] = 0x09;
244         arr_pad[9] = 0x0a;
245         arr_pad[10] = 0x0b;
246         arr_pad[11] = 0x0c;
247         arr_pad[12] = 0x0d;
248         arr_pad[13] = 0x0e;
249         arr_pad[14] = 0x0f;
250 }
251
252 /******************************************************************************/
253
254 byte AES::set_key (byte key [], int keylen)
255 {
256   byte hi ;
257   switch (keylen)
258     {
259     case 16:
260     case 128: 
261       keylen = 16; // 10 rounds
262       round = 10 ;
263       break;
264     case 24:
265     case 192: 
266       keylen = 24; // 12 rounds
267       round = 12 ;
268       break;
269     case 32:
270     case 256: 
271       keylen = 32; // 14 rounds
272       round = 14 ;
273       break;
274     default: 
275       round = 0; 
276       return FAILURE;
277     }
278   hi = (round + 1) << 4 ;
279   copy_n_bytes (key_sched, key, keylen) ;
280   byte t[4] ;
281   byte next = keylen ;
282   for (byte cc = keylen, rc = 1 ; cc < hi ; cc += N_COL) 
283     {
284       for (byte i = 0 ; i < N_COL ; i++)
285         t[i] = key_sched [cc-4+i] ;
286       if (cc == next)
287         {
288           next += keylen ;
289           byte ttt = t[0] ;
290           t[0] = s_box (t[1]) ^ rc ;
291           t[1] = s_box (t[2]) ;
292           t[2] = s_box (t[3]) ;
293           t[3] = s_box (ttt) ;
294           rc = f2 (rc) ;
295         }
296       else if (keylen == 32 && (cc & 31) == 16)
297         {
298           for (byte i = 0 ; i < 4 ; i++)
299             t[i] = s_box (t[i]) ;
300         }
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] ;
304     }
305   return SUCCESS ;
306 }
307
308 /******************************************************************************/
309
310 void AES::clean ()
311 {
312   for (byte i = 0 ; i < KEY_SCHEDULE_BYTES ; i++)
313     key_sched [i] = 0 ;
314   round = 0 ;
315 }
316
317 /******************************************************************************/
318
319 void AES::copy_n_bytes (byte * d, byte * s, byte nn)
320 {
321   while (nn >= 4)
322     {
323       *d++ = *s++ ;  // some unrolling
324       *d++ = *s++ ;
325       *d++ = *s++ ;
326       *d++ = *s++ ;
327       nn -= 4 ;
328     }
329   while (nn--)
330     *d++ = *s++ ;
331 }
332
333 /******************************************************************************/
334
335 byte AES::encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK])
336 {
337   if (round)
338     {
339       byte s1 [N_BLOCK], r ;
340       copy_and_key (s1, plain, (byte*) (key_sched)) ;
341
342       for (r = 1 ; r < round ; r++)
343         {  
344           byte s2 [N_BLOCK] ;
345           mix_sub_columns (s2, s1) ;
346           copy_and_key (s1, s2, (byte*) (key_sched + r * N_BLOCK)) ;
347         }
348       shift_sub_rows (s1) ;
349       copy_and_key (cipher, s1, (byte*) (key_sched + r * N_BLOCK)) ;
350     }
351   else
352     return FAILURE ;
353   return SUCCESS ;
354 }
355
356 /******************************************************************************/
357
358 byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOCK])
359 {
360   while (n_block--)
361     {
362       xor_block (iv, plain) ;
363       if (encrypt (iv, iv) != SUCCESS)
364         return FAILURE ;
365       copy_n_bytes (cipher, iv, N_BLOCK) ;
366       plain  += N_BLOCK ;
367       cipher += N_BLOCK ;
368     }
369   return SUCCESS ;
370 }
371
372 /******************************************************************************/
373
374 byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block)
375 {
376   while (n_block--)
377     {
378           xor_block (iv, plain) ;
379       if (encrypt (iv, iv) != SUCCESS)
380         return FAILURE ;
381       copy_n_bytes (cipher, iv, N_BLOCK) ;
382       plain  += N_BLOCK ;
383       cipher += N_BLOCK ;
384     }
385   return SUCCESS ;
386 }
387
388 /******************************************************************************/
389
390 byte AES::decrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK])
391 {
392   if (round)
393     {
394       byte s1 [N_BLOCK] ;
395       copy_and_key (s1, plain, (byte*) (key_sched + round * N_BLOCK)) ;
396       inv_shift_sub_rows (s1) ;
397
398       for (byte r = round ; --r ; )
399        {
400          byte s2 [N_BLOCK] ;
401          copy_and_key (s2, s1, (byte*) (key_sched + r * N_BLOCK)) ;
402          inv_mix_sub_columns (s1, s2) ;
403        }
404       copy_and_key (cipher, s1, (byte*) (key_sched)) ;
405     }
406   else
407     return FAILURE ;
408   return SUCCESS ;
409 }
410
411 /******************************************************************************/
412
413 byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK])
414 {   
415   while (n_block--)
416     {
417       byte tmp [N_BLOCK] ;
418       copy_n_bytes (tmp, cipher, N_BLOCK) ;
419       if (decrypt (cipher, plain) != SUCCESS)
420         return FAILURE ;
421       xor_block (plain, iv) ;
422       copy_n_bytes (iv, tmp, N_BLOCK) ;
423       plain  += N_BLOCK ;
424       cipher += N_BLOCK;
425     }
426   return SUCCESS ;
427 }
428
429 /******************************************************************************/
430
431 byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block)
432 {   
433   while (n_block--)
434     {
435       byte tmp [N_BLOCK] ;
436       copy_n_bytes (tmp, cipher, N_BLOCK) ;
437       if (decrypt (cipher, plain) != SUCCESS)
438         return FAILURE ;
439       xor_block (plain, iv) ;
440       copy_n_bytes (iv, tmp, N_BLOCK) ;
441       plain  += N_BLOCK ;
442       cipher += N_BLOCK;
443     }
444   return SUCCESS ;
445 }
446
447 /*****************************************************************************/
448
449 void AES::set_IV(unsigned long long int IVCl){
450         memcpy(iv,&IVCl,8);
451         memcpy(iv+8,&IVCl,8);
452         IVC = IVCl;
453 }
454
455 /******************************************************************************/
456
457 void AES::iv_inc(){
458         IVC += 1;
459         memcpy(iv,&IVC,8);
460         memcpy(iv+8,&IVC,8);
461 }
462
463 /******************************************************************************/
464
465 int AES::get_size(){
466         return size;
467 }
468
469 /******************************************************************************/
470
471 void AES::set_size(int sizel){
472         size = sizel;
473 }
474
475
476 /******************************************************************************/
477
478 void AES::get_IV(byte *out){
479         memcpy(out,&IVC,8);
480         memcpy(out+8,&IVC,8);
481 }
482
483 /******************************************************************************/
484
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){
488       size = s_of_p;
489         }else{
490                 size = s_of_p +  (N_BLOCK-(s_of_p % N_BLOCK));
491         }
492         pad = size - s_of_p;
493 }
494
495 /******************************************************************************/
496
497 void AES::padPlaintext(void* in,byte* out)
498 {
499         memcpy(out,in,size);
500         for (int i = size-pad; i < size; i++){;
501                 out[i] = arr_pad[pad - 1];
502         }
503 }
504
505 /******************************************************************************/
506
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]){
512                                 return false;
513                         }
514                 }
515         }else{
516                 return true;
517         }
518 return true;
519 }
520
521 /******************************************************************************/
522
523 void AES::printArray(byte output[],bool p_pad)
524 {
525 uint8_t i,j;
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++)
531   {
532     printf_P(PSTR("%d"),output[j*N_BLOCK + i]);
533   }
534 }
535   printf_P(PSTR("\n"));
536 }
537
538 /******************************************************************************/
539
540 void AES::printArray(byte output[],int sizel)
541 {
542   for (int i = 0; i < sizel; i++)
543   {
544     printf_P(PSTR("%x"),output[i]);
545   }
546   printf_P(PSTR("\n"));
547 }
548
549
550 /******************************************************************************/
551
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);
559 }
560
561 /******************************************************************************/
562
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);
570 }
571
572 /******************************************************************************/
573
574 void AES::do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits, byte ivl [N_BLOCK]){
575         set_size(size_c);
576         int blocks = size_c / N_BLOCK;
577         set_key (key, bits);
578         cbc_decrypt (cipher,plain, blocks, ivl);
579 }
580
581 /******************************************************************************/
582
583 void AES::do_aes_decrypt(byte *cipher,int size_c,byte *plain,byte *key, int bits){
584         set_size(size_c);
585         int blocks = size_c / N_BLOCK;
586         set_key (key, bits);
587         cbc_decrypt (cipher,plain, blocks);
588 }
589
590
591 /******************************************************************************/
592
593 #if defined(AES_LINUX)
594 double AES::millis(){
595         gettimeofday(&tv, NULL);
596         return (tv.tv_sec + 0.000001 * tv.tv_usec);
597 }
598 #endif