200 lines
4.4 KiB
C
200 lines
4.4 KiB
C
|
#include "saltywitch.h"
|
||
|
|
||
|
ERL_NIF_TERM saltywitch_pwhash(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||
|
{
|
||
|
ErlNifBinary pass, salt;
|
||
|
ERL_NIF_TERM term;
|
||
|
|
||
|
uint64_t len, ops, mem;
|
||
|
unsigned char *out;
|
||
|
int alg;
|
||
|
|
||
|
ERL_NIF_TERM err = atom_badarg;
|
||
|
ERL_NIF_TERM reason = atom_err_opaque;
|
||
|
|
||
|
if (enif_get_uint64(env, argv[0], &len) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_inspect_iolist_as_binary(env, argv[1], &pass) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_inspect_binary(env, argv[2], &salt) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (salt.size != crypto_pwhash_SALTBYTES) {
|
||
|
reason = atom_err_invalid_salt_size;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_get_uint64(env, argv[3], &ops) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (ops > crypto_pwhash_OPSLIMIT_MAX) {
|
||
|
reason = atom_err_pwhash_ops_too_large;
|
||
|
goto badarg_FAULT;
|
||
|
} else if (ops < crypto_pwhash_OPSLIMIT_MIN) {
|
||
|
reason = atom_err_pwhash_ops_too_small;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_get_uint64(env, argv[4], &mem) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (mem > crypto_pwhash_OPSLIMIT_MAX) {
|
||
|
reason = atom_err_pwhash_mem_too_large;
|
||
|
goto badarg_FAULT;
|
||
|
} else if (mem < crypto_pwhash_OPSLIMIT_MIN) {
|
||
|
reason = atom_err_pwhash_mem_too_small;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_get_int(env, argv[5], &alg) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
out = enif_make_new_binary(env, len, &term);
|
||
|
if (out == NULL) {
|
||
|
reason = atom_err_nif_alloc;
|
||
|
goto error_FAULT;
|
||
|
}
|
||
|
|
||
|
if (crypto_pwhash(out, len, (char *) pass.data, pass.size, salt.data, ops, mem, alg) != 0) {
|
||
|
goto error_FAULT;
|
||
|
}
|
||
|
|
||
|
return term;
|
||
|
|
||
|
error_FAULT:
|
||
|
err = atom_error;
|
||
|
badarg_FAULT:
|
||
|
return saltywitch_exception(env, err, reason);
|
||
|
}
|
||
|
|
||
|
ERL_NIF_TERM saltywitch_pwhash_str(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||
|
{
|
||
|
char out[crypto_pwhash_STRBYTES];
|
||
|
uint64_t ops, mem;
|
||
|
ErlNifBinary pass;
|
||
|
|
||
|
ERL_NIF_TERM err = atom_badarg;
|
||
|
ERL_NIF_TERM reason = atom_err_opaque;
|
||
|
|
||
|
(void) argc;
|
||
|
|
||
|
if (enif_inspect_iolist_as_binary(env, argv[0], &pass) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_get_uint64(env, argv[1], &ops) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_get_uint64(env, argv[2], &mem) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (crypto_pwhash_str(out, (char *) pass.data, pass.size, ops, mem) != 0) {
|
||
|
goto error_FAULT;
|
||
|
}
|
||
|
|
||
|
return enif_make_string(env, out, ERL_NIF_LATIN1);
|
||
|
|
||
|
error_FAULT:
|
||
|
err = atom_error;
|
||
|
badarg_FAULT:
|
||
|
return saltywitch_exception(env, err, reason);
|
||
|
}
|
||
|
|
||
|
#include <stdio.h>
|
||
|
ERL_NIF_TERM saltywitch_pwhash_str_verify(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||
|
{
|
||
|
ErlNifBinary hash, pass;
|
||
|
|
||
|
ERL_NIF_TERM err = atom_badarg;
|
||
|
ERL_NIF_TERM reason = atom_err_opaque;
|
||
|
|
||
|
(void) argc;
|
||
|
|
||
|
if (enif_inspect_iolist_as_binary(env, argv[0], &hash) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (hash.size > crypto_pwhash_STRBYTES) {
|
||
|
reason = atom_err_pwhash_too_long;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_inspect_iolist_as_binary(env, argv[1], &pass) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (crypto_pwhash_str_verify((char *) hash.data, (char *) pass.data, pass.size) != 0) {
|
||
|
reason = atom_err_verification_failed;
|
||
|
goto error_FAULT;
|
||
|
}
|
||
|
|
||
|
return atom_ok;
|
||
|
|
||
|
error_FAULT:
|
||
|
err = atom_error;
|
||
|
badarg_FAULT:
|
||
|
return saltywitch_exception(env, err, reason);
|
||
|
}
|
||
|
|
||
|
ERL_NIF_TERM saltywitch_pwhash_str_needs_rehash(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||
|
{
|
||
|
ErlNifBinary hash;
|
||
|
uint64_t ops, mem;
|
||
|
|
||
|
ERL_NIF_TERM err = atom_badarg;
|
||
|
ERL_NIF_TERM reason = atom_err_opaque;
|
||
|
|
||
|
if (enif_inspect_binary(env, argv[0], &hash) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (hash.size > crypto_pwhash_STRBYTES) {
|
||
|
reason = atom_err_pwhash_too_long;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_get_uint64(env, argv[1], &ops) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
if (enif_get_uint64(env, argv[2], &mem) == false) {
|
||
|
reason = atom_err_invalid_type;
|
||
|
goto badarg_FAULT;
|
||
|
}
|
||
|
|
||
|
switch (crypto_pwhash_str_needs_rehash((char *) hash.data, ops, mem)) {
|
||
|
case 0:
|
||
|
return atom_ok;
|
||
|
case 1:
|
||
|
reason = atom_err_pwhash_needs_rehash;
|
||
|
}
|
||
|
|
||
|
err = atom_error;
|
||
|
|
||
|
badarg_FAULT:
|
||
|
return saltywitch_exception(env, err, reason);
|
||
|
}
|