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 "partition_alloc/partition_alloc_base/rand_util.h"
6 
7 #include <windows.h>
8 
9 #include <algorithm>
10 #include <cstddef>
11 #include <cstdint>
12 #include <limits>
13 
14 #include "partition_alloc/partition_alloc_base/check.h"
15 
16 // Prototype for ProcessPrng.
17 // See: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng
18 extern "C" {
19 BOOL WINAPI ProcessPrng(PBYTE pbData, SIZE_T cbData);
20 }
21 
22 namespace partition_alloc::internal::base {
23 
RandBytes(void * output,size_t output_length)24 void RandBytes(void* output, size_t output_length) {
25   // Import bcryptprimitives directly rather than cryptbase to avoid opening a
26   // handle to \\Device\KsecDD in the renderer.
27   // Note: we cannot use a magic static here as PA runs too early in process
28   // startup, but this should be safe as the process will be single-threaded
29   // when this first runs.
30   static decltype(&ProcessPrng) process_prng_fn = nullptr;
31   if (!process_prng_fn) {
32     HMODULE hmod = LoadLibraryW(L"bcryptprimitives.dll");
33     PA_BASE_CHECK(hmod);
34     process_prng_fn = reinterpret_cast<decltype(&ProcessPrng)>(
35         GetProcAddress(hmod, "ProcessPrng"));
36     PA_BASE_CHECK(process_prng_fn);
37   }
38   BOOL success = process_prng_fn(static_cast<BYTE*>(output), output_length);
39   // ProcessPrng is documented to always return TRUE.
40   PA_BASE_CHECK(success);
41 }
42 
43 }  // namespace partition_alloc::internal::base
44