Skip to content

Commit

Permalink
rand: only provide weak random when needed
Browse files Browse the repository at this point in the history
builds without TLS and builds using rustls

Closes #14749
  • Loading branch information
bagder committed Sep 2, 2024
1 parent 269fdd4 commit d76b648
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 59 deletions.
102 changes: 58 additions & 44 deletions lib/rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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));
}

/*
Expand Down
5 changes: 5 additions & 0 deletions lib/rand.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion lib/vtls/rustls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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 */
Expand Down
20 changes: 8 additions & 12 deletions lib/vtls/vtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}

/*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
2 changes: 0 additions & 2 deletions lib/vtls/vtls_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit d76b648

Please sign in to comment.