mixmaster

mixmaster 3.0 patched for libressl
git clone git://parazyd.org/mixmaster.git
Log | Files | Refs | README

random.c (4009B)


      1 /* Mixmaster version 3.0  --  (C) 1999 - 2006 Anonymizer Inc. and others.
      2 
      3    Mixmaster may be redistributed and modified under certain conditions.
      4    This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
      5    ANY KIND, either express or implied. See the file COPYRIGHT for
      6    details.
      7 
      8    Randomness
      9    $Id: random.c 934 2006-06-24 13:40:39Z rabbi $ */
     10 
     11 
     12 #include "mix3.h"
     13 #include "crypto.h"
     14 #include <fcntl.h>
     15 #ifdef POSIX
     16 #include <sys/time.h>
     17 #include <unistd.h>
     18 #else /* end of POSIX */
     19 #include <io.h>
     20 #include <process.h>
     21 #endif /* else if not POSIX */
     22 #ifdef WIN32
     23 #include <windows.h>
     24 #endif /* WIN32 */
     25 #include <assert.h>
     26 #include <string.h>
     27 
     28 int rnd_state = RND_NOTSEEDED;
     29 
     30 #ifdef USE_OPENSSL
     31 int rnd_init(void)
     32 {
     33   char r[PATHMAX];
     34   int n;
     35   LOCK *rndlock;
     36 
     37   if (rnd_state == RND_SEEDED)
     38     return(0);
     39   rndlock = lockfile(MIXRAND);
     40   mixfile(r, MIXRAND);
     41   n = RAND_load_file(r, 1024);
     42   if (n < 256 && rnd_seed() == -1)
     43     goto err;
     44   rnd_time();
     45   RAND_write_file(r);
     46   rnd_state = RND_SEEDED;
     47  err:
     48   unlockfile(rndlock);
     49   return (rnd_state == RND_SEEDED ? 0 : -1);
     50 }
     51 
     52 int rnd_final(void)
     53 {
     54   int err = 0;
     55   char r[PATHMAX];
     56   LOCK *rndlock;
     57 
     58   if (rnd_state != RND_SEEDED)
     59     return(-1);
     60 
     61   rnd_update(NULL, 0);
     62   rndlock = lockfile(MIXRAND);
     63   mixfile(r, MIXRAND);
     64   RAND_load_file(r, 1024);	/* add seed file again in case other instances
     65 				   of the program have used it */
     66   if (RAND_write_file(r) < 1)
     67     err = -1;
     68   unlockfile(rndlock);
     69   RAND_cleanup();
     70   return (err);
     71 }
     72 
     73 int rnd_add(byte *b, int l)
     74 {
     75   RAND_seed(b, l);
     76   return (0);
     77 }
     78 #endif /* USE_OPENSSL */
     79 
     80 void rnd_time(void)
     81 {
     82   int pid;
     83 
     84 #ifdef WIN32
     85   SYSTEMTIME t;
     86 #endif /* WIN32 */
     87 
     88 #ifdef HAVE_GETTIMEOFDAY
     89   struct timeval tv;
     90 
     91   gettimeofday(&tv, 0);
     92   rnd_add((byte *) &tv, sizeof(tv));
     93 #elif defined(WIN32) /* end of HAVE_GETTIMEOFDAY */
     94   GetSystemTime(&t);
     95   rnd_add((byte *) &t, sizeof(t));
     96 #else /* end of defined(WIN32) */
     97   rnd_add((byte *) time(NULL), sizeof(time_t));
     98 #endif /* else if not defined(WIN32), HAVE_GETTIMEOFDAY */
     99   pid = getpid();
    100   rnd_add((byte *) &pid, sizeof(pid));
    101 }
    102 
    103 void rnd_update(byte *seed, int l)
    104 {
    105   int fd = -1;
    106   byte b[512];
    107 
    108   rnd_time();
    109   if (seed)
    110     rnd_add(seed, l);
    111 #ifdef DEV_URANDOM
    112   fd = open(DEV_URANDOM, O_RDONLY);
    113   if (fd != -1) {
    114     ssize_t ret;
    115 
    116     ret = read(fd, b, sizeof(b));
    117     if (ret > 0) {
    118       rnd_add(b, ret);
    119     }
    120     close(fd);
    121   }
    122 #endif /* DEV_URANDOM */
    123 }
    124 
    125 int rnd_bytes(byte *b, int n)
    126 {
    127   /* we frequently need to get small amounts of random data.
    128      speed up by pre-generating dating data */
    129 
    130   static byte rand[BUFSIZE];
    131   static int idx = BUFSIZE;
    132 
    133   if (rnd_state != RND_SEEDED)
    134     rnd_error();
    135 
    136   if (n + idx < BUFSIZE) {
    137     memcpy(b, rand + idx, n);
    138     idx += n;
    139   } else
    140     RAND_bytes(b, n);
    141 
    142   if (idx + 256 > BUFSIZE) {
    143     RAND_bytes(rand, BUFSIZE);
    144     idx = 0;
    145   }
    146   return (0);
    147 }
    148 
    149 int rnd_number(int n)
    150 {
    151   int r;
    152 
    153   assert(n > 0);
    154   if (n > 65535)
    155     do
    156       r = rnd_byte() * 65536 +
    157 	rnd_byte() * 256 + rnd_byte();
    158     while (r >= n);
    159   else if (n > 255)
    160     do
    161       r = rnd_byte() * 256 + rnd_byte();
    162     while (r >= n);
    163   else
    164     do
    165       r = rnd_byte();
    166     while (r >= n);
    167   return r;
    168 }
    169 
    170 byte rnd_byte()
    171 {
    172   byte b;
    173 
    174   rnd_bytes(&b, 1);
    175   return b;
    176 }
    177 
    178 void rnd_initialized(void)
    179 {
    180   rnd_state = RND_SEEDED;
    181 }
    182 
    183 #ifdef WIN32
    184 
    185 #define NEEDED 256
    186 
    187 int rnd_mouse(UINT i, WPARAM w, LPARAM l)
    188 {
    189   static int entropy = 0;
    190   static int x, y, dx, dy;
    191   int newx, newy, newdx, newdy;
    192   int rnd[4];
    193 
    194   if (i == WM_MOUSEMOVE) {
    195     newx = LOWORD(l);
    196     newy = HIWORD(l);
    197     newdx = x - newx;
    198     newdy = y - newy;
    199     if (dx != 0 && dy != 0 && dx - newdx != 0 && dy - newdy != 0) {
    200       entropy++;
    201       if (entropy >= NEEDED)
    202 	rnd_state = RND_SEEDED;
    203     }
    204     x = newx, y = newy, dx = newdx, dy = newdy;
    205     rnd[0] = x; rnd[1] = y; rnd[2] = dx; rnd[3] = dy;
    206     rnd_update((byte*)rnd, 4 * sizeof(int));
    207   }
    208   return (rnd_state == RND_SEEDED ? 100 : entropy * 100 / NEEDED);
    209 }
    210 #endif /* WIN32 */