Format; release resources
In the push path, release resources in a stack fashion. This avoids releasing a binary incorrectly.
This commit is contained in:
parent
67fe9c7863
commit
8361450745
@ -1,12 +1,13 @@
|
|||||||
#include <sodium.h>
|
|
||||||
#include <erl_nif.h>
|
#include <erl_nif.h>
|
||||||
|
#include <sodium.h>
|
||||||
|
|
||||||
#include "enacl.h"
|
#include "enacl.h"
|
||||||
#include "secretstream.h"
|
#include "secretstream.h"
|
||||||
|
|
||||||
typedef struct enacl_secretstream_ctx {
|
typedef struct enacl_secretstream_ctx {
|
||||||
ErlNifMutex *mtx;
|
ErlNifMutex *mtx;
|
||||||
crypto_secretstream_xchacha20poly1305_state *state; // The underlying secretstream state
|
crypto_secretstream_xchacha20poly1305_state
|
||||||
|
*state; // The underlying secretstream state
|
||||||
int alive; // Is the context still valid for updates/finalization
|
int alive; // Is the context still valid for updates/finalization
|
||||||
} enacl_secretstream_ctx;
|
} enacl_secretstream_ctx;
|
||||||
|
|
||||||
@ -34,7 +35,8 @@ static void enacl_secretstream_ctx_dtor(ErlNifEnv *env,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (obj->state)
|
if (obj->state)
|
||||||
sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes());
|
sodium_memzero(obj->state,
|
||||||
|
crypto_secretstream_xchacha20poly1305_statebytes());
|
||||||
enif_free(obj->state);
|
enif_free(obj->state);
|
||||||
|
|
||||||
if (obj->mtx != NULL)
|
if (obj->mtx != NULL)
|
||||||
@ -47,61 +49,56 @@ static void enacl_secretstream_ctx_dtor(ErlNifEnv *env,
|
|||||||
* Secretstream
|
* Secretstream
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_ABYTES(
|
ERL_NIF_TERM
|
||||||
ErlNifEnv *env, int argc,
|
enacl_crypto_secretstream_xchacha20poly1305_ABYTES(ErlNifEnv *env, int argc,
|
||||||
const ERL_NIF_TERM argv[]) {
|
const ERL_NIF_TERM argv[]) {
|
||||||
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_ABYTES);
|
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_ABYTES);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_HEADERBYTES(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_HEADERBYTES(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
const ERL_NIF_TERM argv[]) {
|
return enif_make_int64(env,
|
||||||
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_HEADERBYTES);
|
crypto_secretstream_xchacha20poly1305_HEADERBYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_KEYBYTES(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_KEYBYTES(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
const ERL_NIF_TERM argv[]) {
|
|
||||||
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_KEYBYTES);
|
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_KEYBYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
const ERL_NIF_TERM argv[]) {
|
return enif_make_int64(
|
||||||
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX);
|
env, crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_MESSAGE(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_MESSAGE(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
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(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_PUSH(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
const ERL_NIF_TERM argv[]) {
|
|
||||||
|
|
||||||
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_PUSH);
|
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_PUSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_REKEY(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_REKEY(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
const ERL_NIF_TERM argv[]) {
|
|
||||||
|
|
||||||
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_REKEY);
|
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_REKEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_FINAL(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_TAG_FINAL(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
const ERL_NIF_TERM argv[]) {
|
|
||||||
|
|
||||||
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_FINAL);
|
return enif_make_int64(env, crypto_secretstream_xchacha20poly1305_TAG_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_keygen(
|
ERL_NIF_TERM
|
||||||
ErlNifEnv *env, int argc,
|
enacl_crypto_secretstream_xchacha20poly1305_keygen(ErlNifEnv *env, int argc,
|
||||||
const ERL_NIF_TERM argv[]) {
|
const ERL_NIF_TERM argv[]) {
|
||||||
|
|
||||||
ErlNifBinary key;
|
ErlNifBinary key;
|
||||||
@ -110,7 +107,8 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_keygen(
|
|||||||
return enif_make_badarg(env);
|
return enif_make_badarg(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enif_alloc_binary(crypto_secretstream_xchacha20poly1305_KEYBYTES, &key)) {
|
if (!enif_alloc_binary(crypto_secretstream_xchacha20poly1305_KEYBYTES,
|
||||||
|
&key)) {
|
||||||
return enacl_internal_error(env);
|
return enacl_internal_error(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,9 +124,7 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_keygen(
|
|||||||
const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES])
|
const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES])
|
||||||
*/
|
*/
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_push(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_push(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
const ERL_NIF_TERM argv[]
|
|
||||||
) {
|
|
||||||
ERL_NIF_TERM ret;
|
ERL_NIF_TERM ret;
|
||||||
ErlNifBinary key, header;
|
ErlNifBinary key, header;
|
||||||
enacl_secretstream_ctx *obj = NULL;
|
enacl_secretstream_ctx *obj = NULL;
|
||||||
@ -141,7 +137,8 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_push(
|
|||||||
goto bad_arg;
|
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);
|
ret = enacl_internal_error(env);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -155,37 +152,38 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_push(
|
|||||||
obj->state = enif_alloc(crypto_secretstream_xchacha20poly1305_statebytes());
|
obj->state = enif_alloc(crypto_secretstream_xchacha20poly1305_statebytes());
|
||||||
|
|
||||||
if (obj->state == NULL) {
|
if (obj->state == NULL) {
|
||||||
|
ret = enacl_internal_error(env);
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
obj->alive = 1;
|
obj->alive = 1;
|
||||||
|
|
||||||
if ((obj->mtx = enif_mutex_create("enacl.secretstream")) == NULL) {
|
if ((obj->mtx = enif_mutex_create("enacl.secretstream")) == NULL) {
|
||||||
|
ret = enacl_internal_error(env);
|
||||||
goto free;
|
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,
|
ret = enif_make_tuple2(env, enif_make_binary(env, &header),
|
||||||
enif_make_binary(env, &header),
|
enif_make_resource(env, obj));
|
||||||
enif_make_resource(env, obj)
|
|
||||||
);
|
|
||||||
|
|
||||||
goto release;
|
goto release;
|
||||||
|
|
||||||
bad_arg:
|
bad_arg:
|
||||||
return enif_make_badarg(env);
|
return enif_make_badarg(env);
|
||||||
free:
|
free:
|
||||||
if (obj->alive)
|
if (obj->alive)
|
||||||
if (obj->state != NULL) {
|
if (obj->state != NULL) {
|
||||||
sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes());
|
sodium_memzero(obj->state,
|
||||||
|
crypto_secretstream_xchacha20poly1305_statebytes());
|
||||||
enif_free(obj->state);
|
enif_free(obj->state);
|
||||||
obj->state = NULL;
|
obj->state = NULL;
|
||||||
}
|
}
|
||||||
|
release_header:
|
||||||
|
enif_release_binary(&header);
|
||||||
release:
|
release:
|
||||||
// This also frees the mutex via the destructor
|
// This also frees the mutex via the destructor
|
||||||
enif_release_resource(obj);
|
enif_release_resource(obj);
|
||||||
release_header:
|
|
||||||
enif_release_binary(&header);
|
|
||||||
done:
|
done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -197,9 +195,7 @@ crypto_secretstream_xchacha20poly1305_init_pull
|
|||||||
const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES])
|
const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES])
|
||||||
*/
|
*/
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_pull(
|
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_pull(
|
||||||
ErlNifEnv *env, int argc,
|
ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
|
||||||
const ERL_NIF_TERM argv[]
|
|
||||||
) {
|
|
||||||
ERL_NIF_TERM ret;
|
ERL_NIF_TERM ret;
|
||||||
ErlNifBinary header, key;
|
ErlNifBinary header, key;
|
||||||
enacl_secretstream_ctx *obj = NULL;
|
enacl_secretstream_ctx *obj = NULL;
|
||||||
@ -217,8 +213,7 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_pull(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((key.size != crypto_secretstream_xchacha20poly1305_KEYBYTES) ||
|
if ((key.size != crypto_secretstream_xchacha20poly1305_KEYBYTES) ||
|
||||||
(header.size != crypto_secretstream_xchacha20poly1305_HEADERBYTES))
|
(header.size != crypto_secretstream_xchacha20poly1305_HEADERBYTES)) {
|
||||||
{
|
|
||||||
goto bad_arg;
|
goto bad_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +235,8 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_init_pull(
|
|||||||
goto free;
|
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);
|
ret = enif_make_resource(env, obj);
|
||||||
|
|
||||||
@ -251,7 +247,8 @@ bad_arg:
|
|||||||
free:
|
free:
|
||||||
if (obj->alive)
|
if (obj->alive)
|
||||||
if (obj->state != NULL) {
|
if (obj->state != NULL) {
|
||||||
sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes());
|
sodium_memzero(obj->state,
|
||||||
|
crypto_secretstream_xchacha20poly1305_statebytes());
|
||||||
enif_free(obj->state);
|
enif_free(obj->state);
|
||||||
obj->state = NULL;
|
obj->state = NULL;
|
||||||
}
|
}
|
||||||
@ -267,10 +264,9 @@ void
|
|||||||
crypto_secretstream_xchacha20poly1305_rekey
|
crypto_secretstream_xchacha20poly1305_rekey
|
||||||
(crypto_secretstream_xchacha20poly1305_state *state)
|
(crypto_secretstream_xchacha20poly1305_state *state)
|
||||||
*/
|
*/
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_rekey(
|
ERL_NIF_TERM
|
||||||
ErlNifEnv *env, int argc,
|
enacl_crypto_secretstream_xchacha20poly1305_rekey(ErlNifEnv *env, int argc,
|
||||||
const ERL_NIF_TERM argv[]
|
const ERL_NIF_TERM argv[]) {
|
||||||
) {
|
|
||||||
ERL_NIF_TERM ret;
|
ERL_NIF_TERM ret;
|
||||||
enacl_secretstream_ctx *obj = NULL;
|
enacl_secretstream_ctx *obj = NULL;
|
||||||
|
|
||||||
@ -312,10 +308,9 @@ crypto_secretstream_xchacha20poly1305_push
|
|||||||
const unsigned char *m, unsigned long long mlen,
|
const unsigned char *m, unsigned long long mlen,
|
||||||
const unsigned char *ad, unsigned long long adlen, unsigned char tag)
|
const unsigned char *ad, unsigned long long adlen, unsigned char tag)
|
||||||
*/
|
*/
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_push(
|
ERL_NIF_TERM
|
||||||
ErlNifEnv *env, int argc,
|
enacl_crypto_secretstream_xchacha20poly1305_push(ErlNifEnv *env, int argc,
|
||||||
const ERL_NIF_TERM argv[]
|
const ERL_NIF_TERM argv[]) {
|
||||||
) {
|
|
||||||
ERL_NIF_TERM ret;
|
ERL_NIF_TERM ret;
|
||||||
ErlNifBinary m, ad, out;
|
ErlNifBinary m, ad, out;
|
||||||
ErlNifUInt64 tag;
|
ErlNifUInt64 tag;
|
||||||
@ -343,7 +338,8 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_push(
|
|||||||
goto bad_arg;
|
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);
|
return enacl_internal_error(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,12 +348,14 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_push(
|
|||||||
goto err;
|
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 (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
|
||||||
if (obj->state) {
|
if (obj->state) {
|
||||||
obj->alive = 0;
|
obj->alive = 0;
|
||||||
sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes());
|
sodium_memzero(obj->state,
|
||||||
|
crypto_secretstream_xchacha20poly1305_statebytes());
|
||||||
enif_free(obj->state);
|
enif_free(obj->state);
|
||||||
obj->state = NULL;
|
obj->state = NULL;
|
||||||
}
|
}
|
||||||
@ -384,10 +382,9 @@ done:
|
|||||||
const unsigned char *in, unsigned long long inlen,
|
const unsigned char *in, unsigned long long inlen,
|
||||||
const unsigned char *ad, unsigned long long adlen)
|
const unsigned char *ad, unsigned long long adlen)
|
||||||
*/
|
*/
|
||||||
ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_pull(
|
ERL_NIF_TERM
|
||||||
ErlNifEnv *env, int argc,
|
enacl_crypto_secretstream_xchacha20poly1305_pull(ErlNifEnv *env, int argc,
|
||||||
const ERL_NIF_TERM argv[]
|
const ERL_NIF_TERM argv[]) {
|
||||||
) {
|
|
||||||
ERL_NIF_TERM ret;
|
ERL_NIF_TERM ret;
|
||||||
ErlNifBinary m, in, ad;
|
ErlNifBinary m, in, ad;
|
||||||
unsigned char tag;
|
unsigned char tag;
|
||||||
@ -419,7 +416,8 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_pull(
|
|||||||
goto bad_arg;
|
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);
|
return enacl_internal_error(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,7 +426,9 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_pull(
|
|||||||
goto err;
|
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");
|
ret = enacl_error_tuple(env, "failed_verification");
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
@ -436,16 +436,15 @@ ERL_NIF_TERM enacl_crypto_secretstream_xchacha20poly1305_pull(
|
|||||||
if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
|
if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
|
||||||
if (obj->state) {
|
if (obj->state) {
|
||||||
obj->alive = 0;
|
obj->alive = 0;
|
||||||
sodium_memzero(obj->state, crypto_secretstream_xchacha20poly1305_statebytes());
|
sodium_memzero(obj->state,
|
||||||
|
crypto_secretstream_xchacha20poly1305_statebytes());
|
||||||
enif_free(obj->state);
|
enif_free(obj->state);
|
||||||
obj->state = NULL;
|
obj->state = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = enif_make_tuple2(env,
|
ret = enif_make_tuple2(env, enif_make_binary(env, &m),
|
||||||
enif_make_binary(env, &m),
|
enif_make_int64(env, tag));
|
||||||
enif_make_int64(env, tag)
|
|
||||||
);
|
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user