On 2017/10/17 22:12, Christian Weisgerber wrote: > The /dev/arandom device was a detour that we are trying to get rid > of. Nothing should use it any longer. Code should preferably use > the arc4random() family of functions to get random numbers. If > that isn't an option, e.g. in shell, use /dev/urandom. > > I extracted all packages from an amd64 snapshot and ran fgrep -a > /dev/arandom over all files. It turned up these matches:
A common method is to try various /dev/*random nodes in order to find one which works. In some cases this is done at configure time, in others at runtime. To pick one example, nmap: ------------ void nrand_init(nrand_h *r) { u8 seed[256]; /* Starts out with "random" stack data */ int i; /* Gather seed entropy with best the OS has to offer */ #ifdef WIN32 HCRYPTPROV hcrypt = 0; CryptAcquireContext(&hcrypt, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); CryptGenRandom(hcrypt, sizeof(seed), seed); CryptReleaseContext(hcrypt, 0); #else struct timeval *tv = (struct timeval *)seed; int *pid = (int *)(seed + sizeof(*tv)); int fd; gettimeofday(tv, NULL); /* fill lowest seed[] with time */ *pid = getpid(); /* fill next lowest seed[] with pid */ /* Try to fill the rest of the state with OS provided entropy */ if ((fd = open("/dev/urandom", O_RDONLY)) != -1 || (fd = open("/dev/arandom", O_RDONLY)) != -1) { ssize_t n; do { errno = 0; n = read(fd, seed + sizeof(*tv) + sizeof(*pid), sizeof(seed) - sizeof(*tv) - sizeof(*pid)); } while (n < 0 && errno == EINTR); close(fd); } #endif /* Fill up our handle with starter values */ for (i = 0; i < 256; i++) { r->s[i] = i; }; r->i = r->j = 0; nrand_addrandom(r, seed, 128); /* lower half of seed data for entropy */ nrand_addrandom(r, seed + 128, 128); /* Now use upper half */ r->tmp = NULL; r->tmplen = 0; /* This stream will start biased. Get rid of 1K of the stream */ nrand_get(r, seed, 256); nrand_get(r, seed, 256); nrand_get(r, seed, 256); nrand_get(r, seed, 256); } int get_random_bytes(void *buf, int numbytes) { static nrand_h state; static int state_init = 0; /* Initialize if we need to */ if (!state_init) { nrand_init(&state); state_init = 1; } /* Now fill our buffer */ nrand_get(&state, buf, numbytes); return 0; } ------------ In this case, I'd consider converting get_random_bytes() to use arc4random_buf, and get rid of nrand_init which is only called from get_random_bytes. The other get_random_* are implemented in terms of get_random_bytes and should get_random_probably just be left alone (especially the LCG in get_random_unique_u32). That list of files is shorter than I would have guessed :)