From 518dad9298b2e05ad3d42d40cb0830bea011dcc6 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Thu, 13 Nov 2025 15:04:36 -0800 Subject: [PATCH 01/13] JDK-8371864: GaloisCounterMode.implGCMCrypt0 AVX512/AVX2 intrinsics stubs cause AES-GCM encryption failure for certain payload sizes --- src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp index f0726ded7e546..aec10de0d673c 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp @@ -3527,6 +3527,8 @@ void StubGenerator::aesgcm_avx512(Register in, Register len, Register ct, Regist __ bind(MESG_BELOW_32_BLKS); __ subl(len, 16 * 16); + __ cmpl(len, 256); + __ jcc(Assembler::lessEqual, ENC_DEC_DONE); __ addl(pos, 16 * 16); gcm_enc_dec_last_avx512(len, in, pos, AAD_HASHx, SHUF_MASK, avx512_subkeyHtbl, ghashin_offset, HashKey_16, true, true); @@ -4016,13 +4018,15 @@ void StubGenerator::aesgcm_avx2(Register in, Register len, Register ct, Register const Register rounds = r10; const XMMRegister ctr_blockx = xmm9; const XMMRegister aad_hashx = xmm8; - Label encrypt_done, encrypt_by_8_new, encrypt_by_8; + Label encrypt_done, encrypt_by_8_new, encrypt_by_8, exit; //This routine should be called only for message sizes of 128 bytes or more. //Macro flow: //process 8 16 byte blocks in initial_num_blocks. //process 8 16 byte blocks at a time until all are done 'encrypt_by_8_new followed by ghash_last_8' __ xorl(pos, pos); + __ cmpl(len, 128); + __ jcc(Assembler::less, exit); //Generate 8 constants for htbl generateHtbl_8_block_avx2(subkeyHtbl); @@ -4090,6 +4094,7 @@ void StubGenerator::aesgcm_avx2(Register in, Register len, Register ct, Register __ vpxor(xmm0, xmm0, xmm0, Assembler::AVX_128bit); __ vpxor(xmm13, xmm13, xmm13, Assembler::AVX_128bit); + __ bind(exit); } #undef __ From fb6a1ecd7bf912e3599a61d4a39867c808eb48fb Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Mon, 17 Nov 2025 14:05:52 -0800 Subject: [PATCH 02/13] Add TestAesGcmIntrinsic.java. The test is authored by tholenst@google.com and zlukas@google.com. --- .../Cipher/AES/TestAesGcmIntrinsic.java | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java new file mode 100644 index 0000000000000..b5a5de00e1a44 --- /dev/null +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2025, Google LLC. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8371864 + * @run main/othervm TestAesGcmIntrinsic + * @summary Test GaloisCounterMode.implGCMCrypt0 AVX512/AVX2 intrinsics. + */ + +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.time.Duration; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class TestAesGcmIntrinsic { + + static final SecureRandom SECURE_RANDOM = newDefaultSecureRandom(); + + private static SecureRandom newDefaultSecureRandom() { + SecureRandom retval = new SecureRandom(); + retval.nextLong(); // force seeding + return retval; + } + + private static byte[] randBytes(int size) { + byte[] rand = new byte[size]; + SECURE_RANDOM.nextBytes(rand); + return rand; + } + + private static final int IV_SIZE_IN_BYTES = 12; + private static final int TAG_SIZE_IN_BYTES = 16; + + private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] aad) + throws Exception { + byte[] nonce = randBytes(IV_SIZE_IN_BYTES); + SecretKey keySpec = new SecretKeySpec(key, "AES"); + AlgorithmParameterSpec params = + new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, nonce, 0, nonce.length); + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, params); + if (aad != null && aad.length != 0) { + cipher.updateAAD(aad); + } + int outputSize = cipher.getOutputSize(plaintext.length); + int len = IV_SIZE_IN_BYTES + outputSize; + byte[] output = new byte[len]; + System.arraycopy(nonce, 0, output, 0, IV_SIZE_IN_BYTES); + cipher.doFinal(plaintext, 0, plaintext.length, output, IV_SIZE_IN_BYTES); + return output; + } + + // x86-64 parallel intrinsic data size + private static final int PARALLEL_LEN = 512; + // max data size for x86-64 intrinsic + private static final int SPLIT_LEN = 1048576; // 1MB + + private void jitFunc() throws Exception { + byte[] aad = randBytes(20); + byte[] key = randBytes(16); + // Force JIT. + for (int i = 0; i < 100000; i++) { + byte[] message = randBytes(PARALLEL_LEN); + byte[] ciphertext = gcmEncrypt(key, message, aad); + if (ciphertext == null) { + throw new RuntimeException("ciphertext is null"); + } + } + for (int messageSize = SPLIT_LEN; messageSize < SPLIT_LEN + 300; messageSize++) { + byte[] message = randBytes(messageSize); + try { + byte[] ciphertext = gcmEncrypt(key, message, aad); + if (ciphertext == null) { + throw new RuntimeException("ciphertext is null"); + } + } catch (Exception e) { + throw new Exception("Failed for messageSize " + Integer.toHexString(messageSize), e); + } + } + } + + public static void main(String[] args) throws Exception { + TestAesGcmIntrinsic test = new TestAesGcmIntrinsic(); + long startTime = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTime < 60 * 1000) { + test.jitFunc(); + } + } +} From 338a99d087ab6be16bfe6b3936079f635432941e Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Mon, 17 Nov 2025 14:43:03 -0800 Subject: [PATCH 03/13] Fix Whitespace errors --- .../sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java index b5a5de00e1a44..8d71ee5fba79c 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java @@ -23,9 +23,9 @@ /* * @test - * @bug 8371864 + * @bug 8371864 * @run main/othervm TestAesGcmIntrinsic - * @summary Test GaloisCounterMode.implGCMCrypt0 AVX512/AVX2 intrinsics. + * @summary Test GaloisCounterMode.implGCMCrypt0 AVX512/AVX2 intrinsics. */ import java.security.SecureRandom; From eb1a13d24a56712f5edf05b2c1b325eeeddcc41a Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Wed, 19 Nov 2025 16:42:43 -0800 Subject: [PATCH 04/13] Fix indentation. --- .../Cipher/AES/TestAesGcmIntrinsic.java | 122 +++++++++--------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java index 8d71ee5fba79c..0cf2db634cff5 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java @@ -38,76 +38,76 @@ public class TestAesGcmIntrinsic { - static final SecureRandom SECURE_RANDOM = newDefaultSecureRandom(); + static final SecureRandom SECURE_RANDOM = newDefaultSecureRandom(); - private static SecureRandom newDefaultSecureRandom() { - SecureRandom retval = new SecureRandom(); - retval.nextLong(); // force seeding - return retval; - } + private static SecureRandom newDefaultSecureRandom() { + SecureRandom retval = new SecureRandom(); + retval.nextLong(); // force seeding + return retval; + } - private static byte[] randBytes(int size) { - byte[] rand = new byte[size]; - SECURE_RANDOM.nextBytes(rand); - return rand; - } + private static byte[] randBytes(int size) { + byte[] rand = new byte[size]; + SECURE_RANDOM.nextBytes(rand); + return rand; + } - private static final int IV_SIZE_IN_BYTES = 12; - private static final int TAG_SIZE_IN_BYTES = 16; + private static final int IV_SIZE_IN_BYTES = 12; + private static final int TAG_SIZE_IN_BYTES = 16; - private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] aad) - throws Exception { - byte[] nonce = randBytes(IV_SIZE_IN_BYTES); - SecretKey keySpec = new SecretKeySpec(key, "AES"); - AlgorithmParameterSpec params = - new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, nonce, 0, nonce.length); - Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); - cipher.init(Cipher.ENCRYPT_MODE, keySpec, params); - if (aad != null && aad.length != 0) { - cipher.updateAAD(aad); + private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] aad) + throws Exception { + byte[] nonce = randBytes(IV_SIZE_IN_BYTES); + SecretKey keySpec = new SecretKeySpec(key, "AES"); + AlgorithmParameterSpec params = + new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, nonce, 0, nonce.length); + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, params); + if (aad != null && aad.length != 0) { + cipher.updateAAD(aad); + } + int outputSize = cipher.getOutputSize(plaintext.length); + int len = IV_SIZE_IN_BYTES + outputSize; + byte[] output = new byte[len]; + System.arraycopy(nonce, 0, output, 0, IV_SIZE_IN_BYTES); + cipher.doFinal(plaintext, 0, plaintext.length, output, IV_SIZE_IN_BYTES); + return output; } - int outputSize = cipher.getOutputSize(plaintext.length); - int len = IV_SIZE_IN_BYTES + outputSize; - byte[] output = new byte[len]; - System.arraycopy(nonce, 0, output, 0, IV_SIZE_IN_BYTES); - cipher.doFinal(plaintext, 0, plaintext.length, output, IV_SIZE_IN_BYTES); - return output; - } - // x86-64 parallel intrinsic data size - private static final int PARALLEL_LEN = 512; - // max data size for x86-64 intrinsic - private static final int SPLIT_LEN = 1048576; // 1MB + // x86-64 parallel intrinsic data size + private static final int PARALLEL_LEN = 512; + // max data size for x86-64 intrinsic + private static final int SPLIT_LEN = 1048576; // 1MB - private void jitFunc() throws Exception { - byte[] aad = randBytes(20); - byte[] key = randBytes(16); - // Force JIT. - for (int i = 0; i < 100000; i++) { - byte[] message = randBytes(PARALLEL_LEN); - byte[] ciphertext = gcmEncrypt(key, message, aad); - if (ciphertext == null) { - throw new RuntimeException("ciphertext is null"); - } - } - for (int messageSize = SPLIT_LEN; messageSize < SPLIT_LEN + 300; messageSize++) { - byte[] message = randBytes(messageSize); - try { - byte[] ciphertext = gcmEncrypt(key, message, aad); - if (ciphertext == null) { - throw new RuntimeException("ciphertext is null"); + private void jitFunc() throws Exception { + byte[] aad = randBytes(20); + byte[] key = randBytes(16); + // Force JIT. + for (int i = 0; i < 100000; i++) { + byte[] message = randBytes(PARALLEL_LEN); + byte[] ciphertext = gcmEncrypt(key, message, aad); + if (ciphertext == null) { + throw new RuntimeException("ciphertext is null"); + } + } + for (int messageSize = SPLIT_LEN; messageSize < SPLIT_LEN + 300; messageSize++) { + byte[] message = randBytes(messageSize); + try { + byte[] ciphertext = gcmEncrypt(key, message, aad); + if (ciphertext == null) { + throw new RuntimeException("ciphertext is null"); + } + } catch (Exception e) { + throw new Exception("Failed for messageSize " + Integer.toHexString(messageSize), e); + } } - } catch (Exception e) { - throw new Exception("Failed for messageSize " + Integer.toHexString(messageSize), e); - } } - } - public static void main(String[] args) throws Exception { - TestAesGcmIntrinsic test = new TestAesGcmIntrinsic(); - long startTime = System.currentTimeMillis(); - while (System.currentTimeMillis() - startTime < 60 * 1000) { - test.jitFunc(); + public static void main(String[] args) throws Exception { + TestAesGcmIntrinsic test = new TestAesGcmIntrinsic(); + long startTime = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTime < 60 * 1000) { + test.jitFunc(); + } } - } } From 4ef42ffe373298fd27b22f6688e42a4454d43fa3 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Wed, 19 Nov 2025 16:44:58 -0800 Subject: [PATCH 05/13] Stylistic change: '256' to '16 * 16'. --- src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp index aec10de0d673c..98fdd60700f9d 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp @@ -3527,7 +3527,7 @@ void StubGenerator::aesgcm_avx512(Register in, Register len, Register ct, Regist __ bind(MESG_BELOW_32_BLKS); __ subl(len, 16 * 16); - __ cmpl(len, 256); + __ cmpl(len, 16 * 16); __ jcc(Assembler::lessEqual, ENC_DEC_DONE); __ addl(pos, 16 * 16); gcm_enc_dec_last_avx512(len, in, pos, AAD_HASHx, SHUF_MASK, avx512_subkeyHtbl, ghashin_offset, HashKey_16, true, true); From 54e619ab014582064501eeddfc1aa20ed9861856 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Wed, 19 Nov 2025 17:40:33 -0800 Subject: [PATCH 06/13] Address shipilev's comments: - Rename test to TestGCMSplitBound.java - Change test range to [SPLIT_LEN - 300; SPLIT_LEN + 300]. --- .../{TestAesGcmIntrinsic.java => TestGCMSplitBound.java} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename test/jdk/com/sun/crypto/provider/Cipher/AES/{TestAesGcmIntrinsic.java => TestGCMSplitBound.java} (94%) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java similarity index 94% rename from test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java rename to test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java index 0cf2db634cff5..86db34d6239ae 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestAesGcmIntrinsic.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java @@ -24,7 +24,7 @@ /* * @test * @bug 8371864 - * @run main/othervm TestAesGcmIntrinsic + * @run main/othervm TestGCMSplitBound * @summary Test GaloisCounterMode.implGCMCrypt0 AVX512/AVX2 intrinsics. */ @@ -36,7 +36,7 @@ import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; -public class TestAesGcmIntrinsic { +public class TestGCMSplitBound { static final SecureRandom SECURE_RANDOM = newDefaultSecureRandom(); @@ -90,7 +90,7 @@ private void jitFunc() throws Exception { throw new RuntimeException("ciphertext is null"); } } - for (int messageSize = SPLIT_LEN; messageSize < SPLIT_LEN + 300; messageSize++) { + for (int messageSize = SPLIT_LEN - 300; messageSize <= SPLIT_LEN + 300; messageSize++) { byte[] message = randBytes(messageSize); try { byte[] ciphertext = gcmEncrypt(key, message, aad); @@ -104,7 +104,7 @@ private void jitFunc() throws Exception { } public static void main(String[] args) throws Exception { - TestAesGcmIntrinsic test = new TestAesGcmIntrinsic(); + TestGCMSplitBound test = new TestGCMSplitBound(); long startTime = System.currentTimeMillis(); while (System.currentTimeMillis() - startTime < 60 * 1000) { test.jitFunc(); From f1e7291b53940d64665cc70f3316f66f15961ad6 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Wed, 19 Nov 2025 20:50:27 -0800 Subject: [PATCH 07/13] Address shipilev coments: - Replace time-bound loop with an iteration of three runs. - Add encrypt part and check to make sure the encrypted message is the same as the original. --- .../Cipher/AES/TestGCMSplitBound.java | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java index 86db34d6239ae..651d030f24e0c 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java @@ -24,13 +24,14 @@ /* * @test * @bug 8371864 - * @run main/othervm TestGCMSplitBound + * @run main/othervm/timeout=600 TestGCMSplitBound * @summary Test GaloisCounterMode.implGCMCrypt0 AVX512/AVX2 intrinsics. */ import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.time.Duration; +import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; @@ -55,9 +56,8 @@ private static byte[] randBytes(int size) { private static final int IV_SIZE_IN_BYTES = 12; private static final int TAG_SIZE_IN_BYTES = 16; - private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] aad) + private Cipher getCipher(final byte[] key, final byte[] aad, byte[] nonce) throws Exception { - byte[] nonce = randBytes(IV_SIZE_IN_BYTES); SecretKey keySpec = new SecretKeySpec(key, "AES"); AlgorithmParameterSpec params = new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, nonce, 0, nonce.length); @@ -66,6 +66,13 @@ private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] if (aad != null && aad.length != 0) { cipher.updateAAD(aad); } + return cipher; + } + + private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] aad) + throws Exception { + byte[] nonce = randBytes(IV_SIZE_IN_BYTES); + Cipher cipher = getCipher(key, aad, nonce); int outputSize = cipher.getOutputSize(plaintext.length); int len = IV_SIZE_IN_BYTES + outputSize; byte[] output = new byte[len]; @@ -74,40 +81,55 @@ private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] return output; } + private byte[] gcmDecrypt(final byte[] key, final byte[] ciphertext, final byte[] aad) + throws Exception { + byte[] nonce = randBytes(IV_SIZE_IN_BYTES); + System.arraycopy(ciphertext, 0, nonce, 0, IV_SIZE_IN_BYTES); + Cipher cipher = getCipher(key, aad, nonce); + return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES); + } + // x86-64 parallel intrinsic data size private static final int PARALLEL_LEN = 512; // max data size for x86-64 intrinsic private static final int SPLIT_LEN = 1048576; // 1MB - private void jitFunc() throws Exception { + private void encryptAndDecrypt(byte[] key, byte[] aad, byte[] message, int messageSize) + throws Exception { + byte[] ciphertext = gcmEncrypt(key, message, aad); + byte[] decrypted = gcmDecrypt(key, ciphertext, aad); + if (ciphertext == null) { + throw new RuntimeException("ciphertext is null"); + } + if (Arrays.compare(decrypted, 0, messageSize, message, 0, messageSize) != 0) { + throw new RuntimeException( + "Decrypted message is different from the original message"); + } + } + + private void run() throws Exception { byte[] aad = randBytes(20); byte[] key = randBytes(16); // Force JIT. for (int i = 0; i < 100000; i++) { byte[] message = randBytes(PARALLEL_LEN); - byte[] ciphertext = gcmEncrypt(key, message, aad); - if (ciphertext == null) { - throw new RuntimeException("ciphertext is null"); - } + encryptAndDecrypt(key, aad, message, PARALLEL_LEN); } for (int messageSize = SPLIT_LEN - 300; messageSize <= SPLIT_LEN + 300; messageSize++) { byte[] message = randBytes(messageSize); try { - byte[] ciphertext = gcmEncrypt(key, message, aad); - if (ciphertext == null) { - throw new RuntimeException("ciphertext is null"); - } + encryptAndDecrypt(key, aad, message, messageSize); } catch (Exception e) { - throw new Exception("Failed for messageSize " + Integer.toHexString(messageSize), e); + throw new RuntimeException( + "Failed for messageSize " + Integer.toHexString(messageSize), e); } } } public static void main(String[] args) throws Exception { TestGCMSplitBound test = new TestGCMSplitBound(); - long startTime = System.currentTimeMillis(); - while (System.currentTimeMillis() - startTime < 60 * 1000) { - test.jitFunc(); + for (int i = 0; i < 3; i++) { + test.run(); } } } From 528b1b47ad5a9590449bd652bb21c857cdc02cfd Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Wed, 19 Nov 2025 20:58:49 -0800 Subject: [PATCH 08/13] Fix Whitespace error. --- .../com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java index 651d030f24e0c..76cae9f735212 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java @@ -86,7 +86,7 @@ private byte[] gcmDecrypt(final byte[] key, final byte[] ciphertext, final byte[ byte[] nonce = randBytes(IV_SIZE_IN_BYTES); System.arraycopy(ciphertext, 0, nonce, 0, IV_SIZE_IN_BYTES); Cipher cipher = getCipher(key, aad, nonce); - return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES); + return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES); } // x86-64 parallel intrinsic data size From e99a441babb63d3ba804e8a39fa535e503b682a6 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Thu, 20 Nov 2025 11:57:06 -0800 Subject: [PATCH 09/13] Fix indentation --- .../sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java index 76cae9f735212..d07cdabba54fd 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java @@ -83,10 +83,10 @@ private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] private byte[] gcmDecrypt(final byte[] key, final byte[] ciphertext, final byte[] aad) throws Exception { - byte[] nonce = randBytes(IV_SIZE_IN_BYTES); - System.arraycopy(ciphertext, 0, nonce, 0, IV_SIZE_IN_BYTES); - Cipher cipher = getCipher(key, aad, nonce); - return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES); + byte[] nonce = randBytes(IV_SIZE_IN_BYTES); + System.arraycopy(ciphertext, 0, nonce, 0, IV_SIZE_IN_BYTES); + Cipher cipher = getCipher(key, aad, nonce); + return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES); } // x86-64 parallel intrinsic data size From 54fbf2b1f8f82a03511320d888defb85fdd4d4d6 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou <35976689+jianglizhou@users.noreply.github.com> Date: Thu, 20 Nov 2025 12:07:03 -0800 Subject: [PATCH 10/13] Update test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Applied, thanks. Co-authored-by: Aleksey Shipilëv --- .../com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java index d07cdabba54fd..4c8febe3c4086 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java @@ -56,7 +56,7 @@ private static byte[] randBytes(int size) { private static final int IV_SIZE_IN_BYTES = 12; private static final int TAG_SIZE_IN_BYTES = 16; - private Cipher getCipher(final byte[] key, final byte[] aad, byte[] nonce) + private Cipher getCipher(final byte[] key, final byte[] aad, final byte[] nonce) throws Exception { SecretKey keySpec = new SecretKeySpec(key, "AES"); AlgorithmParameterSpec params = From ee583233089d96026dcd5139da08ad4004b5fb9b Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Thu, 20 Nov 2025 15:55:43 -0800 Subject: [PATCH 11/13] Use Cipher.DECRYPT_MODE for gcmDecrypt. --- .../sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java index d07cdabba54fd..3442c57a46889 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java @@ -56,13 +56,13 @@ private static byte[] randBytes(int size) { private static final int IV_SIZE_IN_BYTES = 12; private static final int TAG_SIZE_IN_BYTES = 16; - private Cipher getCipher(final byte[] key, final byte[] aad, byte[] nonce) + private Cipher getCipher(final byte[] key, final byte[] aad, final byte[] nonce, int mode) throws Exception { SecretKey keySpec = new SecretKeySpec(key, "AES"); AlgorithmParameterSpec params = new GCMParameterSpec(8 * TAG_SIZE_IN_BYTES, nonce, 0, nonce.length); Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); - cipher.init(Cipher.ENCRYPT_MODE, keySpec, params); + cipher.init(mode, keySpec, params); if (aad != null && aad.length != 0) { cipher.updateAAD(aad); } @@ -72,7 +72,7 @@ private Cipher getCipher(final byte[] key, final byte[] aad, byte[] nonce) private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] aad) throws Exception { byte[] nonce = randBytes(IV_SIZE_IN_BYTES); - Cipher cipher = getCipher(key, aad, nonce); + Cipher cipher = getCipher(key, aad, nonce, Cipher.ENCRYPT_MODE); int outputSize = cipher.getOutputSize(plaintext.length); int len = IV_SIZE_IN_BYTES + outputSize; byte[] output = new byte[len]; @@ -85,7 +85,7 @@ private byte[] gcmDecrypt(final byte[] key, final byte[] ciphertext, final byte[ throws Exception { byte[] nonce = randBytes(IV_SIZE_IN_BYTES); System.arraycopy(ciphertext, 0, nonce, 0, IV_SIZE_IN_BYTES); - Cipher cipher = getCipher(key, aad, nonce); + Cipher cipher = getCipher(key, aad, nonce, Cipher.DECRYPT_MODE); return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES); } From d26d0ee9c2b9375824f2bfebb670a44ed5859a5e Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Thu, 20 Nov 2025 17:22:02 -0800 Subject: [PATCH 12/13] Change to just create a byte array for 'nonce' without generating random data in gcmDecrypt. Suggested by AI. --- .../com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java index 3442c57a46889..f4ff7fae68aac 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/AES/TestGCMSplitBound.java @@ -83,7 +83,7 @@ private byte[] gcmEncrypt(final byte[] key, final byte[] plaintext, final byte[] private byte[] gcmDecrypt(final byte[] key, final byte[] ciphertext, final byte[] aad) throws Exception { - byte[] nonce = randBytes(IV_SIZE_IN_BYTES); + byte[] nonce = new byte[IV_SIZE_IN_BYTES]; System.arraycopy(ciphertext, 0, nonce, 0, IV_SIZE_IN_BYTES); Cipher cipher = getCipher(key, aad, nonce, Cipher.DECRYPT_MODE); return cipher.doFinal(ciphertext, IV_SIZE_IN_BYTES, ciphertext.length - IV_SIZE_IN_BYTES); From 4ea57ee75c1863dfbc6c35759093d4c5cb2fd581 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Sat, 22 Nov 2025 20:48:25 -0800 Subject: [PATCH 13/13] Fixed the ENCRYPT_16_BLKS fall through case that sviswa7 pointed out in PR review. --- src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp index 98fdd60700f9d..1e728ffa2794e 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp @@ -3524,12 +3524,10 @@ void StubGenerator::aesgcm_avx512(Register in, Register len, Register ct, Regist false, true, false, false, false, ghashin_offset, aesout_offset, HashKey_32); ghash16_avx512(false, true, false, false, true, in, pos, avx512_subkeyHtbl, AAD_HASHx, SHUF_MASK, stack_offset, 16 * 16, 0, HashKey_16); + __ addl(pos, 16 * 16); __ bind(MESG_BELOW_32_BLKS); __ subl(len, 16 * 16); - __ cmpl(len, 16 * 16); - __ jcc(Assembler::lessEqual, ENC_DEC_DONE); - __ addl(pos, 16 * 16); gcm_enc_dec_last_avx512(len, in, pos, AAD_HASHx, SHUF_MASK, avx512_subkeyHtbl, ghashin_offset, HashKey_16, true, true); __ bind(GHASH_DONE);