Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
ebin/
.eunit/
_build
.eqc-info
16 changes: 6 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
before_install:
- sudo apt-get update
- sudo apt-get install libicu-dev libmozjs-dev
before_script: ./bootstrap && ./configure
script: make distcheck
language: erlang
otp_release:
- R15B02
- R15B01
- R15B
- R14B04
- R14B03
- 20.3.8
- 21.3
- 22.3
script:
- chmod u+x rebar3
- ./rebar3 do upgrade, compile, xref, dialyzer, eunit
28 changes: 16 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
.PHONY: deps test
.PHONY: compile rel cover test dialyzer
REBAR=./rebar3

all: deps compile
compile:
$(REBAR) compile

compile: deps
./rebar compile
clean:
$(REBAR) clean

deps:
test -d deps || ./rebar get-deps
cover:
$(REBAR) eunit --cover
$(REBAR) cover

clean:
./rebar clean
test: compile
$(REBAR) eunit

distclean: clean
./rebar delete-deps
dialyzer:
$(REBAR) dialyzer

DIALYZER_APPS = kernel stdlib erts sasl ssl crypto public_key
xref:
$(REBAR) xref

include tools.mk
check: test dialyzer xref
2 changes: 2 additions & 0 deletions test/pbkdf2-port.c → eqc/pbkdf2-port.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <syslog.h>
#include <string.h>

#include <openssl/evp.h>

#include <ei.h>

int main() {
Expand Down
82 changes: 82 additions & 0 deletions eqc/pbkdf2_eqc.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
-module(pbkdf2_eqc).

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

-export([prop_equivalent/0]).

-include_lib("eqc/include/eqc.hrl").
-include_lib("eunit/include/eunit.hrl").

-define(QC_OUT(P),
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()))))}
]
}.

prop_equivalent() ->
?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]).

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

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

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

gen_iterations() ->
?LET(X, ?SUCHTHAT(I, nat(), I > 0), X*X).
Binary file removed rebar
Binary file not shown.
19 changes: 6 additions & 13 deletions rebar.config
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
%% ex: ts=4 sw=4 ft=erlang noet

{cover_enabled, true}.

%% Require at least R14B03. (couchdb requires this version or newer, and this code hasn't been tested on earlier)
{require_min_otp_vsn, "R14B03"}.
{erl_opts, [warnings_as_errors]}.

%% Ensure the ebin directory exists before we try to put files there.
{pre_hooks, [
{compile, "mkdir -p ebin"}
]}.
{eunit_opts, [verbose]}.

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

%% == xref ==

%% Enable xref warnings.
{xref_warnings, true}.

%% xref checks to run
{xref_checks, [undefined_function_calls]}.
{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used,
deprecated_function_calls, deprecated_functions]}.
1 change: 1 addition & 0 deletions rebar.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[].
Binary file added rebar3
Binary file not shown.
2 changes: 1 addition & 1 deletion src/pbkdf2.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{description, "Erlang PBKDF2 Key Derivation Function"},
{vsn, git},
{registered, []},
{applications, [kernel, stdlib]},
{applications, [kernel, stdlib, crypto]},
{modules, [pbkdf2]},
{env, []}
]}.
7 changes: 3 additions & 4 deletions src/pbkdf2.erl
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,9 @@ pbkdf2(MacFunc, Password, Salt, Iterations, BlockIndex, Iteration, Prev, Acc) ->

resolve_mac_func({hmac, DigestFunc}) ->
fun(Key, Data) ->
%crypto:hmac(DigestFunc, Key, Data)
HMAC = crypto:hmac_init(DigestFunc, Key),
HMAC1 = crypto:hmac_update(HMAC, Data),
crypto:hmac_final(HMAC1)
HMAC = crypto:mac_init(hmac, DigestFunc, Key),
HMAC1 = crypto:mac_update(HMAC, Data),
crypto:mac_final(HMAC1)
end;

resolve_mac_func(MacFunc) when is_function(MacFunc) ->
Expand Down
34 changes: 34 additions & 0 deletions test/josefsson-draft-vectors.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
%% -*- mode: erlang; erlang-indent-level: 4; indent-tabs-mode: nil -*-
%%
%% These test vectors are assumed to be Copyright (c) Simon Josefsson
%% as a [by]product of drafts relating to RFC-6070.
%%
%% They can be found in numerous places online; this file is populated with
%% data from the location referenced by Mozilla:
%%
%% Repo: https://github.com/ircmaxell/PHP-PasswordLib
%% Branch: master
%% Path: test/Data/Vectors/pbkdf2-draft-josefsson-sha256.test-vectors
%%

