void noise_get_heavy(void (*func) (void *, int)) { noise_get_light(func); noise_get_processes(func); read_random_seed(func); /* Update the seed immediately, in case another instance uses it. */ random_save_seed(); }
static void random_stir(void) { word32 block[HASHINPUT / sizeof(word32)]; word32 digest[HASHSIZE / sizeof(word32)]; int i, j, k; /* * noise_get_light will call random_add_noise, which may call * back to here. Prevent recursive stirs. */ if (pool.stir_pending) return; pool.stir_pending = TRUE; noise_get_light(random_add_noise); SHATransform((word32 *) pool.incoming, (word32 *) pool.incomingb); pool.incomingpos = 0; /* * Chunks of this code are blatantly endianness-dependent, but * as it's all random bits anyway, WHO CARES? */ memcpy(digest, pool.incoming, sizeof(digest)); /* * Make two passes over the pool. */ for (i = 0; i < 2; i++) { /* * We operate SHA in CFB mode, repeatedly adding the same * block of data to the digest. But we're also fiddling * with the digest-so-far, so this shouldn't be Bad or * anything. */ memcpy(block, pool.pool, sizeof(block)); /* * Each pass processes the pool backwards in blocks of * HASHSIZE, just so that in general we get the output of * SHA before the corresponding input, in the hope that * things will be that much less predictable that way * round, when we subsequently return bytes ... */ for (j = POOLSIZE; (j -= HASHSIZE) >= 0;) { /* * XOR the bit of the pool we're processing into the * digest. */ for (k = 0; k < sizeof(digest) / sizeof(*digest); k++) digest[k] ^= ((word32 *) (pool.pool + j))[k]; /* * Munge our unrevealed first block of the pool into * it. */ SHATransform(digest, block); /* * Stick the result back into the pool. */ for (k = 0; k < sizeof(digest) / sizeof(*digest); k++) ((word32 *) (pool.pool + j))[k] = digest[k]; } } /* * Might as well save this value back into `incoming', just so * there'll be some extra bizarreness there. */ SHATransform(digest, block); memcpy(pool.incoming, digest, sizeof(digest)); pool.poolpos = sizeof(pool.incoming); pool.stir_pending = FALSE; }