/ dev / random return always the same sequence

I was going to use / dev / random output as a seed for generating keys for openssl, then I wrote this little program to check what I would do:

#include <stdio.h> #include <unistd.h> #include <fcntl.h> #define LEN 128 void uc2hex(char* hex, unsigned char* uc, unsigned short uc_len) { FILE* bp=fmemopen(hex,2*uc_len+1,"w"); unsigned short i; for(i=0;i<uc_len;i++) { fprintf(bp,"%02x",uc[i]); //printf("%02x\n",uc[i]); //fprintf(bp,"%d-",i); } fprintf(bp,"%c",'\0'); fclose(bp); } int main() { unsigned char buf[LEN]; char str[2*LEN+1]; int fd=open("/dev/random",O_RDONLY); read(fd,buf,LEN); uc2hex(str,buf,LEN); printf("%s\n",str); close(fd); return 0; } 

I ran the program about once or twice, and everything seemed to work fine, but then I ran it four times in a short sequence, and this is the result:

 [ walter@eM350 ~]$ ./random 0ee08c942ddf901af1278ba8f335b5df8db7cf18e5de2a67ac200f320a7a20e84866f533667a7e66a4572b3bf83d458e6f71f325783f2e3f921868328051f8f296800352cabeaf00000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000 [ walter@eM350 ~]$ ./random 1f69a0b931c16f796bbb1345b3f58f17f74e3df600000000bb03400000000000ffffffff00000000880e648aff7f0000a88103b4d67f000000305cb4d67f000030415fb4d67f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000 [ walter@eM350 ~]$ ./random 4e8a1715238644a840eb66d9ff7f00002e4e3df600000000bb03400000000000ffffffff00000000a8ec66d9ff7f0000a871a37ad97f00000020fc7ad97f00003031ff7ad97f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000 [ walter@eM350 ~]$ ./random 598c57563e8951e6f0173f0cff7f00002e4e3df600000000bb03400000000000ffffffff0000000058193f0cff7f0000a8e1cbda257f0000009024db257f000030a127db257f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000 

Theses seem to me everything except 128-byte random strings, since they are basically the same. Then, excluding the possibility that the NSA had faked the Linux kernel random number generator, I could only guess that it had something to do with the available entropy on my machine, which is depleted when I ask for too many bytes in the sequence. My questions are: 1) Is this an assumption correct? 2) Assuming 1) it is correct, how do I know if entropy is enough to generate a real random sequence of bytes?

+6
source share
2 answers

On the reading manual page:

Upon successful completion, read(), readv(), and pread() return the number of bytes actually read and placed in the buffer. The system guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left before the end-of-file, but in no other case.

Bottom line: check the return value from read and see how many bytes you actually read - there may not have been enough entropy to generate the number of bytes you requested.

 int len = read(fd, buf, LEN); printf("read() returned %d bytes: ", len); if (len > 0) { uc2hex(str, buf, len); printf("%s\n", str); } 

Test:

 $ ./a.out read() returned 16 bytes: c3d5f6a8ee11ddc16f00a0dea4ef237a $ ./a.out read() returned 8 bytes: 24e23c57852a36bb $ ./a.out read() returned 16 bytes: 4ead04d1eedb54ee99ab1b25a41e735b $ 
+13
source

Like other people, you need to check the return value for the number of bytes read.

If / dev / random did not have enough bytes, it will return less.

However, you still use the expected length in the following calls:

 uc2hex(str,buf,LEN); printf("%s\n",str); 

So, you convert and print uninitialized memory. I am not surprised that subsequent calls show the same value - because if this memory was not written between calls, the value will not change.

EDIT: Better would be:

 int nBytes=read(fd,buf,LEN); uc2hex(str,buf,nBytes); printf("%s\n",str); 
+2
source

Source: https://habr.com/ru/post/955552/


All Articles