diff options
author | Ivan Zhakov <ivan@apache.org> | 2019-05-21 05:52:59 +0000 |
---|---|---|
committer | Ivan Zhakov <ivan@apache.org> | 2019-05-21 05:52:59 +0000 |
commit | d15295e5d3ec107622164c39e6c2afdb70c400c1 (patch) | |
tree | 5edc0eb698b3fe9502c7bce5d02bef53aeb41070 /misc | |
parent | 880e3feebcc0774199fa635f1c2f7b25f99cb81f (diff) | |
download | apr-d15295e5d3ec107622164c39e6c2afdb70c400c1.tar.gz |
apr_generate_random_bytes: Use BCryptGenRandom() instead of CryptGenRandom()
on Windows. BCryptGenRandom() is significantly faster since it doesn't require
to load crypto provider on every invocation.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1859608 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'misc')
-rw-r--r-- | misc/win32/rand.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/misc/win32/rand.c b/misc/win32/rand.c index cb5a6537f..855fbe4fd 100644 --- a/misc/win32/rand.c +++ b/misc/win32/rand.c @@ -16,7 +16,8 @@ #include "apr.h" #include <rpc.h> -#include <wincrypt.h> +#include <winnt.h> +#include <bcrypt.h> #include "apr_private.h" #include "apr_general.h" #include "apr_portable.h" @@ -26,27 +27,20 @@ APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char * buf, apr_size_t length) { - HCRYPTPROV hProv; - apr_status_t res = APR_SUCCESS; + NTSTATUS ntstatus; - /* 0x40 bit = CRYPT_SILENT, only introduced in more recent PSDKs - * and will only work for Win2K and later. - */ - DWORD flags = CRYPT_VERIFYCONTEXT - | ((apr_os_level >= APR_WIN_2000) ? 0x40 : 0); + ntstatus = BCryptGenRandom(NULL, buf, (DWORD) length, + BCRYPT_USE_SYSTEM_PREFERRED_RNG); - if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, flags)) { - return apr_get_os_error(); + if (BCRYPT_SUCCESS(ntstatus)) { + return APR_SUCCESS; } - /* XXX: An ugly hack for Win64, randomness is such that noone should - * ever expect > 2^31 bytes of data at once without the prng - * coming to a complete halt. - */ - if (!CryptGenRandom(hProv, (DWORD)length, buf)) { - res = apr_get_os_error(); + else if (ntstatus == STATUS_INVALID_PARAMETER) { + return APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER); + } + else { + return APR_EGENERAL; } - CryptReleaseContext(hProv, 0); - return res; } |