-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys: random: add entropy collector #4294
Closed
Closed
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
9eabd6c
sys: div: add div/mod 44488 (needed for minstd prng)
kaspar030 0c6d4ea
sys: random: add simple LCG PRNGs
kaspar030 85ec5c6
sys: shell: renamed mersenne_* to random_*
kaspar030 6c1b26e
fixup! sys: random: add simple LCG PRNGs
kaspar030 f5f3c2b
DEPENDENCY MERGE: add_minstd_prng
kaspar030 800bfeb
sys: random: add entropy collector
kaspar030 154a718
squash: add /dev/urandom based entropy collection, XOR single rotatin…
kaspar030 6a3d03e
dist: tools: add test_random PRNG evaluation tool
kaspar030 e7e97d2
squash: make minstd.c and musl_lcg.c use entropy if available
kaspar030 6985feb
fixup! dist: tools: add test_random PRNG evaluation tool
kaspar030 eb48cef
squash: minstd.c musl_lcg.c: use highest bits, xor entropy
kaspar030 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
RIOTBASE := ../../.. | ||
INCLUDES := $(RIOTBASE)/sys/include | ||
|
||
CFLAGS += $(patsubst %,-I%,$(INCLUDES)) | ||
CFLAGS += -Wall -O3 | ||
|
||
PRNGS ?= mersenne minstd musl_lcg | ||
|
||
comma:= , | ||
empty:= | ||
space:= $(empty) $(empty) | ||
PRNGS_CSV:= $(subst $(space),$(comma),$(PRNGS)) | ||
|
||
all: $(PRNGS:%=test_%) $(PRNGS:%=test_%_entropy) | ||
|
||
clean: | ||
rm -f test_*_entropy | ||
rm -f test_{$(PRNGS_CSV)} | ||
|
||
test_%: test_random.c $(RIOTBASE)/sys/random/%.c | ||
$(CC) $(CFLAGS) $^ -o $@$(SUFFIX) | ||
|
||
test_%_entropy: test_random.c $(RIOTBASE)/sys/random/%.c $(RIOTBASE)/sys/random/entropy.c | ||
$(CC) $(CFLAGS) -DMODULE_ENTROPY -DURANDOM $^ -o $@$(SUFFIX) | ||
|
||
MODIFIED_ENT:=""#"Chi-percent," | ||
|
||
run_tests: all | ||
echo "prng,Entropy_injection_freq,unused,File-bytes,Entropy,Chi-square,$(MODIFIED_ENT)Mean,Monte-Carlo-Pi,Serial-Correlation" > ent_results.txt | ||
for prng in $(PRNGS) ; do \ | ||
./test_$${prng} > test_$${prng}_out ; \ | ||
echo $${prng},-1,$$(ent -t test_$${prng}_out | tail -n 1) >> ent_results.txt; \ | ||
for freq in 1024 4096 16384 65536 262144 1048576 4194304 16777216; do \ | ||
./test_$${prng}_entropy $${freq}> test_$${prng}_entropy_freq_$${freq}_out ; \ | ||
echo $${prng},$${freq},$$(ent -t test_$${prng}_entropy_freq_$${freq}_out | tail -n 1) >> ent_results.txt; \ | ||
done ; \ | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#include <stdio.h> | ||
#include <stdint.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
|
||
#ifdef MODULE_ENTROPY | ||
#include "entropy.h" | ||
#define ENTROPY_FREQ_DEFAULT 1024 | ||
#endif | ||
|
||
uint32_t genrand_uint32(void); | ||
void genrand_init(uint32_t s); | ||
|
||
#define N_WORDS (2<<24) | ||
|
||
int main(int argc, char *argv[]) { | ||
uint32_t random; | ||
uint32_t n = N_WORDS; | ||
|
||
#ifdef MODULE_ENTROPY | ||
uint32_t entropy_freq; | ||
|
||
if (argc>1) { | ||
entropy_freq = atoi(argv[1]); | ||
} else { | ||
entropy_freq = ENTROPY_FREQ_DEFAULT; | ||
} | ||
|
||
fprintf(stderr, "Injecting a random byte every %u times.\n", entropy_freq); | ||
#endif | ||
|
||
while(n--) { | ||
|
||
#ifdef MODULE_ENTROPY | ||
if (! (n % entropy_freq)) { | ||
fprintf(stderr, "Collecting entropy... %u\n", n); | ||
entropy_collect(); | ||
} | ||
#endif | ||
|
||
random = genrand_uint32(); | ||
write(STDOUT_FILENO, &random, 4); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef ENTROPY_H | ||
#define ENTROPY_H | ||
|
||
#include <stdint.h> | ||
|
||
extern uint32_t entropy; | ||
void entropy_collect(void); | ||
|
||
#endif /* ENTROPY_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,14 @@ | ||
ifeq (,$(filter prng_%,$(USEMODULE))) | ||
USEMODULE += prng_mersenne | ||
endif | ||
ifneq (,$(filter prng_mersenne,$(USEMODULE))) | ||
SRC += mersenne.c | ||
endif | ||
ifneq (,$(filter prng_minstd,$(USEMODULE))) | ||
SRC += minstd.c | ||
endif | ||
ifneq (,$(filter prng_musl_lcg,$(USEMODULE))) | ||
SRC += musl_lcg.c | ||
endif | ||
|
||
include $(RIOTBASE)/Makefile.base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include <stdint.h> | ||
|
||
#ifdef MODULE_XTIMER | ||
#include "xtimer.h" | ||
static uint32_t _last_event; | ||
#endif | ||
|
||
#if defined(URANDOM) | ||
#include <sys/stat.h> | ||
#include <fcntl.h> | ||
#include <unistd.h> | ||
#endif | ||
|
||
uint32_t entropy; | ||
static unsigned _n = 0; | ||
|
||
#ifndef ENTROPY_OP | ||
#define ENTROPY_OP(x) (x & 0xFF) | ||
#endif | ||
|
||
void entropy_collect(void) | ||
{ | ||
#ifdef MODULE_XTIMER | ||
uint32_t now = _lltimer_now(); | ||
uint32_t diff = now - _last_event; | ||
_last_event = now; | ||
#elif defined(URANDOM) | ||
int fd = open("/dev/urandom", O_RDONLY); | ||
char randbyte; | ||
read(fd, &randbyte, 1); | ||
uint32_t diff = (uint8_t) randbyte; | ||
close(fd); | ||
#endif | ||
|
||
entropy ^= ((ENTROPY_OP(diff)) << ((_n++ & 0x3) * 8)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/** | ||
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de> | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
* | ||
* Code taken from C FAQ (http://c-faq.com/lib/rand.html). | ||
*/ | ||
|
||
/** | ||
* @ingroup sys_random | ||
* @{ | ||
* @file | ||
* | ||
* @brief Simple Park & Miller "minimal standard" PRNG | ||
* | ||
* This file contains a simple Park-Miller pseudo random number generator. | ||
* | ||
* While not very random when considering crypto requirements, this is probably | ||
* random enough anywhere where pseudo-randomness is sufficient, e.g., when | ||
* provided with a sensible seed source, for MAC algorithms. | ||
* | ||
* The implementation is taken from the C FAQ, but modified to use magic number | ||
* division and adapted to RIOT's coding conventions.. | ||
* | ||
* @author Kaspar Schleiser <kaspar@schleiser.de> | ||
* @} | ||
*/ | ||
|
||
#include <stdint.h> | ||
|
||
#include "div.h" | ||
|
||
#ifdef MODULE_ENTROPY | ||
#include "entropy.h" | ||
#endif | ||
|
||
#define a 48271 | ||
#define m 2147483647 | ||
#define q (m / a) /* 44488 */ | ||
#define r (m % a) /* 3399 */ | ||
|
||
static uint32_t _seed = 1; | ||
|
||
int rand_minstd(void) | ||
{ | ||
uint32_t hi = div_u32_by_44488(_seed); | ||
uint32_t lo = div_u32_mod_44488(_seed); | ||
uint32_t test = (a * lo) - (r * hi); | ||
|
||
if(test > 0) { | ||
_seed = test; | ||
} | ||
else { | ||
_seed = test + m; | ||
} | ||
|
||
return _seed; | ||
} | ||
|
||
uint32_t genrand_uint32(void) | ||
{ | ||
/* minstd as implemented returns only values from 1 to 2147483647, | ||
* so run it two times to get 32bits */ | ||
uint16_t A = (rand_minstd() >> 15); | ||
uint16_t B = (rand_minstd() >> 15); | ||
|
||
uint32_t res = (((uint32_t)A) << 16) | B; | ||
|
||
#ifdef MODULE_ENTROPY | ||
return res ^ entropy; | ||
#else | ||
return res; | ||
#endif | ||
} | ||
|
||
void genrand_init(uint32_t val) | ||
{ | ||
if (!val) { | ||
val = 1; | ||
} | ||
_seed = val; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de> | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
* | ||
* Code taken from Musl C library. Original copyright notice: | ||
* | ||
* Copyright © 2005-2014 Rich Felker, et al. | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining | ||
* a copy of this software and associated documentation files (the | ||
* "Software"), to deal in the Software without restriction, including | ||
* without limitation the rights to use, copy, modify, merge, publish, | ||
* distribute, sublicense, and/or sell copies of the Software, and to | ||
* permit persons to whom the Software is furnished to do so, subject to | ||
* the following conditions: | ||
|
||
* The above copyright notice and this permission notice shall be | ||
* included in all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
|
||
#include <stdint.h> | ||
|
||
#ifdef MODULE_ENTROPY | ||
#include "entropy.h" | ||
#endif | ||
|
||
static uint64_t _seed; | ||
|
||
void genrand_init(uint32_t s) | ||
{ | ||
_seed = s-1; | ||
} | ||
|
||
uint32_t genrand_uint32(void) | ||
{ | ||
_seed = 6364136223846793005ULL*_seed + 1; | ||
#ifdef MODULE_ENTROPY | ||
return (_seed>>31) ^ entropy; | ||
#else | ||
return _seed>>31; | ||
#endif | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the entropy introduced as a seed, rather then messing with the deterministic qualities of the PNR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I felt that adding something halfway random is less predictive than setting a halfway random starting point. lets ask a mathematician, though.
-----Original Message-----
From: Martine Lenders notifications@github.com
To: RIOT-OS/RIOT RIOT@noreply.github.com
Cc: Kaspar Schleiser kaspar@schleiser.de
Sent: Di., 17 Nov. 2015 18:16
Subject: Re: [RIOT] sys: random: add entropy collector (#4294)
Shouldn't the entropy introduced as a seed, rather then messing with the deterministic qualities of the PNR?
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/4294/files#r45088799
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Speaking as a mathematician: Entropy is not randomness, but something like 'unpredictability'. It is mostly needed for crypto.
It is the continuous experience that adding something 'that looks random' is rather harmful than helpful. A colleague, who is a crypto-mathematician, just recently told me that (with NXP) they had performed a larger study on common sources of 'entropy' (typing, perturbed wireless signals, other hardware fluctuations) and results were disastrous: no reliable unpredictability nowhere.
Practically speaking, a pseudo-random number generator basically reproduces certain statistical properties, starting it's 'randomness' from initialization (seeds). With equal seeds and common generators, number sequences deterministically repeat, which often is a desired property for debugging. I would stick to this approach and clearly state that this is not crypto-safe.
Adding 'something' to the number output, mainly produces the threat of spoiling the statistical properties ... it is very unlikely to maximize entropy by this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to read that study.
Apart from that, I think we have several levels of needed 'randomness'.
Let's solve them one at a time.
This PR might help with the letter edit first edit two if used correctly. And it adds only 15 lines of code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just keep in mind, this (typing, perturbed wireless signals, other hardware fluctuations) is what e.g., Linux is using as entropy. It is very probably better than nothing, and when it will be proven useless one day, we won't be able to use it anymore. But until then, it (probably) improves our "randomness".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that's exactly why "the big OSs" have varying degrees of RNGs:
rand()
in libc for quick, but deterministic PRNG values/dev/random
for slow, but true randomness from outside sources/dev/urandom
for something in betweenI saw the
random
module always as something likerand()
andperiph/random
as our/dev/random
. True, for boards withoutperiph/random
we still need a randomness source, and maybe this is a start, but I wouldn't touch the PRNGs for that (except that we still need some way to initialize them properly).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi again Kaspar,
On 18.11.2015 03:13, Kaspar Schleiser wrote:
I managed to get a hold of the colleague. No official report available,
but helpful input:
First, there is a good standardized test suite of 'randomness' for
random number generators by NIST:
http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html -
one can use this to verify the quality of an implementation.
Second, she said that the best pseudo-randomness at reasonable effort
is achieved by coupling to nonlinear feedback shift register. This would
be feasible for crypto, as well. I have not looked at specific
implementations (and their complexity), but I guess we should keep to
this double strategy (if needed): One very lightweight simple (not
necessariyl crypto-safe) implementation and one that is crypto-compliant.
Thomas
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! I am no mathematician...
Instead of
return y + entropy;
(which can lead to overflows; and from a distribution/security point of view I am not sure if an adittion adds entropy to a source, I would say no.. and on the contrary you will likely have less number having a value lower than MAXINT/4),why don't you perform an xor?
return y ^ entropy;
I think it nicely uses the
entropy
(as a one time pad) to modifyy
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is still the only problem I have with this PR. The entropy should only manipulate the seed, not the return value of the PNRG.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, I gave it a thought, and indeed, adding a random variable to another, has nefarious consequences (or at best not the expected ones I think).
For instance the sum of two uniformly distributed variables, is not uniform anymore:
http://math.stackexchange.com/questions/357672/density-of-sum-of-two-uniform-random-variables-0-1
http://www.dartmouth.edu/~chance/teaching_aids/books_articles/probability_book/Chapter7.pdf figure 7.2.
Assuming "y" and "entropy" variables are random. After adding them we have a probability of 1/2 of having a value >= MaxInt. Better not rely on how overflow is handled by each platform.