diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/rust/rust-argon2/src/argon2.rs | 717 |
1 files changed, 717 insertions, 0 deletions
diff --git a/third_party/rust/rust-argon2/src/argon2.rs b/third_party/rust/rust-argon2/src/argon2.rs new file mode 100644 index 0000000000..d16f3487a4 --- /dev/null +++ b/third_party/rust/rust-argon2/src/argon2.rs @@ -0,0 +1,717 @@ +// Copyright (c) 2017 Martijn Rijkeboer <mrr@sru-systems.com> +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::context::Context; +use super::config::Config; +use super::core; +use super::encoding; +use super::memory::Memory; +use super::result::Result; +use super::thread_mode::ThreadMode; +use super::variant::Variant; +use super::version::Version; + +/// Returns the length of the encoded string. +/// +/// # Remarks +/// +/// The length is **one** less that the original C version, since no null +/// terminator is used. +/// +/// # Examples +/// +/// ```rust +/// use argon2::{self, Variant}; +/// +/// let variant = Variant::Argon2i; +/// let mem = 4096; +/// let time = 10; +/// let parallelism = 10; +/// let salt_len = 8; +/// let hash_len = 32; +/// let enc_len = argon2::encoded_len(variant, mem, time, parallelism, salt_len, hash_len); +/// assert_eq!(enc_len, 86); +/// ``` +#[cfg_attr(rustfmt, rustfmt_skip)] +pub fn encoded_len( + variant: Variant, + mem_cost: u32, + time_cost: u32, + parallelism: u32, + salt_len: u32, + hash_len: u32 +) -> u32 { + ("$$v=$m=,t=,p=$$".len() as u32) + + (variant.as_lowercase_str().len() as u32) + + encoding::num_len(Version::default().as_u32()) + + encoding::num_len(mem_cost) + + encoding::num_len(time_cost) + + encoding::num_len(parallelism) + + encoding::base64_len(salt_len) + + encoding::base64_len(hash_len) +} + +/// Hashes the password and returns the encoded hash. +/// +/// # Examples +/// +/// Create an encoded hash with the default configuration: +/// +/// ``` +/// use argon2::{self, Config}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let config = Config::default(); +/// let encoded = argon2::hash_encoded(pwd, salt, &config).unwrap(); +/// ``` +/// +/// +/// Create an Argon2d encoded hash with 4 lanes and parallel execution: +/// +/// ``` +/// use argon2::{self, Config, ThreadMode, Variant}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let mut config = Config::default(); +/// config.variant = Variant::Argon2d; +/// config.lanes = 4; +/// config.thread_mode = ThreadMode::Parallel; +/// let encoded = argon2::hash_encoded(pwd, salt, &config).unwrap(); +/// ``` +pub fn hash_encoded(pwd: &[u8], salt: &[u8], config: &Config) -> Result<String> { + let context = Context::new(config.clone(), pwd, salt)?; + let hash = run(&context); + let encoded = encoding::encode_string(&context, &hash); + Ok(encoded) +} + +/// Hashes the password using default settings and returns the encoded hash. +/// +/// # Examples +/// +/// ``` +/// use argon2; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let encoded = argon2::hash_encoded_defaults(pwd, salt).unwrap(); +/// ``` +/// +/// The above rewritten using `hash_encoded`: +/// +/// ``` +/// use argon2::{self, Config}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let config = Config::default(); +/// let encoded = argon2::hash_encoded(pwd, salt, &config).unwrap(); +/// ``` +#[deprecated(since = "0.2.0", note = "please use `hash_encoded` instead")] +pub fn hash_encoded_defaults(pwd: &[u8], salt: &[u8]) -> Result<String> { + hash_encoded(pwd, salt, &Config::default()) +} + +/// Hashes the password and returns the encoded hash (pre 0.2.0 `hash_encoded`). +/// +/// # Examples +/// +/// +/// ``` +/// use argon2::{self, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let mem_cost = 4096; +/// let time_cost = 10; +/// let lanes = 1; +/// let threads = 1; +/// let secret = b"secret value"; +/// let ad = b"associated data"; +/// let hash_len = 32; +/// let encoded = argon2::hash_encoded_old(Variant::Argon2i, +/// Version::Version13, +/// mem_cost, +/// time_cost, +/// lanes, +/// threads, +/// pwd, +/// salt, +/// secret, +/// ad, +/// hash_len).unwrap(); +/// ``` +/// +/// The above rewritten using the new `hash_encoded`: +/// +/// ``` +/// use argon2::{self, Config, ThreadMode, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let config = Config { +/// variant: Variant::Argon2i, +/// version: Version::Version13, +/// mem_cost: 4096, +/// time_cost: 10, +/// lanes: 1, +/// thread_mode: ThreadMode::Sequential, +/// secret: b"secret value", +/// ad: b"associated data", +/// hash_length: 32, +/// }; +/// let encoded = argon2::hash_encoded(pwd, salt, &config).unwrap(); +/// ``` +#[deprecated(since = "0.2.0", note = "please use new `hash_encoded` instead")] +pub fn hash_encoded_old( + variant: Variant, + version: Version, + mem_cost: u32, + time_cost: u32, + lanes: u32, + threads: u32, + pwd: &[u8], + salt: &[u8], + secret: &[u8], + ad: &[u8], + hash_len: u32, +) -> Result<String> { + let config = Config { + variant: variant, + version: version, + mem_cost: mem_cost, + time_cost: time_cost, + lanes: lanes, + thread_mode: ThreadMode::from_threads(threads), + secret: secret, + ad: ad, + hash_length: hash_len, + }; + hash_encoded(pwd, salt, &config) +} + +/// Hashes the password and returns the encoded hash (standard). +/// +/// # Examples +/// +/// +/// ``` +/// use argon2::{self, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let mem_cost = 4096; +/// let time_cost = 10; +/// let parallelism = 1; +/// let hash_len = 32; +/// let encoded = argon2::hash_encoded_std(Variant::Argon2i, +/// Version::Version13, +/// mem_cost, +/// time_cost, +/// parallelism, +/// pwd, +/// salt, +/// hash_len).unwrap(); +/// ``` +/// +/// The above rewritten using `hash_encoded`: +/// +/// ``` +/// use argon2::{self, Config, ThreadMode, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let config = Config { +/// variant: Variant::Argon2i, +/// version: Version::Version13, +/// mem_cost: 4096, +/// time_cost: 10, +/// lanes: 1, +/// thread_mode: ThreadMode::Sequential, +/// secret: &[], +/// ad: &[], +/// hash_length: 32, +/// }; +/// let encoded = argon2::hash_encoded(pwd, salt, &config).unwrap(); +/// ``` +#[deprecated(since = "0.2.0", note = "please use `hash_encoded` instead")] +pub fn hash_encoded_std( + variant: Variant, + version: Version, + mem_cost: u32, + time_cost: u32, + parallelism: u32, + pwd: &[u8], + salt: &[u8], + hash_len: u32, +) -> Result<String> { + let config = Config { + variant: variant, + version: version, + mem_cost: mem_cost, + time_cost: time_cost, + lanes: parallelism, + thread_mode: ThreadMode::from_threads(parallelism), + secret: &[], + ad: &[], + hash_length: hash_len, + }; + hash_encoded(pwd, salt, &config) +} + +/// Hashes the password and returns the hash as a vector. +/// +/// # Examples +/// +/// Create a hash with the default configuration: +/// +/// ``` +/// use argon2::{self, Config}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let config = Config::default(); +/// let vec = argon2::hash_raw(pwd, salt, &config).unwrap(); +/// ``` +/// +/// +/// Create an Argon2d hash with 4 lanes and parallel execution: +/// +/// ``` +/// use argon2::{self, Config, ThreadMode, Variant}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let mut config = Config::default(); +/// config.variant = Variant::Argon2d; +/// config.lanes = 4; +/// config.thread_mode = ThreadMode::Parallel; +/// let vec = argon2::hash_raw(pwd, salt, &config).unwrap(); +/// ``` +pub fn hash_raw(pwd: &[u8], salt: &[u8], config: &Config) -> Result<Vec<u8>> { + let context = Context::new(config.clone(), pwd, salt)?; + let hash = run(&context); + Ok(hash) +} + +/// Hashes the password using default settings and returns the hash as a vector. +/// +/// # Examples +/// +/// ``` +/// use argon2; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let vec = argon2::hash_raw_defaults(pwd, salt).unwrap(); +/// ``` +/// +/// The above rewritten using `hash_raw`: +/// +/// ``` +/// use argon2::{self, Config}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let config = Config::default(); +/// let vec = argon2::hash_raw(pwd, salt, &config).unwrap(); +/// ``` +#[deprecated(since = "0.2.0", note = "please use `hash_raw` instead")] +pub fn hash_raw_defaults(pwd: &[u8], salt: &[u8]) -> Result<Vec<u8>> { + hash_raw(pwd, salt, &Config::default()) +} + +/// Hashes the password and returns the hash as a vector (pre 0.2.0 `hash_raw`). +/// +/// # Examples +/// +/// +/// ``` +/// use argon2::{self, Variant, Version}; +/// +/// let mem_cost = 4096; +/// let time_cost = 10; +/// let lanes = 1; +/// let threads = 1; +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let secret = b"secret value"; +/// let ad = b"associated data"; +/// let hash_len = 32; +/// let vec = argon2::hash_raw_old(Variant::Argon2i, +/// Version::Version13, +/// mem_cost, +/// time_cost, +/// lanes, +/// threads, +/// pwd, +/// salt, +/// secret, +/// ad, +/// hash_len).unwrap(); +/// ``` +/// +/// The above rewritten using the new `hash_raw`: +/// +/// ``` +/// use argon2::{self, Config, ThreadMode, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let config = Config { +/// variant: Variant::Argon2i, +/// version: Version::Version13, +/// mem_cost: 4096, +/// time_cost: 10, +/// lanes: 1, +/// thread_mode: ThreadMode::Sequential, +/// secret: b"secret value", +/// ad: b"associated data", +/// hash_length: 32, +/// }; +/// let vec = argon2::hash_raw(pwd, salt, &config); +/// ``` +#[deprecated(since = "0.2.0", note = "please use new `hash_raw` instead")] +pub fn hash_raw_old( + variant: Variant, + version: Version, + mem_cost: u32, + time_cost: u32, + lanes: u32, + threads: u32, + pwd: &[u8], + salt: &[u8], + secret: &[u8], + ad: &[u8], + hash_len: u32, +) -> Result<Vec<u8>> { + let config = Config { + variant: variant, + version: version, + mem_cost: mem_cost, + time_cost: time_cost, + lanes: lanes, + thread_mode: ThreadMode::from_threads(threads), + secret: secret, + ad: ad, + hash_length: hash_len, + }; + hash_raw(pwd, salt, &config) +} + +/// Hashes the password and returns the hash as a vector (standard). +/// +/// # Examples +/// +/// +/// ``` +/// use argon2::{self, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let mem_cost = 4096; +/// let time_cost = 10; +/// let parallelism = 1; +/// let hash_len = 32; +/// let vec = argon2::hash_raw_std(Variant::Argon2i, +/// Version::Version13, +/// mem_cost, +/// time_cost, +/// parallelism, +/// pwd, +/// salt, +/// hash_len).unwrap(); +/// ``` +/// +/// The above rewritten using `hash_raw`: +/// +/// ``` +/// use argon2::{self, Config, ThreadMode, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let config = Config { +/// variant: Variant::Argon2i, +/// version: Version::Version13, +/// mem_cost: 4096, +/// time_cost: 10, +/// lanes: 1, +/// thread_mode: ThreadMode::Sequential, +/// secret: &[], +/// ad: &[], +/// hash_length: 32, +/// }; +/// let vec = argon2::hash_raw(pwd, salt, &config); +/// ``` +#[deprecated(since = "0.2.0", note = "please use `hash_raw` instead")] +pub fn hash_raw_std( + variant: Variant, + version: Version, + mem_cost: u32, + time_cost: u32, + parallelism: u32, + pwd: &[u8], + salt: &[u8], + hash_len: u32, +) -> Result<Vec<u8>> { + let config = Config { + variant: variant, + version: version, + mem_cost: mem_cost, + time_cost: time_cost, + lanes: parallelism, + thread_mode: ThreadMode::from_threads(parallelism), + secret: &[], + ad: &[], + hash_length: hash_len, + }; + hash_raw(pwd, salt, &config) +} + +/// Verifies the password with the encoded hash. +/// +/// # Examples +/// +/// ``` +/// use argon2; +/// +/// let enc = "$argon2i$v=19$m=4096,t=3,p=1$c29tZXNhbHQ\ +/// $iWh06vD8Fy27wf9npn6FXWiCX4K6pW6Ue1Bnzz07Z8A"; +/// let pwd = b"password"; +/// let res = argon2::verify_encoded(enc, pwd).unwrap(); +/// assert!(res); +/// ``` +pub fn verify_encoded(encoded: &str, pwd: &[u8]) -> Result<bool> { + verify_encoded_ext(encoded, pwd, &[], &[]) +} + +/// Verifies the password with the encoded hash, secret and associated data. +/// +/// # Examples +/// +/// ``` +/// use argon2; +/// +/// let enc = "$argon2i$v=19$m=4096,t=3,p=1$c29tZXNhbHQ\ +/// $OlcSvlN20Lz43sK3jhCJ9K04oejhiY0AmI+ck6nuETo"; +/// let pwd = b"password"; +/// let secret = b"secret"; +/// let ad = b"ad"; +/// let res = argon2::verify_encoded_ext(enc, pwd, secret, ad).unwrap(); +/// assert!(res); +/// ``` +pub fn verify_encoded_ext(encoded: &str, pwd: &[u8], secret: &[u8], ad: &[u8]) -> Result<bool> { + let decoded = encoding::decode_string(encoded)?; + let config = Config { + variant: decoded.variant, + version: decoded.version, + mem_cost: decoded.mem_cost, + time_cost: decoded.time_cost, + lanes: decoded.parallelism, + thread_mode: ThreadMode::from_threads(decoded.parallelism), + secret: secret, + ad: ad, + hash_length: decoded.hash.len() as u32, + }; + verify_raw(pwd, &decoded.salt, &decoded.hash, &config) +} + +/// Verifies the password with the supplied configuration. +/// +/// # Examples +/// +/// +/// ``` +/// use argon2::{self, Config}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let hash = &[137, 104, 116, 234, 240, 252, 23, 45, 187, 193, 255, 103, 166, +/// 126, 133, 93, 104, 130, 95, 130, 186, 165, 110, 148, 123, 80, +/// 103, 207, 61, 59, 103, 192]; +/// let config = Config::default(); +/// let res = argon2::verify_raw(pwd, salt, hash, &config).unwrap(); +/// assert!(res); +/// ``` +pub fn verify_raw(pwd: &[u8], salt: &[u8], hash: &[u8], config: &Config) -> Result<bool> { + let config = Config { + hash_length: hash.len() as u32, + ..config.clone() + }; + let context = Context::new(config, pwd, salt)?; + Ok(run(&context) == hash) +} + +/// Verifies the password with the supplied settings (pre 0.2.0 `verify_raw`). +/// +/// # Examples +/// +/// ``` +/// use argon2::{self, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let hash = &[137, 104, 116, 234, 240, 252, 23, 45, 187, 193, 255, 103, 166, +/// 126, 133, 93, 104, 130, 95, 130, 186, 165, 110, 148, 123, 80, +/// 103, 207, 61, 59, 103, 192]; +/// let mem_cost = 4096; +/// let time_cost = 3; +/// let lanes = 1; +/// let threads = 1; +/// let secret = &[]; +/// let ad = &[]; +/// let res = argon2::verify_raw_old(Variant::Argon2i, +/// Version::Version13, +/// mem_cost, +/// time_cost, +/// lanes, +/// threads, +/// pwd, +/// salt, +/// secret, +/// ad, +/// hash).unwrap(); +/// assert!(res); +/// ``` +/// +/// The above rewritten using the new `verify_raw`: +/// +/// ``` +/// use argon2::{self, Config, ThreadMode, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let hash = &[137, 104, 116, 234, 240, 252, 23, 45, 187, 193, 255, 103, 166, +/// 126, 133, 93, 104, 130, 95, 130, 186, 165, 110, 148, 123, 80, +/// 103, 207, 61, 59, 103, 192]; +/// let config = Config { +/// variant: Variant::Argon2i, +/// version: Version::Version13, +/// mem_cost: 4096, +/// time_cost: 3, +/// lanes: 1, +/// thread_mode: ThreadMode::Sequential, +/// secret: &[], +/// ad: &[], +/// hash_length: hash.len() as u32, +/// }; +/// let res = argon2::verify_raw(pwd, salt, hash, &config).unwrap(); +/// assert!(res); +/// ``` +#[deprecated(since = "0.2.0", note = "please use new `verify_raw` instead")] +pub fn verify_raw_old( + variant: Variant, + version: Version, + mem_cost: u32, + time_cost: u32, + lanes: u32, + threads: u32, + pwd: &[u8], + salt: &[u8], + secret: &[u8], + ad: &[u8], + hash: &[u8], +) -> Result<bool> { + let config = Config { + variant: variant, + version: version, + mem_cost: mem_cost, + time_cost: time_cost, + lanes: lanes, + thread_mode: ThreadMode::from_threads(threads), + secret: secret, + ad: ad, + hash_length: hash.len() as u32, + }; + verify_raw(pwd, salt, hash, &config) +} + +/// Verifies the password with the supplied settings (standard). +/// +/// # Examples +/// +/// +/// ``` +/// use argon2::{self, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let hash = &[137, 104, 116, 234, 240, 252, 23, 45, 187, 193, 255, 103, 166, +/// 126, 133, 93, 104, 130, 95, 130, 186, 165, 110, 148, 123, 80, +/// 103, 207, 61, 59, 103, 192]; +/// let mem_cost = 4096; +/// let time_cost = 3; +/// let parallelism = 1; +/// let res = argon2::verify_raw_std(Variant::Argon2i, +/// Version::Version13, +/// mem_cost, +/// time_cost, +/// parallelism, +/// pwd, +/// salt, +/// hash).unwrap(); +/// assert!(res); +/// ``` +/// +/// The above rewritten using `verify_raw`: +/// +/// ``` +/// use argon2::{self, Config, ThreadMode, Variant, Version}; +/// +/// let pwd = b"password"; +/// let salt = b"somesalt"; +/// let hash = &[137, 104, 116, 234, 240, 252, 23, 45, 187, 193, 255, 103, 166, +/// 126, 133, 93, 104, 130, 95, 130, 186, 165, 110, 148, 123, 80, +/// 103, 207, 61, 59, 103, 192]; +/// let config = Config { +/// variant: Variant::Argon2i, +/// version: Version::Version13, +/// mem_cost: 4096, +/// time_cost: 3, +/// lanes: 1, +/// thread_mode: ThreadMode::Sequential, +/// secret: &[], +/// ad: &[], +/// hash_length: hash.len() as u32, +/// }; +/// let res = argon2::verify_raw(pwd, salt, hash, &config).unwrap(); +/// assert!(res); +/// ``` +#[deprecated(since = "0.2.0", note = "please use `verify_raw` instead")] +pub fn verify_raw_std( + variant: Variant, + version: Version, + mem_cost: u32, + time_cost: u32, + parallelism: u32, + pwd: &[u8], + salt: &[u8], + hash: &[u8], +) -> Result<bool> { + let config = Config { + variant: variant, + version: version, + mem_cost: mem_cost, + time_cost: time_cost, + lanes: parallelism, + thread_mode: ThreadMode::from_threads(parallelism), + secret: &[], + ad: &[], + hash_length: hash.len() as u32, + }; + verify_raw(pwd, salt, hash, &config) +} + +fn run(context: &Context) -> Vec<u8> { + let mut memory = Memory::new(context.config.lanes, context.lane_length); + core::initialize(context, &mut memory); + core::fill_memory_blocks(context, &mut memory); + core::finalize(context, &memory) +} |