---
 blowfish-bcrypt.c | 56 ++++++++++++++++++++++++-----------------------
 blowfish.h        | 14 +++++++-----
 nettle.texinfo    | 27 +++++++++++++----------
 3 files changed, 52 insertions(+), 45 deletions(-)

diff --git a/blowfish-bcrypt.c b/blowfish-bcrypt.c
index c06f9e90..491aab82 100644
--- a/blowfish-bcrypt.c
+++ b/blowfish-bcrypt.c
@@ -76,13 +76,14 @@ static const char radix64_encode_table[64] =
     "0123456789";
 
 int
-blowfish_bcrypt_verify(const char *key,
-                       const char *hashed)
+blowfish_bcrypt_verify(size_t lenkey, const char *key,
+                       size_t lenhashed, const char *hashed)
 {
   char newhash[BLOWFISH_BCRYPT_HASH_SIZE];
 
-  return blowfish_bcrypt_hash(sizeof newhash,
-                              newhash, key, hashed, -1, (void*)0)
+  return blowfish_bcrypt_hash(newhash,
+                              lenkey, key, lenhashed, hashed,
+                              -1, (void*)0)
    && !strcmp(newhash, hashed);
 }
 
@@ -159,10 +160,12 @@ static void swap32(uint32_t *x, int count)
 #endif
 }
 
