From c622e0ef898fdc3882cb9cc0e3de7200dd5bcd89 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 13 Jun 2016 18:51:40 +0800 Subject: [PATCH] Bring back old semantics to random and randomSeed, add secureRandom (#1710) --- cores/esp8266/Arduino.h | 2 + cores/esp8266/WMath.cpp | 24 ++++++++++- tests/device/test_random/test_random.ino | 53 ++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 tests/device/test_random/test_random.ino diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index dfc514a45b..90e2da25db 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -271,6 +271,8 @@ void noTone(uint8_t _pin); long random(long); long random(long, long); void randomSeed(unsigned long); +long secureRandom(long); +long secureRandom(long, long); long map(long, long, long, long, long); extern "C" void configTime(long timezone, int daylightOffset_sec, diff --git a/cores/esp8266/WMath.cpp b/cores/esp8266/WMath.cpp index d56db8e5cd..13c2452dc8 100644 --- a/cores/esp8266/WMath.cpp +++ b/cores/esp8266/WMath.cpp @@ -28,9 +28,12 @@ extern "C" { } #include "esp8266_peri.h" +static bool s_randomSeedCalled = false; + void randomSeed(unsigned long seed) { if(seed != 0) { - srand((seed ^ RANDOM_REG32)); + srand(seed); + s_randomSeedCalled = true; } } @@ -38,7 +41,9 @@ long random(long howbig) { if(howbig == 0) { return 0; } - return (rand() ^ RANDOM_REG32) % howbig; + // if randomSeed was called, fall back to software PRNG + uint32_t val = (s_randomSeedCalled) ? rand() : RANDOM_REG32; + return val % howbig; } long random(long howsmall, long howbig) { @@ -49,6 +54,21 @@ long random(long howsmall, long howbig) { return random(diff) + howsmall; } +long secureRandom(long howbig) { + if(howbig == 0) { + return 0; + } + return RANDOM_REG32 % howbig; +} + +long secureRandom(long howsmall, long howbig) { + if(howsmall >= howbig) { + return howsmall; + } + long diff = howbig - howsmall; + return secureRandom(diff) + howsmall; +} + long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } diff --git a/tests/device/test_random/test_random.ino b/tests/device/test_random/test_random.ino new file mode 100644 index 0000000000..5d71350d5e --- /dev/null +++ b/tests/device/test_random/test_random.ino @@ -0,0 +1,53 @@ +#include + +BS_ENV_DECLARE(); + +void setup() +{ + Serial.begin(115200); + BS_RUN(Serial); +} + + +TEST_CASE("If randomSeed is not called, random() uses hardware PRNG", "[random]") +{ + int32_t data[32]; + srand(10); + for (int i = 0; i < sizeof(data)/sizeof(data[0]); ++i) { + data[i] = random(0x7fffffff); + } + srand(10); + for (int i = 0; i < sizeof(data)/sizeof(data[0]); ++i) { + CHECK(random(0x7fffffff) != data[i]); + } +} + + +TEST_CASE("If randomSeed is called, we get same random sequence every time", "[random]") +{ + const int32_t reference_sequence[] = { + 2104627054, 2013331137, 258660947, 107061148, + 317460219, 663931879, 307161078, 1718702872, + 1306951058, 1066376876, 624381721, 850811527, + 329784053, 726742932, 182903521, 787925035, + 1364123723, 198878220, 1117075042, 1108236242, + 1775000610, 500470195, 896676389, 6341838, + 785214762, 1084946248, 1601419914, 2058135092, + 1671754873, 1952290050, 1572975837, 1596343802, + 240941423, 1843946550, 793779187, 441773333, + 884819086, 590861527, 1676358848, 2132930493, + 969627641, 930717537, 195748182, 2064531490, + 1195920216, 347502525, 584628940, 1938341337, + 642503024, 915004020, 2034338438, 1690522669, + 1805037441, 1904039418, 1491310300, 227517325, + 17943876, 570537582, 1409581066, 1819703730, + 730240988, 786466794, 1411137128, 1680096093, + }; + randomSeed(42); + for (int i = 0; i < sizeof(reference_sequence)/sizeof(reference_sequence[0]); ++i) { + CHECK(random(0x7fffffff) == reference_sequence[i]); + } +} + + +void loop() {}