The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/libkern/arc4random.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * THE BEER-WARE LICENSE
    3  *
    4  * <dan@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
    5  * can do whatever you want with this stuff.  If we meet some day, and you
    6  * think this stuff is worth it, you can buy me a beer in return.
    7  *
    8  * Dan Moschuk
    9  *
   10  * $FreeBSD: src/sys/libkern/arc4random.c,v 1.6.4.2 2000/10/06 22:49:54 alfred Exp $
   11  */
   12 
   13 #include <sys/libkern.h>
   14 
   15 #define ARC4_MAXRUNS 64
   16 
   17 static u_int8_t arc4_i, arc4_j;
   18 static int arc4_initialized = 0;
   19 static int arc4_numruns = 0;
   20 static u_int8_t arc4_sbox[256];
   21 
   22 extern u_int read_random (void *, u_int);
   23 
   24 static __inline void
   25 arc4_swap(u_int8_t *a, u_int8_t *b)
   26 {
   27         u_int8_t c;
   28 
   29         c = *a;
   30         *a = *b;
   31         *b = c;
   32 }       
   33 
   34 /*
   35  * Stir our S-box.
   36  */
   37 static void
   38 arc4_randomstir (void)
   39 {
   40         u_int8_t key[256];
   41         int r, n;
   42 
   43         r = read_random(key, sizeof(key));
   44         /* if r == 0 || -1, just use what was on the stack */
   45         if (r > 0)
   46         {
   47                 for (n = r; n < sizeof(key); n++)
   48                         key[n] = key[n % r];
   49         }
   50 
   51         for (n = 0; n < 256; n++)
   52         {
   53                 arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256;
   54                 arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]);
   55         }
   56 }
   57 
   58 /*
   59  * Initialize our S-box to its beginning defaults.
   60  */
   61 static void
   62 arc4_init(void)
   63 {
   64         int n;
   65 
   66         arc4_i = arc4_j = 0;
   67         for (n = 0; n < 256; n++)
   68                 arc4_sbox[n] = (u_int8_t) n;
   69 
   70         arc4_randomstir();
   71         arc4_initialized = 1;
   72 }
   73 
   74 /*
   75  * Generate a random byte.
   76  */
   77 static u_int8_t
   78 arc4_randbyte(void)
   79 {
   80         u_int8_t arc4_t;
   81 
   82         arc4_i = (arc4_i + 1) % 256;
   83         arc4_j = (arc4_j + arc4_sbox[arc4_i]) % 256;
   84 
   85         arc4_swap(&arc4_sbox[arc4_i], &arc4_sbox[arc4_j]);
   86 
   87         arc4_t = (arc4_sbox[arc4_i] + arc4_sbox[arc4_j]) % 256;
   88         return arc4_sbox[arc4_t];
   89 }
   90 
   91 u_int32_t
   92 arc4random(void)
   93 {
   94         u_int32_t ret;
   95 
   96         /* Initialize array if needed. */
   97         if (!arc4_initialized)
   98                 arc4_init();
   99         if (++arc4_numruns > ARC4_MAXRUNS)
  100         {
  101                 arc4_randomstir();
  102                 arc4_numruns = 0;
  103         }
  104 
  105         ret = arc4_randbyte();
  106         ret |= arc4_randbyte() << 8;
  107         ret |= arc4_randbyte() << 16;
  108         ret |= arc4_randbyte() << 24;
  109 
  110         return ret;
  111 }

Cache object: 444eb30eff1d29dac9911e7af915f613


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.