diff options
author | David Benjamin <davidben@chromium.org> | 2014-11-04 13:53:02 -0500 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2014-11-05 00:42:07 +0000 |
commit | dfc2948c73f4f91ad5a0a27836580ba3b0ce2578 (patch) | |
tree | dd713b92ded1ca2d166061047eac82f1b454c09b | |
parent | 0e2a3cf98ac19db1a9cac9aa22ad8086d5be11e9 (diff) | |
download | src-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.c | 57 |
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; } |