From d452bea0376a11ce1ca08914fcb341383aa69c5e Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Sat, 4 Nov 2017 10:18:05 +1000 Subject: [PATCH] Remove EEPROM address argument from RNG.begin() Always store the seed at the very end of EEPROM memory. --- doc/crypto-rng.dox | 23 +++++++------- host/Crypto/RNG_host.cpp | 2 +- libraries/Crypto/RNG.cpp | 30 +++++++++---------- libraries/Crypto/RNG.h | 3 +- .../TestCurve25519/TestCurve25519.ino | 2 +- .../examples/TestEd25519/TestEd25519.ino | 2 +- .../Crypto/examples/TestP521/TestP521.ino | 2 +- libraries/Crypto/examples/TestRNG/TestRNG.ino | 5 +--- .../examples/TestNewHope/TestNewHope.ino | 2 +- 9 files changed, 32 insertions(+), 39 deletions(-) diff --git a/doc/crypto-rng.dox b/doc/crypto-rng.dox index 462c03b9..1138705d 100644 --- a/doc/crypto-rng.dox +++ b/doc/crypto-rng.dox @@ -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 diff --git a/host/Crypto/RNG_host.cpp b/host/Crypto/RNG_host.cpp index 5f123903..c3fdfda6 100644 --- a/host/Crypto/RNG_host.cpp +++ b/host/Crypto/RNG_host.cpp @@ -57,7 +57,7 @@ RNGClass::~RNGClass() clean(stream); } -void RNGClass::begin(const char *tag, int eepromAddress) +void RNGClass::begin(const char *tag) { } diff --git a/libraries/Crypto/RNG.cpp b/libraries/Crypto/RNG.cpp index 8a218eab..c4226555 100644 --- a/libraries/Crypto/RNG.cpp +++ b/libraries/Crypto/RNG.cpp @@ -35,6 +35,8 @@ #define RNG_WATCHDOG 1 // Harvest entropy from watchdog jitter. #include #include +#include +#define RNG_EEPROM_ADDRESS (E2END + 1 - RNGClass::SEED_SIZE) #endif #include @@ -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) diff --git a/libraries/Crypto/RNG.h b/libraries/Crypto/RNG.h index 1e959573..426d6afe 100644 --- a/libraries/Crypto/RNG.h +++ b/libraries/Crypto/RNG.h @@ -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; diff --git a/libraries/Crypto/examples/TestCurve25519/TestCurve25519.ino b/libraries/Crypto/examples/TestCurve25519/TestCurve25519.ino index 51ca1798..9143359d 100644 --- a/libraries/Crypto/examples/TestCurve25519/TestCurve25519.ino +++ b/libraries/Crypto/examples/TestCurve25519/TestCurve25519.ino @@ -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(); diff --git a/libraries/Crypto/examples/TestEd25519/TestEd25519.ino b/libraries/Crypto/examples/TestEd25519/TestEd25519.ino index ec08bcb1..4f616cad 100644 --- a/libraries/Crypto/examples/TestEd25519/TestEd25519.ino +++ b/libraries/Crypto/examples/TestEd25519/TestEd25519.ino @@ -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(); diff --git a/libraries/Crypto/examples/TestP521/TestP521.ino b/libraries/Crypto/examples/TestP521/TestP521.ino index 50832c6a..20c03142 100644 --- a/libraries/Crypto/examples/TestP521/TestP521.ino +++ b/libraries/Crypto/examples/TestP521/TestP521.ino @@ -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(); diff --git a/libraries/Crypto/examples/TestRNG/TestRNG.ino b/libraries/Crypto/examples/TestRNG/TestRNG.ino index 9141c442..196cf4d3 100644 --- a/libraries/Crypto/examples/TestRNG/TestRNG.ino +++ b/libraries/Crypto/examples/TestRNG/TestRNG.ino @@ -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); diff --git a/libraries/NewHope/examples/TestNewHope/TestNewHope.ino b/libraries/NewHope/examples/TestNewHope/TestNewHope.ino index 8db4e0e4..0c811593 100644 --- a/libraries/NewHope/examples/TestNewHope/TestNewHope.ino +++ b/libraries/NewHope/examples/TestNewHope/TestNewHope.ino @@ -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();