packages feed

pbkdf (empty) → 1.0.0.0

raw patch · 7 files changed

+328/−0 lines, 7 filesdep +basedep +binarydep +byteablesetup-changed

Dependencies added: base, binary, byteable, bytedump, bytestring, cryptohash, pbkdf, utf8-string

Files

+ Crypto/PBKDF.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE BangPatterns       #-}+{-# LANGUAGE RecordWildCards    #-}++module Crypto.PBKDF +    ( sha1PBKDF1+    , sha256PBKDF1+    , sha512PBKDF1+    , sha1PBKDF2+    , sha256PBKDF2+    , sha512PBKDF2+    ) where++import           Crypto.PBKDF.Core+import           Text.Bytedump+++-- | Password Based Key Derivation Functions:+--   This module provides stock implementations of the PBKDF functions from+--   RFC-2898 based on the SHA-1, SHA-256 and SHA-256 hash functions. Each+--   function takes the password and salt as a string and returns a hex+--   string. To work with ByteStrings and provide your own hash and+--   psuedo-random use the Crypto.PBKDF.Core that are used to implement+--   these functions.+++-- | SHA-based PBKDF1 functions++sha1PBKDF1, sha256PBKDF1, sha512PBKDF1 +    :: String   -- ^ the password (will be encoded with UTF-8) +    -> String   -- ^ the salt     (will be encoded with UTF-8)+    -> Int      -- ^ the iteration count+    -> String   -- ^ the result key as a hex string+sha1PBKDF1   pw_s na_s c = dumpRawBS $ pbkdf1_ $ sha1PBKDF   pw_s na_s c 0+sha256PBKDF1 pw_s na_s c = dumpRawBS $ pbkdf1_ $ sha256PBKDF pw_s na_s c 0+sha512PBKDF1 pw_s na_s c = dumpRawBS $ pbkdf1_ $ sha512PBKDF pw_s na_s c 0+++-- | SHA-based PBKDF2 functions++sha1PBKDF2, sha256PBKDF2, sha512PBKDF2+    :: String   -- ^ the password (will be encoded with UTF-8) +    -> String   -- ^ the salt     (will be encoded with UTF-8)+    -> Int      -- ^ the iteration count+    -> Int      -- ^ the length of the key to be generated (in octets)+    -> String   -- ^ the result key as a hex string++sha1PBKDF2   pw_s na_s c dkLen = dumpRawBS $ pbkdf2_ $ sha1PBKDF   pw_s na_s c dkLen+sha256PBKDF2 pw_s na_s c dkLen = dumpRawBS $ pbkdf2_ $ sha256PBKDF pw_s na_s c dkLen+sha512PBKDF2 pw_s na_s c dkLen = dumpRawBS $ pbkdf2_ $ sha512PBKDF pw_s na_s c dkLen
+ Crypto/PBKDF/Core.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE BangPatterns       #-}+{-# LANGUAGE RecordWildCards    #-}++module Crypto.PBKDF.Core+    ( sha1PBKDF+    , sha256PBKDF+    , sha512PBKDF+    , pbkdf+    , PBKDF(..)+    , PRF(..)+    , pbkdf1_+    , pbkdf2_+    ) where++import qualified Data.Binary                    as B+import           Data.Bits+import qualified Data.ByteString                as BS+import qualified Data.ByteString.UTF8           as BU+import qualified Data.ByteString.Lazy           as BLC+import qualified Crypto.Hash                    as CH+import           Crypto.MAC.HMAC+import           Data.Byteable+++-- | SHA-1 generator++sha1PBKDF :: String -> String -> Int -> Int -> PBKDF+sha1PBKDF =+    pbkdf+        PRF+            { prf_hmac      = hmac sha1 64          -- 512-bit block+            , prf_hash      = sha1                  -- SHA-1+            , prf_hLen      = 20                    -- 160-bit hash+            } +  where+    sha1 = toBytes . (CH.hash :: BS.ByteString -> CH.Digest CH.SHA1)++-- | SHA-256 generator++sha256PBKDF :: String -> String -> Int -> Int -> PBKDF+sha256PBKDF =+    pbkdf+        PRF+            { prf_hmac      = hmac sha256 64        -- 512-bit block+            , prf_hash      = sha256                -- SHA-256+            , prf_hLen      = 32                    -- 256-bit hash+            } +  where+    sha256 = toBytes . (CH.hash :: BS.ByteString -> CH.Digest CH.SHA256)++-- | SHA-512 generator++sha512PBKDF :: String -> String -> Int -> Int -> PBKDF+sha512PBKDF =+    pbkdf+        PRF+            { prf_hmac      = hmac sha512 128       -- 1024-bit block+            , prf_hash      = sha512                -- SHA-512+            , prf_hLen      = 64                    -- 512-bit hash+            } +  where+    sha512 = toBytes . (CH.hash :: BS.ByteString -> CH.Digest CH.SHA512)++-- | construct a PBKDF generator from a HMAC function++pbkdf :: PRF -> String -> String -> Int -> Int -> PBKDF+pbkdf prf pw_s na_s c dkLen =+    PBKDF+        { pbkdf_PRF    = prf+        , pbkdf_P      = BU.fromString pw_s+        , pbkdf_S      = BU.fromString na_s+        , pbkdf_c      = c+        , pbkdf_dkLen  = dkLen+        }++-- | PBKDF generator parameters++data PBKDF+    = PBKDF+        { pbkdf_PRF    :: PRF              -- ^ the psuedo-random (i.e., HMAC) function+        , pbkdf_P      :: BS.ByteString    -- ^ the password (will be UTF-8 encoded)+        , pbkdf_S      :: BS.ByteString    -- ^ the salt     (will be UTF-8 encoded)+        , pbkdf_c      :: Int              -- ^ iteration count for applying the HMAC+        , pbkdf_dkLen  :: Int              -- ^ the length of the o/p derived key +        }++-- | the HMAC function and its underlying HASH function++data PRF+    = PRF+        { prf_hmac      :: BS.ByteString -> BS.ByteString -> BS.ByteString  -- ^ the PR/HMAC function+        , prf_hash      :: BS.ByteString -> BS.ByteString                   -- ^ the underlying hash function+        , prf_hLen      :: Int                                              -- ^ number of octets in o/p hash+        } +++-- | the pbkdf1_ core function++pbkdf1_ :: PBKDF -> BS.ByteString+pbkdf1_ PBKDF{..} = iterate_n pbkdf_c prf_hash $ pbkdf_P `BS.append` pbkdf_S+  where+    PRF{..} = pbkdf_PRF++-- | the pbkdf2_ core function++pbkdf2_ :: PBKDF -> BS.ByteString+pbkdf2_ PBKDF{..} = BS.take pbkdf_dkLen $ BS.concat $ map f $ zip zbs ivs+  where+    f (zb,iv)   = snd $ itr zb $ pbkdf_S `BS.append` iv++    itr zb msg  = iterate_n pbkdf_c g (msg,zb)++    g (!u,!p)   = (u',BS.pack $ BS.zipWith xor p u')+      where+        u' = prf_hmac pbkdf_P u++    r           = pbkdf_dkLen - (l - 1) * prf_hLen++    l           = ceiling $ (fromIntegral pbkdf_dkLen :: Double) / fromIntegral prf_hLen+    +    zbs         = replicate l (mk_zb prf_hLen) ++ [mk_zb r]+    +    mk_zb sz    = BS.pack $ replicate sz 0++    PRF{..}     = pbkdf_PRF++    ivs = [ BS.pack $ drop (length os - 4) os | bno<-bnos, let os = BLC.unpack $ B.encode bno ]+      where+        bnos = [1..] :: [Int]++-- iterate a function over an argument k times++iterate_n :: Int -> (a->a) -> a -> a+iterate_n !i f !x =+    case i of+      0 -> x+      _ -> iterate_n (i-1) f $ f x
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright 2001-2005, Chris Dornan++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++- Redistributions of source code must retain the above copyright notice,+this list of conditions and the following disclaimer.+ +- Redistributions in binary form must reproduce the above copyright notice,+this list of conditions and the following disclaimer in the documentation+and/or other materials provided with the distribution.+ +- The name of the authors may not be used to endorse or promote products+derived from this software without specific prior written permission. ++THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF+THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,5 @@+pbkdf+=====++The Password Based Key Derivation Functions described in RFC 2898 with+a test suite based on the test vectors published in RFC6070.
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Distribution.Simple++main :: IO ()+main = defaultMain
+ pbkdf.cabal view
@@ -0,0 +1,58 @@+Name:                pbkdf+Version:             1.0.0.0+Synopsis:            Haskell implementation of the PBKDF functions from RFC-2898.+Description:         The Password Based Key Derivation Functions described in RFC-2898 with a test suite to verify that it works with the test vectors published in RFC6070.+Homepage:            https://github.com/cdornan/pbkdf+License:             BSD3+License-file:        LICENSE+Author:              Chris Dornan+Maintainer:          chris.dornan@irisconnect.com+Copyright:           (C) Chris Dornan+Category:            Cryptography+Build-type:          Simple++Cabal-version:       >=1.14++Source-repository this+    type:           git+    location:       https://github.com/cdornan/pbkdf.git+    tag:            1.0.0.0++Source-repository head+    type:           git+    location:       https://github.com/cdornan/pbkdf.git++Library+    Exposed-modules:+        Crypto.PBKDF+        Crypto.PBKDF.Core++    Build-depends:+        base                >= 4.5   && < 5.0       ,+        binary              >= 0.5                  ,+        byteable            >= 0.1                  ,+        bytedump            >= 1.0                  ,+        bytestring          >= 0.9                  ,+        cryptohash          >= 0.10                 ,+        utf8-string         >= 0.3.7+        +    GHC-Options: -Wall++    Default-Language: Haskell2010++Test-Suite rfc-6070+    type:          exitcode-stdio-1.0+    main-is:       rfc6070.hs+    Build-depends:+        base                >= 4.5                  ,+        binary              >= 0.5                  ,+        byteable            >= 0.1                  ,+        bytedump            >= 1.0                  ,+        bytestring          >= 0.9                  ,+        cryptohash          >= 0.10                 ,+        pbkdf                                       ,+        utf8-string         >= 0.3.7++    GHC-Options: -Wall++    Default-Language: Haskell2010
+ rfc6070.hs view
@@ -0,0 +1,46 @@++import           Crypto.PBKDF+import           Text.Printf+import           Control.Applicative+import           System.Exit+++main :: IO ()+main = + do ok <- run_tests+    case ok of+      True  -> return ()+      False -> exitWith $ ExitFailure 1++run_tests :: IO Bool+run_tests = and <$> mapM test test_vectors+  where+    test (pw,na,c,out) =+     do putStr $ printf "%-30s %-40s %8d (%d) : " (show pw) (show na) c dkl+        case ok of+          True  -> putStrLn          "passed"+          False -> putStrLn $ printf "FAILED (%s[%d])" t_out (length t_out)+        return ok+      where+        ok    = t_out == out+        t_out = sha1PBKDF2 pw na c dkl+        dkl   = length out `div` 2++-- RFC6070 test vectors++test_vectors :: [(String,String,Int,String)]+test_vectors = +    [ (,,,) "password"                  "salt"                                  1           "0c60c80f961f0e71f3a9b524af6012062fe037a6"+    , (,,,) "password"                  "salt"                                  2           "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"+    , (,,,) "password"                  "salt"                                  4096        "4b007901b765489abead49d926f721d065a429c1"+    , (,,,) "password"                  "salt"                                  16777216    "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984"+    , (,,,) "passwordPASSWORDpassword"  "saltSALTsaltSALTsaltSALTsaltSALTsalt"  4096        "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"+    , (,,,) "pass\0word"                "sa\0lt"                                4096        "56fa6aa75548099dcc37d7f03425e0c3"+    ]++--simple_test :: IO ()+--simple_test = putStrLn $ sha1PBKDF2   "password" "salt" 4096  20++--sha256_test :: IO ()+--sha256_test = putStrLn $ sha256PBKDF2 "password" "salt" 1000000 32+