diff --git a/putty.h b/putty.h index 0726d057..975b4504 100644 --- a/putty.h +++ b/putty.h @@ -1709,6 +1709,8 @@ void random_setup_special(); /* Manually drop a random seed into the random number generator, e.g. * just before generating a key. */ void random_reseed(ptrlen seed); +/* Limit on how much entropy is worth putting into the generator (bits). */ +size_t random_seed_bits(void); /* * Exports from pinger.c. diff --git a/ssh.h b/ssh.h index 4445bed1..82539d5d 100644 --- a/ssh.h +++ b/ssh.h @@ -902,6 +902,7 @@ void prng_seed_begin(prng *p); void prng_seed_finish(prng *p); void prng_read(prng *p, void *vout, size_t size); void prng_add_entropy(prng *p, unsigned source_id, ptrlen data); +size_t prng_seed_bits(prng *p); /* This function must be implemented by the platform, and returns a * timer in milliseconds that the PRNG can use to know whether it's diff --git a/sshprng.c b/sshprng.c index ee1e0df2..ea40c99f 100644 --- a/sshprng.c +++ b/sshprng.c @@ -284,3 +284,9 @@ void prng_add_entropy(prng *pr, unsigned source_id, ptrlen data) prng_seed_finish(&pi->Prng); } } + +size_t prng_seed_bits(prng *pr) +{ + prng_impl *pi = container_of(pr, prng_impl, Prng); + return pi->hashalg->hlen * 8; +} diff --git a/sshrand.c b/sshrand.c index 292956e4..994c7cfc 100644 --- a/sshrand.c +++ b/sshrand.c @@ -123,4 +123,10 @@ void random_get_savedata(void **data, int *len) *data = buf; } +size_t random_seed_bits(void) +{ + assert(random_active > 0); + return prng_seed_bits(global_prng); +} + #endif /* FUZZING */ diff --git a/windows/winpgen.c b/windows/winpgen.c index 7f6a232a..818bc728 100644 --- a/windows/winpgen.c +++ b/windows/winpgen.c @@ -1166,6 +1166,12 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg, else raw_entropy_required = 256; + /* Bound the entropy collection above by the amount of + * data we can actually fit into the PRNG. Any more + * than that and it's doing no more good. */ + if (raw_entropy_required > random_seed_bits()) + raw_entropy_required = random_seed_bits(); + raw_entropy_buf = snewn(raw_entropy_required, unsigned char); if (win_read_random(raw_entropy_buf, raw_entropy_required)) { /*