From bb63e6cd612ea78d8e006caff3c101fa49d8838c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 6 Aug 2023 18:24:19 -0600 Subject: [PATCH] Revert "argon2: improve `const` compatibility (#438)" This reverts commit 5e3f574c96a3c6aa6ddffdfeb323edb3b400f2d7. These changes are incompatible with #440, which performs runtime CPU feature detection. --- argon2/src/algorithm.rs | 10 ++-- argon2/src/lib.rs | 11 ++--- argon2/src/params.rs | 104 +++++++++++++--------------------------- argon2/src/version.rs | 6 +-- 4 files changed, 43 insertions(+), 88 deletions(-) diff --git a/argon2/src/algorithm.rs b/argon2/src/algorithm.rs index 23a1a322..4efe86b5 100644 --- a/argon2/src/algorithm.rs +++ b/argon2/src/algorithm.rs @@ -52,20 +52,18 @@ pub enum Algorithm { impl Default for Algorithm { fn default() -> Algorithm { - Algorithm::DEFAULT + Algorithm::Argon2id } } impl Algorithm { - /// Default Algorithm (recommended). - pub const DEFAULT: Algorithm = Algorithm::Argon2id; /// Parse an [`Algorithm`] from the provided string. pub fn new(id: impl AsRef) -> Result { id.as_ref().parse() } /// Get the identifier string for this PBKDF2 [`Algorithm`]. - pub const fn as_str(&self) -> &'static str { + pub fn as_str(&self) -> &'static str { match self { Algorithm::Argon2d => "argon2d", Algorithm::Argon2i => "argon2i", @@ -76,7 +74,7 @@ impl Algorithm { /// Get the [`Ident`] that corresponds to this Argon2 [`Algorithm`]. #[cfg(feature = "password-hash")] #[cfg_attr(docsrs, doc(cfg(feature = "password-hash")))] - pub const fn ident(&self) -> Ident<'static> { + pub fn ident(&self) -> Ident<'static> { match self { Algorithm::Argon2d => ARGON2D_IDENT, Algorithm::Argon2i => ARGON2I_IDENT, @@ -85,7 +83,7 @@ impl Algorithm { } /// Serialize primitive type as little endian bytes - pub(crate) const fn to_le_bytes(self) -> [u8; 4] { + pub(crate) fn to_le_bytes(self) -> [u8; 4] { (self as u32).to_le_bytes() } } diff --git a/argon2/src/lib.rs b/argon2/src/lib.rs index 608efbb4..458265d5 100644 --- a/argon2/src/lib.rs +++ b/argon2/src/lib.rs @@ -175,7 +175,7 @@ pub struct Argon2<'key> { impl Default for Argon2<'_> { fn default() -> Self { - Self::DEFAULT + Self::new(Algorithm::default(), Version::default(), Params::default()) } } @@ -190,11 +190,8 @@ impl fmt::Debug for Argon2<'_> { } impl<'key> Argon2<'key> { - /// Default parameters (recommended). - pub const DEFAULT: Argon2<'static> = - Argon2::new(Algorithm::DEFAULT, Version::DEFAULT, Params::DEFAULT); /// Create a new Argon2 context. - pub const fn new(algorithm: Algorithm, version: Version, params: Params) -> Self { + pub fn new(algorithm: Algorithm, version: Version, params: Params) -> Self { Self { algorithm, version, @@ -473,7 +470,7 @@ impl<'key> Argon2<'key> { } /// Get default configured [`Params`]. - pub const fn params(&self) -> &Params { + pub fn params(&self) -> &Params { &self.params } @@ -534,7 +531,7 @@ impl<'key> Argon2<'key> { digest.finalize() } - const fn verify_inputs(pwd: &[u8], salt: &[u8]) -> Result<()> { + fn verify_inputs(pwd: &[u8], salt: &[u8]) -> Result<()> { if pwd.len() > MAX_PWD_LEN { return Err(Error::PwdTooLong); } diff --git a/argon2/src/params.rs b/argon2/src/params.rs index fbbfb735..9db5a3f5 100644 --- a/argon2/src/params.rs +++ b/argon2/src/params.rs @@ -104,33 +104,36 @@ impl Params { /// - `t_cost`: number of iterations. Between 1 and (2^32)-1. /// - `p_cost`: degree of parallelism. Between 1 and 255. /// - `output_len`: size of the KDF output in bytes. Default 32. - pub const fn new( - m_cost: u32, - t_cost: u32, - p_cost: u32, - output_len: Option, - ) -> Result { - ParamsBuilder::new_params(m_cost, t_cost, p_cost, None, None, output_len).build() + pub fn new(m_cost: u32, t_cost: u32, p_cost: u32, output_len: Option) -> Result { + let mut builder = ParamsBuilder::new(); + + builder.m_cost(m_cost).t_cost(t_cost).p_cost(p_cost); + + if let Some(len) = output_len { + builder.output_len(len); + } + + builder.build() } /// Memory size, expressed in kibibytes. Between 1 and (2^32)-1. /// /// Value is an integer in decimal (1 to 10 digits). - pub const fn m_cost(&self) -> u32 { + pub fn m_cost(&self) -> u32 { self.m_cost } /// Number of iterations. Between 1 and (2^32)-1. /// /// Value is an integer in decimal (1 to 10 digits). - pub const fn t_cost(&self) -> u32 { + pub fn t_cost(&self) -> u32 { self.t_cost } /// Degree of parallelism. Between 1 and 255. /// /// Value is an integer in decimal (1 to 3 digits). - pub const fn p_cost(&self) -> u32 { + pub fn p_cost(&self) -> u32 { self.p_cost } @@ -161,25 +164,25 @@ impl Params { } /// Length of the output (in bytes). - pub const fn output_len(&self) -> Option { + pub fn output_len(&self) -> Option { self.output_len } /// Get the number of lanes. #[allow(clippy::cast_possible_truncation)] - pub(crate) const fn lanes(&self) -> usize { + pub(crate) fn lanes(&self) -> usize { self.p_cost as usize } /// Get the number of blocks in a lane. - pub(crate) const fn lane_length(&self) -> usize { + pub(crate) fn lane_length(&self) -> usize { self.segment_length() * SYNC_POINTS } /// Get the segment length given the configured `m_cost` and `p_cost`. /// /// Minimum memory_blocks = 8*`L` blocks, where `L` is the number of lanes. - pub(crate) const fn segment_length(&self) -> usize { + pub(crate) fn segment_length(&self) -> usize { let m_cost = self.m_cost as usize; let memory_blocks = if m_cost < 2 * SYNC_POINTS * self.lanes() { @@ -192,7 +195,7 @@ impl Params { } /// Get the number of blocks required given the configured `m_cost` and `p_cost`. - pub const fn block_count(&self) -> usize { + pub fn block_count(&self) -> usize { self.segment_length() * self.lanes() * SYNC_POINTS } } @@ -214,6 +217,7 @@ macro_rules! param_buf { /// Length of byte array len: usize, } + impl $ty { /// Maximum length in bytes pub const MAX_LEN: usize = $max_len; @@ -229,12 +233,6 @@ macro_rules! param_buf { Ok(Self { bytes, len }) } - /// Empty value. - pub const EMPTY: Self = Self { - bytes: [0u8; Self::MAX_LEN], - len: 0, - }; - #[doc = "Decode"] #[doc = $name] #[doc = " from a B64 string"] @@ -251,12 +249,12 @@ macro_rules! param_buf { } /// Get the length in bytes. - pub const fn len(&self) -> usize { + pub fn len(&self) -> usize { self.len } /// Is this value empty? - pub const fn is_empty(&self) -> bool { + pub fn is_empty(&self) -> bool { self.len() == 0 } } @@ -386,27 +384,8 @@ pub struct ParamsBuilder { impl ParamsBuilder { /// Create a new builder with the default parameters. - pub const fn new() -> Self { - Self::DEFAULT - } - /// Create a new builder with the provided parameters. - /// This function exists to allow for const construction of ParamsBuilder with custom parameters. - pub const fn new_params( - m_cost: u32, - t_cost: u32, - p_cost: u32, - keyid: Option, - data: Option, - output_len: Option, - ) -> Self { - Self { - m_cost, - t_cost, - p_cost, - keyid, - data, - output_len, - } + pub fn new() -> Self { + Self::default() } /// Set memory size, expressed in kibibytes, between 1 and (2^32)-1. @@ -449,7 +428,7 @@ impl ParamsBuilder { /// /// This performs validations to ensure that the given parameters are valid /// and compatible with each other, and will return an error if they are not. - pub const fn build(&self) -> Result { + pub fn build(&self) -> Result { if self.m_cost < Params::MIN_M_COST { return Err(Error::MemoryTooLittle); } @@ -486,15 +465,9 @@ impl ParamsBuilder { } } - let keyid = match self.keyid { - Some(keyid) => keyid, - None => KeyId::EMPTY, - }; + let keyid = self.keyid.unwrap_or_default(); - let data = match self.data { - Some(data) => data, - None => AssociatedData::EMPTY, - }; + let data = self.data.unwrap_or_default(); let params = Params { m_cost: self.m_cost, @@ -509,19 +482,14 @@ impl ParamsBuilder { } /// Create a new [`Argon2`] context using the provided algorithm/version. - pub const fn context(&self, algorithm: Algorithm, version: Version) -> Result> { - Ok(Argon2::new( - algorithm, - version, - match self.build() { - Ok(params) => params, - Err(e) => return Err(e), - }, - )) + pub fn context(&self, algorithm: Algorithm, version: Version) -> Result> { + Ok(Argon2::new(algorithm, version, self.build()?)) } - /// Default parameters (recommended). - pub const DEFAULT: ParamsBuilder = { - let params = Params::DEFAULT; +} + +impl Default for ParamsBuilder { + fn default() -> Self { + let params = Params::default(); Self { m_cost: params.m_cost, t_cost: params.t_cost, @@ -530,12 +498,6 @@ impl ParamsBuilder { data: None, output_len: params.output_len, } - }; -} - -impl Default for ParamsBuilder { - fn default() -> Self { - Self::DEFAULT } } diff --git a/argon2/src/version.rs b/argon2/src/version.rs index 4c85592e..a8b0ef5a 100644 --- a/argon2/src/version.rs +++ b/argon2/src/version.rs @@ -18,17 +18,15 @@ pub enum Version { } impl Version { - /// Default Version (recommended). - pub const DEFAULT: Version = Version::V0x13; /// Serialize version as little endian bytes - pub(crate) const fn to_le_bytes(self) -> [u8; 4] { + pub(crate) fn to_le_bytes(self) -> [u8; 4] { (self as u32).to_le_bytes() } } impl Default for Version { fn default() -> Self { - Self::DEFAULT + Self::V0x13 } }