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:
parent
51596bc608
commit
9647fbc94e
19 changed files with 177 additions and 80 deletions
|
@ -6,9 +6,7 @@
|
||||||
#include "../drivers.h"
|
#include "../drivers.h"
|
||||||
#include "../libdriver/driver.h"
|
#include "../libdriver/driver.h"
|
||||||
#include <sys/ioc_memory.h>
|
#include <sys/ioc_memory.h>
|
||||||
#include "../../kernel/const.h"
|
#include <minix/type.h>
|
||||||
#include "../../kernel/config.h"
|
|
||||||
#include "../../kernel/type.h"
|
|
||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "random.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( int r_ioctl, (struct driver *dp, message *m_ptr, int safe) );
|
||||||
FORWARD _PROTOTYPE( void r_geometry, (struct partition *entry) );
|
FORWARD _PROTOTYPE( void r_geometry, (struct partition *entry) );
|
||||||
FORWARD _PROTOTYPE( void r_random, (struct driver *dp, message *m_ptr) );
|
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. */
|
/* Entry points to this driver. */
|
||||||
PRIVATE struct driver r_dtab = {
|
PRIVATE struct driver r_dtab = {
|
||||||
|
@ -197,9 +196,30 @@ message *m_ptr;
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE void r_init()
|
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();
|
random_init();
|
||||||
r_random(NULL, NULL); /* also set periodic timer */
|
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);
|
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 *
|
* r_random *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
|
@ -229,30 +288,21 @@ struct driver *dp; /* pointer to driver structure */
|
||||||
message *m_ptr; /* pointer to alarm message */
|
message *m_ptr; /* pointer to alarm message */
|
||||||
{
|
{
|
||||||
/* Fetch random information from the kernel to update /dev/random. */
|
/* Fetch random information from the kernel to update /dev/random. */
|
||||||
int i, s, r_next, r_size, r_high;
|
int s;
|
||||||
struct randomness krandom;
|
static int bin = 0;
|
||||||
|
static struct k_randomness_bin krandom_bin;
|
||||||
|
u32_t hi, lo;
|
||||||
|
rand_t r;
|
||||||
|
|
||||||
if (OK != (s=sys_getrandomness(&krandom)))
|
bin = (bin+1) % RANDOM_SOURCES;
|
||||||
report("RANDOM", "sys_getrandomness failed", s);
|
|
||||||
|
|
||||||
for (i= 0; i<RANDOM_SOURCES; i++)
|
if(sys_getrandom_bin(&krandom_bin, bin) == OK)
|
||||||
{
|
r_updatebin(bin, &krandom_bin);
|
||||||
r_next= krandom.bin[i].r_next;
|
|
||||||
r_size= krandom.bin[i].r_size;
|
/* Add our own timing source. */
|
||||||
r_high= r_next+r_size;
|
read_tsc(&hi, &lo);
|
||||||
if (r_high <= RANDOM_ELEMENTS)
|
r = lo;
|
||||||
{
|
random_update(RND_TIMING, &r, 1);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Schedule new alarm for next m_random call. */
|
/* Schedule new alarm for next m_random call. */
|
||||||
if (OK != (s=sys_setalarm(KRANDOM_PERIOD, 0)))
|
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.
|
* re-seed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PRIVATE unsigned long deriv[RANDOM_SOURCES][N_DERIV];
|
PRIVATE unsigned long deriv[TOTAL_SOURCES][N_DERIV];
|
||||||
PRIVATE int pool_ind[RANDOM_SOURCES];
|
PRIVATE int pool_ind[TOTAL_SOURCES];
|
||||||
PRIVATE SHA256_CTX pool_ctx[NR_POOLS];
|
PRIVATE SHA256_CTX pool_ctx[NR_POOLS];
|
||||||
PRIVATE unsigned samples= 0;
|
PRIVATE unsigned samples= 0;
|
||||||
PRIVATE int got_seeded= 0;
|
PRIVATE int got_seeded= 0;
|
||||||
|
@ -39,10 +39,10 @@ PUBLIC void random_init()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
assert(&deriv[RANDOM_SOURCES-1][N_DERIV-1] ==
|
assert(&deriv[TOTAL_SOURCES-1][N_DERIV-1] ==
|
||||||
&deriv[0][0] + RANDOM_SOURCES*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++)
|
for (j= 0; j<N_DERIV; j++)
|
||||||
deriv[i][j]= 0;
|
deriv[i][j]= 0;
|
||||||
|
@ -64,7 +64,7 @@ PUBLIC int random_isseeded()
|
||||||
|
|
||||||
PUBLIC void random_update(source, buf, count)
|
PUBLIC void random_update(source, buf, count)
|
||||||
int source;
|
int source;
|
||||||
unsigned short *buf;
|
rand_t *buf;
|
||||||
int count;
|
int count;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -72,7 +72,7 @@ int count;
|
||||||
#if 0
|
#if 0
|
||||||
printf("random_update: got %d samples for source %d\n", count, source);
|
printf("random_update: got %d samples for source %d\n", count, source);
|
||||||
#endif
|
#endif
|
||||||
if (source < 0 || source >= RANDOM_SOURCES)
|
if (source < 0 || source >= TOTAL_SOURCES)
|
||||||
panic("memory", "random_update: bad source", source);
|
panic("memory", "random_update: bad source", source);
|
||||||
for (i= 0; i<count; i++)
|
for (i= 0; i<count; i++)
|
||||||
add_sample(source, buf[i]);
|
add_sample(source, buf[i]);
|
||||||
|
|
|
@ -4,9 +4,13 @@ random.h
|
||||||
Public interface to the random number generator
|
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( void random_init, (void) );
|
||||||
_PROTOTYPE( int random_isseeded, (void) );
|
_PROTOTYPE( int random_isseeded, (void) );
|
||||||
_PROTOTYPE( void random_update, (int source, unsigned short *buf,
|
_PROTOTYPE( void random_update, (int source, rand_t *buf, int count) );
|
||||||
int count) );
|
|
||||||
_PROTOTYPE( void random_getbytes, (void *buf, size_t size) );
|
_PROTOTYPE( void random_getbytes, (void *buf, size_t size) );
|
||||||
_PROTOTYPE( void random_putbytes, (void *buf, size_t size) );
|
_PROTOTYPE( void random_putbytes, (void *buf, size_t size) );
|
||||||
|
|
|
@ -461,6 +461,7 @@
|
||||||
# define GET_PRIVID 17 /* get ID of privilege structure */
|
# define GET_PRIVID 17 /* get ID of privilege structure */
|
||||||
# define GET_HZ 18 /* get HZ value */
|
# define GET_HZ 18 /* get HZ value */
|
||||||
# define GET_WHOAMI 19 /* get own name and endpoint */
|
# define GET_WHOAMI 19 /* get own name and endpoint */
|
||||||
|
# define GET_RANDOMNESS_BIN 20 /* get one randomness bin */
|
||||||
#define I_ENDPT m7_i4 /* calling process */
|
#define I_ENDPT m7_i4 /* calling process */
|
||||||
#define I_VAL_PTR m7_p1 /* virtual address at caller */
|
#define I_VAL_PTR m7_p1 /* virtual address at caller */
|
||||||
#define I_VAL_LEN m7_i1 /* max length of value */
|
#define I_VAL_LEN m7_i1 /* max length of value */
|
||||||
|
|
|
@ -156,6 +156,7 @@ _PROTOTYPE(int sys_segctl, (int *index, u16_t *seg, vir_bytes *off,
|
||||||
#define sys_getprivtab(dst) sys_getinfo(GET_PRIVTAB, dst, 0,0,0)
|
#define sys_getprivtab(dst) sys_getinfo(GET_PRIVTAB, dst, 0,0,0)
|
||||||
#define sys_getproc(dst,nr) sys_getinfo(GET_PROC, dst, 0,0, nr)
|
#define sys_getproc(dst,nr) sys_getinfo(GET_PROC, dst, 0,0, nr)
|
||||||
#define sys_getrandomness(dst) sys_getinfo(GET_RANDOMNESS, dst, 0,0,0)
|
#define sys_getrandomness(dst) sys_getinfo(GET_RANDOMNESS, dst, 0,0,0)
|
||||||
|
#define sys_getrandom_bin(d,b) sys_getinfo(GET_RANDOMNESS_BIN, d, 0,0,b)
|
||||||
#define sys_getimage(dst) sys_getinfo(GET_IMAGE, dst, 0,0,0)
|
#define sys_getimage(dst) sys_getinfo(GET_IMAGE, dst, 0,0,0)
|
||||||
#define sys_getirqhooks(dst) sys_getinfo(GET_IRQHOOKS, dst, 0,0,0)
|
#define sys_getirqhooks(dst) sys_getinfo(GET_IRQHOOKS, dst, 0,0,0)
|
||||||
#define sys_getirqactids(dst) sys_getinfo(GET_IRQACTIDS, dst, 0,0,0)
|
#define sys_getirqactids(dst) sys_getinfo(GET_IRQACTIDS, dst, 0,0,0)
|
||||||
|
|
|
@ -58,6 +58,8 @@ _PROTOTYPE( int micro_delay, (u32_t micros));
|
||||||
_PROTOTYPE( u32_t micros_to_ticks, (u32_t micros));
|
_PROTOTYPE( u32_t micros_to_ticks, (u32_t micros));
|
||||||
_PROTOTYPE( int asynsend, (endpoint_t ep, message *msg));
|
_PROTOTYPE( int asynsend, (endpoint_t ep, message *msg));
|
||||||
_PROTOTYPE( void ser_putc, (char c));
|
_PROTOTYPE( void ser_putc, (char c));
|
||||||
|
_PROTOTYPE( void get_randomness, (struct k_randomness *, int));
|
||||||
|
|
||||||
|
|
||||||
#define ASSERT(c) if(!(c)) { panic(__FILE__, "assert " #c " failed at line", __LINE__); }
|
#define ASSERT(c) if(!(c)) { panic(__FILE__, "assert " #c " failed at line", __LINE__); }
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,22 @@ struct kmessages {
|
||||||
char km_buf[_KMESS_BUF_SIZE]; /* buffer for messages */
|
char km_buf[_KMESS_BUF_SIZE]; /* buffer for messages */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <ibm/interrupt.h>
|
||||||
|
|
||||||
|
/* randomness struct: random sources after interrupts: */
|
||||||
|
#define RANDOM_SOURCES NR_IRQ_VECTORS
|
||||||
|
#define RANDOM_ELEMENTS 64
|
||||||
|
|
||||||
|
typedef unsigned short rand_t;
|
||||||
|
|
||||||
|
struct k_randomness {
|
||||||
|
int random_elements, random_sources;
|
||||||
|
struct k_randomness_bin {
|
||||||
|
int r_next; /* next index to write */
|
||||||
|
int r_size; /* number of random elements */
|
||||||
|
rand_t r_buf[RANDOM_ELEMENTS]; /* buffer for random info */
|
||||||
|
} bin[RANDOM_SOURCES];
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _TYPE_H */
|
#endif /* _TYPE_H */
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ register message *m_ptr; /* pointer to request message */
|
||||||
* not very random.
|
* not very random.
|
||||||
*/
|
*/
|
||||||
lock;
|
lock;
|
||||||
get_randomness(CLOCK_IRQ);
|
get_randomness(&krandom, CLOCK_IRQ);
|
||||||
unlock;
|
unlock;
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
@ -49,11 +49,6 @@
|
||||||
*/
|
*/
|
||||||
#define P_NAME_LEN 8
|
#define P_NAME_LEN 8
|
||||||
|
|
||||||
/* Buffer to gather randomness. This is used to generate a random stream by
|
|
||||||
* the MEMORY driver when reading from /dev/random.
|
|
||||||
*/
|
|
||||||
#define RANDOM_ELEMENTS 32
|
|
||||||
|
|
||||||
/* This section contains defines for valuable system resources that are used
|
/* This section contains defines for valuable system resources that are used
|
||||||
* by device drivers. The number of elements of the vectors is determined by
|
* by device drivers. The number of elements of the vectors is determined by
|
||||||
* the maximum needed by any given driver. The number of interrupt hooks may
|
* the maximum needed by any given driver. The number of interrupt hooks may
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
#define _SRC_ 0
|
#define _SRC_ 0
|
||||||
#define _DST_ 1
|
#define _DST_ 1
|
||||||
|
|
||||||
/* Number of random sources */
|
|
||||||
#define RANDOM_SOURCES 16
|
|
||||||
|
|
||||||
#define get_sys_bit(map,bit) \
|
#define get_sys_bit(map,bit) \
|
||||||
( MAP_CHUNK(map.chunk,bit) & (1 << CHUNK_OFFSET(bit) )
|
( MAP_CHUNK(map.chunk,bit) & (1 << CHUNK_OFFSET(bit) )
|
||||||
#define get_sys_bits(map,bit) \
|
#define get_sys_bits(map,bit) \
|
||||||
|
|
|
@ -25,7 +25,7 @@ EXTERN char shutdown_started; /* TRUE after shutdowns / reboots */
|
||||||
EXTERN struct kinfo kinfo; /* kernel information for users */
|
EXTERN struct kinfo kinfo; /* kernel information for users */
|
||||||
EXTERN struct machine machine; /* machine information for users */
|
EXTERN struct machine machine; /* machine information for users */
|
||||||
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
|
EXTERN struct kmessages kmess; /* diagnostic messages in kernel */
|
||||||
EXTERN struct randomness krandom; /* gather kernel random information */
|
EXTERN struct k_randomness krandom; /* gather kernel random information */
|
||||||
EXTERN struct loadinfo kloadinfo; /* status of load average */
|
EXTERN struct loadinfo kloadinfo; /* status of load average */
|
||||||
|
|
||||||
/* Process scheduling information and the kernel reentry count. */
|
/* Process scheduling information and the kernel reentry count. */
|
||||||
|
|
|
@ -175,6 +175,8 @@ PUBLIC void main()
|
||||||
cprof_procs_no = 0; /* init nr of hash table slots used */
|
cprof_procs_no = 0; /* init nr of hash table slots used */
|
||||||
|
|
||||||
vm_running = 0;
|
vm_running = 0;
|
||||||
|
krandom.random_sources = RANDOM_SOURCES;
|
||||||
|
krandom.random_elements = RANDOM_ELEMENTS;
|
||||||
|
|
||||||
/* MINIX is now ready. All boot image processes are on the ready queue.
|
/* MINIX is now ready. All boot image processes are on the ready queue.
|
||||||
* Return to the assembly code to start running the current process.
|
* Return to the assembly code to start running the current process.
|
||||||
|
|
|
@ -58,7 +58,6 @@ _PROTOTYPE( int get_priv, (register struct proc *rc, int proc_type) );
|
||||||
_PROTOTYPE( void send_sig, (int proc_nr, int sig_nr) );
|
_PROTOTYPE( void send_sig, (int proc_nr, int sig_nr) );
|
||||||
_PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr) );
|
_PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr) );
|
||||||
_PROTOTYPE( void sys_task, (void) );
|
_PROTOTYPE( void sys_task, (void) );
|
||||||
_PROTOTYPE( void get_randomness, (int source) );
|
|
||||||
#define numap_local(proc_nr, vir_addr, bytes) \
|
#define numap_local(proc_nr, vir_addr, bytes) \
|
||||||
umap_local(proc_addr(proc_nr), D, (vir_addr), (bytes))
|
umap_local(proc_addr(proc_nr), D, (vir_addr), (bytes))
|
||||||
_PROTOTYPE( phys_bytes umap_grant, (struct proc *, cp_grant_id_t,
|
_PROTOTYPE( phys_bytes umap_grant, (struct proc *, cp_grant_id_t,
|
||||||
|
|
|
@ -290,28 +290,6 @@ int proc_type; /* system or user process flag */
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
|
||||||
* get_randomness *
|
|
||||||
*===========================================================================*/
|
|
||||||
PUBLIC void get_randomness(source)
|
|
||||||
int source;
|
|
||||||
{
|
|
||||||
/* Use architecture-dependent high-resolution clock for
|
|
||||||
* raw entropy gathering.
|
|
||||||
*/
|
|
||||||
int r_next;
|
|
||||||
unsigned long tsc_high, tsc_low;
|
|
||||||
|
|
||||||
source %= RANDOM_SOURCES;
|
|
||||||
r_next= krandom.bin[source].r_next;
|
|
||||||
read_tsc(&tsc_high, &tsc_low);
|
|
||||||
krandom.bin[source].r_buf[r_next] = tsc_low;
|
|
||||||
if (krandom.bin[source].r_size < RANDOM_ELEMENTS) {
|
|
||||||
krandom.bin[source].r_size ++;
|
|
||||||
}
|
|
||||||
krandom.bin[source].r_next = (r_next + 1 ) % RANDOM_ELEMENTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* send_sig *
|
* send_sig *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
|
|
@ -31,6 +31,7 @@ register message *m_ptr; /* pointer to request message */
|
||||||
int proc_nr, nr_e, nr;
|
int proc_nr, nr_e, nr;
|
||||||
struct proc *caller;
|
struct proc *caller;
|
||||||
phys_bytes ph;
|
phys_bytes ph;
|
||||||
|
int wipe_rnd_bin = -1;
|
||||||
|
|
||||||
caller = proc_addr(who_p);
|
caller = proc_addr(who_p);
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ register message *m_ptr; /* pointer to request message */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GET_RANDOMNESS: {
|
case GET_RANDOMNESS: {
|
||||||
static struct randomness copy; /* copy to keep counters */
|
static struct k_randomness copy; /* copy to keep counters */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
copy = krandom;
|
copy = krandom;
|
||||||
|
@ -120,10 +121,28 @@ register message *m_ptr; /* pointer to request message */
|
||||||
krandom.bin[i].r_size = 0; /* invalidate random data */
|
krandom.bin[i].r_size = 0; /* invalidate random data */
|
||||||
krandom.bin[i].r_next = 0;
|
krandom.bin[i].r_next = 0;
|
||||||
}
|
}
|
||||||
length = sizeof(struct randomness);
|
length = sizeof(copy);
|
||||||
src_vir = (vir_bytes) ©
|
src_vir = (vir_bytes) ©
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GET_RANDOMNESS_BIN: {
|
||||||
|
int i, bin = m_ptr->I_VAL_LEN2_E;
|
||||||
|
|
||||||
|
if(bin < 0 || bin >= RANDOM_SOURCES) {
|
||||||
|
kprintf("SYSTEM: GET_RANDOMNESS_BIN: %d out of range\n", bin);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(krandom.bin[bin].r_size < RANDOM_ELEMENTS)
|
||||||
|
return ENOENT;
|
||||||
|
|
||||||
|
length = sizeof(krandom.bin[bin]);
|
||||||
|
src_vir = (vir_bytes) &krandom.bin[bin];
|
||||||
|
|
||||||
|
wipe_rnd_bin = bin;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GET_KMESSAGES: {
|
case GET_KMESSAGES: {
|
||||||
length = sizeof(struct kmessages);
|
length = sizeof(struct kmessages);
|
||||||
src_vir = (vir_bytes) &kmess;
|
src_vir = (vir_bytes) &kmess;
|
||||||
|
@ -158,7 +177,12 @@ register message *m_ptr; /* pointer to request message */
|
||||||
if((ph=umap_local(caller, D, (vir_bytes) m_ptr->I_VAL_PTR,length)) == 0)
|
if((ph=umap_local(caller, D, (vir_bytes) m_ptr->I_VAL_PTR,length)) == 0)
|
||||||
return EFAULT;
|
return EFAULT;
|
||||||
CHECKRANGE_OR_SUSPEND(caller, ph, length, 1);
|
CHECKRANGE_OR_SUSPEND(caller, ph, length, 1);
|
||||||
data_copy(SYSTEM, src_vir, who_e, (vir_bytes) m_ptr->I_VAL_PTR, length);
|
if(data_copy(SYSTEM, src_vir, who_e, (vir_bytes) m_ptr->I_VAL_PTR, length) == OK) {
|
||||||
|
if(wipe_rnd_bin >= 0 && wipe_rnd_bin < RANDOM_SOURCES) {
|
||||||
|
krandom.bin[wipe_rnd_bin].r_size = 0;
|
||||||
|
krandom.bin[wipe_rnd_bin].r_next = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ irq_hook_t *hook;
|
||||||
/* As a side-effect, the interrupt handler gathers random information by
|
/* As a side-effect, the interrupt handler gathers random information by
|
||||||
* timestamping the interrupt events. This is used for /dev/random.
|
* timestamping the interrupt events. This is used for /dev/random.
|
||||||
*/
|
*/
|
||||||
get_randomness(hook->irq);
|
get_randomness(&krandom, hook->irq);
|
||||||
|
|
||||||
/* Check if the handler is still alive.
|
/* Check if the handler is still alive.
|
||||||
* If it's dead, this should never happen, as processes that die
|
* If it's dead, this should never happen, as processes that die
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define TYPE_H
|
#define TYPE_H
|
||||||
|
|
||||||
#include <minix/com.h>
|
#include <minix/com.h>
|
||||||
|
#include <ibm/interrupt.h>
|
||||||
|
|
||||||
typedef _PROTOTYPE( void task_t, (void) );
|
typedef _PROTOTYPE( void task_t, (void) );
|
||||||
|
|
||||||
|
@ -27,14 +28,6 @@ struct boot_image {
|
||||||
endpoint_t endpoint; /* endpoint number when started */
|
endpoint_t endpoint; /* endpoint number when started */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct randomness {
|
|
||||||
struct {
|
|
||||||
int r_next; /* next index to write */
|
|
||||||
int r_size; /* number of random elements */
|
|
||||||
unsigned short r_buf[RANDOM_ELEMENTS]; /* buffer for random info */
|
|
||||||
} bin[RANDOM_SOURCES];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef unsigned long irq_policy_t;
|
typedef unsigned long irq_policy_t;
|
||||||
typedef unsigned long irq_id_t;
|
typedef unsigned long irq_id_t;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ libsys_FILES=" \
|
||||||
kprintf.c \
|
kprintf.c \
|
||||||
kputc.c \
|
kputc.c \
|
||||||
tickdelay.c \
|
tickdelay.c \
|
||||||
|
get_randomness.c \
|
||||||
getuptime.c \
|
getuptime.c \
|
||||||
getuptime2.c \
|
getuptime2.c \
|
||||||
env_get_prm.c \
|
env_get_prm.c \
|
||||||
|
|
34
lib/sysutil/get_randomness.c
Normal file
34
lib/sysutil/get_randomness.c
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#include <lib.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <minix/profile.h>
|
||||||
|
#include <minix/syslib.h>
|
||||||
|
#include <minix/type.h>
|
||||||
|
#include <minix/sysutil.h>
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* get_randomness *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC void get_randomness(rand, source)
|
||||||
|
struct k_randomness *rand;
|
||||||
|
int source;
|
||||||
|
{
|
||||||
|
/* Use architecture-dependent high-resolution clock for
|
||||||
|
* raw entropy gathering.
|
||||||
|
*/
|
||||||
|
int r_next;
|
||||||
|
unsigned long tsc_high, tsc_low;
|
||||||
|
|
||||||
|
source %= RANDOM_SOURCES;
|
||||||
|
r_next= rand->bin[source].r_next;
|
||||||
|
read_tsc(&tsc_high, &tsc_low);
|
||||||
|
rand->bin[source].r_buf[r_next] = tsc_low;
|
||||||
|
if (rand->bin[source].r_size < RANDOM_ELEMENTS) {
|
||||||
|
rand->bin[source].r_size ++;
|
||||||
|
}
|
||||||
|
rand->bin[source].r_next = (r_next + 1 ) % RANDOM_ELEMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue