From 772a97d3dbf52eb4d582dc313c0930dfb4ebc4c8 Mon Sep 17 00:00:00 2001 From: Jesper Louis Andersen Date: Mon, 24 Nov 2014 14:39:19 +0100 Subject: [PATCH] Implement low level code for the authenticators. --- c_src/enacl_nif.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/c_src/enacl_nif.c b/c_src/enacl_nif.c index b97d64f..a0dd801 100644 --- a/c_src/enacl_nif.c +++ b/c_src/enacl_nif.c @@ -177,6 +177,11 @@ ERL_NIF_TERM enif_crypto_stream_NONCEBYTES(ErlNifEnv *env, int argc, ERL_NIF_TER return enif_make_int64(env, crypto_stream_NONCEBYTES); } +static +ERL_NIF_TERM enif_crypto_auth_KEYBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + return enif_make_int64(env, crypto_auth_KEYBYTES); +} + static ERL_NIF_TERM enif_crypto_secretbox(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { ErlNifBinary key, nonce, padded_msg, padded_ciphertext; @@ -307,6 +312,56 @@ ERL_NIF_TERM enif_crypto_stream_xor(ErlNifEnv *env, int argc, ERL_NIF_TERM const return enif_make_binary(env, &c); } +static +ERL_NIF_TERM enif_crypto_auth(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + ErlNifBinary a,m,k; + + if ( + (argc != 2) || + (!enif_inspect_iolist_as_binary(env, argv[0], &m)) || + (!enif_inspect_iolist_as_binary(env, argv[1], &k))) { + return enif_make_badarg(env); + } + + if (k.size != crypto_auth_KEYBYTES) { + return enif_make_badarg(env); + } + + if (!enif_alloc_binary(crypto_auth_BYTES, &a)) { + return nacl_error_tuple(env, "alloc_failed"); + } + + crypto_auth(a.data, m.data, m.size, k.data); + + return enif_make_binary(env, &a); +} + +static +ERL_NIF_TERM enif_crypto_auth_verify(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + ErlNifBinary a, m, k; + + if ( + (argc != 3) || + (!enif_inspect_iolist_as_binary(env, argv[0], &a)) || + (!enif_inspect_iolist_as_binary(env, argv[1], &m)) || + (!enif_inspect_iolist_as_binary(env, argv[2], &k))) { + return enif_make_badarg(env); + } + + if ( + (k.size != crypto_auth_KEYBYTES) || + (a.size != crypto_auth_BYTES)) { + return enif_make_badarg(env); + } + + if (0 == crypto_auth_verify(a.data, m.data, m.size, k.data)) { + return enif_make_atom(env, "true"); + } else { + return enif_make_atom(env, "false"); + } +} + + /* Tie the knot to the Erlang world */ static ErlNifFunc nif_funcs[] = { {"crypto_box_NONCEBYTES", 0, enif_crypto_box_NONCEBYTES}, @@ -330,6 +385,10 @@ static ErlNifFunc nif_funcs[] = { {"crypto_stream", 3, enif_crypto_stream, ERL_NIF_DIRTY_JOB_CPU_BOUND}, {"crypto_stream_xor", 3, enif_crypto_stream_xor, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"crypto_auth_KEYBYTES", 0, enif_crypto_auth_KEYBYTES}, + {"crypto_auth", 2, enif_crypto_auth, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"crypto_auth_verify", 3, enif_crypto_auth_verify, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"crypto_hash", 1, enif_crypto_hash, ERL_NIF_DIRTY_JOB_CPU_BOUND} };