Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Date: Mon, 2 Jan 2012 04:49:28 +0400
From: Solar Designer <solar@...nwall.com>
To: oss-security@...ts.openwall.com
Cc: deraadt@...nbsd.org, Todd Miller <Todd.Miller@...rtesan.com>,
	Colin Percival <cperciva@...ebsd.org>, dillon@...llo.backplane.com,
	Christos Zoulas <christos@...las.com>
Subject: OpenBSD bcrypt 8-bit key_len wraparound

Hi,

Christos Zoulas of NetBSD discovered that the key_len variable was
declared in bcrypt.c as u_int8_t and it would potentially wrap around here:

key_len = strlen(key) + (minor >= 'a' ? 1 : 0);

While bcrypt truncates very long passwords at 72 characters (by design),
which is sort of expected behavior, the wraparound is not expected.  It
is substantially different behavior than truncation.  For example, the
following three kinds of passwords all produce the same hash as tested
by calling crypt() with the same $2a$ salt from a C program on OpenBSD 4.6:

1. A string of 72 zeroes:

000000000000000000000000000000000000000000000000000000000000000000000000

2. Any 255-character string starting with a "0", e.g.:

012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234

3. Any 256-character string starting with a "0", e.g.:

0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345

while #2 and #3 would produce the same hash anyway (because of
truncation at 72), it is not expected that they produce the same hash as
the obviously very weak password #1.  (John the Ripper will test all
such passwords quickly if invoked with "--external=Repeats".)

#2 and #3 would produce this same hash even if they contained a lot of
entropy in character positions 2 through 72, which get ignored.

Luckily, it is unrealistic that people will use passwords this long, yet
there's a theoretical issue to fix here.

Simply changing the type of key_len to u_int32_t (assuming that longer
strings are not supported at higher levels anyway, which may or may not
be the case) wouldn't fully do the trick because the underlying
functions use u_int16_t for some reason.  Thus, we opted to fix the
issue by limiting key_len to 72 or 73 right in that place:

http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libcrypt/bcrypt.c.diff?r1=1.13&r2=1.15

+	size_t len;

-	key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
+	len = strlen(key);
+	if (len > 72)
+		key_len = 72;
+	else
+		key_len = (uint8_t)len;
+	key_len += minor >= 'a' ? 1 : 0;

Other *BSDs may want to do the same.

...Oh, and someone may want to check Solaris for this and for the ":"
return bcrypt issue.  (I did not.)

Alexander

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.