Merge pull request #9 from aeternity/secretbox_easy_only
Add access to secretbox_easy/easy_open functions
This commit is contained in:
commit
a3d010ba62
@ -256,6 +256,12 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"crypto_secretbox_open_b", 3, enacl_crypto_secretbox_open},
|
{"crypto_secretbox_open_b", 3, enacl_crypto_secretbox_open},
|
||||||
erl_nif_dirty_job_cpu_bound_macro("crypto_secretbox_open", 3,
|
erl_nif_dirty_job_cpu_bound_macro("crypto_secretbox_open", 3,
|
||||||
enacl_crypto_secretbox_open),
|
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,
|
{"crypto_stream_chacha20_KEYBYTES", 0,
|
||||||
enacl_crypto_stream_chacha20_KEYBYTES},
|
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);
|
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 enacl_crypto_stream_chacha20(ErlNifEnv *env, int argc,
|
||||||
ERL_NIF_TERM const argv[]) {
|
ERL_NIF_TERM const argv[]) {
|
||||||
ErlNifBinary c, n, k;
|
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 enacl_crypto_secretbox_open(ErlNifEnv *env, int argc,
|
||||||
ERL_NIF_TERM const argv[]);
|
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 enacl_crypto_stream_chacha20(ErlNifEnv *env, int argc,
|
||||||
ERL_NIF_TERM const argv[]);
|
ERL_NIF_TERM const argv[]);
|
||||||
|
|
||||||
|
@ -550,6 +550,44 @@ prop_secretbox_failure_integrity() ->
|
|||||||
equals(Err, {error, failed_verification})
|
equals(Err, {error, failed_verification})
|
||||||
end).
|
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
|
||||||
%% ------------------------------------------------------------
|
%% ------------------------------------------------------------
|
||||||
%% * aead_chacha20poly1305_encrypt/4,
|
%% * aead_chacha20poly1305_encrypt/4,
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
secretbox_NONCEBYTES/0,
|
secretbox_NONCEBYTES/0,
|
||||||
secretbox/3,
|
secretbox/3,
|
||||||
secretbox_open/3,
|
secretbox_open/3,
|
||||||
|
secretbox_easy/3,
|
||||||
|
secretbox_open_easy/3,
|
||||||
|
|
||||||
%% No Tests!
|
%% No Tests!
|
||||||
stream_chacha20_KEYBYTES/0,
|
stream_chacha20_KEYBYTES/0,
|
||||||
@ -837,6 +839,50 @@ secretbox_open(CipherText, Nonce, Key) ->
|
|||||||
enacl_nif:crypto_secretbox_open([?S_BOXZEROBYTES, CipherText], Nonce, Key)
|
enacl_nif:crypto_secretbox_open([?S_BOXZEROBYTES, CipherText], Nonce, Key)
|
||||||
end.
|
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
|
%% @doc secretbox_NONCEBYTES()/0 returns the size of the secretbox nonce
|
||||||
%%
|
%%
|
||||||
%% When encrypting with a secretbox, the nonce must have this size
|
%% When encrypting with a secretbox, the nonce must have this size
|
||||||
|
@ -57,6 +57,10 @@
|
|||||||
crypto_secretbox_b/3,
|
crypto_secretbox_b/3,
|
||||||
crypto_secretbox_open/3,
|
crypto_secretbox_open/3,
|
||||||
crypto_secretbox_open_b/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_KEYBYTES/0,
|
||||||
crypto_stream_chacha20_NONCEBYTES/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_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(_Msg, _Nonce, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||||
crypto_secretbox_open_b(_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_KEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||||
crypto_stream_chacha20_NONCEBYTES() -> 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