Skip to content

Commit 3064dd8

Browse files
committed
[libcxx] Use Fuchsia-native CPRNG for std::random_device
Use the zx_cprng_draw system call directly rather than going through the libc getentropy function. The libc function is a trivial wrapper around the system call, and is not a standard C function. Avoiding it reduces the Fuchsia libc ABI surface that libc++ depends on. Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D116498
1 parent 1e50d06 commit 3064dd8

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

libcxx/include/__config

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,12 @@
354354
// When this option is used, the token passed to `std::random_device`'s
355355
// constructor *must* be "/dev/urandom" -- anything else is an error.
356356
//
357+
// _LIBCPP_USING_FUCHSIA_CPRNG
358+
// Use Fuchsia's zx_cprng_draw() system call, which is specified to
359+
// deliver high-quality entropy and cannot fail.
360+
// When this option is used, the token passed to `std::random_device`'s
361+
// constructor *must* be "/dev/urandom" -- anything else is an error.
362+
//
357363
// _LIBCPP_USING_NACL_RANDOM
358364
// NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access,
359365
// including accesses to the special files under `/dev`. This implementation
@@ -367,8 +373,10 @@
367373
// constructor *must* be "/dev/urandom" -- anything else is an error.
368374
#if defined(__OpenBSD__)
369375
# define _LIBCPP_USING_ARC4_RANDOM
370-
#elif defined(__Fuchsia__) || defined(__wasi__)
376+
#elif defined(__wasi__)
371377
# define _LIBCPP_USING_GETENTROPY
378+
#elif defined(__Fuchsia__)
379+
# define _LIBCPP_USING_FUCHSIA_CPRNG
372380
#elif defined(__native_client__)
373381
# define _LIBCPP_USING_NACL_RANDOM
374382
#elif defined(_LIBCPP_WIN32API)

libcxx/src/random.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
# endif
3737
#elif defined(_LIBCPP_USING_NACL_RANDOM)
3838
# include <nacl/nacl_random.h>
39+
#elif defined(_LIBCPP_USING_FUCHSIA_CPRNG)
40+
# include <zircon/syscalls.h>
3941
#endif
4042

4143

@@ -170,6 +172,27 @@ random_device::operator()()
170172
return r;
171173
}
172174

175+
#elif defined(_LIBCPP_USING_FUCHSIA_CPRNG)
176+
177+
random_device::random_device(const string& __token) {
178+
if (__token != "/dev/urandom")
179+
__throw_system_error(ENOENT, ("random device not supported " + __token).c_str());
180+
}
181+
182+
random_device::~random_device() {}
183+
184+
unsigned random_device::operator()() {
185+
// Implicitly link against the vDSO system call ABI without
186+
// requiring the final link to specify -lzircon explicitly when
187+
// statically linking libc++.
188+
# pragma comment(lib, "zircon")
189+
190+
// The system call cannot fail. It returns only when the bits are ready.
191+
unsigned r;
192+
_zx_cprng_draw(&r, sizeof(r));
193+
return r;
194+
}
195+
173196
#else
174197
#error "Random device not implemented for this architecture"
175198
#endif
@@ -189,7 +212,7 @@ random_device::entropy() const noexcept
189212
return std::numeric_limits<result_type>::digits;
190213

191214
return ent;
192-
#elif defined(__OpenBSD__)
215+
#elif defined(__OpenBSD__) || defined(_LIBCPP_USING_FUCHSIA_CPRNG)
193216
return std::numeric_limits<result_type>::digits;
194217
#else
195218
return 0;

0 commit comments

Comments
 (0)