1 /* Generate buffers of random data.
3 Copyright (C) 2006-2023 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 3 of the License, or
8 (at your option) any later version.
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, see <https://www.gnu.org/licenses/>. */
18 /* Written by Paul Eggert. */
20 /* FIXME: Improve performance by adding support for the RDRAND machine
21 instruction if available (e.g., Ivy Bridge processors). */
36 #include <sys/random.h>
39 #define _(msgid) gettext (msgid)
43 #include "rand-isaac.h"
44 #include "stdio-safer.h"
45 #include "unlocked-io.h"
48 #if _STRING_ARCH_unaligned || _STRING_INLINE_unaligned
49 # define ALIGNED_POINTER(ptr, type) true
51 # define ALIGNED_POINTER(ptr, type) ((size_t) (ptr) % alignof (type) == 0)
54 /* The maximum buffer size used for reads of random data. Using the
55 value 2 * ISAAC_BYTES makes this the largest power of two that
56 would not otherwise cause struct randread_source to grow. */
57 #define RANDREAD_BUFFER_SIZE (2 * ISAAC_BYTES)
59 /* A source of random data for generating random buffers. */
60 struct randread_source
62 /* Stream to read random bytes from. If null, the current
63 implementation uses an internal PRNG (ISAAC). */
66 /* Function to call, and its argument, if there is an input error or
67 end of file when reading from the stream; errno is nonzero if
68 there was an error. If this function returns, it should fix the
69 problem before returning. The default handler assumes that
70 handler_arg is the file name of the source. */
71 void (*handler
) (void const *);
72 void const *handler_arg
;
74 /* The buffer for SOURCE. It's kept here to simplify storage
75 allocation and to make it easier to clear out buffered random
79 /* The stream buffer, if SOURCE is not null. */
80 char c
[RANDREAD_BUFFER_SIZE
];
82 /* The buffered ISAAC pseudorandom buffer, if SOURCE is null. */
85 /* The number of bytes that are buffered at the end of data.b. */
88 /* State of the ISAAC generator. */
89 struct isaac_state state
;
91 /* Up to a buffer's worth of pseudorandom data. */
94 isaac_word w
[ISAAC_WORDS
];
95 unsigned char b
[ISAAC_BYTES
];
102 /* The default error handler. */
105 randread_error (void const *file_name
)
107 affirm (exit_failure
);
108 error (exit_failure
, errno
,
109 errno
== 0 ? _("%s: end of file") : _("%s: read error"),
113 /* Simply return a new randread_source object with the default error
116 static struct randread_source
*
117 simple_new (FILE *source
, void const *handler_arg
)
119 struct randread_source
*s
= xmalloc (sizeof *s
);
121 s
->handler
= randread_error
;
122 s
->handler_arg
= handler_arg
;
126 /* Put a nonce value into BUFFER, with size BUFSIZE.
127 Return true on success, false (setting errno) on failure. */
130 get_nonce (void *buffer
, size_t bufsize
)
132 char *buf
= buffer
, *buflim
= buf
+ bufsize
;
136 # define MAX_GETRANDOM 1024
138 # define MAX_GETRANDOM SIZE_MAX
140 size_t max_bytes
= MIN (buflim
- buf
, MAX_GETRANDOM
);
141 ssize_t nbytes
= getrandom (buf
, max_bytes
, 0);
144 else if (errno
!= EINTR
)
150 /* Body of randread_free, broken out to pacify gcc -Wmismatched-dealloc. */
153 randread_free_body (struct randread_source
*s
)
155 FILE *source
= s
->source
;
156 explicit_bzero (s
, sizeof *s
);
158 return source
? fclose (source
) : 0;
161 /* Create and initialize a random data source from NAME, or use a
162 reasonable default source if NAME is null. BYTES_BOUND is an upper
163 bound on the number of bytes that will be needed. If zero, it is a
164 hard bound; otherwise it is just an estimate.
166 If NAME is not null, NAME is saved for use as the argument of the
167 default handler. Unless a non-default handler is used, NAME's
168 lifetime should be at least that of the returned value.
170 Return nullptr (setting errno) on failure. */
172 struct randread_source
*
173 randread_new (char const *name
, size_t bytes_bound
)
175 if (bytes_bound
== 0)
176 return simple_new (nullptr, nullptr);
179 FILE *source
= nullptr;
180 struct randread_source
*s
;
183 if (! (source
= fopen_safer (name
, "rb")))
186 s
= simple_new (source
, name
);
189 setvbuf (source
, s
->buf
.c
, _IOFBF
, MIN (sizeof s
->buf
.c
, bytes_bound
));
192 s
->buf
.isaac
.buffered
= 0;
193 if (! get_nonce (s
->buf
.isaac
.state
.m
,
194 MIN (sizeof s
->buf
.isaac
.state
.m
, bytes_bound
)))
197 randread_free_body (s
);
201 isaac_seed (&s
->buf
.isaac
.state
);
209 /* Set S's handler and its argument. HANDLER (HANDLER_ARG) is called
210 when there is a read error or end of file from the random data
211 source; errno is nonzero if there was an error. If HANDLER
212 returns, it should fix the problem before returning. The default
213 handler assumes that handler_arg is the file name of the source; it
217 randread_set_handler (struct randread_source
*s
, void (*handler
) (void const *))
219 s
->handler
= handler
;
223 randread_set_handler_arg (struct randread_source
*s
, void const *handler_arg
)
225 s
->handler_arg
= handler_arg
;
229 /* Place SIZE random bytes into the buffer beginning at P, using
233 readsource (struct randread_source
*s
, unsigned char *p
, size_t size
)
237 size_t inbytes
= fread (p
, sizeof *p
, size
, s
->source
);
238 int fread_errno
= errno
;
243 errno
= (ferror (s
->source
) ? fread_errno
: 0);
244 s
->handler (s
->handler_arg
);
249 /* Place SIZE pseudorandom bytes into the buffer beginning at P, using
250 the buffered ISAAC generator in ISAAC. */
253 readisaac (struct isaac
*isaac
, void *p
, size_t size
)
255 size_t inbytes
= isaac
->buffered
;
263 memcpy (p
, isaac
->data
.b
+ ISAAC_BYTES
- inbytes
, size
);
264 isaac
->buffered
= inbytes
- size
;
268 memcpy (p
, isaac
->data
.b
+ ISAAC_BYTES
- inbytes
, inbytes
);
269 p
= char_p
+ inbytes
;
272 /* If P is aligned, write to *P directly to avoid the overhead
273 of copying from the buffer. */
274 if (ALIGNED_POINTER (p
, isaac_word
))
277 while (ISAAC_BYTES
<= size
)
279 isaac_refill (&isaac
->state
, wp
);
291 isaac_refill (&isaac
->state
, isaac
->data
.w
);
292 inbytes
= ISAAC_BYTES
;
297 /* Consume random data from *S to generate a random buffer BUF of size
301 randread (struct randread_source
*s
, void *buf
, size_t size
)
304 readsource (s
, buf
, size
);
306 readisaac (&s
->buf
.isaac
, buf
, size
);
310 /* Clear *S so that it no longer contains undelivered random data, and
311 deallocate any system resources associated with *S. Return 0 if
312 successful, a negative number (setting errno) if not (this is rare,
313 but can occur in theory if there is an input error). */
316 randread_free (struct randread_source
*s
)
318 return randread_free_body (s
);