bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Current Version of Entropy Patch


From: Michael Casadevall
Subject: Current Version of Entropy Patch
Date: Sun, 5 Aug 2007 00:52:42 -0400 (EDT)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This is the latest version of the entropy patch with mixing readded; it uses the Peter Gutmann way of mixing entropy (although the code itself was ported from Linux). I haven't added entropy quality control because I still am not sure how to do it (I read the document, and it doesn't really state how to determine the quality of the entropy pool.

My current idea is to have an array the same size as the pool (which
is 460 bytes (I think) at the moment, which carries an integer containing
the quality of that specific piece of entropy. When the entropy quality
is queried, the function would have to walk the array and add up the quality.
New entropy would be accepted if its quality is higher then the average of the pool (I just worry about the time it would take to calculate the average ...)

Anyway, here's the patch thus far:
? INSTALL
? Makefile.in
? aclocal.m4
? autom4te.cache
? build
? build-aux
? config.h.in
? configure
? entropy_driver_with_ipc.patch
? entropy_patch.diff
? stat_time.patch
? device/.entropy.h.swp
? device/entropy.c
? device/entropy.h
? device/test
? doc/mach.info
? doc/mach.info-1
? doc/mach.info-2
? doc/stamp-vti
? doc/version.texi
? i386/i386/timer.h
Index: Makefile.am
===================================================================
RCS file: /sources/hurd/gnumach/Attic/Makefile.am,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 Makefile.am
- --- Makefile.am       2 Jun 2007 07:35:44 -0000       1.1.2.9
+++ Makefile.am 5 Aug 2007 08:50:33 -0000
@@ -127,9 +127,10 @@
 clib_routines := memcpy memmove memset bcopy bzero             \
                 strchr strstr strsep strpbrk strtok            \
                 htonl htons ntohl ntohs                        \
- -              etext edata end # actually ld magic, not libc.
+                udivdi3 __udivdi3                              \
+                etext _edata end _end # actually ld magic, not libc.
 gnumach-undef: gnumach.$(OBJEXT)
- -     $(NM) -u $< | sed 's/  *U  *//;s/^_*//' | sort -u > $@
+       $(NM) -u $< | sed 's/  *U  *//' | sort -u > $@
 MOSTLYCLEANFILES += gnumach-undef
 gnumach-undef-bad: gnumach-undef Makefile
        sed '$(foreach r,$(clib_routines),/^$r$$/d;)' $< > $@
@@ -138,7 +139,7 @@
        if test -s gnumach-undef-bad; \
        then cat gnumach-undef-bad; exit 2; else true; fi
        $(CCLD) -nostdlib -nostartfiles -r -static \
- -       -o $@ `sed 's/^/-Wl,-u,/' < $<` -x c /dev/null -lc
+         -o $@ `sed 's/^/-Wl,-u,/' < $<` -x c /dev/null -lc -lgcc

 gnumach_LINK = $(LD) $(LINKFLAGS) $(gnumach_LINKFLAGS) -o $@
 gnumach_LDADD = gnumach.o clib-routines.o
Index: Makefrag.am
===================================================================
RCS file: /sources/hurd/gnumach/Attic/Makefrag.am,v
retrieving revision 1.1.2.12
diff -u -r1.1.2.12 Makefrag.am
- --- Makefrag.am       2 Jun 2007 13:23:21 -0000       1.1.2.12
+++ Makefrag.am 5 Aug 2007 08:50:34 -0000
@@ -292,6 +292,14 @@
        device/kmsg.h
 endif

+#
+# kernel entrophy generator device
+
+if enable_entropy
+libkernel_a_SOURCES += \
+       device/entropy.c
+       device/entropy.h
+endif

 #
 # Version number.
Index: configfrag.ac
===================================================================
RCS file: /sources/hurd/gnumach/Attic/configfrag.ac,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 configfrag.ac
- --- configfrag.ac     4 Aug 2007 18:50:19 -0000       1.1.2.7
+++ configfrag.ac       5 Aug 2007 08:50:34 -0000
@@ -98,7 +98,7 @@
 AC_DEFINE([SIMPLE_CLOCK], [0], [SIMPLE_CLOCK])

 # Use statistical timing.
- -AC_DEFINE([STAT_TIME], [1], [STAT_TIME])
+AC_DEFINE([STAT_TIME], [0], [STAT_TIME])

 # Kernel tracing.
 AC_DEFINE([XPR_DEBUG], [1], [XPR_DEBUG])
@@ -128,7 +128,18 @@
 [else]
   AM_CONDITIONAL([enable_kmsg], [false])
 [fi]
- - +
+
+AC_ARG_ENABLE([entropy],
+  AS_HELP_STRING([--disable-entropy], [disable use of entropy device]))
+[if [ x"$enable_kmsg" != xno ]; then]
+  AC_DEFINE([MACH_ENTROPY], [], [enable use of entropy device])
+  AM_CONDITIONAL([enable_entropy], [true])
+[else]
+  AM_CONDITIONAL([enable_entropy], [false])
+[fi]
+
+
 #
 # Set up `SYSTYPE/SYSTYPE' and `SYSTYPE/include/mach/SYSTYPE' links.
 #
@@ -138,7 +149,7 @@
 # <http://lists.gnu.org/archive/html/bug-automake/2006-11/msg00027.html>.
 AC_CONFIG_LINKS([machine:$systype/$systype
                 mach/machine:$systype/include/mach/$systype])
- - +
 dnl Local Variables:
 dnl mode: autoconf
 dnl End:
Index: device/blkio.c
===================================================================
RCS file: /sources/hurd/gnumach/device/Attic/blkio.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 blkio.c
- --- device/blkio.c    25 Feb 1997 21:28:13 -0000      1.1.1.1
+++ device/blkio.c      5 Aug 2007 08:50:34 -0000
@@ -36,7 +36,9 @@
 #include <device/io_req.h>
 #include <device/ds_routines.h>

- -
+#ifdef MACH_ENTROPY
+#include <device/entropy.h>
+#endif

 io_return_t block_io(strat, max_count, ior)
        void                    (*strat)();
@@ -149,6 +151,10 @@
        do {
            prev = next;
            next = prev->io_next;
+#ifdef MACH_ENTROPY
+           /*  Let's grab the cylinder numbers for entropy */
+           entropy_putdata (prev, sizeof(io_req_t));
+#endif
        } while (next != 0 && prev->io_cylinder == next->io_cylinder);

        if (next == 0) {
Index: device/cons.c
===================================================================
RCS file: /sources/hurd/gnumach/device/Attic/cons.c,v
retrieving revision 1.2.4.6
diff -u -r1.2.4.6 cons.c
- --- device/cons.c     13 Nov 2006 21:30:36 -0000      1.2.4.6
+++ device/cons.c       5 Aug 2007 08:50:34 -0000
@@ -44,6 +44,10 @@
 #include <device/kmsg.h>
 #endif

+#ifdef MACH_ENTROPY
+#include <device/entropy.h>
+#endif
+
 static int cn_inited = 0;
 static struct consdev *cn_tab = 0;     /* physical console device info */
 #ifndef MACH_KERNEL
@@ -230,8 +234,16 @@
 cngetc()
 {
        if (cn_tab)
- -             return ((*cn_tab->cn_getc)(cn_tab->cn_dev, 1));
+#if defined(MACH_KERNEL) && defined(MACH_ENTROPY)
+               entropy_putchar (cn_tab->cn_dev);
+#endif // MACH_ENTROPY and MACH_ENTROPY`
+       return ((*cn_tab->cn_getc)(cn_tab->cn_dev, 1));
        if (romgetc)
+#ifdef MACH_KERNEL
+#ifdef MACH_ENTROPY
+               entropy_putchar(*romgetc);
+#endif // MACH_KERNL
+#endif // MACH_ENTROPY
                return ((*romgetc)(1));
        return (0);
 }
Index: i386/i386/locore.S
===================================================================
RCS file: /sources/hurd/gnumach/i386/i386/locore.S,v
retrieving revision 1.6.2.10
diff -u -r1.6.2.10 locore.S
- --- i386/i386/locore.S        4 Aug 2007 10:49:55 -0000       1.6.2.10
+++ i386/i386/locore.S  5 Aug 2007 08:50:35 -0000
@@ -112,6 +112,23 @@
        .comm   EXT(current_tstamp), 4*NCPUS

 /*
+ * Get the timer value, uses %eax
+ */
+#ifdef NO_RDTSC
+#define GET_TIMER(out) \
+       movl    VA_ETC,out
+#else
+#define GET_TIMER(out) \
+       pushl   %edx                            /* save %edx */ ;\
+       rdtsc                                   /* get timestamp */ ;\
+       shrl    $10,%eax                        /* Kcycles is better */ ;\
+       shll    $22,%edx                        /* get hi lo bits */ ;\
+       orl     %edx,%eax                       /* into %eax */ ;\
+       movl    %eax,out                        /* and output */ ;\
+       popl    %edx                            /* restore %edx */
+#endif
+
+/*
  * Update time on user trap entry.
  * 11 instructions (including cli on entry)
  * Assumes CPU number in %edx.
@@ -119,7 +136,7 @@
  */
 #define        TIME_TRAP_UENTRY \
        cli                                     /* block interrupts */  ;\
- -     movl    VA_ETC,%ebx                     /* get timer value */   ;\
+       GET_TIMER(%ebx)                         /* get timer value */   ;\
        movl    CX(EXT(current_tstamp),%edx),%ecx       /* get old time stamp 
*/;\
        movl    %ebx,CX(EXT(current_tstamp),%edx)       /* set new time stamp 
*/;\
        subl    %ecx,%ebx                       /* elapsed = new-old */ ;\
@@ -141,7 +158,7 @@
  */
 #define        TIME_TRAP_SENTRY \
        cli                                     /* block interrupts */  ;\
- -     movl    VA_ETC,%ebx                     /* get timer value */   ;\
+       GET_TIMER(%ebx)                         /* get timer value */   ;\
        movl    CX(EXT(current_tstamp),%edx),%ecx       /* get old time stamp 
*/;\
        movl    %ebx,CX(EXT(current_tstamp),%edx)       /* set new time stamp 
*/;\
        subl    %ecx,%ebx                       /* elapsed = new-old */ ;\
@@ -164,7 +181,7 @@
  */
 #define        TIME_TRAP_UEXIT \
        cli                                     /* block interrupts */  ;\
- -     movl    VA_ETC,%ebx                     /* get timer */         ;\
+       GET_TIMER(%ebx)                         /* get timer */         ;\
        movl    CX(EXT(current_tstamp),%edx),%ecx       /* get old time stamp 
*/;\
        movl    %ebx,CX(EXT(current_tstamp),%edx)       /* set new time stamp 
*/;\
        subl    %ecx,%ebx                       /* elapsed = new-old */ ;\
@@ -184,7 +201,7 @@
  * Uses %ecx.
  */
 #define        TIME_INT_ENTRY \
- -     movl    VA_ETC,%ecx                     /* get timer */         ;\
+       GET_TIMER(%ecx)                         /* get timer */         ;\
        movl    CX(EXT(current_tstamp),%edx),%ebx       /* get old time stamp 
*/;\
        movl    %ecx,CX(EXT(current_tstamp),%edx)       /* set new time stamp 
*/;\
        subl    %ebx,%ecx                       /* elapsed = new-old */ ;\
@@ -201,7 +218,7 @@
  * Uses %eax, %ecx.
  */
 #define        TIME_INT_EXIT \
- -     movl    VA_ETC,%eax                     /* get timer */         ;\
+       GET_TIMER(%eax)                         /* get timer */         ;\
        movl    CX(EXT(current_tstamp),%edx),%ecx       /* get old time stamp 
*/;\
        movl    %eax,CX(EXT(current_tstamp),%edx)       /* set new time stamp 
*/;\
        subl    %ecx,%eax                       /* elapsed = new-old */ ;\
@@ -241,7 +258,7 @@
  */
 ENTRY(timer_switch)
        CPU_NUMBER(%edx)                        /* get this CPU  */
- -     movl    VA_ETC,%ecx                     /* get timer */
+       GET_TIMER(%ecx)                         /* get timer */
        movl    CX(EXT(current_tstamp),%edx),%eax       /* get old time stamp  
*/
        movl    %ecx,CX(EXT(current_tstamp),%edx)       /* set new time stamp */
        subl    %ecx,%eax                       /* elapsed = new - old */
@@ -259,7 +276,7 @@
  */
 ENTRY(start_timer)
        CPU_NUMBER(%edx)                        /* get this CPU */
- -     movl    VA_ETC,%ecx                     /* get timer */
+       GET_TIMER(%ecx)                         /* get timer */
        movl    %ecx,CX(EXT(current_tstamp),%edx)       /* set initial time 
stamp */
        movl    S_ARG0,%ecx                     /* get timer */
        movl    %ecx,CX(EXT(current_timer),%edx)        /* set initial timer */
Index: i386/i386at/conf.c
===================================================================
RCS file: /sources/hurd/gnumach/i386/i386at/Attic/conf.c,v
retrieving revision 1.4.2.15
diff -u -r1.4.2.15 conf.c
- --- i386/i386at/conf.c        1 Apr 2007 22:10:40 -0000       1.4.2.15
+++ i386/i386at/conf.c  5 Aug 2007 08:50:35 -0000
@@ -61,6 +61,11 @@
 extern int     kmsgopen(), kmsgclose(), kmsgread(), kmsggetstat();
 #define kmsgname               "kmsg"

+#ifdef MACH_ENTROPY +#define entropyname "entropy"
+extern int     entropyopen(), entropyclose(), entropyread(),  entropygetstat();
+#endif
+
 /*
  * List of devices - console must be at slot 0
  */
@@ -120,6 +125,12 @@
           nodev },
 #endif

+#ifdef MACH_ENTROPY
+       { entropyname,  entropyopen,    entropyclose,   entropyread,
+         nodev,        entropygetstat, nodev,          nomap,
+         nodev,        nulldev,        nulldev,        0,
+         nodev },
+#endif
 };
 int    dev_name_count = sizeof(dev_name_list)/sizeof(dev_name_list[0]);

