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..f995ed7 --- /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 <windows.h> | ||
75 | #include <wtypes.h> | ||
76 | #include <winbase.h> | ||
77 | #include <windef.h> | ||
78 | #include <winnt.h> | ||
79 | #include <winuser.h> | ||
80 | #include <process.h> | ||
81 | |||
82 | volatile unsigned long count, ocount, randbuf; | ||
83 | volatile int dontstop; | ||
84 | char outbuf[1024], *bufp; | ||
85 | |||
86 | static void counter() { | ||
87 | while (dontstop) | ||
88 | count++; | ||
89 | _endthread(); | ||
90 | } | ||
91 | |||
92 | |||
93 | static unsigned long roulette() { | ||
94 | unsigned long thread; | ||
95 | |||
96 | count = 0; | ||
97 | dontstop= 1; | ||
98 | while ((thread = _beginthread((void *)counter, 1024, NULL)) < 0) | ||
99 | ; | ||
100 | |||
101 | Sleep(16); | ||
102 | dontstop = 0; | ||
103 | Sleep(1); | ||
104 | |||
105 | count ^= (count>>3) ^ (count>>6) ^ (ocount); | ||
106 | count &= 0x7; | ||
107 | ocount = count; | ||
108 | randbuf = (randbuf<<3) ^ count; | ||
109 | return randbuf; | ||
110 | } | ||
111 | |||
112 | |||
113 | unsigned long | ||
114 | raw_truerand() { | ||
115 | |||
116 | roulette(); | ||
117 | roulette(); | ||
118 | roulette(); | ||
119 | roulette(); | ||
120 | roulette(); | ||
121 | roulette(); | ||
122 | roulette(); | ||
123 | roulette(); | ||
124 | roulette(); | ||
125 | roulette(); | ||
126 | return roulette(); | ||
127 | } | ||
128 | |||
129 | # endif /* CRYPTOLIB */ | ||
130 | |||
131 | #else /* !WIN32 */ | ||
132 | |||
133 | #include <signal.h> | ||
134 | #include <setjmp.h> | ||
135 | #include <sys/time.h> | ||
136 | #include <math.h> | ||
137 | #include <stdio.h> | ||
138 | |||
139 | #ifdef OLD_TRUERAND | ||
140 | static jmp_buf env; | ||
141 | #endif | ||
142 | static unsigned volatile count | ||
143 | #ifndef OLD_TRUERAND | ||
144 | , done = 0 | ||
145 | #endif | ||
146 | ; | ||
147 | |||
148 | static unsigned ocount; | ||
149 | static unsigned buffer; | ||
150 | |||
151 | static void | ||
152 | tick() | ||
153 | { | ||
154 | struct itimerval it, oit; | ||
155 | |||
156 | it.it_interval.tv_sec = 0; | ||
157 | it.it_interval.tv_usec = 0; | ||
158 | it.it_value.tv_sec = 0; | ||
159 | it.it_value.tv_usec = 16665; | ||
160 | if (setitimer(ITIMER_REAL, &it, &oit) < 0) | ||
161 | perror("tick"); | ||
162 | } | ||
163 | |||
164 | static void | ||
165 | interrupt() | ||
166 | { | ||
167 | if (count) { | ||
168 | #ifdef OLD_TRUERAND | ||
169 | longjmp(env, 1); | ||
170 | #else | ||
171 | ++done; | ||
172 | return; | ||
173 | #endif | ||
174 | } | ||
175 | |||
176 | (void) signal(SIGALRM, interrupt); | ||
177 | tick(); | ||
178 | } | ||
179 | |||
180 | static unsigned long | ||
181 | roulette() | ||
182 | { | ||
183 | #ifdef OLD_TRUERAND | ||
184 | if (setjmp(env)) { | ||
185 | count ^= (count>>3) ^ (count>>6) ^ ocount; | ||
186 | count &= 0x7; | ||
187 | ocount=count; | ||
188 | buffer = (buffer<<3) ^ count; | ||
189 | return buffer; | ||
190 | } | ||
191 | #else | ||
192 | done = 0; | ||
193 | #endif | ||
194 | (void) signal(SIGALRM, interrupt); | ||
195 | count = 0; | ||
196 | tick(); | ||
197 | #ifdef OLD_TRUERAND | ||
198 | for (;;) | ||
199 | #else | ||
200 | while(done == 0) | ||
201 | #endif | ||
202 | count++; /* about 1 MHz on VAX 11/780 */ | ||
203 | #ifndef OLD_TRUERAND | ||
204 | count ^= (count>>3) ^ (count>>6) ^ ocount; | ||
205 | count &= 0x7; | ||
206 | ocount=count; | ||
207 | buffer = (buffer<<3) ^ count; | ||
208 | return buffer; | ||
209 | #endif | ||
210 | } | ||
211 | |||
212 | unsigned long | ||
213 | raw_truerand() | ||
214 | { | ||
215 | count=0; | ||
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 | (void) roulette(); | ||
226 | return roulette(); | ||
227 | } | ||
228 | |||
229 | int | ||
230 | raw_n_truerand(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 */ | ||