summaryrefslogtreecommitdiff
path: root/src/lib/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/random.c')
-rw-r--r--src/lib/random.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/lib/random.c b/src/lib/random.c
index 96315132..a132f470 100644
--- a/src/lib/random.c
+++ b/src/lib/random.c
@@ -28,6 +28,8 @@
#include <stdlib.h>
#elif defined(HAVE_SYS_RANDOM)
#include <sys/random.h>
+#include <errno.h>
+#include <stdint.h>
#elif defined(HAVE_LIBGCRYPT)
#include <gcrypt.h>
#elif defined(HAVE_OPENSSL_RNG)
@@ -42,13 +44,28 @@ int random_buffer(void * buf,
arc4random_buf(buf, len);
return 0;
#elif defined(HAVE_SYS_RANDOM)
- return getrandom(buf, len, GRND_NONBLOCK);
+ size_t off = 0;
+ ssize_t ret;
+
+ while (off < len) {
+ ret = getrandom((uint8_t *) buf + off, len - off,
+ GRND_NONBLOCK);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ return -1;
+ }
+ off += (size_t) ret;
+ }
+
+ return 0;
#elif defined(HAVE_LIBGCRYPT)
gcry_randomize(buf, len, GCRY_STRONG_RANDOM);
return 0;
#elif defined(HAVE_OPENSSL_RNG)
- if (len > 0 && len < INT_MAX)
- return RAND_bytes((unsigned char *) buf, (int) len);
- return -1;
+ if (len == 0 || len >= INT_MAX)
+ return -1;
+
+ return RAND_bytes((unsigned char *) buf, (int) len) == 1 ? 0 : -1;
#endif
}