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

Encryption using GCM results in RuntimeException: input length out of bound

    XMLWordPrintable

Details

    • b08
    • 13
    • b12
    • x86_64
    • linux_ubuntu
    • Verified

    Backports

      Description

        ADDITIONAL SYSTEM INFORMATION :
        Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz, x86_64
        Ubuntu 16.04.6 LTS
        Openjdk-13 (https://jdk.java.net/13/)

        A DESCRIPTION OF THE PROBLEM :
        Encrypting using the GCM algorithm causes the com.sun.crypto.provider.GHASH.ghashRangeCheck function to raise "input length out of bound" exception, even though the input length is not out of bound. In particular, when running the same code with the same parameters in openjdk-11 everything works, and no exception is raised.

        REGRESSION : Last worked in version 11.0.1

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. Create an instance of javax.crypto.Cipher with the parameter "AES/GCM/NoPadding"
        2. Init the cipher with nonce (random byte-array of size 12)
        3. Allocate byte-array for the input with size 100001
        4. Call cipher.doFinal(inputArray)

        From some playing around with the sizes of the inputArray, it looks like the problem starts when the size of the InputArray is greater than 2^16 (2^16 + 1 for instance). But some sizes seem to work though, for example 100000, 1000000, 10000000 etc.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The cipher encrypts the inputArray successfully.
        ACTUAL -
        Getting exception in the com.sun.crypto.provider.GHASH.ghashRangeCheck function. In particular, the input length is not as the size of the inputArray (which is 100001), and I'm not sure where the number 90705 comes from.

        Exception in thread "main" java.lang.RuntimeException: input length out of bound: 100000 > 90705
                at java.base/com.sun.crypto.provider.GHASH.ghashRangeCheck(GHASH.java:209)
                at java.base/com.sun.crypto.provider.GHASH.update(GHASH.java:197)
                at java.base/com.sun.crypto.provider.GaloisCounterMode.doLastBlock(GaloisCounterMode.java:424)
                at java.base/com.sun.crypto.provider.GaloisCounterMode.encryptFinal(GaloisCounterMode.java:497)
                at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1118)
                at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1053)
                at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
                at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
                at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2208)
                at EncBug.bugGCM(EncBug.java:35)
                at EncBug.main(EncBug.java:40)

        ---------- BEGIN SOURCE ----------
        import javax.crypto.Cipher;
        import javax.crypto.SecretKey;
        import javax.crypto.spec.GCMParameterSpec;
        import javax.crypto.spec.SecretKeySpec;
        import java.util.Random;

        public class EncBug {
            public static byte[] bugGCM() throws Exception {
                // AES-GCM parameters
                int GCM_NONCE_LENGTH = 12; // in bytes
                int GCM_TAG_LENGTH = 16; // in bytes

                int inputSize = 100001;
                //int inputSize = 65536 + 1; // 2^16 == 65536

                // init input
                byte[] inputArray = new byte[inputSize];
                for (int i=0; i < inputArray.length; i++) {
                    inputArray[i] = (byte)i;
                }

                // init cipher
                Cipher cipher;
                cipher = Cipher.getInstance("AES/GCM/NoPadding");

                // init nonce
                final byte[] nonce = new byte[GCM_NONCE_LENGTH];
                Random random = new Random();
                random.nextBytes(nonce);
                GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);

                byte[] key_code = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
                SecretKey key = new SecretKeySpec(key_code, "AES");
                cipher.init(Cipher.ENCRYPT_MODE, key, spec);
                byte[] outputArray = cipher.doFinal(inputArray);
                return outputArray;
            }

            public static void main(String[] args) throws Exception {
                bugGCM();
            }
        }
        ---------- END SOURCE ----------

        FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

                sshivang Shivangi Gupta
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                7 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: