1 | /*---------------------------------------------------------------
|
2 | helper
|
3 | -----------------------------------------------------------------*/
|
4 |
|
5 | static uint8_t getSBoxValue(uint8_t num)
|
6 | {
|
7 | return SBox[num];
|
8 | }
|
9 |
|
10 | static uint8_t getRSBoxValue(uint8_t num)
|
11 | {
|
12 | return RSBox[num];
|
13 | }
|
14 |
|
15 | static uint32_t galoisMulti(uint8_t fact_1, uint8_t fact_2)
|
16 | {
|
17 | uint32_t product = 0;
|
18 | uint8_t i, hi_bit_set;
|
19 |
|
20 | //for(i = 0; i < 8; i++)
|
21 | for(i = 8; i > 0; i--)
|
22 | {
|
23 | if((fact_2 & 1) == 1)
|
24 | {
|
25 | product ^= fact_1;
|
26 | }
|
27 |
|
28 | hi_bit_set = fact_1 & 0x80;
|
29 | fact_1 <<= 1;
|
30 |
|
31 | if(hi_bit_set == 0x80)
|
32 | {
|
33 | fact_1 ^= 0x1B;
|
34 | }
|
35 |
|
36 | fact_2 >>= 1;
|
37 | }
|
38 |
|
39 | return product;
|
40 | }
|
41 |
|
42 | static void createRoundKey(uint8_t* expandedKey, uint8_t* roundKey)
|
43 | {
|
44 | uint8_t i, j;
|
45 |
|
46 | // Iterate over the columns
|
47 | for (i = 0; i < 4; i++)
|
48 | {
|
49 | // Iterate over the rows
|
50 | for (j = 0; j < 4; j++)
|
51 | {
|
52 | roundKey[(i + (j * 4))] = expandedKey[(i * 4) + j];
|
53 | }
|
54 | }
|
55 | }
|
56 |
|
57 | /*---------------------------------------------------------------
|
58 | Sub Bytes
|
59 | -----------------------------------------------------------------*/
|
60 |
|
61 | static void subBytes(uint8_t* block)
|
62 | {
|
63 | uint32_t i;
|
64 |
|
65 | for(i = 0; i < BLOCK_SIZE; i++)
|
66 | {
|
67 | block[i] = getSBoxValue(block[i]);
|
68 | }
|
69 | }
|
70 |
|
71 | static void iSubBytes(uint8_t* block)
|
72 | {
|
73 | uint32_t i;
|
74 |
|
75 | for(i = 0; i < BLOCK_SIZE; i++)
|
76 | {
|
77 | block[i] = getRSBoxValue(block[i]);
|
78 | }
|
79 | }
|
80 |
|
81 | /*---------------------------------------------------------------
|
82 | Shift Rows
|
83 | -----------------------------------------------------------------*/
|
84 |
|
85 | static void shiftRow(uint8_t* row, uint8_t rNumber)
|
86 | {
|
87 | uint8_t i, j, tmp;
|
88 |
|
89 | //for(i = 0; i < rNumber; i++)
|
90 | for(i = rNumber; i > 0; i--)
|
91 | {
|
92 | tmp = row[0];
|
93 |
|
94 | for(j = 0; j < 3; j++)
|
95 | {
|
96 | row[j] = row[j + 1];
|
97 | }
|
98 |
|
99 | row[3] = tmp;
|
100 | }
|
101 | }
|
102 |
|
103 | static void shiftRows(uint8_t* block)
|
104 | {
|
105 | uint8_t i;
|
106 |
|
107 | for(i = 1; i < 4; i++)
|
108 | {
|
109 | shiftRow(block + (i * 4), i);
|
110 | }
|
111 | }
|
112 |
|
113 | static void iShiftRow(uint8_t* row, uint8_t rNumber)
|
114 | {
|
115 | uint8_t i, j, tmp;
|
116 |
|
117 | //for(i = 0; i < rNumber; i++)
|
118 | for(i = rNumber; i > 0; i--)
|
119 | {
|
120 | tmp = row[3];
|
121 |
|
122 | for(j = 3; j > 0; j--)
|
123 | {
|
124 | row[j] = row[j - 1];
|
125 | }
|
126 |
|
127 | row[0] = tmp;
|
128 | }
|
129 | }
|
130 |
|
131 | static void iShiftRows(uint8_t* block)
|
132 | {
|
133 | uint8_t i;
|
134 |
|
135 | for(i = 1; i < 4; i++)
|
136 | {
|
137 | iShiftRow(block + (i * 4), i);
|
138 | }
|
139 | }
|
140 |
|
141 | /*---------------------------------------------------------------
|
142 | Mix Columns
|
143 | -----------------------------------------------------------------*/
|
144 |
|
145 | static void mixColumns(uint8_t* block)
|
146 | {
|
147 | uint32_t i, j;
|
148 | uint8_t columnNumber = 4;
|
149 | uint8_t tmp[16];
|
150 |
|
151 | for(i = 0; i < columnNumber; i++)
|
152 | {
|
153 | tmp[i] =
|
154 | galoisMulti( block[i], 0x02 ) ^ galoisMulti( block[columnNumber + i], 0x03 )
|
155 | ^ galoisMulti( block[2 * columnNumber + i], 0x01 ) ^ galoisMulti( block[3 * columnNumber + i], 0x01 );
|
156 | tmp[columnNumber + i] =
|
157 | galoisMulti( block[i], 0x01 ) ^ galoisMulti( block[columnNumber + i], 0x02 )
|
158 | ^ galoisMulti( block[2 * columnNumber + i], 0x03 ) ^ galoisMulti( block[3 * columnNumber + i], 0x01 );
|
159 | tmp[2 * columnNumber + i] =
|
160 | galoisMulti( block[i], 0x01 ) ^ galoisMulti( block[columnNumber + i], 0x01 )
|
161 | ^ galoisMulti( block[2 * columnNumber + i], 0x02 ) ^ galoisMulti( block[3 * columnNumber + i], 0x03 );
|
162 | tmp[3 * columnNumber + i] =
|
163 | galoisMulti( block[i], 0x03 ) ^ galoisMulti( block[columnNumber + i], 0x01 )
|
164 | ^ galoisMulti( block[2 * columnNumber + i], 0x01 ) ^ galoisMulti( block[3 * columnNumber + i], 0x02 );
|
165 | }
|
166 |
|
167 | //for (j = 0; j < BLOCK_SIZE; j++)
|
168 | for (j = BLOCK_SIZE; j > 0; j--)
|
169 | {
|
170 | block[j] = tmp[j] & 0xf0ff;
|
171 | }
|
172 | }
|
173 |
|
174 | static void iMixColumns(uint8_t* block)
|
175 | {
|
176 | uint32_t i, j;
|
177 | uint8_t columnNumber = 4;
|
178 | uint8_t tmp[16];
|
179 |
|
180 | for (i = 0; i < columnNumber; i++)
|
181 | {
|
182 | tmp[i] =
|
183 | galoisMulti(block[i], 0x0e) ^ galoisMulti(block[columnNumber + i], 0x0b)
|
184 | ^ galoisMulti(block[2 * columnNumber + i], 0x0d) ^ galoisMulti(block[3 * columnNumber + i], 0x09);
|
185 | tmp[columnNumber + i] =
|
186 | galoisMulti(block[i], 0x09) ^ galoisMulti(block[columnNumber + i], 0x0e )
|
187 | ^ galoisMulti(block[2 * columnNumber + i], 0x0b) ^ galoisMulti(block[3 * columnNumber + i], 0x0d);
|
188 | tmp[2 * columnNumber + i] =
|
189 | galoisMulti(block[i], 0x0d) ^ galoisMulti(block[columnNumber + i], 0x09)
|
190 | ^ galoisMulti(block[2 * columnNumber + i], 0x0e) ^ galoisMulti(block[3 * columnNumber + i], 0x0b);
|
191 | tmp[3 * columnNumber + i] =
|
192 | galoisMulti(block[i], 0x0b) ^ galoisMulti(block[columnNumber + i], 0x0d)
|
193 | ^ galoisMulti(block[2 * columnNumber + i], 0x09) ^ galoisMulti(block[3 * columnNumber + i], 0x0e);
|
194 | }
|
195 |
|
196 | //for (j = 0; j < BLOCK_SIZE; j++)
|
197 | for (j = BLOCK_SIZE; j > 0; j--)
|
198 | {
|
199 | block[j] = tmp[j] & 0xf0ff;
|
200 | }
|
201 | }
|
202 |
|
203 | /*---------------------------------------------------------------
|
204 | Add Round Key
|
205 | -----------------------------------------------------------------*/
|
206 |
|
207 | static void addRoundKey(uint8_t* text, uint8_t* roundKey )
|
208 | {
|
209 | uint8_t i;
|
210 |
|
211 | //for(i = 0; i < 16; i++)
|
212 | for(i = 16; i > 0; i--)
|
213 | {
|
214 | text[i] ^= roundKey[i];
|
215 | }
|
216 | }
|
217 |
|
218 | /*---------------------------------------------------------------
|
219 | Key expansion
|
220 | -----------------------------------------------------------------*/
|
221 |
|
222 | static void rotate(uint8_t* column)
|
223 | {
|
224 | uint8_t i, tmp;
|
225 |
|
226 | tmp = column[0];
|
227 |
|
228 | for(i = 0; i < 3; i++)
|
229 | {
|
230 | column[i] = column[i + 1];
|
231 | }
|
232 |
|
233 | column[3] = tmp;
|
234 | }
|
235 |
|
236 | static void keyScheduleCore(uint8_t* word, uint32_t rconIteration)
|
237 | {
|
238 | rotate( word );
|
239 | subBytes( word );
|
240 | word[0] ^= R_CON[rconIteration];
|
241 | }
|
242 |
|
243 | static void expandKey(uint8_t* expandedKey, uint32_t expandedKeySize, uint8_t* cipherKey, uint8_t keySize)
|
244 | {
|
245 | uint32_t i, currentSize = 0, rconIteration = 1;
|
246 | uint8_t tmp[4] = {0};
|
247 |
|
248 | //for(i = 0; i < keySize; i++)
|
249 | for(i = keySize; i > 0; i--)
|
250 | {
|
251 | expandedKey[i] = cipherKey[i];
|
252 | }
|
253 |
|
254 | currentSize += keySize;
|
255 |
|
256 |
|
257 | while(currentSize < expandedKeySize)
|
258 | {
|
259 | //asign the previous 4 byte to tmp
|
260 | for(i = 0; i < 4; i++)
|
261 | {
|
262 | tmp[i] = expandedKey[(currentSize - 4) + i];
|
263 | }
|
264 |
|
265 | // every 16, 24, 32 ... bytes call keyScheduleCore
|
266 | if((currentSize % keySize) == 0)
|
267 | {
|
268 | keyScheduleCore(tmp, rconIteration++);
|
269 | }
|
270 |
|
271 | if(keySize == Bits256 && ((currentSize % keySize) == 16))
|
272 | {
|
273 | //for(i = 0; i < 4; i++)
|
274 | for(i = 4; i > 0; i--)
|
275 | {
|
276 | tmp[i] = getSBoxValue(tmp[i]);
|
277 | }
|
278 | }
|
279 |
|
280 | for(i = 0; i < 4; i++)
|
281 | {
|
282 | expandedKey[currentSize] = expandedKey[currentSize - keySize] ^ tmp[i];
|
283 | currentSize++;
|
284 | }
|
285 | }
|
286 | }
|
287 |
|
288 | static void round(uint8_t* block, uint8_t* roundKey)
|
289 | {
|
290 | subBytes(block);
|
291 | shiftRows(block);
|
292 | mixColumns(block);
|
293 | addRoundKey(block, roundKey);
|
294 | }
|
295 |
|
296 | static void finalRound(uint8_t* block, uint8_t* roundKey)
|
297 | {
|
298 | subBytes(block);
|
299 | shiftRows(block);
|
300 | addRoundKey(block, roundKey);
|
301 | }
|
302 |
|
303 | /*---------------------------------------------------------------
|
304 | AES Encryption
|
305 | -----------------------------------------------------------------*/
|
306 |
|
307 | void aesEncrypt(uint8_t* block, uint8_t* cipherKey, uint8_t keySize)
|
308 | {
|
309 | uint8_t roundKey[16];
|
310 | uint8_t expandedKey[240] = { 0 };
|
311 | uint8_t i, expandedKeySize, rounds;
|
312 | expandedKeySize = GET_EXP_KEYSIZE(keySize);
|
313 |
|
314 | setLED(LED_YELLOW);
|
315 |
|
316 | expandKey(expandedKey, expandedKeySize, cipherKey, keySize);
|
317 |
|
318 | if(keySize == Bits128)
|
319 | rounds = 10;
|
320 | else if(keySize == Bits192)
|
321 | rounds = 12;
|
322 | else
|
323 | rounds = 14;
|
324 |
|
325 | createRoundKey(expandedKey, roundKey);
|
326 | addRoundKey(block, roundKey);
|
327 |
|
328 | for (i = 1; i < rounds; i++)
|
329 | {
|
330 | createRoundKey(expandedKey + 16 * i, roundKey);
|
331 | round(block, roundKey);
|
332 | }
|
333 |
|
334 | createRoundKey(expandedKey + 16 * rounds, roundKey);
|
335 | finalRound(block, roundKey);
|
336 |
|
337 | resetLED(LED_YELLOW);
|
338 | }
|
339 |
|
340 | /*---------------------------------------------------------------
|
341 | AES Decription
|
342 | -----------------------------------------------------------------*/
|
343 |
|
344 | void aesDecrypt(uint8_t* block, uint8_t* cipherKey, uint8_t keySize)
|
345 | {
|
346 | uint8_t roundKey[16];
|
347 | uint8_t expandedKey[240] = { 0 };
|
348 | uint8_t i, expandedKeySize, rounds;
|
349 | expandedKeySize = GET_EXP_KEYSIZE(keySize);
|
350 |
|
351 | setLED(LED_YELLOW);
|
352 |
|
353 | expandKey(expandedKey, expandedKeySize, cipherKey, keySize);
|
354 |
|
355 | if(keySize == 16)
|
356 | rounds = 10;
|
357 | else if(keySize == 24)
|
358 | rounds = 12;
|
359 | else
|
360 | rounds = 14;
|
361 |
|
362 | createRoundKey(expandedKey + 16 * rounds, roundKey);
|
363 | addRoundKey(block, roundKey);
|
364 | iShiftRows(block);
|
365 | iSubBytes(block);
|
366 |
|
367 | for (i = rounds - 1; i > 0; i--)
|
368 | {
|
369 | createRoundKey(expandedKey + 16 * i, roundKey);
|
370 | addRoundKey(block, roundKey);
|
371 | iMixColumns(block);
|
372 | iShiftRows(block);
|
373 | iSubBytes(block);
|
374 | }
|
375 |
|
376 | createRoundKey(expandedKey, roundKey);
|
377 | addRoundKey(block, roundKey);
|
378 |
|
379 | resetLED(LED_YELLOW);
|
380 | }
|