1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-29 16:31:18 +01:00

cpu/native: add high-quality random implementation

Per default random data is read from `/dev/random` now.

If specified (e.g. `-s 4711`), data is generated by calls to POSIX
random function like before. The POSIX random API is initialize with
the given seed (`srandom(4711);` in this example).
This commit is contained in:
Ludwig Ortmann 2015-01-10 10:22:51 +01:00
parent 52cc7eb122
commit 88fa49ab38
3 changed files with 124 additions and 16 deletions

View File

@ -145,6 +145,8 @@ extern const char *_progname;
extern char **_native_argv;
extern pid_t _native_pid;
extern pid_t _native_id;
extern unsigned _native_rng_seed;
extern int _native_rng_mode; /**< 0 = /dev/random, 1 = random(3) */
extern const char *_native_unix_socket_path;
#ifdef MODULE_UART0

View File

@ -8,6 +8,7 @@
/**
* @ingroup native_cpu
* @defgroup native_rng
* @{
*
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
@ -16,6 +17,9 @@
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "cpu-conf.h"
#include "native_internal.h"
@ -26,10 +30,40 @@
#include "debug.h"
static int powered = 0;
static int dev_random = -1;
/**********************************************************************
* internal API declaration
**********************************************************************/
/**
* seed host random module with @ref _native_rng_seed
*/
void _native_rng_init_det(void);
void _native_rng_init_hq(void);
unsigned _native_rng_read_det(char *buf, unsigned num);
unsigned _native_rng_read_hq(char *buf, unsigned num);
/**********************************************************************
* public API implementation
**********************************************************************/
void random_init(void)
{
DEBUGF("random_init: powering on\n");
DEBUG("random_init: initializing\n");
switch (_native_rng_mode) {
case 0:
_native_rng_init_hq();
break;
case 1:
_native_rng_init_det();
break;
default:
err(EXIT_FAILURE, "random_init: _native_rng_mode is in invalid state %i\n",
_native_rng_mode);
break;
}
DEBUG("random_init: powering on\n");
random_poweron();
}
@ -40,31 +74,89 @@ int random_read(char *buf, unsigned int num)
return 0;
}
DEBUGF("random_read: writing %ui bytes\n", num);
DEBUG("random_read: writing %u bytes\n", num);
switch (_native_rng_mode) {
case 0:
num = _native_rng_read_hq(buf, num);
break;
case 1:
num = _native_rng_read_det(buf, num);
break;
default:
num = 0;
err(EXIT_FAILURE, "random_read: _native_rng_mode is in invalid state %i\n",
_native_rng_mode);
break;
}
return num;
}
void random_poweron(void)
{
DEBUG("random_poweron: power on\n");
powered = 1;
}
void random_poweroff(void)
{
DEBUG("random_poweroff: power off\n");
powered = 0;
}
/**********************************************************************
* internal API implementation
**********************************************************************/
void _native_rng_init_det(void)
{
DEBUG("_native_rng_init_det\n");
_native_syscall_enter();
real_srandom(_native_rng_seed);
_native_syscall_leave();
}
void _native_rng_init_hq(void)
{
DEBUG("_native_rng_init_hq\n");
_native_syscall_enter();
dev_random = real_open("/dev/random", O_RDONLY);
if (dev_random == -1) {
err(EXIT_FAILURE, "_native_rng_init_hq: open(/dev/random)");
}
_native_syscall_leave();
}
unsigned _native_rng_read_det(char *buf, unsigned num)
{
DEBUG("_native_rng_read_det\n");
for (unsigned i = 0; i < num; i++) {
_native_syscall_enter();
buf[i] = (char)real_random();
_native_syscall_leave();
}
return num;
}
/**
* seed host random module with @ref _native_id
*/
void random_poweron(void)
unsigned _native_rng_read_hq(char *buf, unsigned num)
{
DEBUGF("random_poweron: power on\n");
powered = 1;
_native_syscall_enter();
real_srandom((unsigned int)_native_id);
_native_syscall_leave();
}
DEBUG("_native_rng_read_hq\n");
unsigned offset = 0;
void random_poweroff(void)
{
DEBUGF("random_poweroff: power off\n");
powered = 0;
while (num > 0) {
_native_syscall_enter();
int r = real_read(dev_random, (buf + offset), num);
_native_syscall_leave();
if (r == -1) {
err(EXIT_FAILURE, "_native_rng_read_hq: read");
}
num -= r;
offset += r;
}
return offset;
}
/**

View File

@ -43,6 +43,8 @@ const char *_progname;
char **_native_argv;
pid_t _native_pid;
pid_t _native_id;
unsigned _native_rng_seed = 0;
int _native_rng_mode = 0;
const char *_native_unix_socket_path = NULL;
/**
@ -202,6 +204,8 @@ void usage_exit(void)
#endif
real_printf("\
-i <id> specify instance id (set by config module)\n\
-s <seed> specify srandom(3) seed (/dev/random is used instead of\n\
random(3) if the option is omitted)\n\
-d daemonize\n\
-e redirect stderr to file\n\
-E do not redirect stderr (i.e. leave sterr unchanged despite\n\
@ -262,6 +266,16 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
}
_native_id = atol(argv[argp]);
}
else if (strcmp("-s", arg) == 0) {
if (argp + 1 < argc) {
argp++;
}
else {
usage_exit();
}
_native_rng_seed = atol(argv[argp]);
_native_rng_mode = 1;
}
else if (strcmp("-d", arg) == 0) {
if (strcmp(stdiotype, "stdio") == 0) {
stdiotype = "null";