ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

randm.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * randm.c - Random number generator program file.
00003 *
00004 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
00005 * Copyright (c) 1998 by Global Election Systems Inc.
00006 *
00007 * The authors hereby grant permission to use, copy, modify, distribute,
00008 * and license this software and its documentation for any purpose, provided
00009 * that existing copyright notices are retained in all copies and that this
00010 * notice and the following disclaimer are included verbatim in any 
00011 * distributions. No written agreement, license, or royalty fee is required
00012 * for any of the authorized uses.
00013 *
00014 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
00015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
00017 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00024 *
00025 ******************************************************************************
00026 * REVISION HISTORY
00027 *
00028 * 03-01-01 Marc Boucher <marc@mbsi.ca>
00029 *   Ported to lwIP.
00030 * 98-06-03 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
00031 *   Extracted from avos.
00032 *****************************************************************************/
00033 
00034 #include "lwip/opt.h"
00035 
00036 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
00037 
00038 #include "md5.h"
00039 #include "randm.h"
00040 
00041 #include "ppp.h"
00042 #include "pppdebug.h"
00043 
00044 #include <string.h>
00045 
00046 #if MD5_SUPPORT /* this module depends on MD5 */
00047 #define RANDPOOLSZ 16   /* Bytes stored in the pool of randomness. */
00048 
00049 /*****************************/
00050 /*** LOCAL DATA STRUCTURES ***/
00051 /*****************************/
00052 static char randPool[RANDPOOLSZ];   /* Pool of randomness. */
00053 static long randCount = 0;      /* Pseudo-random incrementer */
00054 
00055 
00056 /***********************************/
00057 /*** PUBLIC FUNCTION DEFINITIONS ***/
00058 /***********************************/
00059 /*
00060  * Initialize the random number generator.
00061  *
00062  * Since this is to be called on power up, we don't have much
00063  *  system randomess to work with.  Here all we use is the
00064  *  real-time clock.  We'll accumulate more randomness as soon
00065  *  as things start happening.
00066  */
00067 void
00068 avRandomInit()
00069 {
00070   avChurnRand(NULL, 0);
00071 }
00072 
00073 /*
00074  * Churn the randomness pool on a random event.  Call this early and often
00075  *  on random and semi-random system events to build randomness in time for
00076  *  usage.  For randomly timed events, pass a null pointer and a zero length
00077  *  and this will use the system timer and other sources to add randomness.
00078  *  If new random data is available, pass a pointer to that and it will be
00079  *  included.
00080  *
00081  * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
00082  */
00083 void
00084 avChurnRand(char *randData, u32_t randLen)
00085 {
00086   MD5_CTX md5;
00087 
00088   /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", randLen, randData)); */
00089   MD5Init(&md5);
00090   MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
00091   if (randData) {
00092     MD5Update(&md5, (u_char *)randData, randLen);
00093   } else {
00094     struct {
00095       /* INCLUDE fields for any system sources of randomness */
00096       char foobar;
00097     } sysData;
00098 
00099     /* Load sysData fields here. */
00100     MD5Update(&md5, (u_char *)&sysData, sizeof(sysData));
00101   }
00102   MD5Final((u_char *)randPool, &md5);
00103 /*  LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */
00104 }
00105 
00106 /*
00107  * Use the random pool to generate random data.  This degrades to pseudo
00108  *  random when used faster than randomness is supplied using churnRand().
00109  * Note: It's important that there be sufficient randomness in randPool
00110  *  before this is called for otherwise the range of the result may be
00111  *  narrow enough to make a search feasible.
00112  *
00113  * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427
00114  *
00115  * XXX Why does he not just call churnRand() for each block?  Probably
00116  *  so that you don't ever publish the seed which could possibly help
00117  *  predict future values.
00118  * XXX Why don't we preserve md5 between blocks and just update it with
00119  *  randCount each time?  Probably there is a weakness but I wish that
00120  *  it was documented.
00121  */
00122 void
00123 avGenRand(char *buf, u32_t bufLen)
00124 {
00125   MD5_CTX md5;
00126   u_char tmp[16];
00127   u32_t n;
00128 
00129   while (bufLen > 0) {
00130     n = LWIP_MIN(bufLen, RANDPOOLSZ);
00131     MD5Init(&md5);
00132     MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
00133     MD5Update(&md5, (u_char *)&randCount, sizeof(randCount));
00134     MD5Final(tmp, &md5);
00135     randCount++;
00136     MEMCPY(buf, tmp, n);
00137     buf += n;
00138     bufLen -= n;
00139   }
00140 }
00141 
00142 /*
00143  * Return a new random number.
00144  */
00145 u32_t
00146 avRandom()
00147 {
00148   u32_t newRand;
00149 
00150   avGenRand((char *)&newRand, sizeof(newRand));
00151 
00152   return newRand;
00153 }
00154 
00155 #else /* MD5_SUPPORT */
00156 
00157 /*****************************/
00158 /*** LOCAL DATA STRUCTURES ***/
00159 /*****************************/
00160 static int  avRandomized = 0;       /* Set when truely randomized. */
00161 static u32_t avRandomSeed = 0;      /* Seed used for random number generation. */
00162 
00163 
00164 /***********************************/
00165 /*** PUBLIC FUNCTION DEFINITIONS ***/
00166 /***********************************/
00167 /*
00168  * Initialize the random number generator.
00169  *
00170  * Here we attempt to compute a random number seed but even if
00171  * it isn't random, we'll randomize it later.
00172  *
00173  * The current method uses the fields from the real time clock,
00174  * the idle process counter, the millisecond counter, and the
00175  * hardware timer tick counter.  When this is invoked
00176  * in startup(), then the idle counter and timer values may
00177  * repeat after each boot and the real time clock may not be
00178  * operational.  Thus we call it again on the first random
00179  * event.
00180  */
00181 void
00182 avRandomInit()
00183 {
00184 #if 0
00185   /* Get a pointer into the last 4 bytes of clockBuf. */
00186   u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]);
00187 
00188   /*
00189    * Initialize our seed using the real-time clock, the idle
00190    * counter, the millisecond timer, and the hardware timer
00191    * tick counter.  The real-time clock and the hardware
00192    * tick counter are the best sources of randomness but
00193    * since the tick counter is only 16 bit (and truncated
00194    * at that), the idle counter and millisecond timer
00195    * (which may be small values) are added to help
00196    * randomize the lower 16 bits of the seed.
00197    */
00198   readClk();
00199   avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr
00200            + ppp_mtime() + ((u32_t)TM1 << 16) + TM1;
00201 #else
00202   avRandomSeed += sys_jiffies(); /* XXX */
00203 #endif
00204 
00205   /* Initialize the Borland random number generator. */
00206   srand((unsigned)avRandomSeed);
00207 }
00208 
00209 /*
00210  * Randomize our random seed value.  Here we use the fact that
00211  * this function is called at *truely random* times by the polling
00212  * and network functions.  Here we only get 16 bits of new random
00213  * value but we use the previous value to randomize the other 16
00214  * bits.
00215  */
00216 void
00217 avRandomize(void)
00218 {
00219   static u32_t last_jiffies;
00220 
00221   if (!avRandomized) {
00222     avRandomized = !0;
00223     avRandomInit();
00224     /* The initialization function also updates the seed. */
00225   } else {
00226     /* avRandomSeed += (avRandomSeed << 16) + TM1; */
00227     avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */
00228   }
00229   last_jiffies = sys_jiffies();
00230 }
00231 
00232 /*
00233  * Return a new random number.
00234  * Here we use the Borland rand() function to supply a pseudo random
00235  * number which we make truely random by combining it with our own
00236  * seed which is randomized by truely random events. 
00237  * Thus the numbers will be truely random unless there have been no
00238  * operator or network events in which case it will be pseudo random
00239  * seeded by the real time clock.
00240  */
00241 u32_t
00242 avRandom()
00243 {
00244   return ((((u32_t)rand() << 16) + rand()) + avRandomSeed);
00245 }
00246 
00247 #endif /* MD5_SUPPORT */
00248 
00249 #endif /* PPP_SUPPORT */

Generated on Sun May 27 2012 04:36:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.