gee i wonder who we can blame for that...

> 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 :)
> 

Reply via email to