Merge pull request #21 from aeternity/add_aead_chacha20poly1305

Add AEAD chacha20poly1305
This commit is contained in:
Jesper Louis Andersen
2018-05-20 19:38:14 +02:00
committed by GitHub
4 changed files with 236 additions and 2 deletions
+128
View File
@@ -153,6 +153,34 @@ ERL_NIF_TERM enif_crypto_curve25519_scalarmult(ErlNifEnv *env, int argc, ERL_NIF
return result;
}
static
ERL_NIF_TERM enif_crypto_curve25519_scalarmult_base(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
ERL_NIF_TERM result;
ErlNifBinary secret, output;
if ((argc != 1) || (!enif_inspect_binary(env, argv[0], &secret))
|| (secret.size != crypto_scalarmult_curve25519_BYTES)) {
return enif_make_badarg(env);
}
do
{
if (!enif_alloc_binary(crypto_scalarmult_curve25519_BYTES, &output)) {
result = nacl_error_tuple(env, "alloc_failed");
continue;
}
if (crypto_scalarmult_curve25519_base(output.data, secret.data) < 0) {
result = nacl_error_tuple(env, "scalarmult_curve25519_base_failed");
continue;
}
result = enif_make_binary(env, &output);
} while (0);
return result;
}
/* Ed 25519 */
static
ERL_NIF_TERM enif_crypto_sign_ed25519_keypair(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
@@ -1313,6 +1341,98 @@ ERL_NIF_TERM enif_crypto_pwhash_str_verify(ErlNifEnv *env, int argc, ERL_NIF_TER
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;
}
/*
* Generic hash
*/
@@ -1606,6 +1726,7 @@ static ErlNifFunc nif_funcs[] = {
{"crypto_pwhash_str_verify", 2, enif_crypto_pwhash_str_verify},
erl_nif_dirty_job_cpu_bound_macro("crypto_curve25519_scalarmult", 2, enif_crypto_curve25519_scalarmult),
erl_nif_dirty_job_cpu_bound_macro("crypto_curve25519_scalarmult_base", 1, enif_crypto_curve25519_scalarmult_base),
erl_nif_dirty_job_cpu_bound_macro("crypto_sign_ed25519_keypair", 0, enif_crypto_sign_ed25519_keypair),
{"crypto_sign_ed25519_public_to_curve25519", 1, enif_crypto_sign_ed25519_public_to_curve25519},
@@ -1624,6 +1745,13 @@ static ErlNifFunc nif_funcs[] = {
{"scramble_block_16", 2, enif_scramble_block_16},
{"crypto_aead_chacha20poly1305_KEYBYTES", 0, enif_crypto_aead_chacha20poly1305_KEYBYTES},
{"crypto_aead_chacha20poly1305_NPUBBYTES", 0, enif_crypto_aead_chacha20poly1305_NPUBBYTES},
{"crypto_aead_chacha20poly1305_ABYTES", 0, enif_crypto_aead_chacha20poly1305_ABYTES},
{"crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX", 0, enif_crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX},
erl_nif_dirty_job_cpu_bound_macro("crypto_aead_chacha20poly1305_encrypt", 4, enif_crypto_aead_chacha20poly1305_encrypt),
erl_nif_dirty_job_cpu_bound_macro("crypto_aead_chacha20poly1305_decrypt", 4, enif_crypto_aead_chacha20poly1305_decrypt),
{"crypto_generichash_BYTES", 0, enif_crypto_generichash_BYTES},
{"crypto_generichash_BYTES_MIN", 0, enif_crypto_generichash_BYTES_MIN},
{"crypto_generichash_BYTES_MAX", 0, enif_crypto_generichash_BYTES_MAX},