Skip to content
New issue

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

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

Already on GitHub? # to your account

Fix nonce incrementing in stateful transport to match the specification #152

Merged
merged 1 commit into from
Mar 11, 2023

Conversation

complexspaces
Copy link
Contributor

This PR fixes #150 by correcting the stateful encrypt/decrypt functions to never use the reserved value of u64::MAX, which additionally guarantees a lack of wraparound issues.

In addition, a unit test was added to ensure this behavior does not regress by mistake.

Fixes #150

@mcginty
Copy link
Owner

mcginty commented Mar 9, 2023

This looks good, and given the wording of that nonce being reserved, I'm wondering if the same restriction should be placed on StatelessCipherState as it would also be using a "special" nonce, regardless of it being exhausted or not.

snow/src/cipherstate.rs

Lines 123 to 153 in b55a713

pub fn encrypt_ad(
&self,
nonce: u64,
authtext: &[u8],
plaintext: &[u8],
out: &mut [u8],
) -> Result<usize, Error> {
if !self.has_key {
return Err(StateProblem::MissingKeyMaterial.into());
}
Ok(self.cipher.encrypt(nonce, authtext, plaintext, out))
}
pub fn decrypt_ad(
&self,
nonce: u64,
authtext: &[u8],
ciphertext: &[u8],
out: &mut [u8],
) -> Result<usize, Error> {
if (ciphertext.len() < TAGLEN) || out.len() < (ciphertext.len() - TAGLEN) {
return Err(Error::Decrypt);
}
if !self.has_key {
return Err(StateProblem::MissingKeyMaterial.into());
}
self.cipher.decrypt(nonce, authtext, ciphertext, out)
}

@complexspaces
Copy link
Contributor Author

complexspaces commented Mar 9, 2023

... I'm wondering if the same restriction should be placed on StatelessCipherState as it would also be using a "special" nonce

That's a valid question, and I almost had implemented that too. The specification is unclear if "reserved" means "reserved for Noise" or "reserved for a protocol to use for certain things." If its the first interpretation, we should, but in the second we might prevent an otherwise valid use case.

@mcginty
Copy link
Owner

mcginty commented Mar 9, 2023

Given the wording for 11.4. Out-of-order transport messages, I think we should cautiously treat it as abiding by the same rules as the in-order transports, if you don't mind adding that to this PR.

I asked for clarification and if I hear anything to the contrary we can update.

@mcginty
Copy link
Owner

mcginty commented Mar 9, 2023

Ah yes, MAXNONCE is used in the REKEY(k) function, so we should consider that reserved for all cases where the nonce is used.

@complexspaces
Copy link
Contributor Author

Oh great catch! I agree we need the check everywhere then. I'll update this PR shortly.

@mcginty
Copy link
Owner

mcginty commented Mar 9, 2023

Thanks to Trevor for pointing it out :).

@complexspaces complexspaces force-pushed the correct-nonce-incrementing branch from 5c1d3a3 to 8cbfc4d Compare March 10, 2023 07:26
@complexspaces complexspaces force-pushed the correct-nonce-incrementing branch from 8cbfc4d to 2b5fb4c Compare March 10, 2023 07:28
@complexspaces
Copy link
Contributor Author

I have pushed the changes that now include validations for the stateless cipher function as well.

@mcginty
Copy link
Owner

mcginty commented Mar 11, 2023

Thanks, this looks great.

The only thought I had is that Exhausted is probably not a great name any more (maybe InvalidNonce with rustdocs to explain the scenario), but that's actually better for me to change separately, as I'd like to get this merged into the 0.9 branch for a correctness patch release.

@mcginty mcginty merged commit 375ba06 into mcginty:master Mar 11, 2023
@complexspaces complexspaces deleted the correct-nonce-incrementing branch March 14, 2023 14:39
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Off by one error allows invalid nonce usage
2 participants