summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl/lib/rand.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/rand.c')
-rw-r--r--Utilities/cmcurl/lib/rand.c77
1 files changed, 73 insertions, 4 deletions
diff --git a/Utilities/cmcurl/lib/rand.c b/Utilities/cmcurl/lib/rand.c
index 8da1e8d968..2e7e7e8238 100644
--- a/Utilities/cmcurl/lib/rand.c
+++ b/Utilities/cmcurl/lib/rand.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
#include "curl_setup.h"
@@ -36,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;
@@ -71,7 +131,15 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
/* ---- non-cryptographic version following ---- */
-#ifdef RANDOM_FILE
+#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 */
int fd = open(RANDOM_FILE, O_RDONLY);
@@ -106,7 +174,8 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
* 'rndptr' points to.
*
* If libcurl is built without TLS support or with a TLS backend that lacks a
- * proper random API (Gskit or mbedTLS), this function will use "weak" random.
+ * proper random API (rustls, Gskit or mbedTLS), this function will use "weak"
+ * random.
*
* When built *with* TLS support and a backend that offers strong random, it
* will return error if it cannot provide strong random values.
@@ -143,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.
*/
@@ -166,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)