moved type and constants for random data to include file;
added consistency check in random; added source of randomness internal to random using timing; only retrieve random bins that are full.
This commit is contained in:
@@ -6,9 +6,7 @@
|
||||
#include "../drivers.h"
|
||||
#include "../libdriver/driver.h"
|
||||
#include <sys/ioc_memory.h>
|
||||
#include "../../kernel/const.h"
|
||||
#include "../../kernel/config.h"
|
||||
#include "../../kernel/type.h"
|
||||
#include <minix/type.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "random.h"
|
||||
@@ -32,6 +30,7 @@ FORWARD _PROTOTYPE( void r_init, (void) );
|
||||
FORWARD _PROTOTYPE( int r_ioctl, (struct driver *dp, message *m_ptr, int safe) );
|
||||
FORWARD _PROTOTYPE( void r_geometry, (struct partition *entry) );
|
||||
FORWARD _PROTOTYPE( void r_random, (struct driver *dp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( void r_updatebin, (int source, struct k_randomness_bin *rb));
|
||||
|
||||
/* Entry points to this driver. */
|
||||
PRIVATE struct driver r_dtab = {
|
||||
@@ -197,9 +196,30 @@ message *m_ptr;
|
||||
*===========================================================================*/
|
||||
PRIVATE void r_init()
|
||||
{
|
||||
/* Initialize this task. All minor devices are initialized one by one. */
|
||||
static struct k_randomness krandom;
|
||||
int i, s;
|
||||
|
||||
random_init();
|
||||
r_random(NULL, NULL); /* also set periodic timer */
|
||||
|
||||
/* Retrieve first randomness buffer with parameters. */
|
||||
if (OK != (s=sys_getrandomness(&krandom))) {
|
||||
report("RANDOM", "sys_getrandomness failed", s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Do sanity check on parameters. */
|
||||
if(krandom.random_sources != RANDOM_SOURCES ||
|
||||
krandom.random_elements != RANDOM_ELEMENTS) {
|
||||
printf("random: parameters (%d, %d) don't match kernel's (%d, %d)\n",
|
||||
RANDOM_SOURCES, RANDOM_ELEMENTS,
|
||||
krandom.random_sources, krandom.random_elements);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Feed initial batch. */
|
||||
for(i = 0; i < RANDOM_SOURCES; i++)
|
||||
r_updatebin(i, &krandom.bin[i]);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
@@ -221,6 +241,45 @@ int safe; /* safe i/o? */
|
||||
return(OK);
|
||||
}
|
||||
|
||||
#define UPDATE(binnumber, bp, startitem, elems) { \
|
||||
rand_t *r, *r2; \
|
||||
int n = elems, item = startitem;\
|
||||
int high; \
|
||||
assert(binnumber >= 0 && binnumber < RANDOM_SOURCES); \
|
||||
assert(item >= 0 && item < RANDOM_ELEMENTS); \
|
||||
if(n > 0) { \
|
||||
high = item+n-1; \
|
||||
assert(high >= item); \
|
||||
assert(high >= 0 && high < RANDOM_ELEMENTS); \
|
||||
r = &bp->r_buf[item]; \
|
||||
r2 = &bp->r_buf[high]; \
|
||||
random_update(binnumber, r, n); \
|
||||
} \
|
||||
}
|
||||
|
||||
PRIVATE void r_updatebin(int source, struct k_randomness_bin *rb)
|
||||
{
|
||||
int r_next, r_size, r_high;
|
||||
|
||||
r_next= rb->r_next;
|
||||
r_size= rb->r_size;
|
||||
|
||||
assert(r_next >= 0 && r_next < RANDOM_ELEMENTS);
|
||||
assert(r_size >= 0 && r_size <= RANDOM_ELEMENTS);
|
||||
|
||||
r_high= r_next+r_size;
|
||||
|
||||
if (r_high <= RANDOM_ELEMENTS) {
|
||||
UPDATE(source, rb, r_next, r_size);
|
||||
} else {
|
||||
assert(r_next < RANDOM_ELEMENTS);
|
||||
UPDATE(source, rb, r_next, RANDOM_ELEMENTS-r_next);
|
||||
UPDATE(source, rb, 0, r_high-RANDOM_ELEMENTS);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*============================================================================*
|
||||
* r_random *
|
||||
*============================================================================*/
|
||||
@@ -229,30 +288,21 @@ struct driver *dp; /* pointer to driver structure */
|
||||
message *m_ptr; /* pointer to alarm message */
|
||||
{
|
||||
/* Fetch random information from the kernel to update /dev/random. */
|
||||
int i, s, r_next, r_size, r_high;
|
||||
struct randomness krandom;
|
||||
int s;
|
||||
static int bin = 0;
|
||||
static struct k_randomness_bin krandom_bin;
|
||||
u32_t hi, lo;
|
||||
rand_t r;
|
||||
|
||||
if (OK != (s=sys_getrandomness(&krandom)))
|
||||
report("RANDOM", "sys_getrandomness failed", s);
|
||||
bin = (bin+1) % RANDOM_SOURCES;
|
||||
|
||||
for (i= 0; i<RANDOM_SOURCES; i++)
|
||||
{
|
||||
r_next= krandom.bin[i].r_next;
|
||||
r_size= krandom.bin[i].r_size;
|
||||
r_high= r_next+r_size;
|
||||
if (r_high <= RANDOM_ELEMENTS)
|
||||
{
|
||||
random_update(i, &krandom.bin[i].r_buf[r_next], r_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(r_next < RANDOM_ELEMENTS);
|
||||
random_update(i, &krandom.bin[i].r_buf[r_next],
|
||||
RANDOM_ELEMENTS-r_next);
|
||||
random_update(i, &krandom.bin[i].r_buf[0],
|
||||
r_high-RANDOM_ELEMENTS);
|
||||
}
|
||||
}
|
||||
if(sys_getrandom_bin(&krandom_bin, bin) == OK)
|
||||
r_updatebin(bin, &krandom_bin);
|
||||
|
||||
/* Add our own timing source. */
|
||||
read_tsc(&hi, &lo);
|
||||
r = lo;
|
||||
random_update(RND_TIMING, &r, 1);
|
||||
|
||||
/* Schedule new alarm for next m_random call. */
|
||||
if (OK != (s=sys_setalarm(KRANDOM_PERIOD, 0)))
|
||||
|
||||
@@ -21,8 +21,8 @@ that data into a seed for a psuedo random number generator.
|
||||
* re-seed.
|
||||
*/
|
||||
|
||||
PRIVATE unsigned long deriv[RANDOM_SOURCES][N_DERIV];
|
||||
PRIVATE int pool_ind[RANDOM_SOURCES];
|
||||
PRIVATE unsigned long deriv[TOTAL_SOURCES][N_DERIV];
|
||||
PRIVATE int pool_ind[TOTAL_SOURCES];
|
||||
PRIVATE SHA256_CTX pool_ctx[NR_POOLS];
|
||||
PRIVATE unsigned samples= 0;
|
||||
PRIVATE int got_seeded= 0;
|
||||
@@ -39,10 +39,10 @@ PUBLIC void random_init()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
assert(&deriv[RANDOM_SOURCES-1][N_DERIV-1] ==
|
||||
&deriv[0][0] + RANDOM_SOURCES*N_DERIV -1);
|
||||
assert(&deriv[TOTAL_SOURCES-1][N_DERIV-1] ==
|
||||
&deriv[0][0] + TOTAL_SOURCES*N_DERIV -1);
|
||||
|
||||
for (i= 0; i<RANDOM_SOURCES; i++)
|
||||
for (i= 0; i<TOTAL_SOURCES; i++)
|
||||
{
|
||||
for (j= 0; j<N_DERIV; j++)
|
||||
deriv[i][j]= 0;
|
||||
@@ -64,7 +64,7 @@ PUBLIC int random_isseeded()
|
||||
|
||||
PUBLIC void random_update(source, buf, count)
|
||||
int source;
|
||||
unsigned short *buf;
|
||||
rand_t *buf;
|
||||
int count;
|
||||
{
|
||||
int i;
|
||||
@@ -72,7 +72,7 @@ int count;
|
||||
#if 0
|
||||
printf("random_update: got %d samples for source %d\n", count, source);
|
||||
#endif
|
||||
if (source < 0 || source >= RANDOM_SOURCES)
|
||||
if (source < 0 || source >= TOTAL_SOURCES)
|
||||
panic("memory", "random_update: bad source", source);
|
||||
for (i= 0; i<count; i++)
|
||||
add_sample(source, buf[i]);
|
||||
|
||||
@@ -4,9 +4,13 @@ random.h
|
||||
Public interface to the random number generator
|
||||
*/
|
||||
|
||||
/* Internal random sources */
|
||||
#define RND_TIMING 0
|
||||
#define RANDOM_SOURCES_INTERNAL 1
|
||||
#define TOTAL_SOURCES (RANDOM_SOURCES+RANDOM_SOURCES_INTERNAL)
|
||||
|
||||
_PROTOTYPE( void random_init, (void) );
|
||||
_PROTOTYPE( int random_isseeded, (void) );
|
||||
_PROTOTYPE( void random_update, (int source, unsigned short *buf,
|
||||
int count) );
|
||||
_PROTOTYPE( void random_update, (int source, rand_t *buf, int count) );
|
||||
_PROTOTYPE( void random_getbytes, (void *buf, size_t size) );
|
||||
_PROTOTYPE( void random_putbytes, (void *buf, size_t size) );
|
||||
|
||||
Reference in New Issue
Block a user