Skip to content

Commit

Permalink
Merge branch 'develop-3.0' of https://github.com/basho/erlang-pbkdf2
Browse files Browse the repository at this point in the history
…into develop-3.0
  • Loading branch information
martinsumner committed May 11, 2020
2 parents b5d58ab + 291533d commit 681494c
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 49 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ compile:
clean:
$(REBAR) clean

cover: test
cover:
$(REBAR) eunit --cover
$(REBAR) cover

test: compile
$(REBAR) as test do eunit
$(REBAR) eunit

dialyzer:
$(REBAR) dialyzer
Expand Down
104 changes: 59 additions & 45 deletions eqc/pbkdf2_eqc.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
-module(pbkdf2_eqc).

%% Compile C code and compare C code execution with Erlang code.

-export([prop_equivalent/0]).

-include_lib("eqc/include/eqc.hrl").
Expand All @@ -9,60 +11,72 @@
eqc:on_output(fun(Str, Args) -> io:format(user, Str, Args) end, P)).

eqc_test_() ->
{timeout, 30,
[
{timeout, 30, ?_assertEqual(true, eqc:quickcheck(eqc:testing_time(14, ?QC_OUT(prop_equivalent()))))}
]
}.
{timeout, 30,
[
{timeout, 30, ?_assertEqual(true, eqc:quickcheck(eqc:testing_time(14, ?QC_OUT(prop_equivalent()))))}
]
}.

prop_equivalent() ->
%% try to compile the openssl port we need to compare the erlang version against:
case code:lib_dir(erl_interface) of
{error, Reason} ->
{error, Reason};
EIDir ->
%% we assume the ebin of this file is in .eunit, where rebar puts it
PortSrcDir = "eqc",
%% yeeehaw
[] = os:cmd("gcc -Wno-format -Wno-pointer-sign -Wno-implicit-function-declaration "++PortSrcDir++"/pbkdf2-port.c -o pbkdf2-port -I"++EIDir++"/include -L"++EIDir++"/lib -lei -lssl -lcrypto"),
?FORALL({Password, Salt, Iterations, KeySize}, {gen_print_bin(), gen_salt(), gen_iterations(), gen_keysize()},
begin
Port = open_port({spawn, "./pbkdf2-port"}, [{packet, 4}]),
Hash = sha, %% only hash openssl supports for PBKDF2 is SHA1 :(
{ok, Bin} = pbkdf2:pbkdf2(Hash, Password, Salt, Iterations, KeySize),
Result = pbkdf2:to_hex(Bin),
port_command(Port, term_to_binary({Hash, Password, Salt, Iterations, KeySize})),
Expected = receive
{Port, {data, E}} ->
list_to_binary(E)
after
5000 ->
timeout
end,
port_close(Port),
?WHENFAIL(begin
io:format(user, "Password ~p~n", [Password]),
io:format(user, "Salt ~p~n", [Salt]),
io:format(user, "Iterations ~p~n", [Iterations]),
io:format(user, "KeySize ~p~n", [KeySize]),
io:format(user, "Expected ~p~n", [Expected]),
io:format(user, "Result ~p~n", [Result])
end,
Expected == Result)
end)
end.
?SETUP(fun() ->
ok = compile_c_code(),
fun(_) -> ok end
end,
?FORALL({Password, Salt, Iterations, KeySize}, {gen_print_bin(), gen_salt(), gen_iterations(), gen_keysize()},
begin
Port = open_port({spawn, "./pbkdf2-port"}, [{packet, 4}]),
Hash = sha, %% only hash openssl supports for PBKDF2 is SHA1 :(
{ok, Bin} = pbkdf2:pbkdf2(Hash, Password, Salt, Iterations, KeySize),
Result = pbkdf2:to_hex(Bin),
port_command(Port, term_to_binary({Hash, Password, Salt, Iterations, KeySize})),
Expected = receive
{Port, {data, E}} ->
list_to_binary(E)
after
5000 ->
timeout
end,
port_close(Port),
?WHENFAIL(begin
io:format(user, "Password ~p~n", [Password]),
io:format(user, "Salt ~p~n", [Salt]),
io:format(user, "Iterations ~p~n", [Iterations]),
io:format(user, "KeySize ~p~n", [KeySize]),
io:format(user, "Expected ~p~n", [Expected]),
io:format(user, "Result ~p~n", [Result])
end,
Expected == Result)
end)).

compile_c_code() ->
%% try to compile the openssl port we need to compare the erlang version against:
case code:lib_dir(erl_interface) of
{error, Reason} ->
{error, Reason};
EIDir ->
%% EIDir is the erl_interface dir which contains lib and include for erl_interface C code
PortSrcDir = "./eqc",
%% yeeehaw
case os:cmd("gcc -Wno-format -Wno-pointer-sign -Wno-implicit-function-declaration "++PortSrcDir++"/pbkdf2-port.c -o pbkdf2-port -I"++EIDir++"/include -L"++EIDir++"/lib -lei -lssl -lcrypto") of
[] ->
ok;
Error ->
%% We need access to include files like openssl/evp.h
{error, {compiling_c_code, Error}}
end
end.

gen_print_str() ->
?LET(Xs, list(char()), [X || X <- Xs, io_lib:printable_list([X]), X /= $~, X < 255]).
?LET(Xs, list(char()), [X || X <- Xs, io_lib:printable_list([X]), X /= $~, X < 255]).

gen_print_bin() ->
?SUCHTHAT(B, ?LET(Xs, gen_print_str(), list_to_binary(Xs)), B/= <<>>).
?SUCHTHAT(B, ?LET(Xs, gen_print_str(), list_to_binary(Xs)), B/= <<>>).

gen_salt() ->
?SUCHTHAT(S, binary(), S /= <<>>).
?SUCHTHAT(S, binary(), S /= <<>>).

gen_keysize() ->
?LET(Xs, nat(), Xs+5).
?LET(Xs, nat(), Xs+5).

gen_iterations() ->
?LET(X, ?SUCHTHAT(I, nat(), I > 0), X*X).
?LET(X, ?SUCHTHAT(I, nat(), I > 0), X*X).
2 changes: 0 additions & 2 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@

{eunit_opts, [verbose]}.


{plugins, [{eqc_rebar, {git, "https://github.com/Quviq/eqc-rebar", {branch, "master"}}}]}.


{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used,
deprecated_function_calls, deprecated_functions]}.

0 comments on commit 681494c

Please sign in to comment.