[libcxx-commits] [PATCH] D116498: [libcxx] Use Fuchsia-native CPRNG for std::random_device

Roland McGrath via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jan 2 11:54:10 PST 2022


mcgrathr created this revision.
mcgrathr added a reviewer: phosek.
Herald added subscribers: abrachet, krytarowski.
mcgrathr requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116498

Files:
  libcxx/include/__config
  libcxx/src/random.cpp


Index: libcxx/src/random.cpp
===================================================================
--- libcxx/src/random.cpp
+++ libcxx/src/random.cpp
@@ -36,6 +36,8 @@
 #   endif
 #elif defined(_LIBCPP_USING_NACL_RANDOM)
 #   include <nacl/nacl_random.h>
+#elif defined(_LIBCPP_USING_FUCHSIA_CPRNG)
+#  include <zircon/syscalls.h>
 #endif
 
 
@@ -170,6 +172,27 @@
     return r;
 }
 
+#elif defined(_LIBCPP_USING_FUCHSIA_CPRNG)
+
+random_device::random_device(const string& __token) {
+  if (__token != "/dev/urandom")
+    __throw_system_error(ENOENT, ("random device not supported " + __token).c_str());
+}
+
+random_device::~random_device() {}
+
+unsigned random_device::operator()() {
+  // Implicitly link against the vDSO system call ABI without
+  // requiring the final link to specify -lzircon explicitly when
+  // statically linking libc++.
+#  pragma comment(lib, "zircon")
+
+  // The system call cannot fail.  It returns only when the bits are ready.
+  unsigned r;
+  _zx_cprng_draw(&r, sizeof(r));
+  return r;
+}
+
 #else
 #error "Random device not implemented for this architecture"
 #endif
@@ -189,7 +212,7 @@
     return std::numeric_limits<result_type>::digits;
 
   return ent;
-#elif defined(__OpenBSD__)
+#elif defined(__OpenBSD__) || defined(_LIBCPP_USING_FUCHSIA_CPRNG)
   return std::numeric_limits<result_type>::digits;
 #else
   return 0;
Index: libcxx/include/__config
===================================================================
--- libcxx/include/__config
+++ libcxx/include/__config
@@ -354,6 +354,12 @@
 //      When this option is used, the token passed to `std::random_device`'s
 //      constructor *must* be "/dev/urandom" -- anything else is an error.
 //
+// _LIBCPP_USING_FUCHSIA_CPRNG
+//      Use Fuchsia's zx_cprng_draw() system call, which is specified to
+//      deliver high-quality entropy and cannot fail.
+//      When this option is used, the token passed to `std::random_device`'s
+//      constructor *must* be "/dev/urandom" -- anything else is an error.
+//
 // _LIBCPP_USING_NACL_RANDOM
 //      NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access,
 //      including accesses to the special files under `/dev`. This implementation
@@ -367,8 +373,10 @@
 //      constructor *must* be "/dev/urandom" -- anything else is an error.
 #if defined(__OpenBSD__)
 #  define _LIBCPP_USING_ARC4_RANDOM
-#elif defined(__Fuchsia__) || defined(__wasi__)
+#elif defined(__wasi__)
 #  define _LIBCPP_USING_GETENTROPY
+#elif defined(__Fuchsia__)
+#  define _LIBCPP_USING_FUCHSIA_CPRNG
 #elif defined(__native_client__)
 #  define _LIBCPP_USING_NACL_RANDOM
 #elif defined(_LIBCPP_WIN32API)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D116498.396943.patch
Type: text/x-patch
Size: 2658 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220102/e5067fe7/attachment-0001.bin>


More information about the libcxx-commits mailing list