Index: i386/i386at/kd.c
===================================================================
RCS file: /sources/hurd/gnumach/i386/i386at/Attic/kd.c,v
retrieving revision 1.5.2.13
diff -u -r1.5.2.13 kd.c
- --- i386/i386at/kd.c  7 May 2007 22:04:53 -0000       1.5.2.13
+++ i386/i386at/kd.c    5 Aug 2007 08:50:36 -0000
@@ -85,6 +85,11 @@
 #include <device/io_req.h>
 #include <device/buf.h>          /* for struct uio (!) */
 #include <vm/vm_kern.h>
+
+#if defined (MACH_KERNEL) && defined(MACH_ENTROPY) +#include <device/entropy.h>
+#endif /* MACH_KERNEL and MACH _ENTROPY */
+
 #include <i386/vm_param.h>
 #include <i386/machspl.h>
 #include <i386/pio.h>
@@ -811,6 +816,16 @@
                up = TRUE;
                scancode &= ~K_UP;
        }
+
+#ifdef MACH_KERNEL
+#ifdef MACH_ENTROPY + /* Sune Kirkeby's entropy patch (which was a port of the
+         * linux entropy drivers for GNU mach) placed the keyboard
+ * entropy source here. I looked at that for an idea of + * where how to do write this driver. */
+         entropy_putchar(scancode | (up ? 0200 : 0));
+#endif /* MACH_ENTROPY */
+#endif /* MACH_KERNEL */
        if (scancode < NUMKEYS) {
                /* Lookup in map, then process. */
                char_idx = kdstate2idx(kd_state, kd_extended);
Index: i386/i386at/kd_mouse.c
===================================================================
RCS file: /sources/hurd/gnumach/i386/i386at/Attic/kd_mouse.c,v
retrieving revision 1.3.2.8
diff -u -r1.3.2.8 kd_mouse.c
- --- i386/i386at/kd_mouse.c    13 Nov 2006 21:30:36 -0000      1.3.2.8
+++ i386/i386at/kd_mouse.c      5 Aug 2007 08:50:36 -0000
@@ -70,6 +70,9 @@
 #ifdef MACH_KERNEL
 #include <device/errno.h>
 #include <device/io_req.h>
+#ifdef MACH_ENTROPY
+#include <device/entropy.h>
+#endif /* MACH_ENTROPY */
 #else  /* MACH_KERNEL */
 #include <sys/file.h>
 #include <sys/errno.h>
@@ -677,6 +680,11 @@
        moved.mm_deltaX = (char)mousebuf[1] + (char)mousebuf[3];
        moved.mm_deltaY = (char)mousebuf[2] + (char)mousebuf[4];

+#ifdef MACH_ENTROPY
+       /* Kick some mouse data to the entropy driver */
+       entropy_putchar((buttonchanges + moved.mm_deltaX
+                       + moved.mm_deltaY));
+#endif
        if (moved.mm_deltaX != 0 || moved.mm_deltaY != 0)
                mouse_moved(moved);

Index: linux/configfrag.ac
===================================================================
RCS file: /sources/hurd/gnumach/linux/Attic/configfrag.ac,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 configfrag.ac
- --- linux/configfrag.ac       4 Aug 2007 18:50:19 -0000       1.1.2.6
+++ linux/configfrag.ac 5 Aug 2007 08:50:37 -0000
@@ -604,6 +604,15 @@
                   linux/dev/include/asm:linux/dev/include/asm-$systype])
 [else] AM_CONDITIONAL([CODE_linux], [false])
 [fi]
