-
Bug
-
Resolution: Fixed
-
P3
-
17, 21, 22
-
b11
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8316750 | 21.0.2 | Aleksey Shipilev | P3 | Resolved | Fixed | b02 |
JDK-8316752 | 17.0.10 | Aleksey Shipilev | P3 | Resolved | Fixed | b01 |
My colleage Ioana Nedelcu discovered the following issue.
In JDK 17 and newer, GaloisCounterMode executes a check that fails with an ArithmeticException if the input data is too short [1], instead of throwing a AEADBadTagException.
[1] https://github.com/openjdk/jdk/blob/0eb0997ae4f81314b764241e69dae5c698dbb6c6/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java#L1575
[2] https://github.com/openjdk/jdk/blob/0eb0997ae4f81314b764241e69dae5c698dbb6c6/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java#L1603C27-L1605
The change was detected by running this test on a recent JDK version: https://github.com/google/tink/blob/43d5698a442b7ca6bcc5c0661af5939559a03dc8/java_src/src/test/java/com/google/crypto/tink/subtle/AesGcmHkdfStreamingTest.java#L276
The following repro shows the same crash:
```
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
public class Test {
public static void main(String[] args) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(new byte[]{88, 26, 43, -100, -24, -29, -70, 10, 34, -85, 52, 101, 45, -68, -105, -123}, "AES");
GCMParameterSpec params = new GCMParameterSpec(8 * 16, new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
cipher.doFinal(ByteBuffer.allocate(0), ByteBuffer.allocate(0));
}
}
```
$ java -fullversion
openjdk full version "16-ea+34-2216"
$ java Test
Exception in thread "main" javax.crypto.AEADBadTagException: Input too short - need tag
at java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:738)
at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1122)
at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1059)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:946)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:501)
at java.base/javax.crypto.CipherSpi.bufferCrypt(CipherSpi.java:799)
at java.base/javax.crypto.CipherSpi.engineDoFinal(CipherSpi.java:735)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:673)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2500)
at Test.main(Test.java:18)
$ java -fullversion
openjdk full version "17.0.2+8-86"
$ java Test
Exception in thread "main" java.lang.ArithmeticException: integer overflow
at java.base/java.lang.Math.subtractExact(Math.java:924)
at java.base/com.sun.crypto.provider.GaloisCounterMode.checkDataLength(GaloisCounterMode.java:576)
at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMDecrypt.doFinal(GaloisCounterMode.java:1433)
at java.base/com.sun.crypto.provider.GaloisCounterMode.engineDoFinal(GaloisCounterMode.java:447)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2500)
at Test.main(Test.java:18)
In JDK 17 and newer, GaloisCounterMode executes a check that fails with an ArithmeticException if the input data is too short [1], instead of throwing a AEADBadTagException.
[1] https://github.com/openjdk/jdk/blob/0eb0997ae4f81314b764241e69dae5c698dbb6c6/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java#L1575
[2] https://github.com/openjdk/jdk/blob/0eb0997ae4f81314b764241e69dae5c698dbb6c6/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java#L1603C27-L1605
The change was detected by running this test on a recent JDK version: https://github.com/google/tink/blob/43d5698a442b7ca6bcc5c0661af5939559a03dc8/java_src/src/test/java/com/google/crypto/tink/subtle/AesGcmHkdfStreamingTest.java#L276
The following repro shows the same crash:
```
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
public class Test {
public static void main(String[] args) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(new byte[]{88, 26, 43, -100, -24, -29, -70, 10, 34, -85, 52, 101, 45, -68, -105, -123}, "AES");
GCMParameterSpec params = new GCMParameterSpec(8 * 16, new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
cipher.doFinal(ByteBuffer.allocate(0), ByteBuffer.allocate(0));
}
}
```
$ java -fullversion
openjdk full version "16-ea+34-2216"
$ java Test
Exception in thread "main" javax.crypto.AEADBadTagException: Input too short - need tag
at java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:738)
at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1122)
at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1059)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:946)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:501)
at java.base/javax.crypto.CipherSpi.bufferCrypt(CipherSpi.java:799)
at java.base/javax.crypto.CipherSpi.engineDoFinal(CipherSpi.java:735)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:673)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2500)
at Test.main(Test.java:18)
$ java -fullversion
openjdk full version "17.0.2+8-86"
$ java Test
Exception in thread "main" java.lang.ArithmeticException: integer overflow
at java.base/java.lang.Math.subtractExact(Math.java:924)
at java.base/com.sun.crypto.provider.GaloisCounterMode.checkDataLength(GaloisCounterMode.java:576)
at java.base/com.sun.crypto.provider.GaloisCounterMode$GCMDecrypt.doFinal(GaloisCounterMode.java:1433)
at java.base/com.sun.crypto.provider.GaloisCounterMode.engineDoFinal(GaloisCounterMode.java:447)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2500)
at Test.main(Test.java:18)
- backported by
-
JDK-8316750 ArithmeticException in GaloisCounterMode
- Resolved
-
JDK-8316752 ArithmeticException in GaloisCounterMode
- Resolved
- relates to
-
JDK-8255557 Decouple GCM from CipherCore
- Resolved
- links to
-
Commit openjdk/jdk17u-dev/125ae25e
-
Commit openjdk/jdk21u/305be8f7
-
Commit openjdk/jdk/f41c267f
-
Review openjdk/jdk17u-dev/1746
-
Review openjdk/jdk21u/164
-
Review openjdk/jdk/15212
(4 links to)