1%% This Source Code Form is subject to the terms of the Mozilla Public
2%% License, v. 2.0. If a copy of the MPL was not distributed with this
3%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4%%
5%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates.  All rights reserved.
6%%
7
8-module(rabbit_password).
9-include_lib("rabbit_common/include/rabbit.hrl").
10
11-define(DEFAULT_HASHING_MODULE, rabbit_password_hashing_sha256).
12
13%%
14%% API
15%%
16
17-export([hash/1, hash/2, generate_salt/0, salted_hash/2, salted_hash/3,
18         hashing_mod/0, hashing_mod/1]).
19
20hash(Cleartext) ->
21    hash(hashing_mod(), Cleartext).
22
23hash(HashingMod, Cleartext) ->
24    SaltBin = generate_salt(),
25    Hash = salted_hash(HashingMod, SaltBin, Cleartext),
26    <<SaltBin/binary, Hash/binary>>.
27
28generate_salt() ->
29    Salt = rand:uniform(16#ffffffff),
30    <<Salt:32>>.
31
32salted_hash(Salt, Cleartext) ->
33    salted_hash(hashing_mod(), Salt, Cleartext).
34
35salted_hash(Mod, Salt, Cleartext) ->
36    Fun = fun Mod:hash/1,
37    Fun(<<Salt/binary, Cleartext/binary>>).
38
39hashing_mod() ->
40    rabbit_misc:get_env(rabbit, password_hashing_module,
41        ?DEFAULT_HASHING_MODULE).
42
43hashing_mod(rabbit_password_hashing_sha256) ->
44    rabbit_password_hashing_sha256;
45hashing_mod(rabbit_password_hashing_md5) ->
46    rabbit_password_hashing_md5;
47%% fall back to the hashing function that's been used prior to 3.6.0
48hashing_mod(undefined) ->
49    rabbit_password_hashing_md5;
50%% if a custom module is configured, simply use it
51hashing_mod(CustomMod) when is_atom(CustomMod) ->
52    CustomMod.
53