Mailinglist Archive: opensuse-security (601 mails)

< Previous Next >
Re: [suse-security] password generator - Doh!
  • From: Steffen Dettmer <steffen@xxxxxxx>
  • Date: Mon, 14 Aug 2000 09:55:44 +0200
  • Message-id: <20000814095544.B4387@xxxxxxxxx>
* John Pinder wrote on Fri, Aug 11, 2000 at 02:03 -0700:
> srand;
> sub randselect {
> $_[0]->[rand @{ $_[0] } ]
> } #Thank you O'Reilly!

mmm... If I see it right then you use rand as source of
randomness only, ain't? This isn't always a nice idea, since the
entrophy of rand may be low, and you have to note that i.e. a pid
has usually only 16 bit (under some circumstances predictable)
entrophy, and time() has a very few bits randomness only and
should be predictable usually.

It seems better for me, to use the tv.usec field returnd by
gettimeofday() and/or collect some entrophy directly from the
user. I made some programm that reads in keystrokes and uses the
timeings between the keystrokes too.

I used the following functions to collect entrophy. It's not
really strong but obviously better than useing some time() get
getpid() only. The value of "ps axww|gzip" should be a nice
non-predictable thing too. I would be glad to get some comment
about the following code, maybe I missed some important things?

Here are the functions:

sub keyboard_seed()
{
return 0 if ($NO_KEY_TYPEING); #do nothing if set

#C would be better... ;-)
my $time_sum=0; #"rotated" value for keystroke timings
my $key_sum=0; #"rotated" value for keycodes
my $rin=''; #select() bit vector
vec($rin,fileno(STDIN),1) = 1; #construct STDIN select vector
$r=$rin; #select-vector
system "stty", '-icanon', '-echo', 'eol', "\001";
#set line discipline: non canonical mode no echo
select(STDOUT); $|=1; #set STDOUT unbuffered
print "I have to collect some enthropy. ",
"I'll analyze you keyboard hits.\n";
print "Please hit 32 keys now: [", " " x 32, "]\n";
print " ---> ";
for ($n=0; $n<32; $n++) { #32 keys
my $one_time=0; #time between two keystrokes
my $c=''; #1 byte input buffer
while (($rin=$r,$nfound = select($rin, undef, undef, 0.01)) == 0) {
#wait until data on STDIN
$one_time++; #a time tick without data
$one_time %= 2**8; #we take 4 bit only...
}
sysread(STDIN, $c, 1); #read char from STDIN
print "*"; #just a mark
#add some bits to sum:
my $b4 = ((4 ** $n)%(2**16)); #max 2 bytes (factor)
my $b6 = ((6 ** $n)%(2**16)); #max 2 bytes (factor)
$time_sum = $time_sum + $one_time * $b4; #4 bits (a "shift" in)
$key_sum = $key_sum + ( ord($c)-ord('0')) * $b6;#6 bits
}
print "\nENOUGH, Thank you!\n\n";
sleep 2;
#now we have to flush input (for such users that type 33 chars :-)
while (($rin=$r,$nfound = select($rin, undef, undef, 0)) != 0) {
sysread(STDIN, $rin, 1); #trash input
}
#restore line discipline mode
system "stty", 'icanon', 'echo', 'eol', '^@'; # ASCII null
select(STDOUT); $|=0; #set line buffered mode
my $seed = $time_sum ^ $key_sum ; #XOR timer and key longs
printf " (Keyboard seed value: 0x%X [T:0x%X K:0x%X])\n",
$seed, $time_sum, $key_sum unless($QUIET_MODE);
return $seed; #pass seed to caller
}

sub rnd_init()
{
#calling srand with entrophy...
#we "hash" some "ps" process info and collect enthropy from user
open(OLDERR, ">&STDERR") or die "STDERR->OLDERR $!\n";
open(STDERR, ">/dev/null") or die "STDERR->/dev/null $!\n";
close(STDERR);
#"redirect" STDERR; it seems that IT DOES NOT WORK CORRECTLY!!
#$seed1 = (unpack "%L*", `find /proc -print | xargs cat gzip`);
$seed1 = keyboard_seed();
$seed2 = (time ^ $$ ^ unpack "%L*", `ps axww | gzip`);
$seed = $seed1 ^ $seed2;
#next line DOES NOT WORK correctly at least under Solaris!!!
open(STDERR, ">&OLDERR") or print OLDERR "OLDERR->STDERR $!\n";
close (OLDERR);
printf " --> 32 bits enthropy: 0x%X <--\n", $seed
unless ($QUIET_MODE);
srand($seed); #set calculated seed
}


oki,

Steffen

--
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.

< Previous Next >