Streamlines generichashThe multi-part hash API is nowreflecting the same crypto modulefunctions in style. This is easierto use for people, I believe.

This commit is contained in:
Jesper Louis Andersen 2020-02-04 12:59:18 +01:00
parent 71832cce4c
commit aa2c69529a
3 changed files with 24 additions and 15 deletions

View File

@ -11,7 +11,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
Pretty large change, but OTOH, this ought to happen before a 1.0 release as well. Pretty large change, but OTOH, this ought to happen before a 1.0 release as well.
- AEAD - AEAD
- enacl - enacl
- generichash
- hash - hash
- kx - kx
- pwhash - pwhash
@ -19,6 +18,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- secret - secret
- sign - sign
- Implement missing EQC tests
- Generichash
- Multi-part generic hash
## [Unreleased] ## [Unreleased]
### Compatibility ### Compatibility
@ -71,6 +74,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Renamed many routines from enif_* to enacl_*. This better reflects where they live - Renamed many routines from enif_* to enacl_*. This better reflects where they live
in the code base, and avoids pollution of the enif_* "namespace". in the code base, and avoids pollution of the enif_* "namespace".
- Split Sign Public Key routines from the rest. Modernize the handling of contexts. - Split Sign Public Key routines from the rest. Modernize the handling of contexts.
- The multi-part generic hash routines now follow the structure of the crypto
modules multi-part constructions in API and style.
### Fixed ### Fixed
- Fix a resource leak in generichash/sign init/update/final. - Fix a resource leak in generichash/sign init/update/final.

View File

@ -157,8 +157,7 @@ ERL_NIF_TERM enacl_crypto_generichash_init(ErlNifEnv *env, int argc,
// Verify that hash size is valid // Verify that hash size is valid
if ((hash_size <= crypto_generichash_BYTES_MIN) || if ((hash_size <= crypto_generichash_BYTES_MIN) ||
(hash_size >= crypto_generichash_BYTES_MAX)) { (hash_size >= crypto_generichash_BYTES_MAX)) {
ret = enacl_error_tuple(env, "invalid_hash_size"); goto bad_arg;
goto done;
} }
// validate key size // validate key size
@ -167,8 +166,7 @@ ERL_NIF_TERM enacl_crypto_generichash_init(ErlNifEnv *env, int argc,
k = NULL; k = NULL;
} else if (key.size <= crypto_generichash_KEYBYTES_MIN || } else if (key.size <= crypto_generichash_KEYBYTES_MIN ||
key.size >= crypto_generichash_KEYBYTES_MAX) { key.size >= crypto_generichash_KEYBYTES_MAX) {
ret = enacl_error_tuple(env, "invalid_key_size"); goto bad_arg;
goto done;
} }
// Create the resource // Create the resource
@ -210,7 +208,7 @@ ERL_NIF_TERM enacl_crypto_generichash_init(ErlNifEnv *env, int argc,
bad_arg: bad_arg:
return enif_make_badarg(env); return enif_make_badarg(env);
err: err:
ret = enacl_error_tuple(env, "internal_error"); ret = enif_make_atom(env, "notsup");
if (obj != NULL) { if (obj != NULL) {
if (obj->alive) { if (obj->alive) {
sodium_free(obj->ctx); sodium_free(obj->ctx);
@ -244,14 +242,12 @@ ERL_NIF_TERM enacl_crypto_generichash_update(ErlNifEnv *env, int argc,
enif_mutex_lock(obj->mtx); enif_mutex_lock(obj->mtx);
if (!obj->alive) { if (!obj->alive) {
ret = enacl_error_tuple(env, "finalized"); goto err;
goto done;
} }
// Update hash state // Update hash state
if (0 != crypto_generichash_update(obj->ctx, data.data, data.size)) { if (0 != crypto_generichash_update(obj->ctx, data.data, data.size)) {
ret = enacl_error_tuple(env, "hash_update_error"); goto err;
goto done;
} }
ret = argv[0]; ret = argv[0];
@ -259,6 +255,8 @@ ERL_NIF_TERM enacl_crypto_generichash_update(ErlNifEnv *env, int argc,
bad_arg: bad_arg:
return enif_make_badarg(env); return enif_make_badarg(env);
err:
ret = enif_make_badarg(env);
done: done:
enif_mutex_unlock(obj->mtx); enif_mutex_unlock(obj->mtx);
return ret; return ret;
@ -278,17 +276,14 @@ ERL_NIF_TERM enacl_crypto_generichash_final(ErlNifEnv *env, int argc,
enif_mutex_lock(obj->mtx); enif_mutex_lock(obj->mtx);
if (!obj->alive) { if (!obj->alive) {
ret = enacl_error_tuple(env, "finalized"); goto err;
goto done;
} }
if (!enif_alloc_binary(obj->outlen, &hash)) { if (!enif_alloc_binary(obj->outlen, &hash)) {
ret = enacl_error_tuple(env, "alloc_failed");
goto done; goto done;
} }
if (0 != crypto_generichash_final(obj->ctx, hash.data, hash.size)) { if (0 != crypto_generichash_final(obj->ctx, hash.data, hash.size)) {
ret = enacl_error_tuple(env, "hash_error");
goto release; goto release;
} }
@ -305,6 +300,8 @@ ERL_NIF_TERM enacl_crypto_generichash_final(ErlNifEnv *env, int argc,
bad_arg: bad_arg:
return enif_make_badarg(env); return enif_make_badarg(env);
err:
ret = enif_make_badarg(env);
release: release:
enif_release_binary(&hash); enif_release_binary(&hash);
done: done:

View File

@ -351,16 +351,23 @@ generichash(HashSize, Message, Key) ->
generichash(HashSize, Message) -> generichash(HashSize, Message) ->
enacl_nif:crypto_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.
generichash_init(HashSize, Key) -> generichash_init(HashSize, Key) ->
enacl_nif:crypto_generichash_init(HashSize, Key). enacl_nif:crypto_generichash_init(HashSize, Key).
%% @doc generichash_update/2 updates a multi-part hash with new data.
%% @end
-spec generichash_update(reference(), iodata()) -> reference().
generichash_update(State, Message) -> generichash_update(State, Message) ->
enacl_nif:crypto_generichash_update(State, Message). enacl_nif:crypto_generichash_update(State, Message).
%% @doc generichash_final/1 finalizes a multi-part hash.
-spec generichash_final(reference()) -> binary().
generichash_final(State) -> generichash_final(State) ->
enacl_nif:crypto_generichash_final(State). enacl_nif:crypto_generichash_final(State).
-type pwhash_limit() :: interactive | moderate | sensitive | pos_integer(). -type pwhash_limit() :: interactive | moderate | sensitive | pos_integer().
%% @doc pwhash/2 hash a password %% @doc pwhash/2 hash a password
%% %%