Split off password hashing
This commit is contained in:
parent
fddbefeabd
commit
d3c033c4e6
@ -1,12 +1,13 @@
|
||||
#include "erl_nif.h"
|
||||
|
||||
#include <sodium.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "erl_nif.h"
|
||||
|
||||
#include "aead.h"
|
||||
#include "enacl.h"
|
||||
#include "generichash.h"
|
||||
#include "hash.h"
|
||||
#include "pwhash.h"
|
||||
#include "sign.h"
|
||||
|
||||
#define CRYPTO_SIGN_STATE_RESOURCE "crypto_sign_state"
|
||||
@ -982,154 +983,6 @@ static ERL_NIF_TERM enif_scramble_block_16(ErlNifEnv *env, int argc,
|
||||
return enif_make_binary(env, &out);
|
||||
}
|
||||
|
||||
static size_t enacl_pwhash_opslimit(ErlNifEnv *env, ERL_NIF_TERM arg) {
|
||||
ERL_NIF_TERM a;
|
||||
size_t r;
|
||||
|
||||
if (enif_is_atom(env, arg)) {
|
||||
a = enif_make_atom(env, "interactive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_INTERACTIVE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "moderate");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_MODERATE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "sensitive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_SENSITIVE;
|
||||
}
|
||||
} else if (enif_get_ulong(env, arg, &r)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t enacl_pwhash_memlimit(ErlNifEnv *env, ERL_NIF_TERM arg) {
|
||||
ERL_NIF_TERM a;
|
||||
size_t r;
|
||||
|
||||
if (enif_is_atom(env, arg)) {
|
||||
a = enif_make_atom(env, "interactive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_INTERACTIVE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "moderate");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_MODERATE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "sensitive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_SENSITIVE;
|
||||
}
|
||||
} else if (enif_get_ulong(env, arg, &r)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM enacl_crypto_pwhash(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary h, p, s;
|
||||
size_t o, m;
|
||||
|
||||
// Validate the arguments
|
||||
if ((argc != 4) || (!enif_inspect_iolist_as_binary(env, argv[0], &p)) ||
|
||||
(!enif_inspect_binary(env, argv[1], &s)) ||
|
||||
!(o = enacl_pwhash_opslimit(env, argv[2])) ||
|
||||
!(m = enacl_pwhash_memlimit(env, argv[3]))) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
// Check limits
|
||||
if ((o < crypto_pwhash_OPSLIMIT_MIN) || (o > crypto_pwhash_OPSLIMIT_MAX) ||
|
||||
(m < crypto_pwhash_MEMLIMIT_MIN) || (m > crypto_pwhash_MEMLIMIT_MAX)) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
// Check Salt size
|
||||
if (s.size != crypto_pwhash_SALTBYTES) {
|
||||
return nacl_error_tuple(env, "invalid_salt_size");
|
||||
}
|
||||
|
||||
// Allocate memory for return binary
|
||||
if (!enif_alloc_binary(crypto_box_SEEDBYTES, &h)) {
|
||||
return nacl_error_tuple(env, "alloc_failed");
|
||||
}
|
||||
|
||||
if (crypto_pwhash(h.data, h.size, (char *)p.data, p.size, s.data, o, m,
|
||||
crypto_pwhash_ALG_DEFAULT) != 0) {
|
||||
/* out of memory */
|
||||
enif_release_binary(&h);
|
||||
return nacl_error_tuple(env, "out_of_memory");
|
||||
}
|
||||
|
||||
ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK);
|
||||
ERL_NIF_TERM ret = enif_make_binary(env, &h);
|
||||
|
||||
return enif_make_tuple2(env, ok, ret);
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM enacl_crypto_pwhash_str(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary h, p;
|
||||
size_t o, m;
|
||||
|
||||
// Validate the arguments
|
||||
if ((argc != 3) || (!enif_inspect_iolist_as_binary(env, argv[0], &p)) ||
|
||||
!(o = enacl_pwhash_opslimit(env, argv[1])) ||
|
||||
!(m = enacl_pwhash_memlimit(env, argv[2]))) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
// Check limits
|
||||
if ((o < crypto_pwhash_OPSLIMIT_MIN) || (o > crypto_pwhash_OPSLIMIT_MAX) ||
|
||||
(m < crypto_pwhash_MEMLIMIT_MIN) || (m > crypto_pwhash_MEMLIMIT_MAX)) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
// Allocate memory for return binary
|
||||
if (!enif_alloc_binary(crypto_pwhash_STRBYTES, &h)) {
|
||||
return nacl_error_tuple(env, "alloc_failed");
|
||||
}
|
||||
|
||||
if (crypto_pwhash_str((char *)h.data, (char *)p.data, p.size, o, m) != 0) {
|
||||
/* out of memory */
|
||||
enif_release_binary(&h);
|
||||
return nacl_error_tuple(env, "out_of_memory");
|
||||
}
|
||||
|
||||
ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK);
|
||||
ERL_NIF_TERM ret = enif_make_binary(env, &h);
|
||||
|
||||
return enif_make_tuple2(env, ok, ret);
|
||||
}
|
||||
|
||||
static ERL_NIF_TERM enacl_crypto_pwhash_str_verify(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary h, p;
|
||||
|
||||
// Validate the arguments
|
||||
if ((argc != 2) || (!enif_inspect_iolist_as_binary(env, argv[0], &h)) ||
|
||||
(!enif_inspect_iolist_as_binary(env, argv[1], &p))) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
ERL_NIF_TERM retVal = enif_make_atom(env, ATOM_TRUE);
|
||||
if (crypto_pwhash_str_verify((char *)h.data, (char *)p.data, p.size) != 0) {
|
||||
/* wrong password */
|
||||
retVal = enif_make_atom(env, ATOM_FALSE);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/* Tie the knot to the Erlang world */
|
||||
static ErlNifFunc nif_funcs[] = {
|
||||
{"crypto_box_NONCEBYTES", 0, enacl_crypto_box_NONCEBYTES},
|
||||
|
152
c_src/pwhash.c
Normal file
152
c_src/pwhash.c
Normal file
@ -0,0 +1,152 @@
|
||||
#include <sodium.h>
|
||||
|
||||
#include "enacl.h"
|
||||
#include "erl_nif.h"
|
||||
#include "pwhash.h"
|
||||
|
||||
static size_t enacl_pwhash_opslimit(ErlNifEnv *env, ERL_NIF_TERM arg) {
|
||||
ERL_NIF_TERM a;
|
||||
size_t r;
|
||||
|
||||
if (enif_is_atom(env, arg)) {
|
||||
a = enif_make_atom(env, "interactive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_INTERACTIVE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "moderate");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_MODERATE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "sensitive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_OPSLIMIT_SENSITIVE;
|
||||
}
|
||||
} else if (enif_get_ulong(env, arg, &r)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t enacl_pwhash_memlimit(ErlNifEnv *env, ERL_NIF_TERM arg) {
|
||||
ERL_NIF_TERM a;
|
||||
size_t r;
|
||||
|
||||
if (enif_is_atom(env, arg)) {
|
||||
a = enif_make_atom(env, "interactive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_INTERACTIVE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "moderate");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_MODERATE;
|
||||
}
|
||||
|
||||
a = enif_make_atom(env, "sensitive");
|
||||
if (enif_is_identical(a, arg)) {
|
||||
return crypto_pwhash_MEMLIMIT_SENSITIVE;
|
||||
}
|
||||
} else if (enif_get_ulong(env, arg, &r)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_pwhash(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary h, p, s;
|
||||
size_t o, m;
|
||||
|
||||
// Validate the arguments
|
||||
if ((argc != 4) || (!enif_inspect_iolist_as_binary(env, argv[0], &p)) ||
|
||||
(!enif_inspect_binary(env, argv[1], &s)) ||
|
||||
!(o = enacl_pwhash_opslimit(env, argv[2])) ||
|
||||
!(m = enacl_pwhash_memlimit(env, argv[3]))) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
// Check limits
|
||||
if ((o < crypto_pwhash_OPSLIMIT_MIN) || (o > crypto_pwhash_OPSLIMIT_MAX) ||
|
||||
(m < crypto_pwhash_MEMLIMIT_MIN) || (m > crypto_pwhash_MEMLIMIT_MAX)) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
// Check Salt size
|
||||
if (s.size != crypto_pwhash_SALTBYTES) {
|
||||
return nacl_error_tuple(env, "invalid_salt_size");
|
||||
}
|
||||
|
||||
// Allocate memory for return binary
|
||||
if (!enif_alloc_binary(crypto_box_SEEDBYTES, &h)) {
|
||||
return nacl_error_tuple(env, "alloc_failed");
|
||||
}
|
||||
|
||||
if (crypto_pwhash(h.data, h.size, (char *)p.data, p.size, s.data, o, m,
|
||||
crypto_pwhash_ALG_DEFAULT) != 0) {
|
||||
/* out of memory */
|
||||
enif_release_binary(&h);
|
||||
return nacl_error_tuple(env, "out_of_memory");
|
||||
}
|
||||
|
||||
ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK);
|
||||
ERL_NIF_TERM ret = enif_make_binary(env, &h);
|
||||
|
||||
return enif_make_tuple2(env, ok, ret);
|
||||
}
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_pwhash_str(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary h, p;
|
||||
size_t o, m;
|
||||
|
||||
// Validate the arguments
|
||||
if ((argc != 3) || (!enif_inspect_iolist_as_binary(env, argv[0], &p)) ||
|
||||
!(o = enacl_pwhash_opslimit(env, argv[1])) ||
|
||||
!(m = enacl_pwhash_memlimit(env, argv[2]))) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
// Check limits
|
||||
if ((o < crypto_pwhash_OPSLIMIT_MIN) || (o > crypto_pwhash_OPSLIMIT_MAX) ||
|
||||
(m < crypto_pwhash_MEMLIMIT_MIN) || (m > crypto_pwhash_MEMLIMIT_MAX)) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
// Allocate memory for return binary
|
||||
if (!enif_alloc_binary(crypto_pwhash_STRBYTES, &h)) {
|
||||
return nacl_error_tuple(env, "alloc_failed");
|
||||
}
|
||||
|
||||
if (crypto_pwhash_str((char *)h.data, (char *)p.data, p.size, o, m) != 0) {
|
||||
/* out of memory */
|
||||
enif_release_binary(&h);
|
||||
return nacl_error_tuple(env, "out_of_memory");
|
||||
}
|
||||
|
||||
ERL_NIF_TERM ok = enif_make_atom(env, ATOM_OK);
|
||||
ERL_NIF_TERM ret = enif_make_binary(env, &h);
|
||||
|
||||
return enif_make_tuple2(env, ok, ret);
|
||||
}
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_pwhash_str_verify(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]) {
|
||||
ErlNifBinary h, p;
|
||||
// Validate the arguments
|
||||
if ((argc != 2) || (!enif_inspect_iolist_as_binary(env, argv[0], &h)) ||
|
||||
(!enif_inspect_iolist_as_binary(env, argv[1], &p))) {
|
||||
return enif_make_badarg(env);
|
||||
}
|
||||
|
||||
ERL_NIF_TERM ret = enif_make_atom(env, ATOM_TRUE);
|
||||
if (crypto_pwhash_str_verify((char *)h.data, (char *)p.data, p.size) != 0) {
|
||||
/* wrong password */
|
||||
ret = enif_make_atom(env, ATOM_FALSE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
15
c_src/pwhash.h
Normal file
15
c_src/pwhash.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef ENACL_PWHASH_H
|
||||
#define ENACL_PWHASH_H
|
||||
|
||||
#include "erl_nif.h"
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_pwhash(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]);
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_pwhash_str(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]);
|
||||
|
||||
ERL_NIF_TERM enacl_crypto_pwhash_str_verify(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user