+
+AC_ARG_ENABLE([entropy],
+                 AS_HELP_STRING([--disable-entropy], [disable use of entropy 
device]))
+       [if [ x"$enable_entropy" != xno ]; then]
+         AC_DEFINE([MACH_ENTROPY], [], [enable use of entropy device])
+         AM_CONDITIONAL([enable_entropy], [true])
+ [else] + AM_CONDITIONAL([enable_entropy], [false]) +[fi]

 dnl Local Variables:
 dnl mode: autoconf
Index: linux/dev/glue/misc.c
===================================================================
RCS file: /sources/hurd/gnumach/linux/dev/glue/Attic/misc.c,v
retrieving revision 1.2
diff -u -r1.2 misc.c
- --- linux/dev/glue/misc.c     18 Sep 2001 21:14:19 -0000      1.2
+++ linux/dev/glue/misc.c       5 Aug 2007 08:50:37 -0000
@@ -67,6 +67,10 @@
 #include <linux/proc_fs.h>
 #include <linux/kernel_stat.h>

+#ifdef MACH_ENTROPY
+#include <device/entropy.h>
+#endif
+
 extern boolean_t vm_map_lookup_entry (register vm_map_t, register vm_offset_t,
                                      vm_map_entry_t *);
 extern int printf (const char *, ...);
