root/drivers/char/random.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. flush_random
  2. rand_initialize
  3. MD5Transform
  4. mix_bucket
  5. add_entropy_byte
  6. add_entropy
  7. add_timer_randomness
  8. add_keyboard_randomness
  9. add_interrupt_randomness
  10. extract_entropy
  11. get_random_bytes
  12. read_random
  13. read_random_unlimited

   1 /*
   2  * random.c -- A strong random number generator
   3  *
   4  * Version 0.92, last modified 21-Sep-95
   5  * 
   6  * Copyright Theodore Ts'o, 1994, 1995.  All rights reserved.
   7  *
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions
  10  * are met:
  11  * 1. Redistributions of source code must retain the above copyright
  12  *    notice, and the entire permission notice in its entirety,
  13  *    including the disclaimer of warranties.
  14  * 2. Redistributions in binary form must reproduce the above copyright
  15  *    notice, this list of conditions and the following disclaimer in the
  16  *    documentation and/or other materials provided with the distribution.
  17  * 3. The name of the author may not be used to endorse or promote
  18  *    products derived from this software without specific prior
  19  *    written permission.
  20  * 
  21  * ALTERNATIVELY, this product may be distributed under the terms of
  22  * the GNU Public License, in which case the provisions of the GPL are
  23  * required INSTEAD OF the above restrictions.  (This clause is
  24  * necessary due to a potential bad interaction between the GPL and
  25  * the restrictions contained in a BSD-style copyright.)
  26  * 
  27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  28  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  29  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  31  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  32  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  33  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  35  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  37  * OF THE POSSIBILITY OF SUCH DAMAGE.
  38  */
  39 
  40 /*
  41  * (now, with legal B.S. out of the way.....) 
  42  * 
  43  * This routine gathers environmental noise from device drivers, etc.,
  44  * and returns good random numbers, suitable for cryptographic use.
  45  * Besides the obvious cryptographic uses, these numbers are also good
  46  * for seeding TCP sequence numbers, and other places where it is
  47  * desireable to have numbers which are not only random, but hard to
  48  * predict by an attacker.
  49  *
  50  * Theory of operation
  51  * ===================
  52  * 
  53  * Computers are very predictable devices.  Hence it is extremely hard
  54  * to produce truely random numbers on a computer --- as opposed to
  55  * pseudo-random numbers, which can easily generated by using a
  56  * algorithm.  Unfortunately, it is very easy for attackers to guess
  57  * the sequence of pseudo-random number generators, and for some
  58  * applications this is not acceptable.  So instead, we must try to
  59  * gather "environmental noise" from the computer's environment, which
  60  * must be hard for outside attackers to observe, and use that to
  61  * generate random numbers.  In a Unix environment, this is best done
  62  * from inside the kernel.
  63  * 
  64  * Sources of randomness from the environment include inter-keyboard
  65  * timings, inter-interrupt timings from some interrupts, and other
  66  * events which are both (a) non-deterministic and (b) hard for an
  67  * outside observer to measure.  Randomness from these sources are
  68  * added to an "entropy pool", which is periodically mixed using the
  69  * MD5 compression function in CBC mode.  As random bytes are mixed
  70  * into the entropy pool, the routines keep an *estimate* of how many
  71  * bits of randomness have been stored into the random number
  72  * generator's internal state.
  73  * 
  74  * When random bytes are desired, they are obtained by taking the MD5
  75  * hash of a counter plus the contents of the "entropy pool".  The
  76  * reason for the MD5 hash is so that we can avoid exposing the
  77  * internal state of random number generator.  Although the MD5 hash
  78  * does protect the pool, as each random byte which is generated from
  79  * the pool reveals some information which was derived from the
  80  * internal state, and thus increasing the amount of information an
  81  * outside attacker has available to try to make some guesses about
  82  * the random number generator's internal state.  For this reason,
  83  * the routine decreases its internal estimate of how many bits of
  84  * "true randomness" are contained in the entropy pool as it outputs
  85  * random numbers.
  86  * 
  87  * If this estimate goes to zero, the routine can still generate random
  88  * numbers; however it may now be possible for an attacker to analyze
  89  * the output of the random number generator, and the MD5 algorithm,
  90  * and thus have some success in guessing the output of the routine.
  91  * Phil Karn (who devised this mechanism of using MD5 plus a counter
  92  * to extract random numbers from an entropy pool) calls this
  93  * "practical randomness", since in the worse case this is equivalent
  94  * to hashing MD5 with a counter and an undisclosed secret.  If MD5 is
  95  * a strong cryptographic hash, this should be fairly resistant to attack.
  96  * 
  97  * Exported interfaces ---- output
  98  * ===============================
  99  * 
 100  * There are three exported interfaces; the first is one designed to
 101  * be used from within the kernel:
 102  *
 103  *      void get_random_bytes(void *buf, int nbytes);
 104  *
 105  * This interface will return the requested number of random bytes,
 106  * and place it in the requested buffer.
 107  * 
 108  * The two other interfaces are two character devices /dev/random and
 109  * /dev/urandom.  /dev/random is suitable for use when very high
 110  * quality randomness is desired (for example, for key generation.),
 111  * as it will only return a maximum of the number of bits of
 112  * randomness (as estimated by the random number generator) contained
 113  * in the entropy pool.
 114  * 
 115  * The /dev/urandom device does not have this limit, and will return
 116  * as many bytes as are requested.  As more and more random bytes are
 117  * requested without giving time for the entropy pool to recharge,
 118  * this will result in lower quality random numbers.  For many
 119  * applications, however, this is acceptable.
 120  *
 121  * Exported interfaces ---- input
 122  * ==============================
 123  *
 124  * The two current exported interfaces for gathering environmental
 125  * noise from the devices are:
 126  * 
 127  *      void add_keyboard_randomness(unsigned char scancode);
 128  *      void add_interrupt_randomness(int irq);
 129  * 
 130  * The first function uses the inter-keypress timing, as well as the
 131  * scancode as random inputs into the "entropy pool".
 132  *
 133  * The second function uses the inter-interrupt timing as random
 134  * inputs to the entropy pool.  Note that not all interrupts are good
 135  * sources of randomness!  For example, the timer interrupts is not a
 136  * good choice, because the periodicity of the interrupts is to
 137  * regular, and hence predictable to an attacker.  Disk interrupts are
 138  * a better measure, since the timing of the disk interrupts are more
 139  * unpredictable.  The routines try to estimate how many bits of
 140  * randomness a particular interrupt channel offers, by keeping track
 141  * of the first and second order deltas in the interrupt timings.
 142  *
 143  * Acknowledgements:
 144  * =================
 145  * 
 146  * Ideas for constructing this random number generator were derived
 147  * from the Pretty Good Privacy's random number generator, and from
 148  * private discussions with Phil Karn.  This design has been further
 149  * modified by myself, so any flaws are solely my responsibility, and
 150  * should not be attributed to the authors of PGP or to Phil.
 151  * 
 152  * The code for MD5 transform was taken from Colin Plumb's
 153  * implementation, which has been placed in the public domain.  The
 154  * MD5 cryptographic checksum was devised by Ronald Rivest, and is
 155  * documented in RFC 1321, "The MD5 Message Digest Algorithm".
 156  * 
 157  * Further background information on this topic may be obtained from
 158  * RFC 1750, "Randomness Recommendations for Security", by Donald
 159  * Eastlake, Steve Crocker, and Jeff Schiller.
 160  */
 161 
 162 #ifdef linux
 163 #include <linux/sched.h>
 164 #include <linux/kernel.h>
 165 #include <linux/major.h>
 166 #include <linux/string.h>
 167 #include <linux/random.h>
 168 
 169 #include <asm/segment.h>
 170 #include <asm/irq.h>
 171 #include <asm/io.h>
 172 #endif
 173 
 174 #ifdef CONFIG_RANDOM
 175 
 176 #define RANDPOOL 512
 177 
 178 struct random_bucket {
 179         int add_ptr;
 180         int entropy_count;
 181         int length;
 182         int bit_length;
 183         int delay_mix:1;
 184         __u8 *pool;
 185 };
 186 
 187 struct timer_rand_state {
 188         unsigned long   last_time;
 189         int             last_delta;
 190         int             nbits;
 191 };
 192 
 193 static struct random_bucket random_state;
 194 static __u32 rand_pool_key[16];
 195 static __u8 random_pool[RANDPOOL];
 196 static __u32 random_counter[16];
 197 static struct timer_rand_state keyboard_timer_state;
 198 static struct timer_rand_state irq_timer_state[NR_IRQS];
 199 
 200 #ifndef MIN
 201 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 202 #endif
 203         
 204 static void flush_random(struct random_bucket *random_state)
     /* [previous][next][first][last][top][bottom][index][help] */
 205 {
 206         random_state->add_ptr = 0;
 207         random_state->bit_length = random_state->length * 8;
 208         random_state->entropy_count = 0;
 209         random_state->delay_mix = 0;
 210 }
 211 
 212 void rand_initialize(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 213 {
 214         random_state.length = RANDPOOL;
 215         random_state.pool = random_pool;
 216         flush_random(&random_state);
 217 }
 218 
 219 /*
 220  * MD5 transform algorithm, taken from code written by Colin Plumb,
 221  * and put into the public domain
 222  */
 223 
 224 /* The four core functions - F1 is optimized somewhat */
 225 
 226 /* #define F1(x, y, z) (x & y | ~x & z) */
 227 #define F1(x, y, z) (z ^ (x & (y ^ z)))
 228 #define F2(x, y, z) F1(z, x, y)
 229 #define F3(x, y, z) (x ^ y ^ z)
 230 #define F4(x, y, z) (y ^ (x | ~z))
 231 
 232 /* This is the central step in the MD5 algorithm. */
 233 #define MD5STEP(f, w, x, y, z, data, s) \
 234         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
 235 
 236 /*
 237  * The core of the MD5 algorithm, this alters an existing MD5 hash to
 238  * reflect the addition of 16 longwords of new data.  MD5Update blocks
 239  * the data and converts bytes into longwords for this routine.
 240  */
 241 static void MD5Transform(__u32 buf[4],
     /* [previous][next][first][last][top][bottom][index][help] */
 242                          __u32 const in[16])
 243 {
 244         __u32 a, b, c, d;
 245 
 246         a = buf[0];
 247         b = buf[1];
 248         c = buf[2];
 249         d = buf[3];
 250 
 251         MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
 252         MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
 253         MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
 254         MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
 255         MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
 256         MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
 257         MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
 258         MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
 259         MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
 260         MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
 261         MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
 262         MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
 263         MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
 264         MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
 265         MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
 266         MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
 267 
 268         MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
 269         MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
 270         MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
 271         MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
 272         MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
 273         MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
 274         MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
 275         MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
 276         MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
 277         MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
 278         MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
 279         MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
 280         MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
 281         MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
 282         MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
 283         MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
 284 
 285         MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
 286         MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
 287         MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
 288         MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
 289         MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
 290         MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
 291         MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
 292         MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
 293         MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
 294         MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
 295         MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
 296         MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
 297         MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
 298         MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
 299         MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
 300         MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
 301 
 302         MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
 303         MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
 304         MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
 305         MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
 306         MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
 307         MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
 308         MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
 309         MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
 310         MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
 311         MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
 312         MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
 313         MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
 314         MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
 315         MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
 316         MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
 317         MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
 318 
 319         buf[0] += a;
 320         buf[1] += b;
 321         buf[2] += c;
 322         buf[3] += d;
 323 }
 324 
 325 #undef F1
 326 #undef F2
 327 #undef F3
 328 #undef F4
 329 #undef MD5STEP
 330 
 331 /*
 332  * The function signature should be take a struct random_bucket * as
 333  * input, but this makes tqueue unhappy.
 334  */
 335 static void mix_bucket(void *v)
     /* [previous][next][first][last][top][bottom][index][help] */
 336 {
 337         struct random_bucket *r = (struct random_bucket *) v;
 338         int     i, num_passes;
 339         __u32 *p;
 340         __u32 iv[4];
 341 
 342         r->delay_mix = 0;
 343         
 344         /* Start IV from last block of the random pool */
 345         memcpy(iv, r->pool + r->length - sizeof(iv), sizeof(iv));
 346 
 347         num_passes = r->length / 16;
 348         for (i = 0, p = (__u32 *) r->pool; i < num_passes; i++) {
 349                 MD5Transform(iv, rand_pool_key);
 350                 iv[0] = (*p++ ^= iv[0]);
 351                 iv[1] = (*p++ ^= iv[1]);
 352                 iv[2] = (*p++ ^= iv[2]);
 353                 iv[3] = (*p++ ^= iv[3]);
 354         }
 355         memcpy(rand_pool_key, r->pool, sizeof(rand_pool_key));
 356         
 357         /* Wipe iv from memory */
 358         memset(iv, 0, sizeof(iv));
 359 
 360         r->add_ptr = 0;
 361 }
 362 
 363 /*
 364  * This function adds a byte into the entropy "pool".  It does not
 365  * update the entropy estimate.  The caller must do this if appropriate.
 366  */
 367 static inline void add_entropy_byte(struct random_bucket *r,
     /* [previous][next][first][last][top][bottom][index][help] */
 368                                     const __u8 ch,
 369                                     int delay)
 370 {
 371         if (!delay && r->delay_mix)
 372                 mix_bucket(r);
 373         r->pool[r->add_ptr++] ^= ch;
 374         if (r->add_ptr >= r->length) {
 375                 if (delay) {
 376                         r->delay_mix = 1;
 377                         r->add_ptr = 0;
 378                 } else
 379                         mix_bucket(r);
 380         }
 381 }
 382 
 383 /*
 384  * This function adds some number of bytes into the entropy pool and
 385  * updates the entropy count as appropriate.
 386  */
 387 void add_entropy(struct random_bucket *r, const __u8 *ptr,
     /* [previous][next][first][last][top][bottom][index][help] */
 388                  int length, int entropy_level, int delay)
 389 {
 390         while (length-- > 0)
 391                 add_entropy_byte(r, *ptr++, delay);
 392                 
 393         r->entropy_count += entropy_level;
 394         if (r->entropy_count > r->length*8)
 395                 r->entropy_count = r->length * 8;
 396 }
 397 
 398 /*
 399  * This function adds entropy to the entropy "pool" by using timing
 400  * delays.  It uses the timer_rand_state structure to make an estimate
 401  * of how many bits of entropy this call has added to the pool.
 402  */
 403 static void add_timer_randomness(struct random_bucket *r,
     /* [previous][next][first][last][top][bottom][index][help] */
 404                                  struct timer_rand_state *state, int delay)
 405 {
 406         int     delta, delta2;
 407         int     nbits;
 408 
 409         /*
 410          * Calculate number of bits of randomness we probably
 411          * added.  We take into account the first and second order
 412          * delta's in order to make our estimate.
 413          */
 414         delta = jiffies - state->last_time;
 415         delta2 = delta - state->last_delta;
 416         state->last_time = jiffies;
 417         state->last_delta = delta;
 418         if (delta < 0) delta = -delta;
 419         if (delta2 < 0) delta2 = -delta2;
 420         delta = MIN(delta, delta2) >> 1;
 421         for (nbits = 0; delta; nbits++)
 422                 delta >>= 1;
 423         
 424         add_entropy(r, (__u8 *) &jiffies, sizeof(jiffies),
 425                     nbits, delay);
 426 
 427 #if defined (__i386__)
 428         /*
 429          * On a Pentium, read the cycle counter. We assume that
 430          * this gives us 8 bits of randomness.  XXX This needs
 431          * investigation.
 432          */
 433         if (x86_capability & 16) {
 434                 unsigned long low, high;
 435                 __asm__(".byte 0x0f,0x31"
 436                         :"=a" (low), "=d" (high));
 437                 add_entropy_byte(r, low, 1);
 438                 r->entropy_count += 8;
 439                 if (r->entropy_count > r->bit_length)
 440                         r->entropy_count = r->bit_length;
 441         }
 442 #endif
 443 }
 444 
 445 void add_keyboard_randomness(unsigned char scancode)
     /* [previous][next][first][last][top][bottom][index][help] */
 446 {
 447         struct random_bucket *r = &random_state;
 448 
 449         add_timer_randomness(r, &keyboard_timer_state, 0);
 450         add_entropy_byte(r, scancode, 0);
 451         r->entropy_count += 6;
 452         if (r->entropy_count > r->bit_length)
 453                 r->entropy_count = r->bit_length;
 454 }
 455 
 456 void add_interrupt_randomness(int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 457 {
 458         struct random_bucket *r = &random_state;
 459 
 460         if (irq >= NR_IRQS)
 461                 return;
 462 
 463         add_timer_randomness(r, &irq_timer_state[irq], 1);
 464 }
 465 
 466 /*
 467  * This function extracts randomness from the "entropy pool", and
 468  * returns it in a buffer.  This function computes how many remaining
 469  * bits of entropy are left in the pool, but it does not restrict the
 470  * number of bytes that are actually obtained.
 471  */
 472 static inline int extract_entropy(struct random_bucket *r, char * buf,
     /* [previous][next][first][last][top][bottom][index][help] */
 473                                   int nbytes, int to_user)
 474 {
 475         int length, ret, passes, i;
 476         __u32 tmp[4];
 477         u8 *cp;
 478         
 479         add_entropy(r, (u8 *) &jiffies, sizeof(jiffies), 0, 0);
 480         
 481         if (r->entropy_count > r->bit_length) 
 482                 r->entropy_count = r->bit_length;
 483         if (nbytes > 32768)
 484                 nbytes = 32768;
 485         ret = nbytes;
 486         r->entropy_count -= ret * 8;
 487         if (r->entropy_count < 0)
 488                 r->entropy_count = 0;
 489         passes = r->length / 64;
 490         while (nbytes) {
 491                 length = MIN(nbytes, 16);
 492                 for (i=0; i < 16; i++) {
 493                         if (++random_counter[i] != 0)
 494                                 break;
 495                 }
 496                 tmp[0] = 0x67452301;
 497                 tmp[1] = 0xefcdab89;
 498                 tmp[2] = 0x98badcfe;
 499                 tmp[3] = 0x10325476;
 500                 MD5Transform(tmp, random_counter);
 501                 for (i = 0, cp = r->pool; i < passes; i++, cp+=64)
 502                         MD5Transform(tmp, (__u32 *) cp);
 503                 if (to_user)
 504                         memcpy_tofs(buf, tmp, length);
 505                 else
 506                         memcpy(buf, tmp, length);
 507                 nbytes -= length;
 508                 buf += length;
 509         }
 510         return ret;
 511 }
 512 
 513 /*
 514  * This function is the exported kernel interface.  It returns some
 515  * number of good random numbers, suitable for seeding TCP sequence
 516  * numbers, etc.
 517  */
 518 void get_random_bytes(void *buf, int nbytes)
     /* [previous][next][first][last][top][bottom][index][help] */
 519 {
 520         extract_entropy(&random_state, (char *) buf, nbytes, 0);
 521 }
 522 
 523 #ifdef linux
 524 int read_random(struct inode * inode,struct file * file,char * buf,int nbytes)
     /* [previous][next][first][last][top][bottom][index][help] */
 525 {
 526         if ((nbytes * 8) > random_state.entropy_count)
 527                 nbytes = random_state.entropy_count / 8;
 528         
 529         return extract_entropy(&random_state, buf, nbytes, 1);
 530 }
 531 
 532 int read_random_unlimited(struct inode * inode,struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 533                           char * buf,int nbytes)
 534 {
 535         return extract_entropy(&random_state, buf, nbytes, 1);
 536 }
 537 #endif
 538 
 539 #endif /* CONFIG_RANDOM */

/* [previous][next][first][last][top][bottom][index][help] */