X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/374330e25a6b51c40436fa869a381dd510790f6e..38c4a8da5955bf0572be423ce46866285b7bcf59:/sshrand.c diff --git a/sshrand.c b/sshrand.c index 17ef6e34..21a1b833 100644 --- a/sshrand.c +++ b/sshrand.c @@ -39,22 +39,7 @@ struct RandPool { }; static struct RandPool pool; - -void random_add_noise(void *noise, int length) { - unsigned char *p = noise; - - while (length >= (HASHINPUT - pool.incomingpos)) { - memcpy(pool.incomingb + pool.incomingpos, p, - HASHINPUT - pool.incomingpos); - p += HASHINPUT - pool.incomingpos; - length -= HASHINPUT - pool.incomingpos; - SHATransform((word32 *)pool.incoming, (word32 *)pool.incomingb); - pool.incomingpos = 0; - } - - memcpy(pool.incomingb, p, length); - pool.incomingpos = length; -} +static int random_active = 0; void random_stir(void) { word32 block[HASHINPUT/sizeof(word32)]; @@ -121,37 +106,83 @@ void random_stir(void) { * there'll be some extra bizarreness there. */ SHATransform(digest, block); - memcpy(digest, pool.incoming, sizeof(digest)); + memcpy(pool.incoming, digest, sizeof(digest)); pool.poolpos = sizeof(pool.incoming); } -static void random_add_heavynoise(void *noise, int length) { +void random_add_noise(void *noise, int length) { unsigned char *p = noise; + int i; - while (length >= (POOLSIZE - pool.poolpos)) { - memcpy(pool.pool + pool.poolpos, p, POOLSIZE - pool.poolpos); - p += POOLSIZE - pool.poolpos; - length -= POOLSIZE - pool.poolpos; + if (!random_active) + return; + + /* + * This function processes HASHINPUT bytes into only HASHSIZE + * bytes, so _if_ we were getting incredibly high entropy + * sources then we would be throwing away valuable stuff. + */ + while (length >= (HASHINPUT - pool.incomingpos)) { + memcpy(pool.incomingb + pool.incomingpos, p, + HASHINPUT - pool.incomingpos); + p += HASHINPUT - pool.incomingpos; + length -= HASHINPUT - pool.incomingpos; + SHATransform((word32 *)pool.incoming, (word32 *)pool.incomingb); + for (i = 0; i < HASHSIZE; i++) { + pool.pool[pool.poolpos++] ^= pool.incomingb[i]; + if (pool.poolpos >= POOLSIZE) + pool.poolpos = 0; + } + if (pool.poolpos < HASHSIZE) + random_stir(); + + pool.incomingpos = 0; + } + + memcpy(pool.incomingb + pool.incomingpos, p, length); + pool.incomingpos += length; +} + +void random_add_heavynoise(void *noise, int length) { + unsigned char *p = noise; + int i; + + while (length >= POOLSIZE) { + for (i = 0; i < POOLSIZE; i++) + pool.pool[i] ^= *p++; random_stir(); - pool.poolpos = 0; + length -= POOLSIZE; } - memcpy(pool.pool, p, length); - pool.poolpos = length; + for (i = 0; i < length; i++) + pool.pool[i] ^= *p++; + random_stir(); +} + +static void random_add_heavynoise_bitbybit(void *noise, int length) { + unsigned char *p = noise; + int i; + + while (length >= POOLSIZE - pool.poolpos) { + for (i = 0; i < POOLSIZE - pool.poolpos; i++) + pool.pool[pool.poolpos + i] ^= *p++; + random_stir(); + length -= POOLSIZE - pool.poolpos; + pool.poolpos = 0; + } + + for (i = 0; i < length; i++) + pool.pool[i] ^= *p++; + pool.poolpos = i; } void random_init(void) { memset(&pool, 0, sizeof(pool)); /* just to start with */ - /* - * For noise_get_heavy, we temporarily use `poolpos' as the - * pointer for addition of noise, rather than extraction of - * random numbers. - */ - pool.poolpos = 0; - noise_get_heavy(random_add_heavynoise); + random_active = 1; + noise_get_heavy(random_add_heavynoise_bitbybit); random_stir(); }