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

This commit is contained in:
Jon Chambers 2024-02-23 18:19:51 -05:00 committed by Jon Chambers
parent f43de4a734
commit c111aa7e9d
4 changed files with 16 additions and 8 deletions

View File

@ -130,8 +130,7 @@ class AESGCMFallbackCipherState implements CipherState {
iv[13] = 0;
iv[14] = 0;
iv[15] = 1;
++n;
// Encrypt a block of zeroes to generate the hash key to XOR
// the GHASH tag with at the end of the encrypt/decrypt operation.
Arrays.fill(hashKey, (byte)0);
@ -207,6 +206,7 @@ class AESGCMFallbackCipherState implements CipherState {
ghash.finish(ciphertext, ciphertextOffset + length, 16);
for (int index = 0; index < 16; ++index)
ciphertext[ciphertextOffset + length + index] ^= hashKey[index];
n += 1;
return length + 16;
}
@ -247,6 +247,7 @@ class AESGCMFallbackCipherState implements CipherState {
if ((temp & 0xFF) != 0)
Noise.throwBadTagException();
encryptCTR(ciphertext, ciphertextOffset, plaintext, plaintextOffset, dataLen);
n += 1;
return dataLen;
}

View File

@ -190,8 +190,7 @@ class AESGCMOnCtrCipherState implements CipherState {
iv[13] = 0;
iv[14] = 0;
iv[15] = 1;
++n;
// Initialize the CTR mode cipher with the key and IV.
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));
@ -255,6 +254,7 @@ class AESGCMOnCtrCipherState implements CipherState {
ghash.finish(ciphertext, ciphertextOffset + length, 16);
for (int index = 0; index < 16; ++index)
ciphertext[ciphertextOffset + length + index] ^= hashKey[index];
n += 1;
return length + 16;
}
@ -312,6 +312,7 @@ class AESGCMOnCtrCipherState implements CipherState {
// Shouldn't happen.
throw new IllegalStateException(e);
}
n += 1;
return dataLen;
}

View File

@ -138,7 +138,7 @@ class ChaChaPolyCipherState implements CipherState {
{
if (n == -1L)
throw new IllegalStateException("Nonce has wrapped around");
ChaChaCore.initIV(input, n++);
ChaChaCore.initIV(input, n);
ChaChaCore.hash(output, input);
Arrays.fill(polyKey, (byte)0);
xorBlock(polyKey, 0, polyKey, 0, 32, output);
@ -234,6 +234,7 @@ class ChaChaPolyCipherState implements CipherState {
poly.update(ciphertext, ciphertextOffset, length);
finish(ad, length);
System.arraycopy(polyKey, 0, ciphertext, ciphertextOffset + length, 16);
n += 1;
return length + 16;
}
@ -273,6 +274,7 @@ class ChaChaPolyCipherState implements CipherState {
if ((temp & 0xFF) != 0)
Noise.throwBadTagException();
encrypt(ciphertext, ciphertextOffset, plaintext, plaintextOffset, dataLen);
n += 1;
return dataLen;
}

View File

@ -149,10 +149,11 @@ public class CipherStateTests {
fail();
}
// Fast-forward the nonce to just before the rollover. We will be able
// to decrypt one more block, and then the next request will be rejected.
cipher.setNonce(-2L);
try {
// Fast-forward the nonce to just before the rollover. We will be able
// to decrypt one more block, and then the next request will be rejected.
cipher.setNonce(-2L);
buffer = new byte [plaintextBytes.length];
Arrays.fill(buffer, (byte)0xAA);
try {
@ -161,6 +162,9 @@ public class CipherStateTests {
} catch (BadPaddingException e) {
// Success!
}
cipher.setNonce(-1L);
try {
cipher.decryptWithAd(adBytes, ciphertextBytes, 0, buffer, 0, ciphertextBytes.length);
fail();