47 #if defined(AES256) && (AES256 == 1)
50 #elif defined(AES192) && (AES192 == 1)
61 #ifndef MULTIPLY_AS_A_FUNCTION
62 #define MULTIPLY_AS_A_FUNCTION 0
79 static const uint8_t sbox[256] =
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
100 static const uint8_t rsbox[256] =
102 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
103 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
104 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
105 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
106 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
107 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
108 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
109 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
110 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
111 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
112 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
113 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
114 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
115 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
116 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
117 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
122 static const uint8_t Rcon[11] =
124 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
147 #define getSBoxValue(num) (sbox[(num)])
154 #define getSBoxInvert(num) (rsbox[(num)])
157 static void KeyExpansion(uint8_t* RoundKey,
const uint8_t* Key)
163 for (i = 0; i < Nk; ++i)
165 RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
166 RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
167 RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
168 RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
172 for (i = Nk; i < Nb * (Nr + 1); ++i)
176 tempa[0] = RoundKey[k + 0];
177 tempa[1] = RoundKey[k + 1];
178 tempa[2] = RoundKey[k + 2];
179 tempa[3] = RoundKey[k + 3];
190 const uint8_t u8tmp = tempa[0];
202 tempa[0] = getSBoxValue(tempa[0]);
203 tempa[1] = getSBoxValue(tempa[1]);
204 tempa[2] = getSBoxValue(tempa[2]);
205 tempa[3] = getSBoxValue(tempa[3]);
208 tempa[0] = tempa[0] ^ Rcon[i / Nk];
211 #if defined(AES256) && (AES256 == 1)
217 tempa[0] = getSBoxValue(tempa[0]);
218 tempa[1] = getSBoxValue(tempa[1]);
219 tempa[2] = getSBoxValue(tempa[2]);
220 tempa[3] = getSBoxValue(tempa[3]);
227 RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
228 RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
229 RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
230 RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
238 #if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
242 memcpy (ctx->
Iv, iv, AES_BLOCKLEN);
246 memcpy (ctx->
Iv, iv, AES_BLOCKLEN);
252 static void AddRoundKey(uint8_t round,
state_t* state,
const uint8_t* RoundKey)
256 for (i = 0; i < 4; ++i)
258 for (j = 0; j < 4; ++j)
260 (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
267 static void SubBytes(
state_t* state)
271 for (i = 0; i < 4; ++i)
273 for (j = 0; j < 4; ++j)
275 (*state)[j][i] = getSBoxValue((*state)[j][i]);
283 static void ShiftRows(
state_t* state)
288 temp = (*state)[0][1];
289 (*state)[0][1] = (*state)[1][1];
290 (*state)[1][1] = (*state)[2][1];
291 (*state)[2][1] = (*state)[3][1];
292 (*state)[3][1] = temp;
295 temp = (*state)[0][2];
296 (*state)[0][2] = (*state)[2][2];
297 (*state)[2][2] = temp;
299 temp = (*state)[1][2];
300 (*state)[1][2] = (*state)[3][2];
301 (*state)[3][2] = temp;
304 temp = (*state)[0][3];
305 (*state)[0][3] = (*state)[3][3];
306 (*state)[3][3] = (*state)[2][3];
307 (*state)[2][3] = (*state)[1][3];
308 (*state)[1][3] = temp;
311 static uint8_t xtime(uint8_t x)
313 return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));
317 static void MixColumns(
state_t* state)
322 for (i = 0; i < 4; ++i)
325 Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
326 Tm = (*state)[i][0] ^ (*state)[i][1] ;
328 (*state)[i][0] ^= Tm ^ Tmp ;
329 Tm = (*state)[i][1] ^ (*state)[i][2] ;
331 (*state)[i][1] ^= Tm ^ Tmp ;
332 Tm = (*state)[i][2] ^ (*state)[i][3] ;
334 (*state)[i][2] ^= Tm ^ Tmp ;
335 Tm = (*state)[i][3] ^ t ;
337 (*state)[i][3] ^= Tm ^ Tmp ;
345 #if MULTIPLY_AS_A_FUNCTION
346 static uint8_t Multiply(uint8_t x, uint8_t y)
348 return (((y & 1) * x) ^
349 ((y >> 1 & 1) * xtime(x)) ^
350 ((y >> 2 & 1) * xtime(xtime(x))) ^
351 ((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^
352 ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x))))));
355 #define Multiply(x, y) \
357 ((y>>1 & 1) * xtime(x)) ^ \
358 ((y>>2 & 1) * xtime(xtime(x))) ^ \
359 ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
360 ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
364 #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
368 static void InvMixColumns(
state_t* state)
373 for (i = 0; i < 4; ++i)
380 (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
381 (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
382 (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
383 (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
390 static void InvSubBytes(
state_t* state)
394 for (i = 0; i < 4; ++i)
396 for (j = 0; j < 4; ++j)
398 (*state)[j][i] = getSBoxInvert((*state)[j][i]);
403 static void InvShiftRows(
state_t* state)
408 temp = (*state)[3][1];
409 (*state)[3][1] = (*state)[2][1];
410 (*state)[2][1] = (*state)[1][1];
411 (*state)[1][1] = (*state)[0][1];
412 (*state)[0][1] = temp;
415 temp = (*state)[0][2];
416 (*state)[0][2] = (*state)[2][2];
417 (*state)[2][2] = temp;
419 temp = (*state)[1][2];
420 (*state)[1][2] = (*state)[3][2];
421 (*state)[3][2] = temp;
424 temp = (*state)[0][3];
425 (*state)[0][3] = (*state)[1][3];
426 (*state)[1][3] = (*state)[2][3];
427 (*state)[2][3] = (*state)[3][3];
428 (*state)[3][3] = temp;
433 static void Cipher(
state_t* state,
const uint8_t* RoundKey)
438 AddRoundKey(0, state, RoundKey);
444 for (round = 1; ; ++round)
455 AddRoundKey(round, state, RoundKey);
459 AddRoundKey(Nr, state, RoundKey);
462 #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
463 static void InvCipher(
state_t* state,
const uint8_t* RoundKey)
468 AddRoundKey(Nr, state, RoundKey);
474 for (round = (Nr - 1); ; --round)
478 AddRoundKey(round, state, RoundKey);
485 InvMixColumns(state);
494 #if defined(ECB) && (ECB == 1)
516 #if defined(CBC) && (CBC == 1)
519 static void XorWithIv(uint8_t* buf,
const uint8_t* Iv)
523 for (i = 0; i < AES_BLOCKLEN; ++i)
532 uint8_t* Iv = ctx->
Iv;
534 for (i = 0; i < length; i += AES_BLOCKLEN)
543 memcpy(ctx->
Iv, Iv, AES_BLOCKLEN);
549 uint8_t storeNextIv[AES_BLOCKLEN];
551 for (i = 0; i < length; i += AES_BLOCKLEN)
553 memcpy(storeNextIv, buf, AES_BLOCKLEN);
555 XorWithIv(buf, ctx->
Iv);
556 memcpy(ctx->
Iv, storeNextIv, AES_BLOCKLEN);
566 #if defined(CTR) && (CTR == 1)
571 uint8_t buffer[AES_BLOCKLEN];
576 for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
578 if (bi == AES_BLOCKLEN)
581 memcpy(buffer, ctx->
Iv, AES_BLOCKLEN);
585 for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
588 if (ctx->
Iv[bi] == 255)
601 buf[i] = (buf[i] ^ buffer[bi]);
void AES_CBC_decrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length)
void AES_ECB_encrypt(const struct AES_ctx *ctx, uint8_t *buf)
void AES_CTR_xcrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length)
void AES_init_ctx_iv(struct AES_ctx *ctx, const uint8_t *key, const uint8_t *iv)
void AES_ECB_decrypt(const struct AES_ctx *ctx, uint8_t *buf)
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length)
void AES_init_ctx(struct AES_ctx *ctx, const uint8_t *key)
void AES_ctx_set_iv(struct AES_ctx *ctx, const uint8_t *iv)
uint8_t RoundKey[AES_keyExpSize]