-static void set_xkey(const char *key, bf_key expanded, bf_key initial,
-    unsigned bug, uint32_t safety)
+static void set_xkey(size_t lenkey, const char *key,
+                     bf_key expanded, bf_key initial,
+                    unsigned bug, uint32_t safety)
 {
   const char *ptr = key;
+  size_t n = lenkey;
   unsigned i, j;
   uint32_t sign, diff, tmp[2];
 
@@ -219,10 +222,10 @@ static void set_xkey(const char *key, bf_key expanded, 
bf_key initial,
  */
       if (j)
         sign |= tmp[1] & 0x80;
-      if (!*ptr)
-        ptr = key;
-      else
+      if (n--)
         ptr++;
+      else
+        ptr = key, n = lenkey;
     }
     diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */
 
@@ -259,8 +262,9 @@ static void set_xkey(const char *key, bf_key expanded, 
bf_key initial,
   initial[0] ^= sign;
 }
 
-static int ibcrypt(size_t length, char *dst,
-                   const char *key, const char *scheme,
+static int ibcrypt(char *dst,
+                   size_t lenkey, const char *key,
+                  size_t lenscheme, const char *scheme,
                   int minlog2rounds,
                   int log2rounds, const uint8_t *salt)
 {
@@ -277,12 +281,10 @@ static int ibcrypt(size_t length, char *dst,
   uint32_t *ptr;
   uint32_t count;
   int i;
-  size_t lenscheme = strlen(scheme);
   unsigned cscheme;
   unsigned bug = 0;
   uint32_t safety = 0;
-  if (length < BLOWFISH_BCRYPT_HASH_SIZE ||
-      lenscheme < 2)
+  if (lenscheme < 2)
     return 0;
 
   if (lenscheme >= 3 && *scheme++ != '$')
@@ -336,7 +338,7 @@ static int ibcrypt(size_t length, char *dst,
     return 0;
   count = (uint32_t)1 << log2rounds;
 
-  set_xkey(key, data.expanded_key, data.ctx.p, bug, safety);
+  set_xkey(lenkey, key, data.expanded_key, data.ctx.p, bug, safety);
   memcpy(data.ctx.s, _nettle_blowfish_initial_ctx.s, sizeof(data.ctx.s));
 
   L = R = 0;
@@ -461,12 +463,13 @@ static int ibcrypt(size_t length, char *dst,
  * The performance cost of this quick self-test is around 0.6% at the "$2a$08"
  * setting.
  */
-int blowfish_bcrypt_hash(size_t length, char *dst,
-                         const char *key, const char *scheme,
+int blowfish_bcrypt_hash(char *dst,
+                         size_t lenkey, const char *key,
+                        size_t lenscheme, const char *scheme,
                         int log2rounds, const uint8_t *salt)
 {
-  const char *test_pw = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
-  const char *test_scheme = "$2a$00$abcdefghijklmnopqrstuu";
+  const char test_pw[] = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
+  const char test_scheme[] = "$2a$00$abcdefghijklmnopqrstuu";
   static const char * const test_hashes[2] =
     {"i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55",  /* 'a', 'b', 'y' */
      "VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55"}; /* 'x' */
@@ -478,10 +481,9 @@ int blowfish_bcrypt_hash(size_t length, char *dst,
     char o[HASHOFFSET + 31 + 1 + 1 + 1];
   } buf;
 
-  if (length)
-    *dst = '\0';
+  *dst = '\0';
 /* Hash the supplied password */
-  cscheme = ibcrypt(length, dst, key, scheme, 4, log2rounds, salt);
+  cscheme = ibcrypt(dst, lenkey, key, lenscheme, scheme, 4, log2rounds, salt);
 
 /*
  * Do a quick self-test. It is important that we make both calls to ibcrypt()
@@ -497,18 +499,18 @@ int blowfish_bcrypt_hash(size_t length, char *dst,
 
   memset(buf.o, 0x55, sizeof(buf.o));
   buf.o[sizeof(buf.o) - 1] = 0;
-  ok = ibcrypt(sizeof(buf.o) - (1 + 1), buf.o, test_pw,
-               buf.s, 0, -1, (void*)0);
+  ok = ibcrypt(buf.o, sizeof(test_pw), test_pw,
+               sizeof(buf.s), buf.s, 0, -1, (void*)0);
 
   ok = (ok &&
       !memcmp(buf.o, buf.s, HASHOFFSET) &&
       !memcmp(buf.o + HASHOFFSET, test_hash, 31 + 1 + 1 + 1));
 
   {
-    const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
+    const char k[] = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
     bf_key ae, ai, ye, yi;
-    set_xkey(k, ae, ai, 0, 0x10000); /* $2a$ */
-    set_xkey(k, ye, yi, 0, 0); /* $2y$ */
+    set_xkey(sizeof(k), k, ae, ai, 0, 0x10000); /* $2a$ */
+    set_xkey(sizeof(k), k, ye, yi, 0, 0); /* $2y$ */
     ai[0] ^= 0x10000; /* undo the safety (for comparison) */
     ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&
         !memcmp(ae, ye, sizeof(ae)) &&
diff --git a/blowfish.h b/blowfish.h
index af48e20f..1c5bdbe1 100644
--- a/blowfish.h
+++ b/blowfish.h
@@ -86,16 +86,18 @@ void
 blowfish_decrypt(const struct blowfish_ctx *ctx,
                  size_t length, uint8_t *dst,
                  const uint8_t *src);
+
+/* dst parameter must point to a buffer of minimally
+ * BLOWFISH_BCRYPT_HASH_SIZE bytes */
 int
-blowfish_bcrypt_hash(size_t length,
-                     char *dst,
-                     const char *key,
-                     const char *scheme,
+blowfish_bcrypt_hash(char *dst,
+                     size_t lenkey, const char *key,
+                     size_t lenscheme, const char *scheme,
                     int log2rounds,
                     const uint8_t *salt);
 int
-blowfish_bcrypt_verify(const char *key,
-                       const char *hashed);
+blowfish_bcrypt_verify(size_t lenkey, const char *key,
+                       size_t lenhashed, const char *hashed);
 
 #ifdef __cplusplus
 }
diff --git a/nettle.texinfo b/nettle.texinfo
index 75e18b58..2269e11d 100644
--- a/nettle.texinfo
+++ b/nettle.texinfo
@@ -1513,7 +1513,7 @@ in any other way.
 Analogous to @code{blowfish_encrypt}
 @end deftypefun
 
-@deftypefun int blowfish_bcrypt_hash (size_t @var{length}, char *@var{dst}, 
const char *@var{key}, const char *@var{scheme}, int @var{log2rounds}, const 
uint8_t *@var{salt})
+@deftypefun int blowfish_bcrypt_hash (char *@var{dst}, size_t @var{lenkey}, 
const char *@var{key}, size_t @var{lenscheme}, const char *@var{scheme}, int 
@var{log2rounds}, const uint8_t *@var{salt})
 Compute the bcrypt password hash.
 The function will return @code{0} if the hash cannot be computed
 due to invalid input.
@@ -1522,13 +1522,13 @@ in the array pointed to by @var{dst}.  The hash is 
computed based
 on the chosen @var{scheme}, number of rounds @var{log2rounds} and
 specified @var{salt}.
 
-@var{length} must be at least @code{BLOWFISH_BCRYPT_HASH_SIZE}.
+@var{dst} must point to a character array of at least
+ @code{BLOWFISH_BCRYPT_HASH_SIZE} bytes.
 
-@var{dst} must point to a character array of the specified @var{length}.
+@var{key} contains the plaintext password string of size @var{lenkey}.
 
-@var{key} contains the zero terminated plaintext password string.
-
-@var{scheme} contains either just the chosen scheme (valid schemes
+@var{scheme} is of size @var{lenscheme} and contains either just the
+chosen scheme (valid schemes
 are: @code{2a}, @code{2b}, @code{2x} or @code{2y}), or
 (the prefix of) an existing hashed password (typically @code{$2b$10$...}).
 
@@ -1543,26 +1543,28 @@ the salt will be extracted from @var{scheme}.
 Sample code to generate a bcrypt hash:
 @example
 char cleartxtpassword[] = "ExamplePassword";
+char scheme[] = "2b";
 uint8_t salt[BLOWFISH_BCRYPT_BINSALT_SIZE];
 @dots{}
 /* Make sure that salt is filled with random bytes */
 @dots{}
 char hashedresult[BLOWFISH_BCRYPT_HASH_SIZE];
-int result = blowfish_bcrypt(sizeof(hashedresult), hashedresult,
-                             cleartxtpassword, "2b", 10, salt);
+int result = blowfish_bcrypt(hashedresult,
+                             sizeof(cleartxtpassword), cleartxtpassword,
+                             sizeof(scheme), scheme, 10, salt);
 if (result)
   printf("%s\n", hashedresult);
 @end example
 @end deftypefun
 
-@deftypefun int blowfish_bcrypt_verify (const char *@var{key}, const char 
*@var{hashed})
+@deftypefun int blowfish_bcrypt_verify (size_t @var{lenkey}, const char 
*@var{key}, size_t @var{lenhashed}, const char *@var{hashed})
 Verifies the bcrypt password hash against the supplied plaintext password.
 The function will return @code{0} if the password does not match.
 The function will return @code{1} if the password matches.
 
-@var{key} contains the zero terminated plaintext password string.
+@var{key} contains the plaintext password string of size @var{lenkey}.
 
-@var{hashed} contains the zero terminated hashed string to compare with.
+@var{hashed} contains the hashed string of size @var{lenhashed} to compare 
with.
 
 Sample code to verify a bcrypt hash:
 @example
@@ -1573,7 +1575,8 @@ char existinghashed[] =
            "$"   /* separator */
            "1b2lPgo4XumibnJGN3r3sO" /* base64 encoded 16-byte salt */
            "u7wE7xNfYDKlAxZffJDCJdVfFTAyevu"; /* Hashedpart */
-if (blowfish_bcrypt_verify(cleartxtpassword, existinghashed))
+if (blowfish_bcrypt_verify(sizeof(cleartxtpassword), cleartxtpassword,
+                           sizeof(existinghashed), existinghashed))
   printf("Password is correct.");
 else
   printf("Password is incorrect.");
-- 
2.20.1

_______________________________________________
nettle-bugs mailing list
[email protected]
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to