Initial commit
[authen-passphrase-scrypt.git] / scrypt-1.2.1 / libcperciva / util / entropy.c
CommitLineData
0c1f3509
MG
1#include <errno.h>
2#include <fcntl.h>
3#include <limits.h>
4#include <stdint.h>
5#include <unistd.h>
6
7#include "warnp.h"
8
9#include "entropy.h"
10
11/**
12 * XXX Portability
13 * XXX We obtain random bytes from the operating system by opening
14 * XXX /dev/urandom and reading them from that device; this works on
15 * XXX modern UNIX-like operating systems but not on systems like
16 * XXX win32 where there is no concept of /dev/urandom.
17 */
18
19/**
20 * entropy_read(buf, buflen):
21 * Fill the given buffer with random bytes provided by the operating system.
22 */
23int
24entropy_read(uint8_t * buf, size_t buflen)
25{
26 int fd;
27 ssize_t lenread;
28
29 /* Sanity-check the buffer size. */
30 if (buflen > SSIZE_MAX) {
31 warn0("Programmer error: "
32 "Trying to read insane amount of random data: %zu",
33 buflen);
34 goto err0;
35 }
36
37 /* Open /dev/urandom. */
38 if ((fd = open("/dev/urandom", O_RDONLY)) == -1) {
39 warnp("open(/dev/urandom)");
40 goto err0;
41 }
42
43 /* Read bytes until we have filled the buffer. */
44 while (buflen > 0) {
45 if ((lenread = read(fd, buf, buflen)) == -1) {
46 warnp("read(/dev/urandom)");
47 goto err1;
48 }
49
50 /* The random device should never EOF. */
51 if (lenread == 0) {
52 warn0("EOF on /dev/urandom?");
53 goto err1;
54 }
55
56 /* We've filled a portion of the buffer. */
57 buf += (size_t)lenread;
58 buflen -= (size_t)lenread;
59 }
60
61 /* Close the device. */
62 while (close(fd) == -1) {
63 if (errno != EINTR) {
64 warnp("close(/dev/urandom)");
65 goto err0;
66 }
67 }
68
69 /* Success! */
70 return (0);
71
72err1:
73 close(fd);
74err0:
75 /* Failure! */
76 return (-1);
77}
This page took 0.012613 seconds and 4 git commands to generate.