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

Add salt recommendation for HKDF docs #78

Merged
merged 3 commits into from
Mar 4, 2023

Conversation

TheAlgorythm
Copy link
Contributor

@TheAlgorythm TheAlgorythm commented Mar 4, 2023

It is easy to misuse the HKDF salt parameter like I've probably found such a weakness in a project depending on this crate (cryptoballot/cryptoballot#17). Therefore it should be a good idea to document how to use the parameters correctly.

I am not 100 percent sure, but I believe I have correctly summarized the information from the following three, at first seemingly contradictory, blog posts.

Soatok

Which means: You’re not supposed to use HKDF with a constant IKM, info label, etc. but vary the salt for multiple invocations. The salt must either be a fixed random value, or NULL.
HKDF uses salts as a mechanism to improve the quality of randomness when working with group elements and passwords.
How Should You Introduce Randomness into HKDF? Just shove it in the info parameter.
It may seem weird, and defy intuition, but the correct way to introduce randomness into HKDF as most developers interact with the algorithm is to skip the salt parameter entirely (either fixing it to a specific value for domain-separation or leaving it NULL), and instead concatenate data into the info parameter.

Filippo

Native X25519 recipients wrap the file key using ChaCha20Poly1305 with a key derived as HKDF-SHA-256(ikm = shared secret, salt = ephemeral share || recipient, info = "age-encryption.org/v1/X25519"). We could just add the Kyber key to the input key material, but we can take the occasion to fix a small regret in the age design: the salt is supposed to be random or fixed for domain separation, while ephemeral share and recipient should have been part of the input key material. [...]

The wrapping key for the Kyber768+X25519 plugin can then be HKDF-SHA-256(ikm = shared secret || ephemeral share || recipient || kyber key, salt = "age-encryption.org/Kyber768+X25519", info = nil).

Cendyne

Here are a few ways HKDF can be misused:

  • In a public setting, no salt is given.
  • The salt input is not indistinguishable from random (IND).
  • The salt input is used for domain separation.
  • The same salt is used across multiple transactions in a public setting.
  • Different salts are used in a private setting.
  • The inputs to HKDFs are the same for different contexts, resulting in the same keys for different purposes.

@TheAlgorythm TheAlgorythm marked this pull request as ready for review March 4, 2023 11:16
@tarcieri
Copy link
Member

tarcieri commented Mar 4, 2023

It would probably be good to add some real-world usage examples such as an AKE.

TLS 1.3, for example, uses a key derivation hierarchy (which is the same regardless of the mode, e.g. PSK, session resumption, or starting a new session) where each successive level of the hierarchy provides inputs to the next via the salt.

@TheAlgorythm
Copy link
Contributor Author

I am not too familiar with the ins and outs of TLS 1.3, but I've found a good resource about the AKE.
But it could be a bit much for the basic usage examples. So I could add it as a separate documentation module.

@tarcieri tarcieri merged commit 3b375ce into RustCrypto:master Mar 4, 2023
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.

2 participants