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 */

Reply via email to