1
0
mirror of https://github.com/taigrr/arduinolibs synced 2025-01-18 04:33:12 -08:00

Move static tables into program space

This commit is contained in:
Rhys Weatherley 2015-01-04 08:32:01 +10:00
parent 9fe7854d0f
commit c009d4a2b4
4 changed files with 88 additions and 50 deletions

View File

@ -22,6 +22,7 @@
#include "AES.h" #include "AES.h"
#include "Crypto.h" #include "Crypto.h"
#include "ProgMemUtil.h"
/** /**
* \class AESCommon AES.h <AES.h> * \class AESCommon AES.h <AES.h>
@ -43,7 +44,7 @@
*/ */
// AES S-box (http://en.wikipedia.org/wiki/Rijndael_S-box) // AES S-box (http://en.wikipedia.org/wiki/Rijndael_S-box)
static uint8_t const sbox[256] = { static uint8_t const sbox[256] PROGMEM = {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, // 0x00 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, // 0x00
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, // 0x10 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, // 0x10
@ -79,7 +80,7 @@ static uint8_t const sbox[256] = {
}; };
// AES inverse S-box (http://en.wikipedia.org/wiki/Rijndael_S-box) // AES inverse S-box (http://en.wikipedia.org/wiki/Rijndael_S-box)
static uint8_t const sbox_inverse[256] = { static uint8_t const sbox_inverse[256] PROGMEM = {
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, // 0x00 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, // 0x00
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, // 0x10 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, // 0x10
@ -178,42 +179,42 @@ static uint8_t const K[8] = {
static void subBytesAndShiftRows(uint8_t *output, const uint8_t *input) static void subBytesAndShiftRows(uint8_t *output, const uint8_t *input)
{ {
OUT(0, 0) = sbox[IN(0, 0)]; OUT(0, 0) = pgm_read_byte(sbox + IN(0, 0));
OUT(0, 1) = sbox[IN(1, 1)]; OUT(0, 1) = pgm_read_byte(sbox + IN(1, 1));
OUT(0, 2) = sbox[IN(2, 2)]; OUT(0, 2) = pgm_read_byte(sbox + IN(2, 2));
OUT(0, 3) = sbox[IN(3, 3)]; OUT(0, 3) = pgm_read_byte(sbox + IN(3, 3));
OUT(1, 0) = sbox[IN(1, 0)]; OUT(1, 0) = pgm_read_byte(sbox + IN(1, 0));
OUT(1, 1) = sbox[IN(2, 1)]; OUT(1, 1) = pgm_read_byte(sbox + IN(2, 1));
OUT(1, 2) = sbox[IN(3, 2)]; OUT(1, 2) = pgm_read_byte(sbox + IN(3, 2));
OUT(1, 3) = sbox[IN(0, 3)]; OUT(1, 3) = pgm_read_byte(sbox + IN(0, 3));
OUT(2, 0) = sbox[IN(2, 0)]; OUT(2, 0) = pgm_read_byte(sbox + IN(2, 0));
OUT(2, 1) = sbox[IN(3, 1)]; OUT(2, 1) = pgm_read_byte(sbox + IN(3, 1));
OUT(2, 2) = sbox[IN(0, 2)]; OUT(2, 2) = pgm_read_byte(sbox + IN(0, 2));
OUT(2, 3) = sbox[IN(1, 3)]; OUT(2, 3) = pgm_read_byte(sbox + IN(1, 3));
OUT(3, 0) = sbox[IN(3, 0)]; OUT(3, 0) = pgm_read_byte(sbox + IN(3, 0));
OUT(3, 1) = sbox[IN(0, 1)]; OUT(3, 1) = pgm_read_byte(sbox + IN(0, 1));
OUT(3, 2) = sbox[IN(1, 2)]; OUT(3, 2) = pgm_read_byte(sbox + IN(1, 2));
OUT(3, 3) = sbox[IN(2, 3)]; OUT(3, 3) = pgm_read_byte(sbox + IN(2, 3));
} }
static void inverseShiftRowsAndSubBytes(uint8_t *output, const uint8_t *input) static void inverseShiftRowsAndSubBytes(uint8_t *output, const uint8_t *input)
{ {
OUT(0, 0) = sbox_inverse[IN(0, 0)]; OUT(0, 0) = pgm_read_byte(sbox_inverse + IN(0, 0));
OUT(0, 1) = sbox_inverse[IN(3, 1)]; OUT(0, 1) = pgm_read_byte(sbox_inverse + IN(3, 1));
OUT(0, 2) = sbox_inverse[IN(2, 2)]; OUT(0, 2) = pgm_read_byte(sbox_inverse + IN(2, 2));
OUT(0, 3) = sbox_inverse[IN(1, 3)]; OUT(0, 3) = pgm_read_byte(sbox_inverse + IN(1, 3));
OUT(1, 0) = sbox_inverse[IN(1, 0)]; OUT(1, 0) = pgm_read_byte(sbox_inverse + IN(1, 0));
OUT(1, 1) = sbox_inverse[IN(0, 1)]; OUT(1, 1) = pgm_read_byte(sbox_inverse + IN(0, 1));
OUT(1, 2) = sbox_inverse[IN(3, 2)]; OUT(1, 2) = pgm_read_byte(sbox_inverse + IN(3, 2));
OUT(1, 3) = sbox_inverse[IN(2, 3)]; OUT(1, 3) = pgm_read_byte(sbox_inverse + IN(2, 3));
OUT(2, 0) = sbox_inverse[IN(2, 0)]; OUT(2, 0) = pgm_read_byte(sbox_inverse + IN(2, 0));
OUT(2, 1) = sbox_inverse[IN(1, 1)]; OUT(2, 1) = pgm_read_byte(sbox_inverse + IN(1, 1));
OUT(2, 2) = sbox_inverse[IN(0, 2)]; OUT(2, 2) = pgm_read_byte(sbox_inverse + IN(0, 2));
OUT(2, 3) = sbox_inverse[IN(3, 3)]; OUT(2, 3) = pgm_read_byte(sbox_inverse + IN(3, 3));
OUT(3, 0) = sbox_inverse[IN(3, 0)]; OUT(3, 0) = pgm_read_byte(sbox_inverse + IN(3, 0));
OUT(3, 1) = sbox_inverse[IN(2, 1)]; OUT(3, 1) = pgm_read_byte(sbox_inverse + IN(2, 1));
OUT(3, 2) = sbox_inverse[IN(1, 2)]; OUT(3, 2) = pgm_read_byte(sbox_inverse + IN(1, 2));
OUT(3, 3) = sbox_inverse[IN(0, 3)]; OUT(3, 3) = pgm_read_byte(sbox_inverse + IN(0, 3));
} }
static void mixColumn(uint8_t *output, uint8_t *input) static void mixColumn(uint8_t *output, uint8_t *input)
@ -329,22 +330,22 @@ void AESCommon::keyScheduleCore(uint8_t *output, const uint8_t *input, uint8_t i
{ {
// Rcon(i), 2^i in the Rijndael finite field, for i = 0..10. // Rcon(i), 2^i in the Rijndael finite field, for i = 0..10.
// http://en.wikipedia.org/wiki/Rijndael_key_schedule // http://en.wikipedia.org/wiki/Rijndael_key_schedule
static uint8_t const rcon[11] = { static uint8_t const rcon[11] PROGMEM = {
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, // 0x00 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, // 0x00
0x80, 0x1B, 0x36 0x80, 0x1B, 0x36
}; };
output[0] = sbox[input[1]] ^ rcon[iteration]; output[0] = pgm_read_byte(sbox + input[1]) ^ pgm_read_byte(rcon + iteration);
output[1] = sbox[input[2]]; output[1] = pgm_read_byte(sbox + input[2]);
output[2] = sbox[input[3]]; output[2] = pgm_read_byte(sbox + input[3]);
output[3] = sbox[input[0]]; output[3] = pgm_read_byte(sbox + input[0]);
} }
void AESCommon::applySbox(uint8_t *output, const uint8_t *input) void AESCommon::applySbox(uint8_t *output, const uint8_t *input)
{ {
output[0] = sbox[input[0]]; output[0] = pgm_read_byte(sbox + input[0]);
output[1] = sbox[input[1]]; output[1] = pgm_read_byte(sbox + input[1]);
output[2] = sbox[input[2]]; output[2] = pgm_read_byte(sbox + input[2]);
output[3] = sbox[input[3]]; output[3] = pgm_read_byte(sbox + input[3]);
} }
/** @endcond */ /** @endcond */

View File

@ -24,6 +24,7 @@
#include "Crypto.h" #include "Crypto.h"
#include "RotateUtil.h" #include "RotateUtil.h"
#include "EndianUtil.h" #include "EndianUtil.h"
#include "ProgMemUtil.h"
#include <string.h> #include <string.h>
/** /**
@ -85,10 +86,10 @@ size_t ChaCha::ivSize() const
bool ChaCha::setKey(const uint8_t *key, size_t len) bool ChaCha::setKey(const uint8_t *key, size_t len)
{ {
static const char tag128[] = "expand 16-byte k"; static const char tag128[] PROGMEM = "expand 16-byte k";
static const char tag256[] = "expand 32-byte k"; static const char tag256[] PROGMEM = "expand 32-byte k";
if (len <= 16) { if (len <= 16) {
memcpy(block, tag128, 16); memcpy_P(block, tag128, 16);
memcpy(block + 16, key, len); memcpy(block + 16, key, len);
memcpy(block + 32, key, len); memcpy(block + 32, key, len);
if (len < 16) { if (len < 16) {
@ -98,7 +99,7 @@ bool ChaCha::setKey(const uint8_t *key, size_t len)
} else { } else {
if (len > 32) if (len > 32)
len = 32; len = 32;
memcpy(block, tag256, 16); memcpy_P(block, tag256, 16);
memcpy(block + 16, key, len); memcpy(block + 16, key, len);
if (len < 32) if (len < 32)
memset(block + 16 + len, 0, 32 - len); memset(block + 16 + len, 0, 32 - len);

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2015 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef CRYPTO_PROGMEMUTIL_H
#define CRYPTO_PROGMEMUTIL_H
#if defined(__AVR__)
#include <avr/pgmspace.h>
#else
#define PROGMEM
#define pgm_read_byte(x) (*(x))
#define pgm_read_word(x) (*(x))
#define pgm_read_dword(x) (*(x))
#endif
#endif

View File

@ -24,6 +24,7 @@
#include "Crypto.h" #include "Crypto.h"
#include "RotateUtil.h" #include "RotateUtil.h"
#include "EndianUtil.h" #include "EndianUtil.h"
#include "ProgMemUtil.h"
#include <string.h> #include <string.h>
/** /**
@ -152,7 +153,7 @@ void SHA256::clear()
void SHA256::processChunk() void SHA256::processChunk()
{ {
// Round constants for SHA-256. // Round constants for SHA-256.
static uint32_t const k[64] = { static uint32_t const k[64] PROGMEM = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
@ -189,7 +190,7 @@ void SHA256::processChunk()
// Perform the first 16 rounds of the compression function main loop. // Perform the first 16 rounds of the compression function main loop.
uint32_t temp1, temp2; uint32_t temp1, temp2;
for (index = 0; index < 16; ++index) { for (index = 0; index < 16; ++index) {
temp1 = h + k[index] + state.w[index] + temp1 = h + pgm_read_dword(k + index) + state.w[index] +
(rightRotate6(e) ^ rightRotate11(e) ^ rightRotate25(e)) + (rightRotate6(e) ^ rightRotate11(e) ^ rightRotate25(e)) +
((e & f) ^ ((~e) & g)); ((e & f) ^ ((~e) & g));
temp2 = (rightRotate2(a) ^ rightRotate13(a) ^ rightRotate22(a)) + temp2 = (rightRotate2(a) ^ rightRotate13(a) ^ rightRotate22(a)) +
@ -217,7 +218,7 @@ void SHA256::processChunk()
(rightRotate17(temp2) ^ rightRotate19(temp2) ^ (temp2 >> 10)); (rightRotate17(temp2) ^ rightRotate19(temp2) ^ (temp2 >> 10));
// Perform the round. // Perform the round.
temp1 = h + k[index] + temp1 + temp1 = h + pgm_read_dword(k + index) + temp1 +
(rightRotate6(e) ^ rightRotate11(e) ^ rightRotate25(e)) + (rightRotate6(e) ^ rightRotate11(e) ^ rightRotate25(e)) +
((e & f) ^ ((~e) & g)); ((e & f) ^ ((~e) & g));
temp2 = (rightRotate2(a) ^ rightRotate13(a) ^ rightRotate22(a)) + temp2 = (rightRotate2(a) ^ rightRotate13(a) ^ rightRotate22(a)) +