cleanup and sync w/ latest Linux source.
authormickey <mickey@openbsd.org>
Fri, 6 Sep 1996 08:36:13 +0000 (08:36 +0000)
committermickey <mickey@openbsd.org>
Fri, 6 Sep 1996 08:36:13 +0000 (08:36 +0000)
remove keyboard randomness entry point.
make Free ppl happy, remove suspicious piece.
missed: SHA neede in libkern, why not to put aRC4 there too?

sys/dev/rnd.c
sys/dev/rndvar.h

index 2d94279..d55cd8c 100644 (file)
@@ -1,44 +1,13 @@
-/*     $OpenBSD: rnd.c,v 1.7 1996/08/29 09:26:36 deraadt Exp $ */
+/*     $OpenBSD: rnd.c,v 1.8 1996/09/06 08:36:13 mickey Exp $  */
 
 /*
- * Copyright (c) 1996 Michael Shalayeff.
- *
- * This software derived from one contributed by Theodore Ts'o.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by Theodore Ts'o.
- * 4. Neither the name of the University nor of the Laboratory may be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *
- *
  * random.c -- A strong random number generator
  *
- * Version 0.96, last modified 29-Dec-95
+ * Copyright (c) 1996 Michael Shalayeff.
+ *
+ * Version 1.00, last modified 26-May-96
  * 
- * Copyright Theodore Ts'o, 1994, 1995.  All rights reserved.
+ * Copyright Theodore Ts'o, 1994, 1995, 1996.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * and returns good random numbers, suitable for cryptographic use.
  * Besides the obvious cryptographic uses, these numbers are also good
  * for seeding TCP sequence numbers, and other places where it is
- * desireable to have numbers which are not only random, but hard to
+ * desirable to have numbers which are not only random, but hard to
  * predict by an attacker.
  *
  * Theory of operation
  * ===================
  * 
  * Computers are very predictable devices.  Hence it is extremely hard
- * to produce truely random numbers on a computer --- as opposed to
+ * to produce truly random numbers on a computer --- as opposed to
  * pseudo-random numbers, which can easily generated by using a
  * algorithm.  Unfortunately, it is very easy for attackers to guess
  * the sequence of pseudo-random number generators, and for some
  * random numbers; however, an attacker may (at least in theory) be
  * able to infer the future output of the generator from prior
  * outputs.  This requires successful cryptanalysis of MD5, which is
- * not believed to be feasible, but there is a remote possiblility.
+ * not believed to be feasible, but there is a remote possibility.
  * Nonetheless, these numbers should be useful for the vast majority
  * of purposes.
  * 
  * The current exported interfaces for gathering environmental noise
  * from the devices are:
  * 
- *     void add_keyboard_randomness(u_char scancode);
  *     void add_mouse_randomness(u_int32_t mouse_data);
- *     void add_interrupt_randomness(int irq);
- *     void add_blkdev_randomness(dev_t dev);
+ *     void add_net_randomness(int isr);
+ *     void add_tty_randomness(dev_t dev, int c);
+ *     void add_blkdev_randomness(int irq);
  * 
  * add_keyboard_randomness() uses the inter-keypress timing, as well as the
  * scancode as random inputs into the "entropy pool".
  * particular randomness source.  They do this by keeping track of the
  * first and second order deltas of the event timings.
  *
+ * Ensuring unpredictability at system startup
+ * ============================================
+ * 
+ * When any operating system starts up, it will go through a sequence
+ * of actions that are fairly predictable by an adversary, especially
+ * if the start-up does not involve interaction with a human operator.
+ * This reduces the actual number of bits of unpredictability in the
+ * entropy pool below the value in entropy_count.  In order to
+ * counteract this effect, it helps to carry information in the
+ * entropy pool across shut-downs and start-ups.  To do this, put the
+ * following lines an appropriate script which is run during the boot
+ * sequence: 
+ *
+ *     echo "Initializing random number generator..."
+ *     # Carry a random seed from start-up to start-up
+ *     # Load and then save 512 bytes, which is the size of the entropy pool
+ *     if [ -f /etc/random-seed ]; then
+ *             cat /etc/random-seed >/dev/urandom
+ *     fi
+ *     dd if=/dev/urandom of=/etc/random-seed count=1
+ *
+ * and the following lines in an appropriate script which is run as
+ * the system is shutdown:
+ * 
+ *     # Carry a random seed from shut-down to start-up
+ *     # Save 512 bytes, which is the size of the entropy pool
+ *     echo "Saving random seed..."
+ *     dd if=/dev/urandom of=/etc/random-seed count=1
+ * 
+ * For example, on many Linux systems, the appropriate scripts are
+ * usually /etc/rc.d/rc.local and /etc/rc.d/rc.0, respectively.
+ * 
+ * Effectively, these commands cause the contents of the entropy pool
+ * to be saved at shut-down time and reloaded into the entropy pool at
+ * start-up.  (The 'dd' in the addition to the bootup script is to
+ * make sure that /etc/random-seed is different for every start-up,
+ * even if the system crashes without executing rc.0.)  Even with
+ * complete knowledge of the start-up activities, predicting the state
+ * of the entropy pool requires knowledge of the previous history of
+ * the system.
+ *
+ * Configuring the /dev/random driver under Linux
+ * ==============================================
+ *
+ * The /dev/random driver under Linux uses minor numbers 8 and 9 of
+ * the /dev/mem major number (#1).  So if your system does not have
+ * /dev/random and /dev/urandom created already, they can be created
+ * by using the commands:
+ *
+ *     mknod /dev/random c 1 8
+ *     mknod /dev/urandom c 1 9
+ * 
  * Acknowledgements:
  * =================
  *
  * entropy pool, taken from PGP 3.0 (under development).  It has since
  * been modified by myself to provide better mixing in the case where
  * the input values to add_entropy_word() are mostly small numbers.
+ * Dale Worley has also contributed many useful ideas and suggestions
+ * to improve this driver.
  * 
  * Any flaws in the design are solely my responsibility, and should
  * not be attributed to the Phil, Colin, or any of authors of PGP.
  * 
+ * The code for MD5 transform was taken from Colin Plumb's
+ * implementation, which has been placed in the public domain.  The
+ * MD5 cryptographic checksum was devised by Ronald Rivest, and is
+ * documented in RFC 1321, "The MD5 Message Digest Algorithm".
+ * 
+ * Further background information on this topic may be obtained from
+ * RFC 1750, "Randomness Recommendations for Security", by Donald
+ * Eastlake, Steve Crocker, and Jeff Schiller.
  */
 
 #include "random.h"
