Arduino Cryptography Library
RNG.cpp
1 /*
2  * Copyright (C) 2015 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "RNG.h"
24 #include "NoiseSource.h"
25 #include "ChaCha.h"
26 #include "Crypto.h"
27 #include <Arduino.h>
28 #include "utility/ProgMemUtil.h"
29 #if defined (__arm__) && defined (__SAM3X8E__)
30 // The Arduino Due does not have any EEPROM natively on the main chip.
31 // However, it does have a TRNG and flash memory.
32 #define RNG_DUE_TRNG 1
33 #elif defined(__AVR__)
34 #include <avr/eeprom.h>
35 #include <avr/wdt.h>
36 #include <avr/io.h>
37 #define RNG_EEPROM 1 // Use EEPROM to save the seed.
38 #if defined(MEGATINYCORE) || defined(LOGIC_H) // If device is Modern AVR with CCL
39 /* This is a highly unconventional use of Configurable Custom Logic to
40  * create an incredibly unstable clock. The speed that this clock runs
41  * is highly dependant on CPU frequency, temperature and other factors.
42  * Attempting to determine the speed of this clock at any point in time
43  * with an oscilliscope results in a reading that bounces uncontrollably.
44  * Since we have CCL counting at a very unpredictable rate, it cannot
45  * be known what the value will be whem the Real Time Counter is triggered.
46  *
47  * Thanks to Spence Konde for the design of the unstable CCL Clock and
48  * Brad Bock for implementing it for random number generation.
49  */
50 #define RNG_CCL 1 // Harvest entropy from Configurable Custom Logic.
51 #elif defined(TCNT1L) || defined(TCNT0L) || defined(TCNT0)
52 #define RNG_WATCHDOG 1 // Harvest entropy from watchdog jitter.
53 #endif
54 
55 #define RNG_EEPROM_ADDRESS (E2END + 1 - RNGClass::SEED_SIZE)
56 #elif defined(ESP8266)
57 // ESP8266 does not have EEPROM but it does have SPI flash memory.
58 // It also has a TRNG register for generating "true" random numbers.
59 // For now we use the TRNG but don't save the seed in flash memory.
60 #define RNG_WORD_TRNG 1
61 #define RNG_WORD_TRNG_GET() (ESP8266_DREG(0x20E44))
62 #elif defined(ESP32)
63 // ESP32 has a word-based TRNG and an API for Non-Volatile Storage (NVS).
64 #define RNG_WORD_TRNG 1
65 #define RNG_WORD_TRNG_GET() (esp_random())
66 #define RNG_ESP_NVS 1
67 #include <nvs.h>
68 #endif
69 #include <string.h>
70 
71 // Throw a warning if there is no built-in hardware random number source.
72 // If this happens, then you need to do one of two things:
73 // 1. Edit RNG.cpp to add your platform's hardware TRNG.
74 // 2. Provide a proper noise source like TransistorNoiseSource
75 // in your sketch and then comment out the #warning line below.
76 #if !defined(RNG_DUE_TRNG) && \
77  !defined(RNG_WATCHDOG) && \
78  !defined(RNG_WORD_TRNG) && \
79  !defined(RNG_CCL)
80 #warning "no hardware random number source detected for this platform"
81 #endif
82 
176 RNGClass RNG;
177 
186 // Number of ChaCha hash rounds to use for random number generation.
187 #define RNG_ROUNDS 20
188 
189 // Force a rekey after this many blocks of random data.
190 #define RNG_REKEY_BLOCKS 16
191 
192 // Maximum entropy credit that can be contained in the pool.
193 #define RNG_MAX_CREDITS 384u
194 
197 // Imported from Crypto.cpp.
198 extern uint8_t crypto_crc8(uint8_t tag, const void *data, unsigned size);
199 
200 // Tag for 256-bit ChaCha20 keys. This will always appear in the
201 // first 16 bytes of the block. The remaining 48 bytes are the seed.
202 static const char tagRNG[16] PROGMEM = {
203  'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
204  '2', '-', 'b', 'y', 't', 'e', ' ', 'k'
205 };
206 
207 // Initialization seed. This is the ChaCha20 output of hashing
208 // "expand 32-byte k" followed by 48 bytes set to the numbers 1 to 48.
209 // The ChaCha20 output block is then truncated to the first 48 bytes.
210 //
211 // This value is intended to start the RNG in a semi-chaotic state if
212 // we don't have a previously saved seed in EEPROM.
213 static const uint8_t initRNG[48] PROGMEM = {
214  0xB0, 0x2A, 0xAE, 0x7D, 0xEE, 0xCB, 0xBB, 0xB1,
215  0xFC, 0x03, 0x6F, 0xDD, 0xDC, 0x7D, 0x76, 0x67,
216  0x0C, 0xE8, 0x1F, 0x0D, 0xA3, 0xA0, 0xAA, 0x1E,
217  0xB0, 0xBD, 0x72, 0x6B, 0x2B, 0x4C, 0x8A, 0x7E,
218  0x34, 0xFC, 0x37, 0x60, 0xF4, 0x1E, 0x22, 0xA0,
219  0x0B, 0xFB, 0x18, 0x84, 0x60, 0xA5, 0x77, 0x72
220 };
221 
222 #if defined(RNG_WATCHDOG)
223 
224 // Use jitter between the watchdog timer and the main CPU clock to
225 // harvest some entropy on AVR-based systems. This technique comes from:
226 //
227 // https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library
228 //
229 // The watchdog generates entropy very slowly - it can take around 32 seconds
230 // to generate 256 bits of entropy credit. This is a "better than nothing"
231 // entropy source but a real noise source is definitely recommended.
232 
233 // Helper macros for specific 32-bit shift counts.
234 #define leftShift3(value) ((value) << 3)
235 #define leftShift10(value) ((value) << 10)
236 #define leftShift15(value) ((value) << 15)
237 #define rightShift6(value) ((value) >> 6)
238 #define rightShift11(value) ((value) >> 11)
239 
240 static uint32_t volatile hash = 0;
241 static uint8_t volatile outBits = 0;
242 
243 // Watchdog interrupt handler. This fires off every 16ms. We collect
244 // 32 bits and then pass them off onto RNGClass::loop().
245 ISR(WDT_vect)
246 {
247  // Read the low byte of Timer 1. We assume that the timer was
248  // initialized by the Arduino startup code for PWM use or that the
249  // application is free-running Timer 1 for its own purposes.
250  // Timer 0 is used on systems that don't have a Timer 1.
251 #if defined(TCNT1L)
252  unsigned char value = TCNT1L;
253 #elif defined(TCNT0L)
254  unsigned char value = TCNT0L;
255 #else
256  unsigned char value = TCNT0;
257 #endif
258  // Use Jenkin's one-at-a-time hash function to scatter the entropy a bit.
259  // https://en.wikipedia.org/wiki/Jenkins_hash_function
260  hash += value;
261  hash += leftShift10(hash);
262  hash ^= rightShift6(hash);
263  ++outBits;
264 }
265 
266 #elif defined(RNG_CCL)
267 
268 // Helper macros for specific 32-bit shift counts.
269 #define leftShift3(value) ((value) << 3)
270 #define leftShift10(value) ((value) << 10)
271 #define leftShift15(value) ((value) << 15)
272 #define rightShift6(value) ((value) >> 6)
273 #define rightShift11(value) ((value) >> 11)
274 
275 static uint32_t volatile hash = 0;
276 static uint8_t volatile outBits = 0;
277 
278 // Interrupt to keep this incredibly unstable CCL Clock going
279 ISR(TCB0_INT_vect)
280 {
281  uint8_t temp = TCB0.INTFLAGS;
282  if (temp & 1) {
283  VPORTA.IN |= 2;
284  }
285  TCB0.INTFLAGS=temp;
286 }
287 
288 // Overflow Interrupt from the stable Real Time Counter
289 ISR(RTC_CNT_vect)
290 {
291  RTC_INTFLAGS = RTC_OVF_bm; // Clear the flag
292  unsigned char value = (TCB0.CNT); // Value of CCL Counter
293  hash += value;
294  hash += leftShift10(hash);
295  hash ^= rightShift6(hash);
296  ++outBits;
297 }
298 
299 #endif
300 
312  : credits(0)
313  , firstSave(1)
314  , initialized(0)
315  , trngPending(0)
316  , timer(0)
317  , timeout(3600000UL) // 1 hour in milliseconds
318  , count(0)
319  , trngPosn(0)
320 {
321 }
322 
327 {
328 #if defined(RNG_DUE_TRNG)
329  // Disable the TRNG in the Arduino Due.
330  REG_TRNG_CR = TRNG_CR_KEY(0x524E47);
331 #endif
332 #if defined(RNG_WATCHDOG)
333  // Disable interrupts and reset the watchdog.
334  cli();
335  wdt_reset();
336 
337  // Clear the "reset due to watchdog" flag.
338  MCUSR &= ~(1 << WDRF);
339 
340  // Disable the watchdog.
341  _WD_CONTROL_REG |= (1 << _WD_CHANGE_BIT) | (1 << WDE);
342  _WD_CONTROL_REG = 0;
343 
344  // Re-enable interrupts. The watchdog should be stopped.
345  sei();
346 #elif defined(RNG_CCL)
347  CCL.CTRLA = 0x00; // disable CCL
348  RTC.CTRLA = 0x00; // disable RTC
349 #endif
350  clean(block);
351  clean(stream);
352 }
353 
354 #if defined(RNG_DUE_TRNG)
355 
356 // Find the flash memory of interest. Allow for the possibility
357 // of other SAM-based Arduino variants in the future.
358 #if defined(IFLASH1_ADDR)
359 #define RNG_FLASH_ADDR IFLASH1_ADDR
360 #define RNG_FLASH_SIZE IFLASH1_SIZE
361 #define RNG_FLASH_PAGE_SIZE IFLASH1_PAGE_SIZE
362 #define RNG_EFC EFC1
363 #elif defined(IFLASH0_ADDR)
364 #define RNG_FLASH_ADDR IFLASH0_ADDR
365 #define RNG_FLASH_SIZE IFLASH0_SIZE
366 #define RNG_FLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
367 #define RNG_EFC EFC0
368 #else
369 #define RNG_FLASH_ADDR IFLASH_ADDR
370 #define RNG_FLASH_SIZE IFLASH_SIZE
371 #define RNG_FLASH_PAGE_SIZE IFLASH_PAGE_SIZE
372 #define RNG_EFC EFC
373 #endif
374 
375 // Address of the flash page to use for saving the seed on the Due.
376 // All SAM variants have a page size of 256 bytes or greater so there is
377 // plenty of room for the 48 byte seed in the last page of flash memory.
378 #define RNG_SEED_ADDR (RNG_FLASH_ADDR + RNG_FLASH_SIZE - RNG_FLASH_PAGE_SIZE)
379 #define RNG_SEED_PAGE ((RNG_FLASH_SIZE / RNG_FLASH_PAGE_SIZE) - 1)
380 
381 // Stir in the unique identifier for the Arduino Due's CPU.
382 // This function must be in RAM because programs running out of
383 // flash memory are not allowed to access the unique identifier.
384 // Info from: http://forum.arduino.cc/index.php?topic=289190.0
385 __attribute__((section(".ramfunc")))
386 static void stirUniqueIdentifier(void)
387 {
388  uint32_t id[4];
389 
390  // Start Read Unique Identifier.
391  RNG_EFC->EEFC_FCR = (0x5A << 24) | EFC_FCMD_STUI;
392  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) != 0)
393  ; // do nothing until FRDY falls.
394 
395  // Read the identifier.
396  id[0] = *((const uint32_t *)RNG_FLASH_ADDR);
397  id[1] = *((const uint32_t *)(RNG_FLASH_ADDR + 4));
398  id[2] = *((const uint32_t *)(RNG_FLASH_ADDR + 8));
399  id[3] = *((const uint32_t *)(RNG_FLASH_ADDR + 12));
400 
401  // Stop Read Unique Identifier.
402  RNG_EFC->EEFC_FCR = (0x5A << 24) | EFC_FCMD_SPUI;
403  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) == 0)
404  ; // do nothing until FRDY rises.
405 
406  // Stir the unique identifier into the entropy pool.
407  RNG.stir((uint8_t *)id, sizeof(id));
408 }
409 
410 // Erases the flash page containing the seed and then writes the new seed.
411 // It is assumed the seed has already been loaded into the latch registers.
412 __attribute__((section(".ramfunc")))
413 static void eraseAndWriteSeed()
414 {
415  // Execute the "Erase and Write Page" command.
416  RNG_EFC->EEFC_FCR = (0x5A << 24) | (RNG_SEED_PAGE << 8) | EFC_FCMD_EWP;
417 
418  // Wait for the FRDY bit to be raised.
419  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) == 0)
420  ; // do nothing until FRDY rises.
421 }
422 
423 #endif
424 
438 void RNGClass::begin(const char *tag)
439 {
440  // Bail out if we have already done this.
441  if (initialized)
442  return;
443 
444  // Initialize the ChaCha20 input block from the saved seed.
445  memcpy_P(block, tagRNG, sizeof(tagRNG));
446  memcpy_P(block + 4, initRNG, sizeof(initRNG));
447 #if defined(RNG_EEPROM)
448  int address = RNG_EEPROM_ADDRESS;
449  eeprom_read_block(stream, (const void *)address, SEED_SIZE);
450  if (crypto_crc8('S', stream, SEED_SIZE - 1) ==
451  ((const uint8_t *)stream)[SEED_SIZE - 1]) {
452  // We have a saved seed: XOR it with the initialization block.
453  // Note: the CRC-8 value is included. No point throwing it away.
454  for (int posn = 0; posn < 12; ++posn)
455  block[posn + 4] ^= stream[posn];
456  }
457 #elif defined(RNG_DUE_TRNG)
458  // Do we have a seed saved in the last page of flash memory on the Due?
459  if (crypto_crc8('S', ((const uint32_t *)RNG_SEED_ADDR) + 1, SEED_SIZE)
460  == ((const uint32_t *)RNG_SEED_ADDR)[0]) {
461  // XOR the saved seed with the initialization block.
462  for (int posn = 0; posn < 12; ++posn)
463  block[posn + 4] ^= ((const uint32_t *)RNG_SEED_ADDR)[posn + 1];
464  }
465 
466  // If the device has just been reprogrammed, there will be no saved seed.
467  // XOR the initialization block with some output from the CPU's TRNG
468  // to permute the state in a first boot situation after reprogramming.
469  pmc_enable_periph_clk(ID_TRNG);
470  REG_TRNG_CR = TRNG_CR_KEY(0x524E47) | TRNG_CR_ENABLE;
471  REG_TRNG_IDR = TRNG_IDR_DATRDY; // Disable interrupts - we will poll.
472  mixTRNG();
473 #endif
474 #if defined(RNG_ESP_NVS)
475  // Do we have a seed saved in ESP non-volatile storage (NVS)?
476  nvs_handle handle = 0;
477  if (nvs_open("rng", NVS_READONLY, &handle) == 0) {
478  size_t len = 0;
479  if (nvs_get_blob(handle, "seed", NULL, &len) == 0 && len == SEED_SIZE) {
480  uint32_t seed[12];
481  if (nvs_get_blob(handle, "seed", seed, &len) == 0) {
482  for (int posn = 0; posn < 12; ++posn)
483  block[posn + 4] ^= seed[posn];
484  }
485  clean(seed);
486  }
487  nvs_close(handle);
488  }
489 #endif
490 #if defined(RNG_WORD_TRNG)
491  // Mix in some output from a word-based TRNG to initialize the state.
492  mixTRNG();
493 #endif
494 
495  // No entropy credits for the saved seed.
496  credits = 0;
497 
498  // Trigger an automatic save once the entropy credits max out.
499  firstSave = 1;
500 
501  // Rekey the random number generator immediately.
502  rekey();
503 
504  // Stir in the supplied tag data but don't credit any entropy to it.
505  if (tag)
506  stir((const uint8_t *)tag, strlen(tag));
507 
508 #if defined(RNG_DUE_TRNG)
509  // Stir in the unique identifier for the CPU so that different
510  // devices will give different outputs even without seeding.
511  stirUniqueIdentifier();
512 #elif defined(ESP8266)
513  // ESP8266's have a 32-bit CPU chip ID and 32-bit flash chip ID
514  // that we can use as a device unique identifier.
515  uint32_t ids[2];
516  ids[0] = ESP.getChipId();
517  ids[1] = ESP.getFlashChipId();
518  stir((const uint8_t *)ids, sizeof(ids));
519 #elif defined(ESP32)
520  // ESP32's have a MAC address that can be used as a device identifier.
521  uint64_t mac = ESP.getEfuseMac();
522  stir((const uint8_t *)&mac, sizeof(mac));
523 #else
524  // AVR devices don't have anything like a serial number so it is
525  // difficult to make every device unique. Use the compilation
526  // time and date to provide a little randomness across applications
527  // if not across devices running the same pre-compiled application.
528  tag = __TIME__ __DATE__;
529  stir((const uint8_t *)tag, strlen(tag));
530 #endif
531 
532 #if defined(RNG_WATCHDOG)
533  // Disable interrupts and reset the watchdog.
534  cli();
535  wdt_reset();
536 
537  // Clear the "reset due to watchdog" flag.
538  MCUSR &= ~(1 << WDRF);
539 
540  // Enable the watchdog with the smallest duration (16ms)
541  // and interrupt-only mode.
542  _WD_CONTROL_REG |= (1 << _WD_CHANGE_BIT) | (1 << WDE);
543  _WD_CONTROL_REG = (1 << WDIE);
544 
545  // Re-enable interrupts. The watchdog should be running.
546  sei();
547 #elif defined(RNG_CCL)
548  // CCL Setup
549  //VPORTA.DIR |= 0x80; // LUT1 comes screaming out of PA7
550  VPORTA.DIR |= 0x02; // disable CCL output
551  CCL.LUT1CTRLB=0x03; //INSEL0 = 3 (Event A)
552  CCL.TRUTH1 = 0x11;
553  CCL.LUT1CTRLA = 0x01; // enable, output to pin with 0x41 (for debugging - 0x01 without output on a pin.
554  EVSYS.CHANNEL0 = EVSYS_CHANNEL0_CCL_LUT1_gc; //Set EVSYS to use output of LUT1 as Channel0.
555  EVSYS.USERCCLLUT1A = EVSYS_USER_CHANNEL0_gc;
556  EVSYS.USERTCB0COUNT = EVSYS_USER_CHANNEL0_gc;
557  TCB0.CTRLB = 0;
558  TCB0.CCMP = 255; // this is the number the timer counts up to
559  TCB0.INTCTRL = 1;
560  TCB0.INTFLAGS = 3;
561  TCB0.CTRLA = 0x0F; //enable with event clock
562 
563  // Enable CCL
564  CCL.CTRLA = 0x01;
565 
566  // RTC Setup
567  RTC.CLKSEL = RTC_CLKSEL_INT32K_gc; // Select 32.768kHZ Internal Clock
568  while (RTC.STATUS > 0); // wait for register
569  uint8_t CCL_SAMPLE_PERIOD;
570 #if(F_CPU > 4000000)
571  CCL_SAMPLE_PERIOD = 2;
572 #elif(F_CPU == 4000000)
573  CCL_SAMPLE_PERIOD = 5;
574 #elif(F_CPU == 2000000)
575  CCL_SAMPLE_PERIOD = 9;
576 #elif(F_CPU == 1000000)
577  CCL_SAMPLE_PERIOD = 16;
578 #else
579  #error "Chip frequency not supported"
580 #endif
581  RTC.PER = CCL_SAMPLE_PERIOD;
582  RTC.INTCTRL |= RTC_OVF_bm; // enable overflow interrupt
583 
584  // Enable RTC
585  RTC.CTRLA = RTC_PRESCALER_DIV1_gc // no prescaler
586  | RTC_RTCEN_bm // RTC timer enabled
587  | RTC_RUNSTDBY_bm; // enabled in standby
588 #endif
589 
590  // Re-save the seed to obliterate the previous value and to ensure
591  // that if the system is reset without a call to save() that we won't
592  // accidentally generate the same sequence of random data again.
593  save();
594 
595  // The RNG has now been initialized.
596  initialized = 1;
597 }
598 
612 {
613  #define MAX_NOISE_SOURCES (sizeof(noiseSources) / sizeof(noiseSources[0]))
614  if (count < MAX_NOISE_SOURCES) {
615  noiseSources[count++] = &source;
616  source.added();
617  }
618 }
619 
636 void RNGClass::setAutoSaveTime(uint16_t minutes)
637 {
638  if (!minutes)
639  minutes = 1; // Just in case.
640  timeout = ((uint32_t)minutes) * 60000U;
641 }
642 
660 void RNGClass::rand(uint8_t *data, size_t len)
661 {
662  // Make sure that the RNG is initialized in case the application
663  // forgot to call RNG.begin() at startup time.
664  if (!initialized)
665  begin(0);
666 
667  // Decrease the amount of entropy in the pool.
668  if ( (uint16_t)len > (credits / 8))
669  credits = 0;
670  else
671  credits -= len * 8;
672 
673  // If we have pending TRNG data from the loop() function,
674  // then force a stir on the state. Otherwise mix in some
675  // fresh data from the TRNG because it is possible that
676  // the application forgot to call RNG.loop().
677  if (trngPending) {
678  stir(0, 0, 0);
679  trngPending = 0;
680  trngPosn = 0;
681  } else {
682  mixTRNG();
683  }
684 
685  // Generate the random data.
686  uint8_t count = 0;
687  while (len > 0) {
688  // Force a rekey if we have generated too many blocks in this request.
689  if (count >= RNG_REKEY_BLOCKS) {
690  rekey();
691  count = 1;
692  } else {
693  ++count;
694  }
695 
696  // Increment the low counter word and generate a new keystream block.
697  ++(block[12]);
698  ChaCha::hashCore(stream, block, RNG_ROUNDS);
699 
700  // Copy the data to the return buffer.
701  if (len < 64) {
702  memcpy(data, stream, len);
703  break;
704  } else {
705  memcpy(data, stream, 64);
706  data += 64;
707  len -= 64;
708  }
709  }
710 
711  // Force a rekey after every request.
712  rekey();
713 }
714 
754 bool RNGClass::available(size_t len) const
755 {
756  if (len >= (RNG_MAX_CREDITS / 8))
757  return credits >= RNG_MAX_CREDITS;
758  else
759  return (uint16_t)len <= (credits / 8);
760 }
761 
787 void RNGClass::stir(const uint8_t *data, size_t len, unsigned int credit)
788 {
789  // Increase the entropy credit.
790  if ((credit / 8) >= len && len)
791  credit = len * 8;
792  if ((uint16_t)(RNG_MAX_CREDITS - credits) > credit)
793  credits += credit;
794  else
795  credits = RNG_MAX_CREDITS;
796 
797  // Process the supplied input data.
798  if (len > 0) {
799  // XOR the data with the ChaCha input block in 48 byte
800  // chunks and rekey the ChaCha cipher for each chunk to mix
801  // the data in. This should scatter any "true entropy" in
802  // the input across the entire block.
803  while (len > 0) {
804  size_t templen = len;
805  if (templen > 48)
806  templen = 48;
807  uint8_t *output = ((uint8_t *)block) + 16;
808  len -= templen;
809  while (templen > 0) {
810  *output++ ^= *data++;
811  --templen;
812  }
813  rekey();
814  }
815  } else {
816  // There was no input data, so just force a rekey so we
817  // get some mixing of the state even without new data.
818  rekey();
819  }
820 
821  // Save if this is the first time we have reached max entropy.
822  // This provides some protection if the system is powered off before
823  // the first auto-save timeout occurs.
824  if (firstSave && credits >= RNG_MAX_CREDITS) {
825  firstSave = 0;
826  save();
827  }
828 }
829 
857 {
858  // Generate random data from the current state and save
859  // that as the seed. Then force a rekey.
860  ++(block[12]);
861  ChaCha::hashCore(stream, block, RNG_ROUNDS);
862 #if defined(RNG_EEPROM)
863  // We shorten the seed from 48 bytes to 47 to leave room for
864  // the CRC-8 value. We do this to align the data on an 8-byte
865  // boundary in EERPOM.
866  int address = RNG_EEPROM_ADDRESS;
867  eeprom_write_block(stream, (void *)address, SEED_SIZE - 1);
868  eeprom_write_byte((uint8_t *)(address + SEED_SIZE - 1),
869  crypto_crc8('S', stream, SEED_SIZE - 1));
870 #elif defined(RNG_DUE_TRNG)
871  unsigned posn;
872  ((uint32_t *)(RNG_SEED_ADDR))[0] = crypto_crc8('S', stream, SEED_SIZE);
873  for (posn = 0; posn < 12; ++posn)
874  ((uint32_t *)(RNG_SEED_ADDR))[posn + 1] = stream[posn];
875  for (posn = 13; posn < (RNG_FLASH_PAGE_SIZE / 4); ++posn)
876  ((uint32_t *)(RNG_SEED_ADDR))[posn + 13] = 0xFFFFFFFF;
877  eraseAndWriteSeed();
878 #elif defined(RNG_ESP_NVS)
879  // Save the seed into ESP non-volatile storage (NVS).
880  nvs_handle handle = 0;
881  if (nvs_open("rng", NVS_READWRITE, &handle) == 0) {
882  nvs_erase_all(handle);
883  nvs_set_blob(handle, "seed", stream, SEED_SIZE);
884  nvs_commit(handle);
885  nvs_close(handle);
886  }
887 #endif
888  rekey();
889  timer = millis();
890 }
891 
899 {
900  // Stir in the entropy from all registered noise sources.
901  for (uint8_t posn = 0; posn < count; ++posn)
902  noiseSources[posn]->stir();
903 
904 #if defined(RNG_DUE_TRNG)
905  // If there is data available from the Arudino Due's TRNG, then XOR
906  // it with the state block and increase the entropy credit. We don't
907  // call stir() yet because that will seriously slow down the system
908  // given how fast the TRNG is. Instead we save up the XOR'ed TRNG
909  // data until the next rand() call and then hash it to generate the
910  // desired output.
911  //
912  // The CPU documentation claims that the TRNG output is very good so
913  // this should only make the pool more and more random as time goes on.
914  // However there is a risk that the CPU manufacturer was pressured by
915  // government or intelligence agencies to insert a back door that
916  // generates predictable output. Or the manufacturer was overly
917  // optimistic about their TRNG design and it is actually flawed in a
918  // way they don't realise.
919  //
920  // If you are concerned about such threats, then make sure to mix in
921  // data from other noise sources. By hashing together the TRNG with
922  // the other noise data, rand() should produce unpredictable data even
923  // if one of the sources is actually predictable.
924  if ((REG_TRNG_ISR & TRNG_ISR_DATRDY) != 0) {
925  block[4 + trngPosn] ^= REG_TRNG_ODATA;
926  if (++trngPosn >= 12)
927  trngPosn = 0;
928  if (credits < RNG_MAX_CREDITS) {
929  // Credit 1 bit of entropy for the word. The TRNG should be
930  // better than this but it is so fast that we want to collect
931  // up more data before passing it to the application.
932  ++credits;
933  }
934  trngPending = 1;
935  }
936 #elif defined(RNG_WORD_TRNG)
937  // Read a word from the TRNG and XOR it into the state.
938  block[4 + trngPosn] ^= RNG_WORD_TRNG_GET();
939  if (++trngPosn >= 12)
940  trngPosn = 0;
941  if (credits < RNG_MAX_CREDITS) {
942  // Credit 1 bit of entropy for the word. The TRNG should be
943  // better than this but it is so fast that we want to collect
944  // up more data before passing it to the application.
945  ++credits;
946  }
947  trngPending = 1;
948 #elif defined(RNG_WATCHDOG)
949  // Read the 32 bit buffer from the WDT interrupt.
950  cli();
951  if (outBits >= 32) {
952  uint32_t value = hash;
953  hash = 0;
954  outBits = 0;
955  sei();
956 
957  // Final steps of the Jenkin's one-at-a-time hash function.
958  // https://en.wikipedia.org/wiki/Jenkins_hash_function
959  value += leftShift3(value);
960  value ^= rightShift11(value);
961  value += leftShift15(value);
962 
963  // Credit 1 bit of entropy for each byte of input. It can take
964  // between 30 and 40 seconds to accumulate 256 bits of credit.
965  credits += 4;
966  if (credits > RNG_MAX_CREDITS)
967  credits = RNG_MAX_CREDITS;
968 
969  // XOR the word with the state. Stir once we accumulate 48 bytes,
970  // which happens about once every 6.4 seconds.
971  block[4 + trngPosn] ^= value;
972  if (++trngPosn >= 12) {
973  trngPosn = 0;
974  trngPending = 0;
975  stir(0, 0, 0);
976  } else {
977  trngPending = 1;
978  }
979  } else {
980  sei();
981  }
982 #elif defined(RNG_CCL)
983  if (outBits >= 32) {
984  uint32_t value = hash;
985  hash = 0;
986  outBits = 0;
987 
988  // Final steps of the Jenkin's one-at-a-time hash function.
989  // https://en.wikipedia.org/wiki/Jenkins_hash_function
990  value += leftShift3(value);
991  value ^= rightShift11(value);
992  value += leftShift15(value);
993 
994  // Credit 4 bits of entropy for each byte of input.
995  credits += 4;
996  if (credits > RNG_MAX_CREDITS)
997  credits = RNG_MAX_CREDITS;
998 
999  // XOR the word with the state. Stir once we accumulate 48 bytes,
1000  block[4 + trngPosn] ^= value;
1001  if (++trngPosn >= 12) {
1002  trngPosn = 0;
1003  trngPending = 0;
1004  stir(0, 0, 0);
1005  } else {
1006  trngPending = 1;
1007  }
1008  }
1009 #endif
1010 
1011  // Save the seed if the auto-save timer has expired.
1012  if ((millis() - timer) >= timeout)
1013  save();
1014 }
1015 
1036 {
1037  clean(block);
1038  clean(stream);
1039 #if defined(RNG_EEPROM)
1040  int address = RNG_EEPROM_ADDRESS;
1041  for (int posn = 0; posn < SEED_SIZE; ++posn)
1042  eeprom_write_byte((uint8_t *)(address + posn), 0xFF);
1043 #elif defined(RNG_DUE_TRNG)
1044  for (unsigned posn = 0; posn < (RNG_FLASH_PAGE_SIZE / 4); ++posn)
1045  ((uint32_t *)(RNG_SEED_ADDR))[posn] = 0xFFFFFFFF;
1046  eraseAndWriteSeed();
1047 #elif defined(RNG_ESP_NVS)
1048  nvs_handle handle = 0;
1049  if (nvs_open("rng", NVS_READWRITE, &handle) == 0) {
1050  nvs_erase_all(handle);
1051  nvs_commit(handle);
1052  nvs_close(handle);
1053  }
1054 #endif
1055  initialized = 0;
1056 }
1057 
1061 void RNGClass::rekey()
1062 {
1063  // Rekey the cipher for the next request by generating a new block.
1064  // This is intended to make it difficult to wind the random number
1065  // backwards if the state is captured later. The first 16 bytes of
1066  // "block" remain set to "tagRNG".
1067  ++(block[12]);
1068  ChaCha::hashCore(stream, block, RNG_ROUNDS);
1069  memcpy(block + 4, stream, 48);
1070 
1071  // Permute the high word of the counter using the system microsecond
1072  // counter to introduce a little bit of non-stir randomness for each
1073  // request. Note: If random data is requested on a predictable schedule
1074  // then this may not help very much. It is still necessary to stir in
1075  // high quality entropy data on a regular basis using stir().
1076  block[13] ^= micros();
1077 }
1078 
1082 void RNGClass::mixTRNG()
1083 {
1084 #if defined(RNG_DUE_TRNG)
1085  // Mix in 12 words from the Due's TRNG.
1086  for (int posn = 0; posn < 12; ++posn) {
1087  // According to the documentation the TRNG should produce a new
1088  // 32-bit random value every 84 clock cycles. If it still hasn't
1089  // produced a value after 200 iterations, then assume that the
1090  // TRNG is not producing output and stop.
1091  int counter;
1092  for (counter = 0; counter < 200; ++counter) {
1093  if ((REG_TRNG_ISR & TRNG_ISR_DATRDY) != 0)
1094  break;
1095  }
1096  if (counter >= 200)
1097  break;
1098  block[posn + 4] ^= REG_TRNG_ODATA;
1099  }
1100 #elif defined(RNG_WORD_TRNG)
1101  // Read 12 words from the TRNG and XOR them into the state.
1102  for (uint8_t index = 4; index < 16; ++index)
1103  block[index] ^= RNG_WORD_TRNG_GET();
1104 #elif defined(RNG_WATCHDOG)
1105  // Read the pending 32 bit buffer from the WDT interrupt and mix it in.
1106  cli();
1107  if (outBits >= 32) {
1108  uint32_t value = hash;
1109  hash = 0;
1110  outBits = 0;
1111  sei();
1112 
1113  // Final steps of the Jenkin's one-at-a-time hash function.
1114  // https://en.wikipedia.org/wiki/Jenkins_hash_function
1115  value += leftShift3(value);
1116  value ^= rightShift11(value);
1117  value += leftShift15(value);
1118 
1119  // XOR the word with the state.
1120  block[4] ^= value;
1121  } else {
1122  sei();
1123  }
1124 #elif defined(RNG_CCL)
1125  if (outBits >= 32) {
1126  uint32_t value = hash;
1127  hash = 0;
1128  outBits = 0;
1129 
1130  // Final steps of the Jenkin's one-at-a-time hash function.
1131  // https://en.wikipedia.org/wiki/Jenkins_hash_function
1132  value += leftShift3(value);
1133  value ^= rightShift11(value);
1134  value += leftShift15(value);
1135 
1136  // XOR the word with the state.
1137  block[4] ^= value;
1138  }
1139 #endif
1140 }
static void hashCore(uint32_t *output, const uint32_t *input, uint8_t rounds)
Executes the ChaCha hash core on an input memory block.
Definition: ChaCha.cpp:253
Abstract base class for random noise sources.
Definition: NoiseSource.h:30
virtual void added()
Called when the noise source is added to RNG with RNG.addNoiseSource().
Definition: NoiseSource.cpp:95
Pseudo random number generator suitable for cryptography.
Definition: RNG.h:32
void save()
Saves the random seed to EEPROM.
Definition: RNG.cpp:856
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:660
void setAutoSaveTime(uint16_t minutes)
Sets the amount of time between automatic seed saves.
Definition: RNG.cpp:636
void begin(const char *tag)
Initializes the random number generator.
Definition: RNG.cpp:438
void loop()
Run periodic housekeeping tasks on the random number generator.
Definition: RNG.cpp:898
void destroy()
Destroys the data in the random number pool and the saved seed in EEPROM.
Definition: RNG.cpp:1035
void addNoiseSource(NoiseSource &source)
Adds a noise source to the random number generator.
Definition: RNG.cpp:611
bool available(size_t len) const
Determine if there is sufficient entropy available for a specific request size.
Definition: RNG.cpp:754
RNGClass()
Constructs a new random number generator instance.
Definition: RNG.cpp:311
void stir(const uint8_t *data, size_t len, unsigned int credit=0)
Stirs additional entropy data into the random pool.
Definition: RNG.cpp:787
static const int SEED_SIZE
Size of a saved random number seed in EEPROM space.
Definition: RNG.h:53
~RNGClass()
Destroys this random number generator instance.
Definition: RNG.cpp:326