Clean up aead construction, plug mem-leak

This commit is contained in:
Jesper Louis Andersen 2020-01-21 13:39:08 +01:00
parent 899fbeefd3
commit fec24995d1

View File

@ -36,76 +36,95 @@ enacl_crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX(ErlNifEnv *env, int argc,
ERL_NIF_TERM ERL_NIF_TERM
enacl_crypto_aead_chacha20poly1305_encrypt(ErlNifEnv *env, int argc, enacl_crypto_aead_chacha20poly1305_encrypt(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) { ERL_NIF_TERM const argv[]) {
ERL_NIF_TERM result; ERL_NIF_TERM ret;
ErlNifBinary key, nonce, ad, message, ciphertext; ErlNifBinary key, nonce, ad, message, ciphertext;
if ((argc != 4) || (!enif_inspect_binary(env, argv[0], &key)) || if (argc != 4)
(!enif_inspect_binary(env, argv[1], &nonce)) || goto bad_arg;
(!enif_inspect_binary(env, argv[2], &ad)) || if (!enif_inspect_binary(env, argv[0], &key))
(!enif_inspect_binary(env, argv[3], &message)) || goto bad_arg;
(key.size != crypto_aead_chacha20poly1305_ietf_KEYBYTES) || if (!enif_inspect_binary(env, argv[1], &nonce))
(nonce.size != crypto_aead_chacha20poly1305_ietf_NPUBBYTES)) { goto bad_arg;
return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[2], &ad))
goto bad_arg;
if (!enif_inspect_binary(env, argv[3], &message))
goto bad_arg;
if (key.size != crypto_aead_chacha20poly1305_ietf_KEYBYTES)
goto bad_arg;
if (nonce.size != crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
goto bad_arg;
if (!enif_alloc_binary(message.size +
crypto_aead_chacha20poly1305_ietf_ABYTES,
&ciphertext)) {
ret = nacl_error_tuple(env, "alloc_failed");
goto done;
} }
do { if (crypto_aead_chacha20poly1305_ietf_encrypt(
if (!enif_alloc_binary(message.size + ciphertext.data, NULL, message.data, message.size, ad.data, ad.size,
crypto_aead_chacha20poly1305_ietf_ABYTES, NULL, nonce.data, key.data) < 0) {
&ciphertext)) { ret = nacl_error_tuple(env, "aead_chacha20poly1305_ietf_encrypt_failed");
result = nacl_error_tuple(env, "alloc_failed"); goto release;
continue; }
}
if (crypto_aead_chacha20poly1305_ietf_encrypt( ret = enif_make_binary(env, &ciphertext);
ciphertext.data, NULL, message.data, message.size, ad.data, ad.size, goto done;
NULL, nonce.data, key.data) < 0) {
result =
nacl_error_tuple(env, "aead_chacha20poly1305_ietf_encrypt_failed");
continue;
}
result = enif_make_binary(env, &ciphertext); bad_arg:
} while (0); return enif_make_badarg(env);
release:
return result; enif_release_binary(&ciphertext);
done:
return ret;
} }
ERL_NIF_TERM ERL_NIF_TERM
enacl_crypto_aead_chacha20poly1305_decrypt(ErlNifEnv *env, int argc, enacl_crypto_aead_chacha20poly1305_decrypt(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) { ERL_NIF_TERM const argv[]) {
ERL_NIF_TERM result; ERL_NIF_TERM ret;
ErlNifBinary key, nonce, ad, message, ciphertext; ErlNifBinary key, nonce, ad, message, ciphertext;
if ((argc != 4) || (!enif_inspect_binary(env, argv[0], &key)) || if (argc != 4)
(!enif_inspect_binary(env, argv[1], &nonce)) || goto bad_arg;
(!enif_inspect_binary(env, argv[2], &ad)) || if (!enif_inspect_binary(env, argv[0], &key))
(!enif_inspect_binary(env, argv[3], &ciphertext)) || goto bad_arg;
(ciphertext.size < crypto_aead_chacha20poly1305_ietf_ABYTES) || if (!enif_inspect_binary(env, argv[1], &nonce))
(key.size != crypto_aead_chacha20poly1305_ietf_KEYBYTES) || goto bad_arg;
(nonce.size != crypto_aead_chacha20poly1305_ietf_NPUBBYTES)) { if (!enif_inspect_binary(env, argv[2], &ad))
return enif_make_badarg(env); goto bad_arg;
if (!enif_inspect_binary(env, argv[3], &ciphertext))
goto bad_arg;
if (ciphertext.size < crypto_aead_chacha20poly1305_ietf_ABYTES)
goto bad_arg;
if (key.size != crypto_aead_chacha20poly1305_ietf_KEYBYTES)
goto bad_arg;
if (nonce.size != crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
goto bad_arg;
if (!enif_alloc_binary(ciphertext.size -
crypto_aead_chacha20poly1305_ietf_ABYTES,
&message)) {
ret = nacl_error_tuple(env, "alloc_failed");
goto done;
} }
do { if (crypto_aead_chacha20poly1305_ietf_decrypt(
if (!enif_alloc_binary(ciphertext.size - message.data, NULL, NULL, ciphertext.data, ciphertext.size, ad.data,
crypto_aead_chacha20poly1305_ietf_ABYTES, ad.size, nonce.data, key.data) < 0) {
&message)) { ret = nacl_error_tuple(env, "aead_chacha20poly1305_ietf_decrypt_failed");
result = nacl_error_tuple(env, "alloc_failed"); goto release;
continue; }
}
if (crypto_aead_chacha20poly1305_ietf_decrypt( ret = enif_make_binary(env, &message);
message.data, NULL, NULL, ciphertext.data, ciphertext.size, ad.data, goto done;
ad.size, nonce.data, key.data) < 0) { bad_arg:
result = return enif_make_badarg(env);
nacl_error_tuple(env, "aead_chacha20poly1305_ietf_decrypt_failed"); release:
continue; enif_release_binary(&message);
} done:
return ret;
result = enif_make_binary(env, &message);
} while (0);
return result;
} }
/* /*