Hi. This is my first post to FreeBSD-Hackers. It's probably the wrong
place at the wrong time and totaly inappropriate in general, so start
flaming right now.

Anyway, I've writting a small patch to enable the thermal noise random
number generator found in the i82802 (i82810).

It breaks the /dev/random semantics slightly as the bitpool never run
out of fresh bits.

Hopefully somebody finds it usefull :-). I do.

BTW, the patch is against the REL-3.3 kernel and x86-only.

/Bjorn

diff -Nru sys.orig/i386/conf/files.i386 sys/i386/conf/files.i386
--- sys.orig/i386/conf/files.i386       Mon Sep  6 00:35:34 1999
+++ sys/i386/conf/files.i386    Fri Jan  7 00:21:44 2000
@@ -79,6 +79,7 @@
 i386/i386/globals.s            standard
 i386/i386/i386-gdbstub.c       optional        ddb
 i386/i386/i686_mem.c           standard
+i386/i386/i82802_rng.c         standard
 i386/i386/identcpu.c           standard
 i386/i386/in_cksum.c           optional        inet
 i386/i386/initcpu.c            standard
diff -Nru sys.orig/i386/i386/i82802_rng.c sys/i386/i386/i82802_rng.c
--- sys.orig/i386/i386/i82802_rng.c     Thu Jan  1 00:00:00 1970
+++ sys/i386/i386/i82802_rng.c  Fri Jan  7 09:38:43 2000
@@ -0,0 +1,68 @@
+/* $Id$
+ *
+ * Copyright (c) 2000 Bjorn Ahlqvist.
+ * All rights reserved.
+ *
+ * v1.0 - Initial version.
+ *
+ * TODO: We should make sure we're really receiving something
+ *      that look random. The specification suggests FIPS 140-1.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <machine/clock.h>
+#include <machine/random.h>
+
+#define I82802_RNG_NAME "i82802 thermal noise random number generator"
+
+#define I82802_HW_RNG_ENABLE   1               /* hw_status */
+#define I82802_HW_RNG_PRESENT  0x40            /* hw_status */
+#define I82802_RNG_DATA_PRESENT 1              /* rng_status */
+#define I82802_RNG_BASE                0xffbc0000      /* absolute address */
+#define I82802_RNG_DELAY       5               /* about 4.5 ms */
+
+struct i82802_rng {
+       u_char fill[0x015f];
+       u_char hw_status;
+       u_char rng_status;
+       u_char rng_data;
+};
+
+
+static struct i82802_rng *rngp;
+int rng_present;
+
+u_char rng_read(void)
+{
+       while(!(rngp->rng_status&I82802_RNG_DATA_PRESENT)) {    /* wait.. */
+               if(!curproc) DELAY(I82802_RNG_DELAY);           /* ..for data */
+               else tsleep(&rng_read,PRIBIO,"rngrd",1);
+       }
+
+       return(rngp->rng_data);                                 /* got some */
+}
+
+static void rng_probe(void *dummy)
+{
+       rngp=pmap_mapdev(I82802_RNG_BASE,sizeof(*rngp));        /* wire mem */
+       
+       rng_present=rngp->hw_status&I82802_HW_RNG_PRESENT;      /* present? */
+       if(!rng_present) return;                                /* no return */
+       rngp->hw_status|=I82802_HW_RNG_ENABLE;                  /* yes enable */
+       
+       printf(I82802_RNG_NAME" at 0x%08x enabled.\n",I82802_RNG_BASE);
+}
+
+SYSINIT(rng,SI_SUB_DRIVERS,SI_ORDER_ANY,rng_probe,NULL)
+
diff -Nru sys.orig/i386/include/random.h sys/i386/include/random.h
--- sys.orig/i386/include/random.h      Sun Aug 29 16:06:47 1999
+++ sys/i386/include/random.h   Fri Jan  7 02:34:17 2000
@@ -66,8 +66,13 @@
        int             sc_intr;
 };
 
+/* Exported variables */
+
+extern int rng_present;
+
 /* Exported functions */
 
+u_char rng_read(void);
 void rand_initialize(void);
 void add_keyboard_randomness(u_char scancode);
 inthand2_t add_interrupt_randomness;
diff -Nru sys.orig/i386/isa/random_machdep.c sys/i386/isa/random_machdep.c
--- sys.orig/i386/isa/random_machdep.c  Sun Aug 29 16:07:31 1999
+++ sys/i386/isa/random_machdep.c       Fri Jan  7 09:36:37 2000
@@ -325,6 +325,13 @@
 u_int
 read_random(void *buf, u_int nbytes)
 {
+       int i;
+
+       if (rng_present) { /* Hardware RNG */ 
+               for(i=0;i<nbytes;i++) *((u_char *)buf)++=rng_read();
+               return nbytes;
+       }
+
        if ((nbytes * 8) > random_state.entropy_count)
                nbytes = random_state.entropy_count / 8;
        

Reply via email to