From 9849e7310af455a9dedd075f6c3cf1b43762892e Mon Sep 17 00:00:00 2001 From: Doug Huff Date: Wed, 28 Oct 2015 21:45:13 +0000 Subject: [PATCH] Add unsafe_memzero/1 --- c_src/enacl_nif.c | 16 ++++++++++++++++ src/enacl.erl | 14 +++++++++++++- src/enacl_nif.erl | 4 +++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/c_src/enacl_nif.c b/c_src/enacl_nif.c index da54551..e759002 100644 --- a/c_src/enacl_nif.c +++ b/c_src/enacl_nif.c @@ -81,6 +81,21 @@ ERL_NIF_TERM enif_crypto_verify_32(ErlNifEnv *env, int argc, ERL_NIF_TERM const } } +/* This is very unsafe. It will not affect things that have been binary_copy()'ed + Use this for destroying key material from ram but nothing more. Be careful! */ +static +ERL_NIF_TERM enif_sodium_memzero(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { + ErlNifBinary x; + + if ((argc != 1) || (!enif_inspect_binary(env, argv[0], &x))) { + return enif_make_badarg(env); + } + + sodium_memzero(x.data,x.size); + + return enif_make_atom(env, "ok"); +} + /* Curve 25519 */ static ERL_NIF_TERM enif_crypto_curve25519_scalarmult(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { @@ -1172,6 +1187,7 @@ static ErlNifFunc nif_funcs[] = { {"crypto_hash", 1, enif_crypto_hash, ERL_NIF_DIRTY_JOB_CPU_BOUND}, {"crypto_verify_16", 2, enif_crypto_verify_16}, {"crypto_verify_32", 2, enif_crypto_verify_32}, + {"sodium_memzero", 1, enif_sodium_memzero}, {"crypto_curve25519_scalarmult", 2, enif_crypto_curve25519_scalarmult, ERL_NIF_DIRTY_JOB_CPU_BOUND}, diff --git a/src/enacl.erl b/src/enacl.erl index 5e06dc8..75e6ba9 100644 --- a/src/enacl.erl +++ b/src/enacl.erl @@ -92,7 +92,8 @@ -export([ hash/1, verify_16/2, - verify_32/2 + verify_32/2, + unsafe_memzero/1 ]). %% Libsodium specific functions (which are also part of the "undocumented" interface to NaCl @@ -214,6 +215,17 @@ verify_16(_, _) -> error(badarg). verify_32(X, Y) when is_binary(X), is_binary(Y) -> enacl_nif:crypto_verify_32(X, Y); verify_32(_, _) -> error(badarg). +%% @doc unsafe_memzero/1 ipmlements guaranteed zero'ing of binary data. +%% +%%

WARNING: Take great care. This way be dragons.

+%%

This is verify unsafe. If any copies of the binary have been made they are unaffected. +%% This is intended for use with cryptographic keys where they are only shared within +%% a running process without copies. This allows removing, eg, symmetric session keys.

+%% @end +-spec unsafe_memzero(binary()) -> atom(). +unsafe_memzero(X) when is_binary(X) -> enacl_nif:sodium_memzero(X); +unsafe_memzero(_) -> error(badarg). + %% Public Key Crypto %% --------------------- %% @doc box_keypair/0 creates a new Public/Secret keypair. diff --git a/src/enacl_nif.erl b/src/enacl_nif.erl index 36ab1d1..917e9d4 100644 --- a/src/enacl_nif.erl +++ b/src/enacl_nif.erl @@ -109,7 +109,8 @@ crypto_hash/1, crypto_hash_b/1, crypto_verify_16/2, - crypto_verify_32/2 + crypto_verify_32/2, + sodium_memzero/1 ]). %% Access to the RNG @@ -220,6 +221,7 @@ crypto_hash(Input) when is_binary(Input) -> erlang:nif_error(nif_not_loaded). crypto_hash_b(Input) when is_binary(Input) -> erlang:nif_error(nif_not_loaded). crypto_verify_16(_X, _Y) -> erlang:nif_error(nif_not_loaded). crypto_verify_32(_X, _Y) -> erlang:nif_error(nif_not_loaded). +sodium_memzero(Input) when is_binary(Input) -> erlang:nif_error(nif_not_loaded). randombytes(_RequestedSize) -> erlang:nif_error(nif_not_loaded).