bug-hurd
[Top][All Lists]
Advanced

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

Yet another updated entropy patch


From: Michael Casadevall
Subject: Yet another updated entropy patch
Date: Fri, 13 Jul 2007 01:04:01 -0400

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

This includes a little more sanity checking, and it also fixes the ring code bug which antrik explained to me in detail. It also has the patch in the proper format:

? INSTALL
? Makefile.in
? aclocal.m4
? autom4te.cache
? build
? build-aux
? config.h.in
? configure
? entropy_driver_with_ipc.patch
? entropy_patch.diff
? device/.entropy.c.swp
? 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
Index: Makefrag.am
===================================================================
RCS file: /sources/hurd/gnumach/Attic/Makefrag.am,v
retrieving revision 1.1.2.12
diff -c -r1.1.2.12 Makefrag.am
*** Makefrag.am 2 Jun 2007 13:23:21 -0000       1.1.2.12
- --- Makefrag.am       13 Jul 2007 05:02:48 -0000
***************
*** 292,297 ****
- --- 292,305 ----
        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.6
diff -c -r1.1.2.6 configfrag.ac
*** configfrag.ac       19 Feb 2007 20:09:16 -0000      1.1.2.6
- --- configfrag.ac     13 Jul 2007 05:02:48 -0000
***************
*** 124,130 ****
  [else]
    AM_CONDITIONAL([enable_kmsg], [false])
  [fi]
! 
  #
  # Set up `SYSTYPE/SYSTYPE' and `SYSTYPE/include/mach/SYSTYPE' links.
  #
- --- 124,141 ----
  [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.
  #
***************
*** 134,140 ****
# <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:
- --- 145,151 ----
# <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 -c -r1.1.1.1 blkio.c
*** device/blkio.c      25 Feb 1997 21:28:13 -0000      1.1.1.1
- --- device/blkio.c    13 Jul 2007 05:02:48 -0000
***************
*** 36,42 ****
  #include <device/io_req.h>
  #include <device/ds_routines.h>

!

  io_return_t block_io(strat, max_count, ior)
        void                    (*strat)();
- --- 36,44 ----
  #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,154 ****
- --- 151,160 ----
        do {
            prev = next;
            next = prev->io_next;
+ #ifdef MACH_ENTROPY
+           // Lets grab the cyclinder 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 -c -r1.2.4.6 cons.c
*** device/cons.c       13 Nov 2006 21:30:36 -0000      1.2.4.6
- --- device/cons.c     13 Jul 2007 05:02:48 -0000
***************
*** 44,49 ****
- --- 44,53 ----
  #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,237 ****
  cngetc()
  {
        if (cn_tab)
!               return ((*cn_tab->cn_getc)(cn_tab->cn_dev, 1));
        if (romgetc)
                return ((*romgetc)(1));
        return (0);
  }
- --- 234,251 ----
  cngetc()
  {
        if (cn_tab)
! #ifdef MACH_KERNEL
! #ifdef MACH_ENTROPY
!               entropy_putchar(cn_tab->cn_dev);
! #endif // MACH_ENTROPY
! #endif // MACH_KERNEL
!               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/i386at/conf.c
===================================================================
RCS file: /sources/hurd/gnumach/i386/i386at/Attic/conf.c,v
retrieving revision 1.4.2.15
diff -c -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        13 Jul 2007 05:02:49 -0000
***************
*** 61,66 ****
- --- 61,71 ----
  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,125 ****
- --- 125,136 ----
            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 -c -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  13 Jul 2007 05:02:49 -0000
***************
*** 85,90 ****
- --- 85,97 ----
  #include <device/io_req.h>
  #include <device/buf.h>         /* for struct uio (!) */
  #include <vm/vm_kern.h>
+
+ #ifdef MACH_KERNEL
+ #ifdef MACH_ENTROPY
+ #include <device/entropy.h>
+ #endif /* MACH_KERNEL */
+ #endif /* MACH_ENTROPY */
+
  #include <i386/vm_param.h>
  #include <i386/machspl.h>
  #include <i386/pio.h>
***************
*** 811,816 ****
- --- 818,835 ----
                up = TRUE;
                scancode &= ~K_UP;
        }
+
+ #ifdef MACH_KERNEL
+ #ifdef MACH_ENTROPY
+       /***
+        * Kirkeby put the get entropy function here, so will I
+        * the OR causes it to only get a some of the keypresses
+        * making this even more random when it fires (he got this
+        * from Linux originally
+        ***/
+       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 -c -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    13 Jul 2007 05:02:49 -0000
***************
*** 70,75 ****
- --- 70,78 ----
  #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,682 ****
- --- 680,690 ----
        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) | 0122);
+ #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.5
diff -c -r1.1.2.5 configfrag.ac
*** linux/configfrag.ac 2 May 2007 19:47:11 -0000       1.1.2.5
- --- linux/configfrag.ac       13 Jul 2007 05:02:51 -0000
***************
*** 601,606 ****
- --- 601,615 ----
                   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 -c -r1.2 misc.c
*** linux/dev/glue/misc.c       18 Sep 2001 21:14:19 -0000      1.2
- --- linux/dev/glue/misc.c     13 Jul 2007 05:02:51 -0000
***************
*** 67,72 ****
- --- 67,76 ----
  #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,229 ****
