diff options
Diffstat (limited to 'libs/libcurl/src/rand.c')
-rw-r--r-- | libs/libcurl/src/rand.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/libs/libcurl/src/rand.c b/libs/libcurl/src/rand.c index dd02f52680..2e7e7e8238 100644 --- a/libs/libcurl/src/rand.c +++ b/libs/libcurl/src/rand.c @@ -38,6 +38,64 @@ #include "curl_memory.h" #include "memdebug.h" +#ifdef WIN32 + +#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) +# define HAVE_MINGW_ORIGINAL +#endif + +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 && \ + !defined(HAVE_MINGW_ORIGINAL) +# define HAVE_WIN_BCRYPTGENRANDOM +# include <bcrypt.h> +# ifdef _MSC_VER +# pragma comment(lib, "bcrypt.lib") +# endif +# ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG +# define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 +# endif +# ifndef STATUS_SUCCESS +# define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +# endif +#elif defined(USE_WIN32_CRYPTO) +# include <wincrypt.h> +# ifdef _MSC_VER +# pragma comment(lib, "advapi32.lib") +# endif +#endif + +CURLcode Curl_win32_random(unsigned char *entropy, size_t length) +{ + memset(entropy, 0, length); + +#if defined(HAVE_WIN_BCRYPTGENRANDOM) + if(BCryptGenRandom(NULL, entropy, (ULONG)length, + BCRYPT_USE_SYSTEM_PREFERRED_RNG) != STATUS_SUCCESS) + return CURLE_FAILED_INIT; + + return CURLE_OK; +#elif defined(USE_WIN32_CRYPTO) + { + HCRYPTPROV hCryptProv = 0; + + if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + return CURLE_FAILED_INIT; + + if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) { + CryptReleaseContext(hCryptProv, 0UL); + return CURLE_FAILED_INIT; + } + + CryptReleaseContext(hCryptProv, 0UL); + } + return CURLE_OK; +#else + return CURLE_NOT_BUILT_IN; +#endif +} +#endif + static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) { unsigned int r; @@ -73,6 +131,14 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) /* ---- non-cryptographic version following ---- */ +#ifdef WIN32 + if(!seeded) { + result = Curl_win32_random((unsigned char *)rnd, sizeof(*rnd)); + if(result != CURLE_NOT_BUILT_IN) + return result; + } +#endif + #if defined(RANDOM_FILE) && !defined(WIN32) if(!seeded) { /* if there's a random file to read a seed from, use it */ @@ -146,7 +212,7 @@ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num) /* * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random - * hexadecimal digits PLUS a zero terminating byte. It must be an odd number + * hexadecimal digits PLUS a null-terminating byte. It must be an odd number * size. */ @@ -169,7 +235,7 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, /* make sure it fits in the local buffer and that it is an odd number! */ return CURLE_BAD_FUNCTION_ARGUMENT; - num--; /* save one for zero termination */ + num--; /* save one for null-termination */ result = Curl_rand(data, buffer, num/2); if(result) |