enacl/c_src/aead.c
Jesper Louis Andersen e67619a403 Update the naming scheme of AEAD xchacha20...
Since this AEAD construction variant is an IETF variant, reflect
this in the names of the functions.

This streamlines the API with the libsodium API.
2020-01-22 19:41:58 +01:00

253 lines
7.6 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_ietf_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_ietf_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_ietf_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_ietf_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_ietf_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_ietf_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_ietf_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_ietf_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_ietf_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_ietf_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_ietf_encrypt(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ErlNifBinary key, nonce, ad, message, ciphertext;
ERL_NIF_TERM ret;
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_xchacha20poly1305_ietf_KEYBYTES)
goto bad_arg;
if (nonce.size != crypto_aead_xchacha20poly1305_ietf_NPUBBYTES)
goto bad_arg;
if (!enif_alloc_binary(message.size +
crypto_aead_xchacha20poly1305_ietf_ABYTES,
&ciphertext)) {
ret = enacl_error_tuple(env, "alloc_failed");
goto done;
}
if (crypto_aead_xchacha20poly1305_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_xchacha20poly1305_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_xchacha20poly1305_ietf_decrypt(ErlNifEnv *env, int argc,
ERL_NIF_TERM const argv[]) {
ErlNifBinary key, nonce, ad, message, ciphertext;
ERL_NIF_TERM ret;
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], &key))
goto bad_arg;
if (ciphertext.size < crypto_aead_xchacha20poly1305_ietf_ABYTES)
goto bad_arg;
if (key.size != crypto_aead_xchacha20poly1305_ietf_KEYBYTES)
goto bad_arg;
if (nonce.size != crypto_aead_xchacha20poly1305_ietf_NPUBBYTES)
goto bad_arg;
if (!enif_alloc_binary(ciphertext.size -
crypto_aead_xchacha20poly1305_ietf_ABYTES,
&message)) {
ret = enacl_error_tuple(env, "alloc_failed");
goto done;
}
if (crypto_aead_xchacha20poly1305_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_xchacha20poly1305_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;
}