Added generic hash NIF
This commit is contained in:
parent
36eedc6751
commit
ba640b0659
@ -9,6 +9,8 @@
|
|||||||
#define ATOM_TRUE "true"
|
#define ATOM_TRUE "true"
|
||||||
#define ATOM_FALSE "false"
|
#define ATOM_FALSE "false"
|
||||||
|
|
||||||
|
#define CRYPTO_GENERICHASH_STATE_RESOURCE "crypto_generichash_state"
|
||||||
|
|
||||||
#ifdef ERL_NIF_DIRTY_JOB_CPU_BOUND
|
#ifdef ERL_NIF_DIRTY_JOB_CPU_BOUND
|
||||||
#define erl_nif_dirty_job_cpu_bound_macro(a,b,c) {a,b,c,ERL_NIF_DIRTY_JOB_CPU_BOUND}
|
#define erl_nif_dirty_job_cpu_bound_macro(a,b,c) {a,b,c,ERL_NIF_DIRTY_JOB_CPU_BOUND}
|
||||||
#else
|
#else
|
||||||
@ -17,15 +19,24 @@
|
|||||||
|
|
||||||
//{"crypto_box_keypair", 0, enif_crypto_box_keypair, ERL_NIF_DIRTY_JOB_CPU_BOUND}
|
//{"crypto_box_keypair", 0, enif_crypto_box_keypair, ERL_NIF_DIRTY_JOB_CPU_BOUND}
|
||||||
/* Errors */
|
/* Errors */
|
||||||
|
|
||||||
|
/* This is a global variable for resource type */
|
||||||
|
static ErlNifResourceType *generichash_state_type = NULL;
|
||||||
|
|
||||||
static
|
static
|
||||||
ERL_NIF_TERM nacl_error_tuple(ErlNifEnv *env, char *error_atom) {
|
ERL_NIF_TERM nacl_error_tuple(ErlNifEnv *env, char *error_atom) {
|
||||||
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, error_atom));
|
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, error_atom));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
static
|
static
|
||||||
int enif_crypto_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) {
|
int enif_crypto_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) {
|
||||||
return sodium_init();
|
// Create a new resource type for crypto_generichash_state
|
||||||
|
if( !(generichash_state_type = enif_open_resource_type(env, NULL, CRYPTO_GENERICHASH_STATE_RESOURCE, NULL, ERL_NIF_RT_CREATE, NULL)) ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sodium_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Low-level functions (Hashing, String Equality, ...) */
|
/* Low-level functions (Hashing, String Equality, ...) */
|
||||||
@ -293,7 +304,9 @@ ERL_NIF_TERM enif_crypto_box(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]
|
|||||||
return nacl_error_tuple(env, "alloc_failed");
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_box(result.data, padded_msg.data, padded_msg.size, nonce.data, pk.data, sk.data);
|
if( 0 != crypto_box(result.data, padded_msg.data, padded_msg.size, nonce.data, pk.data, sk.data) ) {
|
||||||
|
return nacl_error_tuple(env, "box_error");
|
||||||
|
}
|
||||||
|
|
||||||
return enif_make_sub_binary(
|
return enif_make_sub_binary(
|
||||||
env,
|
env,
|
||||||
@ -358,7 +371,10 @@ ERL_NIF_TERM enif_crypto_box_beforenm(ErlNifEnv *env, int argc, ERL_NIF_TERM con
|
|||||||
return nacl_error_tuple(env, "alloc_failed");
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_box_beforenm(k.data, pk.data, sk.data);
|
if( 0 != crypto_box_beforenm(k.data, pk.data, sk.data) ) {
|
||||||
|
// error
|
||||||
|
return nacl_error_tuple(env, "error_gen_shared_secret");
|
||||||
|
}
|
||||||
|
|
||||||
return enif_make_binary(env, &k);
|
return enif_make_binary(env, &k);
|
||||||
}
|
}
|
||||||
@ -1101,7 +1117,10 @@ ERL_NIF_TERM enif_crypto_kx_server_session_keys(ErlNifEnv *env, int argc, ERL_NI
|
|||||||
return nacl_error_tuple(env, "alloc_failed");
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_kx_server_session_keys(rx.data, tx.data, server_pk.data, server_sk.data, client_pk.data);
|
if( 0 != crypto_kx_server_session_keys(rx.data, tx.data, server_pk.data, server_sk.data, client_pk.data) ) {
|
||||||
|
// suspicious client public key
|
||||||
|
return nacl_error_tuple(env, "invalid_client_public_key");
|
||||||
|
}
|
||||||
|
|
||||||
return enif_make_tuple2(env, enif_make_binary(env, &rx), enif_make_binary(env, &tx));
|
return enif_make_tuple2(env, enif_make_binary(env, &rx), enif_make_binary(env, &tx));
|
||||||
}
|
}
|
||||||
@ -1129,7 +1148,10 @@ ERL_NIF_TERM enif_crypto_kx_client_session_keys(ErlNifEnv *env, int argc, ERL_NI
|
|||||||
return nacl_error_tuple(env, "alloc_failed");
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_kx_client_session_keys(rx.data, tx.data, client_pk.data, client_sk.data, server_pk.data);
|
if( 0 != crypto_kx_client_session_keys(rx.data, tx.data, client_pk.data, client_sk.data, server_pk.data) ) {
|
||||||
|
// suspicious server public key
|
||||||
|
return nacl_error_tuple(env, "invalid_server_public_key");
|
||||||
|
}
|
||||||
|
|
||||||
return enif_make_tuple2(env, enif_make_binary(env, &rx), enif_make_binary(env, &tx));
|
return enif_make_tuple2(env, enif_make_binary(env, &rx), enif_make_binary(env, &tx));
|
||||||
}
|
}
|
||||||
@ -1291,6 +1313,211 @@ ERL_NIF_TERM enif_crypto_pwhash_str_verify(ErlNifEnv *env, int argc, ERL_NIF_TER
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic hash
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_BYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_generichash_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_BYTES_MIN(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_generichash_BYTES_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_BYTES_MAX(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_generichash_BYTES_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_KEYBYTES(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_generichash_KEYBYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_KEYBYTES_MIN(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_generichash_KEYBYTES_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_KEYBYTES_MAX(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
return enif_make_int64(env, crypto_generichash_KEYBYTES_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
ErlNifBinary hash, message, key;
|
||||||
|
|
||||||
|
size_t hashSize;
|
||||||
|
|
||||||
|
// Validate the arguments
|
||||||
|
if( (argc != 3) ||
|
||||||
|
(!enif_get_uint64(env, argv[0], &hashSize)) ||
|
||||||
|
(!enif_inspect_binary(env, argv[1], &message)) ||
|
||||||
|
(!enif_inspect_binary(env, argv[2], &key)) ) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that hash size is crypto_generichash_BYTES/crypto_generichash_BYTES_MIN/crypto_generichash_BYTES_MAX
|
||||||
|
if( (hashSize < crypto_generichash_BYTES_MIN) ||
|
||||||
|
(hashSize > crypto_generichash_BYTES_MAX) ) {
|
||||||
|
return nacl_error_tuple(env, "invalid_hash_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate key size
|
||||||
|
unsigned char *k = key.data;
|
||||||
|
if( 0 == key.size ) {
|
||||||
|
k = NULL;
|
||||||
|
} else if( key.size < crypto_generichash_KEYBYTES_MIN || key.size > crypto_generichash_KEYBYTES_MAX ) {
|
||||||
|
return nacl_error_tuple(env, "invalid_key_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate memory for hash
|
||||||
|
if( !enif_alloc_binary(hashSize, &hash) ) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate hash
|
||||||
|
if( 0 != crypto_generichash(hash.data, hash.size, message.data, message.size, k, key.size) ) {
|
||||||
|
enif_release_binary(&hash);
|
||||||
|
return nacl_error_tuple(env, "hash_error");
|
||||||
|
}
|
||||||
|
|
||||||
|
ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK);
|
||||||
|
ERL_NIF_TERM ret = enif_make_binary(env, &hash);
|
||||||
|
|
||||||
|
return enif_make_tuple2(env, ok, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_init(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
ErlNifBinary key;
|
||||||
|
|
||||||
|
size_t hashSize;
|
||||||
|
|
||||||
|
// Validate the arguments
|
||||||
|
if( (argc != 2) ||
|
||||||
|
(!enif_get_uint64(env, argv[0], &hashSize)) ||
|
||||||
|
(!enif_inspect_binary(env, argv[1], &key)) ) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that hash size is crypto_generichash_BYTES/crypto_generichash_BYTES_MIN/crypto_generichash_BYTES_MAX
|
||||||
|
if( (hashSize < crypto_generichash_BYTES_MIN) ||
|
||||||
|
(hashSize > crypto_generichash_BYTES_MAX) ) {
|
||||||
|
return nacl_error_tuple(env, "invalid_hash_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate key size
|
||||||
|
unsigned char *k = key.data;
|
||||||
|
if( 0 == key.size ) {
|
||||||
|
k = NULL;
|
||||||
|
} else if( key.size < crypto_generichash_KEYBYTES_MIN || key.size > crypto_generichash_KEYBYTES_MAX ) {
|
||||||
|
return nacl_error_tuple(env, "invalid_key_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a resource for hash state
|
||||||
|
crypto_generichash_state *state = (crypto_generichash_state *)enif_alloc_resource(generichash_state_type, crypto_generichash_statebytes());
|
||||||
|
if( !state ) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the library function
|
||||||
|
if( 0 != crypto_generichash_init(state, k, key.size, hashSize) ) {
|
||||||
|
return nacl_error_tuple(env, "hash_init_error");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create return values
|
||||||
|
ERL_NIF_TERM e1 = enif_make_atom(env, "hashstate");
|
||||||
|
ERL_NIF_TERM e2 = argv[0];
|
||||||
|
ERL_NIF_TERM e3 = enif_make_resource(env, state);
|
||||||
|
|
||||||
|
|
||||||
|
// release dynamically allocated memory to erlang to mange
|
||||||
|
enif_release_resource(state);
|
||||||
|
|
||||||
|
// return a tuple
|
||||||
|
return enif_make_tuple3(env, e1, e2, e3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_update(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
ErlNifBinary message;
|
||||||
|
|
||||||
|
size_t hashSize;
|
||||||
|
|
||||||
|
crypto_generichash_state *state;
|
||||||
|
|
||||||
|
// Validate the arguments
|
||||||
|
if( (argc != 3) ||
|
||||||
|
(!enif_get_uint64(env, argv[0], &hashSize)) ||
|
||||||
|
(!enif_get_resource(env, argv[1], generichash_state_type, (void **)&state)) ||
|
||||||
|
(!enif_inspect_binary(env, argv[2], &message)) ) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that hash size is crypto_generichash_BYTES/crypto_generichash_BYTES_MIN/crypto_generichash_BYTES_MAX
|
||||||
|
if( (hashSize < crypto_generichash_BYTES_MIN) ||
|
||||||
|
(hashSize > crypto_generichash_BYTES_MAX) ) {
|
||||||
|
return nacl_error_tuple(env, "invalid_hash_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update hash state
|
||||||
|
if( 0 != crypto_generichash_update(state, message.data, message.size) ) {
|
||||||
|
return nacl_error_tuple(env, "hash_update_error");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generate return value
|
||||||
|
ERL_NIF_TERM e1 = enif_make_atom(env, "hashstate");
|
||||||
|
ERL_NIF_TERM e2 = argv[0];
|
||||||
|
ERL_NIF_TERM e3 = enif_make_resource(env, state);
|
||||||
|
|
||||||
|
// return a tuple
|
||||||
|
return enif_make_tuple3(env, e1, e2, e3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ERL_NIF_TERM enif_crypto_generichash_final(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) {
|
||||||
|
ErlNifBinary hash;
|
||||||
|
|
||||||
|
size_t hashSize;
|
||||||
|
|
||||||
|
crypto_generichash_state *state;
|
||||||
|
|
||||||
|
// Validate the arguments
|
||||||
|
if( (argc != 2) ||
|
||||||
|
(!enif_get_uint64(env, argv[0], &hashSize)) ||
|
||||||
|
(!enif_get_resource(env, argv[1], generichash_state_type, (void **)&state)) ) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that hash size is crypto_generichash_BYTES/crypto_generichash_BYTES_MIN/crypto_generichash_BYTES_MAX
|
||||||
|
if( (hashSize < crypto_generichash_BYTES_MIN) ||
|
||||||
|
(hashSize > crypto_generichash_BYTES_MAX) ) {
|
||||||
|
return nacl_error_tuple(env, "invalid_hash_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate memory for hash
|
||||||
|
if( !enif_alloc_binary(hashSize, &hash) ) {
|
||||||
|
return nacl_error_tuple(env, "alloc_failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate hash
|
||||||
|
if( 0 != crypto_generichash_final(state, hash.data, hash.size) ) {
|
||||||
|
enif_release_binary(&hash);
|
||||||
|
return nacl_error_tuple(env, "hash_error");
|
||||||
|
}
|
||||||
|
|
||||||
|
ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK);
|
||||||
|
ERL_NIF_TERM ret = enif_make_binary(env, &hash);
|
||||||
|
|
||||||
|
return enif_make_tuple2(env, ok, ret);
|
||||||
|
}
|
||||||
|
|
||||||
/* 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},
|
||||||
@ -1395,7 +1622,19 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"crypto_kx_SECRETKEYBYTES", 0, enif_crypto_kx_SECRETKEYBYTES},
|
{"crypto_kx_SECRETKEYBYTES", 0, enif_crypto_kx_SECRETKEYBYTES},
|
||||||
{"crypto_kx_SESSIONKEYBYTES", 0, enif_crypto_kx_SESSIONKEYBYTES},
|
{"crypto_kx_SESSIONKEYBYTES", 0, enif_crypto_kx_SESSIONKEYBYTES},
|
||||||
|
|
||||||
{"scramble_block_16", 2, enif_scramble_block_16}
|
{"scramble_block_16", 2, enif_scramble_block_16},
|
||||||
|
|
||||||
|
{"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},
|
||||||
|
{"crypto_generichash_KEYBYTES", 0, enif_crypto_generichash_KEYBYTES},
|
||||||
|
{"crypto_generichash_KEYBYTES_MIN", 0, enif_crypto_generichash_KEYBYTES_MIN},
|
||||||
|
{"crypto_generichash_KEYBYTES_MAX", 0, enif_crypto_generichash_KEYBYTES_MAX},
|
||||||
|
{"crypto_generichash", 3, enif_crypto_generichash},
|
||||||
|
{"crypto_generichash_init", 2, enif_crypto_generichash_init},
|
||||||
|
{"crypto_generichash_update", 3, enif_crypto_generichash_update},
|
||||||
|
{"crypto_generichash_final", 2, enif_crypto_generichash_final}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ERL_NIF_INIT(enacl_nif, nif_funcs, enif_crypto_load, NULL, NULL, NULL);
|
ERL_NIF_INIT(enacl_nif, nif_funcs, enif_crypto_load, NULL, NULL, NULL);
|
||||||
|
@ -113,6 +113,16 @@
|
|||||||
pwhash_str_verify/2
|
pwhash_str_verify/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
%% Generic hash functions
|
||||||
|
-export([
|
||||||
|
generichash/3,
|
||||||
|
generichash/2,
|
||||||
|
|
||||||
|
generichash_init/2,
|
||||||
|
generichash_update/2,
|
||||||
|
generichash_final/1
|
||||||
|
]).
|
||||||
|
|
||||||
%% Libsodium specific functions (which are also part of the "undocumented" interface to NaCl
|
%% Libsodium specific functions (which are also part of the "undocumented" interface to NaCl
|
||||||
-export([
|
-export([
|
||||||
randombytes/1
|
randombytes/1
|
||||||
@ -160,6 +170,13 @@
|
|||||||
-define(CRYPTO_KX_SECRETKEYBYTES, 32).
|
-define(CRYPTO_KX_SECRETKEYBYTES, 32).
|
||||||
-define(CRYPTO_KX_SESSIONKEYBYTES, 32).
|
-define(CRYPTO_KX_SESSIONKEYBYTES, 32).
|
||||||
|
|
||||||
|
-define(CRYPTO_GENERICHASH_BYTES_MIN, 16).
|
||||||
|
-define(CRYPTO_GENERICHASH_BYTES_MAX, 64).
|
||||||
|
-define(CRYPTO_GENERICHASH_BYTES, 32).
|
||||||
|
-define(CRYPTO_GENERICHASH_KEYBYTES_MIN, 16).
|
||||||
|
-define(CRYPTO_GENERICHASH_KEYBYTES_MAX, 64).
|
||||||
|
-define(CRYPTO_GENERICHASH_KEYBYTES, 32).
|
||||||
|
|
||||||
%% @doc Verify makes sure the constants defined in libsodium matches ours
|
%% @doc Verify makes sure the constants defined in libsodium matches ours
|
||||||
verify() ->
|
verify() ->
|
||||||
true = equals(binary:copy(<<0>>, enacl_nif:crypto_box_ZEROBYTES()), ?P_ZEROBYTES),
|
true = equals(binary:copy(<<0>>, enacl_nif:crypto_box_ZEROBYTES()), ?P_ZEROBYTES),
|
||||||
@ -180,7 +197,13 @@ verify() ->
|
|||||||
{crypto_secretbox_BOXZEROBYTES, ?CRYPTO_SECRETBOX_BOXZEROBYTES},
|
{crypto_secretbox_BOXZEROBYTES, ?CRYPTO_SECRETBOX_BOXZEROBYTES},
|
||||||
{crypto_kx_SESSIONKEYBYTES, ?CRYPTO_KX_SESSIONKEYBYTES},
|
{crypto_kx_SESSIONKEYBYTES, ?CRYPTO_KX_SESSIONKEYBYTES},
|
||||||
{crypto_kx_PUBLICKEYBYTES, ?CRYPTO_KX_PUBLICKEYBYTES},
|
{crypto_kx_PUBLICKEYBYTES, ?CRYPTO_KX_PUBLICKEYBYTES},
|
||||||
{crypto_kx_SECRETKEYBYTES, ?CRYPTO_KX_SECRETKEYBYTES}
|
{crypto_kx_SECRETKEYBYTES, ?CRYPTO_KX_SECRETKEYBYTES},
|
||||||
|
{crypto_generichash_BYTES, ?CRYPTO_GENERICHASH_BYTES},
|
||||||
|
{crypto_generichash_BYTES_MIN, ?CRYPTO_GENERICHASH_BYTES_MIN},
|
||||||
|
{crypto_generichash_BYTES_MAX, ?CRYPTO_GENERICHASH_BYTES_MAX},
|
||||||
|
{crypto_generichash_KEYBYTES, ?CRYPTO_GENERICHASH_KEYBYTES},
|
||||||
|
{crypto_generichash_KEYBYTES_MIN, ?CRYPTO_GENERICHASH_KEYBYTES_MIN},
|
||||||
|
{crypto_generichash_KEYBYTES_MAX, ?CRYPTO_GENERICHASH_KEYBYTES_MAX}
|
||||||
],
|
],
|
||||||
run_verifiers(Verifiers).
|
run_verifiers(Verifiers).
|
||||||
|
|
||||||
@ -257,6 +280,33 @@ unsafe_memzero(_) ->
|
|||||||
error(badarg).
|
error(badarg).
|
||||||
|
|
||||||
|
|
||||||
|
%% @doc generichash/3 creates a hash of the message using a key.
|
||||||
|
%%
|
||||||
|
%% This function generates a hash of the message using a key. The hash size is
|
||||||
|
%% either 16, 32 or 64 bytes
|
||||||
|
%% @end
|
||||||
|
-spec generichash(iodata(), binary()) -> {ok, binary()} | {error, term()}.
|
||||||
|
generichash(HashSize, Message, Key) ->
|
||||||
|
enacl_nif:crypto_generichash(HashSize, Message, Key).
|
||||||
|
|
||||||
|
%% @doc generichash/2 creates a hash of the message.
|
||||||
|
%%
|
||||||
|
%% This function generates a hash of the message. The hash size is
|
||||||
|
%% either 16, 32 or 64 bytes
|
||||||
|
%% @end
|
||||||
|
generichash(HashSize, Message) ->
|
||||||
|
enacl_nif:crypto_generichash(HashSize, Message, <<>>).
|
||||||
|
|
||||||
|
generichash_init(HashSize, Key) ->
|
||||||
|
enacl_nif:crypto_generichash_init(HashSize, Key).
|
||||||
|
|
||||||
|
generichash_update({hashstate, HashSize, HashState}, Message) ->
|
||||||
|
enacl_nif:crypto_generichash_update(HashSize, HashState, Message).
|
||||||
|
|
||||||
|
generichash_final({hashstate, HashSize, HashState}) ->
|
||||||
|
enacl_nif:crypto_generichash_final(HashSize, HashState).
|
||||||
|
|
||||||
|
|
||||||
%% @doc pwhash/2 hash a password
|
%% @doc pwhash/2 hash a password
|
||||||
%%
|
%%
|
||||||
%% This function generates a fixed size salted hash of a user defined password.
|
%% This function generates a fixed size salted hash of a user defined password.
|
||||||
|
@ -129,6 +129,21 @@
|
|||||||
crypto_pwhash_str_verify/2
|
crypto_pwhash_str_verify/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
%% Generic hash
|
||||||
|
-export([
|
||||||
|
crypto_generichash_BYTES/0,
|
||||||
|
crypto_generichash_BYTES_MIN/0,
|
||||||
|
crypto_generichash_BYTES_MAX/0,
|
||||||
|
crypto_generichash_KEYBYTES/0,
|
||||||
|
crypto_generichash_KEYBYTES_MIN/0,
|
||||||
|
crypto_generichash_KEYBYTES_MAX/0,
|
||||||
|
|
||||||
|
crypto_generichash/3,
|
||||||
|
crypto_generichash_init/2,
|
||||||
|
crypto_generichash_update/3,
|
||||||
|
crypto_generichash_final/2
|
||||||
|
]).
|
||||||
|
|
||||||
%% Access to the RNG
|
%% Access to the RNG
|
||||||
-export([
|
-export([
|
||||||
randombytes/1
|
randombytes/1
|
||||||
@ -153,6 +168,21 @@ init() ->
|
|||||||
SoName = filename:join(Dir, atom_to_list(?MODULE)),
|
SoName = filename:join(Dir, atom_to_list(?MODULE)),
|
||||||
erlang:load_nif(SoName, 0).
|
erlang:load_nif(SoName, 0).
|
||||||
|
|
||||||
|
crypto_generichash_BYTES() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_generichash_BYTES_MIN() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_generichash_BYTES_MAX() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_generichash_KEYBYTES() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_generichash_KEYBYTES_MIN() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_generichash_KEYBYTES_MAX() -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
|
crypto_generichash(_HashSize, _Message, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
|
crypto_generichash_init(_HashSize, _Key) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_generichash_update(_HashSize, _HashState, _Message) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
crypto_generichash_final(_HashSize, _HashState) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
crypto_pwhash(_Password, _Salt) -> erlang:nif_error(nif_not_loaded).
|
crypto_pwhash(_Password, _Salt) -> erlang:nif_error(nif_not_loaded).
|
||||||
crypto_pwhash_str(_Password) -> erlang:nif_error(nif_not_loaded).
|
crypto_pwhash_str(_Password) -> erlang:nif_error(nif_not_loaded).
|
||||||
crypto_pwhash_str_verify(_HashedPassword, _Password) -> erlang:nif_error(nif_not_loaded).
|
crypto_pwhash_str_verify(_HashedPassword, _Password) -> erlang:nif_error(nif_not_loaded).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user