add_timer_randomness(&extract_timer_state, nbytes);
enqueue_randomness(&extract_timer_state, nbytes);
extract_entropy(buf, nbytes)	register char	*buf;	int	nbytes;{	int	ret, i;	MD5_CTX tmp;		add_timer_randomness(&extract_timer_state, nbytes);		/* Redundant, but just in case... */	if (random_state.entropy_count > POOLBITS) 		random_state.entropy_count = POOLBITS;	ret = nbytes;	if (random_state.entropy_count / 8 >= nbytes)		random_state.entropy_count -= nbytes*8;	else		random_state.entropy_count = 0;	while (nbytes) {		/* Hash the pool to get the output */		MD5Init(&tmp);		for (i = 0; i < POOLWORDS; i += 16)			MD5Update(&tmp, (u_int8_t*)random_state.pool+i, 16);		/* Modify pool so next hash will produce different results */		for (i = 0; i < sizeof(tmp.buffer)/sizeof(tmp.buffer[0]); i++)			add_entropy_word(tmp.buffer[i]);		/*		 * Run the MD5 Transform one more time, since we want		 * to add at least minimal obscuring of the inputs to		 * add_entropy_word().  --- TYT		 */		MD5Update(&tmp, (u_int8_t*)random_state.pool, 16);		/*		 * In case the hash function has some recognizable		 * output pattern, we fold it in half.		 */		{			register u_int8_t	*cp, *dp;			cp = (u_int8_t *) &tmp.buffer;			dp = cp + sizeof(tmp.buffer) - 1;			while (cp < dp)				*cp++ ^= *dp--;		}		/* Copy data to destination buffer */		i = MIN(nbytes, sizeof(tmp.buffer));		bcopy((caddr_t)&tmp.buffer, buf, i);		nbytes -= i;		buf += i;		add_timer_randomness(&extract_timer_state, nbytes);	}	/* Wipe data from memory */	bzero(&tmp, sizeof(tmp));		return ret;}