diff options
Diffstat (limited to '3rd_party/libsrp6a-sha512/t_truerand.c')
-rw-r--r-- | 3rd_party/libsrp6a-sha512/t_truerand.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/3rd_party/libsrp6a-sha512/t_truerand.c b/3rd_party/libsrp6a-sha512/t_truerand.c new file mode 100644 index 0000000..2617b5e --- /dev/null +++ b/3rd_party/libsrp6a-sha512/t_truerand.c | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | * Physically random numbers (very nearly uniform) | ||
3 | * D. P. Mitchell | ||
4 | * Modified by Matt Blaze 7/95 | ||
5 | */ | ||
6 | /* | ||
7 | * The authors of this software are Don Mitchell and Matt Blaze. | ||
8 | * Copyright (c) 1995 by AT&T. | ||
9 | * Permission to use, copy, and modify this software without fee | ||
10 | * is hereby granted, provided that this entire notice is included in | ||
11 | * all copies of any software which is or includes a copy or | ||
12 | * modification of this software and in all copies of the supporting | ||
13 | * documentation for such software. | ||
14 | * | ||
15 | * This software may be subject to United States export controls. | ||
16 | * | ||
17 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED | ||
18 | * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY | ||
19 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY | ||
20 | * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * WARNING: depending on the particular platform, raw_truerand() | ||
25 | * output may be biased or correlated. In general, you can expect | ||
26 | * about 16 bits of "pseudo-entropy" out of each 32 bit word returned | ||
27 | * by truerand(), but it may not be uniformly diffused. You should | ||
28 | * raw_therefore run the output through some post-whitening function | ||
29 | * (like MD5 or DES or whatever) before using it to generate key | ||
30 | * material. (RSAREF's random package does this for you when you feed | ||
31 | * raw_truerand() bits to the seed input function.) | ||
32 | * | ||
33 | * The application interface, for 8, 16, and 32 bit properly "whitened" | ||
34 | * random numbers, can be found in trand8(), trand16(), and trand32(). | ||
35 | * Use those instead of calling raw_truerand() directly. | ||
36 | * | ||
37 | * The basic idea here is that between clock "skew" and various | ||
38 | * hard-to-predict OS event arrivals, counting a tight loop will yield | ||
39 | * a little (maybe a third of a bit or so) of "good" randomness per | ||
40 | * interval clock tick. This seems to work well even on unloaded | ||
41 | * machines. If there is a human operator at the machine, you should | ||
42 | * augment truerand with other measure, like keyboard event timing. | ||
43 | * On server machines (e.g., when you need to generate a | ||
44 | * Diffie-Hellman secret) truerand alone may be good enough. | ||
45 | * | ||
46 | * Test these assumptions on your own platform before fielding a | ||
47 | * system based on this software or these techniques. | ||
48 | * | ||
49 | * This software seems to work well (at 10 or so bits per | ||
50 | * raw_truerand() call) on a Sun Sparc-20 under SunOS 4.1.3 and on a | ||
51 | * P100 under BSDI 2.0. You're on your own elsewhere. | ||
52 | * | ||
53 | */ | ||
54 | |||
55 | #include "t_defines.h" | ||
56 | |||
57 | #ifdef WIN32 | ||
58 | |||
59 | # ifdef CRYPTOLIB | ||
60 | |||
61 | /* Cryptolib contains its own truerand() on both UNIX and Windows. */ | ||
62 | /* Only use cryptolib's truerand under Windows */ | ||
63 | |||
64 | # include "libcrypt.h" | ||
65 | |||
66 | unsigned long | ||
67 | raw_truerand() | ||
68 | { | ||
69 | return truerand(); | ||
70 | } | ||
71 | |||
72 | # else /* !CRYPTOLIB && WIN32 */ | ||
73 | |||
74 | #include <wtypes.h> | ||
75 | #include <winbase.h> | ||
76 | #include <windef.h> | ||
77 | #include <winnt.h> | ||
78 | #include <winuser.h> | ||
79 | #include <process.h> | ||
80 | |||
81 | volatile unsigned long count, ocount, randbuf; | ||
82 | volatile int dontstop; | ||
83 | char outbuf[1024], *bufp; | ||
84 | |||
85 | static void counter() { | ||
86 | while (dontstop) | ||
87 | count++; | ||
88 | _endthread(); | ||
89 | } | ||
90 | |||
91 | |||
92 | static unsigned long roulette() { | ||
93 | unsigned long thread; | ||
94 | |||
95 | count = 0; | ||
96 | dontstop= 1; | ||
97 | while ((thread = _beginthread((void *)counter, 1024, NULL)) < 0) | ||
98 | ; | ||
99 | |||
100 | Sleep(16); | ||
101 | dontstop = 0; | ||
102 | Sleep(1); | ||
103 | |||
104 | count ^= (count>>3) ^ (count>>6) ^ (ocount); | ||
105 | count &= 0x7; | ||
106 | ocount = count; | ||
107 | randbuf = (randbuf<<3) ^ count; | ||
108 | return randbuf; | ||
109 | } | ||
110 | |||
111 | |||
112 | unsigned long | ||
113 | raw_truerand() { | ||
114 | |||
115 | roulette(); | ||
116 | roulette(); | ||
117 | roulette(); | ||
118 | roulette(); | ||
119 | roulette(); | ||
120 | roulette(); | ||
121 | roulette(); | ||
122 | roulette(); | ||
123 | roulette(); | ||
124 | roulette(); | ||
125 | return roulette(); | ||
126 | } | ||
127 | |||
128 | # endif /* CRYPTOLIB */ | ||
129 | |||
130 | #else /* !WIN32 */ | ||
131 | |||
132 | #include <signal.h> | ||
133 | #include <setjmp.h> | ||
134 | #include <sys/time.h> | ||
135 | #include <math.h> | ||
136 | #include <stdio.h> | ||
137 | |||
138 | #ifdef OLD_TRUERAND | ||
139 | static jmp_buf env; | ||
140 | #endif | ||
141 | static unsigned volatile count | ||
142 | #ifndef OLD_TRUERAND | ||
143 | , done = 0 | ||
144 | #endif | ||
145 | ; | ||
146 | |||
147 | static unsigned ocount; | ||
148 | static unsigned buffer; | ||
149 | |||
150 | static void | ||
151 | tick() | ||
152 | { | ||
153 | struct itimerval it, oit; | ||
154 | |||
155 | it.it_interval.tv_sec = 0; | ||
156 | it.it_interval.tv_usec = 0; | ||
157 | it.it_value.tv_sec = 0; | ||
158 | it.it_value.tv_usec = 16665; | ||
159 | if (setitimer(ITIMER_REAL, &it, &oit) < 0) | ||
160 | perror("tick"); | ||
161 | } | ||
162 | |||
163 | static void | ||
164 | interrupt() | ||
165 | { | ||
166 | if (count) { | ||
167 | #ifdef OLD_TRUERAND | ||
168 | longjmp(env, 1); | ||
169 | #else | ||
170 | ++done; | ||
171 | return; | ||
172 | #endif | ||
173 | } | ||
174 | |||
175 | (void) signal(SIGALRM, interrupt); | ||
176 | tick(); | ||
177 | } | ||
178 | |||
179 | static unsigned long | ||
180 | roulette() | ||
181 | { | ||
182 | #ifdef OLD_TRUERAND | ||
183 | if (setjmp(env)) { | ||
184 | count ^= (count>>3) ^ (count>>6) ^ ocount; | ||
185 | count &= 0x7; | ||
186 | ocount=count; | ||
187 | buffer = (buffer<<3) ^ count; | ||
188 | return buffer; | ||
189 | } | ||
190 | #else | ||
191 | done = 0; | ||
192 | #endif | ||
193 | (void) signal(SIGALRM, interrupt); | ||
194 | count = 0; | ||
195 | tick(); | ||
196 | #ifdef OLD_TRUERAND | ||
197 | for (;;) | ||
198 | #else | ||
199 | while(done == 0) | ||
200 | #endif | ||
201 | count++; /* about 1 MHz on VAX 11/780 */ | ||
202 | #ifndef OLD_TRUERAND | ||
203 | count ^= (count>>3) ^ (count>>6) ^ ocount; | ||
204 | count &= 0x7; | ||
205 | ocount=count; | ||
206 | buffer = (buffer<<3) ^ count; | ||
207 | return buffer; | ||
208 | #endif | ||
209 | } | ||
210 | |||
211 | unsigned long | ||
212 | raw_truerand() | ||
213 | { | ||
214 | count=0; | ||
215 | (void) roulette(); | ||
216 | (void) roulette(); | ||
217 | (void) roulette(); | ||
218 | (void) roulette(); | ||
219 | (void) roulette(); | ||
220 | (void) roulette(); | ||
221 | (void) roulette(); | ||
222 | (void) roulette(); | ||
223 | (void) roulette(); | ||
224 | (void) roulette(); | ||
225 | return roulette(); | ||
226 | } | ||
227 | |||
228 | int | ||
229 | raw_n_truerand(n) | ||
230 | int n; | ||
231 | { | ||
232 | int slop, v; | ||
233 | |||
234 | slop = 0x7FFFFFFF % n; | ||
235 | do { | ||
236 | v = raw_truerand() >> 1; | ||
237 | } while (v <= slop); | ||
238 | return v % n; | ||
239 | } | ||
240 | |||
241 | #endif /* !CRYPTOLIB || !WIN32 */ | ||