From d27d4646278372549e0540797a48ac4b0ecaecd0 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Tue, 17 Apr 2018 13:46:51 +0100 Subject: [PATCH] Fix cost parsing for bcrypt The tens value was wrong for values of 20+, as reported in #230. It should be 10*costTens not 10^costTens. This wasn't detected because the values are the same when costTens is 1, and using high cost values is rare with bcrypt because of the performance hit. Also added a simple hash and validate test since the KAT tests only do validation. This doesn't cover this bug since the cost value is too high to include in the test. It allows similar issues to be tested locally though. --- Crypto/KDF/BCrypt.hs | 2 +- tests/BCrypt.hs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Crypto/KDF/BCrypt.hs b/Crypto/KDF/BCrypt.hs index 745de0f..b374b4f 100644 --- a/Crypto/KDF/BCrypt.hs +++ b/Crypto/KDF/BCrypt.hs @@ -159,7 +159,7 @@ parseBCryptHash bc = do costTens = fromIntegral (B.index bc 4) - zero costUnits = fromIntegral (B.index bc 5) - zero version = chr (fromIntegral (B.index bc 2)) - cost = costUnits + (if costTens == 0 then 0 else 10^costTens) :: Int + cost = costUnits + 10*costTens :: Int decodeSaltHash saltHash = do let (s, h) = B.splitAt 22 saltHash diff --git a/tests/BCrypt.hs b/tests/BCrypt.hs index 0a932f2..8a9562b 100644 --- a/tests/BCrypt.hs +++ b/tests/BCrypt.hs @@ -75,4 +75,8 @@ makeKATs = concatMap maketest (zip3 is passwords hashes) tests = testGroup "bcrypt" [ testGroup "KATs" makeKATs , testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash format") (validatePasswordEither B.empty ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: B.ByteString))) + , testCase "Hash and validate" (assertBool "Hashed password should validate" (validatePassword somePassword (bcrypt 5 aSalt somePassword :: B.ByteString))) ] + where + somePassword = "some password" :: B.ByteString + aSalt = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" :: B.ByteString