From 8361450745bdb93312ba2a3356639dd27a94e116 Mon Sep 17 00:00:00 2001 From: Jesper Louis Andersen Date: Sat, 7 Mar 2020 12:01:27 +0100 Subject: [PATCH] Format; release resources In the push path, release resources in a stack fashion. This avoids releasing a binary incorrectly. --- c_src/secretstream.c | 203 +++++++++++++++++++++---------------------- 1 file changed, 101 insertions(+), 102 deletions(-) diff --git a/c_src/secretstream.c b/c_src/secretstream.c index c29ec1b..51414e7 100644 --- a/c_src/secretstream.c +++ b/c_src/secretstream.c @@ -1,25 +1,26 @@ -#include #include +#include #include "enacl.h" #include "secretstream.h" typedef struct enacl_secretstream_ctx { ErlNifMutex *mtx; - crypto_secretstream_xchacha20poly1305_state *state; // The underlying secretstream state - int alive; // Is the context still valid for updates/finalization + crypto_secretstream_xchacha20poly1305_state + *state; // The underlying secretstream state + int alive; // Is the context still valid for updates/finalization } enacl_secretstream_ctx; ErlNifResourceType *enacl_secretstream_ctx_rtype = NULL; static void enacl_secretstream_ctx_dtor(ErlNifEnv *env, - enacl_secretstream_ctx *); + enacl_secretstream_ctx *); int enacl_init_secretstream_ctx(ErlNifEnv *env) { enacl_secretstream_ctx_rtype = - enif_open_resource_type(env, NULL, "enacl_secretstream_context", - (ErlNifResourceDtor *)enacl_secretstream_ctx_dtor, - ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER, NULL); + enif_open_resource_type(env, NULL, "enacl_secretstream_context", + (ErlNifResourceDtor *)enacl_secretstream_ctx_dtor, + ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER, NULL); if (enacl_secretstream_ctx_rtype == NULL) return 0; @@ -34,8 +35,9 @@ static void enacl_secretstream_ctx_dtor(ErlNifEnv *env, } if (obj->state) - sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes()); - enif_free(obj->state); + sodium_memzero(obj->state, + crypto_secretstream_xchacha20poly1305_statebytes()); + enif_free(obj->state); if (obj->mtx != NULL) enif_mutex_destroy(obj->mtx); @@ -47,62 +49,57 @@ static void enacl_secretstream_ctx_dtor(ErlNifEnv *env, * Secretstream */ -ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_ABYTES( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM +enacl_crypto_secretstream_xchacha20poly1305_ABYTES(ErlNifEnv *env, int argc, + const ERL_NIF_TERM argv[]) { return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_ABYTES); - } ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_HEADERBYTES( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { - return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_HEADERBYTES); + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { + return enif_make_int64(env, + crypto_secretstream_xchacha20poly1305_HEADERBYTES); } ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_KEYBYTES( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_KEYBYTES); } ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { - return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX); + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { + return enif_make_int64( + env, crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX); } ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_MESSAGE( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { - return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_MESSAGE); + return enif_make_int64(env, + crypto_secretstream_xchacha20poly1305_TAG_MESSAGE); } ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_PUSH( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_PUSH); } ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_REKEY( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_REKEY); } ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_FINAL( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_FINAL); } -ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_keygen( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM +enacl_crypto_secretstream_xchacha20poly1305_keygen(ErlNifEnv *env, int argc, + const ERL_NIF_TERM argv[]) { ErlNifBinary key; @@ -110,8 +107,9 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_keygen( return enif_make_badarg(env); } - if (!enif_alloc_binary(crypto_secretstream_xchacha20poly1305_KEYBYTES, &key)) { - return enacl_internal_error(env); + if (!enif_alloc_binary(crypto_secretstream_xchacha20poly1305_KEYBYTES, + &key)) { + return enacl_internal_error(env); } crypto_secretstream_xchacha20poly1305_keygen(key.data); @@ -126,9 +124,7 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_keygen( const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) */ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_push( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[] - ) { + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM ret; ErlNifBinary key, header; enacl_secretstream_ctx *obj = NULL; @@ -141,13 +137,14 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_push( goto bad_arg; } - if (!enif_alloc_binary(crypto_secretstream_xchacha20poly1305_HEADERBYTES, &header)) { + if (!enif_alloc_binary(crypto_secretstream_xchacha20poly1305_HEADERBYTES, + &header)) { ret = enacl_internal_error(env); goto done; } - if((obj = enif_alloc_resource(enacl_secretstream_ctx_rtype, - sizeof(enacl_secretstream_ctx))) == NULL) { + if ((obj = enif_alloc_resource(enacl_secretstream_ctx_rtype, + sizeof(enacl_secretstream_ctx))) == NULL) { ret = enacl_internal_error(env); goto release_header; } @@ -155,37 +152,38 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_push( obj->state = enif_alloc(crypto_secretstream_xchacha20poly1305_statebytes()); if (obj->state == NULL) { + ret = enacl_internal_error(env); goto release; } obj->alive = 1; if ((obj->mtx = enif_mutex_create("enacl.secretstream")) == NULL) { + ret = enacl_internal_error(env); goto free; } - crypto_secretstream_xchacha20poly1305_init_push(obj->state, header.data, key.data); + crypto_secretstream_xchacha20poly1305_init_push(obj->state, header.data, + key.data); - ret = enif_make_tuple2(env, - enif_make_binary(env, &header), - enif_make_resource(env, obj) - ); + ret = enif_make_tuple2(env, enif_make_binary(env, &header), + enif_make_resource(env, obj)); goto release; - bad_arg: return enif_make_badarg(env); free: if (obj->alive) if (obj->state != NULL) { - sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes()); + sodium_memzero(obj->state, + crypto_secretstream_xchacha20poly1305_statebytes()); enif_free(obj->state); obj->state = NULL; } +release_header: + enif_release_binary(&header); release: // This also frees the mutex via the destructor enif_release_resource(obj); -release_header: - enif_release_binary(&header); done: return ret; } @@ -197,9 +195,7 @@ crypto_secretstream_xchacha20poly1305_init_pull const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) */ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_pull( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[] - ) { + ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM ret; ErlNifBinary header, key; enacl_secretstream_ctx *obj = NULL; @@ -208,22 +204,21 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_pull( goto bad_arg; } - if(!enif_inspect_binary(env, argv[0], &header)) { + if (!enif_inspect_binary(env, argv[0], &header)) { goto bad_arg; } - if(!enif_inspect_binary(env, argv[1], &key)) { + if (!enif_inspect_binary(env, argv[1], &key)) { goto bad_arg; } if ((key.size != crypto_secretstream_xchacha20poly1305_KEYBYTES) || - (header.size != crypto_secretstream_xchacha20poly1305_HEADERBYTES)) - { + (header.size != crypto_secretstream_xchacha20poly1305_HEADERBYTES)) { goto bad_arg; } - if((obj = enif_alloc_resource(enacl_secretstream_ctx_rtype, - sizeof(enacl_secretstream_ctx))) == NULL) { + if ((obj = enif_alloc_resource(enacl_secretstream_ctx_rtype, + sizeof(enacl_secretstream_ctx))) == NULL) { ret = enacl_internal_error(env); goto done; } @@ -240,7 +235,8 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_pull( goto free; } - crypto_secretstream_xchacha20poly1305_init_pull(obj->state, header.data, key.data); + crypto_secretstream_xchacha20poly1305_init_pull(obj->state, header.data, + key.data); ret = enif_make_resource(env, obj); @@ -251,7 +247,8 @@ bad_arg: free: if (obj->alive) if (obj->state != NULL) { - sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes()); + sodium_memzero(obj->state, + crypto_secretstream_xchacha20poly1305_statebytes()); enif_free(obj->state); obj->state = NULL; } @@ -267,10 +264,9 @@ void crypto_secretstream_xchacha20poly1305_rekey (crypto_secretstream_xchacha20poly1305_state *state) */ -ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_rekey( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[] - ) { +ERL_NIF_TERM +enacl_crypto_secretstream_xchacha20poly1305_rekey(ErlNifEnv *env, int argc, + const ERL_NIF_TERM argv[]) { ERL_NIF_TERM ret; enacl_secretstream_ctx *obj = NULL; @@ -278,9 +274,9 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_rekey( goto bad_arg; } - if(!enif_get_resource(env, argv[0], - (ErlNifResourceType *) enacl_secretstream_ctx_rtype, - (void **)&obj)) { + if (!enif_get_resource(env, argv[0], + (ErlNifResourceType *)enacl_secretstream_ctx_rtype, + (void **)&obj)) { goto bad_arg; } @@ -312,10 +308,9 @@ crypto_secretstream_xchacha20poly1305_push const unsigned char *m, unsigned long long mlen, const unsigned char *ad, unsigned long long adlen, unsigned char tag) */ -ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_push( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[] - ) { +ERL_NIF_TERM +enacl_crypto_secretstream_xchacha20poly1305_push(ErlNifEnv *env, int argc, + const ERL_NIF_TERM argv[]) { ERL_NIF_TERM ret; ErlNifBinary m, ad, out; ErlNifUInt64 tag; @@ -325,25 +320,26 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_push( goto bad_arg; } - if(!enif_get_resource(env, argv[0], - (ErlNifResourceType *) enacl_secretstream_ctx_rtype, - (void **)&obj)) { + if (!enif_get_resource(env, argv[0], + (ErlNifResourceType *)enacl_secretstream_ctx_rtype, + (void **)&obj)) { goto bad_arg; } - if(!enif_inspect_binary(env, argv[1], &m)) { + if (!enif_inspect_binary(env, argv[1], &m)) { goto bad_arg; } - if(!enif_inspect_binary(env, argv[2], &ad)) { + if (!enif_inspect_binary(env, argv[2], &ad)) { goto bad_arg; } - if(!enif_get_uint64(env, argv[3], &tag)) { + if (!enif_get_uint64(env, argv[3], &tag)) { goto bad_arg; } - if (!enif_alloc_binary(m.size + crypto_secretstream_xchacha20poly1305_ABYTES, &out)) { + if (!enif_alloc_binary(m.size + crypto_secretstream_xchacha20poly1305_ABYTES, + &out)) { return enacl_internal_error(env); } @@ -352,12 +348,14 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_push( goto err; } - crypto_secretstream_xchacha20poly1305_push(obj->state, out.data, NULL, m.data, m.size, ad.data, ad.size, tag); + crypto_secretstream_xchacha20poly1305_push(obj->state, out.data, NULL, m.data, + m.size, ad.data, ad.size, tag); if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL) { - if(obj->state) { + if (obj->state) { obj->alive = 0; - sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes()); + sodium_memzero(obj->state, + crypto_secretstream_xchacha20poly1305_statebytes()); enif_free(obj->state); obj->state = NULL; } @@ -384,10 +382,9 @@ done: const unsigned char *in, unsigned long long inlen, const unsigned char *ad, unsigned long long adlen) */ -ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_pull( - ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[] - ) { +ERL_NIF_TERM +enacl_crypto_secretstream_xchacha20poly1305_pull(ErlNifEnv *env, int argc, + const ERL_NIF_TERM argv[]) { ERL_NIF_TERM ret; ErlNifBinary m, in, ad; unsigned char tag; @@ -397,55 +394,57 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_pull( goto bad_arg; } - if(!enif_get_resource(env, argv[0], - (ErlNifResourceType *) enacl_secretstream_ctx_rtype, - (void **)&obj)) { + if (!enif_get_resource(env, argv[0], + (ErlNifResourceType *)enacl_secretstream_ctx_rtype, + (void **)&obj)) { goto bad_arg; } - if(!enif_inspect_binary(env, argv[1], &in)) { + if (!enif_inspect_binary(env, argv[1], &in)) { goto bad_arg; } - if(in.size < crypto_secretstream_xchacha20poly1305_ABYTES) { + if (in.size < crypto_secretstream_xchacha20poly1305_ABYTES) { goto bad_arg; } - if(!enif_inspect_binary(env, argv[2], &ad)) { + if (!enif_inspect_binary(env, argv[2], &ad)) { goto bad_arg; } - if(in.size < crypto_secretstream_xchacha20poly1305_ABYTES) { + if (in.size < crypto_secretstream_xchacha20poly1305_ABYTES) { goto bad_arg; } - if (!enif_alloc_binary(in.size - crypto_secretstream_xchacha20poly1305_ABYTES, &m)) { + if (!enif_alloc_binary(in.size - crypto_secretstream_xchacha20poly1305_ABYTES, + &m)) { return enacl_internal_error(env); } enif_mutex_lock(obj->mtx); - if(!obj->alive) { + if (!obj->alive) { goto err; } - if (0 != crypto_secretstream_xchacha20poly1305_pull(obj->state, m.data, NULL, &tag, in.data, in.size, ad.data, ad.size)) { + if (0 != crypto_secretstream_xchacha20poly1305_pull(obj->state, m.data, NULL, + &tag, in.data, in.size, + ad.data, ad.size)) { ret = enacl_error_tuple(env, "failed_verification"); goto release; } if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL) { - if(obj->state) { + if (obj->state) { obj->alive = 0; - sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes()); + sodium_memzero(obj->state, + crypto_secretstream_xchacha20poly1305_statebytes()); enif_free(obj->state); obj->state = NULL; } } - ret = enif_make_tuple2(env, - enif_make_binary(env, &m), - enif_make_int64(env, tag) - ); + ret = enif_make_tuple2(env, enif_make_binary(env, &m), + enif_make_int64(env, tag)); goto done;