Use PROGMEM for lookup tables on AVR platforms

This commit is contained in:
Christoph Honal 2021-12-22 01:40:58 +01:00
parent 12e7744b49
commit 81c76a9051
2 changed files with 21 additions and 8 deletions

16
aes.c
View File

@ -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.

13
aes.h
View File

@ -4,6 +4,19 @@
#include <stdint.h>
#include <stddef.h>
// Platform-specific optimizations
// On AVR platforms, use flash memory to store static lookup tables, to conserve SRAM
#ifdef __AVR_ARCH__
#include <avr/pgmspace.h>
#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.