From 4d288dc3e981869447fafde3ecb4f3cf21b373d0 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 10 Feb 2019 13:38:15 +0000 Subject: [PATCH] Windows PuTTYgen: reinstate mouse-based entropy collection. This reverts the policy change in 6142013ab (though not the detailed code changes - I've kept the reorganised code layout). Now the old mouse-based manual entropy collection is once again required when generating a public key. Rationale: I came across Wikipedia's page on CryptGenRandom which mentioned that it was not a true kernel-level PRNG of the /dev/random variety, but rather a thing running in userland, no different in principle from PuTTY's own. So I think that makes it no longer a thing we should rely on for all our entropy, and I'm relegating it back to being just one entropy source among many. --- windows/winpgen.c | 79 ++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/windows/winpgen.c b/windows/winpgen.c index 48878e04..7f6a232a 100644 --- a/windows/winpgen.c +++ b/windows/winpgen.c @@ -1169,50 +1169,51 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg, raw_entropy_buf = snewn(raw_entropy_required, unsigned char); if (win_read_random(raw_entropy_buf, raw_entropy_required)) { /* - * If we can get the entropy we need from - * CryptGenRandom, just do that, and go straight - * to the key-generation phase. + * If we can get entropy from CryptGenRandom, use + * it. But CryptGenRandom isn't a kernel-level + * CPRNG (according to Wikipedia), and papers have + * been published cryptanalysing it. So we'll + * still do manual entropy collection; we'll just + * do it _as well_ as this. */ random_reseed( make_ptrlen(raw_entropy_buf, raw_entropy_required)); - start_generating_key(hwnd, state); - } else { - /* - * Manual entropy input, by making the user wave - * the mouse over the window a lot. - * - * My brief statistical tests on mouse movements - * suggest that there are about 2.5 bits of - * randomness in the x position, 2.5 in the y - * position, and 1.7 in the message time, making - * 5.7 bits of unpredictability per mouse - * movement. However, other people have told me - * it's far less than that, so I'm going to be - * stupidly cautious and knock that down to a nice - * round 2. With this method, we require two words - * per mouse movement, so with 2 bits per mouse - * movement we expect 2 bits every 2 words, i.e. - * the number of _words_ of mouse data we want to - * collect is just the same as the number of - * _bits_ of entropy we want. - */ - state->entropy_required = raw_entropy_required; - - ui_set_state(hwnd, state, 1); - SetDlgItemText(hwnd, IDC_GENERATING, entropy_msg); - state->key_exists = false; - state->collecting_entropy = true; - - state->entropy_got = 0; - state->entropy_size = (state->entropy_required * - sizeof(unsigned)); - state->entropy = snewn(state->entropy_required, unsigned); - - SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0, - MAKELPARAM(0, state->entropy_required)); - SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, 0, 0); } + /* + * Manual entropy input, by making the user wave the + * mouse over the window a lot. + * + * My brief statistical tests on mouse movements + * suggest that there are about 2.5 bits of randomness + * in the x position, 2.5 in the y position, and 1.7 + * in the message time, making 5.7 bits of + * unpredictability per mouse movement. However, other + * people have told me it's far less than that, so I'm + * going to be stupidly cautious and knock that down + * to a nice round 2. With this method, we require two + * words per mouse movement, so with 2 bits per mouse + * movement we expect 2 bits every 2 words, i.e. the + * number of _words_ of mouse data we want to collect + * is just the same as the number of _bits_ of entropy + * we want. + */ + state->entropy_required = raw_entropy_required; + + ui_set_state(hwnd, state, 1); + SetDlgItemText(hwnd, IDC_GENERATING, entropy_msg); + state->key_exists = false; + state->collecting_entropy = true; + + state->entropy_got = 0; + state->entropy_size = (state->entropy_required * + sizeof(unsigned)); + state->entropy = snewn(state->entropy_required, unsigned); + + SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETRANGE, 0, + MAKELPARAM(0, state->entropy_required)); + SendDlgItemMessage(hwnd, IDC_PROGRESS, PBM_SETPOS, 0, 0); + smemclr(raw_entropy_buf, raw_entropy_required); sfree(raw_entropy_buf); }