URI: 
       trandom.c - mixmaster - mixmaster 3.0 patched for libressl
  HTML git clone git://parazyd.org/mixmaster.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
       ---
       trandom.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 */