- --- 228,243 ----
  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- Ctrl-C) + // so this is useless for entropic sources. If we ever get more block devices
+   // Uncomment this to get it 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 -c -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      13 Jul 2007 05:02:51 -0000
***************
*** 97,102 ****
- --- 97,107 ----
  #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,304 ****
- --- 304,314 ----
    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 -c -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     13 Jul 2007 05:02:51 -0000
***************
*** 90,96 ****
  #endif /* CONFIG_BLK_DEV_MD */

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

  extern int floppy_init(void);
  extern void rd_load(void);
- --- 90,96 ----
  #endif /* CONFIG_BLK_DEV_MD */

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

  extern int floppy_init(void);
  extern void rd_load(void);
***************
*** 136,142 ****
- --- 136,146 ----
  #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   Thu Apr  5 09:18:41 2007
- --- device/entropy.c  Thu Jul 12 19:39:11 2007
***************
*** 0 ****
- --- 1,313 ----
+ /*
+  * 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.
+  */
+
+ #include "entropy.h"
+ #include <string.h>
+ #include <kern/mach_clock.h>
+
+ /* Variable Declrations */
+ static char entropy_buffer[ENTROPYBUFSIZE]; /* Entropy Buffer */
+ decl_simple_lock_data(static,entropy_lock); /* Lock to each function */
+ static int entropy_read_offset; /* Current read offset */
+ static int entropy_write_offset; /* Current write offset */
+ static int entropy_init_done = 0; /* If this device is already initalized */
+ static int entropy_in_use; /* Mark that this device is in use */
+ static queue_head_t entropy_read_queue; /* I/O queue requests for blocking read */
+
+ void entropyinit() {
+   // Sanity check!
+   if (entropy_init_done == 1) {
+     // should never happen
+     return;
+   }
+
+   /* Initalize all variables to zero, and
+    * setup our queues and locks */
+   entropy_read_offset = 0;
+   entropy_write_offset = 0;
+   entropy_in_use = 0;
+   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);
+
+   entropy_in_use = 1;
+
+   /* We're done, unlock, and return success */
+   simple_unlock(&entropy_lock);
+   return D_SUCCESS;
+ }
+
+ io_return_t entropyclose(dev_t dev, int flag) {
+   /* Lock so we don't get a race condition or something worse */
+   simple_lock(&entropy_lock);
+   entropy_in_use = 0;
+
+   simple_unlock(&entropy_lock);
+   return D_SUCCESS;
+ }
+
+ /* Needed to make the compiler happy */
+ static boolean_t entropy_read_done(io_req_t ior);
+
+ io_return_t entropyread(dev_t dev, io_req_t ior) {
+   int err, amt, 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  */
+  /* amt is how much we want to copy out   */
+  /* len is how much we can copy 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) {
+   int amt, 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 fromt 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;
+   /* 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;
+   }
+
+
+    // Add the entropy to the buffer
+   // And move the write offset
+   entropy_buffer[entropy_write_offset] = c;
+
+   // Advance the pointer for the next write
+   entropy_write_offset += 1;
+
+   if (entropy_write_offset == ENTROPYBUFSIZE) {
+     entropy_write_offset = 0;
+   }
+
+   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);
+ }
+
+ void entropy_putdata(void *data, int size) {
+   // This function is used to copy data from memory pointers directly
+   // into the bufffer
+   io_req_t ior; // Used to tell reads that we got entropy
+
+   // 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
+   }
+
+   // Lets advance the pointer on
+   entropy_write_offset++;
+
+   // See if the buffer needs to wrap around
+   if (entropy_write_offset == ENTROPYBUFSIZE) {
+     entropy_write_offset = 0;
+   }
+
+   // 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;
+   }
+
+   // Do we need to wrap around?
+   if (size + entropy_write_offset > ENTROPYBUFSIZE) {
+     // Yup, we'll do the copy in two stops.
+     int cnt;
+     cnt = ENTROPYBUFSIZE - entropy_write_offset;
+     memcpy(entropy_buffer + entropy_write_offset, data, cnt);
+     memcpy(entropy_buffer, data, size - cnt);
+   } else {
+     // Nope, just copy
+     memcpy(entropy_buffer + entropy_write_offset, data, size);
+   }
+
+   entropy_write_offset += size;
+   if (entropy_write_offset >= ENTROPYBUFSIZE) {
+     entropy_write_offset -= ENTROPYBUFSIZE;
+   }
+
+   if (entropy_write_offset == ENTROPYBUFSIZE) {
+    entropy_write_offset = 0;
+   }
+   // 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   Thu Apr  5 09:18:41 2007
- --- device/entropy.h  Sat Jul  7 09:32:41 2007
***************
*** 0 ****
- --- 1,49 ----
+ /*
+  * 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
+
+ /* typedef struct {
+   unsigned long ticks;
+   int data;
+ } entropy_data; */
+
+ 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)

iD8DBQFGlwfBV/FBeJ6jsZQRAiScAJ9nR7WPA4FEoRCdVXCTCzjFMCB4UwCfUd2t
xEW78tBNObkPQ0w6iiaHh0g=
=Z4Cr
-----END PGP SIGNATURE-----




reply via email to

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