diff options
author | ivan <ivan@13f79535-47bb-0310-9956-ffa450edef68> | 2019-05-21 05:52:59 +0000 |
---|---|---|
committer | ivan <ivan@13f79535-47bb-0310-9956-ffa450edef68> | 2019-05-21 05:52:59 +0000 |
commit | 3f257add3a9f053b03856e11f576e0096350d933 (patch) | |
tree | 5edc0eb698b3fe9502c7bce5d02bef53aeb41070 | |
parent | 88505643019b2b024415c030ccb5211b2deef422 (diff) | |
download | libapr-3f257add3a9f053b03856e11f576e0096350d933.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: http://svn.apache.org/repos/asf/apr/apr/trunk@1859608 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | misc/win32/rand.c | 30 |
2 files changed, 13 insertions, 18 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 37e3c4359..ef29a7618 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,7 @@ SET(APR_SYSTEM_LIBS ws2_32 mswsock rpcrt4 + bcrypt ) INCLUDE_DIRECTORIES(${APR_INCLUDE_DIRECTORIES} ${XMLLIB_INCLUDE_DIR}) 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; } |