rand: only provide weak random when needed

builds without TLS and builds using rustls

Closes #14749
This commit is contained in:
Daniel Stenberg 2024-08-31 23:37:00 +02:00
parent 269fdd4c6e
commit d76b648584
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 73 additions and 59 deletions

View File

@ -100,17 +100,70 @@ CURLcode Curl_win32_random(unsigned char *entropy, size_t length)
}
#endif
#if !defined(USE_SSL) || defined(USE_RUSTLS)
/* ---- possibly non-cryptographic version following ---- */
CURLcode Curl_weak_random(struct Curl_easy *data,
unsigned char *entropy,
size_t length) /* always 4, size of int */
{
unsigned int r;
DEBUGASSERT(length == sizeof(int));
/* Trying cryptographically secure functions first */
#ifdef _WIN32
(void)data;
{
CURLcode result = Curl_win32_random(entropy, length);
if(result != CURLE_NOT_BUILT_IN)
return result;
}
#endif
#if defined(HAVE_ARC4RANDOM)
(void)data;
r = (unsigned int)arc4random();
memcpy(entropy, &r, length);
#else
infof(data, "WARNING: using weak random seed");
{
static unsigned int randseed;
static bool seeded = FALSE;
unsigned int rnd;
if(!seeded) {
struct curltime now = Curl_now();
randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
randseed = randseed * 1103515245 + 12345;
randseed = randseed * 1103515245 + 12345;
randseed = randseed * 1103515245 + 12345;
seeded = TRUE;
}
/* Return an unsigned 32-bit pseudo-random number. */
r = randseed = randseed * 1103515245 + 12345;
rnd = (r << 16) | ((r >> 16) & 0xFFFF);
memcpy(entropy, &rnd, length);
}
#endif
return CURLE_OK;
}
#endif
#ifdef USE_SSL
#define _random(x,y,z) Curl_ssl_random(x,y,z)
#else
#define _random(x,y,z) Curl_weak_random(x,y,z)
#endif
static CURLcode randit(struct Curl_easy *data, unsigned int *rnd,
bool env_override)
{
CURLcode result = CURLE_OK;
static unsigned int randseed;
static bool seeded = FALSE;
#ifdef DEBUGBUILD
if(env_override) {
char *force_entropy = getenv("CURL_ENTROPY");
if(force_entropy) {
static unsigned int randseed;
static bool seeded = FALSE;
if(!seeded) {
unsigned int seed = 0;
size_t elen = strlen(force_entropy);
@ -131,46 +184,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd,
#endif
/* data may be NULL! */
result = Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd));
if(result != CURLE_NOT_BUILT_IN)
/* only if there is no random function in the TLS backend do the non crypto
version, otherwise return result */
return result;
/* ---- 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(HAVE_ARC4RANDOM) && !defined(USE_OPENSSL)
if(!seeded) {
*rnd = (unsigned int)arc4random();
return CURLE_OK;
}
#endif
if(!seeded) {
struct curltime now = Curl_now();
infof(data, "WARNING: using weak random seed");
randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
randseed = randseed * 1103515245 + 12345;
randseed = randseed * 1103515245 + 12345;
randseed = randseed * 1103515245 + 12345;
seeded = TRUE;
}
{
unsigned int r;
/* Return an unsigned 32-bit pseudo-random number. */
r = randseed = randseed * 1103515245 + 12345;
*rnd = (r << 16) | ((r >> 16) & 0xFFFF);
}
return CURLE_OK;
return _random(data, (unsigned char *)rnd, sizeof(*rnd));
}
/*

View File

@ -36,6 +36,11 @@ CURLcode Curl_rand_bytes(struct Curl_easy *data,
#define Curl_rand(a,b,c) Curl_rand_bytes((a), (b), (c))
#endif
/* ---- non-cryptographic version following ---- */
CURLcode Curl_weak_random(struct Curl_easy *data,
unsigned char *rnd,
size_t length);
/*
* Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random
* hexadecimal digits PLUS a null-terminating byte. It must be an odd number

View File

@ -42,6 +42,7 @@
#include "multiif.h"
#include "connect.h" /* for the connect timeout */
#include "cipher_suite.h"
#include "rand.h"
struct rustls_ssl_backend_data
{
@ -1037,7 +1038,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
Curl_none_check_cxn, /* check_cxn */
cr_shutdown, /* shutdown */
cr_data_pending, /* data_pending */
Curl_none_random, /* random */
Curl_weak_random, /* random */
Curl_none_cert_status_request, /* cert_status_request */
cr_connect_blocking, /* connect */
cr_connect_nonblocking, /* connect_nonblocking */

View File

@ -71,6 +71,7 @@
#include "connect.h"
#include "select.h"
#include "strdup.h"
#include "rand.h"
/* The last #include files should be: */
#include "curl_memory.h"
@ -919,11 +920,16 @@ CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data,
return result;
}
/* get 32 bits of random */
CURLcode Curl_ssl_random(struct Curl_easy *data,
unsigned char *entropy,
size_t length)
{
return Curl_ssl->random(data, entropy, length);
DEBUGASSERT(length == sizeof(int));
if(Curl_ssl->random)
return Curl_ssl->random(data, entropy, length);
else
return CURLE_NOT_BUILT_IN;
}
/*
@ -1193,16 +1199,6 @@ int Curl_none_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data)
return -1;
}
CURLcode Curl_none_random(struct Curl_easy *data UNUSED_PARAM,
unsigned char *entropy UNUSED_PARAM,
size_t length UNUSED_PARAM)
{
(void)data;
(void)entropy;
(void)length;
return CURLE_NOT_BUILT_IN;
}
void Curl_none_close_all(struct Curl_easy *data UNUSED_PARAM)
{
(void)data;
@ -1329,7 +1325,7 @@ static const struct Curl_ssl Curl_ssl_multi = {
Curl_none_check_cxn, /* check_cxn */
Curl_none_shutdown, /* shutdown */
Curl_none_data_pending, /* data_pending */
Curl_none_random, /* random */
NULL, /* random */
Curl_none_cert_status_request, /* cert_status_request */
multissl_connect, /* connect */
multissl_connect_nonblocking, /* connect_nonblocking */

View File

@ -171,8 +171,6 @@ void Curl_none_cleanup(void);
CURLcode Curl_none_shutdown(struct Curl_cfilter *cf, struct Curl_easy *data,
bool send_shutdown, bool *done);
int Curl_none_check_cxn(struct Curl_cfilter *cf, struct Curl_easy *data);
CURLcode Curl_none_random(struct Curl_easy *data, unsigned char *entropy,
size_t length);
void Curl_none_close_all(struct Curl_easy *data);
void Curl_none_session_free(void *ptr);
bool Curl_none_data_pending(struct Curl_cfilter *cf,