Disputed / BOGUS

pwgen weak algorithms

Published / (Updated)
Credit
Risk
2013-05-25 / 2013-05-28
Seth Arnold
Medium
CWE
CVE
Local
Remote
N/A
N/A
Yes
No

A user reported to launchpad [1] that pwgen will use /dev/urandom or
/dev/random if it can, but will silently fall back to using drand48() or
random() if the device files fail to open. The report also mentions that
when the device files are available, the output is biased by too-simple
use of the modulo operator to scale the output to 0 <= n < max. There
are further complaints about the poor use of available entropy when
seeding the weaker algorithms.

A potentially related complaint is in Debian's BTS [2]: in this bug
report, the user wanted a way to force use of /dev/random even if
/dev/urandom is available.

I've pasted the relevant source to pastebin.ubuntu.com [3].

Are any of these worthy of a CVE number?

- silent fall-back to weak algorithms
- biased output due to poor use of modulo operations
- poor seeding of weak algorithms

/* from randnum.c in pwgen */

/* Borrowed/adapted from e2fsprogs's UUID generation code */
static int get_random_fd()
{
struct timeval tv;
static int fd = -2;
int i;

if (fd == -2) {
gettimeofday(&tv, 0);
fd = open("/dev/urandom", O_RDONLY);
if (fd == -1)
fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
#ifdef HAVE_DRAND48
srand48((tv.tv_sec<<9) ^ (getpgrp()<<15) ^
(getpid()) ^ (tv.tv_usec>>11));
#else
srandom((getpid() << 16) ^ (getpgrp() << 8) ^ getuid()
^ tv.tv_sec ^ tv.tv_usec);
#endif
}
/* Crank the random number generator a few times */
gettimeofday(&tv, 0);
for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
#ifdef HAVE_DRAND48
drand48();
#else
random();
#endif
return fd;
}

/*
* Generate a random number n, where 0 <= n < max_num, using
* /dev/urandom if possible.
*/
int pw_random_number(max_num)
int max_num;
{
int i, fd = get_random_fd();
int lose_counter = 0, nbytes=4;
unsigned int rand_num;
char *cp = (char *) &rand_num;

if (fd >= 0) {
while (nbytes > 0) {
i = read(fd, cp, nbytes);
if ((i < 0) &&
((errno == EINTR) || (errno == EAGAIN)))
continue;
if (i <= 0) {
if (lose_counter++ == 8)
break;
continue;
}
nbytes -= i;
cp += i;
lose_counter = 0;
}
}
if (nbytes == 0)
return (rand_num % max_num);

/* OK, we weren't able to use /dev/random, fall back to rand/rand48 */

#ifdef HAVE_DRAND48
return ((int) ((drand48() * max_num)));
#else
return ((int) (random() / ((float) RAND_MAX) * max_num));
#endif
}


Thank you

1: https://bugs.launchpad.net/ubuntu/+source/pwgen/+bug/1183213
2: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=672241
3: http://pastebin.ubuntu.com/5698361/

References:

https://bugs.launchpad.net/ubuntu/+source/pwgen/+bug/1183213
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=672241
http://pastebin.ubuntu.com/5698361/
http://seclists.org/oss-sec/2013/q2/407
http://seclists.org/oss-sec/2013/q2/418


See this note in RAW Version

 
Bugtraq RSS
Bugtraq
 
CVE RSS
CVEMAP
 
REDDIT
REDDIT
 
DIGG
DIGG
 
LinkedIn
LinkedIn


Copyright 2017, cxsecurity.com