Argon2 implementation

This commit is contained in:
daxpedda
2021-06-21 12:26:22 -07:00
committed by Kevin Lewi
parent 1572ff0104
commit 535b9b8ee4
5 changed files with 84 additions and 11 deletions
+5 -2
View File
@@ -33,7 +33,7 @@
//!
//! Note that our choice of slow hashing function in this example, `NoOpHash`, is selected only to ensure
//! that the tests execute quickly. A real application should use an actual slow hashing function, such as `scrypt`,
//! which can be enabled through the `slow-hash` feature. See more details in the [features](#features) section.
//! which can be enabled through the `scrypt` feature. See more details in the [features](#features) section.
//!
//! ## Setup
//! To set up the protocol, the server begins by creating a `ServerSetup` object:
@@ -718,13 +718,16 @@
//!
//! # Features
//!
//! - The `slow-hash` feature, when enabled, introduces a dependency on `scrypt` and implements the `SlowHash` trait for `scrypt`
//! - The `scrypt` feature, when enabled, introduces a dependency on `scrypt` and implements the `SlowHash` trait for `scrypt`
//! with a set of default parameters. In general, secure instantiations should choose to invoke a memory-hard password
//! hashing function when the client's password is expected to have low entropy, instead of relying on [slow_hash::NoOpHash]
//! as done in the above example. The more computationally intensive the `SlowHash` function is, the more resistant the server's
//! password file records will be against offline dictionary and precomputation attacks; see
//! [the OPAQUE paper](https://eprint.iacr.org/2018/163.pdf) for more details.
//!
//! - The `argon` feature, when enabled, introduces a dependency on `argon2` and implements the `SlowHash` trait for `argon2`
//! with default parameters. This is an alternative to `scrypt`.
//!
//! - The `serialize` feature, enabled by default, provides convenience functions for serializing and deserializing with
//! [serde](https://serde.rs/).
//!
+25 -5
View File
@@ -7,7 +7,7 @@
use crate::{errors::InternalPakeError, hash::Hash};
use digest::Digest;
#[cfg(feature = "slow-hash")]
#[cfg(any(feature = "argon", feature = "scrypt"))]
use generic_array::typenum::Unsigned;
use generic_array::GenericArray;
@@ -30,14 +30,14 @@ impl<D: Hash> SlowHash<D> for NoOpHash {
}
}
#[cfg(feature = "slow-hash")]
#[cfg(feature = "scrypt")]
const DEFAULT_SCRYPT_LOG_N: u8 = 15u8;
#[cfg(feature = "slow-hash")]
#[cfg(feature = "scrypt")]
const DEFAULT_SCRYPT_R: u32 = 8u32;
#[cfg(feature = "slow-hash")]
#[cfg(feature = "scrypt")]
const DEFAULT_SCRYPT_P: u32 = 1u32;
#[cfg(feature = "slow-hash")]
#[cfg(feature = "scrypt")]
impl<D: Hash> SlowHash<D> for scrypt::ScryptParams {
fn hash(
input: GenericArray<u8, <D as Digest>::OutputSize>,
@@ -51,3 +51,23 @@ impl<D: Hash> SlowHash<D> for scrypt::ScryptParams {
Ok(output)
}
}
#[cfg(feature = "argon")]
impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
fn hash(
input: GenericArray<u8, <D as Digest>::OutputSize>,
) -> Result<Vec<u8>, InternalPakeError> {
let params = argon2::Argon2::default();
let mut output = vec![0u8; <D as Digest>::OutputSize::to_usize()];
params
.hash_password_into(
argon2::Algorithm::Argon2id,
&input,
&[0; argon2::MIN_SALT_LENGTH],
&[],
&mut output,
)
.map_err(|_| InternalPakeError::SlowHashError)?;
Ok(output)
}
}