-
Bug
-
Resolution: Unresolved
-
P4
-
11, 17, 23, 24
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
OS: Gentoo Linux (I expect all OSs are affected)
System: Ryzen-7700X, 32GB RAM
Java: openjdk 17.0.12 2024-07-16
A DESCRIPTION OF THE PROBLEM :
ChaCha20-Poly1305 encryption works perfectly fine.
ChaCha20-Poly1305 decryption runs out of memory for operations greater than ~2GB. ChaCha20-Poly1305 should be able to do up to 256GB see https://crypto.stackexchange.com/questions/71165/largest-message-size-for-xchacha20-poly1305.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Execute the Java code i provided.
2. Observe the out of memory crash.
3. Deactivate decryption by commenting out "byte[] plaintext = dec.update(ciphertext);" and "assert(Arrays.equals(randomData, plaintext));" and replacing "dec.doFinal(enc.doFinal());" by "dec.doFinal();"
4. Observe everything works fine.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Decrypting large files with ChaCha20-Poly1305 does not run out of memory.
ACTUAL -
While decryption is active, you can see your memory filling slowly, until out of memory.
While decryption is inactive, you can see almost no memory usage, and the program just runs trough as expected.
---------- BEGIN SOURCE ----------
import java.security.SecureRandom;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class ChaChaPolyTest {
public static void main(String[] args) throws Exception {
//Generate a key
KeyGenerator keyGen = KeyGenerator.getInstance("ChaCha20");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
//Generate a nonce
SecureRandom secRand = new SecureRandom();
byte[] nonce = new byte[12];
secRand.nextBytes(nonce);
// Create a cipher for encryption
Cipher enc = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
enc.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(nonce));
// Create a cipher for decryption
Cipher dec = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
dec.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(nonce));
//Set up generator of "random" test data
Random random = new Random();
//Prevent infinite loop
long dataToProcess = 4l * 1024l * 1024l * 1024l;// 4 GiB
long dataProcessed = 0;
Instant lastUpdate = Instant.now();
byte[] randomData = new byte[1024];
while(dataProcessed < dataToProcess) {
//Generate some test data
random.nextBytes(randomData);
//Encrypt test data
byte[] ciphertext = enc.update(randomData);
//Decrypt test data
byte[] plaintext = dec.update(ciphertext);
//Check for data corruption
assert(Arrays.equals(randomData, plaintext));
//Update statistics
dataProcessed += randomData.length;
if(Duration.between(lastUpdate, Instant.now()).getSeconds() > 2) {
System.out.println("Processed " + dataProcessed +" bytes");
lastUpdate = Instant.now();
}
}
dec.doFinal(enc.doFinal());
}
}
---------- END SOURCE ----------
FREQUENCY : always
OS: Gentoo Linux (I expect all OSs are affected)
System: Ryzen-7700X, 32GB RAM
Java: openjdk 17.0.12 2024-07-16
A DESCRIPTION OF THE PROBLEM :
ChaCha20-Poly1305 encryption works perfectly fine.
ChaCha20-Poly1305 decryption runs out of memory for operations greater than ~2GB. ChaCha20-Poly1305 should be able to do up to 256GB see https://crypto.stackexchange.com/questions/71165/largest-message-size-for-xchacha20-poly1305.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Execute the Java code i provided.
2. Observe the out of memory crash.
3. Deactivate decryption by commenting out "byte[] plaintext = dec.update(ciphertext);" and "assert(Arrays.equals(randomData, plaintext));" and replacing "dec.doFinal(enc.doFinal());" by "dec.doFinal();"
4. Observe everything works fine.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Decrypting large files with ChaCha20-Poly1305 does not run out of memory.
ACTUAL -
While decryption is active, you can see your memory filling slowly, until out of memory.
While decryption is inactive, you can see almost no memory usage, and the program just runs trough as expected.
---------- BEGIN SOURCE ----------
import java.security.SecureRandom;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class ChaChaPolyTest {
public static void main(String[] args) throws Exception {
//Generate a key
KeyGenerator keyGen = KeyGenerator.getInstance("ChaCha20");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
//Generate a nonce
SecureRandom secRand = new SecureRandom();
byte[] nonce = new byte[12];
secRand.nextBytes(nonce);
// Create a cipher for encryption
Cipher enc = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
enc.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(nonce));
// Create a cipher for decryption
Cipher dec = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
dec.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(nonce));
//Set up generator of "random" test data
Random random = new Random();
//Prevent infinite loop
long dataToProcess = 4l * 1024l * 1024l * 1024l;// 4 GiB
long dataProcessed = 0;
Instant lastUpdate = Instant.now();
byte[] randomData = new byte[1024];
while(dataProcessed < dataToProcess) {
//Generate some test data
random.nextBytes(randomData);
//Encrypt test data
byte[] ciphertext = enc.update(randomData);
//Decrypt test data
byte[] plaintext = dec.update(ciphertext);
//Check for data corruption
assert(Arrays.equals(randomData, plaintext));
//Update statistics
dataProcessed += randomData.length;
if(Duration.between(lastUpdate, Instant.now()).getSeconds() > 2) {
System.out.println("Processed " + dataProcessed +" bytes");
lastUpdate = Instant.now();
}
}
dec.doFinal(enc.doFinal());
}
}
---------- END SOURCE ----------
FREQUENCY : always
- relates to
-
JDK-8320743 AEAD ciphers throw undocumented exceptions on overflow
-
- Resolved
-