]> Zhao Yanbai Git Server - minix.git/commitdiff
moved type and constants for random data to include file;
authorBen Gras <ben@minix3.org>
Thu, 2 Apr 2009 15:24:44 +0000 (15:24 +0000)
committerBen Gras <ben@minix3.org>
Thu, 2 Apr 2009 15:24:44 +0000 (15:24 +0000)
added consistency check in random; added source of randomness
internal to random using timing; only retrieve random bins that are full.

19 files changed:
drivers/random/main.c
drivers/random/random.c
drivers/random/random.h
include/minix/com.h
include/minix/syslib.h
include/minix/sysutil.h
include/minix/type.h
kernel/arch/i386/do_int86.c
kernel/config.h
kernel/const.h
kernel/glo.h
kernel/main.c
kernel/proto.h
kernel/system.c
kernel/system/do_getinfo.c
kernel/system/do_irqctl.c
kernel/type.h
lib/sysutil/Makefile.in
lib/sysutil/get_randomness.c [new file with mode: 0644]

index a032205f564ac6d235b05f4360a876c37ec3a23b..d1d135eefbcff266fdc9517a8de5a508d8c308aa 100644 (file)
@@ -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)))
index ce15c1755411a6815aafad91eff3cf408caae658..001a1a78fd7961eb2522b49bf02060424ea36ed9 100644 (file)
@@ -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]);
index f1318aad24cc5304d9b5674cc152cfc7ace2a18c..2930eb2303624018dc77a817bb5f71472d89c02d 100644 (file)
@@ -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)             );
index 50a13c87a4fda690330fcf035c630f31f82a15db..267c187343f823a7aaa43bc3bf7d27fae6e3757f 100755 (executable)
 #   define GET_PRIVID    17    /* get ID of privilege structure */
 #   define GET_HZ        18    /* get HZ value */
 #   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_VAL_PTR      m7_p1   /* virtual address at caller */ 
 #define I_VAL_LEN      m7_i1   /* max length of value */
index 24f394b820fae3bc599653d6ce75fa711286bbf3..d4facdc2c5f82805f78f95bf2afa80d540bc7680 100755 (executable)
@@ -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_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_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_getirqhooks(dst)   sys_getinfo(GET_IRQHOOKS, dst, 0,0,0)
 #define sys_getirqactids(dst)  sys_getinfo(GET_IRQACTIDS, dst, 0,0,0)
index 31a1edb012cc85980932023774451f42e14479e5..e0b2987b8897d58bd33b9f02aa91752d486e3eb1 100644 (file)
@@ -58,6 +58,8 @@ _PROTOTYPE( int micro_delay, (u32_t micros));
 _PROTOTYPE( u32_t micros_to_ticks, (u32_t micros));
 _PROTOTYPE( int asynsend, (endpoint_t ep, message *msg));
 _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__); }
 
