enacl/c_src/aead.c
Jesper Louis Andersen bdb4719f6d Fix AEAD parameter order / naming.
The order of parameters were in the wrong order. Make them equal
to the official order of libsodium.

While here, rename NONCEBYTES to NPUBBYTES so it reflects the
underlying names as well.
2020-01-21 13:57:39 +01:00

216 lines
7.0 KiB
C

#include <sodium.h>
#include <erl_nif.h>
#include "aead.h"
#include "enacl.h"
/*
* AEAD ChaCha20 Poly1305
*/
ERL_NIF_TERM
enacl_crypto_aead_chacha20poly1305_KEYBYTES(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
return enif_make_int64(env, crypto_aead_chacha20poly1305_ietf_KEYBYTES);
}
ERL_NIF_TERM
enacl_crypto_aead_chacha20poly1305_NPUBBYTES(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
return enif_make_int64(env, crypto_aead_chacha20poly1305_ietf_NPUBBYTES);
}
ERL_NIF_TERM
enacl_crypto_aead_chacha20poly1305_ABYTES(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
return enif_make_int64(env, crypto_aead_chacha20poly1305_ietf_ABYTES);
}
ERL_NIF_TERM
enacl_crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
return enif_make_int64(env,
crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX);
}
ERL_NIF_TERM
enacl_crypto_aead_chacha20poly1305_encrypt(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ERL_NIF_TERM ret;
ErlNifBinary key, nonce, ad, message, ciphertext;
if (argc != 4)
goto bad_arg;
if (!enif_inspect_binary(env, argv[0], &message))
goto bad_arg;
if (!enif_inspect_binary(env, argv[1], &ad))
goto bad_arg;
if (!enif_inspect_binary(env, argv[2], &nonce))
goto bad_arg;
if (!enif_inspect_binary(env, argv[3], &key))
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 = enacl_error_tuple(env, "alloc_failed");
goto done;
}
if (crypto_aead_chacha20poly1305_ietf_encrypt(
ciphertext.data, NULL, message.data, message.size, ad.data, ad.size,
NULL, nonce.data, key.data) < 0) {
ret = enacl_error_tuple(env, "aead_chacha20poly1305_ietf_encrypt_failed");
goto release;
}
ret = enif_make_binary(env, &ciphertext);
goto done;
bad_arg:
return enif_make_badarg(env);
release:
enif_release_binary(&ciphertext);
done:
return ret;
}
ERL_NIF_TERM
enacl_crypto_aead_chacha20poly1305_decrypt(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ERL_NIF_TERM ret;
ErlNifBinary key, nonce, ad, message, ciphertext;
if (argc != 4)
goto bad_arg;
if (!enif_inspect_binary(env, argv[0], &ciphertext))
goto bad_arg;
if (!enif_inspect_binary(env, argv[1], &ad))
goto bad_arg;
if (!enif_inspect_binary(env, argv[2], &nonce))
goto bad_arg;
if (!enif_inspect_binary(env, argv[3], &message))
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 = enacl_error_tuple(env, "alloc_failed");
goto done;
}
if (crypto_aead_chacha20poly1305_ietf_decrypt(
message.data, NULL, NULL, ciphertext.data, ciphertext.size, ad.data,
ad.size, nonce.data, key.data) < 0) {
ret = enacl_error_tuple(env, "aead_chacha20poly1305_ietf_decrypt_failed");
goto release;
}
ret = enif_make_binary(env, &message);
goto done;
bad_arg:
return enif_make_badarg(env);
release:
enif_release_binary(&message);
done:
return ret;
}
/*
* AEAD XChaCha20 Poly1305
*/
ERL_NIF_TERM
enacl_crypto_aead_xchacha20poly1305_KEYBYTES(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
return enif_make_int64(env, crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
}
ERL_NIF_TERM
enacl_crypto_aead_xchacha20poly1305_NPUBBYTES(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
return enif_make_int64(env, crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
}
ERL_NIF_TERM
enacl_crypto_aead_xchacha20poly1305_ABYTES(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
return enif_make_int64(env, crypto_aead_xchacha20poly1305_ietf_ABYTES);
}
ERL_NIF_TERM
enacl_crypto_aead_xchacha20poly1305_MESSAGEBYTES_MAX(
ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
return enif_make_int64(env,
crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX);
}
ERL_NIF_TERM
enacl_crypto_aead_xchacha20poly1305_encrypt(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ErlNifBinary key, nonce, ad, message, ciphertext;
if ((argc != 4) || (!enif_inspect_binary(env, argv[0], &key)) ||
(!enif_inspect_binary(env, argv[1], &nonce)) ||
(!enif_inspect_binary(env, argv[2], &ad)) ||
(!enif_inspect_binary(env, argv[3], &message)) ||
(key.size != crypto_aead_xchacha20poly1305_ietf_KEYBYTES) ||
(nonce.size != crypto_aead_xchacha20poly1305_ietf_NPUBBYTES)) {
return enif_make_badarg(env);
}
if (!enif_alloc_binary(message.size +
crypto_aead_xchacha20poly1305_ietf_ABYTES,
&ciphertext)) {
return enacl_error_tuple(env, "alloc_failed");
}
if (crypto_aead_xchacha20poly1305_ietf_encrypt(
ciphertext.data, NULL, message.data, message.size, ad.data, ad.size,
NULL, nonce.data, key.data) < 0) {
return enacl_error_tuple(env, "aead_xchacha20poly1305_ietf_encrypt_failed");
}
return enif_make_binary(env, &ciphertext);
}
ERL_NIF_TERM
enacl_crypto_aead_xchacha20poly1305_decrypt(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ErlNifBinary key, nonce, ad, message, ciphertext;
if ((argc != 4) || (!enif_inspect_binary(env, argv[0], &key)) ||
(!enif_inspect_binary(env, argv[1], &nonce)) ||
(!enif_inspect_binary(env, argv[2], &ad)) ||
(!enif_inspect_binary(env, argv[3], &ciphertext)) ||
(ciphertext.size < crypto_aead_xchacha20poly1305_ietf_ABYTES) ||
(key.size != crypto_aead_xchacha20poly1305_ietf_KEYBYTES) ||
(nonce.size != crypto_aead_xchacha20poly1305_ietf_NPUBBYTES)) {
return enif_make_badarg(env);
}
if (!enif_alloc_binary(ciphertext.size -
crypto_aead_xchacha20poly1305_ietf_ABYTES,
&message)) {
return enacl_error_tuple(env, "alloc_failed");
}
if (crypto_aead_xchacha20poly1305_ietf_decrypt(
message.data, NULL, NULL, ciphertext.data, ciphertext.size, ad.data,
ad.size, nonce.data, key.data) < 0) {
return enacl_error_tuple(env, "aead_xchacha20poly1305_ietf_decrypt_failed");
}
return enif_make_binary(env, &message);
}