1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/rand_util.h"
11 // #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the
12 // "Community Additions" comment on MSDN here:
13 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx
14 #define SystemFunction036 NTAPI SystemFunction036
16 #undef SystemFunction036
22 #include "base/check.h"
23 #include "base/feature_list.h"
24 #include "third_party/boringssl/src/include/openssl/crypto.h"
25 #include "third_party/boringssl/src/include/openssl/rand.h"
33 // The BoringSSl helpers are duplicated in rand_util_fuchsia.cc and
34 // rand_util_posix.cc.
35 std::atomic<bool> g_use_boringssl;
37 BASE_FEATURE(kUseBoringSSLForRandBytes,
38 "UseBoringSSLForRandBytes",
39 FEATURE_DISABLED_BY_DEFAULT);
43 void ConfigureBoringSSLBackedRandBytesFieldTrial() {
44 g_use_boringssl.store(FeatureList::IsEnabled(kUseBoringSSLForRandBytes),
45 std::memory_order_relaxed);
48 bool UseBoringSSLForRandBytes() {
49 return g_use_boringssl.load(std::memory_order_relaxed);
52 } // namespace internal
56 void RandBytes(void* output, size_t output_length, bool avoid_allocation) {
57 if (!avoid_allocation && internal::UseBoringSSLForRandBytes()) {
58 // Ensure BoringSSL is initialized so it can use things like RDRAND.
59 CRYPTO_library_init();
60 // BoringSSL's RAND_bytes always returns 1. Any error aborts the program.
61 (void)RAND_bytes(static_cast<uint8_t*>(output), output_length);
65 char* output_ptr = static_cast<char*>(output);
66 while (output_length > 0) {
67 const ULONG output_bytes_this_pass = static_cast<ULONG>(std::min(
68 output_length, static_cast<size_t>(std::numeric_limits<ULONG>::max())));
70 RtlGenRandom(output_ptr, output_bytes_this_pass) != FALSE;
72 output_length -= output_bytes_this_pass;
73 output_ptr += output_bytes_this_pass;
79 void RandBytes(void* output, size_t output_length) {
80 RandBytes(output, output_length, /*avoid_allocation=*/false);
85 double RandDoubleAvoidAllocation() {
87 RandBytes(&number, sizeof(number), /*avoid_allocation=*/true);
88 // This transformation is explained in rand_util.cc.
89 return (number >> 11) * 0x1.0p-53;
92 } // namespace internal