index 8be6b33a6aa368d23b0ec27edc3307192d1eb9a9..7d182348dc7e7727376933f4b3b9acdbdb361c8d 100755 (executable)
@@ -178,6 +178,22 @@ struct kmessages {
   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 */
 
index 9ff1db87628f51663b69bb77d3d1504946b4d719..6b7510e1a5ecf3a1dc9ef8c67a438dbb396536fd 100644 (file)
@@ -36,7 +36,7 @@ register message *m_ptr;      /* pointer to request message */
    * not very random.
    */
   lock;
-  get_randomness(CLOCK_IRQ);
+  get_randomness(&krandom, CLOCK_IRQ);
   unlock;
 
   return(OK);
index 0fb906db77a5a22a5102c5a7c33f0608aa65d260..2c02039301a839b4c1e4781ed0147ae5cef255e2 100644 (file)
  */
 #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
  * 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
index 62588b35c6f80707e9771ad05930e1960dc07124..c3f1ea00831692154dcf1467c3e7f50cad0ebf89 100755 (executable)
@@ -25,9 +25,6 @@
 #define _SRC_  0
 #define _DST_  1
 
-/* Number of random sources */
-#define RANDOM_SOURCES 16
-
 #define get_sys_bit(map,bit) \
        ( MAP_CHUNK(map.chunk,bit) & (1 << CHUNK_OFFSET(bit) )
 #define get_sys_bits(map,bit) \
index 8e240324db8fcb8d522c0686668622ad704f974d..e3ed5735bd1b4b381e135fff2458372bc5f88da1 100755 (executable)
@@ -25,7 +25,7 @@ EXTERN char shutdown_started;         /* TRUE after shutdowns / reboots */
 EXTERN struct kinfo kinfo;             /* kernel information for users */
 EXTERN struct machine machine;         /* machine information for users */
 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 */
 
 /* Process scheduling information and the kernel reentry count. */
index 05bf762fddd9bf061284ad47e83a62c7a9a293e0..1ef2474aaa9a5f15a212bd05cda9a6e2d5d2f815 100755 (executable)
@@ -175,6 +175,8 @@ PUBLIC void main()
   cprof_procs_no = 0;  /* init nr of hash table slots used */
 
   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.
    * Return to the assembly code to start running the current process. 
index 71edffa56601d59dffb9f1991cd368a6ed654726..a3070efdd3c3bb0931a39c25ad7d39ad73ff8670 100755 (executable)
@@ -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 cause_sig, (int proc_nr, int sig_nr)                  );
 _PROTOTYPE( void sys_task, (void)                                      );
-_PROTOTYPE( void get_randomness, (int source)                          );
 #define numap_local(proc_nr, vir_addr, bytes) \
        umap_local(proc_addr(proc_nr), D, (vir_addr), (bytes))
 _PROTOTYPE( phys_bytes umap_grant, (struct proc *, cp_grant_id_t,
index 03f4f9d3c268d144ec8abe57a05998c4a86082a3..77642f62bc0acbfbac082f4a3a2ee7af830d115e 100755 (executable)
@@ -290,28 +290,6 @@ int proc_type;                             /* system or user process flag */
   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                                     *
  *===========================================================================*/
index 5c4062e10e633fe2b3488c2f00e270dc71fb80cd..e40889e1c51c52638a1f22952bba44f6391e0fb1 100644 (file)
@@ -31,6 +31,7 @@ register message *m_ptr;      /* pointer to request message */
   int proc_nr, nr_e, nr;
   struct proc *caller;
   phys_bytes ph;
+  int wipe_rnd_bin = -1;
 
   caller = proc_addr(who_p);
 
@@ -112,7 +113,7 @@ register message *m_ptr;    /* pointer to request message */
         break;
     }
     case GET_RANDOMNESS: {             
-        static struct randomness copy;         /* copy to keep counters */
+        static struct k_randomness copy;       /* copy to keep counters */
        int i;
 
         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_next = 0;
        }
-       length = sizeof(struct randomness);
+       length = sizeof(copy);
        src_vir = (vir_bytes) &copy;
        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: {
         length = sizeof(struct kmessages);
         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)
        return EFAULT;
   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);
 }
 
index 9625a9825e14b787839129f4838858a1bd74cbfc..53893c3915e19d824f6d336dea4c7047e02ed205 100644 (file)
@@ -142,7 +142,7 @@ irq_hook_t *hook;
   /* As a side-effect, the interrupt handler gathers random information by 
    * 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.
    * If it's dead, this should never happen, as processes that die 
index 8f3b6864bf43828de65738ee37bee4a3f206df2c..f09939737704b37ef98ce8d7af43237b51ecec4b 100755 (executable)
@@ -2,6 +2,7 @@
 #define TYPE_H
 
 #include <minix/com.h>
+#include <ibm/interrupt.h>
 
 typedef _PROTOTYPE( void task_t, (void) );
 
@@ -27,14 +28,6 @@ struct boot_image {
   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_id_t;        
 
index 4f348804fc547a6c085069ccbbd5d4432deb8b47..a44addf98309e19eae967e6a003d4fe78c65b7e0 100644 (file)
@@ -10,6 +10,7 @@ libsys_FILES=" \
        kprintf.c \
        kputc.c \
        tickdelay.c \
+       get_randomness.c \
        getuptime.c \
        getuptime2.c \
        env_get_prm.c \
diff --git a/lib/sysutil/get_randomness.c b/lib/sysutil/get_randomness.c
new file mode 100644 (file)
index 0000000..a52a1e2
--- /dev/null
@@ -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;  
+} 
+  
+