diff --git a/src/pbkdf2.erl b/src/pbkdf2.erl deleted file mode 100644 index 34b7b5652..000000000 --- a/src/pbkdf2.erl +++ /dev/null @@ -1,157 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(pbkdf2). - --export([pbkdf2/4, pbkdf2/5, compare_secure/2, to_hex/1]). - --type(hex_char() :: 48 .. 57 | 97 .. 102). --type(hex_list() :: [hex_char()]). - --type(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)). - -%%-------------------------------------------------------------------- -%% Public API -%%-------------------------------------------------------------------- - --spec(pbkdf2(MacFunc, Password, Salt, Iterations) -> {ok, Key} | {error, derived_key_too_long} when - MacFunc :: mac_func_info(), - Password :: binary(), - Salt :: binary(), - Iterations :: integer(), - Key :: binary()). -pbkdf2(MacFunc, Password, Salt, Iterations) -> - MacFunc1 = resolve_mac_func(MacFunc), - DerivedLength = byte_size(MacFunc1(<<"test key">>, <<"test data">>)), - Bin = pbkdf2(MacFunc1, Password, Salt, Iterations, DerivedLength, 1, []), - {ok, Bin}. - --spec(pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength) -> {ok, Key} | {error, derived_key_too_long} when - MacFunc :: mac_func_info(), - Password :: binary(), - Salt :: binary(), - Iterations :: integer(), - DerivedLength :: integer(), - Key :: binary()). -pbkdf2(_MacFunc, _Password, _Salt, _Iterations, DerivedLength) when DerivedLength > ?MAX_DERIVED_KEY_LENGTH -> - {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}. - --spec(to_hex(Data) -> HexData when - Data :: iolist(), - HexData :: binary() | hex_list()). -to_hex(<<>>) -> - <<>>; -to_hex(<>) -> - CharHex1 = to_hex_digit(Char div 16), - CharHex2 = to_hex_digit(Char rem 16), - RestHex = to_hex(Rest), - <>; -to_hex([]) -> - []; -to_hex([Char | Rest]) -> - [to_hex_digit(Char div 16), to_hex_digit(Char rem 16) | to_hex(Rest)]. - -%%-------------------------------------------------------------------- -%% Internal Functions -%%-------------------------------------------------------------------- - --spec(pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength, BlockIndex, Acc) -> Key when - MacFunc :: fun((binary(), binary()) -> binary()), - Password :: binary(), - Salt :: binary(), - Iterations :: integer(), - DerivedLength :: integer(), - BlockIndex :: integer(), - Acc :: iolist(), - Key :: binary()). -pbkdf2(MacFunc, Password, Salt, Iterations, DerivedLength, BlockIndex, Acc) -> - case iolist_size(Acc) > DerivedLength of - true -> <> = 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. - --spec(pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, Iteration, Prev, Acc) -> Key when - MacFunc :: fun((binary(), binary()) -> binary()), - Password :: binary(), - Salt :: binary(), - Iterations :: integer(), - BlockIndex :: integer(), - Iteration :: integer(), - Prev :: binary(), - Acc :: binary(), - Key :: binary()). -pbkdf2(_MacFunc, _Password, _Salt, Iterations, _BlockIndex, Iteration, _Prev, Acc) when Iteration > Iterations -> - Acc; -pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, 1, _Prev, _Acc) -> - InitialBlock = MacFunc(Password, <>), - 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)). - -resolve_mac_func({hmac, DigestFunc}) -> - fun(Key, Data) -> - HMAC = crypto:hmac_init(DigestFunc, Key), - HMAC1 = crypto:hmac_update(HMAC, Data), - crypto:hmac_final(HMAC1) - end; - -resolve_mac_func(MacFunc) when is_function(MacFunc) -> - MacFunc; - -resolve_mac_func(md4) -> resolve_mac_func({hmac, md4}); -resolve_mac_func(md5) -> resolve_mac_func({hmac, md5}); -resolve_mac_func(ripemd160) -> resolve_mac_func({hmac, ripemd160}); -resolve_mac_func(sha) -> resolve_mac_func({hmac, sha}); -resolve_mac_func(sha224) -> resolve_mac_func({hmac, sha224}); -resolve_mac_func(sha256) -> resolve_mac_func({hmac, sha256}); -resolve_mac_func(sha384) -> resolve_mac_func({hmac, sha384}); -resolve_mac_func(sha512) -> resolve_mac_func({hmac, sha512}). - -%% Compare two strings or binaries for equality without short-circuits to avoid timing attacks. - --spec(compare_secure(First, Second) -> boolean() when - First :: binary() | string(), - Second :: binary() | string()). -compare_secure(<>, <>) -> - 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; -compare_secure(_X, _Y) -> false. - --spec(compare_secure(First, Second, Accum) -> boolean() when - First :: string(), - Second :: string(), - Accum :: integer()). -compare_secure([X|RestX], [Y|RestY], Result) -> - compare_secure(RestX, RestY, (X bxor Y) bor Result); -compare_secure([], [], Result) -> - Result == 0. - --spec(to_hex_digit(Nyble :: 0 .. 15) -> hex_char()). -to_hex_digit(N) when N < 10 -> - $0 + N; -to_hex_digit(N) -> - $a + N - 10.