Add access to secretbox_easy/easy_open functions
They are just a simplification of the secretbox API, thus it does not provide any new functionality. But it helps mapping function names to libsodium documentation.
This commit is contained in:
parent
67fceef42c
commit
fa94eaf6f6
@ -256,6 +256,12 @@ static ErlNifFunc nif_funcs[] = {
|
||||
{"crypto_secretbox_open_b", 3, enacl_crypto_secretbox_open},
|
||||
erl_nif_dirty_job_cpu_bound_macro("crypto_secretbox_open", 3,
|
||||
enacl_crypto_secretbox_open),
|
||||
{"crypto_secretbox_easy_b", 3, enacl_crypto_secretbox_easy},
|
||||
erl_nif_dirty_job_cpu_bound_macro("crypto_secretbox_easy", 3,
|
||||
enacl_crypto_secretbox_easy),
|
||||
{"crypto_secretbox_open_easy_b", 3, enacl_crypto_secretbox_open_easy},
|
||||
erl_nif_dirty_job_cpu_bound_macro("crypto_secretbox_open_easy", 3,
|
||||
enacl_crypto_secretbox_open_easy),
|
||||
|
||||
{"crypto_stream_chacha20_KEYBYTES", 0,
|
||||
enacl_crypto_stream_chacha20_KEYBYTES},
|
||||
|
@ -137,6 +137,64 @@ ERL_NIF_TERM enacl_crypto_secretbox_open(ErlNifEnv *env, int argc,
|
||||
return enif_make_tuple2(env, ret_ok, ret_bin);
|
||||
}
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_secretbox_easy(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary key, nonce, msg, cipherbox;
|
||||
|
||||
if ((argc != 3) ||
|
||||
(!enif_inspect_iolist_as_binary(env, argv[0], &msg)) ||
|
||||
(!enif_inspect_binary(env, argv[1], &nonce)) ||
|
||||
(!enif_inspect_binary(env, argv[2], &key))) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
if ((key.size != crypto_secretbox_KEYBYTES) ||
|
||||
(nonce.size != crypto_secretbox_NONCEBYTES)) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
if (!enif_alloc_binary(msg.size + crypto_secretbox_MACBYTES, &cipherbox)) {
|
||||
return enacl_internal_error(env);
|
||||
}
|
||||
|
||||
crypto_secretbox_easy(cipherbox.data, msg.data, msg.size,
|
||||
nonce.data, key.data);
|
||||
|
||||
return enif_make_binary(env, &cipherbox);
|
||||
}
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_secretbox_open_easy(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary key, nonce, cipherbox, msg;
|
||||
|
||||
if ((argc != 3) ||
|
||||
(!enif_inspect_iolist_as_binary(env, argv[0], &cipherbox)) ||
|
||||
(!enif_inspect_binary(env, argv[1], &nonce)) ||
|
||||
(!enif_inspect_binary(env, argv[2], &key))) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
if ((key.size != crypto_secretbox_KEYBYTES) ||
|
||||
(nonce.size != crypto_secretbox_NONCEBYTES) ||
|
||||
(cipherbox.size < crypto_secretbox_MACBYTES)) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
if (!enif_alloc_binary(cipherbox.size - crypto_secretbox_MACBYTES, &msg)) {
|
||||
return enacl_internal_error(env);
|
||||
}
|
||||
|
||||
if (crypto_secretbox_open_easy(msg.data, cipherbox.data, cipherbox.size,
|
||||
nonce.data, key.data) != 0) {
|
||||
enif_release_binary(&msg);
|
||||
return enacl_error_tuple(env, "failed_verification");
|
||||
}
|
||||
|
||||
ERL_NIF_TERM ret_ok = enif_make_atom(env, ATOM_OK);
|
||||
ERL_NIF_TERM ret_bin = enif_make_binary(env, &msg);
|
||||
return enif_make_tuple2(env, ret_ok, ret_bin);
|
||||
}
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_stream_chacha20(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary c, n, k;
|
||||
|
@ -43,6 +43,12 @@ ERL_NIF_TERM enacl_crypto_secretbox(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM enacl_crypto_secretbox_open(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]);
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_secretbox_easy(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]);
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_secretbox_open_easy(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]);
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_stream_chacha20(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]);
|
||||
|
||||
|
@ -550,6 +550,44 @@ prop_secretbox_failure_integrity() ->
|
||||
equals(Err, {error, failed_verification})
|
||||
end).
|
||||
|
||||
secretbox_easy(Msg, Nonce, Key) ->
|
||||
try enacl:secretbox_easy(Msg, Nonce, Key)
|
||||
catch error:badarg -> badarg
|
||||
end.
|
||||
|
||||
secretbox_open_easy(Msg, Nonce, Key) ->
|
||||
try enacl:secretbox_open_easy(Msg, Nonce, Key)
|
||||
catch error:badarg -> badarg
|
||||
end.
|
||||
|
||||
prop_secretbox_easy_correct() ->
|
||||
?FORALL({Msg, Nonce, Key},
|
||||
{?FAULT_RATE(1, 40, g_iodata()),
|
||||
?FAULT_RATE(1, 40, nonce()),
|
||||
?FAULT_RATE(1, 40, secret_key())},
|
||||
begin
|
||||
case v_iodata(Msg) andalso nonce_valid(Nonce) andalso secret_key_valid(Key) of
|
||||
true ->
|
||||
CipherText = enacl:secretbox_easy(Msg, Nonce, Key),
|
||||
{ok, DecodedMsg} = enacl:secretbox_open_easy(CipherText, Nonce, Key),
|
||||
equals(iolist_to_binary(Msg), DecodedMsg);
|
||||
false ->
|
||||
case secretbox_easy(Msg, Nonce, Key) of
|
||||
badarg -> true;
|
||||
Res ->
|
||||
failure(secretbox_open_easy(Res, Nonce, Key))
|
||||
end
|
||||
end
|
||||
end).
|
||||
|
||||
prop_secretbox_easy_failure_integrity() ->
|
||||
?FORALL({Msg, Nonce, Key}, {g_iodata(), nonce(), secret_key()},
|
||||
begin
|
||||
CipherText = enacl:secretbox_easy(Msg, Nonce, Key),
|
||||
Err = enacl:secretbox_open_easy([<<"x">>, CipherText], Nonce, Key),
|
||||
equals(Err, {error, failed_verification})
|
||||
end).
|
||||
|
||||
%% AEAD ChaCha20Poly1305
|
||||
%% ------------------------------------------------------------
|
||||
%% * aead_chacha20poly1305_encrypt/4,
|
||||
|
@ -59,6 +59,8 @@
|
||||
secretbox_NONCEBYTES/0,
|
||||
secretbox/3,
|
||||
secretbox_open/3,
|
||||
secretbox_easy/3,
|
||||
secretbox_open_easy/3,
|
||||
|
||||
%% No Tests!
|
||||
stream_chacha20_KEYBYTES/0,
|
||||
@ -837,6 +839,50 @@ secretbox_open(CipherText, Nonce, Key) ->
|
||||
enacl_nif:crypto_secretbox_open([?S_BOXZEROBYTES, CipherText], Nonce, Key)
|
||||
end.
|
||||
|
||||
%% @doc secretbox_easy/3 encrypts a message with a key (and nonce)
|
||||
%%
|
||||
%% Given a `Msg', a `Nonce' and a `Key' encrypt the message with the Key while taking the
|
||||
%% nonce into consideration. `easy' refers to not having to take padding, etc. into
|
||||
%% account. The function returns the Box obtained from the encryption.
|
||||
%% @end
|
||||
-spec secretbox_easy(Msg, Nonce, Key) -> Box
|
||||
when
|
||||
Msg :: iodata(),
|
||||
Nonce :: binary(),
|
||||
Key :: binary(),
|
||||
Box :: binary().
|
||||
secretbox_easy(Msg, Nonce, Key) ->
|
||||
case iolist_size(Msg) of
|
||||
K when K =< ?SECRETBOX_SIZE ->
|
||||
bump(enacl_nif:crypto_secretbox_easy_b(Msg, Nonce, Key),
|
||||
?SECRETBOX_REDUCTIONS,
|
||||
?SECRETBOX_SIZE,
|
||||
K);
|
||||
_ ->
|
||||
enacl_nif:crypto_secretbox_easy(Msg, Nonce, Key)
|
||||
end.
|
||||
|
||||
%% @doc secretbox_open_easy/3 opens a sealed box.
|
||||
%%
|
||||
%% Given a boxed `CipherText' and given we know the used `Nonce' and `Key' we can open the box
|
||||
%% to obtain the `Msg' within. `easy' refers to not having to take padding, etc. into
|
||||
%% account. Returns either `{ok, Msg}' or `{error, failed_verification}'.
|
||||
%% @end
|
||||
-spec secretbox_open_easy(CipherText, Nonce, Key) -> {ok, Msg} | {error, failed_verification}
|
||||
when
|
||||
CipherText :: iodata(),
|
||||
Nonce :: binary(),
|
||||
Key :: binary(),
|
||||
Msg :: binary().
|
||||
secretbox_open_easy(CipherText, Nonce, Key) ->
|
||||
case iolist_size(CipherText) of
|
||||
K when K =< ?SECRETBOX_SIZE ->
|
||||
R = enacl_nif:crypto_secretbox_open_easy_b(CipherText, Nonce, Key),
|
||||
bump(R, ?SECRETBOX_OPEN_REDUCTIONS, ?SECRETBOX_SIZE, K);
|
||||
_ ->
|
||||
enacl_nif:crypto_secretbox_open_easy(CipherText, Nonce, Key)
|
||||
end.
|
||||
|
||||
%% @doc secretbox_NONCEBYTES()/0 returns the size of the secretbox nonce
|
||||
%%
|
||||
%% When encrypting with a secretbox, the nonce must have this size
|
||||
|
@ -57,6 +57,10 @@
|
||||
crypto_secretbox_b/3,
|
||||
crypto_secretbox_open/3,
|
||||
crypto_secretbox_open_b/3,
|
||||
crypto_secretbox_easy/3,
|
||||
crypto_secretbox_easy_b/3,
|
||||
crypto_secretbox_open_easy/3,
|
||||
crypto_secretbox_open_easy_b/3,
|
||||
|
||||
crypto_stream_chacha20_KEYBYTES/0,
|
||||
crypto_stream_chacha20_NONCEBYTES/0,
|
||||
@ -303,6 +307,10 @@ crypto_secretbox(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_secretbox_b(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_secretbox_open(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_secretbox_open_b(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_secretbox_easy(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_secretbox_easy_b(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_secretbox_open_easy(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_secretbox_open_easy_b(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||
|
||||
crypto_stream_chacha20_KEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||
crypto_stream_chacha20_NONCEBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||
|
Loading…
x
Reference in New Issue
Block a user