diff options
Diffstat (limited to 'src/lib/libcrypto/rand/rand_unix.c')
-rw-r--r-- | src/lib/libcrypto/rand/rand_unix.c | 118 |
1 files changed, 36 insertions, 82 deletions
diff --git a/src/lib/libcrypto/rand/rand_unix.c b/src/lib/libcrypto/rand/rand_unix.c index e3a65571c8..4bb9666e49 100644 --- a/src/lib/libcrypto/rand/rand_unix.c +++ b/src/lib/libcrypto/rand/rand_unix.c | |||
@@ -133,102 +133,56 @@ | |||
133 | # define FD_SETSIZE (8*sizeof(fd_set)) | 133 | # define FD_SETSIZE (8*sizeof(fd_set)) |
134 | #endif | 134 | #endif |
135 | 135 | ||
136 | #if defined(OPENSSL_SYS_VOS) | 136 | #ifdef __VOS__ |
137 | |||
138 | /* The following algorithm repeatedly samples the real-time clock | ||
139 | (RTC) to generate a sequence of unpredictable data. The algorithm | ||
140 | relies upon the uneven execution speed of the code (due to factors | ||
141 | such as cache misses, interrupts, bus activity, and scheduling) and | ||
142 | upon the rather large relative difference between the speed of the | ||
143 | clock and the rate at which it can be read. | ||
144 | |||
145 | If this code is ported to an environment where execution speed is | ||
146 | more constant or where the RTC ticks at a much slower rate, or the | ||
147 | clock can be read with fewer instructions, it is likely that the | ||
148 | results would be far more predictable. | ||
149 | |||
150 | As a precaution, we generate 4 times the minimum required amount of | ||
151 | seed data. */ | ||
152 | |||
153 | int RAND_poll(void) | 137 | int RAND_poll(void) |
154 | { | 138 | { |
155 | short int code; | 139 | unsigned char buf[ENTROPY_NEEDED]; |
156 | gid_t curr_gid; | ||
157 | pid_t curr_pid; | 140 | pid_t curr_pid; |
158 | uid_t curr_uid; | 141 | uid_t curr_uid; |
159 | int i, k; | 142 | static int first=1; |
143 | int i; | ||
144 | long rnd = 0; | ||
160 | struct timespec ts; | 145 | struct timespec ts; |
161 | unsigned char v; | 146 | unsigned seed; |
162 | 147 | ||
163 | #ifdef OPENSSL_SYS_VOS_HPPA | 148 | /* The VOS random() function starts from a static seed so its |
164 | long duration; | 149 | initial value is predictable. If random() returns the |
165 | extern void s$sleep (long *_duration, short int *_code); | 150 | initial value, reseed it with dynamic data. The VOS |
166 | #else | 151 | real-time clock has a granularity of 1 nsec so it should be |
167 | #ifdef OPENSSL_SYS_VOS_IA32 | 152 | reasonably difficult to predict its exact value. Do not |
168 | long long duration; | 153 | gratuitously reseed the PRNG because other code in this |
169 | extern void s$sleep2 (long long *_duration, short int *_code); | 154 | process or thread may be using it. */ |
170 | #else | 155 | |
171 | #error "Unsupported Platform." | 156 | if (first) { |
172 | #endif /* OPENSSL_SYS_VOS_IA32 */ | 157 | first = 0; |
173 | #endif /* OPENSSL_SYS_VOS_HPPA */ | 158 | rnd = random (); |
174 | 159 | if (rnd == 1804289383) { | |
175 | /* Seed with the gid, pid, and uid, to ensure *some* | 160 | clock_gettime (CLOCK_REALTIME, &ts); |
176 | variation between different processes. */ | 161 | curr_pid = getpid(); |
177 | 162 | curr_uid = getuid(); | |
178 | curr_gid = getgid(); | 163 | seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid; |
179 | RAND_add (&curr_gid, sizeof curr_gid, 1); | 164 | srandom (seed); |
180 | curr_gid = 0; | 165 | } |
181 | 166 | } | |
182 | curr_pid = getpid(); | ||
183 | RAND_add (&curr_pid, sizeof curr_pid, 1); | ||
184 | curr_pid = 0; | ||
185 | |||
186 | curr_uid = getuid(); | ||
187 | RAND_add (&curr_uid, sizeof curr_uid, 1); | ||
188 | curr_uid = 0; | ||
189 | |||
190 | for (i=0; i<(ENTROPY_NEEDED*4); i++) | ||
191 | { | ||
192 | /* burn some cpu; hope for interrupts, cache | ||
193 | collisions, bus interference, etc. */ | ||
194 | for (k=0; k<99; k++) | ||
195 | ts.tv_nsec = random (); | ||
196 | |||
197 | #ifdef OPENSSL_SYS_VOS_HPPA | ||
198 | /* sleep for 1/1024 of a second (976 us). */ | ||
199 | duration = 1; | ||
200 | s$sleep (&duration, &code); | ||
201 | #else | ||
202 | #ifdef OPENSSL_SYS_VOS_IA32 | ||
203 | /* sleep for 1/65536 of a second (15 us). */ | ||
204 | duration = 1; | ||
205 | s$sleep2 (&duration, &code); | ||
206 | #endif /* OPENSSL_SYS_VOS_IA32 */ | ||
207 | #endif /* OPENSSL_SYS_VOS_HPPA */ | ||
208 | |||
209 | /* get wall clock time. */ | ||
210 | clock_gettime (CLOCK_REALTIME, &ts); | ||
211 | 167 | ||
212 | /* take 8 bits */ | 168 | for (i = 0; i < sizeof(buf); i++) { |
213 | v = (unsigned char) (ts.tv_nsec % 256); | 169 | if (i % 4 == 0) |
214 | RAND_add (&v, sizeof v, 1); | 170 | rnd = random(); |
215 | v = 0; | 171 | buf[i] = rnd; |
172 | rnd >>= 8; | ||
216 | } | 173 | } |
174 | RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); | ||
175 | memset(buf, 0, sizeof(buf)); | ||
176 | |||
217 | return 1; | 177 | return 1; |
218 | } | 178 | } |
219 | #elif defined __OpenBSD__ | 179 | #elif defined __OpenBSD__ |
220 | int RAND_poll(void) | 180 | int RAND_poll(void) |
221 | { | 181 | { |
222 | u_int32_t rnd = 0, i; | ||
223 | unsigned char buf[ENTROPY_NEEDED]; | 182 | unsigned char buf[ENTROPY_NEEDED]; |
224 | 183 | ||
225 | for (i = 0; i < sizeof(buf); i++) { | 184 | arc4random_buf(buf, sizeof(buf)); |
226 | if (i % 4 == 0) | 185 | RAND_add(buf, sizeof(buf), sizeof(buf)); |
227 | rnd = arc4random(); | ||
228 | buf[i] = rnd; | ||
229 | rnd >>= 8; | ||
230 | } | ||
231 | RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); | ||
232 | memset(buf, 0, sizeof(buf)); | 186 | memset(buf, 0, sizeof(buf)); |
233 | 187 | ||
234 | return 1; | 188 | return 1; |