From 78621356ecd3624dd1cbab25f5b5698be56a40cf Mon Sep 17 00:00:00 2001 From: Jesper Louis Andersen Date: Wed, 5 Feb 2020 12:08:28 +0100 Subject: [PATCH] Split extension functions away --- c_src/enacl_ext.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ c_src/enacl_ext.h | 9 +++++ c_src/enacl_nif.c | 91 ++++------------------------------------------- 3 files changed, 102 insertions(+), 84 deletions(-) create mode 100644 c_src/enacl_ext.c create mode 100644 c_src/enacl_ext.h diff --git a/c_src/enacl_ext.c b/c_src/enacl_ext.c new file mode 100644 index 0000000..44cc4ef --- /dev/null +++ b/c_src/enacl_ext.c @@ -0,0 +1,86 @@ +#include + +#include + +#include "enacl.h" +#include "enacl_ext.h" + +static void uint64_pack(unsigned char *y, ErlNifUInt64 x) { + *y++ = x; + x >>= 8; + *y++ = x; + x >>= 8; + *y++ = x; + x >>= 8; + *y++ = x; + x >>= 8; + *y++ = x; + x >>= 8; + *y++ = x; + x >>= 8; + *y++ = x; + x >>= 8; + *y++ = x; +} + +static ErlNifUInt64 uint64_unpack(const unsigned char *x) { + ErlNifUInt64 result; + + result = x[7]; + result <<= 8; + result |= x[6]; + result <<= 8; + result |= x[5]; + result <<= 8; + result |= x[4]; + result <<= 8; + result |= x[3]; + result <<= 8; + result |= x[2]; + result <<= 8; + result |= x[1]; + result <<= 8; + result |= x[0]; + return result; +} + +static int crypto_block(unsigned char *out, const unsigned char *in, + const unsigned char *k) { + ErlNifUInt64 v0 = uint64_unpack(in + 0); + ErlNifUInt64 v1 = uint64_unpack(in + 8); + ErlNifUInt64 k0 = uint64_unpack(k + 0); + ErlNifUInt64 k1 = uint64_unpack(k + 8); + ErlNifUInt64 k2 = uint64_unpack(k + 16); + ErlNifUInt64 k3 = uint64_unpack(k + 24); + ErlNifUInt64 sum = 0; + ErlNifUInt64 delta = 0x9e3779b97f4a7c15; + int i; + for (i = 0; i < 32; ++i) { + sum += delta; + v0 += ((v1 << 7) + k0) ^ (v1 + sum) ^ ((v1 >> 12) + k1); + v1 += ((v0 << 16) + k2) ^ (v0 + sum) ^ ((v0 >> 8) + k3); + } + uint64_pack(out + 0, v0); + uint64_pack(out + 8, v1); + + return 0; +} + +ERL_NIF_TERM enif_scramble_block_16(ErlNifEnv *env, int argc, + ERL_NIF_TERM const argv[]) { + ErlNifBinary in, out, key; + + if ((argc != 2) || (!enif_inspect_binary(env, argv[0], &in)) || + (!enif_inspect_binary(env, argv[1], &key)) || (in.size != 16) || + (key.size != 32)) { + return enif_make_badarg(env); + } + + if (!enif_alloc_binary(in.size, &out)) { + return enacl_error_tuple(env, "alloc_failed"); + } + + crypto_block(out.data, in.data, key.data); + + return enif_make_binary(env, &out); +} \ No newline at end of file diff --git a/c_src/enacl_ext.h b/c_src/enacl_ext.h new file mode 100644 index 0000000..c0e5a5a --- /dev/null +++ b/c_src/enacl_ext.h @@ -0,0 +1,9 @@ +#ifndef ENACL_EXT_H +#define ENACL_EXT_H + +#include + +ERL_NIF_TERM enif_scramble_block_16(ErlNifEnv *env, int argc, + ERL_NIF_TERM const argv[]); + +#endif diff --git a/c_src/enacl_nif.c b/c_src/enacl_nif.c index 1e47712..acf1ba6 100644 --- a/c_src/enacl_nif.c +++ b/c_src/enacl_nif.c @@ -5,6 +5,7 @@ #include "aead.h" #include "enacl.h" +#include "enacl_ext.h" #include "generichash.h" #include "hash.h" #include "kx.h" @@ -121,11 +122,12 @@ enacl_crypto_curve25519_scalarmult(ErlNifEnv *env, int argc, do { if (!enif_alloc_binary(crypto_scalarmult_curve25519_BYTES, &output)) { - result = enacl_error_tuple(env, "alloc_failed"); + result = enacl_internal_error(env); continue; } - if (crypto_scalarmult_curve25519(output.data, secret.data, bp) < 0) { + if (crypto_scalarmult_curve25519(output.data, secret.data, bp) != 0) { + enif_release_binary(&output); result = enacl_error_tuple(env, "scalarmult_curve25519_failed"); continue; } @@ -151,11 +153,12 @@ enacl_crypto_curve25519_scalarmult_base(ErlNifEnv *env, int argc, do { if (!enif_alloc_binary(crypto_scalarmult_curve25519_BYTES, &output)) { - result = enacl_error_tuple(env, "alloc_failed"); + result = enacl_internal_error(env); continue; } - if (crypto_scalarmult_curve25519_base(output.data, secret.data) < 0) { + if (crypto_scalarmult_curve25519_base(output.data, secret.data) != 0) { + enif_release_binary(&output); result = enacl_error_tuple(env, "scalarmult_curve25519_base_failed"); continue; } @@ -166,86 +169,6 @@ enacl_crypto_curve25519_scalarmult_base(ErlNifEnv *env, int argc, return result; } -/* Various other helper functions */ -static void uint64_pack(unsigned char *y, ErlNifUInt64 x) { - *y++ = x; - x >>= 8; - *y++ = x; - x >>= 8; - *y++ = x; - x >>= 8; - *y++ = x; - x >>= 8; - *y++ = x; - x >>= 8; - *y++ = x; - x >>= 8; - *y++ = x; - x >>= 8; - *y++ = x; -} - -static ErlNifUInt64 uint64_unpack(const unsigned char *x) { - ErlNifUInt64 result; - - result = x[7]; - result <<= 8; - result |= x[6]; - result <<= 8; - result |= x[5]; - result <<= 8; - result |= x[4]; - result <<= 8; - result |= x[3]; - result <<= 8; - result |= x[2]; - result <<= 8; - result |= x[1]; - result <<= 8; - result |= x[0]; - return result; -} -static int crypto_block(unsigned char *out, const unsigned char *in, - const unsigned char *k) { - ErlNifUInt64 v0 = uint64_unpack(in + 0); - ErlNifUInt64 v1 = uint64_unpack(in + 8); - ErlNifUInt64 k0 = uint64_unpack(k + 0); - ErlNifUInt64 k1 = uint64_unpack(k + 8); - ErlNifUInt64 k2 = uint64_unpack(k + 16); - ErlNifUInt64 k3 = uint64_unpack(k + 24); - ErlNifUInt64 sum = 0; - ErlNifUInt64 delta = 0x9e3779b97f4a7c15; - int i; - for (i = 0; i < 32; ++i) { - sum += delta; - v0 += ((v1 << 7) + k0) ^ (v1 + sum) ^ ((v1 >> 12) + k1); - v1 += ((v0 << 16) + k2) ^ (v0 + sum) ^ ((v0 >> 8) + k3); - } - uint64_pack(out + 0, v0); - uint64_pack(out + 8, v1); - - return 0; -} - -static ERL_NIF_TERM enif_scramble_block_16(ErlNifEnv *env, int argc, - ERL_NIF_TERM const argv[]) { - ErlNifBinary in, out, key; - - if ((argc != 2) || (!enif_inspect_binary(env, argv[0], &in)) || - (!enif_inspect_binary(env, argv[1], &key)) || (in.size != 16) || - (key.size != 32)) { - return enif_make_badarg(env); - } - - if (!enif_alloc_binary(in.size, &out)) { - return enacl_error_tuple(env, "alloc_failed"); - } - - crypto_block(out.data, in.data, key.data); - - return enif_make_binary(env, &out); -} - /* Tie the knot to the Erlang world */ static ErlNifFunc nif_funcs[] = { {"crypto_box_NONCEBYTES", 0, enacl_crypto_box_NONCEBYTES},