Skip to content

Commit

Permalink
chore: refactor key manager hasher (#6330)
Browse files Browse the repository at this point in the history
Description
---
Refactors the key manager hasher for clarity.

Closes #6327.

Motivation and Context
---
The key manager hasher is instantiated using a wrapper function that is
poorly named, as it is reused in multiple contexts. This PR refactors
for clarity.

How Has This Been Tested?
---
Tests pass.

What process can a PR reviewer use to test or verify this change?
---
Check the refactoring does not change behavior.
  • Loading branch information
AaronFeickert committed May 8, 2024
1 parent 4033f07 commit c9eb579
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 28 deletions.
32 changes: 18 additions & 14 deletions base_layer/key_manager/src/cipher_seed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ use digest::consts::U32;
use rand::{rngs::OsRng, RngCore};
use serde::{Deserialize, Serialize};
use subtle::ConstantTimeEq;
use tari_crypto::hashing::DomainSeparatedHasher;
use tari_utilities::{hidden::Hidden, safe_array::SafeArray, SafePassword};
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};

use crate::{
error::KeyManagerError,
mac_domain_hasher,
mnemonic::{from_bytes, to_bytes, to_bytes_with_language, Mnemonic, MnemonicLanguage},
CipherSeedEncryptionKey,
CipherSeedMacKey,
KeyManagerDomain,
SeedWords,
LABEL_ARGON_ENCODING,
LABEL_CHACHA20_ENCODING,
Expand Down Expand Up @@ -301,9 +302,10 @@ impl CipherSeed {
salt: &[u8],
) -> Result<(), KeyManagerError> {
// The ChaCha20 nonce is derived from the main salt
let encryption_nonce = mac_domain_hasher::<Blake2b<U32>>(LABEL_CHACHA20_ENCODING)
.chain(salt)
.finalize();
let encryption_nonce =
DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(LABEL_CHACHA20_ENCODING)
.chain(salt)
.finalize();
let encryption_nonce = &encryption_nonce.as_ref()[..size_of::<Nonce>()];

// Encrypt/decrypt the data
Expand Down Expand Up @@ -347,21 +349,23 @@ impl CipherSeed {
return Err(KeyManagerError::InvalidData);
}

Ok(mac_domain_hasher::<Blake2b<U32>>(LABEL_MAC_GENERATION)
.chain(birthday)
.chain(entropy)
.chain([cipher_seed_version])
.chain(salt)
.chain(mac_key.reveal())
.finalize()
.as_ref()[..CIPHER_SEED_MAC_BYTES]
.to_vec())
Ok(
DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(LABEL_MAC_GENERATION)
.chain(birthday)
.chain(entropy)
.chain([cipher_seed_version])
.chain(salt)
.chain(mac_key.reveal())
.finalize()
.as_ref()[..CIPHER_SEED_MAC_BYTES]
.to_vec(),
)
}

/// Use Argon2 to derive encryption and MAC keys from a passphrase and main salt
fn derive_keys(passphrase: &SafePassword, salt: &[u8]) -> DerivedCipherSeedKeys {
// The Argon2 salt is derived from the main salt
let argon2_salt = mac_domain_hasher::<Blake2b<U32>>(LABEL_ARGON_ENCODING)
let argon2_salt = DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(LABEL_ARGON_ENCODING)
.chain(salt)
.finalize();
let argon2_salt = &argon2_salt.as_ref()[..ARGON2_SALT_BYTES];
Expand Down
6 changes: 3 additions & 3 deletions base_layer/key_manager/src/key_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ use derivative::Derivative;
use digest::{consts::U64, typenum::IsEqual, Digest};
use serde::{Deserialize, Serialize};
use tari_crypto::{
hashing::LengthExtensionAttackResistant,
hashing::{DomainSeparatedHasher, LengthExtensionAttackResistant},
keys::{PublicKey, SecretKey},
tari_utilities::byte_array::ByteArrayError,
};
use zeroize::Zeroize;

use crate::{cipher_seed::CipherSeed, mac_domain_hasher, LABEL_DERIVE_KEY};
use crate::{cipher_seed::CipherSeed, KeyManagerDomain, LABEL_DERIVE_KEY};

#[derive(Clone, Derivative, Serialize, Deserialize, Zeroize)]
#[derivative(Debug)]
Expand Down Expand Up @@ -102,7 +102,7 @@ where
// apply domain separation to generate derive key. Under the hood, the hashing api prepends the length of each
// piece of data for concatenation, reducing the risk of collisions due to redundancy of variable length
// input
let derive_key = mac_domain_hasher::<D>(LABEL_DERIVE_KEY)
let derive_key = DomainSeparatedHasher::<D, KeyManagerDomain>::new_with_label(LABEL_DERIVE_KEY)
.chain(self.seed.entropy())
.chain(self.branch_seed.as_bytes())
.chain(key_index.to_le_bytes())
Expand Down
12 changes: 1 addition & 11 deletions base_layer/key_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
use std::str::FromStr;

use cipher_seed::BIRTHDAY_GENESIS_FROM_UNIX_EPOCH;
use digest::Digest;
use tari_crypto::{
hash_domain,
hashing::{DomainSeparatedHasher, LengthExtensionAttackResistant},
};
use tari_crypto::hash_domain;
use tari_utilities::{hidden::Hidden, hidden_type, safe_array::SafeArray};
use zeroize::Zeroize;

Expand All @@ -35,12 +31,6 @@ const LABEL_CHACHA20_ENCODING: &str = "chacha20_encoding";
const LABEL_MAC_GENERATION: &str = "mac_generation";
const LABEL_DERIVE_KEY: &str = "derive_key";

pub(crate) fn mac_domain_hasher<D: Digest + LengthExtensionAttackResistant>(
label: &'static str,
) -> DomainSeparatedHasher<D, KeyManagerDomain> {
DomainSeparatedHasher::<D, KeyManagerDomain>::new_with_label(label)
}

hidden_type!(CipherSeedEncryptionKey, SafeArray<u8, CIPHER_SEED_ENCRYPTION_KEY_BYTES>);
hidden_type!(CipherSeedMacKey, SafeArray< u8, CIPHER_SEED_MAC_KEY_BYTES>);

Expand Down

0 comments on commit c9eb579

Please sign in to comment.