Permalink
Browse files

Fixed to_hex to return binary if it gets a binary, and removed the ab…

…ility to pass arbitrary digest functions, since crypto:hmac doesn't support it.
  • Loading branch information...
1 parent 9d9946e commit 267eb2c97c07f7f5bec83c12b36cd6cd3a90d5e5 @whitelynx committed Mar 3, 2013
Showing with 45 additions and 66 deletions.
  1. +45 −66 src/pbkdf2.erl
View
@@ -19,20 +19,10 @@
-type(hex_char() :: 48 .. 57 | 97 .. 102).
-type(hex_list() :: [hex_char()]).
--type digest_func() :: fun((Data :: binary()) -> Hash :: binary()).
-%-type mac_func() :: fun((Key :: binary(), Data :: binary(), MacLength :: integer()) -> Mac :: binary()).
--type mac_func() :: fun((Key :: binary(), Data :: binary()) -> Mac :: binary()).
+-type digest_func_info() :: md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512.
--type(digest_func_info() ::
- digest_func() | {digest_func(), DigestLength :: integer()}
- | md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512
-).
-
--type(mac_func_info() ::
- mac_func() | {hmac, digest_func_info()}
- | md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512
-).
+-type mac_func_info() :: {hmac, digest_func_info()} | digest_func_info().
-define(MAX_DERIVED_KEY_LENGTH, (1 bsl 32 - 1)).
@@ -50,7 +40,7 @@
pbkdf2(MacFunc, Password, Salt, Iterations) ->
MacFunc1 = resolve_mac_func(MacFunc),
DerivedLength = byte_size(MacFunc1(<<"test key">>, <<"test data">>)),
- pbkdf2(MacFunc1, Password, Salt, Iterations, DerivedLength, 1, []).
+ pbkdf2(MacFunc1, Password, Salt, Iterations, DerivedLength, 1, []).
%----------------------------------------------------------------------------------------------------------------------
@@ -63,12 +53,12 @@ pbkdf2(MacFunc, Password, Salt, Iterations) ->
Key :: binary().
pbkdf2(_MacFunc, _Password, _Salt, _Iterations, DerivedLength) when DerivedLength > ?MAX_DERIVED_KEY_LENGTH ->
- {error, derived_key_too_long};
+ {error, derived_key_too_long};
pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength) ->
MacFunc1 = resolve_mac_func(MacFunc),
- Bin = pbkdf2(MacFunc1, Password, Salt, Iterations, DerivedLength, 1, []),
- {ok, Bin}.
+ Bin = pbkdf2(MacFunc1, Password, Salt, Iterations, DerivedLength, 1, []),
+ {ok, Bin}.
%======================================================================================================================
% Internal Functions
@@ -83,13 +73,15 @@ pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength) ->
Acc :: iolist(),
Key :: binary().
-pbkdf2(_MacFunc, _Password, _Salt, _Iterations, DerivedLength, _BlockIndex, Acc) when length(Acc) > DerivedLength ->
- <<Bin:DerivedLength/binary, _/binary>> = iolist_to_binary(lists:reverse(Acc)),
- Bin;
-
pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength, BlockIndex, Acc) ->
- Block = pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, 1, <<>>, <<>>),
- pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength, BlockIndex + 1, [Block | Acc]).
+ case iolist_size(Acc) > DerivedLength of
+ true ->
+ <<Bin:DerivedLength/binary, _/binary>> = iolist_to_binary(lists:reverse(Acc)),
+ Bin;
+ false ->
+ Block = pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, 1, <<>>, <<>>),
+ pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength, BlockIndex + 1, [Block | Acc])
+ end.
%----------------------------------------------------------------------------------------------------------------------
@@ -105,48 +97,29 @@ pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength, BlockIndex, Acc) ->
Key :: binary().
pbkdf2(_MacFunc, _Password, _Salt, Iterations, _BlockIndex, Iteration, _Prev, Acc) when Iteration > Iterations ->
- Acc;
+ Acc;
pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, 1, _Prev, _Acc) ->
- InitialBlock = MacFunc(Password, <<Salt/binary, BlockIndex:32/integer>>),
- pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, 2, InitialBlock, InitialBlock);
+ InitialBlock = MacFunc(Password, <<Salt/binary, BlockIndex:32/integer>>),
+ pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, 2, InitialBlock, InitialBlock);
pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, Iteration, Prev, Acc) ->
- Next = MacFunc(Password, Prev),
- pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, Iteration + 1, Next, crypto:exor(Next, Acc)).
-
-%----------------------------------------------------------------------------------------------------------------------
-
-%-type digest_func_info() :: digest_func() | {digest_func(), DigestLength}
-% | md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512.
-
-resolve_digest_func({DigestFunc, DigestLength}) when is_function(DigestFunc) ->
- {DigestFunc, DigestLength};
-
-resolve_digest_func(md4) -> {crypto, md4};
-resolve_digest_func(md5) -> {crypto, md5};
-resolve_digest_func(ripemd160) -> {crypto, ripemd160};
-resolve_digest_func(sha) -> {crypto, sha};
-resolve_digest_func(sha224) -> {crypto, sha224};
-resolve_digest_func(sha256) -> {crypto, sha256};
-resolve_digest_func(sha384) -> {crypto, sha384};
-resolve_digest_func(sha512) -> {crypto, sha512}.
+ Next = MacFunc(Password, Prev),
+ pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, Iteration + 1, Next, crypto:exor(Next, Acc)).
%----------------------------------------------------------------------------------------------------------------------
%-type mac_func_info() :: mac_func() | {hmac, digest_func_info()}
% | md4 | md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512.
resolve_mac_func({hmac, DigestFunc}) ->
- DigestFunc1 = resolve_digest_func(DigestFunc),
fun(Key, Data) ->
- crypto:hmac(DigestFunc1, Key, Data)
+ %crypto:hmac(DigestFunc, Key, Data)
+ HMAC = crypto:hmac_init(DigestFunc, Key),
+ HMAC1 = crypto:hmac_update(HMAC, Data),
+ crypto:hmac_final(HMAC1)
end;
-% fun(Key, Data, MacLength) ->
-% crypto:hmac(DigestFunc1, Key, Data, MacLength)
-% end;
-
resolve_mac_func(MacFunc) when is_function(MacFunc) ->
MacFunc;
@@ -168,15 +141,15 @@ resolve_mac_func(sha512) -> resolve_mac_func({hmac, sha512}).
Second :: binary() | string().
compare_secure(<<X/binary>>, <<Y/binary>>) ->
- compare_secure(binary_to_list(X), binary_to_list(Y));
+ compare_secure(binary_to_list(X), binary_to_list(Y));
compare_secure(X, Y) when is_list(X) and is_list(Y) ->
- case length(X) == length(Y) of
- true ->
- compare_secure(X, Y, 0);
- false ->
- false
- end;
+ case length(X) == length(Y) of
+ true ->
+ compare_secure(X, Y, 0);
+ false ->
+ false
+ end;
compare_secure(_X, _Y) -> false.
@@ -186,25 +159,31 @@ compare_secure(_X, _Y) -> false.
Accum :: integer().
compare_secure([X|RestX], [Y|RestY], Result) ->
- compare_secure(RestX, RestY, (X bxor Y) bor Result);
+ compare_secure(RestX, RestY, (X bxor Y) bor Result);
compare_secure([], [], Result) ->
- Result == 0.
+ Result == 0.
%----------------------------------------------------------------------------------------------------------------------
-spec to_hex(Data) -> HexData when
Data :: binary() | list(),
- HexData :: hex_list().
+ HexData :: binary() | hex_list().
-to_hex([]) ->
- [];
+to_hex(<<>>) ->
+ <<>>;
+
+to_hex(<<Char:8/integer, Rest/binary>>) ->
+ CharHex1 = to_hex_digit(Char div 16),
+ CharHex2 = to_hex_digit(Char rem 16),
+ RestHex = to_hex(Rest),
+ <<CharHex1, CharHex2, RestHex/binary>>;
-to_hex(Bin) when is_binary(Bin) ->
- to_hex(binary_to_list(Bin));
+to_hex([]) ->
+ [];
-to_hex([H|T]) ->
- [to_hex_digit(H div 16), to_hex_digit(H rem 16) | to_hex(T)].
+to_hex([Char | Rest]) ->
+ [to_hex_digit(Char div 16), to_hex_digit(Char rem 16) | to_hex(Rest)].
%----------------------------------------------------------------------------------------------------------------------

0 comments on commit 267eb2c

Please sign in to comment.