Split off AEAD functions to a separate file
This commit is contained in:
parent
0047af286f
commit
3ee5a94caf
@ -30,10 +30,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||||||
following the style of the Erlang/OTP `crypto` library. While here, make sure
|
following the style of the Erlang/OTP `crypto` library. While here, make sure
|
||||||
we clean up correctly and that we don't accidentally mis-ref-count data. The
|
we clean up correctly and that we don't accidentally mis-ref-count data. The
|
||||||
code is a bit more goto heavy, but this style is surprisingly common in C code.
|
code is a bit more goto heavy, but this style is surprisingly common in C code.
|
||||||
|
- Use sodium's dynamic memory allocators. These guarantee 64bit alignment, and also
|
||||||
|
provide guard pages around the allocation, somewhat protecting it. It adds some
|
||||||
|
page table pressure compared to the current code, but is easier to maintain and
|
||||||
|
much cleaner code.
|
||||||
- The code now rejects updates to generichash states which were already finalized.
|
- The code now rejects updates to generichash states which were already finalized.
|
||||||
- We now track the desired outlen of a generichash operation in the opaque NIF
|
- We now track the desired outlen of a generichash operation in the opaque NIF
|
||||||
resource rather than on the Erlang side. This avoids some checks in the code,
|
resource rather than on the Erlang side. This avoids some checks in the code,
|
||||||
and streamlines a good deal of the interface.
|
and streamlines a good deal of the interface.
|
||||||
|
- Split AEAD routines off from the main enacl_nif.c file
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Fix a resource leak in generichash/sign init/update/final.
|
- Fix a resource leak in generichash/sign init/update/final.
|
||||||
|
195
c_src/aead.c
Normal file
195
c_src/aead.c
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#include "aead.h"
|
||||||
|
#include "enacl.h"
|
||||||
|
#include "erl_nif.h"
|
||||||
|
|
||||||
|
#include <sodium.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AEAD ChaCha20 Poly1305
|
||||||
|
*/
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_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
|
||||||
|
enif_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
|
||||||
|
enif_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
|
||||||
|
enif_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
|
||||||
|
enif_crypto_aead_chacha20poly1305_encrypt(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]) {
|
||||||
|
ERL_NIF_TERM result;
|
||||||
|
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_chacha20poly1305_ietf_KEYBYTES) ||
|
||||||
|
(nonce.size != crypto_aead_chacha20poly1305_ietf_NPUBBYTES)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!enif_alloc_binary(message.size +
|
||||||
|
crypto_aead_chacha20poly1305_ietf_ABYTES,
|
||||||
|
&ciphertext)) {
|
||||||
|
result = nacl_error_tuple(env, "alloc_failed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crypto_aead_chacha20poly1305_ietf_encrypt(
|
||||||
|
ciphertext.data, NULL, message.data, message.size, ad.data, ad.size,
|
||||||
|
NULL, nonce.data, key.data) < 0) {
|
||||||
|
result =
|
||||||
|
nacl_error_tuple(env, "aead_chacha20poly1305_ietf_encrypt_failed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = enif_make_binary(env, &ciphertext);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_chacha20poly1305_decrypt(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]) {
|
||||||
|
ERL_NIF_TERM result;
|
||||||
|
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_chacha20poly1305_ietf_ABYTES) ||
|
||||||
|
(key.size != crypto_aead_chacha20poly1305_ietf_KEYBYTES) ||
|
||||||
|
(nonce.size != crypto_aead_chacha20poly1305_ietf_NPUBBYTES)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!enif_alloc_binary(ciphertext.size -
|
||||||
|
crypto_aead_chacha20poly1305_ietf_ABYTES,
|
||||||
|
&message)) {
|
||||||
|
result = nacl_error_tuple(env, "alloc_failed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crypto_aead_chacha20poly1305_ietf_decrypt(
|
||||||
|
message.data, NULL, NULL, ciphertext.data, ciphertext.size, ad.data,
|
||||||
|
ad.size, nonce.data, key.data) < 0) {
|
||||||
|
result =
|
||||||
|
nacl_error_tuple(env, "aead_chacha20poly1305_ietf_decrypt_failed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = enif_make_binary(env, &message);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AEAD XChaCha20 Poly1305
|
||||||
|
*/
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_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
|
||||||
|
enif_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
|
||||||
|
enif_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
|
||||||
|
enif_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
|
||||||
|
enif_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 nacl_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 nacl_error_tuple(env, "aead_xchacha20poly1305_ietf_encrypt_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return enif_make_binary(env, &ciphertext);
|
||||||
|
}
|
||||||
|
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_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 nacl_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 nacl_error_tuple(env, "aead_xchacha20poly1305_ietf_decrypt_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return enif_make_binary(env, &message);
|
||||||
|
}
|
46
c_src/aead.h
Normal file
46
c_src/aead.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef ENACL_AEAD_H
|
||||||
|
#define ENACL_AEAD_H
|
||||||
|
|
||||||
|
#include "erl_nif.h"
|
||||||
|
|
||||||
|
/* AEAD ChaCha20 Poly1305 */
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_chacha20poly1305_KEYBYTES(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_chacha20poly1305_NPUBBYTES(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_chacha20poly1305_ABYTES(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_chacha20poly1305_encrypt(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_chacha20poly1305_decrypt(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
|
||||||
|
/* AEAD XChaCha20 Poly1305 */
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_xchacha20poly1305_KEYBYTES(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_xchacha20poly1305_NPUBBYTES(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_xchacha20poly1305_ABYTES(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_xchacha20poly1305_MESSAGEBYTES_MAX(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_xchacha20poly1305_encrypt(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
ERL_NIF_TERM
|
||||||
|
enif_crypto_aead_xchacha20poly1305_decrypt(ErlNifEnv *env, int argc,
|
||||||
|
ERL_NIF_TERM const argv[]);
|
||||||
|
|
||||||
|
#endif
|
@ -3,6 +3,7 @@
|
|||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "aead.h"
|
||||||
#include "enacl.h"
|
#include "enacl.h"
|
||||||
#include "generichash.h"
|
#include "generichash.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
@ -1544,196 +1545,6 @@ static ERL_NIF_TERM enif_crypto_pwhash_str_verify(ErlNifEnv *env, int argc,
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* AEAD ChaCha20 Poly1305
|
|
||||||
*/
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_crypto_aead_chacha20poly1305_KEYBYTES(ErlNifEnv *env, int argc,
|
|
||||||
ERL_NIF_TERM const argv[]) {
|
|
||||||
return enif_make_int64(env, crypto_aead_chacha20poly1305_ietf_KEYBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_crypto_aead_chacha20poly1305_NPUBBYTES(ErlNifEnv *env, int argc,
|
|
||||||
ERL_NIF_TERM const argv[]) {
|
|
||||||
return enif_make_int64(env, crypto_aead_chacha20poly1305_ietf_NPUBBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_crypto_aead_chacha20poly1305_ABYTES(ErlNifEnv *env, int argc,
|
|
||||||
ERL_NIF_TERM const argv[]) {
|
|
||||||
return enif_make_int64(env, crypto_aead_chacha20poly1305_ietf_ABYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_crypto_aead_chacha20poly1305_encrypt(ErlNifEnv *env, int argc,
|
|
||||||
ERL_NIF_TERM const argv[]) {
|
|
||||||
ERL_NIF_TERM result;
|
|
||||||
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_chacha20poly1305_ietf_KEYBYTES) ||
|
|
||||||
(nonce.size != crypto_aead_chacha20poly1305_ietf_NPUBBYTES)) {
|
|
||||||
return enif_make_badarg(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!enif_alloc_binary(message.size +
|
|
||||||
crypto_aead_chacha20poly1305_ietf_ABYTES,
|
|
||||||
&ciphertext)) {
|
|
||||||
result = nacl_error_tuple(env, "alloc_failed");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crypto_aead_chacha20poly1305_ietf_encrypt(
|
|
||||||
ciphertext.data, NULL, message.data, message.size, ad.data, ad.size,
|
|
||||||
NULL, nonce.data, key.data) < 0) {
|
|
||||||
result =
|
|
||||||
nacl_error_tuple(env, "aead_chacha20poly1305_ietf_encrypt_failed");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = enif_make_binary(env, &ciphertext);
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_crypto_aead_chacha20poly1305_decrypt(ErlNifEnv *env, int argc,
|
|
||||||
ERL_NIF_TERM const argv[]) {
|
|
||||||
ERL_NIF_TERM result;
|
|
||||||
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_chacha20poly1305_ietf_ABYTES) ||
|
|
||||||
(key.size != crypto_aead_chacha20poly1305_ietf_KEYBYTES) ||
|
|
||||||
(nonce.size != crypto_aead_chacha20poly1305_ietf_NPUBBYTES)) {
|
|
||||||
return enif_make_badarg(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!enif_alloc_binary(ciphertext.size -
|
|
||||||
crypto_aead_chacha20poly1305_ietf_ABYTES,
|
|
||||||
&message)) {
|
|
||||||
result = nacl_error_tuple(env, "alloc_failed");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(
|
|
||||||
message.data, NULL, NULL, ciphertext.data, ciphertext.size, ad.data,
|
|
||||||
ad.size, nonce.data, key.data) < 0) {
|
|
||||||
result =
|
|
||||||
nacl_error_tuple(env, "aead_chacha20poly1305_ietf_decrypt_failed");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = enif_make_binary(env, &message);
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AEAD XChaCha20 Poly1305
|
|
||||||
*/
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_crypto_aead_xchacha20poly1305_KEYBYTES(ErlNifEnv *env, int argc,
|
|
||||||
ERL_NIF_TERM const argv[]) {
|
|
||||||
return enif_make_int64(env, crypto_aead_xchacha20poly1305_ietf_KEYBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_crypto_aead_xchacha20poly1305_NPUBBYTES(ErlNifEnv *env, int argc,
|
|
||||||
ERL_NIF_TERM const argv[]) {
|
|
||||||
return enif_make_int64(env, crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_crypto_aead_xchacha20poly1305_ABYTES(ErlNifEnv *env, int argc,
|
|
||||||
ERL_NIF_TERM const argv[]) {
|
|
||||||
return enif_make_int64(env, crypto_aead_xchacha20poly1305_ietf_ABYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_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 nacl_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 nacl_error_tuple(env, "aead_xchacha20poly1305_ietf_encrypt_failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
return enif_make_binary(env, &ciphertext);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
enif_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 nacl_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 nacl_error_tuple(env, "aead_xchacha20poly1305_ietf_decrypt_failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
return enif_make_binary(env, &message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tie the knot to the Erlang world */
|
/* Tie the knot to the Erlang world */
|
||||||
static ErlNifFunc nif_funcs[] = {
|
static ErlNifFunc nif_funcs[] = {
|
||||||
{"crypto_box_NONCEBYTES", 0, enif_crypto_box_NONCEBYTES},
|
{"crypto_box_NONCEBYTES", 0, enif_crypto_box_NONCEBYTES},
|
||||||
|
@ -79,7 +79,7 @@ generichash_chunked(_Config) ->
|
|||||||
{ok, Expected} = enacl:generichash_final(State),
|
{ok, Expected} = enacl:generichash_final(State),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
generichash_chunked(State, Msg, 0) -> State;
|
generichash_chunked(State, _Msg, 0) -> State;
|
||||||
generichash_chunked(State, Msg, N) ->
|
generichash_chunked(State, Msg, N) ->
|
||||||
State2 = enacl:generichash_update(State, Msg),
|
State2 = enacl:generichash_update(State, Msg),
|
||||||
generichash_chunked(State2, Msg, N-1).
|
generichash_chunked(State2, Msg, N-1).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user