diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2016-12-16 23:10:19 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2016-12-16 23:10:19 +0100 |
commit | 4e75d7f504b61ef031d14e4283fc5842cf126357 (patch) | |
tree | a138169ee4c393cb4255fcf8296e93f6c4e3dc15 /winsup/cygwin/miscfuncs.cc | |
parent | f46f501471dc3505b0c920a61b14ec9551df40c7 (diff) | |
download | newlib-4e75d7f504b61ef031d14e4283fc5842cf126357.zip newlib-4e75d7f504b61ef031d14e4283fc5842cf126357.tar.gz newlib-4e75d7f504b61ef031d14e4283fc5842cf126357.tar.bz2 |
Export getentropy and getrandom calls
getentropy per OpenBSD
http://man.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
getrandom per Linux
http://man7.org/linux/man-pages/man2/getrandom.2.html
Note that GRND_NONBLOCK is not handled
Diffstat (limited to 'winsup/cygwin/miscfuncs.cc')
-rw-r--r-- | winsup/cygwin/miscfuncs.cc | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index e92ccba..044d727 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -14,6 +14,7 @@ details. */ #include <alloca.h> #include <limits.h> #include <sys/param.h> +#include <sys/random.h> #include <wchar.h> #include "cygtls.h" #include "ntdll.h" @@ -234,19 +235,62 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite) return -1; } -/* Used by arc2random, fhandler_socket and fhandler_random. */ extern "C" int getentropy (void *ptr, size_t len) { - if (!RtlGenRandom (ptr, len)) + /* Per BSD man page: The maximum buffer size permitted is 256 bytes. + If buflen exceeds this, an error of EIO will be indicated. */ + if (len > 256) { - debug_printf ("%E = RtlGenRandom()"); + debug_printf ("len (%U) > 256", len); set_errno (EIO); return -1; } + __try + { + if (!RtlGenRandom (ptr, len)) + { + debug_printf ("RtlGenRandom() = FALSE"); + set_errno (EIO); + return -1; + } + } + __except (EFAULT) + { + return -1; + } + __endtry return 0; } +extern "C" ssize_t +getrandom (void *ptr, size_t len, unsigned int flags) +{ + if (flags & ~(GRND_NONBLOCK | GRND_RANDOM)) + { + debug_printf ("invalid flags: %y", flags); + set_errno (EINVAL); + return -1; + } + /* Max. bytes returned by Linux call. */ + len = MAX (len, (flags & GRND_RANDOM) ? 512 : 33554431); + __try + { + if (!RtlGenRandom (ptr, len)) + { + debug_printf ("RtlGenRandom() = FALSE"); + set_errno (EIO); + return -1; + } + } + __except (EFAULT) + { + return -1; + } + __endtry + return len; +} + /* Try hard to schedule another thread. Remember not to call this in a lock condition or you'll potentially suffer starvation. */ |