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