@@ -224,6 +228,18 @@
 void
 add_blkdev_randomness (int major)
 {
+#ifdef MACH_ENTROPY
+  /* Linux provides a nice way to get random bits, so lets use it
+   * This generates a LOT of Ctrl-Cs for some reason. No idea whats
+   * going on here
+   *
+   * THe problem is that mach only has 1 block device, floppy (major 3
+ * corresponds to Ctrl C) so this is useless for entropic sources. If we + * ever get more block devices this should be uncommented for additional
+   * entropy. */
+ + /*entropy_putchar(major); */
+#endif
 }

 void
Index: linux/dev/glue/net.c
===================================================================
RCS file: /sources/hurd/gnumach/linux/dev/glue/Attic/net.c,v
retrieving revision 1.1.4.7
diff -u -r1.1.4.7 net.c
- --- linux/dev/glue/net.c      27 Mar 2007 22:47:11 -0000      1.1.4.7
+++ linux/dev/glue/net.c        5 Aug 2007 08:50:37 -0000
@@ -97,6 +97,11 @@
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>

+#ifdef MACH_KERNEL
+#ifdef MACH_ENTROPY
+#include <device/entropy.h>
+#endif // MACH_KERNEL
+#endif // MACH_ENTROPY
 extern int linux_intr_pri;

 /* One of these is associated with each instance of a device.  */
