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

fix: address domain separation regarding challenge generation for mac origin (see issue #4333) #4338

Conversation

jorgeantonio21
Copy link
Contributor

@jorgeantonio21 jorgeantonio21 commented Jul 22, 2022

Description

Add use of hashing API to create challenge for mac origin.

Motivation and Context

Tackle issue.

How Has This Been Tested?

Existing unit tests.

@@ -248,7 +248,7 @@ where S: Service<DecryptedDhtMessage, Response = (), Error = PipelineError>
Ok(origin_mac) => {
// If this fails, discard the message because we decrypted and deserialized the message with our shared
// ECDH secret but the message could not be authenticated
let msg_challenge = crypt::create_message_challenge(&message.dht_header, &message.body);
let msg_challenge = crypt::create_message_domain_separated_hash(&message.dht_header, &message.body);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend renaming to be consistent with the rest of the PR.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like binding_message_representation might be nicely expressive if used consistently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed these variables, as you suggested, as well as the terminology OriginMac/origin_mac

Copy link
Contributor

@hansieodendaal hansieodendaal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, please see suggestions below.

@@ -43,6 +43,8 @@ use crate::{
version::DhtProtocolVersion,
};

const DOMAIN_SEPARATION_CHALLENGE_LABEL: &str = "com.tari.comms.dht.crypt.message_parts";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const DOMAIN_SEPARATION_CHALLENGE_LABEL: &str = "com.tari.comms.dht.crypt.message_parts";

Please use comms_dht_hash_domain()

// we digest the given data into a domain independent hash function to produce a signature
// use of the hashing API for domain separation and deal with variable length input
let domain_separated_hash =
DomainSeparatedHasher::<Challenge, GenericHashDomain>::new(DOMAIN_SEPARATION_CHALLENGE_LABEL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
DomainSeparatedHasher::<Challenge, GenericHashDomain>::new(DOMAIN_SEPARATION_CHALLENGE_LABEL)
comms_dht_hash_domain().mac_hasher::<Challenge>()

Note that mac_hasher can also be used, which implements the LengthExtensionAttackResistant trait.

Comment on lines +140 to +146
.finalize()
.into_vec();

let mut output = [0u8; 32];
// the use of Challenge bind to Blake256, should always produce a 32-byte length output data
output.copy_from_slice(domain_separated_hash.as_slice());
output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.finalize()
.into_vec();
let mut output = [0u8; 32];
// the use of Challenge bind to Blake256, should always produce a 32-byte length output data
output.copy_from_slice(domain_separated_hash.as_slice());
output
.finalize();
domain_separated_hash.hash_to_bytes()
.expect("Fixed output of '0 < size <= 32' bytes with 32 byte hasher cannot fail.")

This way the runtime panic is not hidden in copy_from_slice. As an alternative, the function could return a result and the runtime error could be handled.

@@ -102,7 +104,7 @@ pub fn create_message_challenge(header: &DhtMessageHeader, body: &[u8]) -> [u8;
}

/// Generates a 32-byte hashed challenge that commits to all message parts
pub fn create_message_challenge_parts(
pub fn create_message_domain_separated_hash_parts(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn create_message_domain_separated_hash_parts(
pub fn create_message_hash(

The previous name conveys the intent well enough, but the addition of _parts is confusing, so create_message_challenge could also work.

pub fn create_message_hash(origin_mac: &[u8], body: &[u8]) -> [u8; 32] {
Challenge::new().chain(origin_mac).chain(&body).finalize().into()
pub fn create_message_hash(message_signature: &[u8], body: &[u8]) -> [u8; 32] {
Challenge::new().chain(message_signature).chain(&body).finalize().into()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Challenge::new().chain(message_signature).chain(&body).finalize().into()
comms_dht_hash_domain()
.mac_hasher::<Challenge>()
.chain(message_signature)
.chain(&body)
.finalize()
.hash_to_bytes()
.expect("Fixed output of '0 < size <= 32' bytes with 32 byte hasher cannot fail.")

signer_public_key: CommsPublicKey,
signature: Signature,
}

fn construct_origin_mac_hash(
fn construct_message_signature_hash(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should also implement comms_dht_hash_domain() as

pub fn create_message_hash(message_signature: &[u8], body: &[u8]) -> [u8; 32] {
    comms_dht_hash_domain()
        .hasher::<Challenge>()
        .chain(message_signature)
        .chain(&body)
        .finalize()
        .hash_to_bytes()
        .expect("Fixed output of '0 < size <= 32' bytes with as 32 byte hasher cannot fail.")
}

@jorgeantonio21
Copy link
Contributor Author

jorgeantonio21 commented Jul 28, 2022

This PR has been addressed by this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants