Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
Rename main NIF module to bcrypt_nif and use rebar-generated .app file
  • Loading branch information
Hunter Morris committed Mar 31, 2011
1 parent 9bb923c commit d9d3d27a9f32df421c11ea64339f59d146724cef
Showing 8 changed files with 124 additions and 26 deletions.
@@ -1,5 +1,6 @@
*.beam
ebin/*.beam
ebin/bcrypt.app
_build/
lib/bcrypt/bcrypt

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 Hunter Morris <huntermorris@gmail.com>
* Copyright (c) 2011 Hunter Morris <hunter.morris@smarkets.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -48,7 +48,7 @@ static ERL_NIF_TERM erl_encode_salt(ErlNifEnv* env, int argc, const ERL_NIF_TERM

encode_salt((char *)bin.data, (u_int8_t*)csalt.data, csalt.size, log_rounds);
enif_release_binary(&csalt);

return enif_make_string(env, (char *)bin.data, ERL_NIF_LATIN1);
}

@@ -57,10 +57,10 @@ static ERL_NIF_TERM hashpw(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
char pw[1024];
char salt[1024];
char *ret = NULL;

(void)memset(&pw, '\0', sizeof(pw));
(void)memset(&salt, '\0', sizeof(salt));

if (enif_get_string(env, argv[0], pw, sizeof(pw), ERL_NIF_LATIN1) < 1)
return enif_make_badarg(env);

@@ -70,7 +70,7 @@ static ERL_NIF_TERM hashpw(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
if (NULL == (ret = bcrypt(pw, salt)) || 0 == strcmp(ret, ":")) {
return enif_make_badarg(env);
}

return enif_make_string(env, ret, ERL_NIF_LATIN1);
}

@@ -80,4 +80,4 @@ static ErlNifFunc bcrypt_nif_funcs[] =
{"hashpw", 2, hashpw}
};

ERL_NIF_INIT(bcrypt, bcrypt_nif_funcs, NULL, NULL, NULL, NULL)
ERL_NIF_INIT(bcrypt_nif, bcrypt_nif_funcs, NULL, NULL, NULL, NULL)
Empty file.

This file was deleted.

@@ -0,0 +1,3 @@
%% -*- mode: erlang;erlang-indent-level: 2;indent-tabs-mode: nil -*-
{so_name, "bcrypt_nif.so"}.
{erl_opts, [debug_info]}.
@@ -0,0 +1,12 @@
%% -*- mode: erlang;erlang-indent-level: 2;indent-tabs-mode: nil -*-
{application, bcrypt,
[{description, "An Erlang wrapper (NIF or port program) for the OpenBSD password scheme, bcrypt."},
{vsn, "0.3.0"},
{registered, []},
{applications, [kernel, stdlib, crypto]},
{env, [
% Default number of 'rounds', defining the hashing complexity
{default_log_rounds, 12}
]}
]
}.
@@ -1,5 +1,5 @@
%% @author Hunter Morris <huntermorris@gmail.com>
%% @copyright 2009 Hunter Morris
%% @author Hunter Morris <hunter.morris@smarkets.com>
%% @copyright 2011 Hunter Morris
%%
%% @doc Wrapper around the OpenBSD Blowfish password hashing algorithm, as
%% described in "A Future-Adaptable Password Scheme" by Niels Provos and
@@ -37,7 +37,13 @@
%% @end
%%--------------------------------------------------------------------
init() ->
erlang:load_nif(filename:join(code:priv_dir(?MODULE), atom_to_list(?MODULE) ++ "_drv"), 0).
Dir = case code:priv_dir(bcrypt) of
{error, bad_name} -> "../priv";
Priv -> Priv
end,
erlang:load_nif(filename:join(Dir, "bcrypt"), 0).

nif_stub_error(Line) -> erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}).

%%--------------------------------------------------------------------
%% @doc Generate a salt with the default number of rounds, 12.
@@ -62,7 +68,7 @@ gen_salt(LogRounds) when is_integer(LogRounds),
encode_salt(R, LogRounds).

encode_salt(_R, _LogRounds) ->
nif_error(?LINE).
nif_stub_error(?LINE).

%%--------------------------------------------------------------------
%% @doc Hash the specified password and the salt using the OpenBSD
@@ -74,7 +80,4 @@ hash(Password, Salt) when is_binary(Password), is_binary(Salt) ->
hashpw(Password, Salt).

hashpw(_Password, _Salt) ->
nif_error(?LINE).

nif_error(Line) ->
exit({nif_not_loaded, module, ?MODULE, line, Line}).
nif_stub_error(?LINE).
@@ -0,0 +1,91 @@
%% @author Hunter Morris <hunter.morris@smarkets.com>
%% @copyright 2011 Hunter Morris
%%
%% @doc Wrapper around the OpenBSD Blowfish password hashing algorithm, as
%% described in "A Future-Adaptable Password Scheme" by Niels Provos and
%% David Mazieres: http://www.openbsd.org/papers/bcrypt-paper.ps
%% @end
%%
%% Permission to use, copy, modify, and distribute this software for any
%% purpose with or without fee is hereby granted, provided that the above
%% copyright notice and this permission notice appear in all copies.

%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-module(bcrypt_nif).
-author('Hunter Morris <hunter.morris@smarkets.com>').

%% API
-export([init/0]).
-export([gen_salt/0, gen_salt/1]).
-export([hash/2, hashpw/2]).

-define(DEFAULT_LOG_ROUNDS, 12).
-define(MAX_LOG_ROUNDS(L), L < 32).
-define(MIN_LOG_ROUNDS(L), L > 3).

-on_load(init/0).

%%--------------------------------------------------------------------
%% @doc Load the bcrypt NIFs
%% @spec init() -> ok
%% @end
%%--------------------------------------------------------------------
init() ->
Dir = case code:priv_dir(bcrypt) of
{error, bad_name} ->
case code:which(bcrypt) of
Filename when is_list(Filename) ->
filename:join(
[filename:dirname(Filename), "../priv"]);
_ ->
"../priv"
end;
Priv -> Priv
end,
erlang:load_nif(filename:join(Dir, "bcrypt_nif"), 0).

nif_stub_error(Line) ->
erlang:nif_error({nif_not_loaded, module, ?MODULE, line, Line}).

%%--------------------------------------------------------------------
%% @doc Generate a salt with the default number of rounds, 12.
%% @see gen_salt/1
%% @spec gen_salt() -> string()
%% @end
%%--------------------------------------------------------------------
gen_salt() ->
gen_salt(?DEFAULT_LOG_ROUNDS).

%%--------------------------------------------------------------------
%% @doc Generate a random text salt for use with hashpw/3. LogRounds
%% defines the complexity of the hashing, increasing the cost as
%% 2^log_rounds.
%% @spec gen_salt(integer()) -> string()
%% @end
%%--------------------------------------------------------------------
gen_salt(LogRounds) when is_integer(LogRounds),
?MAX_LOG_ROUNDS(LogRounds),
?MIN_LOG_ROUNDS(LogRounds) ->
R = crypto:rand_bytes(16),
encode_salt(R, LogRounds).

encode_salt(_R, _LogRounds) ->
nif_stub_error(?LINE).

%%--------------------------------------------------------------------
%% @doc Hash the specified password and the salt using the OpenBSD
%% Blowfish password hashing algorithm. Returns the hashed password.
%% @spec hash(Password::binary(), Salt::binary()) -> string()
%% @end
%%--------------------------------------------------------------------
hash(Password, Salt) when is_binary(Password), is_binary(Salt) ->
hashpw(Password, Salt).

hashpw(_Password, _Salt) ->
nif_stub_error(?LINE).

0 comments on commit d9d3d27

Please sign in to comment.