Question

I am trying to gather true random numbers from /dev/random. Here is my simple code:

u_char buf[256];

memset(buf, 0, 256);

int dev = open("/dev/random", O_RDONLY);

int nbr = read(dev, buf, 100);

printf("Number of bytes returned : %d\n", nbr);

As you can see that i am asking for 100 random bytes but when i run this program i always get output in variable nbr in range of 15 to 30 which is understandable as /dev/random does not always have enough entropy but my expectation was that upon read(), /dev/random should block until it fills my buffer to 100 random bytes which does not occur in this case and program does not block. I read man pages for /dev/random. It says that

When the entropy pool is empty, reads from /dev/random will block until additional environmental noise is gathered.

Does this literally mean that /dev/random will only block when entropy pool is empty and will not block when it has any amount data whether or not it is less than the required bytes?

Any help would be appreciated.

Was it helpful?

Solution

That's not special to /dev/random, that's just the behaviour of read. The parameter is a buffer size and read will return what's available up to that size.

Consider using a FILE* and fread instead to read one block of 100 bytes.

OTHER TIPS

In short, unless there's no data to be read, read will not block. It will always return the amount it could read or an error, even if that's less data than you wanted.

Your program is reading 100 bytes from /dev/random. If you restart it with some manual action (e.g. typing the command, or simply the arrow-up key for bash), that manual action (sequence of keypresses) is feeding the entropy pool of random(4). So you would never be in the blocking case.

And the semantics of the read(2) syscall applied to /dev/random is that it will try to read some bytes. If at least one byte has been read, the read(2) syscall succeeds and does not block.

Also, as I commented, recent enough hardware and recent enough kernel has a good enough random source which might maje random(4) never block.

/dev/random gets a data from SHA1(entropy_pool_data). SHA1 outputs only 20 bytes. It doesn't make sense to request more than 160 bits from /dev/random if you wish to obtain a truly random bits.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top