Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: update key manager hasher labels #6329

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions base_layer/key_manager/src/cipher_seed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,18 @@ use crate::{
CipherSeedMacKey,
KeyManagerDomain,
SeedWords,
LABEL_ARGON_ENCODING,
LABEL_CHACHA20_ENCODING,
LABEL_MAC_GENERATION,
HASHER_LABEL_CIPHER_SEED_ENCRYPTION_NONCE,
HASHER_LABEL_CIPHER_SEED_MAC,
HASHER_LABEL_CIPHER_SEED_PBKDF_SALT,
};

// The version should be incremented for any breaking change to the format
// NOTE: Only the most recent version is supported!
// History:
// 0: initial version
// 1: fixed incorrect key derivation and birthday genesis
const CIPHER_SEED_VERSION: u8 = 1u8;
// 2: updated hasher domain labels and MAC input ordering
const CIPHER_SEED_VERSION: u8 = 2u8;

pub const BIRTHDAY_GENESIS_FROM_UNIX_EPOCH: u64 = 1640995200; // seconds to 2022-01-01 00:00:00 UTC
pub const DEFAULT_CIPHER_SEED_PASSPHRASE: &str = "TARI_CIPHER_SEED"; // the default passphrase if none is supplied
Expand Down Expand Up @@ -181,9 +182,9 @@ impl CipherSeed {

// Generate the MAC
let mac = Self::generate_mac(
CIPHER_SEED_VERSION,
&self.birthday.to_le_bytes(),
self.entropy.as_ref(),
CIPHER_SEED_VERSION,
self.salt.as_ref(),
&mac_key,
)?;
Expand Down Expand Up @@ -280,7 +281,7 @@ impl CipherSeed {
let birthday = u16::from_le_bytes(birthday_bytes);

// Generate the MAC
let expected_mac = Self::generate_mac(&birthday_bytes, entropy.reveal(), version, salt.as_ref(), &mac_key)?;
let expected_mac = Self::generate_mac(version, &birthday_bytes, entropy.reveal(), salt.as_ref(), &mac_key)?;

// Verify the MAC in constant time to avoid leaking data
if mac.ct_eq(&expected_mac).into() {
Expand All @@ -302,10 +303,11 @@ impl CipherSeed {
salt: &[u8],
) -> Result<(), KeyManagerError> {
// The ChaCha20 nonce is derived from the main salt
let encryption_nonce =
DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(LABEL_CHACHA20_ENCODING)
.chain(salt)
.finalize();
let encryption_nonce = DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(
HASHER_LABEL_CIPHER_SEED_ENCRYPTION_NONCE,
)
.chain(salt)
.finalize();
let encryption_nonce = &encryption_nonce.as_ref()[..size_of::<Nonce>()];

// Encrypt/decrypt the data
Expand All @@ -332,9 +334,9 @@ impl CipherSeed {

/// Generate a MAC using Blake2b
fn generate_mac(
version: u8,
birthday: &[u8],
entropy: &[u8],
cipher_seed_version: u8,
salt: &[u8],
mac_key: &CipherSeedMacKey,
) -> Result<Vec<u8>, KeyManagerError> {
Expand All @@ -350,10 +352,10 @@ impl CipherSeed {
}

Ok(
DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(LABEL_MAC_GENERATION)
DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(HASHER_LABEL_CIPHER_SEED_MAC)
.chain([version])
.chain(birthday)
.chain(entropy)
.chain([cipher_seed_version])
.chain(salt)
.chain(mac_key.reveal())
.finalize()
Expand All @@ -365,9 +367,11 @@ impl CipherSeed {
/// 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 = DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(LABEL_ARGON_ENCODING)
.chain(salt)
.finalize();
let argon2_salt = DomainSeparatedHasher::<Blake2b<U32>, KeyManagerDomain>::new_with_label(
HASHER_LABEL_CIPHER_SEED_PBKDF_SALT,
)
.chain(salt)
.finalize();
let argon2_salt = &argon2_salt.as_ref()[..ARGON2_SALT_BYTES];

// Run Argon2 with enough output to accommodate both keys, so we only run it once
Expand Down
4 changes: 2 additions & 2 deletions base_layer/key_manager/src/key_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use tari_crypto::{
};
use zeroize::Zeroize;

use crate::{cipher_seed::CipherSeed, KeyManagerDomain, LABEL_DERIVE_KEY};
use crate::{cipher_seed::CipherSeed, KeyManagerDomain, HASHER_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 = DomainSeparatedHasher::<D, KeyManagerDomain>::new_with_label(LABEL_DERIVE_KEY)
let derive_key = DomainSeparatedHasher::<D, KeyManagerDomain>::new_with_label(HASHER_LABEL_DERIVE_KEY)
.chain(self.seed.entropy())
.chain(self.branch_seed.as_bytes())
.chain(key_index.to_le_bytes())
Expand Down
8 changes: 4 additions & 4 deletions base_layer/key_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ pub mod schema;

hash_domain!(KeyManagerDomain, "com.tari.base_layer.key_manager", 1);

const LABEL_ARGON_ENCODING: &str = "argon2_encoding";
const LABEL_CHACHA20_ENCODING: &str = "chacha20_encoding";
const LABEL_MAC_GENERATION: &str = "mac_generation";
const LABEL_DERIVE_KEY: &str = "derive_key";
const HASHER_LABEL_CIPHER_SEED_PBKDF_SALT: &str = "cipher_seed_pbkdf_salt";
const HASHER_LABEL_CIPHER_SEED_ENCRYPTION_NONCE: &str = "cipher_seed_encryption_nonce";
const HASHER_LABEL_CIPHER_SEED_MAC: &str = "cipher_seed_mac";
const HASHER_LABEL_DERIVE_KEY: &str = "derive_key";

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