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:
parent
506af269b7
commit
d452bea037
@ -133,8 +133,8 @@ all of the application's noise sources:
|
|||||||
\code
|
\code
|
||||||
void setup() {
|
void setup() {
|
||||||
// Initialize the random number generator with the application tag
|
// Initialize the random number generator with the application tag
|
||||||
// "MyApp 1.0" and load the previous seed from EEPROM address 950.
|
// "MyApp 1.0" and load the previous seed from EEPROM.
|
||||||
RNG.begin("MyApp 1.0", 950);
|
RNG.begin("MyApp 1.0");
|
||||||
|
|
||||||
// Add the noise source to the list of sources known to RNG.
|
// Add the noise source to the list of sources known to RNG.
|
||||||
RNG.addNoiseSource(noise);
|
RNG.addNoiseSource(noise);
|
||||||
@ -143,17 +143,16 @@ void setup() {
|
|||||||
}
|
}
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
The begin() function is passed two arguments: a tag string that should
|
The begin() function is passed a tag string that should be different for
|
||||||
be different for every application and an EEPROM address to use to
|
every application. The tag string ensures that different applications and
|
||||||
load and save the random number seed. The tag string ensures that
|
versions will generate different random numbers upon first boot before
|
||||||
different applications and versions will generate different random numbers
|
the noise source has collected any entropy. If the device also has a unique
|
||||||
upon first boot before the noise source has collected any entropy.
|
serial number or a MAC address, then those can be mixed in during the
|
||||||
If the device also has a unique serial number or a MAC address, then
|
setup() function after calling begin():
|
||||||
those can be mixed in during the setup() function after calling begin():
|
|
||||||
|
|
||||||
\code
|
\code
|
||||||
void setup() {
|
void setup() {
|
||||||
RNG.begin("MyApp 1.0", 950);
|
RNG.begin("MyApp 1.0");
|
||||||
RNG.stir(serial_number, sizeof(serial_number));
|
RNG.stir(serial_number, sizeof(serial_number));
|
||||||
RNG.stir(mac_address, sizeof(mac_address));
|
RNG.stir(mac_address, sizeof(mac_address));
|
||||||
RNG.addNoiseSource(noise);
|
RNG.addNoiseSource(noise);
|
||||||
@ -161,8 +160,8 @@ void setup() {
|
|||||||
}
|
}
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
The random number generator needs 49 bytes of EEPROM space at the
|
The random number generator uses 49 bytes of space at the end of
|
||||||
specified address to store the previous seed. When the system is started
|
EEPROM memory to store the previous seed. When the system is started
|
||||||
next time, the previous saved seed is loaded and then deliberately
|
next time, the previous saved seed is loaded and then deliberately
|
||||||
overwritten with a new seed. This ensures that the device will not
|
overwritten with a new seed. This ensures that the device will not
|
||||||
accidentally generate the same sequence of random numbers if it is
|
accidentally generate the same sequence of random numbers if it is
|
||||||
|
@ -57,7 +57,7 @@ RNGClass::~RNGClass()
|
|||||||
clean(stream);
|
clean(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RNGClass::begin(const char *tag, int eepromAddress)
|
void RNGClass::begin(const char *tag)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
#define RNG_WATCHDOG 1 // Harvest entropy from watchdog jitter.
|
#define RNG_WATCHDOG 1 // Harvest entropy from watchdog jitter.
|
||||||
#include <avr/eeprom.h>
|
#include <avr/eeprom.h>
|
||||||
#include <avr/wdt.h>
|
#include <avr/wdt.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#define RNG_EEPROM_ADDRESS (E2END + 1 - RNGClass::SEED_SIZE)
|
||||||
#endif
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -73,8 +75,8 @@
|
|||||||
* Ethernet.begin(mac_address);
|
* Ethernet.begin(mac_address);
|
||||||
*
|
*
|
||||||
* // Initialize the random number generator with the application tag
|
* // Initialize the random number generator with the application tag
|
||||||
* // "MyApp 1.0" and load the previous seed from EEPROM address 950.
|
* // "MyApp 1.0" and load the previous seed from EEPROM.
|
||||||
* RNG.begin("MyApp 1.0", 950);
|
* RNG.begin("MyApp 1.0");
|
||||||
*
|
*
|
||||||
* // Stir in the Ethernet MAC address.
|
* // Stir in the Ethernet MAC address.
|
||||||
* RNG.stir(mac_address, sizeof(mac_address));
|
* RNG.stir(mac_address, sizeof(mac_address));
|
||||||
@ -101,8 +103,8 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
* The loop() function will automatically save the random number seed on a
|
* 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
|
* regular basis to the last SEED_SIZE bytes of EEPROM memory. By default
|
||||||
* changed using setAutoSaveTime().
|
* 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.
|
* 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
|
* 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
|
* \var RNGClass::SEED_SIZE
|
||||||
* \brief Size of a saved random number seed in EEPROM space.
|
* \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.
|
// Number of ChaCha hash rounds to use for random number generation.
|
||||||
@ -228,8 +233,7 @@ ISR(WDT_vect)
|
|||||||
* \sa begin()
|
* \sa begin()
|
||||||
*/
|
*/
|
||||||
RNGClass::RNGClass()
|
RNGClass::RNGClass()
|
||||||
: address(0)
|
: credits(0)
|
||||||
, credits(0)
|
|
||||||
, firstSave(1)
|
, firstSave(1)
|
||||||
, timer(0)
|
, timer(0)
|
||||||
, timeout(3600000UL) // 1 hour in milliseconds
|
, 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
|
* 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
|
* version such as "MyApp 1.0" so that different applications do not
|
||||||
* generate the same sequence of values upon first boot.
|
* 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
|
* This function should be followed by calls to addNoiseSource() to
|
||||||
* register the application's noise sources.
|
* 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()
|
* \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.
|
// Initialize the ChaCha20 input block from the saved seed.
|
||||||
memcpy_P(block, tagRNG, sizeof(tagRNG));
|
memcpy_P(block, tagRNG, sizeof(tagRNG));
|
||||||
memcpy_P(block + 4, initRNG, sizeof(initRNG));
|
memcpy_P(block + 4, initRNG, sizeof(initRNG));
|
||||||
#if defined(RNG_EEPROM)
|
#if defined(RNG_EEPROM)
|
||||||
|
int address = RNG_EEPROM_ADDRESS;
|
||||||
if (eeprom_read_byte((const uint8_t *)address) == 'S') {
|
if (eeprom_read_byte((const uint8_t *)address) == 'S') {
|
||||||
// We have a saved seed: XOR it with the initialization block.
|
// We have a saved seed: XOR it with the initialization block.
|
||||||
for (int posn = 0; posn < 12; ++posn) {
|
for (int posn = 0; posn < 12; ++posn) {
|
||||||
@ -691,6 +687,7 @@ void RNGClass::save()
|
|||||||
++(block[12]);
|
++(block[12]);
|
||||||
ChaCha::hashCore(stream, block, RNG_ROUNDS);
|
ChaCha::hashCore(stream, block, RNG_ROUNDS);
|
||||||
#if defined(RNG_EEPROM)
|
#if defined(RNG_EEPROM)
|
||||||
|
int address = RNG_EEPROM_ADDRESS;
|
||||||
eeprom_write_block(stream, (void *)(address + 1), 48);
|
eeprom_write_block(stream, (void *)(address + 1), 48);
|
||||||
eeprom_update_byte((uint8_t *)address, 'S');
|
eeprom_update_byte((uint8_t *)address, 'S');
|
||||||
#elif defined(RNG_DUE_TRNG)
|
#elif defined(RNG_DUE_TRNG)
|
||||||
@ -808,6 +805,7 @@ void RNGClass::destroy()
|
|||||||
clean(block);
|
clean(block);
|
||||||
clean(stream);
|
clean(stream);
|
||||||
#if defined(RNG_EEPROM)
|
#if defined(RNG_EEPROM)
|
||||||
|
int address = RNG_EEPROM_ADDRESS;
|
||||||
for (int posn = 0; posn < SEED_SIZE; ++posn)
|
for (int posn = 0; posn < SEED_SIZE; ++posn)
|
||||||
eeprom_write_byte((uint8_t *)(address + posn), 0xFF);
|
eeprom_write_byte((uint8_t *)(address + posn), 0xFF);
|
||||||
#elif defined(RNG_DUE_TRNG)
|
#elif defined(RNG_DUE_TRNG)
|
||||||
|
@ -34,7 +34,7 @@ public:
|
|||||||
RNGClass();
|
RNGClass();
|
||||||
~RNGClass();
|
~RNGClass();
|
||||||
|
|
||||||
void begin(const char *tag, int eepromAddress);
|
void begin(const char *tag);
|
||||||
void addNoiseSource(NoiseSource &source);
|
void addNoiseSource(NoiseSource &source);
|
||||||
|
|
||||||
void setAutoSaveTime(uint16_t minutes);
|
void setAutoSaveTime(uint16_t minutes);
|
||||||
@ -55,7 +55,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
uint32_t block[16];
|
uint32_t block[16];
|
||||||
uint32_t stream[16];
|
uint32_t stream[16];
|
||||||
int address;
|
|
||||||
uint16_t credits : 15;
|
uint16_t credits : 15;
|
||||||
uint16_t firstSave : 1;
|
uint16_t firstSave : 1;
|
||||||
unsigned long timer;
|
unsigned long timer;
|
||||||
|
@ -207,7 +207,7 @@ void setup()
|
|||||||
// Start the random number generator. We don't initialise a noise
|
// Start the random number generator. We don't initialise a noise
|
||||||
// source here because we don't need one for testing purposes.
|
// source here because we don't need one for testing purposes.
|
||||||
// Real DH applications should of course use a proper noise source.
|
// 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.
|
// Perform the tests.
|
||||||
testEval();
|
testEval();
|
||||||
|
@ -173,7 +173,7 @@ void setup()
|
|||||||
// Start the random number generator. We don't initialise a noise
|
// Start the random number generator. We don't initialise a noise
|
||||||
// source here because we don't need one for testing purposes.
|
// source here because we don't need one for testing purposes.
|
||||||
// Real applications should of course use a proper noise source.
|
// Real applications should of course use a proper noise source.
|
||||||
RNG.begin("TestEd25519 1.0", 950);
|
RNG.begin("TestEd25519 1.0");
|
||||||
|
|
||||||
// Perform the tests.
|
// Perform the tests.
|
||||||
testFixedVectors();
|
testFixedVectors();
|
||||||
|
@ -503,7 +503,7 @@ void setup()
|
|||||||
// Start the random number generator. We don't initialise a noise
|
// Start the random number generator. We don't initialise a noise
|
||||||
// source here because we don't need one for testing purposes.
|
// source here because we don't need one for testing purposes.
|
||||||
// Real DH applications should of course use a proper noise source.
|
// 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.
|
// Perform the tests.
|
||||||
testEval();
|
testEval();
|
||||||
|
@ -11,9 +11,6 @@
|
|||||||
// even if the input noise or seed data is otherwise identical.
|
// even if the input noise or seed data is otherwise identical.
|
||||||
#define RNG_APP_TAG "MyApp 1.0"
|
#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.
|
// Noise source to seed the random number generator.
|
||||||
TransistorNoiseSource noise(A1);
|
TransistorNoiseSource noise(A1);
|
||||||
//RingOscillatorNoiseSource noise;
|
//RingOscillatorNoiseSource noise;
|
||||||
@ -28,7 +25,7 @@ void setup() {
|
|||||||
Serial.println("start");
|
Serial.println("start");
|
||||||
|
|
||||||
// Initialize the random number generator.
|
// 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.
|
// Add the noise source to the list of sources known to RNG.
|
||||||
RNG.addNoiseSource(noise);
|
RNG.addNoiseSource(noise);
|
||||||
|
@ -908,7 +908,7 @@ void setup()
|
|||||||
// Start the random number generator. We don't initialise a noise
|
// Start the random number generator. We don't initialise a noise
|
||||||
// source here because we don't need one for testing purposes.
|
// source here because we don't need one for testing purposes.
|
||||||
// Real applications should of course use a proper noise source.
|
// Real applications should of course use a proper noise source.
|
||||||
RNG.begin("TestNewHope 1.0", 950);
|
RNG.begin("TestNewHope 1.0");
|
||||||
|
|
||||||
// Perform the tests.
|
// Perform the tests.
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user