On Sun, Apr 06, 2014 at 19:23, Dmitry Chestnykh wrote:
> Hello,
>
> I have discovered that bcrypt_pbkdf(3) could write out of bounds of
> the given key buffer in certain cases. For example, if requested
> keylen is 88, it will write to key[88].
Indeed. That's my fault. A side effect of the out of bounds bug was
that a byte of key material wasn't being copied out.
Here's a diff that fixes both issues. As a result of this change,
certain (odd) key strides will behave differently now, and generate
different keys. I don't think these were used in practice. ssh uses an
even stride.
Index: bcrypt_pbkdf.c
===================================================================
RCS file: /cvs/src/lib/libutil/bcrypt_pbkdf.c,v
retrieving revision 1.6
diff -u -p -r1.6 bcrypt_pbkdf.c
--- bcrypt_pbkdf.c 31 Jan 2014 16:56:32 -0000 1.6
+++ bcrypt_pbkdf.c 7 Apr 2014 22:04:03 -0000
@@ -104,6 +104,7 @@ bcrypt_pbkdf(const char *pass, size_t pa
uint8_t countsalt[4];
size_t i, j, amt, stride;
uint32_t count;
+ size_t origkeylen = keylen;
/* nothing crazy */
if (rounds < 1)
@@ -149,9 +150,13 @@ bcrypt_pbkdf(const char *pass, size_t pa
* pbkdf2 deviation: ouput the key material non-linearly.
*/
amt = MIN(amt, keylen);
- for (i = 0; i < amt; i++)
- key[i * stride + (count - 1)] = out[i];
- keylen -= amt;
+ for (i = 0; i < amt; i++) {
+ size_t dest = i * stride + (count - 1);
+ if (dest >= origkeylen)
+ break;
+ key[dest] = out[i];
+ }
+ keylen -= i;
}
/* zap */