diff --git a/CHANGELOG.md b/CHANGELOG.md index 808b0f3..c0d569a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [TODO] + +- Go through all calls and make them return {ok, _} | {error, _} if applicable. + Pretty large change, but OTOH, this ought to happen before a 1.0 release as well. + - AEAD + - enacl + - generichash + - hash + - kx + - public + - pwhash + - randombytes + - secret + - sign + ## [Unreleased] ### Compatibility +- Many functions returned the type `value() | {error, term()}`. They have been + updated to return the more erlang-idiomatic `{ok, value()} | {error, term()}`. - If you used `aead_chacha20poly1305_*` functions, please read through the changelog carefully as we have made changes to these functions. TL;DR: look for `aead_chacha20poly1305_ietf_*` but note it is *not* just a simple substitution diff --git a/c_src/public.c b/c_src/public.c index a160b35..cc1925b 100644 --- a/c_src/public.c +++ b/c_src/public.c @@ -100,9 +100,12 @@ ERL_NIF_TERM enacl_crypto_box(ErlNifEnv *env, int argc, goto release; } - ret = enif_make_sub_binary(env, enif_make_binary(env, &result), - crypto_box_BOXZEROBYTES, - padded_msg.size - crypto_box_BOXZEROBYTES); + ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK); + ERL_NIF_TERM ret_bin = enif_make_sub_binary( + env, enif_make_binary(env, &result), crypto_box_BOXZEROBYTES, + padded_msg.size - crypto_box_BOXZEROBYTES); + ret = enif_make_tuple2(env, ret_ok, ret_bin); + goto done; bad_arg: @@ -143,9 +146,12 @@ ERL_NIF_TERM enacl_crypto_box_open(ErlNifEnv *env, int argc, return enacl_error_tuple(env, "failed_verification"); } - return enif_make_sub_binary(env, enif_make_binary(env, &result), - crypto_box_ZEROBYTES, - padded_ciphertext.size - crypto_box_ZEROBYTES); + ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK); + ERL_NIF_TERM ret_bin = enif_make_sub_binary( + env, enif_make_binary(env, &result), crypto_box_ZEROBYTES, + padded_ciphertext.size - crypto_box_ZEROBYTES); + + return enif_make_tuple2(env, ret_ok, ret_bin); } /* Precomputed crypto boxes */ @@ -171,7 +177,9 @@ ERL_NIF_TERM enacl_crypto_box_beforenm(ErlNifEnv *env, int argc, return enacl_error_tuple(env, "error_gen_shared_secret"); } - return enif_make_binary(env, &k); + ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK); + ERL_NIF_TERM ret_bin = enif_make_binary(env, &k); + return enif_make_tuple2(env, ret_ok, ret_bin); } ERL_NIF_TERM enacl_crypto_box_afternm(ErlNifEnv *env, int argc, @@ -193,9 +201,11 @@ ERL_NIF_TERM enacl_crypto_box_afternm(ErlNifEnv *env, int argc, crypto_box_afternm(result.data, m.data, m.size, nonce.data, k.data); - return enif_make_sub_binary(env, enif_make_binary(env, &result), - crypto_box_BOXZEROBYTES, - m.size - crypto_box_BOXZEROBYTES); + ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK); + ERL_NIF_TERM ret_bin = enif_make_sub_binary( + env, enif_make_binary(env, &result), crypto_box_BOXZEROBYTES, + m.size - crypto_box_BOXZEROBYTES); + return enif_make_tuple2(env, ret_ok, ret_bin); } ERL_NIF_TERM enacl_crypto_box_open_afternm(ErlNifEnv *env, int argc, @@ -221,9 +231,11 @@ ERL_NIF_TERM enacl_crypto_box_open_afternm(ErlNifEnv *env, int argc, return enacl_error_tuple(env, "failed_verification"); } - return enif_make_sub_binary(env, enif_make_binary(env, &result), - crypto_box_ZEROBYTES, - m.size - crypto_box_ZEROBYTES); + ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK); + ERL_NIF_TERM ret_bin = + enif_make_sub_binary(env, enif_make_binary(env, &result), + crypto_box_ZEROBYTES, m.size - crypto_box_ZEROBYTES); + return enif_make_tuple2(env, ret_ok, ret_bin); } /* Sealed box functions */ diff --git a/eqc_test/enacl_eqc.erl b/eqc_test/enacl_eqc.erl index 66781bb..2a1a9f0 100644 --- a/eqc_test/enacl_eqc.erl +++ b/eqc_test/enacl_eqc.erl @@ -183,10 +183,10 @@ prop_box_correct() -> begin case v_iodata(Msg) andalso nonce_valid(Nonce) andalso keypair_valid(PK1, SK1) andalso keypair_valid(PK2, SK2) of true -> - Key = enacl:box_beforenm(PK2, SK1), - Key = enacl:box_beforenm(PK1, SK2), - CipherText = enacl:box(Msg, Nonce, PK2, SK1), - CipherText = enacl:box_afternm(Msg, Nonce, Key), + {ok, Key} = enacl:box_beforenm(PK2, SK1), + {ok, Key} = enacl:box_beforenm(PK1, SK2), + {ok, CipherText} = enacl:box(Msg, Nonce, PK2, SK1), + {ok, CipherText} = enacl:box_afternm(Msg, Nonce, Key), {ok, DecodedMsg} = enacl:box_open(CipherText, Nonce, PK1, SK2), {ok, DecodedMsg} = enacl:box_open_afternm(CipherText, Nonce, Key), equals(iolist_to_binary(Msg), DecodedMsg); @@ -210,8 +210,8 @@ prop_box_failure_integrity() -> andalso keypair_valid(PK1, SK1) andalso keypair_valid(PK2, SK2) of true -> - Key = enacl:box_beforenm(PK2, SK1), - CipherText = enacl:box(Msg, Nonce, PK2, SK1), + {ok, Key} = enacl:box_beforenm(PK2, SK1), + {ok, CipherText} = enacl:box(Msg, Nonce, PK2, SK1), Err = enacl:box_open([<<"x">>, CipherText], Nonce, PK1, SK2), Err = enacl:box_open_afternm([<<"x">>, CipherText], Nonce, Key), equals(Err, {error, failed_verification}); diff --git a/src/enacl.erl b/src/enacl.erl index cdfd578..5a2375a 100644 --- a/src/enacl.erl +++ b/src/enacl.erl @@ -446,7 +446,7 @@ box_keypair() -> %% Encrypt a `Msg' to the party identified by public key `PK' using your own secret key `SK' to %% authenticate yourself. Requires a `Nonce' in addition. Returns the ciphered message. %% @end --spec box(Msg, Nonce, PK, SK) -> CipherText +-spec box(Msg, Nonce, PK, SK) -> {ok, CipherText} | {error, term()} when Msg :: iodata(), Nonce :: binary(), @@ -470,14 +470,11 @@ box(Msg, Nonce, PK, SK) -> SK :: binary(), Msg :: binary(). box_open(CipherText, Nonce, PK, SK) -> - case enacl_nif:crypto_box_open([?P_BOXZEROBYTES, CipherText], Nonce, PK, SK) of - {error, Err} -> {error, Err}; - Bin when is_binary(Bin) -> {ok, Bin} - end. + enacl_nif:crypto_box_open([?P_BOXZEROBYTES, CipherText], Nonce, PK, SK). %% @doc box_beforenm/2 precomputes a box shared key for a PK/SK keypair %% @end --spec box_beforenm(PK, SK) -> binary() +-spec box_beforenm(PK, SK) -> {ok, binary()} | {error, term()} when PK :: binary(), SK :: binary(). @@ -492,7 +489,7 @@ box_beforenm(PK, SK) -> %% if you had called `box(M, Nonce, PK, SK)'. Except that it avoids computations in the elliptic curve Curve25519, %% and thus is a much faster operation. %% @end --spec box_afternm(Msg, Nonce, K) -> CipherText +-spec box_afternm(Msg, Nonce, K) -> {ok, CipherText} | {error, term()} when Msg :: iodata(), Nonce :: binary(), @@ -522,23 +519,10 @@ box_afternm(Msg, Nonce, Key) -> box_open_afternm(CipherText, Nonce, Key) -> case iolist_size(CipherText) of K when K =< ?BOX_AFTERNM_SIZE -> - R = - case enacl_nif:crypto_box_open_afternm_b( - [?P_BOXZEROBYTES, CipherText], Nonce, Key) of - {error, Err} -> - {error, Err}; - Bin when is_binary(Bin) -> - {ok, Bin} - end, + R = enacl_nif:crypto_box_open_afternm_b([?P_BOXZEROBYTES, CipherText], Nonce, Key), bump(R, ?BOX_AFTERNM_REDUCTIONS, ?BOX_AFTERNM_SIZE, K); _ -> - case enacl_nif:crypto_box_open_afternm( - [?P_BOXZEROBYTES, CipherText], Nonce, Key) of - {error, Err} -> - {error, Err}; - Bin when is_binary(Bin) -> - {ok, Bin} - end + enacl_nif:crypto_box_open_afternm([?P_BOXZEROBYTES, CipherText], Nonce, Key) end. %% @doc box_nonce_size/0 return the byte-size of the nonce