mirror of
https://github.com/rosenpass/rosenpass.git
synced 2026-02-28 06:23:08 -08:00
Rename hash selection enum to KeyedHash, restructure traits
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
|
|||||||
20
cipher-traits/src/algorithms.rs
Normal file
20
cipher-traits/src/algorithms.rs
Normal file
@@ -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<KEY_LEN, OUT_LEN> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
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<KEY_LEN, OUT_LEN> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use keyed_hash_blake2b::KeyedHashBlake2b;
|
||||||
|
pub use keyed_hash_shake256::KeyedHashShake256;
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
|
mod algorithms;
|
||||||
|
mod primitives;
|
||||||
|
|
||||||
|
pub use algorithms::*;
|
||||||
|
pub use primitives::*;
|
||||||
|
|
||||||
mod kem;
|
mod kem;
|
||||||
mod keyed_hash;
|
|
||||||
pub use kem::Kem;
|
pub use kem::Kem;
|
||||||
pub use keyed_hash::*;
|
|
||||||
|
|||||||
1
cipher-traits/src/primitives.rs
Normal file
1
cipher-traits/src/primitives.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod keyed_hash;
|
||||||
@@ -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 anyhow::Result;
|
||||||
use rosenpass_secret_memory::Secret;
|
use rosenpass_secret_memory::Secret;
|
||||||
use rosenpass_to::To;
|
use rosenpass_to::To;
|
||||||
|
|
||||||
use crate::keyed_hash as hash;
|
use crate::keyed_hash as hash;
|
||||||
|
|
||||||
use crate::subtle::either_hash::EitherShakeOrBlake;
|
use crate::subtle::either_hash::KeyedHash;
|
||||||
pub use hash::KEY_LEN;
|
pub use hash::KEY_LEN;
|
||||||
use rosenpass_cipher_traits::KeyedHashInstance;
|
use rosenpass_cipher_traits::keyed_hash::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>(())
|
|
||||||
///```
|
|
||||||
///
|
|
||||||
|
|
||||||
// TODO Use a proper Dec interface
|
// TODO Use a proper Dec interface
|
||||||
/// A use-once hash domain for a specified key that can be used directly.
|
/// 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,
|
/// The key must consist of [KEY_LEN] many bytes. If the key must remain secret,
|
||||||
/// use [SecretHashDomain] instead.
|
/// use [SecretHashDomain] instead.
|
||||||
#[derive(Clone, Debug)]
|
#[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.
|
/// 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,
|
/// The key must consist of [KEY_LEN] many bytes. If the key must remain secret,
|
||||||
/// use [SecretHashDomainNamespace] instead.
|
/// use [SecretHashDomainNamespace] instead.
|
||||||
#[derive(Clone, Debug)]
|
#[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
|
/// 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.
|
/// by wrapping it in [Secret]. The key must consist of [KEY_LEN] many bytes.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SecretHashDomain(Secret<KEY_LEN>, EitherShakeOrBlake);
|
pub struct SecretHashDomain(Secret<KEY_LEN>, KeyedHash);
|
||||||
/// A reusable secure hash domain for a namespace identified by the key and that keeps the key secure
|
/// 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.
|
/// by wrapping it in [Secret]. The key must consist of [KEY_LEN] many bytes.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SecretHashDomainNamespace(Secret<KEY_LEN>, EitherShakeOrBlake);
|
pub struct SecretHashDomainNamespace(Secret<KEY_LEN>, KeyedHash);
|
||||||
|
|
||||||
impl HashDomain {
|
impl HashDomain {
|
||||||
/// Creates a nw [HashDomain] initialized with a all-zeros key.
|
/// 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)
|
Self([0u8; KEY_LEN], choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ impl SecretHashDomain {
|
|||||||
pub fn invoke_primitive(
|
pub fn invoke_primitive(
|
||||||
k: &[u8],
|
k: &[u8],
|
||||||
d: &[u8],
|
d: &[u8],
|
||||||
hash_choice: EitherShakeOrBlake,
|
hash_choice: KeyedHash,
|
||||||
) -> Result<SecretHashDomain> {
|
) -> Result<SecretHashDomain> {
|
||||||
let mut new_secret_key = Secret::zero();
|
let mut new_secret_key = Secret::zero();
|
||||||
hash_choice.keyed_hash(k.try_into()?, d, new_secret_key.secret_mut())?;
|
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.
|
/// 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)
|
Self(Secret::zero(), hash_choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ impl SecretHashDomain {
|
|||||||
/// Creates a new [SecretHashDomain] from a [Secret] `k`.
|
/// Creates a new [SecretHashDomain] from a [Secret] `k`.
|
||||||
///
|
///
|
||||||
/// It requires that `k` consist of exactly [KEY_LEN] bytes.
|
/// It requires that `k` consist of exactly [KEY_LEN] bytes.
|
||||||
pub fn danger_from_secret(k: Secret<KEY_LEN>, hash_choice: EitherShakeOrBlake) -> Self {
|
pub fn danger_from_secret(k: Secret<KEY_LEN>, hash_choice: KeyedHash) -> Self {
|
||||||
Self(k, hash_choice)
|
Self(k, hash_choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ impl SecretHashDomainNamespace {
|
|||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shake_or_blake(&self) -> &EitherShakeOrBlake {
|
pub fn shake_or_blake(&self) -> &KeyedHash {
|
||||||
&self.1
|
&self.1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
use crate::subtle::hash_functions::keyed_shake256::SHAKE256Core;
|
|
||||||
use crate::subtle::incorrect_hmac_blake2b::Blake2bCore;
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use rosenpass_cipher_traits::{KeyedHash, KeyedHashInstance};
|
use rosenpass_cipher_traits::keyed_hash::KeyedHashInstance;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
pub const KEY_LEN: usize = 32;
|
||||||
pub enum EitherHash<
|
pub const HASH_LEN: usize = 32;
|
||||||
const KEY_LEN: usize,
|
|
||||||
const HASH_LEN: usize,
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
Error,
|
pub enum KeyedHash {
|
||||||
L: KeyedHash<KEY_LEN, HASH_LEN, Error = Error>,
|
KeyedShake256(super::hash_functions::keyed_shake256::SHAKE256<KEY_LEN, HASH_LEN>),
|
||||||
R: KeyedHash<KEY_LEN, HASH_LEN, Error = Error>,
|
IncorrectHmacBlake2b(super::hash_functions::incorrect_hmac_blake2b::Blake2b),
|
||||||
> {
|
|
||||||
Left(L),
|
|
||||||
Right(R),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const KEY_LEN: usize, const HASH_LEN: usize, Error, L, R> KeyedHashInstance<KEY_LEN, HASH_LEN>
|
impl KeyedHash {
|
||||||
for EitherHash<KEY_LEN, HASH_LEN, Error, L, R>
|
pub fn keyed_shake256() -> Self {
|
||||||
where
|
Self::KeyedShake256(Default::default())
|
||||||
L: KeyedHash<KEY_LEN, HASH_LEN, Error = Error>,
|
}
|
||||||
R: KeyedHash<KEY_LEN, HASH_LEN, Error = Error>,
|
|
||||||
{
|
pub fn incorrect_hmac_blake2b() -> Self {
|
||||||
type Error = Error;
|
Self::IncorrectHmacBlake2b(Default::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyedHashInstance<KEY_LEN, HASH_LEN> for KeyedHash {
|
||||||
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
fn keyed_hash(
|
fn keyed_hash(
|
||||||
&self,
|
&self,
|
||||||
@@ -30,19 +30,8 @@ where
|
|||||||
out: &mut [u8; HASH_LEN],
|
out: &mut [u8; HASH_LEN],
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::Left(_) => L::keyed_hash(key, data, out),
|
Self::KeyedShake256(h) => h.keyed_hash(key, data, out),
|
||||||
Self::Right(_) => R::keyed_hash(key, data, out),
|
Self::IncorrectHmacBlake2b(h) => h.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()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
use rosenpass_cipher_traits::KeyedHash;
|
use rosenpass_cipher_traits::keyed_hash::KeyedHash;
|
||||||
use rosenpass_constant_time::xor;
|
use rosenpass_constant_time::xor;
|
||||||
use rosenpass_to::{ops::copy_slice, with_destination, To};
|
use rosenpass_to::{ops::copy_slice, with_destination, To};
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use rosenpass_cipher_traits::{KeyedHash, KeyedHashInstance};
|
use rosenpass_cipher_traits::keyed_hash::{KeyedHash, KeyedHashInstance};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
/// This is a helper to allow for type parameter inference when calling functions
|
/// This is a helper to allow for type parameter inference when calling functions
|
||||||
@@ -60,7 +60,7 @@ impl<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper traits /////////////////////////////////////////////
|
// Helper traits /////////////////////////////////////////////
|
||||||
|
|
||||||
impl<Static, const KEY_LEN: usize, const OUT_LEN: usize> Default
|
impl<Static, const KEY_LEN: usize, const OUT_LEN: usize> Default
|
||||||
for InferKeyedHash<Static, KEY_LEN, OUT_LEN>
|
for InferKeyedHash<Static, KEY_LEN, OUT_LEN>
|
||||||
@@ -78,7 +78,7 @@ where
|
|||||||
Static: KeyedHash<KEY_LEN, OUT_LEN, Error = anyhow::Error>,
|
Static: KeyedHash<KEY_LEN, OUT_LEN, Error = anyhow::Error>,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self::new()
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::subtle::hash_functions::infer_keyed_hash::InferKeyedHash;
|
use crate::subtle::hash_functions::infer_keyed_hash::InferKeyedHash;
|
||||||
use anyhow::ensure;
|
use anyhow::ensure;
|
||||||
use rosenpass_cipher_traits::KeyedHash;
|
use rosenpass_cipher_traits::keyed_hash::KeyedHash;
|
||||||
use sha3::digest::{ExtendableOutput, Update, XofReader};
|
use sha3::digest::{ExtendableOutput, Update, XofReader};
|
||||||
use sha3::Shake256;
|
use sha3::Shake256;
|
||||||
|
|
||||||
@@ -71,6 +71,12 @@ impl<const KEY_LEN: usize, const HASH_LEN: usize> SHAKE256Core<KEY_LEN, HASH_LEN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const KEY_LEN: usize, const HASH_LEN: usize> Default for SHAKE256Core<KEY_LEN, HASH_LEN> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// TODO use inferred hash somehow here
|
/// TODO use inferred hash somehow here
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use rosenpass_ciphers::subtle::keyed_shake256::{SHAKE256};
|
/// # use rosenpass_ciphers::subtle::keyed_shake256::{SHAKE256};
|
||||||
|
|||||||
@@ -54,9 +54,7 @@
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use rosenpass_ciphers::hash_domain::HashDomain;
|
use rosenpass_ciphers::hash_domain::HashDomain;
|
||||||
use rosenpass_ciphers::subtle::either_hash::EitherShakeOrBlake;
|
use rosenpass_ciphers::subtle::either_hash::KeyedHash;
|
||||||
use rosenpass_ciphers::subtle::incorrect_hmac_blake2b::Blake2bCore;
|
|
||||||
use rosenpass_ciphers::subtle::keyed_shake256::SHAKE256Core;
|
|
||||||
|
|
||||||
/// Declare a hash function
|
/// Declare a hash function
|
||||||
///
|
///
|
||||||
@@ -70,7 +68,7 @@ use rosenpass_ciphers::subtle::keyed_shake256::SHAKE256Core;
|
|||||||
macro_rules! hash_domain_ns {
|
macro_rules! hash_domain_ns {
|
||||||
($(#[$($attrss:tt)*])* $base:ident, $name:ident, $($lbl:expr),+ ) => {
|
($(#[$($attrss:tt)*])* $base:ident, $name:ident, $($lbl:expr),+ ) => {
|
||||||
$(#[$($attrss)*])*
|
$(#[$($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 = $base(hash_choice)?;
|
||||||
$( let t = t.mix($lbl.as_bytes())?; )*
|
$( let t = t.mix($lbl.as_bytes())?; )*
|
||||||
Ok(t)
|
Ok(t)
|
||||||
@@ -89,7 +87,7 @@ macro_rules! hash_domain_ns {
|
|||||||
macro_rules! hash_domain {
|
macro_rules! hash_domain {
|
||||||
($(#[$($attrss:tt)*])* $base:ident, $name:ident, $($lbl:expr),+ ) => {
|
($(#[$($attrss:tt)*])* $base:ident, $name:ident, $($lbl:expr),+ ) => {
|
||||||
$(#[$($attrss)*])*
|
$(#[$($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 = $base(hash_choice)?;
|
||||||
$( let t = t.mix($lbl.as_bytes())?; )*
|
$( let t = t.mix($lbl.as_bytes())?; )*
|
||||||
Ok(t.into_value())
|
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 source file for details about how this is used concretely.
|
||||||
///
|
///
|
||||||
/// See the [module](self) documentation on how to use the hash domains in general
|
/// See the [module](self) documentation on how to use the hash domains in general
|
||||||
pub fn protocol(hash_choice: EitherShakeOrBlake) -> Result<HashDomain> {
|
pub fn protocol(hash_choice: KeyedHash) -> Result<HashDomain> {
|
||||||
// TODO: Update this string that is mixed in?
|
// TODO: Update this string that is mixed in?
|
||||||
match hash_choice {
|
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()),
|
.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()),
|
.mix("Rosenpass v1 mceliece460896 Kyber512 ChaChaPoly1305 Blake2b".as_bytes()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ use rosenpass_cipher_traits::Kem;
|
|||||||
use rosenpass_ciphers::hash_domain::{SecretHashDomain, SecretHashDomainNamespace};
|
use rosenpass_ciphers::hash_domain::{SecretHashDomain, SecretHashDomainNamespace};
|
||||||
use rosenpass_ciphers::kem::{EphemeralKem, StaticKem};
|
use rosenpass_ciphers::kem::{EphemeralKem, StaticKem};
|
||||||
use rosenpass_ciphers::keyed_hash;
|
use rosenpass_ciphers::keyed_hash;
|
||||||
use rosenpass_ciphers::subtle::either_hash::EitherShakeOrBlake;
|
use rosenpass_ciphers::subtle::either_hash::KeyedHash;
|
||||||
use rosenpass_ciphers::subtle::incorrect_hmac_blake2b::Blake2bCore;
|
|
||||||
use rosenpass_ciphers::subtle::keyed_shake256::SHAKE256Core;
|
|
||||||
use rosenpass_ciphers::{aead, xaead, KEY_LEN};
|
use rosenpass_ciphers::{aead, xaead, KEY_LEN};
|
||||||
use rosenpass_constant_time as constant_time;
|
use rosenpass_constant_time as constant_time;
|
||||||
use rosenpass_secret_memory::{Public, PublicBox, Secret};
|
use rosenpass_secret_memory::{Public, PublicBox, Secret};
|
||||||
@@ -373,10 +371,10 @@ pub enum ProtocolVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ProtocolVersion {
|
impl ProtocolVersion {
|
||||||
pub fn shake_or_blake(&self) -> EitherShakeOrBlake {
|
pub fn shake_or_blake(&self) -> KeyedHash {
|
||||||
match self {
|
match self {
|
||||||
ProtocolVersion::V02 => EitherShakeOrBlake::Right(Blake2bCore),
|
ProtocolVersion::V02 => KeyedHash::incorrect_hmac_blake2b(),
|
||||||
ProtocolVersion::V03 => EitherShakeOrBlake::Left(SHAKE256Core),
|
ProtocolVersion::V03 => KeyedHash::keyed_shake256(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,7 +503,7 @@ impl Peer {
|
|||||||
initiation_requested: false,
|
initiation_requested: false,
|
||||||
handshake: None,
|
handshake: None,
|
||||||
known_init_conf_response: 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
|
/// Calculate the peer ID of this CryptoServer
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn pidm(&self, shake_or_blake: EitherShakeOrBlake) -> Result<PeerId> {
|
pub fn pidm(&self, shake_or_blake: KeyedHash) -> Result<PeerId> {
|
||||||
Ok(Public::new(
|
Ok(Public::new(
|
||||||
hash_domains::peerid(shake_or_blake)?
|
hash_domains::peerid(shake_or_blake)?
|
||||||
.mix(self.spkm.deref())?
|
.mix(self.spkm.deref())?
|
||||||
@@ -1474,7 +1472,7 @@ impl CryptoServer {
|
|||||||
handshake: None,
|
handshake: None,
|
||||||
known_init_conf_response: None,
|
known_init_conf_response: None,
|
||||||
initiation_requested: false,
|
initiation_requested: false,
|
||||||
protocol_version: protocol_version,
|
protocol_version,
|
||||||
};
|
};
|
||||||
let peerid = peer.pidt()?;
|
let peerid = peer.pidt()?;
|
||||||
let peerno = self.peers.len();
|
let peerno = self.peers.len();
|
||||||
@@ -1671,7 +1669,7 @@ impl Peer {
|
|||||||
handshake: None,
|
handshake: None,
|
||||||
known_init_conf_response: None,
|
known_init_conf_response: None,
|
||||||
initiation_requested: false,
|
initiation_requested: false,
|
||||||
protocol_version: protocol_version,
|
protocol_version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1702,11 +1700,11 @@ impl Session {
|
|||||||
///
|
///
|
||||||
/// rosenpass_secret_memory::secret_policy_try_use_memfd_secrets();
|
/// 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.created_at, 0.0);
|
||||||
/// assert_eq!(s.handshake_role, HandshakeRole::Initiator);
|
/// assert_eq!(s.handshake_role, HandshakeRole::Initiator);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn zero(shake_or_blake: EitherShakeOrBlake) -> Self {
|
pub fn zero(shake_or_blake: KeyedHash) -> Self {
|
||||||
Self {
|
Self {
|
||||||
created_at: 0.0,
|
created_at: 0.0,
|
||||||
sidm: SessionId::zero(),
|
sidm: SessionId::zero(),
|
||||||
@@ -2177,7 +2175,7 @@ impl CryptoServer {
|
|||||||
let cookie_secret = cookie_secret.get(self).value.secret();
|
let cookie_secret = cookie_secret.get(self).value.secret();
|
||||||
let mut cookie_value = [0u8; 16];
|
let mut cookie_value = [0u8; 16];
|
||||||
cookie_value.copy_from_slice(
|
cookie_value.copy_from_slice(
|
||||||
&hash_domains::cookie_value(EitherShakeOrBlake::Left(SHAKE256Core))?
|
&hash_domains::cookie_value(KeyedHash::keyed_shake256())?
|
||||||
.mix(cookie_secret)?
|
.mix(cookie_secret)?
|
||||||
.mix(host_identification.encode())?
|
.mix(host_identification.encode())?
|
||||||
.into_value()[..16],
|
.into_value()[..16],
|
||||||
@@ -2193,7 +2191,7 @@ impl CryptoServer {
|
|||||||
let msg_in = Ref::<&[u8], Envelope<InitHello>>::new(rx_buf)
|
let msg_in = Ref::<&[u8], Envelope<InitHello>>::new(rx_buf)
|
||||||
.ok_or(RosenpassError::BufferSizeMismatch)?;
|
.ok_or(RosenpassError::BufferSizeMismatch)?;
|
||||||
expected.copy_from_slice(
|
expected.copy_from_slice(
|
||||||
&hash_domains::cookie(EitherShakeOrBlake::Left(SHAKE256Core))?
|
&hash_domains::cookie(KeyedHash::keyed_shake256())?
|
||||||
.mix(&cookie_value)?
|
.mix(&cookie_value)?
|
||||||
.mix(&msg_in.as_bytes()[span_of!(Envelope<InitHello>, msg_type..cookie)])?
|
.mix(&msg_in.as_bytes()[span_of!(Envelope<InitHello>, msg_type..cookie)])?
|
||||||
.into_value()[..16],
|
.into_value()[..16],
|
||||||
@@ -2230,7 +2228,7 @@ impl CryptoServer {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let cookie_value = active_cookie_value.unwrap();
|
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())?
|
.mix(self.spkm.deref())?
|
||||||
.into_value();
|
.into_value();
|
||||||
|
|
||||||
@@ -2322,18 +2320,18 @@ impl CryptoServer {
|
|||||||
let peer_shake256 = self.handle_init_hello(
|
let peer_shake256 = self.handle_init_hello(
|
||||||
&msg_in.payload,
|
&msg_in.payload,
|
||||||
&mut msg_out.payload,
|
&mut msg_out.payload,
|
||||||
EitherShakeOrBlake::Left(SHAKE256Core),
|
KeyedHash::keyed_shake256(),
|
||||||
);
|
);
|
||||||
let (peer, peer_hash_choice) = match peer_shake256 {
|
let (peer, peer_hash_choice) = match peer_shake256 {
|
||||||
Ok(peer) => (peer, EitherShakeOrBlake::Left(SHAKE256Core)),
|
Ok(peer) => (peer, KeyedHash::keyed_shake256()),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let peer_blake2b = self.handle_init_hello(
|
let peer_blake2b = self.handle_init_hello(
|
||||||
&msg_in.payload,
|
&msg_in.payload,
|
||||||
&mut msg_out.payload,
|
&mut msg_out.payload,
|
||||||
EitherShakeOrBlake::Right(Blake2bCore),
|
KeyedHash::incorrect_hmac_blake2b(),
|
||||||
);
|
);
|
||||||
match peer_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"),
|
Err(_) => bail!("No valid hash function found for InitHello"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2398,18 +2396,18 @@ impl CryptoServer {
|
|||||||
let peer_shake256 = self.handle_init_conf(
|
let peer_shake256 = self.handle_init_conf(
|
||||||
&msg_in.payload,
|
&msg_in.payload,
|
||||||
&mut msg_out.payload,
|
&mut msg_out.payload,
|
||||||
EitherShakeOrBlake::Left(SHAKE256Core),
|
KeyedHash::keyed_shake256(),
|
||||||
);
|
);
|
||||||
let (peer, peer_hash_choice) = match peer_shake256 {
|
let (peer, peer_hash_choice) = match peer_shake256 {
|
||||||
Ok(peer) => (peer, EitherShakeOrBlake::Left(SHAKE256Core)),
|
Ok(peer) => (peer, KeyedHash::keyed_shake256()),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let peer_blake2b = self.handle_init_conf(
|
let peer_blake2b = self.handle_init_conf(
|
||||||
&msg_in.payload,
|
&msg_in.payload,
|
||||||
&mut msg_out.payload,
|
&mut msg_out.payload,
|
||||||
EitherShakeOrBlake::Right(Blake2bCore),
|
KeyedHash::incorrect_hmac_blake2b(),
|
||||||
);
|
);
|
||||||
match peer_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"),
|
Err(_) => bail!("No valid hash function found for InitHello"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2459,19 +2457,15 @@ impl CryptoServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TODO documentation
|
/// TODO documentation
|
||||||
fn verify_hash_choice_match(
|
fn verify_hash_choice_match(&self, peer: PeerPtr, peer_hash_choice: KeyedHash) -> Result<()> {
|
||||||
&self,
|
|
||||||
peer: PeerPtr,
|
|
||||||
peer_hash_choice: EitherShakeOrBlake,
|
|
||||||
) -> Result<()> {
|
|
||||||
match peer.get(self).protocol_version.shake_or_blake() {
|
match peer.get(self).protocol_version.shake_or_blake() {
|
||||||
EitherShakeOrBlake::Left(SHAKE256Core) => match peer_hash_choice {
|
KeyedHash::KeyedShake256(_) => match peer_hash_choice {
|
||||||
EitherShakeOrBlake::Left(SHAKE256Core) => Ok(()),
|
KeyedHash::KeyedShake256(_) => Ok(()),
|
||||||
EitherShakeOrBlake::Right(Blake2bCore) => bail!("Hash function mismatch"),
|
KeyedHash::IncorrectHmacBlake2b(_) => bail!("Hash function mismatch"),
|
||||||
},
|
},
|
||||||
EitherShakeOrBlake::Right(Blake2bCore) => match peer_hash_choice {
|
KeyedHash::IncorrectHmacBlake2b(_) => match peer_hash_choice {
|
||||||
EitherShakeOrBlake::Left(SHAKE256Core) => bail!("Hash function mismatch"),
|
KeyedHash::KeyedShake256(_) => bail!("Hash function mismatch"),
|
||||||
EitherShakeOrBlake::Right(Blake2bCore) => Ok(()),
|
KeyedHash::IncorrectHmacBlake2b(_) => Ok(()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3242,11 +3236,7 @@ where
|
|||||||
M: AsBytes + FromBytes,
|
M: AsBytes + FromBytes,
|
||||||
{
|
{
|
||||||
/// Internal business logic: Check the message authentication code produced by [Self::seal]
|
/// Internal business logic: Check the message authentication code produced by [Self::seal]
|
||||||
pub fn check_seal(
|
pub fn check_seal(&self, srv: &CryptoServer, shake_or_blake: KeyedHash) -> Result<bool> {
|
||||||
&self,
|
|
||||||
srv: &CryptoServer,
|
|
||||||
shake_or_blake: EitherShakeOrBlake,
|
|
||||||
) -> Result<bool> {
|
|
||||||
let expected = hash_domains::mac(shake_or_blake)?
|
let expected = hash_domains::mac(shake_or_blake)?
|
||||||
.mix(srv.spkm.deref())?
|
.mix(srv.spkm.deref())?
|
||||||
.mix(&self.as_bytes()[span_of!(Self, msg_type..mac)])?;
|
.mix(&self.as_bytes()[span_of!(Self, msg_type..mac)])?;
|
||||||
@@ -3259,7 +3249,7 @@ where
|
|||||||
|
|
||||||
impl InitiatorHandshake {
|
impl InitiatorHandshake {
|
||||||
/// Zero initialization of an InitiatorHandshake, with up to date timestamp
|
/// 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 {
|
InitiatorHandshake {
|
||||||
created_at: srv.timebase.now(),
|
created_at: srv.timebase.now(),
|
||||||
next: HandshakeStateMachine::RespHello,
|
next: HandshakeStateMachine::RespHello,
|
||||||
@@ -3278,7 +3268,7 @@ impl InitiatorHandshake {
|
|||||||
|
|
||||||
impl HandshakeState {
|
impl HandshakeState {
|
||||||
/// Zero initialization of an HandshakeState
|
/// Zero initialization of an HandshakeState
|
||||||
pub fn zero(shake_or_blake: EitherShakeOrBlake) -> Self {
|
pub fn zero(shake_or_blake: KeyedHash) -> Self {
|
||||||
Self {
|
Self {
|
||||||
sidi: SessionId::zero(),
|
sidi: SessionId::zero(),
|
||||||
sidr: SessionId::zero(),
|
sidr: SessionId::zero(),
|
||||||
@@ -3423,7 +3413,7 @@ impl HandshakeState {
|
|||||||
biscuit_ct: &[u8],
|
biscuit_ct: &[u8],
|
||||||
sidi: SessionId,
|
sidi: SessionId,
|
||||||
sidr: SessionId,
|
sidr: SessionId,
|
||||||
shake_or_blake: EitherShakeOrBlake,
|
shake_or_blake: KeyedHash,
|
||||||
) -> Result<(PeerPtr, BiscuitId, HandshakeState)> {
|
) -> Result<(PeerPtr, BiscuitId, HandshakeState)> {
|
||||||
// The first bit of the biscuit indicates which biscuit key was used
|
// The first bit of the biscuit indicates which biscuit key was used
|
||||||
let bk = BiscuitKeyPtr(((biscuit_ct[0] & 0b1000_0000) >> 7) as usize);
|
let bk = BiscuitKeyPtr(((biscuit_ct[0] & 0b1000_0000) >> 7) as usize);
|
||||||
@@ -3475,7 +3465,7 @@ impl HandshakeState {
|
|||||||
self,
|
self,
|
||||||
srv: &CryptoServer,
|
srv: &CryptoServer,
|
||||||
role: HandshakeRole,
|
role: HandshakeRole,
|
||||||
either_shake_or_blake: EitherShakeOrBlake,
|
either_shake_or_blake: KeyedHash,
|
||||||
) -> Result<Session> {
|
) -> Result<Session> {
|
||||||
let HandshakeState { ck, sidi, sidr } = self;
|
let HandshakeState { ck, sidi, sidr } = self;
|
||||||
let tki = ck
|
let tki = ck
|
||||||
@@ -3588,7 +3578,7 @@ impl CryptoServer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ih: &InitHello,
|
ih: &InitHello,
|
||||||
rh: &mut RespHello,
|
rh: &mut RespHello,
|
||||||
shake_or_blake: EitherShakeOrBlake,
|
shake_or_blake: KeyedHash,
|
||||||
) -> Result<PeerPtr> {
|
) -> Result<PeerPtr> {
|
||||||
let mut core = HandshakeState::zero(shake_or_blake);
|
let mut core = HandshakeState::zero(shake_or_blake);
|
||||||
|
|
||||||
@@ -3758,7 +3748,7 @@ impl CryptoServer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ic: &InitConf,
|
ic: &InitConf,
|
||||||
rc: &mut EmptyData,
|
rc: &mut EmptyData,
|
||||||
shake_or_blake: EitherShakeOrBlake,
|
shake_or_blake: KeyedHash,
|
||||||
) -> Result<PeerPtr> {
|
) -> Result<PeerPtr> {
|
||||||
// (peer, bn) ← LoadBiscuit(InitConf.biscuit)
|
// (peer, bn) ← LoadBiscuit(InitConf.biscuit)
|
||||||
// ICR1
|
// ICR1
|
||||||
@@ -3943,7 +3933,7 @@ impl CryptoServer {
|
|||||||
}?;
|
}?;
|
||||||
|
|
||||||
let spkt = peer.get(self).spkt.deref();
|
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)?
|
.mix(spkt)?
|
||||||
.into_value();
|
.into_value();
|
||||||
let cookie_value = peer.cv().update_mut(self).unwrap();
|
let cookie_value = peer.cv().update_mut(self).unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user