From 3f257add3a9f053b03856e11f576e0096350d933 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 21 May 2019 05:52:59 +0000 Subject: 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 --- CMakeLists.txt | 1 + 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 -#include +#include +#include #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; } -- cgit v1.2.1