
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.
216 lines
7.0 KiB
C
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);
|
|
}
|