Skip to content

Commit

Permalink
Add support for PBKDFs
Browse files Browse the repository at this point in the history
Supports version 1 and 2, with sha1, sha256 and sha512.
Checked with the test vectors from:
  RFC6070
  https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors
  https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
  • Loading branch information
np committed Jan 16, 2015
1 parent 9a62219 commit 3c35724
Show file tree
Hide file tree
Showing 40 changed files with 781 additions and 8 deletions.
4 changes: 2 additions & 2 deletions default.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file was auto-generated by cabal2nix. Please do NOT edit manually!

{ cabal, aeson, attoparsec, base16Bytestring, binary, cryptohash
, either, hashable, haskoin, RFC1751, scientific, text
, either, hashable, haskoin, pbkdf, RFC1751, scientific, text
, unorderedContainers
}:

Expand All @@ -13,7 +13,7 @@ cabal.mkDerivation (self: {
isExecutable = true;
buildDepends = [
aeson attoparsec base16Bytestring binary cryptohash either hashable
haskoin RFC1751 scientific text unorderedContainers
haskoin pbkdf RFC1751 scientific text unorderedContainers
];
meta = {
homepage = "https://github.com/np/hx";
Expand Down
2 changes: 1 addition & 1 deletion hx.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ executable hx
ghc-options: -Wall
build-depends: base >=4.6, haskoin, bytestring, base16-bytestring,
scientific, binary, RFC1751 >= 0.3, containers,
aeson, cryptohash,
aeson, cryptohash, pbkdf,
-- required by aeson
attoparsec, hashable, unordered-containers, text,
-- required by haskoin
Expand Down
51 changes: 46 additions & 5 deletions hx.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ import qualified Data.ByteString.Lazy as LBS
import Crypto.MAC.HMAC (hmac)
import qualified Crypto.Hash.SHA224 as SHA224 (hash)
import qualified Crypto.Hash.SHA384 as SHA384 (hash)
import Crypto.PBKDF (sha1PBKDF1
,sha256PBKDF1
,sha512PBKDF1
,sha1PBKDF2
,sha256PBKDF2
,sha512PBKDF2
)

import Network.Haskoin.Crypto
import Network.Haskoin.Internals ( curveP, curveN, curveG, integerA, integerB
Expand Down Expand Up @@ -445,7 +452,26 @@ hx_showtx _ = error "Usage: hx showtx [-j|--json] [<TXFILE>]"

hx_hmac :: String -> (BS -> BS) -> Int -> [BS] -> BS
hx_hmac _ h s [key,input] = encodeHex $ hmac h s (decodeHex "hmac key" key) (decodeHex "hmac data" input)
hx_hmac m _ _ _ = error $ "hx hmac-" ++ m ++ " <KEY> [<INPUT>]"
hx_hmac m _ _ _ = error $ "hx hmac-" ++ m ++ " <HEX-KEY> [<HEX-INPUT>]"

hx_PBKDF1 :: (String -> String -> Int -> String) -> BS -> [BS] -> IO ()
hx_PBKDF1 f m = interactArgsLn go
where
usage = "hx " ++ B8.unpack m ++ " [--hex] <PASSWORD> [--hex] <SALT> <COUNT>"
go args0 = let (password,args1) = get_hex_arg "password" usage args0
(salt,args2) = get_hex_arg "salt" usage args1
(count,args3) = get_int_arg "count" usage args2
in no_args usage args3 . B8.pack $ f (B8.unpack password) (B8.unpack salt) count

hx_PBKDF2 :: (String -> String -> Int -> Int -> String) -> BS -> [BS] -> IO ()
hx_PBKDF2 f m = interactArgsLn go
where
usage = "hx " ++ B8.unpack m ++ " [--hex] <PASSWORD> [--hex] <SALT> <COUNT> <LENGTH>"
go args0 = let (password,args1) = get_hex_arg "password" usage args0
(salt,args2) = get_hex_arg "salt" usage args1
(count,args3) = get_int_arg "count" usage args2
(len,args4) = get_int_arg "length" usage args3
in no_args usage args4 . B8.pack $ f (B8.unpack password) (B8.unpack salt) count len

chksum32_encode :: BS -> BS
chksum32_encode d = d <> encode' (chksum32 d)
Expand Down Expand Up @@ -561,6 +587,12 @@ mainArgs ("hmac-sha224":args) = interactArgsLn (hx_hmac "sha224" SHA224.h
mainArgs ("hmac-sha256":args) = interactArgsLn (hx_hmac "sha256" hash256BS 64) args
mainArgs ("hmac-sha384":args) = interactArgsLn (hx_hmac "sha384" SHA384.hash 128) args
mainArgs ("hmac-sha512":args) = interactArgsLn (hx_hmac "sha512" hash512BS 128) args
mainArgs (arg@"sha1pbkdf1":args) = hx_PBKDF1 sha1PBKDF1 arg args
mainArgs (arg@"sha256pbkdf1":args) = hx_PBKDF1 sha256PBKDF1 arg args
mainArgs (arg@"sha512pbkdf1":args) = hx_PBKDF1 sha512PBKDF1 arg args
mainArgs (arg@"sha1pbkdf2":args) = hx_PBKDF2 sha1PBKDF2 arg args
mainArgs (arg@"sha256pbkdf2":args) = hx_PBKDF2 sha256PBKDF2 arg args
mainArgs (arg@"sha512pbkdf2":args) = hx_PBKDF2 sha512PBKDF2 arg args

mainArgs ("chksum32":args) = interactArgs hx_chksum32 args
mainArgs ("chksum32-encode":args) = interactArgs hx_chksum32_encode args
Expand Down Expand Up @@ -707,10 +739,19 @@ mainArgs _ = error $ unlines ["Unexpected arguments."
,"hx hash256 [0]"
,""
,"# HASH BASED MACs"
,"hx hmac-sha224 <KEY> [<HEX-INPUT>] [0]"
,"hx hmac-sha256 <KEY> [<HEX-INPUT>] [0]"
,"hx hmac-sha384 <KEY> [<HEX-INPUT>] [0]"
,"hx hmac-sha512 <KEY> [<HEX-INPUT>] [0]"
-- TODO the second argument is not optional yet
,"hx hmac-sha224 <HEX-KEY> [<HEX-INPUT>] [0]"
,"hx hmac-sha256 <HEX-KEY> [<HEX-INPUT>] [0]"
,"hx hmac-sha384 <HEX-KEY> [<HEX-INPUT>] [0]"
,"hx hmac-sha512 <HEX-KEY> [<HEX-INPUT>] [0]"
,""
,"# PASSWORD BASED KEY DERIVATION FUNCTIONS"
,"hx sha1pbkdf1 [--hex] <PASSWORD> [--hex] <SALT> <COUNT> [0]"
,"hx sha256pbkdf1 [--hex] <PASSWORD> [--hex] <SALT> <COUNT> [0]"
,"hx sha512pbkdf1 [--hex] <PASSWORD> [--hex] <SALT> <COUNT> [0]"
,"hx sha1pbkdf2 [--hex] <PASSWORD> [--hex] <SALT> <COUNT> <LENGTH> [0]"
,"hx sha256pbkdf2 [--hex] <PASSWORD> [--hex] <SALT> <COUNT> <LENGTH> [0]"
,"hx sha512pbkdf2 [--hex] <PASSWORD> [--hex] <SALT> <COUNT> <LENGTH> [0]"
,""
,"[0]: Not available in sx"
,"[1]: `hx showtx` is always using JSON output,"
Expand Down
42 changes: 42 additions & 0 deletions tests/SHA256PBKDF2-password-salt-1-32.t/TESTRECIPE
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

testname=SHA256PBKDF2-password-salt-1-32.t
command=hx
args=( SHA256PBKDF2 password salt 1 32 )
exit_code=0
stdin_file=/dev/null
stdout_file=stdout
stderr_file=/dev/null
sources=( )
products=( )

# Environment variables:
env_vars=( )

setup(){
: Perform here actions to be run before the tested program
}

munge(){
: Munge here the results of the tested program to ease the check
}

check(){
check_exit_code &&
check_stderr &&
check_stdout &&
check_products &&
: Perform here extra checks on the tested program
}

explain(){
explain_exit_code
explain_stdout
explain_stderr
explain_products
: Explain here more potential differences
}

teardown(){
: Undo here the actions of setup
}
1 change: 1 addition & 0 deletions tests/SHA256PBKDF2-password-salt-1-32.t/stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b
42 changes: 42 additions & 0 deletions tests/SHA256PBKDF2-password-salt-2-32.t/TESTRECIPE
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

testname=SHA256PBKDF2-password-salt-2-32.t
command=hx
args=( SHA256PBKDF2 password salt 2 32 )
exit_code=0
stdin_file=/dev/null
stdout_file=stdout
stderr_file=/dev/null
sources=( )
products=( )

# Environment variables:
env_vars=( )

setup(){
: Perform here actions to be run before the tested program
}

munge(){
: Munge here the results of the tested program to ease the check
}

check(){
check_exit_code &&
check_stderr &&
check_stdout &&
check_products &&
: Perform here extra checks on the tested program
}

explain(){
explain_exit_code
explain_stdout
explain_stderr
explain_products
: Explain here more potential differences
}

teardown(){
: Undo here the actions of setup
}
1 change: 1 addition & 0 deletions tests/SHA256PBKDF2-password-salt-2-32.t/stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43
42 changes: 42 additions & 0 deletions tests/SHA256PBKDF2-password-salt-4096-32.t/TESTRECIPE
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

testname=SHA256PBKDF2-password-salt-4096-32.t
command=hx
args=( SHA256PBKDF2 password salt 4096 32 )
exit_code=0
stdin_file=/dev/null
stdout_file=stdout
stderr_file=/dev/null
sources=( )
products=( )

# Environment variables:
env_vars=( )

setup(){
: Perform here actions to be run before the tested program
}

munge(){
: Munge here the results of the tested program to ease the check
}

check(){
check_exit_code &&
check_stderr &&
check_stdout &&
check_products &&
: Perform here extra checks on the tested program
}

explain(){
explain_exit_code
explain_stdout
explain_stderr
explain_products
: Explain here more potential differences
}

teardown(){
: Undo here the actions of setup
}
1 change: 1 addition & 0 deletions tests/SHA256PBKDF2-password-salt-4096-32.t/stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

testname=SHA256PBKDF2-passwordPASSWORDpassword-saltSALTsaltSALTsaltSALTsaltSALTsalt-4096-40.t
command=hx
args=( SHA256PBKDF2 passwordPASSWORDpassword saltSALTsaltSALTsaltSALTsaltSALTsalt 4096 40 )
exit_code=0
stdin_file=/dev/null
stdout_file=stdout
stderr_file=/dev/null
sources=( )
products=( )

# Environment variables:
env_vars=( )

setup(){
: Perform here actions to be run before the tested program
}

munge(){
: Munge here the results of the tested program to ease the check
}

check(){
check_exit_code &&
check_stderr &&
check_stdout &&
check_products &&
: Perform here extra checks on the tested program
}

explain(){
explain_exit_code
explain_stdout
explain_stderr
explain_products
: Explain here more potential differences
}

teardown(){
: Undo here the actions of setup
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

testname=SHA512PBKDF2-gloom-knee-orient-skull-dance-awake-payment-unusual-inflict-cinnamon-blush-seed-elder-crawl-size-catch-inflict-perfect-foster-sugar-fox-mnemonic-2048-64.t
command=hx
args=( SHA512PBKDF2 gloom\ knee\ orient\ skull\ dance\ awake\ payment\ unusual\ inflict\ cinnamon\ blush\ seed\ elder\ crawl\ size\ catch\ inflict\ perfect\ foster\ sugar\ fox mnemonic 2048 64 )
exit_code=0
stdin_file=/dev/null
stdout_file=stdout
stderr_file=/dev/null
sources=( )
products=( )

# Environment variables:
env_vars=( )

setup(){
: Perform here actions to be run before the tested program
}

munge(){
: Munge here the results of the tested program to ease the check
}

check(){
check_exit_code &&
check_stderr &&
check_stdout &&
check_products &&
: Perform here extra checks on the tested program
}

explain(){
explain_exit_code
explain_stdout
explain_stderr
explain_products
: Explain here more potential differences
}

teardown(){
: Undo here the actions of setup
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1929625a9cb3ff0fc1a2bc5288807730469969278dc9629926a862cf3932bd888cb0d621f818ee7bee359281e9aa08f35deaa0dd559be5041bbc4c64ff57d7c6
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

testname=SHA512PBKDF2-gloom-knee-orient-skull-dance-awake-payment-unusual-inflict-cinnamon-blush-seed-elder-crawl-size-catch-inflict-perfect-foster-sugar-fox-mnemonichunter2-2048-64.t
command=hx
args=( SHA512PBKDF2 gloom\ knee\ orient\ skull\ dance\ awake\ payment\ unusual\ inflict\ cinnamon\ blush\ seed\ elder\ crawl\ size\ catch\ inflict\ perfect\ foster\ sugar\ fox mnemonichunter2 2048 64 )
exit_code=0
stdin_file=/dev/null
stdout_file=stdout
stderr_file=/dev/null
sources=( )
products=( )

# Environment variables:
env_vars=( )

setup(){
: Perform here actions to be run before the tested program
}

munge(){
: Munge here the results of the tested program to ease the check
}

check(){
check_exit_code &&
check_stderr &&
check_stdout &&
check_products &&
: Perform here extra checks on the tested program
}

explain(){
explain_exit_code
explain_stdout
explain_stderr
explain_products
: Explain here more potential differences
}

teardown(){
: Undo here the actions of setup
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
07630c4bd98dce320c60d103323907252ffedc4c68d7564e5536077f696946bd247532152ae61d4b7c34a5883ee30d2e691ad184818d3b6e68e4f93089ad8bbd
Loading

0 comments on commit 3c35724

Please sign in to comment.