Re: Why does reading from /dev/urandom deplete entropy so much?

Matt Mackall
2007-12-04T21:55:40Z

On Tue, Dec 04, 2007 at 02:48:12PM -0600, Mike McGrath wrote:
> Alan Cox wrote:
> >>Here's the top 5:
> >>
> >> 266 28caf2c3-9766-4fe1-9e4c-d6b0ba8a0132
> >> 336 810e7126-1c69-4aff-b8b1-9db0fa8aa15a
> >> 402 c8dbb9d3-a9bd-4ba6-b92e-4a294ba5a95f
> >> 884 06e84493-e024-44b1-9b32-32d78af04039
> >> 931 e2b67e1d-e325-4740-b938-795addb45280
> >>
> >>The left number is times this month someone has submitted a profile with
> >>that UUID. If we take the last one as an example has come from over 800
> >>IP's in the last 20 days. It seems very unlikely that one person would
> >>find his way to 800 different IP's this month. Let me know if you'd
> >>like more.
> >>
> Background - Smolt runs this during its install:
>
> /bin/cat /proc/sys/kernel/random/uuid > /etc/sysconfig/hw-uuid
>
> For most users this would be run by the RPM %post scripts during install
> from anaconda. For some reason there are some UUID's (like those listed
> above) that come up more often then it seems they should if they are
> truly random.

Ok, this sounds like it's run from install from CD or NFS, very early
in the boot process. Presumably it gets run during hands-free install
as well.

So a) we don't have a useful random seed file and b) we may have no
entropy. We should probably dredge up some more system data for the
initial pool seed (perhaps by passing in entropy from device probing).

The random seed file weakness is quite substantial. It affects
basically everything on RO media. We can probably implement a loop
something like the following to extract bits of entropy from the
system timing for those systems with no RW media:

int get_raw_timing_bit(void)
{
int parity = 0;
int start = clock();

while(start == clock()) {
parity ^= 1;
}

return parity;
}

int get_whitened_timing_bit(void) {
int a, b;

while (1) {
a = get_raw_timing_bit();
b = get_raw_timing_bit();
if (a > b)
return 0;
if (b > a)
return 1;
}
}

int main(void)
{
int i;

for (i = 0; i < 64; i++)
printf("%d", get_whitened_timing_bit());

printf("\n");
}

That's gonna average about 4 clock edges per bit bits, so if the
external clock is running at 100HZ, we're looking at ~2.5 seconds for
64 bits of clock skew and scheduling "entropy".

The above can be done in userspace of course.

--
Mathematics is the supreme nostalgia of our time.