Commit c26fb6a5 authored by Matteo Brichese's avatar Matteo Brichese
Browse files

adding Key Expansion for AES192 and AES256

parent 200274e3
...@@ -37,18 +37,28 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) ...@@ -37,18 +37,28 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
#include <string.h> // CBC mode, for memset #include <string.h> // CBC mode, for memset
#include "aes.h" #include "aes.h"
/*****************************************************************************/ /*****************************************************************************/
/* Defines: */ /* Defines: */
/*****************************************************************************/ /*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4 // The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4 #define Nb 4
// The number of 32 bit words in a key.
#define Nk 4 #ifdef AES256
// Key length in bytes [128 bit] #define Nk 8
#define KEYLEN 16 #define KEYLEN 32
// The number of rounds in AES Cipher. #define Nr 14
#define Nr 10 #define keyExpSize 240
#elif defined(AES192)
#define Nk 6
#define KEYLEN 24
#define Nr 12
#define keyExpSize 208
#else
#define Nk 4 // The number of 32 bit words in a key.
#define KEYLEN 16 // Key length in bytes
#define Nr 10 // The number of rounds in AES Cipher.
#define keyExpSize 176
#endif
// jcallan@github points out that declaring Multiply as a function // jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler. // reduces code size considerably with the Keil ARM compiler.
...@@ -66,7 +76,7 @@ typedef uint8_t state_t[4][4]; ...@@ -66,7 +76,7 @@ typedef uint8_t state_t[4][4];
static state_t* state; static state_t* state;
// The array that stores the round keys. // The array that stores the round keys.
static uint8_t RoundKey[176]; static uint8_t RoundKey[keyExpSize];
// The Key input to the AES Program // The Key input to the AES Program
static const uint8_t* Key; static const uint8_t* Key;
...@@ -116,11 +126,9 @@ static const uint8_t rsbox[256] = ...@@ -116,11 +126,9 @@ static const uint8_t rsbox[256] =
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
// The round constant word array, Rcon[i], contains the values given by // The round constant word array, Rcon[i], contains the values given by
// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
// Note that i starts at 1, not 0). static const uint8_t Rcon[256] = {
static const uint8_t Rcon[255] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
...@@ -136,7 +144,7 @@ static const uint8_t Rcon[255] = { ...@@ -136,7 +144,7 @@ static const uint8_t Rcon[255] = {
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb }; 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d };
/*****************************************************************************/ /*****************************************************************************/
...@@ -155,7 +163,7 @@ static uint8_t getSBoxInvert(uint8_t num) ...@@ -155,7 +163,7 @@ static uint8_t getSBoxInvert(uint8_t num)
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. // This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
static void KeyExpansion(void) static void KeyExpansion(void)
{ {
uint32_t i, j, k; uint32_t i, k;
uint8_t tempa[4]; // Used for the column/row operations uint8_t tempa[4]; // Used for the column/row operations
// The first round key is the key itself. // The first round key is the key itself.
...@@ -168,15 +176,19 @@ static void KeyExpansion(void) ...@@ -168,15 +176,19 @@ static void KeyExpansion(void)
} }
// All other round keys are found from the previous round keys. // All other round keys are found from the previous round keys.
for(; (i < (Nb * (Nr + 1))); ++i) //i == Nk
for(i = Nk; i < Nb * (Nr + 1); ++i)
{ {
for(j = 0; j < 4; ++j)
{ {
tempa[j]=RoundKey[(i-1) * 4 + j]; tempa[0]=RoundKey[(i-1) * 4 + 0];
tempa[1]=RoundKey[(i-1) * 4 + 1];
tempa[2]=RoundKey[(i-1) * 4 + 2];
tempa[3]=RoundKey[(i-1) * 4 + 3];
} }
if (i % Nk == 0) if (i % Nk == 0)
{ {
// This function rotates the 4 bytes in a word to the left once. // This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0] // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord() // Function RotWord()
...@@ -201,7 +213,8 @@ static void KeyExpansion(void) ...@@ -201,7 +213,8 @@ static void KeyExpansion(void)
tempa[0] = tempa[0] ^ Rcon[i/Nk]; tempa[0] = tempa[0] ^ Rcon[i/Nk];
} }
else if (Nk > 6 && i % Nk == 4) #ifdef AES256
if (i % Nk == 4)
{ {
// Function Subword() // Function Subword()
{ {
...@@ -211,6 +224,7 @@ static void KeyExpansion(void) ...@@ -211,6 +224,7 @@ static void KeyExpansion(void)
tempa[3] = getSBoxValue(tempa[3]); tempa[3] = getSBoxValue(tempa[3]);
} }
} }
#endif
RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0]; RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0];
RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1]; RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1];
RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2]; RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2];
...@@ -451,7 +465,7 @@ static void BlockCopy(uint8_t* output, const uint8_t* input) ...@@ -451,7 +465,7 @@ static void BlockCopy(uint8_t* output, const uint8_t* input)
#if defined(ECB) && ECB #if defined(ECB) && ECB
void AES128_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t* output) void AES_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t* output)
{ {
// Copy input to output, and work in-memory on output // Copy input to output, and work in-memory on output
BlockCopy(output, input); BlockCopy(output, input);
...@@ -464,7 +478,7 @@ void AES128_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t* outpu ...@@ -464,7 +478,7 @@ void AES128_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t* outpu
Cipher(); Cipher();
} }
void AES128_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output) void AES_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output)
{ {
// Copy input to output, and work in-memory on output // Copy input to output, and work in-memory on output
BlockCopy(output, input); BlockCopy(output, input);
...@@ -496,7 +510,7 @@ static void XorWithIv(uint8_t* buf) ...@@ -496,7 +510,7 @@ static void XorWithIv(uint8_t* buf)
} }
} }
void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv) void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{ {
uintptr_t i; uintptr_t i;
uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */ uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */
...@@ -536,7 +550,7 @@ void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, ...@@ -536,7 +550,7 @@ void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length,
} }
} }
void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv) void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{ {
uintptr_t i; uintptr_t i;
uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */ uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */
...@@ -577,7 +591,4 @@ void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, ...@@ -577,7 +591,4 @@ void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length,
} }
} }
#endif // #if defined(CBC) && CBC #endif // #if defined(CBC) && CBC
...@@ -19,22 +19,20 @@ ...@@ -19,22 +19,20 @@
#endif #endif
#if defined(ECB) && ECB #if defined(ECB) && ECB
void AES128_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t *output); void AES_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t *output);
void AES128_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output); void AES_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output);
#endif // #if defined(ECB) && ECB #endif // #if defined(ECB) && ECB
#if defined(CBC) && CBC #if defined(CBC) && CBC
void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv); void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv);
#endif // #if defined(CBC) && CBC #endif // #if defined(CBC) && CBC
#endif //_AES_H_ #endif //_AES_H_
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment