summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@chromium.org>2014-11-04 13:53:02 -0500
committerAdam Langley <agl@google.com>2014-11-05 00:42:07 +0000
commitdfc2948c73f4f91ad5a0a27836580ba3b0ce2578 (patch)
treedd713b92ded1ca2d166061047eac82f1b454c09b
parent0e2a3cf98ac19db1a9cac9aa22ad8086d5be11e9 (diff)
downloadsrc-dfc2948c73f4f91ad5a0a27836580ba3b0ce2578.tar.gz
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 <agl@google.com>
-rw-r--r--crypto/rand/windows.c57
1 files changed, 18 insertions, 39 deletions
diff --git a/crypto/rand/windows.c b/crypto/rand/windows.c
index 967dd9b..ed6e5e9 100644
--- a/crypto/rand/windows.c
+++ b/crypto/rand/windows.c
@@ -14,57 +14,36 @@
#include <openssl/rand.h>
-#include <openssl/thread.h>
-
-
#if defined(OPENSSL_WINDOWS)
+#include <limits.h>
#include <stdlib.h>
#include <Windows.h>
-#include <Wincrypt.h>
-static char global_provider_init;
-static HCRYPTPROV global_provider;
+/* #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the
+ * "Community Additions" comment on MSDN here:
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */
+#define SystemFunction036 NTAPI SystemFunction036
+#include <NTSecAPI.h>
+#undef SystemFunction036
+
void RAND_cleanup(void) {
- CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- CryptReleaseContext(global_provider, 0);
- global_provider_init = 0;
- CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
}
int RAND_bytes(uint8_t *out, size_t requested) {
- HCRYPTPROV provider = 0;
- int ok;
-
- CRYPTO_r_lock(CRYPTO_LOCK_RAND);
- if (!global_provider_init) {
- CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
- CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- if (!global_provider_init) {
- if (CryptAcquireContext(&global_provider, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
- global_provider_init = 1;
- }
+ while (requested > 0) {
+ ULONG output_bytes_this_pass = ULONG_MAX;
+ if (requested < output_bytes_this_pass) {
+ output_bytes_this_pass = requested;
}
- CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
- CRYPTO_r_lock(CRYPTO_LOCK_RAND);
- }
-
- ok = global_provider_init;
- provider = global_provider;
- CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
-
- if (!ok) {
- abort();
- return ok;
- }
-
- if (TRUE != CryptGenRandom(provider, requested, out)) {
- abort();
- return 0;
+ if (RtlGenRandom(out, output_bytes_this_pass) == FALSE) {
+ abort();
+ return 0;
+ }
+ requested -= output_bytes_this_pass;
+ out += output_bytes_this_pass;
}
-
return 1;
}