diff --git a/aes.c b/aes.c index 4481f7b..42eb2b0 100644 --- a/aes.c +++ b/aes.c @@ -76,7 +76,7 @@ typedef uint8_t state_t[4][4]; // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM // The numbers below can be computed dynamically trading ROM for RAM - // This can be useful in (embedded) bootloader applications, where ROM is often limited. -static const uint8_t sbox[256] = { +static const uint8_t sbox[256] PROGMEM = { //0 1 2 3 4 5 6 7 8 9 A B C D E F 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, @@ -96,7 +96,7 @@ static const uint8_t sbox[256] = { 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1) -static const uint8_t rsbox[256] = { +static const uint8_t rsbox[256] PROGMEM = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, @@ -117,7 +117,7 @@ static const uint8_t rsbox[256] = { // The round constant word array, Rcon[i], contains the values given by // x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) -static const uint8_t Rcon[11] = { +static const uint8_t Rcon[11] PROGMEM = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; /* @@ -137,10 +137,10 @@ static const uint8_t Rcon[11] = { /* static uint8_t getSBoxValue(uint8_t num) { - return sbox[num]; + return pgm_read_byte(sbox + (num)); } */ -#define getSBoxValue(num) (sbox[(num)]) +#define getSBoxValue(num) (pgm_read_byte(sbox + (num))) // This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key) @@ -194,7 +194,7 @@ static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key) tempa[3] = getSBoxValue(tempa[3]); } - tempa[0] = tempa[0] ^ Rcon[i/Nk]; + tempa[0] = tempa[0] ^ (pgm_read_byte(Rcon + (i/Nk))); } #if defined(AES256) && (AES256 == 1) if (i % Nk == 4) @@ -339,10 +339,10 @@ static uint8_t Multiply(uint8_t x, uint8_t y) /* static uint8_t getSBoxInvert(uint8_t num) { - return rsbox[num]; + return pgm_read_byte(rsbox + (num)); } */ -#define getSBoxInvert(num) (rsbox[(num)]) +#define getSBoxInvert(num) (pgm_read_byte(rsbox + (num))) // MixColumns function mixes the columns of the state matrix. // The method used to multiply may be difficult to understand for the inexperienced. diff --git a/aes.h b/aes.h index b29b668..f12d0bd 100644 --- a/aes.h +++ b/aes.h @@ -4,6 +4,19 @@ #include #include + +// Platform-specific optimizations + +// On AVR platforms, use flash memory to store static lookup tables, to conserve SRAM +#ifdef __AVR_ARCH__ + #include +#else + // Generic implementation: Emulate PROGMEM using regular RAM + #define PROGMEM + inline uint8_t pgm_read_byte(const uint8_t* p) { return(*p); } +#endif + + // #define the macros below to 1/0 to enable/disable the mode of operation. // // CBC enables AES encryption in CBC-mode of operation.