261 lines
6.0 KiB
C
261 lines
6.0 KiB
C
#include "saltywitch.h"
|
|
|
|
ERL_NIF_TERM saltywitch_secretbox_keygen(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
ERL_NIF_TERM term;
|
|
|
|
unsigned char *key = enif_make_new_binary(env, crypto_secretbox_KEYBYTES, &term);
|
|
if (key == NULL) {
|
|
return saltywitch_exception(env, atom_error, atom_err_nif_alloc);
|
|
}
|
|
|
|
crypto_secretbox_keygen(key);
|
|
|
|
return term;
|
|
}
|
|
|
|
ERL_NIF_TERM saltywitch_secretbox_easy(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
ErlNifBinary key, nonce, message;
|
|
unsigned char *cipher;
|
|
ERL_NIF_TERM term;
|
|
|
|
ERL_NIF_TERM err = atom_badarg;
|
|
ERL_NIF_TERM reason = atom_err_opaque;
|
|
|
|
if (enif_inspect_binary(env, argv[0], &key) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (key.size != crypto_secretbox_KEYBYTES) {
|
|
reason = atom_err_invalid_key_size;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[1], &nonce) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (nonce.size != crypto_secretbox_NONCEBYTES) {
|
|
reason = atom_err_invalid_nonce_size;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[2], &message) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
cipher = enif_make_new_binary(env, message.size + crypto_secretbox_MACBYTES, &term);
|
|
if (cipher == NULL) {
|
|
reason = atom_err_nif_alloc;
|
|
goto error_FAULT;
|
|
}
|
|
|
|
crypto_secretbox_easy(cipher, message.data, message.size, nonce.data, key.data);
|
|
|
|
return term;
|
|
|
|
error_FAULT:
|
|
err = atom_error;
|
|
badarg_FAULT:
|
|
return saltywitch_exception(env, err, reason);
|
|
}
|
|
|
|
ERL_NIF_TERM saltywitch_secretbox_open_easy(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
ErlNifBinary key, nonce, cipher;
|
|
unsigned char *message;
|
|
ERL_NIF_TERM term;
|
|
|
|
ERL_NIF_TERM err = atom_badarg;
|
|
ERL_NIF_TERM reason = atom_err_opaque;
|
|
|
|
(void) argc;
|
|
|
|
if (enif_inspect_binary(env, argv[0], &key) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (key.size != crypto_secretbox_KEYBYTES) {
|
|
reason = atom_err_invalid_key_size;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[1], &nonce) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (nonce.size != crypto_secretbox_NONCEBYTES) {
|
|
reason = atom_err_invalid_nonce_size;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[2], &cipher) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (cipher.size <= crypto_secretbox_MACBYTES) {
|
|
reason = atom_err_ciphertext_too_small;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
message = enif_make_new_binary(env, cipher.size - crypto_secretbox_MACBYTES, &term);
|
|
if (message == NULL) {
|
|
reason = atom_err_nif_alloc;
|
|
goto error_FAULT;
|
|
}
|
|
|
|
if (crypto_secretbox_open_easy(message, cipher.data, cipher.size, nonce.data, key.data) != 0) {
|
|
reason = atom_err_invalid_type;
|
|
goto error_FAULT;
|
|
}
|
|
|
|
return term;
|
|
|
|
error_FAULT:
|
|
err = atom_error;
|
|
badarg_FAULT:
|
|
return saltywitch_exception(env, err, reason);
|
|
}
|
|
|
|
ERL_NIF_TERM saltywitch_secretbox_detached(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
ERL_NIF_TERM cipher_term, mac_term;
|
|
ErlNifBinary key, message, nonce;
|
|
unsigned char *cipher, *mac;
|
|
|
|
ERL_NIF_TERM err = atom_badarg;
|
|
ERL_NIF_TERM reason = atom_err_opaque;
|
|
|
|
if (enif_inspect_binary(env, argv[0], &key) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (key.size != crypto_secretbox_KEYBYTES) {
|
|
reason = atom_err_invalid_key_size;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[1], &nonce) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (nonce.size != crypto_secretbox_NONCEBYTES) {
|
|
reason = atom_err_invalid_nonce_size;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[2], &message) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto badarg_FAULT;
|
|
}
|
|
|
|
cipher = enif_make_new_binary(env, message.size, &cipher_term);
|
|
if (cipher == NULL) {
|
|
reason = atom_err_nif_alloc;
|
|
goto error_FAULT;
|
|
}
|
|
|
|
mac = enif_make_new_binary(env, crypto_secretbox_MACBYTES, &mac_term);
|
|
if (mac == NULL) {
|
|
reason = atom_err_nif_alloc;
|
|
goto error_FAULT;
|
|
}
|
|
|
|
crypto_secretbox_detached(cipher, mac, message.data, message.size, nonce.data, key.data);
|
|
|
|
return enif_make_tuple2(env, cipher_term, mac_term);
|
|
|
|
error_FAULT:
|
|
err = atom_error;
|
|
badarg_FAULT:
|
|
return saltywitch_exception(env, err, reason);
|
|
}
|
|
|
|
ERL_NIF_TERM saltywitch_secretbox_open_detached(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
ErlNifBinary key, nonce, cipher, mac;
|
|
unsigned char *message;
|
|
ERL_NIF_TERM term;
|
|
|
|
ERL_NIF_TERM err = atom_badarg;
|
|
ERL_NIF_TERM reason = atom_err_opaque;
|
|
|
|
if (enif_inspect_binary(env, argv[0], &key) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto FAULT;
|
|
}
|
|
|
|
if (key.size != crypto_secretbox_KEYBYTES) {
|
|
goto FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[1], &nonce) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto FAULT;
|
|
}
|
|
|
|
if (nonce.size != crypto_secretbox_NONCEBYTES) {
|
|
goto FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[2], &cipher) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto FAULT;
|
|
}
|
|
|
|
if (enif_inspect_binary(env, argv[3], &mac) == false) {
|
|
reason = atom_err_invalid_type;
|
|
goto FAULT;
|
|
}
|
|
|
|
if (mac.size != crypto_secretbox_MACBYTES) {
|
|
goto FAULT;
|
|
}
|
|
|
|
message = enif_make_new_binary(env, cipher.size, &term);
|
|
|
|
if (crypto_secretbox_open_detached(message, cipher.data, mac.data, cipher.size, nonce.data, key.data) != 0) {
|
|
err = atom_error;
|
|
goto FAULT;
|
|
}
|
|
|
|
return term;
|
|
|
|
FAULT:
|
|
term = saltywitch_exception(env, err, reason);
|
|
return term;
|
|
}
|
|
|
|
ERL_NIF_TERM saltywitch_secretbox_keybytes(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
(void) argc;
|
|
(void) argv;
|
|
|
|
return enif_make_uint(env, crypto_secretbox_KEYBYTES);
|
|
}
|
|
|
|
ERL_NIF_TERM saltywitch_secretbox_macbytes(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
(void) argc;
|
|
(void) argv;
|
|
|
|
return enif_make_uint(env, crypto_secretbox_MACBYTES);
|
|
}
|
|
|
|
ERL_NIF_TERM saltywitch_secretbox_noncebytes(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
{
|
|
(void) argc;
|
|
(void) argv;
|
|
|
|
return enif_make_uint(env, crypto_secretbox_NONCEBYTES);
|
|
}
|