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