
Since the chacha20poly1305 constructions were the IETF variants, we renamed those so they follow the official library better. While here, we also fixed the argument order of the files.
216 lines
7.1 KiB
C
216 lines
7.1 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_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);
|
|
}
|