@@ -226,6 +257,17 @@ int        rnd_debug = 0x0000;
 #define        RD_WAIT         0x0100  /* sleep/wakeup for good data */
 #endif
 
+#ifdef RND_USE_SHA
+#define        HASH_BUFFER_SIZE        5
+#define        HASH_TRANSFORM  SHATransform
+#else  /* RND_USE_MD5 */
+#ifndef        RND_USE_MD5
+#define        RND_USE_MD5
+#endif
+#define        HASH_BUFFER_SIZE        4
+#define        HASH_TRANSFORM  MD5Transform
+#endif
+
 /*
  * The pool is stirred with a primitive polynomial of degree 128
  * over GF(2), namely x^128 + x^99 + x^59 + x^31 + x^9 + x^7 + 1.
@@ -274,9 +316,6 @@ struct arc4_stream {
 #define        ENT_BLKDEV      0x200
 #define ENT_TTY                0x300
 
-/* device functions prototypes: XXX move em to dev_conf.h */
-cdev_decl(random);
-
 static struct random_bucket random_state;
 struct arc4_stream arc4random_state;
 static u_int32_t random_pool[POOLWORDS];
@@ -322,7 +361,7 @@ arc4_getbyte (struct arc4_stream *as)
        return (as->s[(si + sj) & 0xff]);
 }
 
-u_long
+u_int32_t
 arc4random (void)
 {
   return ((arc4_getbyte (&arc4random_state) << 24)
@@ -330,7 +369,7 @@ arc4random (void)
          | (arc4_getbyte (&arc4random_state) << 8)
          | arc4_getbyte (&arc4random_state));
 }
-       
+
 void
 randomattach(num)
        int     num;