@@ -299,6 +304,11 @@
   ph->length = (skb->len - sizeof (struct ether_header)
                + sizeof (struct packet_header));

+#ifdef MACH_ENTROPY
+  // Grab the packet for entropy purposes
+  entropy_putdata(ph + 1, skb->len - sizeof(struct ether_header));
+#endif
+
   dev_kfree_skb (skb, FREE_READ);

   net_kmsg(kmsg)->sent = FALSE; /* Mark packet as received.  */
Index: linux/dev/include/linux/blk.h
===================================================================
RCS file: /sources/hurd/gnumach/linux/dev/include/linux/Attic/blk.h,v
retrieving revision 1.2
diff -u -r1.2 blk.h
- --- linux/dev/include/linux/blk.h     5 Apr 2001 06:39:21 -0000       1.2
+++ linux/dev/include/linux/blk.h       5 Aug 2007 08:50:37 -0000
@@ -90,7 +90,7 @@
 #endif /* CONFIG_BLK_DEV_MD */

 extern void set_device_ro(kdev_t dev,int flag);
- -void add_blkdev_randomness(int major);
+extern void add_blkdev_randomness(int major);

 extern int floppy_init(void);
 extern void rd_load(void);
@@ -136,7 +136,11 @@
 #define DEVICE_NR(device) (MINOR(device))
 #define DEVICE_ON(device)
 #define DEVICE_OFF(device)
+
+// HACK
+#ifndef MACH_ENTROPY
 #define DEVICE_NO_RANDOM
+#endif

 #elif (MAJOR_NR == FLOPPY_MAJOR)

