[libc++] Use ioctl when available to get random_device entropy.

Implemented the idea from D94571 to improve entropy on Linux.

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D94953
This commit is contained in:
Marek Kurdej 2021-01-21 17:55:19 +01:00
parent 266820be35
commit f3b979b65e
2 changed files with 25 additions and 5 deletions

View File

@ -13,6 +13,7 @@
#define _CRT_RAND_S
#endif // defined(_LIBCPP_USING_WIN32_RANDOM)
#include "limits"
#include "random"
#include "system_error"
@ -29,6 +30,10 @@
#elif defined(_LIBCPP_USING_DEV_RANDOM)
#include <fcntl.h>
#include <unistd.h>
#if __has_include(<sys/ioctl.h>) && __has_include(<linux/random.h>)
#include <sys/ioctl.h>
#include <linux/random.h>
#endif
#elif defined(_LIBCPP_USING_NACL_RANDOM)
#include <nacl/nacl_random.h>
#endif
@ -172,7 +177,21 @@ random_device::operator()()
double
random_device::entropy() const _NOEXCEPT
{
#if defined(_LIBCPP_USING_DEV_RANDOM) && defined(RNDGETENTCNT)
int ent;
if (::ioctl(__f_, RNDGETENTCNT, &ent) < 0)
return 0;
if (ent < 0)
return 0;
if (ent > std::numeric_limits<result_type>::digits)
return std::numeric_limits<result_type>::digits;
return ent;
#else
return 0;
#endif
}
_LIBCPP_END_NAMESPACE_STD

View File

@ -16,14 +16,15 @@
#include <random>
#include <cassert>
#include <climits>
#include "test_macros.h"
int main(int, char**)
{
std::random_device r;
double e = r.entropy();
((void)e); // Prevent unused warning
int main(int, char**) {
std::random_device r;
double e = r.entropy();
assert(e >= 0);
assert(e <= sizeof(typename std::random_device::result_type) * CHAR_BIT);
return 0;
}