From e5e0c736ca4c3eafe7bddb5b39805e5ddb38d726 Mon Sep 17 00:00:00 2001 From: Benshuai5D Date: Sat, 3 Aug 2024 15:27:34 +0800 Subject: [PATCH] IAHM8D: Extending the IV Length Supported by KAEProvider AES/Gcm --- ...tStream-readTrailer-uses-faulty-avai.patch | 147 ++++++++++++++++++ ...-Length-Supported-by-KAEProvider-AES.patch | 137 ++++++++++++++++ openjdk-17.spec | 12 +- 3 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch create mode 100644 Huawei-Extending-the-IV-Length-Supported-by-KAEProvider-AES.patch diff --git a/Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch b/Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch new file mode 100644 index 0000000..01e688e --- /dev/null +++ b/Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch @@ -0,0 +1,147 @@ +From d99167036135396d6bdd798027c4d669e5765e7f Mon Sep 17 00:00:00 2001 +Subject: 7036144:GZIPInputStream readTrailer uses faulty available() test for end-of-stream +--- + .../java/util/zip/GZIPInputStream.java | 24 ++--- + .../zip/GZIP/GZIPInputStreamAvailable.java | 93 +++++++++++++++++++ + 2 files changed, 102 insertions(+), 15 deletions(-) + create mode 100644 test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java + +diff --git a/src/java.base/share/classes/java/util/zip/GZIPInputStream.java b/src/java.base/share/classes/java/util/zip/GZIPInputStream.java +index 613a02bba..4f3f9eae4 100644 +--- a/src/java.base/share/classes/java/util/zip/GZIPInputStream.java ++++ b/src/java.base/share/classes/java/util/zip/GZIPInputStream.java +@@ -224,23 +224,17 @@ public class GZIPInputStream extends InflaterInputStream { + (readUInt(in) != (inf.getBytesWritten() & 0xffffffffL))) + throw new ZipException("Corrupt GZIP trailer"); + +- // If there are more bytes available in "in" or +- // the leftover in the "inf" is > 26 bytes: +- // this.trailer(8) + next.header.min(10) + next.trailer(8) + // try concatenated case +- if (this.in.available() > 0 || n > 26) { +- int m = 8; // this.trailer +- try { +- m += readHeader(in); // next.header +- } catch (IOException ze) { +- return true; // ignore any malformed, do nothing +- } +- inf.reset(); +- if (n > m) +- inf.setInput(buf, len - n + m, n - m); +- return false; ++ int m = 8; // this.trailer ++ try { ++ m += readHeader(in); // next.header ++ } catch (IOException ze) { ++ return true; // ignore any malformed, do nothing + } +- return true; ++ inf.reset(); ++ if (n > m) ++ inf.setInput(buf, len - n + m, n - m); ++ return false; + } + + /* +diff --git a/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java b/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java +new file mode 100644 +index 000000000..1468c104f +--- /dev/null ++++ b/test/jdk/java/util/zip/GZIP/GZIPInputStreamAvailable.java +@@ -0,0 +1,93 @@ ++/* ++ * Copyright (c) 2023, Oracle and/or its affiliates. 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 7036144 ++ * @summary Test concatenated gz streams when available() returns zero ++ * @run junit GZIPInputStreamAvailable ++ */ ++ ++import org.junit.jupiter.api.Test; ++ ++import java.io.*; ++import java.util.*; ++import java.util.zip.*; ++ ++import static org.junit.jupiter.api.Assertions.assertArrayEquals; ++ ++public class GZIPInputStreamAvailable { ++ ++ public static final int NUM_COPIES = 100; ++ ++ @Test ++ public void testZeroAvailable() throws IOException { ++ ++ // Create some uncompressed data and then repeat it NUM_COPIES times ++ byte[] uncompressed1 = "this is a test".getBytes("ASCII"); ++ byte[] uncompressedN = repeat(uncompressed1, NUM_COPIES); ++ ++ // Compress the original data and then repeat that NUM_COPIES times ++ byte[] compressed1 = deflate(uncompressed1); ++ byte[] compressedN = repeat(compressed1, NUM_COPIES); ++ ++ // (a) Read back inflated data from a stream where available() is accurate and verify ++ byte[] readback1 = inflate(new ByteArrayInputStream(compressedN)); ++ assertArrayEquals(uncompressedN, readback1); ++ ++ // (b) Read back inflated data from a stream where available() always returns zero and verify ++ byte[] readback2 = inflate(new ZeroAvailableStream(new ByteArrayInputStream(compressedN))); ++ assertArrayEquals(uncompressedN, readback2); ++ } ++ ++ public static byte[] repeat(byte[] data, int count) { ++ byte[] repeat = new byte[data.length * count]; ++ int off = 0; ++ for (int i = 0; i < count; i++) { ++ System.arraycopy(data, 0, repeat, off, data.length); ++ off += data.length; ++ } ++ return repeat; ++ } ++ ++ public static byte[] deflate(byte[] data) throws IOException { ++ ByteArrayOutputStream buf = new ByteArrayOutputStream(); ++ try (GZIPOutputStream out = new GZIPOutputStream(buf)) { ++ out.write(data); ++ } ++ return buf.toByteArray(); ++ } ++ ++ public static byte[] inflate(InputStream in) throws IOException { ++ return new GZIPInputStream(in).readAllBytes(); ++ } ++ ++ public static class ZeroAvailableStream extends FilterInputStream { ++ public ZeroAvailableStream(InputStream in) { ++ super(in); ++ } ++ @Override ++ public int available() { ++ return 0; ++ } ++ } ++} +-- +2.23.0 + diff --git a/Huawei-Extending-the-IV-Length-Supported-by-KAEProvider-AES.patch b/Huawei-Extending-the-IV-Length-Supported-by-KAEProvider-AES.patch new file mode 100644 index 0000000..eb6b171 --- /dev/null +++ b/Huawei-Extending-the-IV-Length-Supported-by-KAEProvider-AES.patch @@ -0,0 +1,137 @@ +From 0a09586f510fb92a4e9eec3aa87fd9673b7b68a7 Mon Sep 17 00:00:00 2001 +Subject: Extending the IV Length Supported by KAEProvider AES/Gcm + +--- + .../security/openssl/kae_symmetric_cipher.c | 23 ++++++-- + .../security/openssl/KAEGcmIvLenTest.java | 53 +++++++++++++++++++ + 2 files changed, 73 insertions(+), 3 deletions(-) + create mode 100644 test/jdk/org/openeuler/security/openssl/KAEGcmIvLenTest.java + +diff --git a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c +index 67151f53a..220964d5f 100644 +--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c ++++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c +@@ -146,6 +146,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en + const EVP_CIPHER* cipher = NULL; + ENGINE* kaeEngine = NULL; + int keyLength = (*env)->GetArrayLength(env, key); ++ int ivLength = 0; + + const char* algo = (*env)->GetStringUTFChars(env, cipherType, 0); + if (StartsWith("aes", algo)) { +@@ -158,7 +159,6 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en + + KAE_TRACE("KAESymmetricCipherBase_nativeInit: kaeEngine => %p", kaeEngine); + +- (*env)->ReleaseStringUTFChars(env, cipherType, algo); + if (cipher == NULL) { + KAE_ThrowOOMException(env, "create EVP_CIPHER fail"); + goto cleanup; +@@ -170,19 +170,35 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en + + if (iv != NULL) { + ivBytes = (*env)->GetByteArrayElements(env, iv, NULL); ++ ivLength = (*env)->GetArrayLength(env, iv); + } + if (key != NULL) { + keyBytes = (*env)->GetByteArrayElements(env, key, NULL); + } + +- if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, (const unsigned char*)keyBytes, +- (const unsigned char*)ivBytes, encrypt ? 1 : 0)) { ++ if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, NULL, ++ NULL, encrypt ? 1 : 0)) { + KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex failed", KAE_ThrowRuntimeException); + goto cleanup; + } + ++ if (strcasecmp(algo + 8, "gcm") == 0) { ++ /* Set IV length if default 12 bytes (96 bits) is not appropriate */ ++ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivLength, NULL)) { ++ KAE_ThrowFromOpenssl(env, "EVP_CIPHER_CTX_ctrl failed", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ } ++ ++ if (!EVP_CipherInit_ex(ctx, NULL, kaeEngine, (const unsigned char*)keyBytes, ++ (const unsigned char*)ivBytes, encrypt ? 1 : 0)) { ++ KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex int key & iv failed", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ + EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0); + ++ (*env)->ReleaseStringUTFChars(env, cipherType, algo); + FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength); + return (jlong)ctx; + +@@ -190,6 +206,7 @@ cleanup: + if (ctx != NULL) { + EVP_CIPHER_CTX_free(ctx); + } ++ (*env)->ReleaseStringUTFChars(env, cipherType, algo); + FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength); + return 0; + } +diff --git a/test/jdk/org/openeuler/security/openssl/KAEGcmIvLenTest.java b/test/jdk/org/openeuler/security/openssl/KAEGcmIvLenTest.java +new file mode 100644 +index 000000000..444e47264 +--- /dev/null ++++ b/test/jdk/org/openeuler/security/openssl/KAEGcmIvLenTest.java +@@ -0,0 +1,53 @@ ++import org.openeuler.security.openssl.KAEProvider; ++ ++import javax.crypto.Cipher; ++import javax.crypto.spec.GCMParameterSpec; ++import javax.crypto.spec.SecretKeySpec; ++import java.nio.charset.StandardCharsets; ++import java.security.Security; ++import java.util.Arrays; ++ ++/** ++ * @test ++ * @summary Basic test for AES/GCM Iv ++ * @modules jdk.crypto.kaeprovider/org.openeuler.security.openssl ++ * @requires os.arch=="aarch64" ++ * @run main KAEGcmIvLenTest ++ */ ++public class KAEGcmIvLenTest { ++ private static String plainText = "helloworldhellow"; // 16bytes for NoPadding ++ private static String shortPlainText = "helloworld"; // 5 bytes for padding ++ private static SecretKeySpec ks = new SecretKeySpec("AESEncryptionKey".getBytes(StandardCharsets.UTF_8), "AES"); // key has 16 bytes ++ private static int[] ivLens = {12, 16}; ++ public static void main(String[] args) throws Exception { ++ Security.addProvider(new KAEProvider()); ++ for (int ivLen : ivLens) { ++ testGcm(plainText,"AES/GCM/NoPadding", "KAEProvider", "SunJCE", ivLen); ++ testGcm(plainText,"AES/GCM/NoPadding", "SunJCE", "KAEProvider", ivLen); ++ testGcm(shortPlainText,"AES/GCM/NoPadding", "KAEProvider", "SunJCE", ivLen); ++ testGcm(shortPlainText,"AES/GCM/NoPadding", "SunJCE", "KAEProvider", ivLen); ++ } ++ ++ } ++ ++ private static void testGcm(String plainText, String algo, String encryptProvider, String decryptProvider, int ivLen) throws Exception { ++ Cipher enCipher = Cipher.getInstance(algo, encryptProvider); ++ enCipher.init(Cipher.ENCRYPT_MODE, ks, getIv(ivLen)); ++ byte[] cipherText = enCipher.doFinal(plainText.getBytes()); ++ ++ Cipher deCipher = Cipher.getInstance(algo, decryptProvider); ++ deCipher.init(Cipher.DECRYPT_MODE, ks, getIv(ivLen)); ++ byte[] origin = deCipher.doFinal(cipherText); ++ ++ if (!Arrays.equals(plainText.getBytes(), origin)) { ++ throw new RuntimeException("gcm decryption failed, algo = " + algo); ++ } ++ } ++ ++ private static GCMParameterSpec getIv(int ivLen) { ++ if (ivLen == 16) { ++ return new GCMParameterSpec(128, "abcdefghabcdefgh".getBytes(StandardCharsets.UTF_8)); ++ } ++ return new GCMParameterSpec(96, "abcdefghabcd".getBytes(StandardCharsets.UTF_8)); ++ } ++} +-- +2.19.1 + diff --git a/openjdk-17.spec b/openjdk-17.spec index 6fde297..339ae75 100644 --- a/openjdk-17.spec +++ b/openjdk-17.spec @@ -903,7 +903,7 @@ Provides: java-src%{?1} = %{epoch}:%{version}-%{release} Name: java-%{javaver}-%{origin} Version: %{newjavaver}.%{buildver} -Release: 1 +Release: 2 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages @@ -1013,6 +1013,10 @@ Patch43: puyuan-jdk17.0.9-patch.patch #17.0.11 Patch44: jdk17-Add-KAE-provider.patch +#17.0.12 +Patch45: Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch +Patch46: Huawei-Extending-the-IV-Length-Supported-by-KAEProvider-AES.patch + ############################################ # # LoongArch64 specific patches @@ -1270,6 +1274,8 @@ pushd %{top_level_dir_name} %patch42 -p1 %patch43 -p1 %patch44 -p1 +%patch45 -p1 +%patch46 -p1 popd # openjdk %endif @@ -1837,6 +1843,10 @@ cjc.mainProgram(args) -- the returns from copy_jdk_configs.lua should not affect %changelog +* Sat Aug 3 2024 kuenking111 - 1:17.0.12.7-2 +- add Huawei-Extending-the-IV-Length-Supported-by-KAEProvider-AES.patch +- add Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch + * Thu Jul 25 2024 songliyang - 1:17.0.12.7-1 - update Loongarch support patch to fix the error while applying in prep stage - delete redundant symbols while viewing spec file with vim that make it strange on highlight -- Gitee