Skip to content
This repository has been archived by the owner on Apr 4, 2020. It is now read-only.

Pwhash implementation #7

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

daveed-al
Copy link

No description provided.

@daveed-al
Copy link
Author

work in progress for pwhash implementation.
the libsodium crypto_pwhash function https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_pwhash/crypto_pwhash.c#L129
has a switch / case for the algorithm, values can either be can either be pwhash_ALG_ARGON2ID13 or pwhash_ALG_ARGON2I13
when I call the Elixir function using Salty.Nif.pwhash_ALG_ARGON2ID13 it works
when I use Salty.Nif.pwhash_ALG_ARGON2I13 it errors.

here is the code I use to test:

require Salty.Nif

### pwhash
outlen = 16
password = "thepassword"
{:ok, password_salt} = Salty.Nif.randombytes_buf(16)
opslimit = 2
memlimit = Salty.Nif.pwhash_argon2id_MEMLIMIT_INTERACTIVE
# alg can either be pwhash_ALG_ARGON2ID13 or pwhash_ALG_ARGON2I13
alg = Salty.Nif.pwhash_ALG_ARGON2ID13
# alg = Salty.Nif.pwhash_ALG_ARGON2I13
{:ok, pwhash} = Salty.Nif.pwhash(outlen, password, password_salt, opslimit, memlimit, alg)

also the code for str_verify and needs_rehash is in progress as well - I pull request to reach out for help and get feedback and understand what I am missing. thanks

@ArteMisc
Copy link
Owner

Hi there, and thanks for taking the time to work on this!

The approach to high level APIs in this library is to not bind them directly, but provide a method "primitive()" that returns the module that implements the default (high level) primitive. Take the secretbox API as an example.

In case of Salty.PwHash, that would lead to exposing the pwhash/pwhash_str/str_verify/str_needs_rehash methods in the modules that implement the primitives (Salty.PwHash.Scrypt, Salty.PwHash.Argon2i, Salty.PwHash.Argon2id), and returning the Argon2id module from the Salty.PwHash.primitive() method. This removes the requirement to work with algorithm identifiers altogether, and lets you call the primitives' implementations directly in salty_nif.c instead.

As a special case, the str_verify/str_needs_rehash methods could be implemented in the Salty.PwHash module as well, as they do not need any algorithm specific input parameters.

That aside, what is the error message that you're getting? Also, which version of libsodium are you using, and on which system are you testing?

On another note, in order to use pwhash within Elixir (or Erlang's VM for that matter), the methods for pwhash, str and str_verify will need to use the dirty scheduler in order for applications to be able to use it without messing up the scheduler.

I hope this answers some of your questions, let me know if there is anything else.

@daveed-al
Copy link
Author

daveed-al commented Jan 29, 2018

Hi @ArteMisc - I apologize for the delay and thanks a lot for your detailed explanation.
I am still going through it.
The error I am getting (when alg == Salty.Nif.pwhash_ALG_ARGON2I13 == 1) is
** (MatchError) no match of right hand side value: {:error, :salty_error_unknown}

If I try a few more times I have a segmentation fault:

iex(18)> {:ok, pwhash} = Salty.Nif.pwhash(outlen, password, password_salt, opslimit, memlimit, 1)
** (MatchError) no match of right hand side value: {:error, :salty_error_unknown}

iex(18)> {:ok, pwhash} = Salty.Nif.pwhash(outlen, password, password_salt, opslimit, memlimit, 1)
** (MatchError) got FunctionClauseError with message "no function clause matching in Inspect.Any.inspect/2" while retrieving Exception.message/1 for %Inspect.Error{message: "got FunctionClauseError with message \"no function clause matching in Inspect.Any.inspect/2\" while inspecting %{__exception__: true, __struct__: MatchError, term: {:error, :salty_error_unknown}}"}

iex(18)> {:ok, pwhash} = Salty.Nif.pwhash(outlen, password, password_salt, opslimit, memlimit, 1)
[1]    29426 segmentation fault  iex -S mix

I am using libsodium 1.0.16 on macOS High Sierra 10.13.2
I was using Elixir 1.7.0 but have the same issue when now using Elixir 1.6.0.

Hopefully that helps troubleshooting. Thanks

@daveed-al
Copy link
Author

Implementing primitives now @ArteMisc to respect high level API approach.

@daveed-al
Copy link
Author

daveed-al commented Jan 30, 2018

updated the pull request - the seg fault no longer happens.
Now using the following code to test:

outlen = 16
password = "thepassword"
{:ok, password_salt} = Salty.Nif.randombytes_buf(16)
opslimit = Salty.PwHash.Argon2i.opslimit_interactive
memlimit = Salty.PwHash.Argon2i.memlimit_interactive
alg = Salty.PwHash.Argon2i.alg
{:ok, pwhash} = Salty.PwHash.Argon2i.pwhash(outlen, password, password_salt, opslimit, memlimit, alg)

@daveed-al
Copy link
Author

any updates @ArteMisc ? thanks

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants