bug-hurd
[Top][All Lists]
Advanced

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

Corrected Entropy Patch


From: Michael Casadevall
Subject: Corrected Entropy Patch
Date: Mon, 6 Aug 2007 13:38:31 -0400

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

I've fixed the patch correcting the GCS violations, and I'm sending it with a different mailer which shouldn't mutate the patch:

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 6 Aug 2007 15:05:19 -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       6 Aug 2007 15:05:19 -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_entropy" != 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      6 Aug 2007 15:05:19 -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       6 Aug 2007 15:05:19 -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_KERNEL */
+#endif /* MACH_ENTROPY */
                return ((*romgetc)(1));
        return (0);
}
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  6 Aug 2007 15:05:20 -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    6 Aug 2007 15:05:22 -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      6 Aug 2007 15:05:23 -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 6 Aug 2007 15:05:24 -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       6 Aug 2007 15:05:24 -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        6 Aug 2007 15:05:25 -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       6 Aug 2007 15:05:26 -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,10 @@
#define DEVICE_NR(device) (MINOR(device))
#define DEVICE_ON(device)
#define DEVICE_OFF(device)
+
+#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-05 01:33:45.000000000 -0400
@@ -0,0 +1,407 @@
+/*
+ * 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.910000000 -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 (Darwin)

iD8DBQFGt1yYV/FBeJ6jsZQRAkInAJ0VxHPLEJjXS92iwoyHXIvnTPy6AQCdHSRc
ERKwpa5vHU7reoeFTky4SWQ=
=6iZe
-----END PGP SIGNATURE-----




reply via email to

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