From 5b40c01394eb362e3f5b3f58481b7c1a619c4d4b Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 6 Apr 2025 10:47:47 -0400 Subject: [PATCH] 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. --- .../southernstorm/noise/protocol/ChaChaPolyCipherState.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/router/java/src/com/southernstorm/noise/protocol/ChaChaPolyCipherState.java b/router/java/src/com/southernstorm/noise/protocol/ChaChaPolyCipherState.java index 64fcbb1afd..bcba6ed52d 100644 --- a/router/java/src/com/southernstorm/noise/protocol/ChaChaPolyCipherState.java +++ b/router/java/src/com/southernstorm/noise/protocol/ChaChaPolyCipherState.java @@ -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; }