summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/random.c
diff options
context:
space:
mode:
authorotto <>2005-11-30 07:51:02 +0000
committerotto <>2005-11-30 07:51:02 +0000
commitf8452f05564b5820c3745b9348d85a2b3a745467 (patch)
tree803b53c012ae878cdf973f67d5346e2452f9e177 /src/lib/libc/stdlib/random.c
parent75ccbec66ef4157baa8c840a64a98a73287280fb (diff)
downloadopenbsd-f8452f05564b5820c3745b9348d85a2b3a745467.tar.gz
openbsd-f8452f05564b5820c3745b9348d85a2b3a745467.tar.bz2
openbsd-f8452f05564b5820c3745b9348d85a2b3a745467.zip
Use sysctl(KERN_ARND) to get n bytes, instead of just 4 at a time
and remove fallback code. If somebody is dumb enough to make the sysctl fail using systrace, he deserves what he gets. Saves 7 syscalls on process startup. looks good miod@ ok deraadt@ tedu@
Diffstat (limited to 'src/lib/libc/stdlib/random.c')
-rw-r--r--src/lib/libc/stdlib/random.c49
1 files changed, 11 insertions, 38 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 565542ecdb..48e892042b 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: random.c,v 1.14 2005/08/08 08:05:37 espie Exp $ */ 1/* $OpenBSD: random.c,v 1.15 2005/11/30 07:51:02 otto Exp $ */
2/* 2/*
3 * Copyright (c) 1983 Regents of the University of California. 3 * Copyright (c) 1983 Regents of the University of California.
4 * All rights reserved. 4 * All rights reserved.
@@ -220,17 +220,17 @@ srandom(unsigned int x)
220 * srandomdev: 220 * srandomdev:
221 * 221 *
222 * Many programs choose the seed value in a totally predictable manner. 222 * Many programs choose the seed value in a totally predictable manner.
223 * This often causes problems. We seed the generator using the much more 223 * This often causes problems. We seed the generator using random
224 * secure arandom(4) interface. Note that this particular seeding 224 * data from the kernel.
225 * procedure can generate states which are impossible to reproduce by 225 * Note that this particular seeding procedure can generate states
226 * calling srandom() with any value, since the succeeding terms in the 226 * which are impossible to reproduce by calling srandom() with any
227 * state buffer are no longer derived from the LC algorithm applied to 227 * value, since the succeeding terms in the state buffer are no longer
228 * a fixed seed. 228 * derived from the LC algorithm applied to a fixed seed.
229 */ 229 */
230void 230void
231srandomdev(void) 231srandomdev(void)
232{ 232{
233 int fd, i, mib[2], n; 233 int mib[2];
234 size_t len; 234 size_t len;
235 235
236 if (rand_type == TYPE_0) 236 if (rand_type == TYPE_0)
@@ -238,36 +238,9 @@ srandomdev(void)
238 else 238 else
239 len = rand_deg * sizeof(state[0]); 239 len = rand_deg * sizeof(state[0]);
240 240
241 /* 241 mib[0] = CTL_KERN;
242 * To get seed data, first try reading from /dev/arandom. 242 mib[1] = KERN_ARND;
243 * If that fails, try the KERN_ARND sysctl() (one int at a time). 243 sysctl(mib, 2, state, &len, NULL, 0);
244 * As a last resort, call srandom().
245 */
246 if ((fd = open("/dev/arandom", O_RDONLY, 0)) != -1 &&
247 read(fd, (void *) state, len) == (ssize_t) len) {
248 close(fd);
249 } else {
250 if (fd != -1)
251 close(fd);
252 mib[0] = CTL_KERN;
253 mib[1] = KERN_ARND;
254 n = len / sizeof(int);
255 len = sizeof(int);
256 for (i = 0; i < n; i++) {
257 if (sysctl(mib, 2, (char *)((int *)state + i), &len,
258 NULL, 0) == -1)
259 break;
260 }
261 if (i != n) {
262 struct timeval tv;
263 u_int junk;
264
265 /* XXX - this could be better */
266 gettimeofday(&tv, NULL);
267 srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
268 return;
269 }
270 }
271 244
272 if (rand_type != TYPE_0) { 245 if (rand_type != TYPE_0) {
273 fptr = &state[rand_sep]; 246 fptr = &state[rand_sep];