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:
parent
52cc7eb122
commit
88fa49ab38
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user