diff options
Diffstat (limited to 'openbsd-compat/arc4random.c')
-rw-r--r-- | openbsd-compat/arc4random.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c index 09dbfda16..046f57e61 100644 --- a/openbsd-compat/arc4random.c +++ b/openbsd-compat/arc4random.c | |||
@@ -26,15 +26,19 @@ | |||
26 | 26 | ||
27 | #include "includes.h" | 27 | #include "includes.h" |
28 | 28 | ||
29 | #include <sys/types.h> | ||
30 | |||
31 | #include <fcntl.h> | ||
29 | #include <stdlib.h> | 32 | #include <stdlib.h> |
30 | #include <string.h> | 33 | #include <string.h> |
31 | #include <unistd.h> | 34 | #include <unistd.h> |
32 | #include <sys/types.h> | ||
33 | 35 | ||
34 | #ifndef HAVE_ARC4RANDOM | 36 | #ifndef HAVE_ARC4RANDOM |
35 | 37 | ||
38 | #ifdef WITH_OPENSSL | ||
36 | #include <openssl/rand.h> | 39 | #include <openssl/rand.h> |
37 | #include <openssl/err.h> | 40 | #include <openssl/err.h> |
41 | #endif | ||
38 | 42 | ||
39 | #include "log.h" | 43 | #include "log.h" |
40 | 44 | ||
@@ -73,14 +77,44 @@ _rs_init(u_char *buf, size_t n) | |||
73 | chacha_ivsetup(&rs, buf + KEYSZ); | 77 | chacha_ivsetup(&rs, buf + KEYSZ); |
74 | } | 78 | } |
75 | 79 | ||
80 | #ifndef WITH_OPENSSL | ||
81 | #define SSH_RANDOM_DEV "/dev/urandom" | ||
82 | /* XXX use getrandom() if supported on Linux */ | ||
83 | static void | ||
84 | getrnd(u_char *s, size_t len) | ||
85 | { | ||
86 | int fd; | ||
87 | ssize_t r; | ||
88 | size_t o = 0; | ||
89 | |||
90 | if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) | ||
91 | fatal("Couldn't open %s: %s", SSH_RANDOM_DEV, strerror(errno)); | ||
92 | while (o < len) { | ||
93 | r = read(fd, s + o, len - o); | ||
94 | if (r < 0) { | ||
95 | if (errno == EAGAIN || errno == EINTR || | ||
96 | errno == EWOULDBLOCK) | ||
97 | continue; | ||
98 | fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno)); | ||
99 | } | ||
100 | o += r; | ||
101 | } | ||
102 | close(fd); | ||
103 | } | ||
104 | #endif | ||
105 | |||
76 | static void | 106 | static void |
77 | _rs_stir(void) | 107 | _rs_stir(void) |
78 | { | 108 | { |
79 | u_char rnd[KEYSZ + IVSZ]; | 109 | u_char rnd[KEYSZ + IVSZ]; |
80 | 110 | ||
111 | #ifdef WITH_OPENSSL | ||
81 | if (RAND_bytes(rnd, sizeof(rnd)) <= 0) | 112 | if (RAND_bytes(rnd, sizeof(rnd)) <= 0) |
82 | fatal("Couldn't obtain random bytes (error %ld)", | 113 | fatal("Couldn't obtain random bytes (error %ld)", |
83 | ERR_get_error()); | 114 | ERR_get_error()); |
115 | #else | ||
116 | getrnd(rnd, sizeof(rnd)); | ||
117 | #endif | ||
84 | 118 | ||
85 | if (!rs_initialized) { | 119 | if (!rs_initialized) { |
86 | rs_initialized = 1; | 120 | rs_initialized = 1; |