Don't increment nonces within a CipherState unless the encryption/decryption operation succeeds

Adapted from https://github.com/rweather/noise-java/pull/18

Section 5.1 of the The Noise Protocol Framework, revision 34 states in the description for DecryptWithAd that:

If an authentication failure occurs in DECRYPT() then n is not incremented and an error is signaled to the caller.

But noise-java currently increments the nonce unconditionally.
This change defers incrementing the nonce until encryption/decryption operations actually succeed.
This commit is contained in:
zzz
2025-04-06 10:47:47 -04:00
parent a4fe0da2b4
commit 5b40c01394

View File

@ -125,7 +125,8 @@ public class ChaChaPolyCipherState implements CipherState {
{
if (n == -1L)
throw new IllegalStateException("Nonce has wrapped around");
ChaChaCore.initIV(input, n++);
// n will be incremented on success below
ChaChaCore.initIV(input, n);
// UNCOMMENT TO RUN THE main() TEST
// input[13] = TEST_VECTOR_NONCE_HIGH_BYTES;
ChaChaCore.hash(output, input);
@ -235,6 +236,7 @@ public class ChaChaPolyCipherState implements CipherState {
poly.update(ciphertext, ciphertextOffset, length);
finish(adLength, length);
System.arraycopy(polyKey, 0, ciphertext, ciphertextOffset + length, 16);
n++;
return length + 16;
}
@ -287,6 +289,7 @@ public class ChaChaPolyCipherState implements CipherState {
if ((temp & 0xFF) != 0)
Noise.throwBadTagException();
encrypt(ciphertext, ciphertextOffset, plaintext, plaintextOffset, dataLen);
n++;
return dataLen;
}