kernel: fq_codel: dont reinit flow state
[openwrt.git] / package / ead / src / tinysrp / t_truerand.c
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 #include <signal.h>
58 #include <setjmp.h>
59 #include <sys/time.h>
60 #include <math.h>
61 #include <stdio.h>
62
63 #ifdef OLD_TRUERAND
64 static jmp_buf env;
65 #endif
66 static unsigned volatile count
67 #ifndef OLD_TRUERAND
68   , done = 0
69 #endif
70 ;
71
72 static unsigned ocount;
73 static unsigned buffer;
74
75 static void
76 tick()
77 {
78         struct itimerval it, oit;
79
80         it.it_interval.tv_sec = 0;
81         it.it_interval.tv_usec = 0;
82         it.it_value.tv_sec = 0;
83         it.it_value.tv_usec = 16665;
84         if (setitimer(ITIMER_REAL, &it, &oit) < 0)
85                 perror("tick");
86 }
87
88 static void
89 interrupt()
90 {
91         if (count) {
92 #ifdef OLD_TRUERAND
93                 longjmp(env, 1);
94 #else
95                 ++done;
96                 return;
97 #endif
98         }
99
100         (void) signal(SIGALRM, interrupt);
101         tick();
102 }
103
104 static unsigned long
105 roulette()
106 {
107 #ifdef OLD_TRUERAND
108         if (setjmp(env)) {
109                 count ^= (count>>3) ^ (count>>6) ^ ocount;
110                 count &= 0x7;
111                 ocount=count;
112                 buffer = (buffer<<3) ^ count;
113                 return buffer;
114         }
115 #else
116         done = 0;
117 #endif
118         (void) signal(SIGALRM, interrupt);
119         count = 0;
120         tick();
121 #ifdef OLD_TRUERAND
122         for (;;)
123 #else
124         while(done == 0)
125 #endif
126                 count++;        /* about 1 MHz on VAX 11/780 */
127 #ifndef OLD_TRUERAND
128         count ^= (count>>3) ^ (count>>6) ^ ocount;
129         count &= 0x7;
130         ocount=count;
131         buffer = (buffer<<3) ^ count;
132         return buffer;
133 #endif
134 }
135
136 unsigned long
137 raw_truerand()
138 {
139         count=0;
140         (void) roulette();
141         (void) roulette();
142         (void) roulette();
143         (void) roulette();
144         (void) roulette();
145         (void) roulette();
146         (void) roulette();
147         (void) roulette();
148         (void) roulette();
149         (void) roulette();
150         return roulette();
151 }