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!: improve wallet key derivation by use of proper domain separation (see issue #4170) #4316

Merged

Conversation

jorgeantonio21
Copy link
Contributor

Description
--- Add domain separation for wallet key derivation for type KeyManager.

Motivation and Context
--- The current wallet key derivation uses plain concatenation of variable length inputs. This procedure is known to not be collision resistant. A better methodology, as pointed here, is to prepend the length of each datum to it before passing it through the hash function. We attain this by using the current hashing API, which gives a suitable interface for domain separation, (which always prepends input length).

How Has This Been Tested?
--- Unit tests.

@delta1
Copy link
Contributor

delta1 commented Jul 17, 2022

Just out of interest this is a breaking change

@AaronFeickert
Copy link
Collaborator

Length extension attack resistance isn't strictly a requirement here, as key derivation security doesn't depend on it. However, it is the case that any underlying hash function susceptible to length extension is probably a poor choice for other design or performance reasons anyway.

@@ -84,13 +87,17 @@ where

/// Derive a new private key from master key: derived_key=SHA256(master_key||branch_seed||index)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This comment is no longer accurate, as SHA-256 is not resistant to length extension attacks, and the input structure implied by the comment is out of date and no longer correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Absolutely ! Thank you for taking notice of it !

// piece of data for concatenation, reducing the risk of collisions due to redundance of variable length
// input
let derive_key = DomainSeparatedHasher::<D, GenericHashDomain>::new(DOMAIN_SEPARATION_LABEL)
.chain(self.seed.entropy().to_vec().to_hex())
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any reason to use a hex encoding here? It seems unnecessary, and the use of the hashing API is already a breaking change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are totally right Aaron, one can simply chain the seed entropy as it is.

@jorgeantonio21 jorgeantonio21 marked this pull request as ready for review July 20, 2022 08:04
@stringhandler stringhandler changed the title fix: improve wallet key derivation by use of proper domain separation (see issue #4170) fix!: improve wallet key derivation by use of proper domain separation (see issue #4170) Jul 20, 2022
stringhandler
stringhandler previously approved these changes Jul 20, 2022
hansieodendaal
hansieodendaal previously approved these changes Jul 26, 2022
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.

LGTM

Comment on lines 21 to 31
pub fn base_layer_key_manager_mac_generation() -> HashingDomain {
HashingDomain::new("base_layer.key_manager.cipher_seed.mac_generation")
}

pub fn base_layer_key_manager_argon2_encoding() -> HashingDomain {
HashingDomain::new("base_layer.key_manager.cipher_seed.argon2_encoding")
}

pub fn base_layer_key_manager_chacha20_encoding() -> HashingDomain {
HashingDomain::new("base_layer.key_manager.cipher_seed.chacha20_encoding")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I see these functions are not being used in this PR; I suppose they were created for use elsewhere?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I see, used in #4296.

}

pub fn base_layer_key_manager() -> HashingDomain {
HashingDomain::new("base_layer.key_manager.key_manager")
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
HashingDomain::new("base_layer.key_manager.key_manager")
HashingDomain::new("base_layer.key_manager")

@aviator-app aviator-app bot added mq-failed and removed mq-failed labels Aug 2, 2022
@stringhandler stringhandler merged commit 7a25028 into tari-project:development Aug 2, 2022
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.

5 participants