adding Key Expansion for AES192 and AES256

This commit is contained in:
Matteo Brichese 2017-06-05 17:07:34 -07:00
parent 200274e385
commit c26fb6a5ec
2 changed files with 55 additions and 46 deletions

61
aes.c
View File

@ -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 "aes.h"
/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4
// The number of 32 bit words in a key.
#define Nk 4
// Key length in bytes [128 bit]
#define KEYLEN 16
// The number of rounds in AES Cipher.
#define Nr 10
#ifdef AES256
#define Nk 8
#define KEYLEN 32
#define Nr 14
#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
// reduces code size considerably with the Keil ARM compiler.
@ -66,7 +76,7 @@ typedef uint8_t state_t[4][4];
static state_t* state;
// The array that stores the round keys.
static uint8_t RoundKey[176];
static uint8_t RoundKey[keyExpSize];
// The Key input to the AES Program
static const uint8_t* Key;
@ -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,
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
// 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[255] = {
static const uint8_t Rcon[256] = {
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,
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] = {
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,
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)
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
static void KeyExpansion(void)
{
uint32_t i, j, k;
uint32_t i, k;
uint8_t tempa[4]; // Used for the column/row operations
// The first round key is the key itself.
@ -168,15 +176,19 @@ static void KeyExpansion(void)
}
// 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)
{
// 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]
// Function RotWord()
@ -201,7 +213,8 @@ static void KeyExpansion(void)
tempa[0] = tempa[0] ^ Rcon[i/Nk];
}
else if (Nk > 6 && i % Nk == 4)
#ifdef AES256
if (i % Nk == 4)
{
// Function Subword()
{
@ -211,6 +224,7 @@ static void KeyExpansion(void)
tempa[3] = getSBoxValue(tempa[3]);
}
}
#endif
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 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2];
@ -451,7 +465,7 @@ static void BlockCopy(uint8_t* output, const uint8_t* input)
#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
BlockCopy(output, input);
@ -464,7 +478,7 @@ void AES128_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t* outpu
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
BlockCopy(output, input);
@ -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;
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,
}
}
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;
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,
}
}
#endif // #if defined(CBC) && CBC

10
aes.h
View File

@ -19,22 +19,20 @@
#endif
#if defined(ECB) && ECB
void AES128_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_encrypt(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
#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 AES128_CBC_decrypt_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 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 //_AES_H_