From dcf31cdc994163b3ee5641545ae8706f3c10182f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 18 Mar 2016 14:46:20 +0100 Subject: [PATCH] Implement getentropy for Cygwin * miscfuncs.cc (getentropy): Move fhandler_dev_random::crypt_gen_random here and rename to getentropy. Fix type and return values to match getentropy requirements. * miscfuncs.h (getentropy): Add prototype. * fhandler.h (fhandler_dev_random::crypt_gen_random): Remove prototype. * fhandler_random.cc (fhandler_dev_random::crypt_gen_random): Drop. (fhandler_dev_random::write): Use getentropy instead. (fhandler_dev_random::read): Ditto. * fhandler_socket.cc (fhandler_socket::af_local_set_secret): Ditto. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 2 -- winsup/cygwin/fhandler_random.cc | 31 +++++-------------------------- winsup/cygwin/fhandler_socket.cc | 3 +-- winsup/cygwin/miscfuncs.cc | 19 +++++++++++++++++++ winsup/cygwin/miscfuncs.h | 2 ++ 5 files changed, 27 insertions(+), 30 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 1c1862b59..4b8efee46 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1731,8 +1731,6 @@ class fhandler_dev_random: public fhandler_base void __reg3 read (void *ptr, size_t& len); off_t lseek (off_t, int) { return 0; } - static bool crypt_gen_random (void *ptr, size_t len); - fhandler_dev_random () : fhandler_base () {} fhandler_dev_random (void *) {} diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc index 375398296..37bc76e80 100644 --- a/winsup/cygwin/fhandler_random.cc +++ b/winsup/cygwin/fhandler_random.cc @@ -29,23 +29,6 @@ details. */ #define PSEUDO_MULTIPLIER (6364136223846793005LL) #define PSEUDO_SHIFTVAL (21) -/* There's a bug in ntsecapi.h (Mingw as well as MSFT). SystemFunction036 - is, in fact, a WINAPI function, but it's not defined as such. Therefore - we have to do it correctly here. */ -#define RtlGenRandom SystemFunction036 -extern "C" BOOLEAN WINAPI RtlGenRandom (PVOID, ULONG); - -bool -fhandler_dev_random::crypt_gen_random (void *ptr, size_t len) -{ - if (!RtlGenRandom (ptr, len)) - { - debug_printf ("%E = RtlGenRandom()"); - return false; - } - return true; -} - int fhandler_dev_random::pseudo_write (const void *ptr, size_t len) { @@ -73,11 +56,8 @@ fhandler_dev_random::write (const void *ptr, size_t len) memcpy (buf, ptr, limited_len); /* Mess up system entropy source. Return error if device is /dev/random. */ - if (!crypt_gen_random (buf, limited_len) && dev () == FH_RANDOM) - { - __seterrno (); - return -1; - } + if (getentropy (buf, limited_len) && dev () == FH_RANDOM) + return -1; /* Mess up the pseudo random number generator. */ pseudo_write (buf, limited_len); return len; @@ -125,10 +105,9 @@ fhandler_dev_random::read (void *ptr, size_t& len) } for (size_t offset = 0; offset < len; offset += 512) { - if (!crypt_gen_random (dummy, RESEED_INTERVAL) || - !crypt_gen_random ((PBYTE) ptr + offset, len - offset)) + if (getentropy (dummy, RESEED_INTERVAL) || + getentropy ((PBYTE) ptr + offset, len - offset)) { - __seterrno (); len = (size_t) -1; break; } @@ -138,6 +117,6 @@ fhandler_dev_random::read (void *ptr, size_t& len) /* If device is /dev/urandom, just use system RNG as is, with our own PRNG as fallback. */ - else if (!crypt_gen_random (ptr, len)) + else if (getentropy (ptr, len)) len = pseudo_read (ptr, len); } diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 990cdc713..e71954321 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -488,8 +488,7 @@ fhandler_socket::af_local_copy (fhandler_socket *sock) void fhandler_socket::af_local_set_secret (char *buf) { - if (!fhandler_dev_random::crypt_gen_random (connect_secret, - sizeof (connect_secret))) + if (getentropy (connect_secret, sizeof (connect_secret))) bzero ((char*) connect_secret, sizeof (connect_secret)); __small_sprintf (buf, "%08x-%08x-%08x-%08x", connect_secret [0], connect_secret [1], diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index 796494132..54150f106 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -236,6 +236,25 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite) return -1; } +/* There's a bug in ntsecapi.h (Mingw as well as MSFT). SystemFunction036 + is, in fact, a WINAPI function, but it's not defined as such. Therefore + we have to do it correctly here. */ +#define RtlGenRandom SystemFunction036 +extern "C" BOOLEAN WINAPI RtlGenRandom (PVOID, ULONG); + +/* Used by arc2random, fhandler_socket and fhandler_random. */ +extern "C" int +getentropy (void *ptr, size_t len) +{ + if (!RtlGenRandom (ptr, len)) + { + debug_printf ("%E = RtlGenRandom()"); + set_errno (EIO); + return -1; + } + return 0; +} + /* Try hard to schedule another thread. Remember not to call this in a lock condition or you'll potentially suffer starvation. */ diff --git a/winsup/cygwin/miscfuncs.h b/winsup/cygwin/miscfuncs.h index 3a9f0258c..2690e44a9 100644 --- a/winsup/cygwin/miscfuncs.h +++ b/winsup/cygwin/miscfuncs.h @@ -15,6 +15,8 @@ details. */ #define likely(X) __builtin_expect (!!(X), 1) #define unlikely(X) __builtin_expect (!!(X), 0) +extern "C" int getentropy (void *ptr, size_t len); + int __reg1 winprio_to_nice (DWORD); DWORD __reg1 nice_to_winprio (int &);