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 */