Rearrange RNG code slightly
In preparation of exporting getentropy/getrandom to userspace, rearrange code a bit: - Define RtlGenRandom in ntdll.h. - Drop calls to getentropy in favor of RtlGenRandom (fhandler_socket, fhandler_dev_random). - Add try/except blocks in fhandler_dev_random to return EFAULT rather than crashing if buffer pointer is invalid. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
80f4987f02
commit
74f7872f89
|
@ -47,16 +47,26 @@ fhandler_dev_random::write (const void *ptr, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Limit len to a value <= 4096 since we don't want to overact.
|
/* Limit len to a value <= 4096 since we don't want to overact.
|
||||||
Copy to local buffer because CryptGenRandom violates const. */
|
Copy to local buffer because RtlGenRandom violates const. */
|
||||||
size_t limited_len = MIN (len, 4096);
|
size_t limited_len = MIN (len, 4096);
|
||||||
unsigned char buf[limited_len];
|
unsigned char buf[limited_len];
|
||||||
memcpy (buf, ptr, limited_len);
|
|
||||||
|
|
||||||
/* Mess up system entropy source. Return error if device is /dev/random. */
|
/* Mess up system entropy source. Return error if device is /dev/random. */
|
||||||
if (getentropy (buf, limited_len) && dev () == FH_RANDOM)
|
__try
|
||||||
|
{
|
||||||
|
memcpy (buf, ptr, limited_len);
|
||||||
|
if (!RtlGenRandom (buf, limited_len) && dev () == FH_RANDOM)
|
||||||
return -1;
|
return -1;
|
||||||
/* Mess up the pseudo random number generator. */
|
/* Mess up the pseudo random number generator. */
|
||||||
pseudo_write (buf, limited_len);
|
pseudo_write (buf, limited_len);
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
{
|
||||||
|
len = -1;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
|
/* Note that we return len, not limited_len. No reason to confuse the
|
||||||
|
caller... */
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +98,8 @@ fhandler_dev_random::read (void *ptr, size_t& len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
/* /dev/random has to provide high quality random numbers. Therefore we
|
/* /dev/random has to provide high quality random numbers. Therefore we
|
||||||
re-seed the system PRNG for each block of 512 bytes. This results in
|
re-seed the system PRNG for each block of 512 bytes. This results in
|
||||||
sufficiently random sequences, comparable to the Linux /dev/random. */
|
sufficiently random sequences, comparable to the Linux /dev/random. */
|
||||||
|
@ -102,8 +114,8 @@ fhandler_dev_random::read (void *ptr, size_t& len)
|
||||||
}
|
}
|
||||||
for (size_t offset = 0; offset < len; offset += 512)
|
for (size_t offset = 0; offset < len; offset += 512)
|
||||||
{
|
{
|
||||||
if (getentropy (dummy, RESEED_INTERVAL) ||
|
if (!RtlGenRandom (dummy, RESEED_INTERVAL) ||
|
||||||
getentropy ((PBYTE) ptr + offset, len - offset))
|
!RtlGenRandom ((PBYTE) ptr + offset, len - offset))
|
||||||
{
|
{
|
||||||
len = (size_t) -1;
|
len = (size_t) -1;
|
||||||
break;
|
break;
|
||||||
|
@ -114,6 +126,12 @@ fhandler_dev_random::read (void *ptr, size_t& len)
|
||||||
|
|
||||||
/* If device is /dev/urandom, just use system RNG as is, with our own
|
/* If device is /dev/urandom, just use system RNG as is, with our own
|
||||||
PRNG as fallback. */
|
PRNG as fallback. */
|
||||||
else if (getentropy (ptr, len))
|
else if (!RtlGenRandom (ptr, len))
|
||||||
len = pseudo_read (ptr, len);
|
len = pseudo_read (ptr, len);
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
{
|
||||||
|
len = (size_t) -1;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,7 +485,7 @@ fhandler_socket::af_local_copy (fhandler_socket *sock)
|
||||||
void
|
void
|
||||||
fhandler_socket::af_local_set_secret (char *buf)
|
fhandler_socket::af_local_set_secret (char *buf)
|
||||||
{
|
{
|
||||||
if (getentropy (connect_secret, sizeof (connect_secret)))
|
if (!RtlGenRandom (connect_secret, sizeof (connect_secret)))
|
||||||
bzero ((char*) connect_secret, sizeof (connect_secret));
|
bzero ((char*) connect_secret, sizeof (connect_secret));
|
||||||
__small_sprintf (buf, "%08x-%08x-%08x-%08x",
|
__small_sprintf (buf, "%08x-%08x-%08x-%08x",
|
||||||
connect_secret [0], connect_secret [1],
|
connect_secret [0], connect_secret [1],
|
||||||
|
|
|
@ -233,12 +233,6 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
|
||||||
return -1;
|
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. */
|
/* Used by arc2random, fhandler_socket and fhandler_random. */
|
||||||
extern "C" int
|
extern "C" int
|
||||||
getentropy (void *ptr, size_t len)
|
getentropy (void *ptr, size_t len)
|
||||||
|
|
|
@ -1608,4 +1608,10 @@ extern "C"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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. *Strictly*, this is not ntdll... */
|
||||||
|
#define RtlGenRandom SystemFunction036
|
||||||
|
extern "C" BOOLEAN WINAPI RtlGenRandom (PVOID, ULONG);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue