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

AEAD ciphers throw undocumented exceptions on overflow

XMLWordPrintable

      Cipher class enforces some restrictions on AEAD use:
      - ChaCha20 cipher is preventing the counter from wrapping around
      - AEAD decryption does not return any data from Cipher.update. Decrypted data is only returned from doFinal after verifying the tag. DoFinal can not produce more than 2GB of data, so decrypting longer buffers is impossible.

      We should document the exception types thrown in response to these error conditions. Currently the exception types thrown are not documented, and are inconsistent across ciphers.

      I did an experiment to verify what happens if I encrypt/decrypt larger amounts of data, see attached reproducer. Results:

      ChaCha20-Poly1305, encryption fails after 256GB with:
      java.lang.RuntimeException: java.security.KeyException: Counter exhausted. Reinitialize with new key and/or nonce
      at java.base/com.sun.crypto.provider.ChaCha20Cipher.engineUpdate(ChaCha20Cipher.java:653)
      at java.base/javax.crypto.Cipher.update(Cipher.java:1869)
      at com.test.AEADWrap.crypt(AEADWrap.java:57)
      at com.test.AEADWrap.main(AEADWrap.java:40)
      Caused by: java.security.KeyException: Counter exhausted. Reinitialize with new key and/or nonce
      at java.base/com.sun.crypto.provider.ChaCha20Cipher.chaCha20Transform(ChaCha20Cipher.java:1046)
      at java.base/com.sun.crypto.provider.ChaCha20Cipher$EngineAEADEnc.doUpdate(ChaCha20Cipher.java:1326)
      at java.base/com.sun.crypto.provider.ChaCha20Cipher.engineUpdate(ChaCha20Cipher.java:651)
      ... 3 more

      ChaCha20-Poly1305, decryption fails after 2GB with:
      java.lang.OutOfMemoryError: Required array length 1073741840 + 1073741840 is too large
      at java.base/jdk.internal.util.ArraysSupport.hugeLength(ArraysSupport.java:752)
      at java.base/jdk.internal.util.ArraysSupport.newLength(ArraysSupport.java:745)
      at java.base/java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:100)
      at java.base/java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:132)
      at java.base/com.sun.crypto.provider.ChaCha20Cipher$EngineAEADDec.doUpdate(ChaCha20Cipher.java:1392)
      at java.base/com.sun.crypto.provider.ChaCha20Cipher.engineUpdate(ChaCha20Cipher.java:651)
      at java.base/javax.crypto.Cipher.update(Cipher.java:1869)
      at com.test.AEADWrap.crypt(AEADWrap.java:57)
      at com.test.AEADWrap.main(AEADWrap.java:46)

      AES-GCM encryption fails after 2GB with:
      java.security.ProviderException: SunJCE provider only supports input size up to 2147483647 bytes
      at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMEncrypt.checkDataLength(GaloisCounterMode.java:1098)
      at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMEncrypt.doUpdate(GaloisCounterMode.java:1143)
      at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMEncrypt.doUpdate(GaloisCounterMode.java:1120)
      at java.base/com.sun.crypto.provider.GaloisCounterMode.engineUpdate(GaloisCounterMode.java:349)
      at java.base/javax.crypto.Cipher.update(Cipher.java:1869)
      at com.test.AEADWrap.crypt(AEADWrap.java:57)
      at com.test.AEADWrap.main(AEADWrap.java:25)

      AES-GCM decryption fails after 2GB with:
      java.lang.OutOfMemoryError: Required array length 1073741840 + 1073741840 is too large
      at java.base/jdk.internal.util.ArraysSupport.hugeLength(ArraysSupport.java:752)
      at java.base/jdk.internal.util.ArraysSupport.newLength(ArraysSupport.java:745)
      at java.base/java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:100)
      at java.base/java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:132)
      at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMDecrypt.doUpdate(GaloisCounterMode.java:1458)
      at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMDecrypt.doUpdate(GaloisCounterMode.java:1441)
      at java.base/com.sun.crypto.provider.GaloisCounterMode.engineUpdate(GaloisCounterMode.java:349)
      at java.base/javax.crypto.Cipher.update(Cipher.java:1869)
      at com.test.AEADWrap.crypt(AEADWrap.java:57)
      at com.test.AEADWrap.main(AEADWrap.java:31)

            kdriver Kevin Driver
            djelinski Daniel Jelinski
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: