password-2.0.0.0: test/tasty/PBKDF2.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module PBKDF2 where
import Crypto.Hash.Algorithms as Crypto (HashAlgorithm, SHA1(..), SHA256(..), SHA512(..))
import Crypto.KDF.PBKDF2 as PBKDF2
import Data.ByteString (ByteString)
#if !MIN_VERSION_base(4,13,0)
import Data.Semigroup ((<>))
#endif
import Test.Tasty
import Test.Tasty.QuickCheck
import Test.QuickCheck.Instances.ByteString ()
import Test.QuickCheck.Instances.Text ()
import Data.Password.PBKDF2
import Internal
_10k :: Num a => a
_10k = 10 * 1000
testPBKDF2 :: TestTree
testPBKDF2 = testGroup "PBKDF2"
[ testIt "PBKDF2 (hashPassword)" $ _10k defaultParams -- This is PBKDF2_SHA512
, testIncorrectPassword_
"PBKDF2 (hashPassword) fail"
(hashPasswordWithParams $ _10k defaultParams)
checkPassword
, testWithSalt
"PBKDF2 (hashPasswordWithSalt)"
(hashPasswordWithSalt $ _10k defaultParams)
checkPassword
, testIt "PBKDF2 (md5)" (defaultParams{ pbkdf2Algorithm = PBKDF2_MD5, pbkdf2Iterations = 5000 })
, testIt "PBKDF2 (sha1)" (_10k defaultParams{ pbkdf2Algorithm = PBKDF2_SHA1 })
, testIt "PBKDF2 (sha256)" (_10k defaultParams{ pbkdf2Algorithm = PBKDF2_SHA256 })
, testFast Crypto.SHA1 20 PBKDF2.fastPBKDF2_SHA1
, testFast Crypto.SHA256 32 PBKDF2.fastPBKDF2_SHA256
, testFast Crypto.SHA512 64 PBKDF2.fastPBKDF2_SHA512
-- Check to see if a hash with "pbkdf2:" prefixed also works
, testCorrectPassword
"PBKDF2 (pbkdf2:sha-...)"
(hashPasswordWithParams $ _10k defaultParams)
(\pass (PasswordHash hash) -> checkPassword pass . PasswordHash $ "pbkdf2:" <> hash)
]
where
testIt s params = testCorrectPassword s (hashPasswordWithParams params) checkPassword
_10k params = params{ pbkdf2Iterations = 10 * 1000 }
testFast :: (HashAlgorithm a, Show a)
=> a
-> Int
-> (Parameters -> ByteString -> ByteString -> ByteString)
-> TestTree
testFast alg i f = testProperty s $ \pass salt -> run10 $
return $ f params pass salt ===
PBKDF2.generate (PBKDF2.prfHMAC alg) params pass salt
where
params = cryptoParams i
s = sAlg ++ " HMAC == fast_" ++ sAlg
sAlg = show alg
cryptoParams :: Int -> PBKDF2.Parameters
cryptoParams i = PBKDF2.Parameters {
PBKDF2.iterCounts = 5000,
PBKDF2.outputLength = i
}