Skip to content

Commit dfc2948

Browse files
davidbenagl
authored andcommitted
Call RtlGenRandom directly in RAND_bytes.
It works within the Chromium sandbox, unlike CryptAcquireContext and CryptGenRandom which requires the HCRYPTPROV be pre-warmed and held within the sandbox. Also account for the mismatch between size_t and ULONG/DWORD. See https://chromium.googlesource.com/chromium/src/+/master/base/rand_util_win.cc BUG=crbug.com/429919 Change-Id: Ia684124736c0c039ca9410509973192a597856ab Reviewed-on: https://boringssl-review.googlesource.com/2190 Reviewed-by: Adam Langley <[email protected]>
1 parent 0e2a3cf commit dfc2948

File tree

1 file changed

+18
-39
lines changed

1 file changed

+18
-39
lines changed

crypto/rand/windows.c

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,57 +14,36 @@
1414

1515
#include <openssl/rand.h>
1616

17-
#include <openssl/thread.h>
18-
19-
2017
#if defined(OPENSSL_WINDOWS)
2118

19+
#include <limits.h>
2220
#include <stdlib.h>
2321
#include <Windows.h>
24-
#include <Wincrypt.h>
2522

26-
static char global_provider_init;
27-
static HCRYPTPROV global_provider;
23+
/* #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the
24+
* "Community Additions" comment on MSDN here:
25+
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */
26+
#define SystemFunction036 NTAPI SystemFunction036
27+
#include <NTSecAPI.h>
28+
#undef SystemFunction036
29+
2830

2931
void RAND_cleanup(void) {
30-
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
31-
CryptReleaseContext(global_provider, 0);
32-
global_provider_init = 0;
33-
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
3432
}
3533

3634
int RAND_bytes(uint8_t *out, size_t requested) {
37-
HCRYPTPROV provider = 0;
38-
int ok;
39-
40-
CRYPTO_r_lock(CRYPTO_LOCK_RAND);
41-
if (!global_provider_init) {
42-
CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
43-
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
44-
if (!global_provider_init) {
45-
if (CryptAcquireContext(&global_provider, NULL, NULL, PROV_RSA_FULL,
46-
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
47-
global_provider_init = 1;
48-
}
35+
while (requested > 0) {
36+
ULONG output_bytes_this_pass = ULONG_MAX;
37+
if (requested < output_bytes_this_pass) {
38+
output_bytes_this_pass = requested;
4939
}
50-
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
51-
CRYPTO_r_lock(CRYPTO_LOCK_RAND);
52-
}
53-
54-
ok = global_provider_init;
55-
provider = global_provider;
56-
CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
57-
58-
if (!ok) {
59-
abort();
60-
return ok;
61-
}
62-
63-
if (TRUE != CryptGenRandom(provider, requested, out)) {
64-
abort();
65-
return 0;
40+
if (RtlGenRandom(out, output_bytes_this_pass) == FALSE) {
41+
abort();
42+
return 0;
43+
}
44+
requested -= output_bytes_this_pass;
45+
out += output_bytes_this_pass;
6646
}
67-
6847
return 1;
6948
}
7049

0 commit comments

Comments
 (0)