packages feed

crypton-2.0.0: tests/KDF/BCryptPBKDFSpec.hs

{-# LANGUAGE OverloadedStrings #-}

module KDF.BCryptPBKDFSpec (spec) where

import qualified Data.ByteString as B

import Control.Exception (evaluate)
import Test.Hspec

import Crypto.Error
import Crypto.KDF.BCryptPBKDF (
    Parameters (..),
    generate,
    tryGenerate,
    hashInternal,
    tryHashInternal,
 )

spec :: Spec
spec = do
    describe "generate" $ do
        it "1" generate1
        it "2" generate2
        it "3" generate3
    describe "hashInternal" $ do
        it "1" hashInternal1
    describe "invalid parameters" $ do
        it "rejects an iteration count below one" $
            evaluate (run (Parameters 0 32)) `shouldThrow` cryptoError
        it "rejects an output length of zero" $
            evaluate (run (Parameters 1 0)) `shouldThrow` cryptoError
        it "rejects an output length above 1024" $
            evaluate (run (Parameters 1 1025)) `shouldThrow` cryptoError
        it "reports them without raising" $ do
            run' (Parameters 0 32) `shouldBe` refused
            run' (Parameters 1 0) `shouldBe` refused
            run' (Parameters 1 1025) `shouldBe` refused
        it "rejects a hashInternal input that is not 512 bits" $ do
            evaluate
                (hashInternal (B.replicate 63 0x61) (B.replicate 64 0x61) :: B.ByteString)
                `shouldThrow` cryptoError
            ( tryHashInternal (B.replicate 64 0x61) (B.replicate 63 0x61)
                    :: CryptoFailable B.ByteString
                )
                `shouldBe` refused
  where
    run params =
        generate params ("password" :: B.ByteString) ("salt" :: B.ByteString)
            :: B.ByteString
    run' params =
        tryGenerate params ("password" :: B.ByteString) ("salt" :: B.ByteString)
            :: CryptoFailable B.ByteString
    refused = CryptoFailed CryptoError_ParameterInvalid
    cryptoError e = e == CryptoError_ParameterInvalid
    -- test vector taken from the go implementation by @dchest
    generate1 = generate params pass salt `shouldBe` expected
      where
        params = Parameters 12 32
        pass = "password" :: B.ByteString
        salt = "salt" :: B.ByteString
        expected =
            B.pack
                [ 0x1a
                , 0xe4
                , 0x2c
                , 0x05
                , 0xd4
                , 0x87
                , 0xbc
                , 0x02
                , 0xf6
                , 0x49
                , 0x21
                , 0xa4
                , 0xeb
                , 0xe4
                , 0xea
                , 0x93
                , 0xbc
                , 0xac
                , 0xfe
                , 0x13
                , 0x5f
                , 0xda
                , 0x99
                , 0x97
                , 0x4c
                , 0x06
                , 0xb7
                , 0xb0
                , 0x1f
                , 0xae
                , 0x14
                , 0x9a
                ]
                :: B.ByteString

    -- test vector generated with the go implemenation by @dchest
    generate2 = generate params pass salt `shouldBe` expected
      where
        params = Parameters 7 71
        pass = "DieWuerdeDesMenschenIstUnantastbar" :: B.ByteString
        salt = "Tafelsalz" :: B.ByteString
        expected =
            B.pack
                [ 0x17
                , 0xb4
                , 0x76
                , 0xaa
                , 0xd7
                , 0x42
                , 0x33
                , 0x49
                , 0x5c
                , 0xe8
                , 0x79
                , 0x49
                , 0x15
                , 0x74
                , 0x4c
                , 0x71
                , 0xf9
                , 0x99
                , 0x66
                , 0x89
                , 0x7a
                , 0x60
                , 0xc3
                , 0x70
                , 0xb4
                , 0x3c
                , 0xa8
                , 0x83
                , 0x80
                , 0x5a
                , 0x56
                , 0xde
                , 0x38
                , 0xbc
                , 0x51
                , 0x8c
                , 0xd4
                , 0xeb
                , 0xd1
                , 0xcf
                , 0x46
                , 0x0a
                , 0x68
                , 0x3d
                , 0xc8
                , 0x12
                , 0xcf
                , 0xf8
                , 0x43
                , 0xce
                , 0x21
                , 0x9d
                , 0x98
                , 0x81
                , 0x20
                , 0x26
                , 0x6e
                , 0x42
                , 0x0f
                , 0xaa
                , 0x75
                , 0x5d
                , 0x09
                , 0x8d
                , 0x45
                , 0xda
                , 0xd5
                , 0x15
                , 0x6e
                , 0x65
                , 0x1d
                ]
                :: B.ByteString

    -- test vector generated with the go implemenation by @dchest
    generate3 = generate params pass salt `shouldBe` expected
      where
        params = Parameters 5 5
        pass = "ABC" :: B.ByteString
        salt = "DEF" :: B.ByteString
        expected =
            B.pack
                [ 0xdd
                , 0x6e
                , 0xa0
                , 0x69
                , 0x29
                ]
                :: B.ByteString

    hashInternal1 = hashInternal passHash saltHash `shouldBe` expected
      where
        passHash = B.pack [0 .. 63] :: B.ByteString
        saltHash = B.pack [64 .. 127] :: B.ByteString
        expected =
            B.pack
                [ 0x87
                , 0x90
                , 0x48
                , 0x70
                , 0xee
                , 0xf9
                , 0xde
                , 0xdd
                , 0xf8
                , 0xe7
                , 0x61
                , 0x1a
                , 0x14
                , 0x01
                , 0x06
                , 0xe6
                , 0xaa
                , 0xf1
                , 0xa3
                , 0x63
                , 0xd9
                , 0xa2
                , 0xc5
                , 0x04
                , 0xdb
                , 0x35
                , 0x64
                , 0x43
                , 0x72
                , 0x1e
                , 0xb5
                , 0x55
                ]
                :: B.ByteString