Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8343339

ChaCha20-Poly1305 out of memory during decryption

XMLWordPrintable

      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


            jnimeh Jamil Nimeh
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: