summaryrefslogtreecommitdiff
path: root/openbsd-compat/arc4random.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat/arc4random.c')
-rw-r--r--openbsd-compat/arc4random.c36
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 */
83static void
84getrnd(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
76static void 106static 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;