diff --git a/CHANGELOG.md b/CHANGELOG.md index 614b015..dac3c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,18 +10,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Go through all calls and make them return streamlined exceptions if applicable. Pretty large change, but OTOH, this ought to happen before a 1.0 release as well. - AEAD - - enacl - hash - kx - - generichash - - pwhash - randombytes - secret - sign + - enacl_nif - Implement missing EQC tests - Generichash - Multi-part generic hash + - pwhash + - Extend with limit for ops and memory as well. ## [Unreleased] diff --git a/c_src/generichash.c b/c_src/generichash.c index 05794bc..4da2c80 100644 --- a/c_src/generichash.c +++ b/c_src/generichash.c @@ -98,8 +98,7 @@ ERL_NIF_TERM enacl_crypto_generichash(ErlNifEnv *env, int argc, // crypto_generichash_BYTES/crypto_generichash_BYTES_MIN/crypto_generichash_BYTES_MAX if ((hash_size <= crypto_generichash_BYTES_MIN) || (hash_size >= crypto_generichash_BYTES_MAX)) { - ret = enacl_error_tuple(env, "invalid_hash_size"); - goto done; + goto bad_arg; } // validate key size @@ -108,33 +107,29 @@ ERL_NIF_TERM enacl_crypto_generichash(ErlNifEnv *env, int argc, k = NULL; } else if (key.size <= crypto_generichash_KEYBYTES_MIN || key.size >= crypto_generichash_KEYBYTES_MAX) { - ret = enacl_error_tuple(env, "invalid_key_size"); - goto done; + goto bad_arg; } // allocate memory for hash if (!enif_alloc_binary(hash_size, &hash)) { - ret = enacl_error_tuple(env, "alloc_failed"); - goto done; + goto err; } // calculate hash if (0 != crypto_generichash(hash.data, hash.size, message.data, message.size, k, key.size)) { - ret = enacl_error_tuple(env, "hash_error"); goto release; } - ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK); - ERL_NIF_TERM ret_hash = enif_make_binary(env, &hash); - - ret = enif_make_tuple2(env, ok, ret_hash); + ret = enif_make_binary(env, &hash); goto done; bad_arg: return enif_make_badarg(env); release: enif_release_binary(&hash); +err: + ret = enacl_internal_error(env); done: return ret; } @@ -208,7 +203,7 @@ ERL_NIF_TERM enacl_crypto_generichash_init(ErlNifEnv *env, int argc, bad_arg: return enif_make_badarg(env); err: - ret = enif_make_atom(env, "notsup"); + ret = enacl_internal_error(env); if (obj != NULL) { if (obj->alive) { sodium_free(obj->ctx); @@ -256,7 +251,7 @@ ERL_NIF_TERM enacl_crypto_generichash_update(ErlNifEnv *env, int argc, bad_arg: return enif_make_badarg(env); err: - ret = enif_make_badarg(env); + ret = enacl_internal_error(env); done: enif_mutex_unlock(obj->mtx); return ret; @@ -276,11 +271,11 @@ ERL_NIF_TERM enacl_crypto_generichash_final(ErlNifEnv *env, int argc, enif_mutex_lock(obj->mtx); if (!obj->alive) { - goto err; + goto bad_arg; } if (!enif_alloc_binary(obj->outlen, &hash)) { - goto done; + goto err; } if (0 != crypto_generichash_final(obj->ctx, hash.data, hash.size)) { @@ -292,18 +287,15 @@ ERL_NIF_TERM enacl_crypto_generichash_final(ErlNifEnv *env, int argc, sodium_free(obj->ctx); obj->alive = 0; - ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK); - ERL_NIF_TERM h = enif_make_binary(env, &hash); - - ret = enif_make_tuple2(env, ok, h); + ret = enif_make_binary(env, &hash); goto done; bad_arg: return enif_make_badarg(env); -err: - ret = enif_make_badarg(env); release: enif_release_binary(&hash); +err: + ret = enif_make_badarg(env); done: enif_mutex_unlock(obj->mtx); return ret; diff --git a/c_src/pwhash.c b/c_src/pwhash.c index be5df5d..be74851 100644 --- a/c_src/pwhash.c +++ b/c_src/pwhash.c @@ -78,25 +78,22 @@ ERL_NIF_TERM enacl_crypto_pwhash(ErlNifEnv *env, int argc, // Check Salt size if (s.size != crypto_pwhash_SALTBYTES) { - return enacl_error_tuple(env, "invalid_salt_size"); + return enif_make_badarg(env); } // Allocate memory for return binary if (!enif_alloc_binary(crypto_box_SEEDBYTES, &h)) { - return enacl_error_tuple(env, "alloc_failed"); + return enacl_internal_error(env); } if (crypto_pwhash(h.data, h.size, (char *)p.data, p.size, s.data, o, m, crypto_pwhash_ALG_DEFAULT) != 0) { /* out of memory */ enif_release_binary(&h); - return enacl_error_tuple(env, "out_of_memory"); + return enacl_internal_error(env); } - ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK); - ERL_NIF_TERM ret = enif_make_binary(env, &h); - - return enif_make_tuple2(env, ok, ret); + return enif_make_binary(env, &h); } ERL_NIF_TERM enacl_crypto_pwhash_str(ErlNifEnv *env, int argc, @@ -119,19 +116,16 @@ ERL_NIF_TERM enacl_crypto_pwhash_str(ErlNifEnv *env, int argc, // Allocate memory for return binary if (!enif_alloc_binary(crypto_pwhash_STRBYTES, &h)) { - return enacl_error_tuple(env, "alloc_failed"); + return enacl_internal_error(env); } if (crypto_pwhash_str((char *)h.data, (char *)p.data, p.size, o, m) != 0) { /* out of memory */ enif_release_binary(&h); - return enacl_error_tuple(env, "out_of_memory"); + return enacl_internal_error(env); } - ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK); - ERL_NIF_TERM ret = enif_make_binary(env, &h); - - return enif_make_tuple2(env, ok, ret); + return enif_make_binary(env, &h); } ERL_NIF_TERM enacl_crypto_pwhash_str_verify(ErlNifEnv *env, int argc, diff --git a/eqc_test/enacl_eqc.erl b/eqc_test/enacl_eqc.erl index 66781bb..bef5da2 100644 --- a/eqc_test/enacl_eqc.erl +++ b/eqc_test/enacl_eqc.erl @@ -726,7 +726,7 @@ prop_pwhash_str_verify() -> begin case v_iodata(Passwd) of true -> - {ok, Ascii} = enacl:pwhash_str(Passwd), + Ascii = enacl:pwhash_str(Passwd), S = enacl:pwhash_str_verify(Ascii, Passwd), equals(S, true); false -> diff --git a/src/enacl.erl b/src/enacl.erl index f54eeaa..658472c 100644 --- a/src/enacl.erl +++ b/src/enacl.erl @@ -338,7 +338,7 @@ unsafe_memzero(_) -> %% either 16, 32 or 64 bytes %% @end -type generichash_bytes() :: 10..64. --spec generichash(generichash_bytes(), iodata(), binary()) -> {ok, binary()} | {error, term()}. +-spec generichash(generichash_bytes(), iodata(), binary()) -> binary(). generichash(HashSize, Message, Key) -> enacl_nif:crypto_generichash(HashSize, Message, Key). @@ -347,13 +347,13 @@ generichash(HashSize, Message, Key) -> %% This function generates a hash of the message. The hash size is %% either 16, 32 or 64 bytes %% @end --spec generichash(generichash_bytes(), iodata()) -> {ok, binary()} | {error, term()}. +-spec generichash(generichash_bytes(), iodata()) -> binary(). generichash(HashSize, Message) -> enacl_nif:crypto_generichash(HashSize, Message, <<>>). %% @doc generichash_init/2 initializes a multi-part hash. %% @end --spec generichash_init(generichash_bytes(), binary()) -> reference() | notsup. +-spec generichash_init(generichash_bytes(), binary()) -> reference(). generichash_init(HashSize, Key) -> enacl_nif:crypto_generichash_init(HashSize, Key). @@ -374,7 +374,7 @@ generichash_final(State) -> %% This function generates a fixed size salted hash of a user defined password. %% Defaults to interactive/interactive limits. %% @end --spec pwhash(iodata(), binary()) -> {ok, binary()} | {error, term()}. +-spec pwhash(iodata(), binary()) -> binary(). pwhash(Password, Salt) -> pwhash(Password, Salt, interactive, interactive). @@ -383,7 +383,7 @@ pwhash(Password, Salt) -> %% This function generates a fixed size salted hash of a user defined password given Ops and Mem %% limits. %% @end --spec pwhash(Password, Salt, Ops, Mem) -> {ok, binary()} | {error, term()} +-spec pwhash(Password, Salt, Ops, Mem) -> binary() when Password :: iodata(), Salt :: binary(), @@ -397,7 +397,7 @@ pwhash(Password, Salt, Ops, Mem) -> %% 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()}. +-spec pwhash_str(iodata()) -> iodata(). pwhash_str(Password) -> pwhash_str(Password, interactive, interactive). @@ -406,18 +406,13 @@ pwhash_str(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()} +-spec pwhash_str(Password, Ops, Mem) -> iodata() 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} -> - {error, Reason} - end. + strip_null_terminate(enacl_nif:crypto_pwhash_str(Password, Ops, Mem)). strip_null_terminate(Binary) -> [X, _] = binary:split(Binary, <<0>>), diff --git a/test/enacl_SUITE.erl b/test/enacl_SUITE.erl index d36ba83..dec7371 100644 --- a/test/enacl_SUITE.erl +++ b/test/enacl_SUITE.erl @@ -59,9 +59,9 @@ generichash_basic_neg(_Config) -> "I've watched C-beams glitter in the dark near the Tannhäuser Gate. " "All those... moments... will be lost... in time, like... tears... in rain">>, Key = <<"Hash Key 123456789">>, - {error, invalid_hash_size} = enacl:generichash(9, Msg, Key), - {error, invalid_hash_size} = enacl:generichash(65, Msg, Key), - {error, invalid_key_size} = enacl:generichash(32, Msg, <<"Small">>), + {'EXIT', {badarg, _}} = (catch enacl:generichash(9, Msg, Key)), + {'EXIT', {badarg, _}} = (catch enacl:generichash(65, Msg, Key)), + {'EXIT', {badarg, _}} = (catch enacl:generichash(32, Msg, <<"Small">>)), ok. generichash_basic_pos(_Config) -> @@ -69,8 +69,8 @@ generichash_basic_pos(_Config) -> "I've watched C-beams glitter in the dark near the Tannhäuser Gate. " "All those... moments... will be lost... in time, like... tears... in rain">>, Key = <<"Hash Key 123456789">>, - {ok,<<189,104,45,187,170,229,212,4,121,43,137,74,241,173,181,77, - 67,211,133,70,196,6,128,97>>} = enacl:generichash(24, Msg, Key), + <<189,104,45,187,170,229,212,4,121,43,137,74,241,173,181,77, + 67,211,133,70,196,6,128,97>> = enacl:generichash(24, Msg, Key), ok. generichash_chunked(_Config) -> @@ -82,7 +82,7 @@ generichash_chunked(_Config) -> State = generichash_chunked(State, Msg, 10000), Expected = <<46,49,32,18,13,186,182,105,106,122,253,139,89,176,169,141, 73,93,99,6,41,216,110,41>>, - {ok, Expected} = enacl:generichash_final(State), + Expected = enacl:generichash_final(State), ok. generichash_chunked(State, _Msg, 0) -> State; @@ -119,8 +119,8 @@ pwhash(_Config) -> Salt = <<"1234567890abcdef">>, Hash1 = <<164,75,127,151,168,101,55,77,48,77,240,204,64,20,43,23,88, 18,133,11,53,151,2,113,232,95,84,165,50,7,60,20>>, - {ok, Hash1} = enacl:pwhash(PW, Salt), - {ok, Str1} = enacl:pwhash_str(PW), + Hash1 = enacl:pwhash(PW, Salt), + Str1 = enacl:pwhash_str(PW), true = enacl:pwhash_str_verify(Str1, PW), false = enacl:pwhash_str_verify(Str1, <>), ok.