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.
6 The implementation is verified against the test vectors in:
7 National Institute of Standards and Technology Special Publication 800-38A 2001 ED
13 6bc1bee22e409f96e93d7e117393172a
14 ae2d8a571e03ac9c9eb76fac45af8e51
15 30c81c46a35ce411e5fbc1191a0a52ef
16 f69f2445df4f9b17ad2b417be66c3710
19 2b7e151628aed2a6abf7158809cf4f3c
22 3ad77bb40d7a3660a89ecaf32466ef97
23 f5d3d58503b9699de785895a96fdbaaf
24 43b1cd7f598ece23881b00e3ed030688
25 7b0c785e27e8ad3f8223207104725dd4
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.
35 /*****************************************************************************/
37 /*****************************************************************************/
39 #include <string.h> // CBC mode, for memset
42 /*****************************************************************************/
44 /*****************************************************************************/
45 // The number of columns comprising a state in AES. This is a constant in AES. Value=4
48 #if defined(AES256) && (AES256 == 1)
51 #elif defined(AES192) && (AES192 == 1)
55 #define Nk 4 // The number of 32 bit words in a key.
56 #define Nr 10 // The number of rounds in AES Cipher.
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
69 /*****************************************************************************/
70 /* Private variables: */
71 /*****************************************************************************/
72 // state - array holding the intermediate results during decryption.
73 typedef uint8_t state_t[4][4];
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 };
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 };
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 };
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 };
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.
147 * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
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."
154 /*****************************************************************************/
155 /* Private functions: */
156 /*****************************************************************************/
158 static uint8_t getSBoxValue(uint8_t num)
163 #define getSBoxValue(num) (sbox[(num)])
165 #define My_getSBoxValue(num) (My_sbox[(num)])
167 static uint8_t getSBoxInvert(uint8_t num)
172 #define getSBoxInvert(num) (rsbox[(num)])
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)
179 uint8_t tempa[4]; // Used for the column/row operations
181 // The first round key is the key itself.
182 for (i = 0; i < Nk; ++i)
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];
190 // All other round keys are found from the previous round keys.
191 for (i = Nk; i < Nb * (Nr + 1); ++i)
195 tempa[0]=RoundKey[k + 0];
196 tempa[1]=RoundKey[k + 1];
197 tempa[2]=RoundKey[k + 2];
198 tempa[3]=RoundKey[k + 3];
204 // This function shifts the 4 bytes in a word to the left once.
205 // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
207 // Function RotWord()
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.
219 // Function Subword()
221 tempa[0] = getSBoxValue(tempa[0]);
222 tempa[1] = getSBoxValue(tempa[1]);
223 tempa[2] = getSBoxValue(tempa[2]);
224 tempa[3] = getSBoxValue(tempa[3]);
227 tempa[0] = tempa[0] ^ Rcon[i/Nk];
229 #if defined(AES256) && (AES256 == 1)
232 // Function Subword()
234 tempa[0] = getSBoxValue(tempa[0]);
235 tempa[1] = getSBoxValue(tempa[1]);
236 tempa[2] = getSBoxValue(tempa[2]);
237 tempa[3] = getSBoxValue(tempa[3]);
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];
249 void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
251 KeyExpansion(ctx->RoundKey, key);
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)
256 KeyExpansion(ctx->RoundKey, key);
257 memcpy (ctx->Iv, iv, AES_BLOCKLEN);
259 void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
261 memcpy (ctx->Iv, iv, AES_BLOCKLEN);
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)
270 for (i = 0; i < 4; ++i)
272 for (j = 0; j < 4; ++j)
274 (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
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)
284 for (i = 0; i < 4; ++i)
286 for (j = 0; j < 4; ++j)
288 (*state)[j][i] = getSBoxValue((*state)[j][i]);
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)
298 for (i = 0; i < 4; ++i)
300 for (j = 0; j < 4; ++j)
302 (*state)[j][i] = My_getSBoxValue((*state)[j][i]);
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)
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;
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;
326 temp = (*state)[1][2];
327 (*state)[1][2] = (*state)[3][2];
328 (*state)[3][2] = temp;
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;
338 static uint8_t xtime(uint8_t x)
340 return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
343 // MixColumns function mixes the columns of the state matrix
344 static void MixColumns(state_t* state)
348 for (i = 0; i < 4; ++i)
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 ;
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)
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 */
373 #define Multiply(x, y) \
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)))))) \
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)
389 for (i = 0; i < 4; ++i)
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);
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)
409 for (i = 0; i < 4; ++i)
411 for (j = 0; j < 4; ++j)
413 (*state)[j][i] = getSBoxInvert((*state)[j][i]);
419 static void InvShiftRows(state_t* state)
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;
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;
435 temp = (*state)[1][2];
436 (*state)[1][2] = (*state)[3][2];
437 (*state)[3][2] = temp;
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;
448 // Cipher is the main function that encrypts the PlainText.
449 static void Cipher(state_t* state, uint8_t* RoundKey)
453 // Add the First round key to the state before starting the rounds.
454 AddRoundKey(0, state, RoundKey);
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)
464 AddRoundKey(round, state, RoundKey);
467 // The last round is given below.
468 // The MixColumns function is not here in the last round.
471 AddRoundKey(Nr, state, RoundKey);
475 // Cipher is the main function that encrypts the PlainText.
476 static void My_Cipher(state_t* state, uint8_t* RoundKey)
480 // Add the First round key to the state before starting the rounds.
481 AddRoundKey(0, state, RoundKey);
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)
491 AddRoundKey(round, state, RoundKey);
494 // The last round is given below.
495 // The MixColumns function is not here in the last round.
498 AddRoundKey(Nr, state, RoundKey);
501 static void InvCipher(state_t* state,uint8_t* RoundKey)
505 // Add the First round key to the state before starting the rounds.
506 AddRoundKey(Nr, state, RoundKey);
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)
515 AddRoundKey(round, state, RoundKey);
516 InvMixColumns(state);
519 // The last round is given below.
520 // The MixColumns function is not here in the last round.
523 AddRoundKey(0, state, RoundKey);
528 /*****************************************************************************/
529 /* Public functions: */
530 /*****************************************************************************/
531 #if defined(ECB) && (ECB == 1)
534 void AES_ECB_encrypt(struct AES_ctx *ctx,const uint8_t* buf)
536 // The next function call encrypts the PlainText with the Key using AES algorithm.
537 Cipher((state_t*)buf, ctx->RoundKey);
540 void AES_ECB_decrypt(struct AES_ctx* ctx,const uint8_t* buf)
542 // The next function call decrypts the PlainText with the Key using AES algorithm.
543 InvCipher((state_t*)buf, ctx->RoundKey);
547 #endif // #if defined(ECB) && (ECB == 1)
553 #if defined(CBC) && (CBC == 1)
556 static void XorWithIv(uint8_t* buf, uint8_t* Iv)
559 for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
565 void AES_CBC_encrypt_buffer(struct AES_ctx *ctx,uint8_t* buf, uint32_t length)
568 uint8_t *Iv = ctx->Iv;
569 for (i = 0; i < length; i += AES_BLOCKLEN)
572 Cipher((state_t*)buf, ctx->RoundKey);
575 //printf("Step %d - %d", i/16, i);
577 /* store Iv in ctx for next call */
578 memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
581 void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
584 uint8_t storeNextIv[AES_BLOCKLEN];
585 for (i = 0; i < length; i += AES_BLOCKLEN)
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);
596 #endif // #if defined(CBC) && (CBC == 1)
600 #if defined(CTR) && (CTR == 1)
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)
605 uint8_t buffer[AES_BLOCKLEN];
609 for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
611 if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
614 memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
615 Cipher((state_t*)buffer,ctx->RoundKey);
617 /* Increment Iv and handle overflow */
618 for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
620 /* inc will owerflow */
621 if (ctx->Iv[bi] == 255)
632 buf[i] = (buf[i] ^ buffer[bi]);
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)
639 uint8_t buffer[AES_BLOCKLEN];
643 for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
645 if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
648 memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
649 My_Cipher((state_t*)buffer,ctx->RoundKey);
651 /* Increment Iv and handle overflow */
652 for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
654 /* inc will owerflow */
655 if (ctx->Iv[bi] == 255)
666 buf[i] = (buf[i] ^ buffer[bi]);
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)
680 uint8_t tempa[4]; // Used for the column/row operations
682 // The first round key is the key itself.
683 for (i = 0; i < Nk; ++i)
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];
691 // All other round keys are found from the previous round keys.
692 for (i = Nk; i < Nb * (Nr + 1); ++i)
696 tempa[0]=RoundKey[k + 0];
697 tempa[1]=RoundKey[k + 1];
698 tempa[2]=RoundKey[k + 2];
699 tempa[3]=RoundKey[k + 3];
705 // This function shifts the 4 bytes in a word to the left once.
706 // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
708 // Function RotWord()
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.
720 // Function Subword()
722 tempa[0] = getSBoxValue(tempa[0]);
723 tempa[1] = getSBoxValue(tempa[1]);
724 tempa[2] = getSBoxValue(tempa[2]);
725 tempa[3] = getSBoxValue(tempa[3]);
728 tempa[0] = tempa[0] ^ Rcon[i/Nk];
730 #if defined(AES256) && (AES256 == 1)
733 // Function Subword()
735 tempa[0] = getSBoxValue(tempa[0]);
736 tempa[1] = getSBoxValue(tempa[1]);
737 tempa[2] = getSBoxValue(tempa[2]);
738 tempa[3] = getSBoxValue(tempa[3]);
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];
753 void rc4key(unsigned char *key, int size_DK) {
755 for(int i=0;i<256;i++) {
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 ];
781 #endif // #if defined(CTR) && (CTR == 1)