[M108 Migration][VD] Support set time and time zone offset
[platform/framework/web/chromium-efl.git] / base / rand_util_win.cc
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.
4
5 #include "base/rand_util.h"
6
7 #include <windows.h>
8 #include <stddef.h>
9 #include <stdint.h>
10
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
15 #include <NTSecAPI.h>
16 #undef SystemFunction036
17
18 #include <algorithm>
19 #include <atomic>
20 #include <limits>
21
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"
26
27 namespace base {
28
29 namespace internal {
30
31 namespace {
32
33 // The BoringSSl helpers are duplicated in rand_util_fuchsia.cc and
34 // rand_util_posix.cc.
35 std::atomic<bool> g_use_boringssl;
36
37 BASE_FEATURE(kUseBoringSSLForRandBytes,
38              "UseBoringSSLForRandBytes",
39              FEATURE_DISABLED_BY_DEFAULT);
40
41 }  // namespace
42
43 void ConfigureBoringSSLBackedRandBytesFieldTrial() {
44   g_use_boringssl.store(FeatureList::IsEnabled(kUseBoringSSLForRandBytes),
45                         std::memory_order_relaxed);
46 }
47
48 bool UseBoringSSLForRandBytes() {
49   return g_use_boringssl.load(std::memory_order_relaxed);
50 }
51
52 }  // namespace internal
53
54 namespace {
55
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);
62     return;
63   }
64
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())));
69     const bool success =
70         RtlGenRandom(output_ptr, output_bytes_this_pass) != FALSE;
71     CHECK(success);
72     output_length -= output_bytes_this_pass;
73     output_ptr += output_bytes_this_pass;
74   }
75 }
76
77 }  // namespace
78
79 void RandBytes(void* output, size_t output_length) {
80   RandBytes(output, output_length, /*avoid_allocation=*/false);
81 }
82
83 namespace internal {
84
85 double RandDoubleAvoidAllocation() {
86   uint64_t number;
87   RandBytes(&number, sizeof(number), /*avoid_allocation=*/true);
88   // This transformation is explained in rand_util.cc.
89   return (number >> 11) * 0x1.0p-53;
90 }
91
92 }  // namespace internal
93
94 }  // namespace base