@@ -443,7 +482,7 @@ add_timer_randomness(r, state, num)
 {
        int     delta, delta2;
        u_int   nbits;
-       u_int32_t       time;
+       u_long  time;
 
        {
                struct timeval  tv;
@@ -491,17 +530,6 @@ add_timer_randomness(r, state, num)
        }
 }
 
-void
-add_keyboard_randomness(scancode)
-       u_char  scancode;
-{
-#ifdef DEBUG
-       if (rnd_debug & RD_INPUT)
-               printf("rnd: adding %02x from kbd\n", scancode);
-#endif
-       add_timer_randomness(&random_state, &keyboard_timer_state, scancode);
-}
-
 void
 add_mouse_randomness(mouse_data)
        u_int32_t       mouse_data;
@@ -559,16 +587,13 @@ extract_entropy(r, buf, nbytes)
        int     nbytes;
 {
        int     ret, i;
-       u_int32_t tmp[4];
+       u_int32_t tmp[HASH_BUFFER_SIZE];
        
        add_timer_randomness(r, &extract_timer_state, nbytes);
        
        /* Redundant, but just in case... */
        if (r->entropy_count > POOLBITS) 
                r->entropy_count = POOLBITS;
-       /* Why is this here?  Left in from Ted Ts'o.  Perhaps to limit time. */
-       if (nbytes > 32768)
-               nbytes = 32768;
 
        ret = nbytes;
        if (r->entropy_count / 8 >= nbytes)
@@ -578,26 +603,46 @@ extract_entropy(r, buf, nbytes)
 
        while (nbytes) {
                /* Hash the pool to get the output */
+#ifdef RND_USE_MD5
                MD5Init(tmp);
+#endif
                for (i = 0; i < POOLWORDS; i += 16)
-                       MD5Transform(tmp, r->pool+i);
+                       HASH_TRANSFORM(tmp, r->pool+i);
                /* Modify pool so next hash will produce different results */
                add_entropy_word(r, tmp[0]);
                add_entropy_word(r, tmp[1]);
                add_entropy_word(r, tmp[2]);
                add_entropy_word(r, tmp[3]);
+#ifdef RND_USE_SHA
+               add_entropy_word(r, tmp[5]);
+#endif
                /*
                 * Run the MD5 Transform one more time, since we want
                 * to add at least minimal obscuring of the inputs to
                 * add_entropy_word().  --- TYT
                 */
-               MD5Transform(tmp, r->pool);
-               
+               HASH_TRANSFORM(tmp, r->pool);
+
+               /*
+                * In case the hash function has some recognizable
+                * output pattern, we fold it in half.
+                */
+               {
+                       register u_int8_t       *cp, *dp;
+                       cp = (u_int8_t *) tmp;
+                       dp = cp + (HASH_BUFFER_SIZE*sizeof(tmp[0])) - 1;
+                       for (i=0; i < HASH_BUFFER_SIZE*sizeof(tmp[0])/2; i++) {
+                               *cp ^= *dp;
+                               cp++;  dp--;
+                       }
+               }
+
                /* Copy data to destination buffer */
-               i = MIN(nbytes, 16);
+               i = MIN(nbytes, HASH_BUFFER_SIZE*sizeof(tmp[0]));
                bcopy((caddr_t)tmp, buf, i);
                nbytes -= i;
                buf += i;
+               add_timer_randomness(r, &extract_timer_state, nbytes);
        }
 
        /* Wipe data from memory */
@@ -638,6 +683,7 @@ randomread(dev, uio, ioflag)
                s = splhigh();
                switch(minor(dev)) {
                case RND_RND:
+                       ret = EIO;      /* no chip -- error */
                        break;
                case RND_SRND:
                        if (random_state.entropy_count < 8) {
index 34297e6..013ffe3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rndvar.h,v 1.3 1996/08/11 07:31:32 dm Exp $   */
+/*     $OpenBSD: rndvar.h,v 1.4 1996/09/06 08:36:14 mickey Exp $       */
 
 /*
  * Copyright (c) 1996 Michael Shalayeff.
@@ -54,7 +54,7 @@ extern void add_blkdev_randomness __P((dev_t));
 extern void add_tty_randomness __P((dev_t, int));
 
 extern void get_random_bytes __P((void *, size_t));
-extern unsigned long arc4random __P((void));
+extern u_int32_t arc4random __P((void));
 
 #endif /* _KERNEL */