Skip to content

Commit 5803d9d

Browse files
author
Yves-Marie Morgan
committed
[DEV] random: use RtlGenRandom() on Windows
rand_s() is readily available in Windows's CRT, accessible through <stdlib.h>. Unfortunately its output is limited to an integer, thus requiring multiple calls to fill a large buffer. RtlGenRandom() is the other hand can accomodate any buffer size, but is a pure Windows (NT) function, not available in Windows's CRT, as it's declared in <ntsecapi.h> and available in advapi32.dll. And according to Microsoft documentation, the availability of the function is unclear, it's future too. https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom But according to Rust community the function is used in Firefox, Chromium, etc, thus it's unlikely to be removed. rust-random/rand#111 Especially since the rand_s() documentation state its uses RtlGenRandom(): https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=vs-2019 So rand_s() uses RtlGenRandom(), hence make use of advapi32.dll, then there's no need to use rand_s() when RtlGenRandom() is available. This patch makes use of RtlGenRandom(), and fallback to rand_s() if the former fail. Note: for newer Windows versions (>= 10), RtlGenRandom() could be replaced by newer, recommanded functions: BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, buffer, len, 0); https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-pseudo-handles
1 parent cf913fd commit 5803d9d

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

src/random.c

+12
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131

3232
#ifdef _WIN32
3333
# define _CRT_RAND_S
34+
# define WIN32_LEAN_AND_MEAN
35+
# include <windows.h>
36+
# include <ntsecapi.h>
37+
# define HAVE_RTLGENRANDOM 1
3438
#endif /* _WIN32 */
3539

3640
#include "futils/random.h"
@@ -50,6 +54,14 @@ int futils_random_bytes(void *buffer, size_t len)
5054
uint8_t *p = buffer;
5155
int ret = 0;
5256
unsigned int val = 0;
57+
58+
#ifdef HAVE_RTLGENRANDOM
59+
if (!RtlGenRandom(buffer, len))
60+
ULOGE("RtlGenRandom");
61+
else
62+
return 0;
63+
#endif
64+
5365
while (len) {
5466
size_t chunk = sizeof(val);
5567
if (chunk > len)

0 commit comments

Comments
 (0)