]> AND Private Git Repository - Cipher_code.git/blob - SboxAES/IOT/aes.c
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
new hash version
[Cipher_code.git] / SboxAES / IOT / aes.c
1 /*
2
3 This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
4 Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
5
6 The implementation is verified against the test vectors in:
7   National Institute of Standards and Technology Special Publication 800-38A 2001 ED
8
9 ECB-AES128
10 ----------
11
12   plain-text:
13     6bc1bee22e409f96e93d7e117393172a
14     ae2d8a571e03ac9c9eb76fac45af8e51
15     30c81c46a35ce411e5fbc1191a0a52ef
16     f69f2445df4f9b17ad2b417be66c3710
17
18   key:
19     2b7e151628aed2a6abf7158809cf4f3c
20
21   resulting cipher
22     3ad77bb40d7a3660a89ecaf32466ef97 
23     f5d3d58503b9699de785895a96fdbaaf 
24     43b1cd7f598ece23881b00e3ed030688 
25     7b0c785e27e8ad3f8223207104725dd4 
26
27
28 NOTE:   String length must be evenly divisible by 16byte (str_len % 16 == 0)
29         You should pad the end of the string with zeros if this is not the case.
30         For AES192/256 the key size is proportionally larger.
31
32 */
33
34
35 /*****************************************************************************/
36 /* Includes:                                                                 */
37 /*****************************************************************************/
38 #include <stdint.h>
39 #include <string.h> // CBC mode, for memset
40 #include "aes.h"
41
42 /*****************************************************************************/
43 /* Defines:                                                                  */
44 /*****************************************************************************/
45 // The number of columns comprising a state in AES. This is a constant in AES. Value=4
46 #define Nb 4
47
48 #if defined(AES256) && (AES256 == 1)
49     #define Nk 8
50     #define Nr 14
51 #elif defined(AES192) && (AES192 == 1)
52     #define Nk 6
53     #define Nr 12
54 #else
55     #define Nk 4        // The number of 32 bit words in a key.
56     #define Nr 10       // The number of rounds in AES Cipher.
57 #endif
58
59 // jcallan@github points out that declaring Multiply as a function 
60 // reduces code size considerably with the Keil ARM compiler.
61 // See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
62 #ifndef MULTIPLY_AS_A_FUNCTION
63   #define MULTIPLY_AS_A_FUNCTION 0
64 #endif
65
66
67
68
69 /*****************************************************************************/
70 /* Private variables:                                                        */
71 /*****************************************************************************/
72 // state - array holding the intermediate results during decryption.
73 typedef uint8_t state_t[4][4];
74
75
76
77 // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
78 // The numbers below can be computed dynamically trading ROM for RAM - 
79 // This can be useful in (embedded) bootloader applications, where ROM is often limited.
80 static const uint8_t sbox[256] = {
81   //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
82   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
83   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
84   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
85   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
86   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
87   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
88   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
89   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
90   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
91   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
92   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
93   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
94   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
95   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
96   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
97   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
98
99 static  uint8_t My_sbox[256] = {
100   //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
101   0x63, 0x7c, 0x77, 0xb7, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
102   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
103   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
104   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
105   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
106   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
107   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
108   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
109   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
110   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
111   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
112   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
113   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
114   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
115   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
116   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
117
118
119 static const uint8_t rsbox[256] = {
120   0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
121   0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
122   0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
123   0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
124   0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
125   0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
126   0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
127   0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
128   0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
129   0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
130   0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
131   0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
132   0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
133   0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
134   0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
135   0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
136
137
138 // The round constant word array, Rcon[i], contains the values given by 
139 // x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
140 static const uint8_t Rcon[11] = {
141   0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
142
143 /*
144  * Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
145  * that you can remove most of the elements in the Rcon array, because they are unused.
146  *
147  * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
148  * 
149  * "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed), 
150  *  up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
151  */
152
153
154 /*****************************************************************************/
155 /* Private functions:                                                        */
156 /*****************************************************************************/
157 /*
158 static uint8_t getSBoxValue(uint8_t num)
159 {
160   return sbox[num];
161 }
162 */
163 #define getSBoxValue(num) (sbox[(num)])
164
165 #define My_getSBoxValue(num) (My_sbox[(num)])
166 /*
167 static uint8_t getSBoxInvert(uint8_t num)
168 {
169   return rsbox[num];
170 }
171 */
172 #define getSBoxInvert(num) (rsbox[(num)])
173
174
175 // This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. 
176 void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
177 {
178   unsigned i, j, k;
179   uint8_t tempa[4]; // Used for the column/row operations
180   
181   // The first round key is the key itself.
182   for (i = 0; i < Nk; ++i)
183   {
184     RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
185     RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
186     RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
187     RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
188   }
189
190   // All other round keys are found from the previous round keys.
191   for (i = Nk; i < Nb * (Nr + 1); ++i)
192   {
193     {
194       k = (i - 1) * 4;
195       tempa[0]=RoundKey[k + 0];
196       tempa[1]=RoundKey[k + 1];
197       tempa[2]=RoundKey[k + 2];
198       tempa[3]=RoundKey[k + 3];
199
200     }
201
202     if (i % Nk == 0)
203     {
204       // This function shifts the 4 bytes in a word to the left once.
205       // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
206
207       // Function RotWord()
208       {
209         k = tempa[0];
210         tempa[0] = tempa[1];
211         tempa[1] = tempa[2];
212         tempa[2] = tempa[3];
213         tempa[3] = k;
214       }
215
216       // SubWord() is a function that takes a four-byte input word and 
217       // applies the S-box to each of the four bytes to produce an output word.
218
219       // Function Subword()
220       {
221         tempa[0] = getSBoxValue(tempa[0]);
222         tempa[1] = getSBoxValue(tempa[1]);
223         tempa[2] = getSBoxValue(tempa[2]);
224         tempa[3] = getSBoxValue(tempa[3]);
225       }
226
227       tempa[0] = tempa[0] ^ Rcon[i/Nk];
228     }
229 #if defined(AES256) && (AES256 == 1)
230     if (i % Nk == 4)
231     {
232       // Function Subword()
233       {
234         tempa[0] = getSBoxValue(tempa[0]);
235         tempa[1] = getSBoxValue(tempa[1]);
236         tempa[2] = getSBoxValue(tempa[2]);
237         tempa[3] = getSBoxValue(tempa[3]);
238       }
239     }
240 #endif
241     j = i * 4; k=(i - Nk) * 4;
242     RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
243     RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
244     RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
245     RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
246   }
247 }
248
249 void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
250 {
251   KeyExpansion(ctx->RoundKey, key);
252 }
253 #if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
254 void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
255 {
256   KeyExpansion(ctx->RoundKey, key);
257   memcpy (ctx->Iv, iv, AES_BLOCKLEN);
258 }
259 void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
260 {
261   memcpy (ctx->Iv, iv, AES_BLOCKLEN);
262 }
263 #endif
264
265 // This function adds the round key to state.
266 // The round key is added to the state by an XOR function.
267 static void AddRoundKey(uint8_t round,state_t* state,uint8_t* RoundKey)
268 {
269   uint8_t i,j;
270   for (i = 0; i < 4; ++i)
271   {
272     for (j = 0; j < 4; ++j)
273     {
274       (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
275     }
276   }
277 }
278
279 // The SubBytes Function Substitutes the values in the
280 // state matrix with values in an S-box.
281 static void SubBytes(state_t* state)
282 {
283   uint8_t i, j;
284   for (i = 0; i < 4; ++i)
285   {
286     for (j = 0; j < 4; ++j)
287     {
288       (*state)[j][i] = getSBoxValue((*state)[j][i]);
289     }
290   }
291 }
292
293 // The SubBytes Function Substitutes the values in the
294 // state matrix with values in an S-box.
295 static void My_SubBytes(state_t* state)
296 {
297   uint8_t i, j;
298   for (i = 0; i < 4; ++i)
299   {
300     for (j = 0; j < 4; ++j)
301     {
302       (*state)[j][i] = My_getSBoxValue((*state)[j][i]);
303     }
304   }
305 }
306
307 // The ShiftRows() function shifts the rows in the state to the left.
308 // Each row is shifted with different offset.
309 // Offset = Row number. So the first row is not shifted.
310 static void ShiftRows(state_t* state)
311 {
312   uint8_t temp;
313
314   // Rotate first row 1 columns to left  
315   temp           = (*state)[0][1];
316   (*state)[0][1] = (*state)[1][1];
317   (*state)[1][1] = (*state)[2][1];
318   (*state)[2][1] = (*state)[3][1];
319   (*state)[3][1] = temp;
320
321   // Rotate second row 2 columns to left  
322   temp           = (*state)[0][2];
323   (*state)[0][2] = (*state)[2][2];
324   (*state)[2][2] = temp;
325
326   temp           = (*state)[1][2];
327   (*state)[1][2] = (*state)[3][2];
328   (*state)[3][2] = temp;
329
330   // Rotate third row 3 columns to left
331   temp           = (*state)[0][3];
332   (*state)[0][3] = (*state)[3][3];
333   (*state)[3][3] = (*state)[2][3];
334   (*state)[2][3] = (*state)[1][3];
335   (*state)[1][3] = temp;
336 }
337
338 static uint8_t xtime(uint8_t x)
339 {
340   return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
341 }
342
343 // MixColumns function mixes the columns of the state matrix
344 static void MixColumns(state_t* state)
345 {
346   uint8_t i;
347   uint8_t Tmp, Tm, t;
348   for (i = 0; i < 4; ++i)
349   {  
350     t   = (*state)[i][0];
351     Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
352     Tm  = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm);  (*state)[i][0] ^= Tm ^ Tmp ;
353     Tm  = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm);  (*state)[i][1] ^= Tm ^ Tmp ;
354     Tm  = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm);  (*state)[i][2] ^= Tm ^ Tmp ;
355     Tm  = (*state)[i][3] ^ t ;              Tm = xtime(Tm);  (*state)[i][3] ^= Tm ^ Tmp ;
356   }
357 }
358
359 // Multiply is used to multiply numbers in the field GF(2^8)
360 // Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
361 //       The compiler seems to be able to vectorize the operation better this way.
362 //       See https://github.com/kokke/tiny-AES-c/pull/34
363 #if MULTIPLY_AS_A_FUNCTION
364 static uint8_t Multiply(uint8_t x, uint8_t y)
365 {
366   return (((y & 1) * x) ^
367        ((y>>1 & 1) * xtime(x)) ^
368        ((y>>2 & 1) * xtime(xtime(x))) ^
369        ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
370        ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
371   }
372 #else
373 #define Multiply(x, y)                                \
374       (  ((y & 1) * x) ^                              \
375       ((y>>1 & 1) * xtime(x)) ^                       \
376       ((y>>2 & 1) * xtime(xtime(x))) ^                \
377       ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^         \
378       ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))   \
379
380 #endif
381
382 // MixColumns function mixes the columns of the state matrix.
383 // The method used to multiply may be difficult to understand for the inexperienced.
384 // Please use the references to gain more information.
385 static void InvMixColumns(state_t* state)
386 {
387   int i;
388   uint8_t a, b, c, d;
389   for (i = 0; i < 4; ++i)
390   { 
391     a = (*state)[i][0];
392     b = (*state)[i][1];
393     c = (*state)[i][2];
394     d = (*state)[i][3];
395
396     (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
397     (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
398     (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
399     (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
400   }
401 }
402
403
404 // The SubBytes Function Substitutes the values in the
405 // state matrix with values in an S-box.
406 static void InvSubBytes(state_t* state)
407 {
408   uint8_t i, j;
409   for (i = 0; i < 4; ++i)
410   {
411     for (j = 0; j < 4; ++j)
412     {
413       (*state)[j][i] = getSBoxInvert((*state)[j][i]);
414     }
415   }
416 }
417
418
419 static void InvShiftRows(state_t* state)
420 {
421   uint8_t temp;
422
423   // Rotate first row 1 columns to right  
424   temp = (*state)[3][1];
425   (*state)[3][1] = (*state)[2][1];
426   (*state)[2][1] = (*state)[1][1];
427   (*state)[1][1] = (*state)[0][1];
428   (*state)[0][1] = temp;
429
430   // Rotate second row 2 columns to right 
431   temp = (*state)[0][2];
432   (*state)[0][2] = (*state)[2][2];
433   (*state)[2][2] = temp;
434
435   temp = (*state)[1][2];
436   (*state)[1][2] = (*state)[3][2];
437   (*state)[3][2] = temp;
438
439   // Rotate third row 3 columns to right
440   temp = (*state)[0][3];
441   (*state)[0][3] = (*state)[1][3];
442   (*state)[1][3] = (*state)[2][3];
443   (*state)[2][3] = (*state)[3][3];
444   (*state)[3][3] = temp;
445 }
446
447
448 // Cipher is the main function that encrypts the PlainText.
449 static void Cipher(state_t* state, uint8_t* RoundKey)
450 {
451   uint8_t round = 0;
452
453   // Add the First round key to the state before starting the rounds.
454   AddRoundKey(0, state, RoundKey); 
455   
456   // There will be Nr rounds.
457   // The first Nr-1 rounds are identical.
458   // These Nr-1 rounds are executed in the loop below.
459   for (round = 1; round < Nr; ++round)
460   {
461     SubBytes(state);
462     ShiftRows(state);
463     MixColumns(state);
464     AddRoundKey(round, state, RoundKey);
465   }
466   
467   // The last round is given below.
468   // The MixColumns function is not here in the last round.
469   SubBytes(state);
470   ShiftRows(state);
471   AddRoundKey(Nr, state, RoundKey);
472 }
473
474
475 // Cipher is the main function that encrypts the PlainText.
476 static void My_Cipher(state_t* state, uint8_t* RoundKey)
477 {
478   uint8_t round = 0;
479
480   // Add the First round key to the state before starting the rounds.
481   AddRoundKey(0, state, RoundKey); 
482   
483   // There will be Nr rounds.
484   // The first Nr-1 rounds are identical.
485   // These Nr-1 rounds are executed in the loop below.
486   for (round = 1; round < Nr; ++round)
487   {
488     My_SubBytes(state);
489     ShiftRows(state);
490     MixColumns(state);
491     AddRoundKey(round, state, RoundKey);
492   }
493   
494   // The last round is given below.
495   // The MixColumns function is not here in the last round.
496   My_SubBytes(state);
497   ShiftRows(state);
498   AddRoundKey(Nr, state, RoundKey);
499 }
500
501 static void InvCipher(state_t* state,uint8_t* RoundKey)
502 {
503   uint8_t round = 0;
504
505   // Add the First round key to the state before starting the rounds.
506   AddRoundKey(Nr, state, RoundKey); 
507
508   // There will be Nr rounds.
509   // The first Nr-1 rounds are identical.
510   // These Nr-1 rounds are executed in the loop below.
511   for (round = (Nr - 1); round > 0; --round)
512   {
513     InvShiftRows(state);
514     InvSubBytes(state);
515     AddRoundKey(round, state, RoundKey);
516     InvMixColumns(state);
517   }
518   
519   // The last round is given below.
520   // The MixColumns function is not here in the last round.
521   InvShiftRows(state);
522   InvSubBytes(state);
523   AddRoundKey(0, state, RoundKey);
524 }
525
526
527
528 /*****************************************************************************/
529 /* Public functions:                                                         */
530 /*****************************************************************************/
531 #if defined(ECB) && (ECB == 1)
532
533
534 void AES_ECB_encrypt(struct AES_ctx *ctx,const uint8_t* buf)
535 {
536   // The next function call encrypts the PlainText with the Key using AES algorithm.
537   Cipher((state_t*)buf, ctx->RoundKey);
538 }
539
540 void AES_ECB_decrypt(struct AES_ctx* ctx,const uint8_t* buf)
541 {
542   // The next function call decrypts the PlainText with the Key using AES algorithm.
543   InvCipher((state_t*)buf, ctx->RoundKey);
544 }
545
546
547 #endif // #if defined(ECB) && (ECB == 1)
548
549
550
551
552
553 #if defined(CBC) && (CBC == 1)
554
555
556 static void XorWithIv(uint8_t* buf, uint8_t* Iv)
557 {
558   uint8_t i;
559   for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
560   {
561     buf[i] ^= Iv[i];
562   }
563 }
564
565 void AES_CBC_encrypt_buffer(struct AES_ctx *ctx,uint8_t* buf, uint32_t length)
566 {
567   uintptr_t i;
568   uint8_t *Iv = ctx->Iv;
569   for (i = 0; i < length; i += AES_BLOCKLEN)
570   {
571     XorWithIv(buf, Iv);
572     Cipher((state_t*)buf, ctx->RoundKey);
573     Iv = buf;
574     buf += AES_BLOCKLEN;
575     //printf("Step %d - %d", i/16, i);
576   }
577   /* store Iv in ctx for next call */
578   memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
579 }
580
581 void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf,  uint32_t length)
582 {
583   uintptr_t i;
584   uint8_t storeNextIv[AES_BLOCKLEN];
585   for (i = 0; i < length; i += AES_BLOCKLEN)
586   {
587     memcpy(storeNextIv, buf, AES_BLOCKLEN);
588     InvCipher((state_t*)buf, ctx->RoundKey);
589     XorWithIv(buf, ctx->Iv);
590     memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
591     buf += AES_BLOCKLEN;
592   }
593
594 }
595
596 #endif // #if defined(CBC) && (CBC == 1)
597
598
599
600 #if defined(CTR) && (CTR == 1)
601
602 /* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
603 void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
604 {
605   uint8_t buffer[AES_BLOCKLEN];
606   
607   unsigned i;
608   int bi;
609   for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
610   {
611     if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
612     {
613       
614       memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
615       Cipher((state_t*)buffer,ctx->RoundKey);
616
617       /* Increment Iv and handle overflow */
618       for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
619       {
620         /* inc will owerflow */
621         if (ctx->Iv[bi] == 255)
622         {
623           ctx->Iv[bi] = 0;
624           continue;
625         } 
626         ctx->Iv[bi] += 1;
627         break;   
628       }
629       bi = 0;
630     }
631
632     buf[i] = (buf[i] ^ buffer[bi]);
633   }
634 }
635
636 /* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
637 void My_AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
638 {
639   uint8_t buffer[AES_BLOCKLEN];
640   
641   unsigned i;
642   int bi;
643   for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
644   {
645     if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
646     {
647       
648       memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
649       My_Cipher((state_t*)buffer,ctx->RoundKey);
650
651       /* Increment Iv and handle overflow */
652       for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
653       {
654         /* inc will owerflow */
655         if (ctx->Iv[bi] == 255)
656         {
657           ctx->Iv[bi] = 0;
658           continue;
659         } 
660         ctx->Iv[bi] += 1;
661         break;   
662       }
663       bi = 0;
664     }
665
666     buf[i] = (buf[i] ^ buffer[bi]);
667   }
668 }
669
670
671
672
673
674
675
676 // This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. 
677 void My_KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
678 {
679   unsigned i, j, k;
680   uint8_t tempa[4]; // Used for the column/row operations
681   
682   // The first round key is the key itself.
683   for (i = 0; i < Nk; ++i)
684   {
685     RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
686     RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
687     RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
688     RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
689   }
690
691   // All other round keys are found from the previous round keys.
692   for (i = Nk; i < Nb * (Nr + 1); ++i)
693   {
694     {
695       k = (i - 1) * 4;
696       tempa[0]=RoundKey[k + 0];
697       tempa[1]=RoundKey[k + 1];
698       tempa[2]=RoundKey[k + 2];
699       tempa[3]=RoundKey[k + 3];
700
701     }
702
703     if (i % Nk == 0)
704     {
705       // This function shifts the 4 bytes in a word to the left once.
706       // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
707
708       // Function RotWord()
709       {
710         k = tempa[0];
711         tempa[0] = tempa[1];
712         tempa[1] = tempa[2];
713         tempa[2] = tempa[3];
714         tempa[3] = k;
715       }
716
717       // SubWord() is a function that takes a four-byte input word and 
718       // applies the S-box to each of the four bytes to produce an output word.
719
720       // Function Subword()
721       {
722         tempa[0] = getSBoxValue(tempa[0]);
723         tempa[1] = getSBoxValue(tempa[1]);
724         tempa[2] = getSBoxValue(tempa[2]);
725         tempa[3] = getSBoxValue(tempa[3]);
726       }
727
728       tempa[0] = tempa[0] ^ Rcon[i/Nk];
729     }
730 #if defined(AES256) && (AES256 == 1)
731     if (i % Nk == 4)
732     {
733       // Function Subword()
734       {
735         tempa[0] = getSBoxValue(tempa[0]);
736         tempa[1] = getSBoxValue(tempa[1]);
737         tempa[2] = getSBoxValue(tempa[2]);
738         tempa[3] = getSBoxValue(tempa[3]);
739       }
740     }
741 #endif
742     j = i * 4; k=(i - Nk) * 4;
743     RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
744     RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
745     RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
746     RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
747   }
748 }
749
750
751
752
753 void rc4key(unsigned char *key, int size_DK) {
754
755   for(int i=0;i<256;i++) {
756     My_sbox[i]=i;
757   }
758
759
760   unsigned char j0 = 0;
761   for(int i0=0; i0<256; i0++) {
762     j0 = (j0 + My_sbox[i0] + key[i0&(size_DK-1)] );
763     unsigned char tmp = My_sbox[i0];
764     My_sbox[i0] = My_sbox[j0 ];
765     My_sbox[j0] = tmp;
766   }
767 }
768
769
770
771
772
773
774
775
776
777
778
779
780
781 #endif // #if defined(CTR) && (CTR == 1)