summaryrefslogtreecommitdiffstats
path: root/aes.c
diff options
context:
space:
mode:
Diffstat (limited to 'aes.c')
-rw-r--r--aes.c145
1 files changed, 70 insertions, 75 deletions
diff --git a/aes.c b/aes.c
index d44d281..0bafcb0 100644
--- a/aes.c
+++ b/aes.c
@@ -37,18 +37,29 @@ 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
+#define BLOCKLEN 16 //Block length in bytes AES is 128b block only
+
+#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 +77,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,27 +127,25 @@ 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] = {
- 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, 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, 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, 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, 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 };
+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,
+ 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, 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, 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, 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, 0x8d };
/*****************************************************************************/
@@ -155,7 +164,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 +177,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 < 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 +214,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 +225,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];
@@ -434,16 +449,6 @@ static void InvCipher(void)
AddRoundKey(0);
}
-static void BlockCopy(uint8_t* output, const uint8_t* input)
-{
- uint8_t i;
- for (i=0;i<KEYLEN;++i)
- {
- output[i] = input[i];
- }
-}
-
-
/*****************************************************************************/
/* Public functions: */
@@ -451,10 +456,10 @@ 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, const uint32_t length)
{
// Copy input to output, and work in-memory on output
- BlockCopy(output, input);
+ memcpy(output, input, length);
state = (state_t*)output;
Key = key;
@@ -464,10 +469,10 @@ 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, const uint32_t length)
{
// Copy input to output, and work in-memory on output
- BlockCopy(output, input);
+ memcpy(output, input, length);
state = (state_t*)output;
// The KeyExpansion routine must be called before encryption.
@@ -490,19 +495,16 @@ void AES128_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *outpu
static void XorWithIv(uint8_t* buf)
{
uint8_t i;
- for(i = 0; i < KEYLEN; ++i)
+ for(i = 0; i < BLOCKLEN; ++i) //WAS for(i = 0; i < KEYLEN; ++i) but the block in AES is always 128bit so 16 bytes!
{
buf[i] ^= Iv[i];
}
}
-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 */
-
- BlockCopy(output, input);
- state = (state_t*)output;
+ uint8_t extra = length % BLOCKLEN; /* Remaining bytes in the last non-full block */
// Skip the key expansion if key is passed as 0
if(0 != key)
@@ -516,33 +518,30 @@ void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length,
Iv = (uint8_t*)iv;
}
- for(i = 0; i < length; i += KEYLEN)
+ for(i = 0; i < length; i += BLOCKLEN)
{
XorWithIv(input);
- BlockCopy(output, input);
+ memcpy(output, input, BLOCKLEN);
state = (state_t*)output;
Cipher();
Iv = output;
- input += KEYLEN;
- output += KEYLEN;
+ input += BLOCKLEN;
+ output += BLOCKLEN;
+ //printf("Step %d - %d", i/16, i);
}
- if(remainders)
+ if(extra)
{
- BlockCopy(output, input);
- memset(output + remainders, 0, KEYLEN - remainders); /* add 0-padding */
+ memcpy(output, input, extra);
state = (state_t*)output;
Cipher();
}
}
-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 */
-
- BlockCopy(output, input);
- state = (state_t*)output;
+ uint8_t extra = length % BLOCKLEN; /* Remaining bytes in the last non-full block */
// Skip the key expansion if key is passed as 0
if(0 != key)
@@ -557,27 +556,23 @@ void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length,
Iv = (uint8_t*)iv;
}
- for(i = 0; i < length; i += KEYLEN)
+ for(i = 0; i < length; i += BLOCKLEN)
{
- BlockCopy(output, input);
+ memcpy(output, input, BLOCKLEN);
state = (state_t*)output;
InvCipher();
XorWithIv(output);
Iv = input;
- input += KEYLEN;
- output += KEYLEN;
+ input += BLOCKLEN;
+ output += BLOCKLEN;
}
- if(remainders)
+ if(extra)
{
- BlockCopy(output, input);
- memset(output+remainders, 0, KEYLEN - remainders); /* add 0-padding */
+ memcpy(output, input, extra);
state = (state_t*)output;
InvCipher();
}
}
-
#endif // #if defined(CBC) && CBC
-
-