1 /* Generate buffers of random data.
3 Copyright (C) 2006 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 /* Written by Paul Eggert. */
36 #define _(msgid) gettext (msgid)
38 #include "rand-isaac.h"
39 #include "stdio-safer.h"
40 #include "unlocked-io.h"
44 # define MIN(a, b) ((a) < (b) ? (a) : (b))
47 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
48 # define __attribute__(x)
51 #ifndef ATTRIBUTE_UNUSED
52 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
55 #if _STRING_ARCH_unaligned
56 # define ALIGNED_POINTER(ptr, type) true
58 # define alignof(type) offsetof (struct { char c; type x; }, x)
59 # define ALIGNED_POINTER(ptr, type) ((size_t) (ptr) % alignof (type) == 0)
62 #ifndef DEFAULT_RANDOM_FILE
63 # define DEFAULT_RANDOM_FILE "/dev/urandom"
66 /* The maximum buffer size used for reads of random data. Using the
67 value 2 * ISAAC_BYTES makes this the largest power of two that
68 would not otherwise cause struct randread_source to grow. */
69 #define RANDREAD_BUFFER_SIZE (2 * ISAAC_BYTES)
71 /* A source of random data for generating random buffers. */
72 struct randread_source
74 /* Stream to read random bytes from. If null, the behavior is
75 undefined; the current implementation uses ISAAC in this case,
76 but this is for old-fashioned implementations that lack
77 /dev/urandom and callers should not rely on this. */
80 /* Function to call, and its argument, if there is an input error or
81 end of file when reading from the stream; errno is nonzero if
82 there was an error. If this function returns, it should fix the
83 problem before returning. The default handler assumes that
84 handler_arg is the file name of the source. */
85 void (*handler
) (void const *);
86 void const *handler_arg
;
88 /* The buffer for SOURCE. It's kept here to simplify storage
89 allocation and to make it easier to clear out buffered random
93 /* The stream buffer, if SOURCE is not null. */
94 char c
[RANDREAD_BUFFER_SIZE
];
96 /* The buffered ISAAC pseudorandom buffer, if SOURCE is null. */
99 /* The number of bytes that are buffered at the end of data.b. */
102 /* State of the ISAAC generator. */
103 struct isaac_state state
;
105 /* Up to a buffer's worth of pseudorandom data. */
108 uint32_t w
[ISAAC_WORDS
];
109 unsigned char b
[ISAAC_BYTES
];
116 /* The default error handler. */
119 randread_error (void const *file_name
)
122 error (exit_failure
, errno
,
123 _(errno
== 0 ? "%s: end of file" : "%s: read error"),
124 quotearg_colon (file_name
));
128 /* Simply return a new randread_source object with the default error
131 static struct randread_source
*
132 simple_new (FILE *source
, void const *handler_arg
)
134 struct randread_source
*s
= xmalloc (sizeof *s
);
136 s
->handler
= randread_error
;
137 s
->handler_arg
= handler_arg
;
141 /* Create and initialize a random data source from NAME, or use a
142 reasonable default source if NAME is null. BYTES_BOUND is an upper
143 bound on the number of bytes that will be needed. If zero, it is a
144 hard bound; otherwise it is just an estimate.
146 If NAME is not null, NAME is saved for use as the argument of the
147 default handler. Unless a non-default handler is used, NAME's
148 lifetime should be at least that of the returned value.
150 Return NULL (setting errno) on failure. */
152 struct randread_source
*
153 randread_new (char const *name
, size_t bytes_bound
)
155 if (bytes_bound
== 0)
156 return simple_new (NULL
, NULL
);
159 char const *file_name
= (name
? name
: DEFAULT_RANDOM_FILE
);
160 FILE *source
= fopen_safer (file_name
, "rb");
161 struct randread_source
*s
;
170 s
= simple_new (source
, file_name
);
173 setvbuf (source
, s
->buf
.c
, _IOFBF
, MIN (sizeof s
->buf
.c
, bytes_bound
));
176 s
->buf
.isaac
.buffered
= 0;
177 isaac_seed (&s
->buf
.isaac
.state
);
185 /* Set S's handler and its argument. HANDLER (HANDLER_ARG) is called
186 when there is a read error or end of file from the random data
187 source; errno is nonzero if there was an error. If HANDLER
188 returns, it should fix the problem before returning. The default
189 handler assumes that handler_arg is the file name of the source; it
193 randread_set_handler (struct randread_source
*s
, void (*handler
) (void const *))
195 s
->handler
= handler
;
199 randread_set_handler_arg (struct randread_source
*s
, void const *handler_arg
)
201 s
->handler_arg
= handler_arg
;
205 /* Place SIZE random bytes into the buffer beginning at P, using
209 readsource (struct randread_source
*s
, unsigned char *p
, size_t size
)
213 size_t inbytes
= fread (p
, sizeof *p
, size
, s
->source
);
214 int fread_errno
= errno
;
219 errno
= (ferror (s
->source
) ? fread_errno
: 0);
220 s
->handler (s
->handler_arg
);
225 /* Place SIZE pseudorandom bytes into the buffer beginning at P, using
226 the buffered ISAAC generator in ISAAC. */
229 readisaac (struct isaac
*isaac
, unsigned char *p
, size_t size
)
231 size_t inbytes
= isaac
->buffered
;
237 memcpy (p
, isaac
->data
.b
+ ISAAC_BYTES
- inbytes
, size
);
238 isaac
->buffered
= inbytes
- size
;
242 memcpy (p
, isaac
->data
.b
+ ISAAC_BYTES
- inbytes
, inbytes
);
246 /* If P is aligned, write to *P directly to avoid the overhead
247 of copying from the buffer. */
248 if (ALIGNED_POINTER (p
, uint32_t))
250 uint32_t *wp
= (uint32_t *) p
;
251 while (ISAAC_BYTES
<= size
)
253 isaac_refill (&isaac
->state
, wp
);
262 p
= (unsigned char *) wp
;
265 isaac_refill (&isaac
->state
, isaac
->data
.w
);
266 inbytes
= ISAAC_BYTES
;
271 /* Consume random data from *S to generate a random buffer BUF of size
275 randread (struct randread_source
*s
, void *buf
, size_t size
)
278 readsource (s
, buf
, size
);
280 readisaac (&s
->buf
.isaac
, buf
, size
);
284 /* Clear *S so that it no longer contains undelivered random data, and
285 deallocate any system resources associated with *S. Return 0 if
286 successful, a negative number (setting errno) if not (this is rare,
287 but can occur in theory if there is an input error). */
290 randread_free (struct randread_source
*s
)
292 FILE *source
= s
->source
;
293 memset (s
, 0, sizeof *s
);
295 return (source
? fclose (source
) : 0);