52 lines
1.4 KiB
OCaml
52 lines
1.4 KiB
OCaml
type pbkdf2_sha256_params = {
|
|
pbkdf2_sha256_iter : int;
|
|
}
|
|
|
|
type scrypt_params = {
|
|
scrypt_n : int;
|
|
scrypt_r : int;
|
|
scrypt_p : int;
|
|
}
|
|
|
|
let scrypt_params ?(scrypt_n = 16384) ?(scrypt_r = 8) ?(scrypt_p = 1) () =
|
|
{ scrypt_n; scrypt_r; scrypt_p }
|
|
|
|
type pbkdf2_sha256 =
|
|
[ `Pbkdf2_sha256 of string * string * pbkdf2_sha256_params ]
|
|
|
|
type scrypt = [ `Scrypt of string * string * scrypt_params ]
|
|
|
|
type password_hash = [ pbkdf2_sha256 | scrypt ]
|
|
|
|
type 'a user_info = {
|
|
username : string;
|
|
password_hash : [< password_hash ] as 'a;
|
|
restricted : bool;
|
|
}
|
|
|
|
let pbkdf2_sha256 ~params:{ pbkdf2_sha256_iter = count } ~salt ~password =
|
|
Pbkdf.pbkdf2 ~prf:`SHA256 ~count ~dk_len:32l ~salt ~password
|
|
|
|
let scrypt ~params:{ scrypt_n = n; scrypt_r = r; scrypt_p = p } ~salt ~password =
|
|
Scrypt.scrypt ~n ~r ~p ~dk_len:32l ~salt ~password
|
|
|
|
let hash ?(scrypt_params=scrypt_params ())
|
|
~username ~password ~restricted () =
|
|
let salt = Mirage_crypto_rng.generate 16 in
|
|
let password_hash = scrypt ~params:scrypt_params ~salt ~password in
|
|
{
|
|
username;
|
|
password_hash = `Scrypt (password_hash, salt, scrypt_params);
|
|
restricted;
|
|
}
|
|
|
|
let verify_password password user_info =
|
|
match user_info.password_hash with
|
|
| `Pbkdf2_sha256 (password_hash, salt, params) ->
|
|
String.equal
|
|
(pbkdf2_sha256 ~params ~salt ~password)
|
|
password_hash
|
|
| `Scrypt (password_hash, salt, params) ->
|
|
String.equal
|
|
(scrypt ~params ~salt ~password)
|
|
password_hash
|