From 32ae8f7051d091fe3a746b89646e97d7e6b029ed Mon Sep 17 00:00:00 2001 From: "Jan Winkelmann (keks)" Date: Mon, 24 Feb 2025 12:42:49 +0100 Subject: [PATCH] Rename hash selection enum to KeyedHash, restructure traits --- Cargo.lock | 2 +- cipher-traits/src/algorithms.rs | 20 +++++ cipher-traits/src/lib.rs | 8 +- cipher-traits/src/primitives.rs | 1 + .../src/{ => primitives}/keyed_hash.rs | 0 ciphers/src/hash_domain.rs | 82 +++++++++---------- ciphers/src/subtle/either_hash.rs | 55 +++++-------- .../hash_functions/incorrect_hmac_blake2b.rs | 2 +- .../subtle/hash_functions/infer_keyed_hash.rs | 6 +- .../subtle/hash_functions/keyed_shake256.rs | 8 +- rosenpass/src/hash_domains.rs | 14 ++-- rosenpass/src/protocol/protocol.rs | 82 ++++++++----------- 12 files changed, 144 insertions(+), 136 deletions(-) create mode 100644 cipher-traits/src/algorithms.rs create mode 100644 cipher-traits/src/primitives.rs rename cipher-traits/src/{ => primitives}/keyed_hash.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 4e6ec91..4934275 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" diff --git a/cipher-traits/src/algorithms.rs b/cipher-traits/src/algorithms.rs new file mode 100644 index 0000000..14ccdad --- /dev/null +++ b/cipher-traits/src/algorithms.rs @@ -0,0 +1,20 @@ +pub mod keyed_hash_blake2b { + use crate::primitives::keyed_hash::*; + + pub const KEY_LEN: usize = 32; + pub const OUT_LEN: usize = 32; + + pub trait KeyedHashBlake2b: KeyedHash {} +} + +pub mod keyed_hash_shake256 { + use crate::primitives::keyed_hash::*; + + pub const KEY_LEN: usize = 32; + pub const OUT_LEN: usize = 32; + + pub trait KeyedHashShake256: KeyedHash {} +} + +pub use keyed_hash_blake2b::KeyedHashBlake2b; +pub use keyed_hash_shake256::KeyedHashShake256; diff --git a/cipher-traits/src/lib.rs b/cipher-traits/src/lib.rs index f6059d9..a755325 100644 --- a/cipher-traits/src/lib.rs +++ b/cipher-traits/src/lib.rs @@ -1,4 +1,8 @@ +mod algorithms; +mod primitives; + +pub use algorithms::*; +pub use primitives::*; + mod kem; -mod keyed_hash; pub use kem::Kem; -pub use keyed_hash::*; diff --git a/cipher-traits/src/primitives.rs b/cipher-traits/src/primitives.rs new file mode 100644 index 0000000..4ea27d7 --- /dev/null +++ b/cipher-traits/src/primitives.rs @@ -0,0 +1 @@ +pub mod keyed_hash; diff --git a/cipher-traits/src/keyed_hash.rs b/cipher-traits/src/primitives/keyed_hash.rs similarity index 100% rename from cipher-traits/src/keyed_hash.rs rename to cipher-traits/src/primitives/keyed_hash.rs diff --git a/ciphers/src/hash_domain.rs b/ciphers/src/hash_domain.rs index 7c5c04f..a0f2412 100644 --- a/ciphers/src/hash_domain.rs +++ b/ciphers/src/hash_domain.rs @@ -1,66 +1,66 @@ +//! +//!```rust +//! # use rosenpass_ciphers::hash_domain::{HashDomain, HashDomainNamespace, SecretHashDomain, SecretHashDomainNamespace}; +//! use rosenpass_ciphers::subtle::either_hash::EitherShakeOrBlake; +//! use rosenpass_ciphers::subtle::keyed_shake256::SHAKE256Core; +//! use rosenpass_secret_memory::Secret; +//! # rosenpass_secret_memory::secret_policy_use_only_malloc_secrets(); +//! +//! const PROTOCOL_IDENTIFIER: &str = "MY_PROTOCOL:IDENTIFIER"; +//! // create use once hash domain for the protocol identifier +//! let mut hash_domain = HashDomain::zero(EitherShakeOrBlake::Left(SHAKE256Core)); +//! hash_domain = hash_domain.mix(PROTOCOL_IDENTIFIER.as_bytes())?; +//! // upgrade to reusable hash domain +//! let hash_domain_namespace: HashDomainNamespace = hash_domain.dup(); +//! // derive new key +//! let key_identifier = "my_key_identifier"; +//! let key = hash_domain_namespace.mix(key_identifier.as_bytes())?.into_value(); +//! // derive a new key based on a secret +//! const MY_SECRET_LEN: usize = 21; +//! let my_secret_bytes = "my super duper secret".as_bytes(); +//! let my_secret: Secret<21> = Secret::from_slice("my super duper secret".as_bytes()); +//! let secret_hash_domain: SecretHashDomain = hash_domain_namespace.mix_secret(my_secret)?; +//! // derive a new key based on the secret key +//! let new_key_identifier = "my_new_key_identifier".as_bytes(); +//! let new_key = secret_hash_domain.mix(new_key_identifier)?.into_secret(); +//! +//! # Ok::<(), anyhow::Error>(()) +//!``` +//! + use anyhow::Result; use rosenpass_secret_memory::Secret; use rosenpass_to::To; use crate::keyed_hash as hash; -use crate::subtle::either_hash::EitherShakeOrBlake; +use crate::subtle::either_hash::KeyedHash; pub use hash::KEY_LEN; -use rosenpass_cipher_traits::KeyedHashInstance; - -/// -///```rust -/// # use rosenpass_ciphers::hash_domain::{HashDomain, HashDomainNamespace, SecretHashDomain, SecretHashDomainNamespace}; -/// use rosenpass_ciphers::subtle::either_hash::EitherShakeOrBlake; -/// use rosenpass_ciphers::subtle::keyed_shake256::SHAKE256Core; -/// use rosenpass_secret_memory::Secret; -/// # rosenpass_secret_memory::secret_policy_use_only_malloc_secrets(); -/// -/// const PROTOCOL_IDENTIFIER: &str = "MY_PROTOCOL:IDENTIFIER"; -/// // create use once hash domain for the protocol identifier -/// let mut hash_domain = HashDomain::zero(EitherShakeOrBlake::Left(SHAKE256Core)); -/// hash_domain = hash_domain.mix(PROTOCOL_IDENTIFIER.as_bytes())?; -/// // upgrade to reusable hash domain -/// let hash_domain_namespace: HashDomainNamespace = hash_domain.dup(); -/// // derive new key -/// let key_identifier = "my_key_identifier"; -/// let key = hash_domain_namespace.mix(key_identifier.as_bytes())?.into_value(); -/// // derive a new key based on a secret -/// const MY_SECRET_LEN: usize = 21; -/// let my_secret_bytes = "my super duper secret".as_bytes(); -/// let my_secret: Secret<21> = Secret::from_slice("my super duper secret".as_bytes()); -/// let secret_hash_domain: SecretHashDomain = hash_domain_namespace.mix_secret(my_secret)?; -/// // derive a new key based on the secret key -/// let new_key_identifier = "my_new_key_identifier".as_bytes(); -/// let new_key = secret_hash_domain.mix(new_key_identifier)?.into_secret(); -/// -/// # Ok::<(), anyhow::Error>(()) -///``` -/// +use rosenpass_cipher_traits::keyed_hash::KeyedHashInstance; // TODO Use a proper Dec interface /// A use-once hash domain for a specified key that can be used directly. /// The key must consist of [KEY_LEN] many bytes. If the key must remain secret, /// use [SecretHashDomain] instead. #[derive(Clone, Debug)] -pub struct HashDomain([u8; KEY_LEN], EitherShakeOrBlake); +pub struct HashDomain([u8; KEY_LEN], KeyedHash); /// A reusable hash domain for a namespace identified by the key. /// The key must consist of [KEY_LEN] many bytes. If the key must remain secret, /// use [SecretHashDomainNamespace] instead. #[derive(Clone, Debug)] -pub struct HashDomainNamespace([u8; KEY_LEN], EitherShakeOrBlake); +pub struct HashDomainNamespace([u8; KEY_LEN], KeyedHash); /// A use-once hash domain for a specified key that can be used directly /// by wrapping it in [Secret]. The key must consist of [KEY_LEN] many bytes. #[derive(Clone, Debug)] -pub struct SecretHashDomain(Secret, EitherShakeOrBlake); +pub struct SecretHashDomain(Secret, KeyedHash); /// A reusable secure hash domain for a namespace identified by the key and that keeps the key secure /// by wrapping it in [Secret]. The key must consist of [KEY_LEN] many bytes. #[derive(Clone, Debug)] -pub struct SecretHashDomainNamespace(Secret, EitherShakeOrBlake); +pub struct SecretHashDomainNamespace(Secret, KeyedHash); impl HashDomain { /// Creates a nw [HashDomain] initialized with a all-zeros key. - pub fn zero(choice: EitherShakeOrBlake) -> Self { + pub fn zero(choice: KeyedHash) -> Self { Self([0u8; KEY_LEN], choice) } @@ -128,7 +128,7 @@ impl SecretHashDomain { pub fn invoke_primitive( k: &[u8], d: &[u8], - hash_choice: EitherShakeOrBlake, + hash_choice: KeyedHash, ) -> Result { let mut new_secret_key = Secret::zero(); hash_choice.keyed_hash(k.try_into()?, d, new_secret_key.secret_mut())?; @@ -138,7 +138,7 @@ impl SecretHashDomain { } /// Creates a new [SecretHashDomain] that is initialized with an all zeros key. - pub fn zero(hash_choice: EitherShakeOrBlake) -> Self { + pub fn zero(hash_choice: KeyedHash) -> Self { Self(Secret::zero(), hash_choice) } @@ -150,7 +150,7 @@ impl SecretHashDomain { /// Creates a new [SecretHashDomain] from a [Secret] `k`. /// /// It requires that `k` consist of exactly [KEY_LEN] bytes. - pub fn danger_from_secret(k: Secret, hash_choice: EitherShakeOrBlake) -> Self { + pub fn danger_from_secret(k: Secret, hash_choice: KeyedHash) -> Self { Self(k, hash_choice) } @@ -213,7 +213,7 @@ impl SecretHashDomainNamespace { self.0 } - pub fn shake_or_blake(&self) -> &EitherShakeOrBlake { + pub fn shake_or_blake(&self) -> &KeyedHash { &self.1 } } diff --git a/ciphers/src/subtle/either_hash.rs b/ciphers/src/subtle/either_hash.rs index e2d5549..86e3e82 100644 --- a/ciphers/src/subtle/either_hash.rs +++ b/ciphers/src/subtle/either_hash.rs @@ -1,27 +1,27 @@ -use crate::subtle::hash_functions::keyed_shake256::SHAKE256Core; -use crate::subtle::incorrect_hmac_blake2b::Blake2bCore; use anyhow::Result; -use rosenpass_cipher_traits::{KeyedHash, KeyedHashInstance}; +use rosenpass_cipher_traits::keyed_hash::KeyedHashInstance; -#[derive(Debug, Eq, PartialEq)] -pub enum EitherHash< - const KEY_LEN: usize, - const HASH_LEN: usize, - Error, - L: KeyedHash, - R: KeyedHash, -> { - Left(L), - Right(R), +pub const KEY_LEN: usize = 32; +pub const HASH_LEN: usize = 32; + +#[derive(Debug, Eq, PartialEq, Clone)] +pub enum KeyedHash { + KeyedShake256(super::hash_functions::keyed_shake256::SHAKE256), + IncorrectHmacBlake2b(super::hash_functions::incorrect_hmac_blake2b::Blake2b), } -impl KeyedHashInstance - for EitherHash -where - L: KeyedHash, - R: KeyedHash, -{ - type Error = Error; +impl KeyedHash { + pub fn keyed_shake256() -> Self { + Self::KeyedShake256(Default::default()) + } + + pub fn incorrect_hmac_blake2b() -> Self { + Self::IncorrectHmacBlake2b(Default::default()) + } +} + +impl KeyedHashInstance for KeyedHash { + type Error = anyhow::Error; fn keyed_hash( &self, @@ -30,19 +30,8 @@ where out: &mut [u8; HASH_LEN], ) -> Result<(), Self::Error> { match self { - Self::Left(_) => L::keyed_hash(key, data, out), - Self::Right(_) => R::keyed_hash(key, data, out), - } - } -} - -pub type EitherShakeOrBlake = EitherHash<32, 32, anyhow::Error, SHAKE256Core<32, 32>, Blake2bCore>; - -impl Clone for EitherShakeOrBlake { - fn clone(&self) -> Self { - match self { - Self::Left(l) => Self::Left(l.clone()), - Self::Right(r) => Self::Right(r.clone()), + Self::KeyedShake256(h) => h.keyed_hash(key, data, out), + Self::IncorrectHmacBlake2b(h) => h.keyed_hash(key, data, out), } } } diff --git a/ciphers/src/subtle/hash_functions/incorrect_hmac_blake2b.rs b/ciphers/src/subtle/hash_functions/incorrect_hmac_blake2b.rs index 50db959..c2bf64a 100644 --- a/ciphers/src/subtle/hash_functions/incorrect_hmac_blake2b.rs +++ b/ciphers/src/subtle/hash_functions/incorrect_hmac_blake2b.rs @@ -1,5 +1,5 @@ use anyhow::ensure; -use rosenpass_cipher_traits::KeyedHash; +use rosenpass_cipher_traits::keyed_hash::KeyedHash; use rosenpass_constant_time::xor; use rosenpass_to::{ops::copy_slice, with_destination, To}; use zeroize::Zeroizing; diff --git a/ciphers/src/subtle/hash_functions/infer_keyed_hash.rs b/ciphers/src/subtle/hash_functions/infer_keyed_hash.rs index 07183da..a84710b 100644 --- a/ciphers/src/subtle/hash_functions/infer_keyed_hash.rs +++ b/ciphers/src/subtle/hash_functions/infer_keyed_hash.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use rosenpass_cipher_traits::{KeyedHash, KeyedHashInstance}; +use rosenpass_cipher_traits::keyed_hash::{KeyedHash, KeyedHashInstance}; use std::marker::PhantomData; /// This is a helper to allow for type parameter inference when calling functions @@ -60,7 +60,7 @@ impl< } } -/// Helper traits ///////////////////////////////////////////// +// Helper traits ///////////////////////////////////////////// impl Default for InferKeyedHash @@ -78,7 +78,7 @@ where Static: KeyedHash, { fn clone(&self) -> Self { - Self::new() + *self } } diff --git a/ciphers/src/subtle/hash_functions/keyed_shake256.rs b/ciphers/src/subtle/hash_functions/keyed_shake256.rs index 60016c7..017a54c 100644 --- a/ciphers/src/subtle/hash_functions/keyed_shake256.rs +++ b/ciphers/src/subtle/hash_functions/keyed_shake256.rs @@ -1,6 +1,6 @@ use crate::subtle::hash_functions::infer_keyed_hash::InferKeyedHash; use anyhow::ensure; -use rosenpass_cipher_traits::KeyedHash; +use rosenpass_cipher_traits::keyed_hash::KeyedHash; use sha3::digest::{ExtendableOutput, Update, XofReader}; use sha3::Shake256; @@ -71,6 +71,12 @@ impl SHAKE256Core Default for SHAKE256Core { + fn default() -> Self { + Self::new() + } +} + /// TODO use inferred hash somehow here /// ```rust /// # use rosenpass_ciphers::subtle::keyed_shake256::{SHAKE256}; diff --git a/rosenpass/src/hash_domains.rs b/rosenpass/src/hash_domains.rs index bd95968..70c4a00 100644 --- a/rosenpass/src/hash_domains.rs +++ b/rosenpass/src/hash_domains.rs @@ -54,9 +54,7 @@ use anyhow::Result; use rosenpass_ciphers::hash_domain::HashDomain; -use rosenpass_ciphers::subtle::either_hash::EitherShakeOrBlake; -use rosenpass_ciphers::subtle::incorrect_hmac_blake2b::Blake2bCore; -use rosenpass_ciphers::subtle::keyed_shake256::SHAKE256Core; +use rosenpass_ciphers::subtle::either_hash::KeyedHash; /// Declare a hash function /// @@ -70,7 +68,7 @@ use rosenpass_ciphers::subtle::keyed_shake256::SHAKE256Core; macro_rules! hash_domain_ns { ($(#[$($attrss:tt)*])* $base:ident, $name:ident, $($lbl:expr),+ ) => { $(#[$($attrss)*])* - pub fn $name(hash_choice: EitherShakeOrBlake) -> ::anyhow::Result<::rosenpass_ciphers::hash_domain::HashDomain> { + pub fn $name(hash_choice: KeyedHash) -> ::anyhow::Result<::rosenpass_ciphers::hash_domain::HashDomain> { let t = $base(hash_choice)?; $( let t = t.mix($lbl.as_bytes())?; )* Ok(t) @@ -89,7 +87,7 @@ macro_rules! hash_domain_ns { macro_rules! hash_domain { ($(#[$($attrss:tt)*])* $base:ident, $name:ident, $($lbl:expr),+ ) => { $(#[$($attrss)*])* - pub fn $name(hash_choice: EitherShakeOrBlake) -> ::anyhow::Result<[u8; ::rosenpass_ciphers::KEY_LEN]> { + pub fn $name(hash_choice: KeyedHash) -> ::anyhow::Result<[u8; ::rosenpass_ciphers::KEY_LEN]> { let t = $base(hash_choice)?; $( let t = t.mix($lbl.as_bytes())?; )* Ok(t.into_value()) @@ -111,12 +109,12 @@ macro_rules! hash_domain { /// See the source file for details about how this is used concretely. /// /// See the [module](self) documentation on how to use the hash domains in general -pub fn protocol(hash_choice: EitherShakeOrBlake) -> Result { +pub fn protocol(hash_choice: KeyedHash) -> Result { // TODO: Update this string that is mixed in? match hash_choice { - EitherShakeOrBlake::Left(SHAKE256Core) => HashDomain::zero(hash_choice) + KeyedHash::KeyedShake256(_) => HashDomain::zero(hash_choice) .mix("Rosenpass v1 mceliece460896 Kyber512 ChaChaPoly1305 SHAKE256".as_bytes()), - EitherShakeOrBlake::Right(Blake2bCore) => HashDomain::zero(hash_choice) + KeyedHash::IncorrectHmacBlake2b(_) => HashDomain::zero(hash_choice) .mix("Rosenpass v1 mceliece460896 Kyber512 ChaChaPoly1305 Blake2b".as_bytes()), } } diff --git a/rosenpass/src/protocol/protocol.rs b/rosenpass/src/protocol/protocol.rs index 380ea56..61ffb80 100644 --- a/rosenpass/src/protocol/protocol.rs +++ b/rosenpass/src/protocol/protocol.rs @@ -25,9 +25,7 @@ use rosenpass_cipher_traits::Kem; use rosenpass_ciphers::hash_domain::{SecretHashDomain, SecretHashDomainNamespace}; use rosenpass_ciphers::kem::{EphemeralKem, StaticKem}; use rosenpass_ciphers::keyed_hash; -use rosenpass_ciphers::subtle::either_hash::EitherShakeOrBlake; -use rosenpass_ciphers::subtle::incorrect_hmac_blake2b::Blake2bCore; -use rosenpass_ciphers::subtle::keyed_shake256::SHAKE256Core; +use rosenpass_ciphers::subtle::either_hash::KeyedHash; use rosenpass_ciphers::{aead, xaead, KEY_LEN}; use rosenpass_constant_time as constant_time; use rosenpass_secret_memory::{Public, PublicBox, Secret}; @@ -373,10 +371,10 @@ pub enum ProtocolVersion { } impl ProtocolVersion { - pub fn shake_or_blake(&self) -> EitherShakeOrBlake { + pub fn shake_or_blake(&self) -> KeyedHash { match self { - ProtocolVersion::V02 => EitherShakeOrBlake::Right(Blake2bCore), - ProtocolVersion::V03 => EitherShakeOrBlake::Left(SHAKE256Core), + ProtocolVersion::V02 => KeyedHash::incorrect_hmac_blake2b(), + ProtocolVersion::V03 => KeyedHash::keyed_shake256(), } } } @@ -505,7 +503,7 @@ impl Peer { initiation_requested: false, handshake: None, known_init_conf_response: None, - protocol_version: protocol_version, + protocol_version, } } } @@ -1418,7 +1416,7 @@ impl CryptoServer { /// Calculate the peer ID of this CryptoServer #[rustfmt::skip] - pub fn pidm(&self, shake_or_blake: EitherShakeOrBlake) -> Result { + pub fn pidm(&self, shake_or_blake: KeyedHash) -> Result { Ok(Public::new( hash_domains::peerid(shake_or_blake)? .mix(self.spkm.deref())? @@ -1474,7 +1472,7 @@ impl CryptoServer { handshake: None, known_init_conf_response: None, initiation_requested: false, - protocol_version: protocol_version, + protocol_version, }; let peerid = peer.pidt()?; let peerno = self.peers.len(); @@ -1671,7 +1669,7 @@ impl Peer { handshake: None, known_init_conf_response: None, initiation_requested: false, - protocol_version: protocol_version, + protocol_version, } } @@ -1702,11 +1700,11 @@ impl Session { /// /// rosenpass_secret_memory::secret_policy_try_use_memfd_secrets(); /// - /// let s = Session::zero(EitherShakeOrBlake::Left(SHAKE256Core)); + /// let s = Session::zero(EitherShakeOrBlake::keyed_shake256()); /// assert_eq!(s.created_at, 0.0); /// assert_eq!(s.handshake_role, HandshakeRole::Initiator); /// ``` - pub fn zero(shake_or_blake: EitherShakeOrBlake) -> Self { + pub fn zero(shake_or_blake: KeyedHash) -> Self { Self { created_at: 0.0, sidm: SessionId::zero(), @@ -2177,7 +2175,7 @@ impl CryptoServer { let cookie_secret = cookie_secret.get(self).value.secret(); let mut cookie_value = [0u8; 16]; cookie_value.copy_from_slice( - &hash_domains::cookie_value(EitherShakeOrBlake::Left(SHAKE256Core))? + &hash_domains::cookie_value(KeyedHash::keyed_shake256())? .mix(cookie_secret)? .mix(host_identification.encode())? .into_value()[..16], @@ -2193,7 +2191,7 @@ impl CryptoServer { let msg_in = Ref::<&[u8], Envelope>::new(rx_buf) .ok_or(RosenpassError::BufferSizeMismatch)?; expected.copy_from_slice( - &hash_domains::cookie(EitherShakeOrBlake::Left(SHAKE256Core))? + &hash_domains::cookie(KeyedHash::keyed_shake256())? .mix(&cookie_value)? .mix(&msg_in.as_bytes()[span_of!(Envelope, msg_type..cookie)])? .into_value()[..16], @@ -2230,7 +2228,7 @@ impl CryptoServer { ); let cookie_value = active_cookie_value.unwrap(); - let cookie_key = hash_domains::cookie_key(EitherShakeOrBlake::Left(SHAKE256Core))? + let cookie_key = hash_domains::cookie_key(KeyedHash::keyed_shake256())? .mix(self.spkm.deref())? .into_value(); @@ -2322,18 +2320,18 @@ impl CryptoServer { let peer_shake256 = self.handle_init_hello( &msg_in.payload, &mut msg_out.payload, - EitherShakeOrBlake::Left(SHAKE256Core), + KeyedHash::keyed_shake256(), ); let (peer, peer_hash_choice) = match peer_shake256 { - Ok(peer) => (peer, EitherShakeOrBlake::Left(SHAKE256Core)), + Ok(peer) => (peer, KeyedHash::keyed_shake256()), Err(_) => { let peer_blake2b = self.handle_init_hello( &msg_in.payload, &mut msg_out.payload, - EitherShakeOrBlake::Right(Blake2bCore), + KeyedHash::incorrect_hmac_blake2b(), ); match peer_blake2b { - Ok(peer) => (peer, EitherShakeOrBlake::Right(Blake2bCore)), + Ok(peer) => (peer, KeyedHash::incorrect_hmac_blake2b()), Err(_) => bail!("No valid hash function found for InitHello"), } } @@ -2398,18 +2396,18 @@ impl CryptoServer { let peer_shake256 = self.handle_init_conf( &msg_in.payload, &mut msg_out.payload, - EitherShakeOrBlake::Left(SHAKE256Core), + KeyedHash::keyed_shake256(), ); let (peer, peer_hash_choice) = match peer_shake256 { - Ok(peer) => (peer, EitherShakeOrBlake::Left(SHAKE256Core)), + Ok(peer) => (peer, KeyedHash::keyed_shake256()), Err(_) => { let peer_blake2b = self.handle_init_conf( &msg_in.payload, &mut msg_out.payload, - EitherShakeOrBlake::Right(Blake2bCore), + KeyedHash::incorrect_hmac_blake2b(), ); match peer_blake2b { - Ok(peer) => (peer, EitherShakeOrBlake::Right(Blake2bCore)), + Ok(peer) => (peer, KeyedHash::incorrect_hmac_blake2b()), Err(_) => bail!("No valid hash function found for InitHello"), } } @@ -2459,19 +2457,15 @@ impl CryptoServer { } /// TODO documentation - fn verify_hash_choice_match( - &self, - peer: PeerPtr, - peer_hash_choice: EitherShakeOrBlake, - ) -> Result<()> { + fn verify_hash_choice_match(&self, peer: PeerPtr, peer_hash_choice: KeyedHash) -> Result<()> { match peer.get(self).protocol_version.shake_or_blake() { - EitherShakeOrBlake::Left(SHAKE256Core) => match peer_hash_choice { - EitherShakeOrBlake::Left(SHAKE256Core) => Ok(()), - EitherShakeOrBlake::Right(Blake2bCore) => bail!("Hash function mismatch"), + KeyedHash::KeyedShake256(_) => match peer_hash_choice { + KeyedHash::KeyedShake256(_) => Ok(()), + KeyedHash::IncorrectHmacBlake2b(_) => bail!("Hash function mismatch"), }, - EitherShakeOrBlake::Right(Blake2bCore) => match peer_hash_choice { - EitherShakeOrBlake::Left(SHAKE256Core) => bail!("Hash function mismatch"), - EitherShakeOrBlake::Right(Blake2bCore) => Ok(()), + KeyedHash::IncorrectHmacBlake2b(_) => match peer_hash_choice { + KeyedHash::KeyedShake256(_) => bail!("Hash function mismatch"), + KeyedHash::IncorrectHmacBlake2b(_) => Ok(()), }, } } @@ -3242,11 +3236,7 @@ where M: AsBytes + FromBytes, { /// Internal business logic: Check the message authentication code produced by [Self::seal] - pub fn check_seal( - &self, - srv: &CryptoServer, - shake_or_blake: EitherShakeOrBlake, - ) -> Result { + pub fn check_seal(&self, srv: &CryptoServer, shake_or_blake: KeyedHash) -> Result { let expected = hash_domains::mac(shake_or_blake)? .mix(srv.spkm.deref())? .mix(&self.as_bytes()[span_of!(Self, msg_type..mac)])?; @@ -3259,7 +3249,7 @@ where impl InitiatorHandshake { /// Zero initialization of an InitiatorHandshake, with up to date timestamp - pub fn zero_with_timestamp(srv: &CryptoServer, shake_or_blake: EitherShakeOrBlake) -> Self { + pub fn zero_with_timestamp(srv: &CryptoServer, shake_or_blake: KeyedHash) -> Self { InitiatorHandshake { created_at: srv.timebase.now(), next: HandshakeStateMachine::RespHello, @@ -3278,7 +3268,7 @@ impl InitiatorHandshake { impl HandshakeState { /// Zero initialization of an HandshakeState - pub fn zero(shake_or_blake: EitherShakeOrBlake) -> Self { + pub fn zero(shake_or_blake: KeyedHash) -> Self { Self { sidi: SessionId::zero(), sidr: SessionId::zero(), @@ -3423,7 +3413,7 @@ impl HandshakeState { biscuit_ct: &[u8], sidi: SessionId, sidr: SessionId, - shake_or_blake: EitherShakeOrBlake, + shake_or_blake: KeyedHash, ) -> Result<(PeerPtr, BiscuitId, HandshakeState)> { // The first bit of the biscuit indicates which biscuit key was used let bk = BiscuitKeyPtr(((biscuit_ct[0] & 0b1000_0000) >> 7) as usize); @@ -3475,7 +3465,7 @@ impl HandshakeState { self, srv: &CryptoServer, role: HandshakeRole, - either_shake_or_blake: EitherShakeOrBlake, + either_shake_or_blake: KeyedHash, ) -> Result { let HandshakeState { ck, sidi, sidr } = self; let tki = ck @@ -3588,7 +3578,7 @@ impl CryptoServer { &mut self, ih: &InitHello, rh: &mut RespHello, - shake_or_blake: EitherShakeOrBlake, + shake_or_blake: KeyedHash, ) -> Result { let mut core = HandshakeState::zero(shake_or_blake); @@ -3758,7 +3748,7 @@ impl CryptoServer { &mut self, ic: &InitConf, rc: &mut EmptyData, - shake_or_blake: EitherShakeOrBlake, + shake_or_blake: KeyedHash, ) -> Result { // (peer, bn) ← LoadBiscuit(InitConf.biscuit) // ICR1 @@ -3943,7 +3933,7 @@ impl CryptoServer { }?; let spkt = peer.get(self).spkt.deref(); - let cookie_key = hash_domains::cookie_key(EitherShakeOrBlake::Left(SHAKE256Core))? + let cookie_key = hash_domains::cookie_key(KeyedHash::keyed_shake256())? .mix(spkt)? .into_value(); let cookie_value = peer.cv().update_mut(self).unwrap();