Pick three bugfixes from next branch to trunk for inclusion in 4.5.0 RC2, as discusse...
[sdcc.git] / sdcc / support / regression / tests / tinyaes.c.in
blobaaae962b8e4df693854d3d44213e3ea152d52023
1 /*
2 tinyaes.c
3 mode: CBC, ECB, CTR
4 keylen: 128, 192, 256
5 AES cipher
7 Test uses the implementation from tinyaes.
8 */
10 #include <testfwk.h>
12 #if !defined(__SDCC_pdk13) && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) && !defined(__SDCC_mcs51) && !( (defined (__SDCC_mos6502) || defined(__SDCC_mos65c02 )) && defined(__SDCC_STACK_AUTO) ) // Lack of memory
13 #define {mode} 1
14 #define AES{keylen} 1
17 This is free and unencumbered software released into the public domain.
19 Anyone is free to copy, modify, publish, use, compile, sell, or
20 distribute this software, either in source code form or as a compiled
21 binary, for any purpose, commercial or non-commercial, and by any
22 means.
24 In jurisdictions that recognize copyright laws, the author or authors
25 of this software dedicate any and all copyright interest in the
26 software to the public domain. We make this dedication for the benefit
27 of the public at large and to the detriment of our heirs and
28 successors. We intend this dedication to be an overt act of
29 relinquishment in perpetuity of all present and future rights to this
30 software under copyright law.
32 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
35 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
36 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
37 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
38 OTHER DEALINGS IN THE SOFTWARE.
40 For more information, please refer to <http://unlicense.org/>
43 #include <stdint.h>
44 #include <stddef.h>
46 #define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only
48 #if defined(AES256) && (AES256 == 1)
49 #define AES_KEYLEN 32
50 #define AES_keyExpSize 240
51 #elif defined(AES192) && (AES192 == 1)
52 #define AES_KEYLEN 24
53 #define AES_keyExpSize 208
54 #else
55 #define AES_KEYLEN 16 // Key length in bytes
56 #define AES_keyExpSize 176
57 #endif
59 struct AES_ctx
61 uint8_t RoundKey[AES_keyExpSize];
62 #if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
63 uint8_t Iv[AES_BLOCKLEN];
64 #endif
67 void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
68 #if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
69 void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
70 void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
71 #endif
73 #if defined(ECB) && (ECB == 1)
74 // buffer size is exactly AES_BLOCKLEN bytes;
75 // you need only AES_init_ctx as IV is not used in ECB
76 // NB: ECB is considered insecure for most uses
77 void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
78 void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
80 #endif // #if defined(ECB) && (ECB == !)
83 #if defined(CBC) && (CBC == 1)
84 // buffer size MUST be mutile of AES_BLOCKLEN;
85 // Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
86 // NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
87 // no IV should ever be reused with the same key
88 void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
89 void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
91 #endif // #if defined(CBC) && (CBC == 1)
94 #if defined(CTR) && (CTR == 1)
96 // Same function for encrypting as for decrypting.
97 // IV is incremented for every block, and used after encryption as XOR-compliment for output
98 // Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
99 // NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
100 // no IV should ever be reused with the same key
101 void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
103 #endif // #if defined(CTR) && (CTR == 1)
105 #include <string.h> // CBC mode, for memset
107 /*****************************************************************************/
108 /* Defines: */
109 /*****************************************************************************/
110 // The number of columns comprising a state in AES. This is a constant in AES. Value=4
111 #define Nb 4
113 #if defined(AES256) && (AES256 == 1)
114 #define Nk 8
115 #define Nr 14
116 #elif defined(AES192) && (AES192 == 1)
117 #define Nk 6
118 #define Nr 12
119 #else
120 #define Nk 4 // The number of 32 bit words in a key.
121 #define Nr 10 // The number of rounds in AES Cipher.
122 #endif
124 // jcallan@github points out that declaring Multiply as a function
125 // reduces code size considerably with the Keil ARM compiler.
126 // See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
127 #ifndef MULTIPLY_AS_A_FUNCTION
128 #define MULTIPLY_AS_A_FUNCTION 0
129 #endif
134 /*****************************************************************************/
135 /* Private variables: */
136 /*****************************************************************************/
137 // state - array holding the intermediate results during decryption.
138 typedef uint8_t state_t[4][4];
142 // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
143 // The numbers below can be computed dynamically trading ROM for RAM -
144 // This can be useful in (embedded) bootloader applications, where ROM is often limited.
145 static const uint8_t sbox[256] = {
146 //0 1 2 3 4 5 6 7 8 9 A B C D E F
147 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
148 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
149 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
150 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
151 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
152 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
153 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
154 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
155 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
156 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
157 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
158 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
159 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
160 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
161 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
162 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
164 #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
165 static const uint8_t rsbox[256] = {
166 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
167 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
168 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
169 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
170 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
171 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
172 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
173 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
174 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
175 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
176 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
177 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
178 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
179 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
180 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
181 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
182 #endif
184 // The round constant word array, Rcon[i], contains the values given by
185 // x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
186 static const uint8_t Rcon[11] = {
187 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
190 * Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
191 * that you can remove most of the elements in the Rcon array, because they are unused.
193 * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
195 * "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed),
196 * up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
200 /*****************************************************************************/
201 /* Private functions: */
202 /*****************************************************************************/
204 static uint8_t getSBoxValue(uint8_t num)
206 return sbox[num];
209 #define getSBoxValue(num) (sbox[(num)])
211 // This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
212 static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
214 unsigned i, j, k;
215 uint8_t tempa[4]; // Used for the column/row operations
217 // The first round key is the key itself.
218 for (i = 0; i < Nk; ++i)
220 RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
221 RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
222 RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
223 RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
226 // All other round keys are found from the previous round keys.
227 for (i = Nk; i < Nb * (Nr + 1); ++i)
230 k = (i - 1) * 4;
231 tempa[0]=RoundKey[k + 0];
232 tempa[1]=RoundKey[k + 1];
233 tempa[2]=RoundKey[k + 2];
234 tempa[3]=RoundKey[k + 3];
238 if (i % Nk == 0)
240 // This function shifts the 4 bytes in a word to the left once.
241 // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
243 // Function RotWord()
245 const uint8_t u8tmp = tempa[0];
246 tempa[0] = tempa[1];
247 tempa[1] = tempa[2];
248 tempa[2] = tempa[3];
249 tempa[3] = u8tmp;
252 // SubWord() is a function that takes a four-byte input word and
253 // applies the S-box to each of the four bytes to produce an output word.
255 // Function Subword()
257 tempa[0] = getSBoxValue(tempa[0]);
258 tempa[1] = getSBoxValue(tempa[1]);
259 tempa[2] = getSBoxValue(tempa[2]);
260 tempa[3] = getSBoxValue(tempa[3]);
263 tempa[0] = tempa[0] ^ Rcon[i/Nk];
265 #if defined(AES256) && (AES256 == 1)
266 if (i % Nk == 4)
268 // Function Subword()
270 tempa[0] = getSBoxValue(tempa[0]);
271 tempa[1] = getSBoxValue(tempa[1]);
272 tempa[2] = getSBoxValue(tempa[2]);
273 tempa[3] = getSBoxValue(tempa[3]);
276 #endif
277 j = i * 4; k=(i - Nk) * 4;
278 RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
279 RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
280 RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
281 RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
285 void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
287 KeyExpansion(ctx->RoundKey, key);
289 #if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
290 void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
292 KeyExpansion(ctx->RoundKey, key);
293 memcpy (ctx->Iv, iv, AES_BLOCKLEN);
295 void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
297 memcpy (ctx->Iv, iv, AES_BLOCKLEN);
299 #endif
301 // This function adds the round key to state.
302 // The round key is added to the state by an XOR function.
303 static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
305 uint8_t i,j;
306 for (i = 0; i < 4; ++i)
308 for (j = 0; j < 4; ++j)
310 (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
315 // The SubBytes Function Substitutes the values in the
316 // state matrix with values in an S-box.
317 static void SubBytes(state_t* state)
319 uint8_t i, j;
320 for (i = 0; i < 4; ++i)
322 for (j = 0; j < 4; ++j)
324 (*state)[j][i] = getSBoxValue((*state)[j][i]);
329 // The ShiftRows() function shifts the rows in the state to the left.
330 // Each row is shifted with different offset.
331 // Offset = Row number. So the first row is not shifted.
332 static void ShiftRows(state_t* state)
334 uint8_t temp;
336 // Rotate first row 1 columns to left
337 temp = (*state)[0][1];
338 (*state)[0][1] = (*state)[1][1];
339 (*state)[1][1] = (*state)[2][1];
340 (*state)[2][1] = (*state)[3][1];
341 (*state)[3][1] = temp;
343 // Rotate second row 2 columns to left
344 temp = (*state)[0][2];
345 (*state)[0][2] = (*state)[2][2];
346 (*state)[2][2] = temp;
348 temp = (*state)[1][2];
349 (*state)[1][2] = (*state)[3][2];
350 (*state)[3][2] = temp;
352 // Rotate third row 3 columns to left
353 temp = (*state)[0][3];
354 (*state)[0][3] = (*state)[3][3];
355 (*state)[3][3] = (*state)[2][3];
356 (*state)[2][3] = (*state)[1][3];
357 (*state)[1][3] = temp;
360 static uint8_t xtime(uint8_t x)
362 return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
365 // MixColumns function mixes the columns of the state matrix
366 static void MixColumns(state_t* state)
368 uint8_t i;
369 uint8_t Tmp, Tm, t;
370 for (i = 0; i < 4; ++i)
372 t = (*state)[i][0];
373 Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
374 Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
375 Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
376 Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
377 Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
381 // Multiply is used to multiply numbers in the field GF(2^8)
382 // Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
383 // The compiler seems to be able to vectorize the operation better this way.
384 // See https://github.com/kokke/tiny-AES-c/pull/34
385 #if MULTIPLY_AS_A_FUNCTION
386 static uint8_t Multiply(uint8_t x, uint8_t y)
388 return (((y & 1) * x) ^
389 ((y>>1 & 1) * xtime(x)) ^
390 ((y>>2 & 1) * xtime(xtime(x))) ^
391 ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
392 ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
394 #else
395 #define Multiply(x, y) \
396 ( ((y & 1) * x) ^ \
397 ((y>>1 & 1) * xtime(x)) ^ \
398 ((y>>2 & 1) * xtime(xtime(x))) ^ \
399 ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
400 ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
402 #endif
404 #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
406 static uint8_t getSBoxInvert(uint8_t num)
408 return rsbox[num];
411 #define getSBoxInvert(num) (rsbox[(num)])
413 // MixColumns function mixes the columns of the state matrix.
414 // The method used to multiply may be difficult to understand for the inexperienced.
415 // Please use the references to gain more information.
416 static void InvMixColumns(state_t* state)
418 int i;
419 uint8_t a, b, c, d;
420 for (i = 0; i < 4; ++i)
422 a = (*state)[i][0];
423 b = (*state)[i][1];
424 c = (*state)[i][2];
425 d = (*state)[i][3];
427 (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
428 (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
429 (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
430 (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
435 // The SubBytes Function Substitutes the values in the
436 // state matrix with values in an S-box.
437 static void InvSubBytes(state_t* state)
439 uint8_t i, j;
440 for (i = 0; i < 4; ++i)
442 for (j = 0; j < 4; ++j)
444 (*state)[j][i] = getSBoxInvert((*state)[j][i]);
449 static void InvShiftRows(state_t* state)
451 uint8_t temp;
453 // Rotate first row 1 columns to right
454 temp = (*state)[3][1];
455 (*state)[3][1] = (*state)[2][1];
456 (*state)[2][1] = (*state)[1][1];
457 (*state)[1][1] = (*state)[0][1];
458 (*state)[0][1] = temp;
460 // Rotate second row 2 columns to right
461 temp = (*state)[0][2];
462 (*state)[0][2] = (*state)[2][2];
463 (*state)[2][2] = temp;
465 temp = (*state)[1][2];
466 (*state)[1][2] = (*state)[3][2];
467 (*state)[3][2] = temp;
469 // Rotate third row 3 columns to right
470 temp = (*state)[0][3];
471 (*state)[0][3] = (*state)[1][3];
472 (*state)[1][3] = (*state)[2][3];
473 (*state)[2][3] = (*state)[3][3];
474 (*state)[3][3] = temp;
476 #endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
478 // Cipher is the main function that encrypts the PlainText.
479 static void Cipher(state_t* state, const uint8_t* RoundKey)
481 uint8_t round = 0;
483 // Add the First round key to the state before starting the rounds.
484 AddRoundKey(0, state, RoundKey);
486 // There will be Nr rounds.
487 // The first Nr-1 rounds are identical.
488 // These Nr rounds are executed in the loop below.
489 // Last one without MixColumns()
490 for (round = 1; ; ++round)
492 SubBytes(state);
493 ShiftRows(state);
494 if (round == Nr) {
495 break;
497 MixColumns(state);
498 AddRoundKey(round, state, RoundKey);
500 // Add round key to last round
501 AddRoundKey(Nr, state, RoundKey);
504 #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
505 static void InvCipher(state_t* state, const uint8_t* RoundKey)
507 uint8_t round = 0;
509 // Add the First round key to the state before starting the rounds.
510 AddRoundKey(Nr, state, RoundKey);
512 // There will be Nr rounds.
513 // The first Nr-1 rounds are identical.
514 // These Nr rounds are executed in the loop below.
515 // Last one without InvMixColumn()
516 for (round = (Nr - 1); ; --round)
518 InvShiftRows(state);
519 InvSubBytes(state);
520 AddRoundKey(round, state, RoundKey);
521 if (round == 0) {
522 break;
524 InvMixColumns(state);
528 #endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
530 /*****************************************************************************/
531 /* Public functions: */
532 /*****************************************************************************/
533 #if defined(ECB) && (ECB == 1)
536 void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
538 // The next function call encrypts the PlainText with the Key using AES algorithm.
539 Cipher((state_t*)buf, ctx->RoundKey);
542 void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
544 // The next function call decrypts the PlainText with the Key using AES algorithm.
545 InvCipher((state_t*)buf, ctx->RoundKey);
549 #endif // #if defined(ECB) && (ECB == 1)
555 #if defined(CBC) && (CBC == 1)
558 static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
560 uint8_t i;
561 for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
563 buf[i] ^= Iv[i];
567 void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length)
569 size_t i;
570 uint8_t *Iv = ctx->Iv;
571 for (i = 0; i < length; i += AES_BLOCKLEN)
573 XorWithIv(buf, Iv);
574 Cipher((state_t*)buf, ctx->RoundKey);
575 Iv = buf;
576 buf += AES_BLOCKLEN;
578 /* store Iv in ctx for next call */
579 memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
582 void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
584 size_t i;
585 uint8_t storeNextIv[AES_BLOCKLEN];
586 for (i = 0; i < length; i += AES_BLOCKLEN)
588 memcpy(storeNextIv, buf, AES_BLOCKLEN);
589 InvCipher((state_t*)buf, ctx->RoundKey);
590 XorWithIv(buf, ctx->Iv);
591 memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
592 buf += AES_BLOCKLEN;
597 #endif // #if defined(CBC) && (CBC == 1)
601 #if defined(CTR) && (CTR == 1)
603 /* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
604 void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
606 uint8_t buffer[AES_BLOCKLEN];
608 size_t i;
609 int bi;
610 for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
612 if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
615 memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
616 Cipher((state_t*)buffer,ctx->RoundKey);
618 /* Increment Iv and handle overflow */
619 for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
621 /* inc will overflow */
622 if (ctx->Iv[bi] == 255)
624 ctx->Iv[bi] = 0;
625 continue;
627 ctx->Iv[bi] += 1;
628 break;
630 bi = 0;
633 buf[i] = (buf[i] ^ buffer[bi]);
637 #endif // #if defined(CTR) && (CTR == 1)
639 #ifdef ECB
640 void encrypt_ecb(void)
642 #if defined(AES256)
643 uint8_t key[] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
644 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 };
645 uint8_t out[] = { 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8 };
646 #elif defined(AES192)
647 uint8_t key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
648 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b };
649 uint8_t out[] = { 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc };
650 #elif defined(AES128)
651 uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
652 uint8_t out[] = { 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97 };
653 #endif
655 uint8_t in[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a };
656 struct AES_ctx ctx;
658 AES_init_ctx(&ctx, key);
659 AES_ECB_encrypt(&ctx, in);
661 ASSERT (0 == memcmp((char*) out, (char*) in, 16));
663 #endif
665 #ifdef CBC
666 void decrypt_cbc(void)
669 #if defined(AES256)
670 uint8_t key[] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
671 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 };
672 uint8_t in[] = { 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
673 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
674 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
675 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b };
676 #elif defined(AES192)
677 uint8_t key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b };
678 uint8_t in[] = { 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
679 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4, 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a,
680 0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0, 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0,
681 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd };
682 #elif defined(AES128)
683 uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
684 uint8_t in[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
685 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
686 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
687 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 };
688 #endif
689 uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
690 uint8_t out[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
691 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
692 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
693 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 };
694 // uint8_t buffer[64];
695 struct AES_ctx ctx;
697 AES_init_ctx_iv(&ctx, key, iv);
698 AES_CBC_decrypt_buffer(&ctx, in, 64);
700 ASSERT (0 == memcmp((char*) out, (char*) in, 64));
703 void encrypt_cbc(void)
705 #if defined(AES256)
706 uint8_t key[] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
707 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 };
708 uint8_t out[] = { 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
709 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
710 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
711 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b };
712 #elif defined(AES192)
713 uint8_t key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b };
714 uint8_t out[] = { 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
715 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4, 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a,
716 0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0, 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0,
717 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd };
718 #elif defined(AES128)
719 uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
720 uint8_t out[] = { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
721 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
722 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
723 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 };
724 #endif
725 uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
726 uint8_t in[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
727 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
728 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
729 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 };
730 struct AES_ctx ctx;
732 AES_init_ctx_iv(&ctx, key, iv);
733 AES_CBC_encrypt_buffer(&ctx, in, 64);
735 ASSERT (0 == memcmp((char*) out, (char*) in, 64));
737 #endif
739 #ifdef CTR
740 void xcrypt_ctr(void);
741 void encrypt_ctr(void)
743 return xcrypt_ctr();
746 void decrypt_ctr(void)
748 return xcrypt_ctr();
751 void xcrypt_ctr(void)
753 #if defined(AES256)
754 uint8_t key[32] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
755 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 };
756 uint8_t in[64] = { 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
757 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5,
758 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d,
759 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6 };
760 #elif defined(AES192)
761 uint8_t key[24] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
762 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b };
763 uint8_t in[64] = { 0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2, 0x4f, 0x2b, 0x04, 0x59, 0xfe, 0x7e, 0x6e, 0x0b,
764 0x09, 0x03, 0x39, 0xec, 0x0a, 0xa6, 0xfa, 0xef, 0xd5, 0xcc, 0xc2, 0xc6, 0xf4, 0xce, 0x8e, 0x94,
765 0x1e, 0x36, 0xb2, 0x6b, 0xd1, 0xeb, 0xc6, 0x70, 0xd1, 0xbd, 0x1d, 0x66, 0x56, 0x20, 0xab, 0xf7,
766 0x4f, 0x78, 0xa7, 0xf6, 0xd2, 0x98, 0x09, 0x58, 0x5a, 0x97, 0xda, 0xec, 0x58, 0xc6, 0xb0, 0x50 };
767 #elif defined(AES128)
768 uint8_t key[16] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
769 uint8_t in[64] = { 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
770 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
771 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
772 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee };
773 #endif
774 uint8_t iv[16] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
775 uint8_t out[64] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
776 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
777 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
778 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 };
779 struct AES_ctx ctx;
781 AES_init_ctx_iv(&ctx, key, iv);
782 AES_CTR_xcrypt_buffer(&ctx, in, 64);
784 ASSERT (0 == memcmp((char *) out, (char *) in, 64));
786 #endif
788 #ifdef ECB
789 void decrypt_ecb(void)
791 #if defined(AES256)
792 uint8_t key[] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
793 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 };
794 uint8_t in[] = { 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8 };
795 #elif defined(AES192)
796 uint8_t key[] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
797 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b };
798 uint8_t in[] = { 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc };
799 #elif defined(AES128)
800 uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
801 uint8_t in[] = { 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97 };
802 #endif
804 uint8_t out[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a };
805 struct AES_ctx ctx;
807 AES_init_ctx(&ctx, key);
808 AES_ECB_decrypt(&ctx, in);
810 ASSERT (0 == memcmp((char*) out, (char*) in, 16));
812 #endif
814 #endif // Disable everything until here for some targets with too little memory
816 void
817 testAES (void)
819 #ifdef CBC
820 decrypt_cbc();
821 encrypt_cbc();
822 #endif
824 #ifdef ECB
825 encrypt_ecb();
826 decrypt_ecb();
827 #endif
829 #ifdef CTR
830 encrypt_ctr();
831 decrypt_ctr();
832 #endif