%% {digest, password, salt, iterations, derived_key_length, derived_key}
{'josefsson-draft', [
% Set 1
{sha256, <<"password">>, <<"salt">>, 1,
32, <<16#120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b:256>>},
% Set 2
{sha256, <<"password">>, <<"salt">>, 2,
32, <<16#ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43:256>>},
% Set 3
{sha256, <<"password">>, <<"salt">>, 4096,
32, <<16#c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a:256>>},
% Set 4
{sha256, <<"password">>, <<"salt">>, 16777216,
32, <<16#cf81c66fe8cfc04d1f31ecb65dab4089f7f179e89b3b0bcb17ad10e3ac6eba46:256>>},
% Set 5
{sha256, <<"passwordPASSWORDpassword">>, <<"saltSALTsaltSALTsaltSALTsaltSALTsalt">>,
4096, 40, <<16#348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9:320>>},
% Set 6
{sha256, <<"pass\0word">>, <<"sa\0lt">>, 4096, 16,
<<16#89b69d0516f829893c696226650a8687:128>>}
]}.
74 changes: 0 additions & 74 deletions test/pbkdf2_eqc.erl

This file was deleted.

50 changes: 50 additions & 0 deletions test/rfc3962-vectors.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
%% -*- mode: erlang; erlang-indent-level: 4; indent-tabs-mode: nil -*-
%%
%% IETF RFC-3962 AES Encryption for Kerberos 5.
%% Copyright (c) 2005 The Internet Society.
%% Refer to https://tools.ietf.org/html/rfc3962 for legal provisions.
%%

%% {digest, password, salt, iterations, derived_key_length, derived_key}
{'rfc3962', [
% Set 1
{sha, <<"password">>, <<"ATHENA.MIT.EDUraeburn">>, 1,
16, <<16#cdedb5281bb2f801565a1122b2563515:128>>},
% Set 2
{sha, <<"password">>, <<"ATHENA.MIT.EDUraeburn">>, 1,
32, <<16#cdedb5281bb2f801565a1122b25635150ad1f7a04bb9f3a333ecc0e2e1f70837:256>>},
% Set 3
{sha, <<"password">>, <<"ATHENA.MIT.EDUraeburn">>, 2,
16, <<16#01dbee7f4a9e243e988b62c73cda935d:128>>},
% Set 4
{sha, <<"password">>, <<"ATHENA.MIT.EDUraeburn">>, 2,
32, <<16#01dbee7f4a9e243e988b62c73cda935da05378b93244ec8f48a99e61ad799d86:256>>},
% Set 5
{sha, <<"password">>, <<"ATHENA.MIT.EDUraeburn">>, 1200,
16, <<16#5c08eb61fdf71e4e4ec3cf6ba1f5512b:128>>},
% Set 6
{sha, <<"password">>, <<"ATHENA.MIT.EDUraeburn">>, 1200,
32, <<16#5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13:256>>},
% Set 7
{sha, <<"password">>, <<16#1234567878563412:64>>, 5,
16, <<16#d1daa78615f287e6a1c8b120d7062a49:128>>},
% Set 8
{sha, <<"password">>, <<16#1234567878563412:64>>, 5,
32, <<16#d1daa78615f287e6a1c8b120d7062a493f98d203e6be49a6adf4fa574b6e64ee:256>>},
% Set 9
{sha, <<"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">>,
<<"pass phrase equals block size">>, 1200,
16, <<16#139c30c0966bc32ba55fdbf212530ac9:128>>},
% Set 10
{sha, <<"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">>,
<<"pass phrase equals block size">>, 1200,
32, <<16#139c30c0966bc32ba55fdbf212530ac9c5ec59f1a452f5cc9ad940fea0598ed1:256>>},
% Set 11
{sha, <<"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">>,
<<"pass phrase exceeds block size">>, 1200,
16, <<16#9ccad6d468770cd51b10e6a68721be61:128>>},
% Set 12
{sha, <<"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">>,
<<"pass phrase exceeds block size">>, 1200,
32, <<16#9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a:256>>}
]}.
28 changes: 28 additions & 0 deletions test/rfc6070-vectors.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
%% -*- mode: erlang; erlang-indent-level: 4; indent-tabs-mode: nil -*-
%%
%% IETF RFC-6070 PBKDF2 Test Vectors.
%% Copyright (c) 2011 IETF Trust and Simon Josefsson.
%% Refer to https://tools.ietf.org/html/rfc6070 for legal provisions.
%%

%% {digest, password, salt, iterations, derived_key_length, derived_key}
{'rfc6070', [
% Set 1
{sha, <<"password">>, <<"salt">>, 1,
20, <<16#0c60c80f961f0e71f3a9b524af6012062fe037a6:160>>},
% Set 2
{sha, <<"password">>, <<"salt">>, 2,
20, <<16#ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957:160>>},
% Set 3
{sha, <<"password">>, <<"salt">>, 4096,
20, <<16#4b007901b765489abead49d926f721d065a429c1:160>>},
% Set 4
{sha, <<"password">>, <<"salt">>, 16777216,
20, <<16#eefe3d61cd4da4e4e9945b3d6ba2158c2634e984:160>>},
% Set 5
{sha, <<"passwordPASSWORDpassword">>, <<"saltSALTsaltSALTsaltSALTsaltSALTsalt">>,
4096, 25, <<16#3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038:200>>},
% Set 6
{sha, <<"pass\0word">>, <<"sa\0lt">>, 4096, 16,
<<16#56fa6aa75548099dcc37d7f03425e0c3:128>>}
]}.
Loading