Add choice of ops and mem limits to pwhash_str
It natively checks atoms, which is kinda messy, but it avoids having to export the libsodium pwhash constants, which is nice.
This commit is contained in:
parent
f650c72b02
commit
d779071285
@ -1259,6 +1259,61 @@ ERL_NIF_TERM enif_scramble_block_16(ErlNifEnv *env, int argc, ERL_NIF_TERM const
|
||||
return enif_make_binary(env, &out);
|
||||
}
|
||||
|
||||
static
|
||||
size_t enacl_pwhash_opslimit(ErlNifEnv *env, ERL_NIF_TERM arg) {
|
||||
ERL_NIF_TERM a;
|
||||
size_t r;
|
||||
|
||||
if (enif_is_atom(env, arg)) {
|
||||
a = enif_make_atom(env, "interactive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_INTERACTIVE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "moderate");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_MODERATE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "sensitive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_SENSITIVE;
|
||||
}
|
||||
} else if (enif_get_ulong(env, arg, &r)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
size_t enacl_pwhash_memlimit(ErlNifEnv *env, ERL_NIF_TERM arg) {
|
||||
ERL_NIF_TERM a;
|
||||
size_t r;
|
||||
|
||||
if (enif_is_atom(env, arg)) {
|
||||
a = enif_make_atom(env, "interactive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_INTERACTIVE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "moderate");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_MODERATE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "sensitive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_SENSITIVE;
|
||||
}
|
||||
} else if (enif_get_ulong(env, arg, &r)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
ERL_NIF_TERM enif_crypto_pwhash(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary h, p, s;
|
||||
@ -1296,10 +1351,13 @@ ERL_NIF_TERM enif_crypto_pwhash(ErlNifEnv *env, int argc, ERL_NIF_TERM const arg
|
||||
static
|
||||
ERL_NIF_TERM enif_crypto_pwhash_str(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary h, p;
|
||||
size_t o, m;
|
||||
|
||||
// Validate the arguments
|
||||
if( (argc != 1) ||
|
||||
(!enif_inspect_iolist_as_binary(env, argv[0], &p)) ) {
|
||||
if( (argc != 3) ||
|
||||
(!enif_inspect_iolist_as_binary(env, argv[0], &p)) ||
|
||||
!(o = enacl_pwhash_opslimit(env, argv[1])) ||
|
||||
!(m = enacl_pwhash_memlimit(env, argv[2])) ) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
@ -1308,8 +1366,7 @@ ERL_NIF_TERM enif_crypto_pwhash_str(ErlNifEnv *env, int argc, ERL_NIF_TERM const
|
||||
return nacl_error_tuple(env, "alloc_failed");
|
||||
}
|
||||
|
||||
if( crypto_pwhash_str((char *)h.data, (char *)p.data, p.size,
|
||||
crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE) != 0) {
|
||||
if( crypto_pwhash_str((char *)h.data, (char *)p.data, p.size, o, m) != 0) {
|
||||
/* out of memory */
|
||||
enif_release_binary(&h);
|
||||
return nacl_error_tuple(env, "out_of_memory");
|
||||
@ -1722,7 +1779,7 @@ static ErlNifFunc nif_funcs[] = {
|
||||
{"sodium_memzero", 1, enif_sodium_memzero},
|
||||
|
||||
{"crypto_pwhash", 2, enif_crypto_pwhash},
|
||||
{"crypto_pwhash_str", 1, enif_crypto_pwhash_str},
|
||||
{"crypto_pwhash_str", 3, enif_crypto_pwhash_str},
|
||||
{"crypto_pwhash_str_verify", 2, enif_crypto_pwhash_str_verify},
|
||||
|
||||
erl_nif_dirty_job_cpu_bound_macro("crypto_curve25519_scalarmult", 2, enif_crypto_curve25519_scalarmult),
|
||||
|
@ -101,6 +101,9 @@
|
||||
shorthash_size/0,
|
||||
shorthash/2,
|
||||
|
||||
%% No Tests!
|
||||
pwhash_str/3,
|
||||
|
||||
%% EQC
|
||||
pwhash/2,
|
||||
pwhash_str/1,
|
||||
@ -336,6 +339,7 @@ generichash_final({hashstate, HashSize, HashState}) ->
|
||||
enacl_nif:crypto_generichash_final(HashSize, HashState).
|
||||
|
||||
|
||||
-type pwhash_limit() :: interactive | moderate | sensitive | pos_integer().
|
||||
%% @doc pwhash/2 hash a password
|
||||
%%
|
||||
%% This function generates a fixed size salted hash of a user defined password.
|
||||
@ -347,10 +351,24 @@ pwhash(Password, Salt) ->
|
||||
%% @doc pwhash_str/1 generates a ASCII encoded hash of a password
|
||||
%%
|
||||
%% This function generates a fixed size, salted, ASCII encoded hash of a user defined password.
|
||||
%% Defaults to interactive/interactive limits.
|
||||
%% @end
|
||||
-spec pwhash_str(iodata()) -> {ok, iodata()} | {error, term()}.
|
||||
pwhash_str(Password) ->
|
||||
case enacl_nif:crypto_pwhash_str(Password) of
|
||||
pwhash_str(Password, interactive, interactive).
|
||||
|
||||
%% @doc pwhash_str/3 generates a ASCII encoded hash of a password
|
||||
%%
|
||||
%% This function generates a fixed size, salted, ASCII encoded hash of a user defined password
|
||||
%% given Ops and Mem limits.
|
||||
%% @end
|
||||
-spec pwhash_str(Password, Ops, Mem) -> {ok, iodata()} | {error, term()}
|
||||
when
|
||||
Password :: iodata(),
|
||||
Ops :: pwhash_limit(),
|
||||
Mem :: pwhash_limit().
|
||||
pwhash_str(Password, Ops, Mem) ->
|
||||
case enacl_nif:crypto_pwhash_str(Password, Ops, Mem) of
|
||||
{ok, ASCII} ->
|
||||
{ok, strip_null_terminate(ASCII)};
|
||||
{error, Reason} ->
|
||||
|
@ -133,7 +133,7 @@
|
||||
%% Password Hashing - Argon2 Algorithm
|
||||
-export([
|
||||
crypto_pwhash/2,
|
||||
crypto_pwhash_str/1,
|
||||
crypto_pwhash_str/3,
|
||||
crypto_pwhash_str_verify/2
|
||||
]).
|
||||
|
||||
@ -189,7 +189,7 @@ crypto_generichash_update(_HashSize, _HashState, _Message) -> erlang:nif_error(
|
||||
crypto_generichash_final(_HashSize, _HashState) -> erlang:nif_error(nif_not_loaded).
|
||||
|
||||
crypto_pwhash(_Password, _Salt) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_pwhash_str(_Password) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_pwhash_str(_Password, _Ops, _Mem) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_pwhash_str_verify(_HashedPassword, _Password) -> erlang:nif_error(nif_not_loaded).
|
||||
|
||||
crypto_box_NONCEBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||
|
Loading…
x
Reference in New Issue
Block a user