Merge pull request #6 from reith/sealed-box-func

Expose Seal Box functions
This commit is contained in:
Jesper Louis Andersen 2015-08-10 10:39:20 +02:00
commit 7b64f3e52b
3 changed files with 115 additions and 4 deletions

View File

@ -554,6 +554,71 @@ ERL_NIF_TERM enif_crypto_sign_verify_detached(ErlNifEnv* env, int argc, ERL_NIF_
}
}
/* Sealed box functions */
static
ERL_NIF_TERM enif_crypto_box_SEALBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
return enif_make_int64(env, crypto_box_SEALBYTES);
}
static
ERL_NIF_TERM enif_crypto_box_seal(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
ErlNifBinary key, msg, ciphertext;
if (
(argc != 2) ||
(!enif_inspect_iolist_as_binary(env, argv[0], &msg)) ||
(!enif_inspect_binary(env, argv[1], &key))) {
return enif_make_badarg(env);
}
if (!enif_alloc_binary(msg.size + crypto_box_SEALBYTES, &ciphertext)) {
return nacl_error_tuple(env, "alloc_failed");
}
crypto_box_seal(
ciphertext.data,
msg.data,
msg.size,
key.data);
return enif_make_binary(env, &ciphertext);
}
static
ERL_NIF_TERM enif_crypto_box_seal_open(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
ErlNifBinary pk, sk, ciphertext, msg;
if (
(argc != 3) ||
(!enif_inspect_iolist_as_binary(env, argv[0], &ciphertext)) ||
(!enif_inspect_binary(env, argv[1], &pk)) ||
(!enif_inspect_binary(env, argv[2], &sk))) {
return enif_make_badarg(env);
}
if (ciphertext.size <= crypto_box_SEALBYTES) {
return enif_make_badarg(env);
}
if (!enif_alloc_binary(ciphertext.size - crypto_box_SEALBYTES, &msg)) {
return nacl_error_tuple(env, "alloc_failed");
}
if (crypto_box_seal_open(
msg.data,
ciphertext.data,
ciphertext.size,
pk.data,
sk.data) != 0) {
enif_release_binary(&msg);
return nacl_error_tuple(env, "failed_verification");
}
return enif_make_binary(env, &msg);
}
/* Secret key cryptography */
static
@ -958,6 +1023,10 @@ static ErlNifFunc nif_funcs[] = {
{"crypto_sign_detached", 2, enif_crypto_sign_detached, ERL_NIF_DIRTY_JOB_CPU_BOUND},
{"crypto_sign_verify_detached", 3, enif_crypto_sign_verify_detached, ERL_NIF_DIRTY_JOB_CPU_BOUND},
{"crypto_box_SEALBYTES", 0, enif_crypto_box_SEALBYTES},
{"crypto_box_seal", 2, enif_crypto_box_seal, ERL_NIF_DIRTY_JOB_CPU_BOUND},
{"crypto_box_seal_open", 3, enif_crypto_box_seal_open, ERL_NIF_DIRTY_JOB_CPU_BOUND},
{"crypto_secretbox_NONCEBYTES", 0, enif_crypto_secretbox_NONCEBYTES},
{"crypto_secretbox_ZEROBYTES", 0, enif_crypto_secretbox_ZEROBYTES},
{"crypto_secretbox_BOXZEROBYTES", 0, enif_crypto_secretbox_BOXZEROBYTES},

View File

@ -35,8 +35,11 @@
sign_keypair/0,
sign/2,
sign_open/2,
sign_detached/2,
sign_verify_detached/3
sign_detached/2,
sign_verify_detached/3,
seal_box/2,
seal_box_open/3
]).
%% Secret key crypto
@ -196,6 +199,7 @@ box_keypair() ->
{PK, SK} = enacl_nif:crypto_box_keypair(),
#{ public => PK, secret => SK}.
%% @doc box/4 encrypts+authenticates a message to another party.
%%
%% Encrypt a `Msg' to the party identified by public key `PK' using your own secret key `SK' to
@ -414,6 +418,36 @@ sign_verify_detached(SIG, M, PK) ->
box_secret_key_bytes() ->
enacl_nif:crypto_box_SECRETKEYBYTES().
%% @doc seal_box/2 encrypts an anonymous message to another party.
%%
%% Encrypt a `Msg' to a party using his public key, `PK'. This generates an ephemeral
%% keypair and then uses `box'. Ephemeral public key will sent to other party. Returns the
%% enciphered message `SealedCipherText' which includes ephemeral public key at head.
%% @end
-spec seal_box(Msg, PK) -> SealedCipherText
when Msg :: iodata(),
PK :: binary(),
SealedCipherText :: binary().
seal_box(Msg, PK) ->
enacl_nif:crypto_box_seal(Msg, PK).
%% @doc seal_box_open/3 decrypts+check message integrity from an unknown sender.
%%
%% Decrypt a `SealedCipherText' which contains an ephemeral public key from another party
%% into a `Msg' using that key and your public and secret keys, `PK' and `SK'. Returns the
%% plaintext message.
%% @end
-spec seal_box_open(SealedCipherText, PK, SK) -> {ok, Msg} | {error, failed_verification}
when SealedCipherText :: iodata(),
PK :: binary(),
SK :: binary(),
Msg :: binary().
seal_box_open(SealedCipherText, PK, SK) ->
case enacl_nif:crypto_box_seal_open(SealedCipherText, PK, SK) of
{error, Err} -> {error, Err};
Bin when is_binary(Bin) -> Bin
end.
%% @doc secretbox/3 encrypts a message with a key
%%
%% Given a `Msg', a `Nonce' and a `Key' encrypt the message with the Key while taking the

View File

@ -33,8 +33,12 @@
crypto_sign_open/2,
crypto_sign_open_b/2,
crypto_sign_detached/2,
crypto_sign_verify_detached/3
crypto_sign_detached/2,
crypto_sign_verify_detached/3,
crypto_box_seal/2,
crypto_box_seal_open/3,
crypto_box_SEALBYTES/0
]).
@ -151,6 +155,10 @@ crypto_sign_open_b(_SignedMessage, _PK) -> erlang:nif_error(nif_not_loaded).
crypto_sign_detached(_M, _SK) -> erlang:nif_error(nif_not_loaded).
crypto_sign_verify_detached(_SIG, _M, _PK) -> erlang:nif_error(nif_not_loaded).
crypto_box_seal(_Msg, _PK) -> erlang:nif_error(nif_not_loaded).
crypto_box_seal_open(_CipherText, _PK, _SK) -> erlang:nif_error(nif_not_loaded).
crypto_box_SEALBYTES() -> erlang:nif_error(nif_not_loaded).
crypto_secretbox_NONCEBYTES() -> erlang:nif_error(nif_not_loaded).
crypto_secretbox_ZEROBYTES() -> erlang:nif_error(nif_not_loaded).
crypto_secretbox_KEYBYTES() -> erlang:nif_error(nif_not_loaded).