llvm-capstone/libcxx/include/__random/random_device.h
Louis Dionne d202c76441 [libc++] Start using arc4random() to implement std::random_device on Apple
On Apple platforms, arc4random is faster than /dev/urandom, and it is
the recommended user-space RNG according to Apple's own OS folks.

This commit adds an ABI switch to guard ABI-break-protections in
std::random_device, and starts using arc4random instead of /dev/urandom
to implement std::random_device on Apple platforms.

Note that previously, `std::random_device` would allow passing a custom
token to its constructor, and that token would be interpreted as the name
of a file to read entropy from. This was implementation-defined and
undocumented. After this change, Apple platforms will be using arc4random()
instead, and any custom token passed to the constructor will be ignored.
This behavioral change will also impact other platforms that use the
arc4random() implementation, such as OpenBSD. This should be fine since
that is effectively a relaxation of the constructor's requirements.

rdar://86638350

Differential Revision: https://reviews.llvm.org/D116045
2022-01-12 11:24:23 -05:00

89 lines
2.4 KiB
C++

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___RANDOM_RANDOM_DEVICE_H
#define _LIBCPP___RANDOM_RANDOM_DEVICE_H
#include <__config>
#include <string>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE)
class _LIBCPP_TYPE_VIS random_device
{
#ifdef _LIBCPP_USING_DEV_RANDOM
int __f_;
#elif !defined(_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT)
# if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunused-private-field"
# endif
// Apple platforms used to use the `_LIBCPP_USING_DEV_RANDOM` code path, and now
// use `arc4random()` as of this comment. In order to avoid breaking the ABI, we
// retain the same layout as before.
# if defined(__APPLE__)
int __padding_; // padding to fake the `__f_` field above
# endif
// ... vendors can add workarounds here if they switch to a different representation ...
# if defined(__clang__)
# pragma clang diagnostic pop
# endif
#endif
public:
// types
typedef unsigned result_type;
// generator characteristics
static _LIBCPP_CONSTEXPR const result_type _Min = 0;
static _LIBCPP_CONSTEXPR const result_type _Max = 0xFFFFFFFFu;
_LIBCPP_INLINE_VISIBILITY
static _LIBCPP_CONSTEXPR result_type min() { return _Min;}
_LIBCPP_INLINE_VISIBILITY
static _LIBCPP_CONSTEXPR result_type max() { return _Max;}
// constructors
#ifndef _LIBCPP_CXX03_LANG
random_device() : random_device("/dev/urandom") {}
explicit random_device(const string& __token);
#else
explicit random_device(const string& __token = "/dev/urandom");
#endif
~random_device();
// generating functions
result_type operator()();
// property functions
double entropy() const _NOEXCEPT;
random_device(const random_device&) = delete;
void operator=(const random_device&) = delete;
};
#endif // !_LIBCPP_HAS_NO_RANDOM_DEVICE
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___RANDOM_RANDOM_DEVICE_H