- --- /dev/null 2007-04-05 09:18:41.000000000 -0400
+++ device/entropy.c    2007-08-04 03:49:54.000000000 -0400
@@ -0,0 +1,405 @@
+/*
+ * Mach Kernel - Entropy Generating Device
+ * Copyright (C) 2007 Free Software Foundation.
+ * + * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* System Header Files */
+#include <string.h>
+#include <kern/mach_clock.h>
+
+/* Local Header Files */
+#include "entropy.h"
+
+/* Variable Declarations */
+
+/* Entropy Buffer */
+static char entropy_buffer[ENTROPYBUFSIZE]; + +/* Lock to each function */ +decl_simple_lock_data(static,entropy_lock);
+
+/* Current read offset */
+static int entropy_read_offset = 0;
+
+/* Current write offset */
+static int entropy_write_offset = 0;
+
+/* If this device is already initalized */
+static int entropy_init_done = 0;
+
+/* I/O queue requests for blocking read */
+static queue_head_t entropy_read_queue; +
+/*
+ * The following is from linux's random.c, and is used
+ * under the GPL
+ *
+ * Look there for a full explination on what these numbers
+ * mean and how this works
+ */
+
+static struct poolinfo {
+       int poolwords;
+       int tap1, tap2, tap3, tap4, tap5;
+  } poolinfo_table [] = {
+    /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
+    { 128,     103,    76,     51,     25,     1 },
+    /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
+    { 32,      26,     20,     14,     7,      1 },
+    /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
+    {  2048,   1638,   1231,   819,    411,    1 },
+    /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */
+    { 1024,    817,    615,    412,    204,    1 },
+    /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */
+    { 1024,    819,    616,    410,    207,    2 },
+    /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */
+    { 512,     411,    308,    208,    104,    1 },
+    /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */
+    { 512,     409,    307,    206,    102,    2 },
+    /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */
+    { 512,     409,    309,    205,    103,    2 },
+    /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */
+    { 256,     205,    155,    101,    52,     1 },
+    /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */
+    { 128,     103,    78,     51,     27,     2 },
+    /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */
+    { 64,      52,     39,     26,     14,     1 },
+};
+
+/* Number of taps -1 */
+const int number_of_taps = 10;
+
+void +entropyinit() +{
+  /* Sanity check! */
+  if (entropy_init_done == 1) {
+       assert(entropy_init_done);
+  }
+
+  /* Setup locks */
+  queue_init(&entropy_read_queue);
+  simple_lock_init(&entropy_lock);
+  entropy_init_done = 1;
+}
+
+io_return_t +entropyopen(dev_t dev, int flag, io_req_t ior) +{
+  /* Check to see if we've initalized entropy */
+  if(entropy_init_done == 0) {
+         entropyinit();
+  }
+
+  /* Lock the function so we don't get a race condition */
+  simple_lock(&entropy_lock);
+
+  /* We're done, unlock, and return success */
+  simple_unlock(&entropy_lock);
+  return D_SUCCESS;
+}
+
+io_return_t +entropyclose(dev_t dev, int flag) +{
+  return D_SUCCESS;
+}
+
+/* Forward Declaration */
+static boolean_t entropy_read_done(io_req_t ior);
+
+io_return_t +entropyread(dev_t dev, io_req_t ior) +{
+  /* Possible Error Code */
+  int err;
+
+  /* Amount of entropy we want to read out*/
+  int amt;
+
+  /* Amount of entropy we have to read out */
+  int len;
+
+  /* Allocate memory*/
+  err = device_read_alloc(ior, ior->io_count);
+  if (err != KERN_SUCCESS) {
+    return err;
+  }
+
+  /* Lock the device */
+  simple_lock(&entropy_lock);
+  if (entropy_read_offset == entropy_write_offset) {
+    /* We got no entropy at the moment, queue it up */
+    if (ior->io_mode & D_NOWAIT) {
+     /* Got a non-blocking socket, so just tell it we would block */
+     simple_unlock(&entropy_lock);
+     return D_WOULD_BLOCK;
+    }
+
+    /* Pass the point to the read_done function which */
+    /* will notify if the IO read is REALLY done      */
+
+    ior->io_done = entropy_read_done;
+ + /* queue it up */
+    enqueue_tail(&entropy_read_queue, (queue_entry_t) ior);
+    simple_unlock(&entropy_lock);
+    return D_IO_QUEUED;
+  }
+
+ /* Determine how much we're reading out */ + len = entropy_write_offset - entropy_read_offset; + + if (len < 0 )
+   len += ENTROPYBUFSIZE;
+
+ amt = ior->io_count;
+ if (amt > len)
+   amt = len;
+ if (entropy_read_offset + amt <= ENTROPYBUFSIZE)
+   {
+     /* Copy available entropy into the device buffer */
+     memcpy (ior->io_data, entropy_buffer + entropy_read_offset, amt);
+   } else {
+ /* We need to wrap around so do it in two copies */ + int cnt;
+     cnt = ENTROPYBUFSIZE - entropy_read_offset;
+     memcpy(ior->io_data, entropy_buffer + entropy_read_offset, cnt);
+ memcpy(ior->io_data, entropy_buffer, amt - cnt); + }
+
+  /* Move the read offset */
+  entropy_read_offset += amt;
+  if (entropy_read_offset >= ENTROPYBUFSIZE) {
+    entropy_read_offset -= ENTROPYBUFSIZE;
+  }
+
+  /* Notify the caller how much data we were able to return */
+  ior->io_residual = ior->io_count - amt;
+
+  /* Unlock, and return success */
+  simple_unlock(&entropy_lock);
+  return D_SUCCESS;
+}
+
+/* This function called when the io read is complete */
+/* by device_read (I think)                         */
+static boolean_t +entropy_read_done(io_req_t ior) +{
+  /* Amount of entropy we want */
+  int amt;
+ + /* Amount of entropy we have */
+  int len;
+
+  /* Lock the device */
+  simple_lock(&entropy_lock);
+  if (entropy_read_offset == entropy_write_offset) {
+    /* The queue is empty so return false */
+    ior->io_done = entropy_read_done;
+    enqueue_tail(&entropy_read_queue, (queue_entry_t) ior);
+    simple_unlock (&entropy_lock);
+    return FALSE;
+  }
+
+  len = entropy_write_offset - entropy_read_offset;
+  if (len < 0)
+    len += ENTROPYBUFSIZE;
+
+  amt = ior->io_count;
+  if (amt > len)
+    amt = len;
+
+  if (entropy_read_offset + amt <= ENTROPYBUFSIZE) {
+    /* Copy the data from the buffer */
+    memcpy (ior->io_data, entropy_buffer + entropy_read_offset, amt);
+  } else {
+    /* The buffer needs to wrap around, so copy in two installments */
+    int cnt;
+
+    cnt = ENTROPYBUFSIZE - entropy_read_offset;
+    memcpy (ior->io_data, entropy_buffer + entropy_read_offset, cnt);
+    memcpy (ior->io_data + cnt, entropy_buffer, amt - cnt);
+  }
+
+ + entropy_read_offset += amt;
+  if (entropy_read_offset >= ENTROPYBUFSIZE) {
+    entropy_read_offset -= ENTROPYBUFSIZE;
+  }
+ + ior->io_residual = ior->io_count - amt;
+
+ /* Finish up, and unlock */ + simple_unlock(&entropy_lock);
+  ds_read_done (ior);
+
+  return TRUE;
+}
+
+io_return_t +entropygetstat(dev_t dev, int flavor, int *data, unsigned int *count) +{
+  switch (flavor) {
+     case DEV_GET_SIZE:
+       data[DEV_GET_SIZE_DEVICE_SIZE] = 0;
+       data[DEV_GET_SIZE_RECORD_SIZE] = 1;
+       *count = DEV_GET_SIZE_COUNT;
+       break;
+    default:
+       return D_INVALID_OPERATION;
+  }
+
+  return D_SUCCESS;
+}
+
+void
+entropy_putchar(int c) +{
+  /* We'll get data from a given source, and stick it in the buffer */
+  io_req_t ior;
+ + /* + * Twist table, and twisting and mixing code adopted from
+   * Linux's random.c
+   */
+  static unsigned long const twist_table [8] = {
+    0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
+    0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
+ /* Taps available for use */ + unsigned long int tap1, tap2, tap3, tap4, tap5; + + /* Random mask to twist by */
+  int wordmask;
+
+  /* Bit rotation of the taps */
+  static int input_rotate;
+ + /* Current Tap in use */
+  static short current_tap;
+
+  /* Input being twisted */
+  unsigned long word;
+
+  /* Its possible we MIGHT get here before the device is opened */
+  /* so just make sure we're initalized before doing anythign!  */
+
+  if(!entropy_init_done) {
+    entropyinit();
+  }
+
+  /* See if the buffer is full, if it is, bail out */
+  if (entropy_write_offset+1 == entropy_read_offset) {
+    return;
+  }
+
+ // Ok, we're going to TRY to lock since we don't want to block
+  // trying to get the lock
+  if (!simple_lock_try(&entropy_lock)) {
+   /* Didn't get it, bail out */
+    return;
+  }
+
+  /* Get the taps based on which array to use */
+  wordmask = poolinfo_table[current_tap].poolwords - 1;
+  tap1 = poolinfo_table[current_tap].tap1;
+  tap2 = poolinfo_table[current_tap].tap2;
+  tap3 = poolinfo_table[current_tap].tap3;
+  tap4 = poolinfo_table[current_tap].tap4;
+  tap5 = poolinfo_table[current_tap].tap5;
+
+  /* Mix the tap into the incoming entropy */
+  c++;
+  word = ((c << input_rotate) | (c >> (32 - input_rotate)));
+
+  /* XOR in the various taps, then add to the buffer */
+  word ^= entropy_buffer[(entropy_write_offset + tap1) & wordmask];
+  word ^= entropy_buffer[(entropy_write_offset + tap2) & wordmask];
+  word ^= entropy_buffer[(entropy_write_offset + tap3) & wordmask];
+  word ^= entropy_buffer[(entropy_write_offset + tap4) & wordmask];
+  word ^= entropy_buffer[(entropy_write_offset + tap5) & wordmask];
+ + /* Add the entropy to the buffer */ + entropy_buffer[entropy_write_offset] = (word >> 3) ^ twist_table[word & 7]; + + /* Advance the pointer for the next write */
+  entropy_write_offset += 1;
+
+  if (entropy_write_offset == ENTROPYBUFSIZE) {
+    entropy_write_offset = 0;
+  }
+
+  /* Deep magic (tells any read functiosn more entropy is available) */
+  while ((ior = (io_req_t) dequeue_head (&entropy_read_queue)) != NULL)
+    iodone (ior);
+
+  simple_unlock(&entropy_lock);
+}
+  /*
+   * This function is used to copy data from memory pointers directly
+ * into the bufffer + */ +void +entropy_putdata(void *data, int size) +{
+  /* Used to tell reads that we got entropy */
+  io_req_t ior;
+  int i;
+
+  /* See if we are initalized; if not, initalize the driver */
+  if (!entropy_init_done) {
+    entropyinit();
+  }
+ + /* See if the buffer is full, if it is, bail out */
+  if (entropy_write_offset+1 == entropy_read_offset) {
+    return;
+  }
+
+ /* Try to grab a lock on the device, otherwise bail */
+  if (!simple_lock_try(&entropy_lock)) {
+    return; /* Bailing out */
+  }
+
+    /* Is the data we're copying in bigger then our buffer? */
+  if (size >= ENTROPYBUFSIZE) {
+ + /* + * Set the offset to zero, and then copy set the size
+     * to the size of the buffer
+     */
+
+     size = ENTROPYBUFSIZE;
+  }
+
+  /* entropy_putchar is going to handle twisting,
+   * so simply feed into it bit by bit
+   */
+
+  for (i = 0; i == size; i++) {
+    entropy_putchar((int*)data+i);
+  }
+
+  /* Tell any reads that we have more entropy */
+  while ((ior = (io_req_t) dequeue_head (&entropy_read_queue)) != NULL)
+    iodone (ior);
+
+  simple_unlock(&entropy_lock);
+  return;
+}
+
- --- /dev/null 2007-04-05 09:18:41.000000000 -0400
+++ device/entropy.h    2007-07-13 15:43:17.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * Mach Kernel - Entropy Generating Device
+ * Copyright (C) 2007 Free Software Foundation.
+ * + * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Entropy device header */
+
+#ifndef _DEVICE_ENTROPY_H_
+#define _DEVICE_ENTROPY_H_
+
+#ifdef MACH_KERNEL
+
+#include <sys/types.h>
+#include <device/conf.h>
+#include <device/ds_routines.h>
+#include <device/io_req.h>
+#include <device/device_types.h>
+
+#define ENTROPYBUFSIZE sizeof(unsigned long)*128 +
+io_return_t entropyopen(dev_t dev, int flag, io_req_t ior);
+io_return_t entropyclose(dev_t dev, int flag);
+io_return_t entropyread(dev_t dev, io_req_t ior);
+io_return_t entropygetstat(dev_t dev, int flavor,
+                          int *data, unsigned int *count);
+void entropy_putchar(int c);
+void entropy_putdata(void *data, int size);
+
+#endif /* MACH_KERNEL */
+#endif /* ! _DEVICE_ENTROPY_H_ */
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU)

iD8DBQFGtVeaV/FBeJ6jsZQRAkomAJ9R/jGv9KAwuLvFXkYAaNQ9qUnoTwCfciFV
Rd2YDkV/etKKdz6OKmRbDOQ=
=7gUM
-----END PGP SIGNATURE-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]