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

Remove EEPROM address argument from RNG.begin()

Always store the seed at the very end of EEPROM memory.
This commit is contained in:
Rhys Weatherley 2017-11-04 10:18:05 +10:00
parent 506af269b7
commit d452bea037
9 changed files with 32 additions and 39 deletions

View File

@ -133,8 +133,8 @@ all of the application's noise sources:
\code
void setup() {
// Initialize the random number generator with the application tag
// "MyApp 1.0" and load the previous seed from EEPROM address 950.
RNG.begin("MyApp 1.0", 950);
// "MyApp 1.0" and load the previous seed from EEPROM.
RNG.begin("MyApp 1.0");
// Add the noise source to the list of sources known to RNG.
RNG.addNoiseSource(noise);
@ -143,17 +143,16 @@ void setup() {
}
\endcode
The begin() function is passed two arguments: a tag string that should
be different for every application and an EEPROM address to use to
load and save the random number seed. The tag string ensures that
different applications and versions will generate different random numbers
upon first boot before the noise source has collected any entropy.
If the device also has a unique serial number or a MAC address, then
those can be mixed in during the setup() function after calling begin():
The begin() function is passed a tag string that should be different for
every application. The tag string ensures that different applications and
versions will generate different random numbers upon first boot before
the noise source has collected any entropy. If the device also has a unique
serial number or a MAC address, then those can be mixed in during the
setup() function after calling begin():
\code
void setup() {
RNG.begin("MyApp 1.0", 950);
RNG.begin("MyApp 1.0");
RNG.stir(serial_number, sizeof(serial_number));
RNG.stir(mac_address, sizeof(mac_address));
RNG.addNoiseSource(noise);
@ -161,8 +160,8 @@ void setup() {
}
\endcode
The random number generator needs 49 bytes of EEPROM space at the
specified address to store the previous seed. When the system is started
The random number generator uses 49 bytes of space at the end of
EEPROM memory to store the previous seed. When the system is started
next time, the previous saved seed is loaded and then deliberately
overwritten with a new seed. This ensures that the device will not
accidentally generate the same sequence of random numbers if it is

View File

@ -57,7 +57,7 @@ RNGClass::~RNGClass()
clean(stream);
}
void RNGClass::begin(const char *tag, int eepromAddress)
void RNGClass::begin(const char *tag)
{
}

View File

@ -35,6 +35,8 @@
#define RNG_WATCHDOG 1 // Harvest entropy from watchdog jitter.
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include <avr/io.h>
#define RNG_EEPROM_ADDRESS (E2END + 1 - RNGClass::SEED_SIZE)
#endif
#include <string.h>
@ -73,8 +75,8 @@
* Ethernet.begin(mac_address);
*
* // Initialize the random number generator with the application tag
* // "MyApp 1.0" and load the previous seed from EEPROM address 950.
* RNG.begin("MyApp 1.0", 950);
* // "MyApp 1.0" and load the previous seed from EEPROM.
* RNG.begin("MyApp 1.0");
*
* // Stir in the Ethernet MAC address.
* RNG.stir(mac_address, sizeof(mac_address));
@ -101,8 +103,8 @@
* \endcode
*
* The loop() function will automatically save the random number seed on a
* regular basis. By default the seed is saved every hour but this can be
* changed using setAutoSaveTime().
* regular basis to the last SEED_SIZE bytes of EEPROM memory. By default
* the seed is saved every hour but this can be changed using setAutoSaveTime().
*
* Keep in mind that saving too often may cause the EEPROM to wear out quicker.
* It is wise to limit saving to once an hour or once a day depending
@ -136,6 +138,9 @@ RNGClass RNG;
/**
* \var RNGClass::SEED_SIZE
* \brief Size of a saved random number seed in EEPROM space.
*
* The seed is saved into the last SEED_SIZE bytes of EEPROM memory.
* The address is dependent upon the size of EEPROM fitted in the device.
*/
// Number of ChaCha hash rounds to use for random number generation.
@ -228,8 +233,7 @@ ISR(WDT_vect)
* \sa begin()
*/
RNGClass::RNGClass()
: address(0)
, credits(0)
: credits(0)
, firstSave(1)
, timer(0)
, timeout(3600000UL) // 1 hour in milliseconds
@ -344,27 +348,19 @@ static void eraseAndWriteSeed()
* usually this should be a value that is unique to the application and
* version such as "MyApp 1.0" so that different applications do not
* generate the same sequence of values upon first boot.
* \param eepromAddress The EEPROM address to load the previously saved
* seed from and to save new seeds when save() is called. There must be
* at least SEED_SIZE (49) bytes of EEPROM space available at the address.
*
* This function should be followed by calls to addNoiseSource() to
* register the application's noise sources.
*
* The \a eepromAddress is ignored on the Arduino Due. The seed is instead
* stored in the last page of system flash memory.
*
* \sa addNoiseSource(), stir(), save()
*/
void RNGClass::begin(const char *tag, int eepromAddress)
void RNGClass::begin(const char *tag)
{
// Save the EEPROM address for use by save().
address = eepromAddress;
// Initialize the ChaCha20 input block from the saved seed.
memcpy_P(block, tagRNG, sizeof(tagRNG));
memcpy_P(block + 4, initRNG, sizeof(initRNG));
#if defined(RNG_EEPROM)
int address = RNG_EEPROM_ADDRESS;
if (eeprom_read_byte((const uint8_t *)address) == 'S') {
// We have a saved seed: XOR it with the initialization block.
for (int posn = 0; posn < 12; ++posn) {
@ -691,6 +687,7 @@ void RNGClass::save()
++(block[12]);
ChaCha::hashCore(stream, block, RNG_ROUNDS);
#if defined(RNG_EEPROM)
int address = RNG_EEPROM_ADDRESS;
eeprom_write_block(stream, (void *)(address + 1), 48);
eeprom_update_byte((uint8_t *)address, 'S');
#elif defined(RNG_DUE_TRNG)
@ -808,6 +805,7 @@ void RNGClass::destroy()
clean(block);
clean(stream);
#if defined(RNG_EEPROM)
int address = RNG_EEPROM_ADDRESS;
for (int posn = 0; posn < SEED_SIZE; ++posn)
eeprom_write_byte((uint8_t *)(address + posn), 0xFF);
#elif defined(RNG_DUE_TRNG)

View File

@ -34,7 +34,7 @@ public:
RNGClass();
~RNGClass();
void begin(const char *tag, int eepromAddress);
void begin(const char *tag);
void addNoiseSource(NoiseSource &source);
void setAutoSaveTime(uint16_t minutes);
@ -55,7 +55,6 @@ public:
private:
uint32_t block[16];
uint32_t stream[16];
int address;
uint16_t credits : 15;
uint16_t firstSave : 1;
unsigned long timer;

View File

@ -207,7 +207,7 @@ void setup()
// Start the random number generator. We don't initialise a noise
// source here because we don't need one for testing purposes.
// Real DH applications should of course use a proper noise source.
RNG.begin("TestCurve25519 1.0", 950);
RNG.begin("TestCurve25519 1.0");
// Perform the tests.
testEval();

View File

@ -173,7 +173,7 @@ void setup()
// Start the random number generator. We don't initialise a noise
// source here because we don't need one for testing purposes.
// Real applications should of course use a proper noise source.
RNG.begin("TestEd25519 1.0", 950);
RNG.begin("TestEd25519 1.0");
// Perform the tests.
testFixedVectors();

View File

@ -503,7 +503,7 @@ void setup()
// Start the random number generator. We don't initialise a noise
// source here because we don't need one for testing purposes.
// Real DH applications should of course use a proper noise source.
RNG.begin("TestP521 1.0", 950);
RNG.begin("TestP521 1.0");
// Perform the tests.
testEval();

View File

@ -11,9 +11,6 @@
// even if the input noise or seed data is otherwise identical.
#define RNG_APP_TAG "MyApp 1.0"
// EEPROM address to save the random number seed at.
#define RNG_EEPROM_ADDRESS 950
// Noise source to seed the random number generator.
TransistorNoiseSource noise(A1);
//RingOscillatorNoiseSource noise;
@ -28,7 +25,7 @@ void setup() {
Serial.println("start");
// Initialize the random number generator.
RNG.begin(RNG_APP_TAG, RNG_EEPROM_ADDRESS);
RNG.begin(RNG_APP_TAG);
// Add the noise source to the list of sources known to RNG.
RNG.addNoiseSource(noise);

View File

@ -908,7 +908,7 @@ void setup()
// Start the random number generator. We don't initialise a noise
// source here because we don't need one for testing purposes.
// Real applications should of course use a proper noise source.
RNG.begin("TestNewHope 1.0", 950);
RNG.begin("TestNewHope 1.0");
// Perform the tests.
Serial.println();