From 33a47c2cea429c924c463b2aea25622e598d648d Mon Sep 17 00:00:00 2001 From: Benshuai5D Date: Fri, 28 Nov 2025 01:23:53 +0800 Subject: [PATCH] add huawei-JDK8-adapts-to-OpenSSL3.patch --- huawei-JDK8-adapts-to-OpenSSL3.patch | 8170 ++++++++++++++++++++++++++ openjdk-1.8.0.spec | 7 +- 2 files changed, 8176 insertions(+), 1 deletion(-) create mode 100644 huawei-JDK8-adapts-to-OpenSSL3.patch diff --git a/huawei-JDK8-adapts-to-OpenSSL3.patch b/huawei-JDK8-adapts-to-OpenSSL3.patch new file mode 100644 index 0000000..660803b --- /dev/null +++ b/huawei-JDK8-adapts-to-OpenSSL3.patch @@ -0,0 +1,8170 @@ +Date: Fri, 28 Nov 2025 01:08:47 +0800 +Subject: [PATCH] JDK8 adapts to OpenSSL3 + +--- + .../make/linux/makefiles/mapfile-vers-product | 8 + + jdk/make/lib/SecurityLibraries.gmk | 2 +- + jdk/make/mapfiles/libj2kae/mapfile-vers | 11 + + jdk/src/share/lib/security/kaeprovider.conf | 17 +- + .../openeuler/security/openssl/KAEConfig.java | 22 +- + .../security/openssl/KAECurveDB.java | 758 +++++++++ + .../security/openssl/KAEECDHKeyAgreement.java | 12 +- + .../security/openssl/KAEECKeyFactory.java | 291 ++++ + .../openssl/KAEECKeyPairGenerator.java | 15 +- + .../security/openssl/KAEECParameters.java | 241 +++ + .../security/openssl/KAEECPrivateKeyImpl.java | 232 +++ + .../security/openssl/KAEECPublicKeyImpl.java | 148 ++ + .../security/openssl/KAENamedCurve.java | 87 ++ + .../security/openssl/KAEProvider.java | 63 +- + .../security/openssl/KAESM2Cipher.java | 385 +++++ + .../openssl/KAESM2KeyPairGenerator.java | 108 ++ + .../security/openssl/KAESM2Signature.java | 373 +++++ + .../openeuler/security/openssl/KAEUtils.java | 35 + + .../security/openssl/kae_cipher_rsa.c | 69 +- + .../security/openssl/kae_cipher_sm2.c | 368 +++++ + .../openeuler/security/openssl/kae_digest.c | 28 +- + .../security/openssl/kae_exception.c | 19 +- + .../security/openssl/kae_exception.h | 7 + + .../org/openeuler/security/openssl/kae_hmac.c | 25 +- + .../security/openssl/kae_keyagreement_dh.c | 19 +- + .../security/openssl/kae_keyagreement_ecdh.c | 23 +- + .../openssl/kae_keypairgenerator_dh.c | 15 +- + .../openssl/kae_keypairgenerator_ec.c | 95 +- + .../openssl/kae_keypairgenerator_rsa.c | 25 +- + .../openeuler/security/openssl/kae_provider.c | 59 +- + .../security/openssl/kae_signature_rsa.c | 47 +- + .../security/openssl/kae_signature_sm2.c | 286 ++++ + .../security/openssl/kae_symmetric_cipher.c | 61 +- + .../org/openeuler/security/openssl/kae_util.c | 25 +- + .../org/openeuler/security/openssl/kae_util.h | 6 +- + .../security/openssl/openssl1_macro.h | 55 + + .../security/openssl/openssl3_macro.h | 37 + + .../openeuler/security/openssl/ssl_utils.c | 1372 +++++++++++++++++ + .../openeuler/security/openssl/ssl_utils.h | 313 ++++ + .../security/openssl/SM2CipherBenchmark.java | 117 ++ + .../openssl/SM2SignatureBenchmark.java | 104 ++ + .../openeuler/security/openssl/ECDHTest.java | 24 +- + .../security/openssl/KAEConfTest.java | 21 +- + .../security/openssl/KAETestHelper.java | 3 +- + .../security/openssl/KAEUseEngineTest.java | 54 +- + .../security/openssl/KaeProviderTest.java | 32 +- + .../openeuler/security/openssl/SM2Test.java | 174 +++ + 47 files changed, 5967 insertions(+), 324 deletions(-) + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAECurveDB.java + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyFactory.java + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECParameters.java + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECPrivateKeyImpl.java + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECPublicKeyImpl.java + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAENamedCurve.java + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2Cipher.java + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2KeyPairGenerator.java + create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2Signature.java + create mode 100644 jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_sm2.c + create mode 100644 jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_sm2.c + create mode 100644 jdk/src/solaris/native/org/openeuler/security/openssl/openssl1_macro.h + create mode 100644 jdk/src/solaris/native/org/openeuler/security/openssl/openssl3_macro.h + create mode 100644 jdk/src/solaris/native/org/openeuler/security/openssl/ssl_utils.c + create mode 100644 jdk/src/solaris/native/org/openeuler/security/openssl/ssl_utils.h + create mode 100644 jdk/test/micro/org/openeuler/bench/security/openssl/SM2CipherBenchmark.java + create mode 100644 jdk/test/micro/org/openeuler/bench/security/openssl/SM2SignatureBenchmark.java + create mode 100644 jdk/test/org/openeuler/security/openssl/SM2Test.java + +diff --git a/hotspot/make/linux/makefiles/mapfile-vers-product b/hotspot/make/linux/makefiles/mapfile-vers-product +index 713bc9cf0..99aa04473 100644 +--- a/hotspot/make/linux/makefiles/mapfile-vers-product ++++ b/hotspot/make/linux/makefiles/mapfile-vers-product +@@ -277,6 +277,14 @@ SUNWprivate_1.1 { + AsyncGetCallTrace; + + # INSERT EXTENDED SYMBOLS HERE ++ # EXTENDED SYMBOLS START ++ HeapDict_Add; ++ HeapDict_Lookup; ++ HeapDict_Free; ++ HeapVector_Add; ++ HeapVector_GetNext; ++ HeapVector_Free; ++ # EXTENDED SYMBOLS END + + # INSERT VTABLE SYMBOLS HERE + +diff --git a/jdk/make/lib/SecurityLibraries.gmk b/jdk/make/lib/SecurityLibraries.gmk +index fcded0a46..bf44687ec 100644 +--- a/jdk/make/lib/SecurityLibraries.gmk ++++ b/jdk/make/lib/SecurityLibraries.gmk +@@ -317,7 +317,7 @@ ifeq ($(ENABLE_KAE), true) + MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2kae/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ +- LDFLAGS_SUFFIX_linux := $(LIBDL) -lssl -lcrypto, \ ++ LDFLAGS_SUFFIX_linux := $(LIBDL) -lm, \ + LDFLAGS_SUFFIX_posix := $(LIBDL), \ + LDFLAGS_SUFFIX_solaris := -lc, \ + VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \ +diff --git a/jdk/make/mapfiles/libj2kae/mapfile-vers b/jdk/make/mapfiles/libj2kae/mapfile-vers +index a1bdb830b..955599942 100644 +--- a/jdk/make/mapfiles/libj2kae/mapfile-vers ++++ b/jdk/make/mapfiles/libj2kae/mapfile-vers +@@ -62,6 +62,17 @@ SUNWprivate_1.1 { + Java_org_openeuler_security_openssl_KAERSASignatureNative_rsaVerify; + Java_org_openeuler_security_openssl_KAERSASignatureNative_pssSign; + Java_org_openeuler_security_openssl_KAERSASignatureNative_pssVerify; ++ Java_org_openeuler_security_openssl_KAESM2Cipher_nativeCreateSM2PublicKey; ++ Java_org_openeuler_security_openssl_KAESM2Cipher_nativeCreateSM2PrivateKey; ++ Java_org_openeuler_security_openssl_KAESM2Cipher_nativeFreeKey; ++ Java_org_openeuler_security_openssl_KAESM2Cipher_nativeSM2Encrypt; ++ Java_org_openeuler_security_openssl_KAESM2Cipher_nativeSM2Decrypt; ++ Java_org_openeuler_security_openssl_KAESM2Signature_nativeClone; ++ Java_org_openeuler_security_openssl_KAESM2Signature_nativeFreeSM2Ctx; ++ Java_org_openeuler_security_openssl_KAESM2Signature_nativeInitSM2Ctx; ++ Java_org_openeuler_security_openssl_KAESM2Signature_nativeSM2Update; ++ Java_org_openeuler_security_openssl_KAESM2Signature_nativeSM2SignFinal; ++ Java_org_openeuler_security_openssl_KAESM2Signature_nativeSM2VerifyFinal; + + local: + *; +diff --git a/jdk/src/share/lib/security/kaeprovider.conf b/jdk/src/share/lib/security/kaeprovider.conf +index cc50611d1..b299718ee 100644 +--- a/jdk/src/share/lib/security/kaeprovider.conf ++++ b/jdk/src/share/lib/security/kaeprovider.conf +@@ -18,14 +18,12 @@ + # kae.rsa=false + # kae.dh=false + # kae.ec=false ++# kae.sm2.cipher=false ++# kae.sm2.signature=false + + # Configure engine id, the default value is kae. + # kae.engine.id=kae + +-# Configure whether libcrypto.so uses GLOBAL mode, uses LOCAL mode by default. +-# If you use uadk_engine, you need to enable this option. +-# kae.libcrypto.useGlobalMode=false +- + # The following configuration will only take effect when using KAEProvider. + # Configure whether to enable KAE hardware acceleration for each category of algorithm. + # The configurable value are as follows: +@@ -42,9 +40,11 @@ + # kae.rsa.useKaeEngine=true + # kae.dh.useKaeEngine=true + # kae.ec.useKaeEngine=false ++# kae.sm2.useKaeEngine=false + # + # Some engines do not fully support certain categories of algorithms, for example, the digest +-# algorithm implemented by kae engine only supports md5 and sm3.For more information, please refer to: ++# algorithm implemented by kae engine only supports md5 and sm3, asymmetric cipher not support sm2. ++# For more information, please refer to: + # KAE : https://github.com/kunpengcompute/KAE#:~:text=Digest%20algorithm%3A%20SM3/MD5 + # UADK: https://gitee.com/openeuler/uadk/wikis/%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3/UADK%20quick%20start#11-uadk + # +@@ -60,13 +60,18 @@ + # rsa : rsa + # dh : dh + # ec : ec +-# kae.engine.disabledAlgorithms=sha256,sha384 ++# sm2 : sm2 ++# kae.engine.disabledAlgorithms=sha256,sha384,sm2 + + # SM4 max chunk size of each encryption or decryption. + # when input data does not have an accessible byte[]. + # The default value is 4096, when configuring a non-positive Integer type, use the default value of 4096. + # kae.sm4.maxChunkSize=4096 + ++# Which Openssl version prefer to use. Default value is 0, representing that default policy(firstly find 3, if 3 not exist then find 1) ++# If definite version is decided, can set value to 1 or 3 to choose definitely version, other value will report error. ++# kae.useOpensslVersion=0 ++# + # Enable engine load log. + # kae.log=true + # +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEConfig.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEConfig.java +index 07294dbd6..6f6db5f74 100644 +--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEConfig.java ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEConfig.java +@@ -51,7 +51,9 @@ public class KAEConfig { + "kae.hmac", + "kae.rsa", + "kae.dh", +- "kae.ec" ++ "kae.ec", ++ "kae.sm2.cipher", ++ "kae.sm2.signature" + }; + + // these property names indicate whether KAE hardware acceleration is enabled for each algorithm +@@ -62,7 +64,8 @@ public class KAEConfig { + "kae.hmac.useKaeEngine", + "kae.rsa.useKaeEngine", + "kae.dh.useKaeEngine", +- "kae.ec.useKaeEngine" ++ "kae.ec.useKaeEngine", ++ "kae.sm2.useKaeEngine" + }; + + // algorithm names +@@ -95,7 +98,8 @@ public class KAEConfig { + "hmac-sha512", + "rsa", + "dh", +- "ec" ++ "ec", ++ "sm2" + }; + + // algorithm name and algorithm index mapping +@@ -234,7 +238,8 @@ public class KAEConfig { + false, // hmac + true, // rsa + true, // dh +- false // ec ++ false, // ec ++ false // sm2 + }; + for (int i = 0; i < useKaeEnginePropertyNames.length; i++) { + String configValue = privilegedGetOverridable(useKaeEnginePropertyNames[i]); +@@ -243,8 +248,9 @@ public class KAEConfig { + } + } + +- // EC algorithm currently does not support KAE hardware acceleration, temporarily use openssl soft calculation. +- categoryFlagsForEngine[useKaeEnginePropertyNames.length - 1] = false; ++ // EC and SM2 algorithm currently does not support KAE hardware acceleration, temporarily use openssl soft calculation. ++ categoryFlagsForEngine[6] = false; ++ categoryFlagsForEngine[7] = false; + + for (int i = 0; i < useKaeEngineFlags.length; i++) { + Integer algorithmCategoryIndex = algorithmNameCategoryMap.get(algorithmNames[i]); +@@ -296,6 +302,7 @@ public class KAEConfig { + * 4 : rsa + * 5 : dh + * 6 : ec ++ * 7 : sm2 + */ + private static void initAlgorithmNameCategoryMap() { + algorithmNameCategoryMap.put("md5", 0); +@@ -327,6 +334,7 @@ public class KAEConfig { + algorithmNameCategoryMap.put("rsa", 4); + algorithmNameCategoryMap.put("dh", 5); + algorithmNameCategoryMap.put("ec", 6); ++ algorithmNameCategoryMap.put("sm2", 7); + } + + private static void initAlgorithmNameMap() { +@@ -336,7 +344,7 @@ public class KAEConfig { + + private static String[] getDisabledAlgorithms() { + String disabledAlgorithms = privilegedGetOverridable("kae.engine.disabledAlgorithms", +- "sha256,sha384"); ++ "sha256,sha384,sm2"); + return disabledAlgorithms.replaceAll(" ", "").split("\\,"); + } + +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAECurveDB.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAECurveDB.java +new file mode 100644 +index 000000000..95b03df35 +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAECurveDB.java +@@ -0,0 +1,758 @@ ++/* ++ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2023, Huawei Technologies Co., Ltd. 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import java.math.BigInteger; ++ ++import java.security.spec.*; ++ ++import java.util.*; ++import java.util.regex.Pattern; ++ ++import sun.security.util.ECUtil; ++ ++/** ++ * Repository for well-known Elliptic Curve parameters. It is used by both ++ * the SunPKCS11 and SunJSSE code. ++ * ++ * @since 1.6 ++ * @author Andreas Sterbenz ++ */ ++public class KAECurveDB { ++ private final static int P = 1; // prime curve ++ private final static int B = 2; // binary curve ++ private final static int PD = 5; // prime curve, mark as default ++ private final static int BD = 6; // binary curve, mark as default ++ ++ private static final Map oidMap = ++ new LinkedHashMap(); ++ private static final Map nameMap = ++ new HashMap(); ++ private static final Map lengthMap = ++ new HashMap(); ++ ++ private static Collection specCollection; ++ ++ public static final String SPLIT_PATTERN = ",|\\[|\\]"; ++ ++ // Used by SunECEntries ++ public static CollectiongetSupportedCurves() { ++ return specCollection; ++ } ++ ++ // Return a NamedCurve for the specified OID/name or null if unknown. ++ static KAENamedCurve lookup(String name) { ++ KAENamedCurve spec = oidMap.get(name); ++ if (spec != null) { ++ return spec; ++ } ++ ++ return nameMap.get(name); ++ } ++ ++ // Return EC parameters for the specified field size. If there are known ++ // NIST recommended parameters for the given length, they are returned. ++ // Otherwise, if there are multiple matches for the given size, an ++ // arbitrary one is returns. ++ // If no parameters are known, the method returns null. ++ // NOTE that this method returns both prime and binary curves. ++ static KAENamedCurve lookup(int length) { ++ return lengthMap.get(length); ++ } ++ ++ // Convert the given ECParameterSpec object to a NamedCurve object. ++ // If params does not represent a known named curve, return null. ++ static KAENamedCurve lookup(ECParameterSpec params) { ++ if ((params instanceof KAENamedCurve) || (params == null)) { ++ return (KAENamedCurve)params; ++ } ++ ++ // This is a hack to allow SunJSSE to work with 3rd party crypto ++ // providers for ECC and not just SunPKCS11. ++ // This can go away once we decide how to expose curve names in the ++ // public API. ++ // Note that it assumes that the 3rd party provider encodes named ++ // curves using the short form, not explicitly. If it did that, then ++ // the SunJSSE TLS ECC extensions are wrong, which could lead to ++ // interoperability problems. ++ int fieldSize = params.getCurve().getField().getFieldSize(); ++ for (KAENamedCurve namedCurve : specCollection) { ++ // ECParameterSpec does not define equals, so check all the ++ // components ourselves. ++ // Quick field size check first ++ if (namedCurve.getCurve().getField().getFieldSize() != fieldSize) { ++ continue; ++ } ++ if (ECUtil.equals(namedCurve, params)) { ++ // everything matches our named curve, return it ++ return namedCurve; ++ } ++ } ++ // no match found ++ return null; ++ } ++ ++ private static BigInteger bi(String s) { ++ return new BigInteger(s, 16); ++ } ++ ++ private static void add(String name, String soid, int type, String sfield, ++ String a, String b, String x, String y, String n, int h, ++ Pattern nameSplitPattern) { ++ BigInteger p = bi(sfield); ++ ECField field; ++ if ((type == P) || (type == PD)) { ++ field = new ECFieldFp(p); ++ } else if ((type == B) || (type == BD)) { ++ field = new ECFieldF2m(p.bitLength() - 1, p); ++ } else { ++ throw new RuntimeException("Invalid type: " + type); ++ } ++ ++ EllipticCurve curve = new EllipticCurve(field, bi(a), bi(b)); ++ ECPoint g = new ECPoint(bi(x), bi(y)); ++ ++ KAENamedCurve params = new KAENamedCurve(name, soid, curve, g, bi(n), h); ++ if (oidMap.put(soid, params) != null) { ++ throw new RuntimeException("Duplication oid: " + soid); ++ } ++ ++ String[] commonNames = nameSplitPattern.split(name); ++ for (String commonName : commonNames) { ++ if (nameMap.put(commonName.trim(), params) != null) { ++ throw new RuntimeException("Duplication name: " + commonName); ++ } ++ } ++ ++ int len = field.getFieldSize(); ++ if ((type == PD) || (type == BD) || (lengthMap.get(len) == null)) { ++ // add entry if none present for this field size or if ++ // the curve is marked as a default curve. ++ lengthMap.put(len, params); ++ } ++ } ++ ++ private static class Holder { ++ private static final Pattern nameSplitPattern = Pattern.compile( ++ SPLIT_PATTERN); ++ } ++ ++ // Return all the names the EC curve could be using. ++ static String[] getNamesByOID(String oid) { ++ KAENamedCurve nc = oidMap.get(oid); ++ if (nc == null) { ++ return new String[0]; ++ } ++ String[] list = Holder.nameSplitPattern.split(nc.getName()); ++ int i = 0; ++ do { ++ list[i] = list[i].trim(); ++ } while (++i < list.length); ++ return list; ++ } ++ ++ static { ++ Pattern nameSplitPattern = Holder.nameSplitPattern; ++ ++ /* SEC2 prime curves */ ++ add("secp112r1", "1.3.132.0.6", P, ++ "DB7C2ABF62E35E668076BEAD208B", ++ "DB7C2ABF62E35E668076BEAD2088", ++ "659EF8BA043916EEDE8911702B22", ++ "09487239995A5EE76B55F9C2F098", ++ "A89CE5AF8724C0A23E0E0FF77500", ++ "DB7C2ABF62E35E7628DFAC6561C5", ++ 1, nameSplitPattern); ++ ++ add("secp112r2", "1.3.132.0.7", P, ++ "DB7C2ABF62E35E668076BEAD208B", ++ "6127C24C05F38A0AAAF65C0EF02C", ++ "51DEF1815DB5ED74FCC34C85D709", ++ "4BA30AB5E892B4E1649DD0928643", ++ "adcd46f5882e3747def36e956e97", ++ "36DF0AAFD8B8D7597CA10520D04B", ++ 4, nameSplitPattern); ++ ++ add("secp128r1", "1.3.132.0.28", P, ++ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", ++ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", ++ "E87579C11079F43DD824993C2CEE5ED3", ++ "161FF7528B899B2D0C28607CA52C5B86", ++ "CF5AC8395BAFEB13C02DA292DDED7A83", ++ "FFFFFFFE0000000075A30D1B9038A115", ++ 1, nameSplitPattern); ++ ++ add("secp128r2", "1.3.132.0.29", P, ++ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", ++ "D6031998D1B3BBFEBF59CC9BBFF9AEE1", ++ "5EEEFCA380D02919DC2C6558BB6D8A5D", ++ "7B6AA5D85E572983E6FB32A7CDEBC140", ++ "27B6916A894D3AEE7106FE805FC34B44", ++ "3FFFFFFF7FFFFFFFBE0024720613B5A3", ++ 4, nameSplitPattern); ++ ++ add("secp160k1", "1.3.132.0.9", P, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", ++ "0000000000000000000000000000000000000000", ++ "0000000000000000000000000000000000000007", ++ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", ++ "938CF935318FDCED6BC28286531733C3F03C4FEE", ++ "0100000000000000000001B8FA16DFAB9ACA16B6B3", ++ 1, nameSplitPattern); ++ ++ add("secp160r1", "1.3.132.0.8", P, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", ++ "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", ++ "4A96B5688EF573284664698968C38BB913CBFC82", ++ "23A628553168947D59DCC912042351377AC5FB32", ++ "0100000000000000000001F4C8F927AED3CA752257", ++ 1, nameSplitPattern); ++ ++ add("secp160r2", "1.3.132.0.30", P, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", ++ "B4E134D3FB59EB8BAB57274904664D5AF50388BA", ++ "52DCB034293A117E1F4FF11B30F7199D3144CE6D", ++ "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", ++ "0100000000000000000000351EE786A818F3A1A16B", ++ 1, nameSplitPattern); ++ ++ add("secp192k1", "1.3.132.0.31", P, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", ++ "000000000000000000000000000000000000000000000000", ++ "000000000000000000000000000000000000000000000003", ++ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", ++ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", ++ "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", ++ 1, nameSplitPattern); ++ ++ add("secp192r1 [NIST P-192, X9.62 prime192v1]", "1.2.840.10045.3.1.1", PD, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", ++ "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", ++ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", ++ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", ++ "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", ++ 1, nameSplitPattern); ++ ++ add("secp224k1", "1.3.132.0.32", P, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", ++ "00000000000000000000000000000000000000000000000000000000", ++ "00000000000000000000000000000000000000000000000000000005", ++ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", ++ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", ++ "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", ++ 1, nameSplitPattern); ++ ++ add("secp224r1 [NIST P-224]", "1.3.132.0.33", PD, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", ++ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", ++ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", ++ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", ++ 1, nameSplitPattern); ++ ++ add("secp256k1", "1.3.132.0.10", P, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", ++ "0000000000000000000000000000000000000000000000000000000000000000", ++ "0000000000000000000000000000000000000000000000000000000000000007", ++ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", ++ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", ++ 1, nameSplitPattern); ++ ++ add("secp256r1 [NIST P-256, X9.62 prime256v1]", "1.2.840.10045.3.1.7", PD, ++ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", ++ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", ++ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", ++ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", ++ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", ++ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", ++ 1, nameSplitPattern); ++ ++ add("secp384r1 [NIST P-384]", "1.3.132.0.34", PD, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", ++ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", ++ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", ++ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", ++ 1, nameSplitPattern); ++ ++ add("secp521r1 [NIST P-521]", "1.3.132.0.35", PD, ++ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", ++ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", ++ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", ++ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", ++ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", ++ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", ++ 1, nameSplitPattern); ++ ++ /* ANSI X9.62 prime curves */ ++ add("X9.62 prime192v2", "1.2.840.10045.3.1.2", P, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", ++ "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", ++ "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", ++ "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", ++ "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", ++ 1, nameSplitPattern); ++ ++ add("X9.62 prime192v3", "1.2.840.10045.3.1.3", P, ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", ++ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", ++ "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", ++ "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", ++ "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", ++ "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", ++ 1, nameSplitPattern); ++ ++ add("X9.62 prime239v1", "1.2.840.10045.3.1.4", P, ++ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", ++ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", ++ "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", ++ "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", ++ "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", ++ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", ++ 1, nameSplitPattern); ++ ++ add("X9.62 prime239v2", "1.2.840.10045.3.1.5", P, ++ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", ++ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", ++ "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", ++ "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", ++ "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", ++ "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", ++ 1, nameSplitPattern); ++ ++ add("X9.62 prime239v3", "1.2.840.10045.3.1.6", P, ++ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", ++ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", ++ "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", ++ "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", ++ "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", ++ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", ++ 1, nameSplitPattern); ++ ++ /* SEC2 binary curves */ ++ add("sect113r1", "1.3.132.0.4", B, ++ "020000000000000000000000000201", ++ "003088250CA6E7C7FE649CE85820F7", ++ "00E8BEE4D3E2260744188BE0E9C723", ++ "009D73616F35F4AB1407D73562C10F", ++ "00A52830277958EE84D1315ED31886", ++ "0100000000000000D9CCEC8A39E56F", ++ 2, nameSplitPattern); ++ ++ add("sect113r2", "1.3.132.0.5", B, ++ "020000000000000000000000000201", ++ "00689918DBEC7E5A0DD6DFC0AA55C7", ++ "0095E9A9EC9B297BD4BF36E059184F", ++ "01A57A6A7B26CA5EF52FCDB8164797", ++ "00B3ADC94ED1FE674C06E695BABA1D", ++ "010000000000000108789B2496AF93", ++ 2, nameSplitPattern); ++ ++ add("sect131r1", "1.3.132.0.22", B, ++ "080000000000000000000000000000010D", ++ "07A11B09A76B562144418FF3FF8C2570B8", ++ "0217C05610884B63B9C6C7291678F9D341", ++ "0081BAF91FDF9833C40F9C181343638399", ++ "078C6E7EA38C001F73C8134B1B4EF9E150", ++ "0400000000000000023123953A9464B54D", ++ 2, nameSplitPattern); ++ ++ add("sect131r2", "1.3.132.0.23", B, ++ "080000000000000000000000000000010D", ++ "03E5A88919D7CAFCBF415F07C2176573B2", ++ "04B8266A46C55657AC734CE38F018F2192", ++ "0356DCD8F2F95031AD652D23951BB366A8", ++ "0648F06D867940A5366D9E265DE9EB240F", ++ "0400000000000000016954A233049BA98F", ++ 2, nameSplitPattern); ++ ++ add("sect163k1 [NIST K-163]", "1.3.132.0.1", BD, ++ "0800000000000000000000000000000000000000C9", ++ "000000000000000000000000000000000000000001", ++ "000000000000000000000000000000000000000001", ++ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", ++ "0289070FB05D38FF58321F2E800536D538CCDAA3D9", ++ "04000000000000000000020108A2E0CC0D99F8A5EF", ++ 2, nameSplitPattern); ++ ++ add("sect163r1", "1.3.132.0.2", B, ++ "0800000000000000000000000000000000000000C9", ++ "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", ++ "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", ++ "0369979697AB43897789566789567F787A7876A654", ++ "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883", ++ "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", ++ 2, nameSplitPattern); ++ ++ add("sect163r2 [NIST B-163]", "1.3.132.0.15", BD, ++ "0800000000000000000000000000000000000000C9", ++ "000000000000000000000000000000000000000001", ++ "020A601907B8C953CA1481EB10512F78744A3205FD", ++ "03F0EBA16286A2D57EA0991168D4994637E8343E36", ++ "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", ++ "040000000000000000000292FE77E70C12A4234C33", ++ 2, nameSplitPattern); ++ ++ add("sect193r1", "1.3.132.0.24", B, ++ "02000000000000000000000000000000000000000000008001", ++ "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", ++ "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", ++ "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", ++ "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", ++ "01000000000000000000000000C7F34A778F443ACC920EBA49", ++ 2, nameSplitPattern); ++ ++ add("sect193r2", "1.3.132.0.25", B, ++ "02000000000000000000000000000000000000000000008001", ++ "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", ++ "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", ++ "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", ++ "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", ++ "010000000000000000000000015AAB561B005413CCD4EE99D5", ++ 2, nameSplitPattern); ++ ++ add("sect233k1 [NIST K-233]", "1.3.132.0.26", BD, ++ "020000000000000000000000000000000000000004000000000000000001", ++ "000000000000000000000000000000000000000000000000000000000000", ++ "000000000000000000000000000000000000000000000000000000000001", ++ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", ++ "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", ++ "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", ++ 4, nameSplitPattern); ++ ++ add("sect233r1 [NIST B-233]", "1.3.132.0.27", B, ++ "020000000000000000000000000000000000000004000000000000000001", ++ "000000000000000000000000000000000000000000000000000000000001", ++ "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", ++ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", ++ "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", ++ "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", ++ 2, nameSplitPattern); ++ ++ add("sect239k1", "1.3.132.0.3", B, ++ "800000000000000000004000000000000000000000000000000000000001", ++ "000000000000000000000000000000000000000000000000000000000000", ++ "000000000000000000000000000000000000000000000000000000000001", ++ "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", ++ "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", ++ "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", ++ 4, nameSplitPattern); ++ ++ add("sect283k1 [NIST K-283]", "1.3.132.0.16", BD, ++ "0800000000000000000000000000000000000000000000000000000000000000000010A1", ++ "000000000000000000000000000000000000000000000000000000000000000000000000", ++ "000000000000000000000000000000000000000000000000000000000000000000000001", ++ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", ++ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", ++ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", ++ 4, nameSplitPattern); ++ ++ add("sect283r1 [NIST B-283]", "1.3.132.0.17", B, ++ "0800000000000000000000000000000000000000000000000000000000000000000010A1", ++ "000000000000000000000000000000000000000000000000000000000000000000000001", ++ "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", ++ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", ++ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", ++ "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", ++ 2, nameSplitPattern); ++ ++ add("sect409k1 [NIST K-409]", "1.3.132.0.36", BD, ++ "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", ++ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", ++ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", ++ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", ++ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", ++ "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", ++ 4, nameSplitPattern); ++ ++ add("sect409r1 [NIST B-409]", "1.3.132.0.37", B, ++ "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", ++ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", ++ "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", ++ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", ++ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", ++ "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", ++ 2, nameSplitPattern); ++ ++ add("sect571k1 [NIST K-571]", "1.3.132.0.38", BD, ++ "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", ++ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", ++ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", ++ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", ++ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", ++ "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", ++ 4, nameSplitPattern); ++ ++ add("sect571r1 [NIST B-571]", "1.3.132.0.39", B, ++ "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", ++ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", ++ "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", ++ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", ++ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", ++ "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", ++ 2, nameSplitPattern); ++ ++ /* ANSI X9.62 binary curves */ ++ add("X9.62 c2tnb191v1", "1.2.840.10045.3.0.5", B, ++ "800000000000000000000000000000000000000000000201", ++ "2866537B676752636A68F56554E12640276B649EF7526267", ++ "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", ++ "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", ++ "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", ++ "40000000000000000000000004A20E90C39067C893BBB9A5", ++ 2, nameSplitPattern); ++ ++ add("X9.62 c2tnb191v2", "1.2.840.10045.3.0.6", B, ++ "800000000000000000000000000000000000000000000201", ++ "401028774D7777C7B7666D1366EA432071274F89FF01E718", ++ "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", ++ "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", ++ "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", ++ "20000000000000000000000050508CB89F652824E06B8173", ++ 4, nameSplitPattern); ++ ++ add("X9.62 c2tnb191v3", "1.2.840.10045.3.0.7", B, ++ "800000000000000000000000000000000000000000000201", ++ "6C01074756099122221056911C77D77E77A777E7E7E77FCB", ++ "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", ++ "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", ++ "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", ++ "155555555555555555555555610C0B196812BFB6288A3EA3", ++ 6, nameSplitPattern); ++ ++ add("X9.62 c2tnb239v1", "1.2.840.10045.3.0.11", B, ++ "800000000000000000000000000000000000000000000000001000000001", ++ "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", ++ "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", ++ "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", ++ "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", ++ "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", ++ 4, nameSplitPattern); ++ ++ add("X9.62 c2tnb239v2", "1.2.840.10045.3.0.12", B, ++ "800000000000000000000000000000000000000000000000001000000001", ++ "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", ++ "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", ++ "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", ++ "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", ++ "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", ++ 6, nameSplitPattern); ++ ++ add("X9.62 c2tnb239v3", "1.2.840.10045.3.0.13", B, ++ "800000000000000000000000000000000000000000000000001000000001", ++ "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", ++ "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", ++ "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", ++ "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", ++ "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", ++ 0xA, nameSplitPattern); ++ ++ add("X9.62 c2tnb359v1", "1.2.840.10045.3.0.18", B, ++ "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001", ++ "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", ++ "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", ++ "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097", ++ "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD", ++ "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", ++ 0x4C, nameSplitPattern); ++ ++ add("X9.62 c2tnb431r1", "1.2.840.10045.3.0.20", B, ++ "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001", ++ "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", ++ "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", ++ "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", ++ "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", ++ "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", ++ 0x2760, nameSplitPattern); ++ ++ /* ANSI X9.62 binary curves from the 1998 standard but forbidden ++ * in the 2005 version of the standard. ++ * We don't register them but leave them here for the time being in ++ * case we need to support them after all. ++ */ ++/* ++ add("X9.62 c2pnb163v1", "1.2.840.10045.3.0.1", B, ++ "080000000000000000000000000000000000000107", ++ "072546B5435234A422E0789675F432C89435DE5242", ++ "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", ++ "07AF69989546103D79329FCC3D74880F33BBE803CB", ++ "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", ++ "0400000000000000000001E60FC8821CC74DAEAFC1", ++ 2, nameSplitPattern); ++ ++ add("X9.62 c2pnb163v2", "1.2.840.10045.3.0.2", B, ++ "080000000000000000000000000000000000000107", ++ "0108B39E77C4B108BED981ED0E890E117C511CF072", ++ "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", ++ "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", ++ "079F684DDF6684C5CD258B3890021B2386DFD19FC5", ++ "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", ++ 2, nameSplitPattern); ++ ++ add("X9.62 c2pnb163v3", "1.2.840.10045.3.0.3", B, ++ "080000000000000000000000000000000000000107", ++ "07A526C63D3E25A256A007699F5447E32AE456B50E", ++ "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", ++ "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", ++ "05B935590C155E17EA48EB3FF3718B893DF59A05D0", ++ "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", ++ 2, nameSplitPattern); ++ ++ add("X9.62 c2pnb176w1", "1.2.840.10045.3.0.4", B, ++ "0100000000000000000000000000000000080000000007", ++ "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", ++ "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", ++ "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", ++ "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", ++ "00010092537397ECA4F6145799D62B0A19CE06FE26AD", ++ 0xFF6E, nameSplitPattern); ++ ++ add("X9.62 c2pnb208w1", "1.2.840.10045.3.0.10", B, ++ "010000000000000000000000000000000800000000000000000007", ++ "0000000000000000000000000000000000000000000000000000", ++ "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", ++ "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", ++ "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", ++ "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", ++ 0xFE48, nameSplitPattern); ++ ++ add("X9.62 c2pnb272w1", "1.2.840.10045.3.0.16", B, ++ "010000000000000000000000000000000000000000000000000000010000000000000B", ++ "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", ++ "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", ++ "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", ++ "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", ++ "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", ++ 0xFF06, nameSplitPattern); ++ ++ add("X9.62 c2pnb304w1", "1.2.840.10045.3.0.17", B, ++ "010000000000000000000000000000000000000000000000000000000000000000000000000807", ++ "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", ++ "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", ++ "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614", ++ "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B", ++ "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", ++ 0xFE2E, nameSplitPattern); ++ ++ add("X9.62 c2pnb368w1", "1.2.840.10045.3.0.19", B, ++ "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007", ++ "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", ++ "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", ++ "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F", ++ "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310", ++ "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", ++ 0xFF70, nameSplitPattern); ++*/ ++ ++ /* ++ * Brainpool curves (RFC 5639) ++ * (Twisted curves are not included) ++ */ ++ ++ add("brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1", P, ++ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", ++ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", ++ "1E589A8595423412134FAA2DBDEC95C8D8675E58", ++ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", ++ "1667CB477A1A8EC338F94741669C976316DA6321", ++ "E95E4A5F737059DC60DF5991D45029409E60FC09", ++ 1, nameSplitPattern); ++ ++ add("brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", P, ++ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", ++ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", ++ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", ++ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", ++ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", ++ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", ++ 1, nameSplitPattern); ++ ++ add("brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", P, ++ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", ++ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", ++ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", ++ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", ++ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", ++ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", ++ 1, nameSplitPattern); ++ ++ add("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", P, ++ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", ++ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", ++ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", ++ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", ++ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", ++ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", ++ 1, nameSplitPattern); ++ ++ add("brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", P, ++ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", ++ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", ++ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", ++ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", ++ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", ++ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", ++ 1, nameSplitPattern); ++ ++ add("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", P, ++ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", ++ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", ++ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", ++ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", ++ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", ++ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", ++ 1, nameSplitPattern); ++ ++ add("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", P, ++ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", ++ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", ++ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", ++ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", ++ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", ++ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", ++ 1, nameSplitPattern); ++ ++ /* SM2 prime curves */ ++ add("sm2p256v1", "1.2.156.10197.1.301", P, ++ "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", ++ "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", ++ "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", ++ "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", ++ "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", ++ "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", ++ 1, nameSplitPattern); ++ ++ specCollection = Collections.unmodifiableCollection(oidMap.values()); ++ } ++} +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java +index 7a9cc5cc5..2171b2607 100644 +--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java +@@ -27,6 +27,7 @@ + package org.openeuler.security.openssl; + + import sun.security.ec.ECKeyFactory; ++import sun.security.util.NamedCurve; + + import java.math.BigInteger; + import java.security.InvalidAlgorithmParameterException; +@@ -95,7 +96,16 @@ public class KAEECDHKeyAgreement extends KeyAgreementSpi { + // Bits to bytes. + expectedSecretLen = (keyLenBits + 7) >> 3; + +- curveName = KAEUtils.getCurveBySize(keyLenBits); ++ // Using KAENamedCurve.name can be inaccurate. need ObjectId ++ if (params instanceof KAENamedCurve) { ++ curveName = KAEUtils.getCurveByAlias(((KAENamedCurve) params).getObjectId()); ++ }else if (params instanceof NamedCurve) { ++ curveName = KAEUtils.getCurveByAlias(((NamedCurve) params).getObjectId()); ++ }else { ++ KAENamedCurve curve = KAECurveDB.lookup(params); ++ curveName = KAEUtils.getCurveByAlias(curve.getObjectId()); ++ } ++ + if (curveName == null) { + throw new InvalidParameterException("unknown keyLenBits " + keyLenBits); + } +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyFactory.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyFactory.java +new file mode 100644 +index 000000000..b71f65088 +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyFactory.java +@@ -0,0 +1,291 @@ ++/* ++ * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2023, Huawei Technologies Co., Ltd. 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import java.security.*; ++import java.security.interfaces.*; ++import java.security.spec.*; ++ ++/** ++ * KeyFactory for EC keys. Keys must be instances of PublicKey or PrivateKey ++ * and getAlgorithm() must return "EC". For such keys, it supports conversion ++ * between the following: ++ * ++ * For public keys: ++ * . PublicKey with an X.509 encoding ++ * . ECPublicKey ++ * . ECPublicKeySpec ++ * . X509EncodedKeySpec ++ * ++ * For private keys: ++ * . PrivateKey with a PKCS#8 encoding ++ * . ECPrivateKey ++ * . ECPrivateKeySpec ++ * . PKCS8EncodedKeySpec ++ * ++ * @since 1.6 ++ * @author Andreas Sterbenz ++ */ ++public final class KAEECKeyFactory extends KeyFactorySpi { ++ ++ // Used by translateKey() ++ private static KeyFactory instance; ++ ++ private static KeyFactory getInstance() { ++ if (instance == null) { ++ try { ++ instance = KeyFactory.getInstance("EC", "KAEProvider"); ++ } catch (NoSuchProviderException e) { ++ throw new RuntimeException(e); ++ } catch (NoSuchAlgorithmException e) { ++ throw new RuntimeException(e); ++ } ++ } ++ ++ return instance; ++ } ++ ++ public KAEECKeyFactory() { ++ // empty ++ } ++ ++ /** ++ * Static method to convert Key into a useable instance of ++ * ECPublicKey or ECPrivateKey. Check the key and convert it ++ * to a Sun key if necessary. If the key is not an EC key ++ * or cannot be used, throw an InvalidKeyException. ++ * ++ * The difference between this method and engineTranslateKey() is that ++ * we do not convert keys of other providers that are already an ++ * instance of ECPublicKey or ECPrivateKey. ++ * ++ * To be used by future Java ECDSA and ECDH implementations. ++ */ ++ public static ECKey toECKey(Key key) throws InvalidKeyException { ++ if (key instanceof ECKey) { ++ ECKey ecKey = (ECKey)key; ++ checkKey(ecKey); ++ return ecKey; ++ } else { ++ /* ++ * We don't call the engineTranslateKey method directly ++ * because KeyFactory.translateKey adds code to loop through ++ * all key factories. ++ */ ++ return (ECKey)getInstance().translateKey(key); ++ } ++ } ++ ++ /** ++ * Check that the given EC key is valid. ++ */ ++ private static void checkKey(ECKey key) throws InvalidKeyException { ++ // check for subinterfaces, omit additional checks for our keys ++ if (key instanceof ECPublicKey) { ++ if (key instanceof KAEECPublicKeyImpl) { ++ return; ++ } ++ } else if (key instanceof ECPrivateKey) { ++ if (key instanceof KAEECPrivateKeyImpl) { ++ return; ++ } ++ } else { ++ throw new InvalidKeyException("Neither a public nor a private key"); ++ } ++ // ECKey does not extend Key, so we need to do a cast ++ String keyAlg = ((Key)key).getAlgorithm(); ++ if (!keyAlg.equals("EC") && !keyAlg.equals("SM2")) { ++ throw new InvalidKeyException("Not an EC key: " + keyAlg); ++ } ++ // XXX further sanity checks about whether this key uses supported ++ // fields, point formats, etc. would go here ++ } ++ ++ /** ++ * Translate an EC key into a Sun EC key. If conversion is ++ * not possible, throw an InvalidKeyException. ++ * See also JCA doc. ++ */ ++ protected Key engineTranslateKey(Key key) throws InvalidKeyException { ++ if (key == null) { ++ throw new InvalidKeyException("Key must not be null"); ++ } ++ String keyAlg = key.getAlgorithm(); ++ if (!keyAlg.equals("EC") && !keyAlg.equals("SM2")) { ++ throw new InvalidKeyException("Not an EC key: " + keyAlg); ++ } ++ if (key instanceof PublicKey) { ++ return implTranslatePublicKey((PublicKey)key); ++ } else if (key instanceof PrivateKey) { ++ return implTranslatePrivateKey((PrivateKey)key); ++ } else { ++ throw new InvalidKeyException("Neither a public nor a private key"); ++ } ++ } ++ ++ // see JCA doc ++ protected PublicKey engineGeneratePublic(KeySpec keySpec) ++ throws InvalidKeySpecException { ++ try { ++ return implGeneratePublic(keySpec); ++ } catch (InvalidKeySpecException e) { ++ throw e; ++ } catch (GeneralSecurityException e) { ++ throw new InvalidKeySpecException(e); ++ } ++ } ++ ++ // see JCA doc ++ protected PrivateKey engineGeneratePrivate(KeySpec keySpec) ++ throws InvalidKeySpecException { ++ try { ++ return implGeneratePrivate(keySpec); ++ } catch (InvalidKeySpecException e) { ++ throw e; ++ } catch (GeneralSecurityException e) { ++ throw new InvalidKeySpecException(e); ++ } ++ } ++ ++ // internal implementation of translateKey() for public keys. See JCA doc ++ private PublicKey implTranslatePublicKey(PublicKey key) ++ throws InvalidKeyException { ++ if (key instanceof ECPublicKey) { ++ if (key instanceof KAEECPublicKeyImpl) { ++ return key; ++ } ++ ECPublicKey ecKey = (ECPublicKey)key; ++ return new KAEECPublicKeyImpl( ++ ecKey.getW(), ++ ecKey.getParams() ++ ); ++ } else if ("X.509".equals(key.getFormat())) { ++ byte[] encoded = key.getEncoded(); ++ return new KAEECPublicKeyImpl(encoded); ++ } else { ++ throw new InvalidKeyException("Public keys must be instance " ++ + "of ECPublicKey or have X.509 encoding"); ++ } ++ } ++ ++ // internal implementation of translateKey() for private keys. See JCA doc ++ private PrivateKey implTranslatePrivateKey(PrivateKey key) ++ throws InvalidKeyException { ++ if (key instanceof ECPrivateKey) { ++ if (key instanceof KAEECPrivateKeyImpl) { ++ return key; ++ } ++ ECPrivateKey ecKey = (ECPrivateKey)key; ++ return new KAEECPrivateKeyImpl( ++ ecKey.getS(), ++ ecKey.getParams() ++ ); ++ } else if ("PKCS#8".equals(key.getFormat())) { ++ return new KAEECPrivateKeyImpl(key.getEncoded()); ++ } else { ++ throw new InvalidKeyException("Private keys must be instance " ++ + "of ECPrivateKey or have PKCS#8 encoding"); ++ } ++ } ++ ++ // internal implementation of generatePublic. See JCA doc ++ private PublicKey implGeneratePublic(KeySpec keySpec) ++ throws GeneralSecurityException { ++ if (keySpec instanceof X509EncodedKeySpec) { ++ X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; ++ return new KAEECPublicKeyImpl(x509Spec.getEncoded()); ++ } else if (keySpec instanceof ECPublicKeySpec) { ++ ECPublicKeySpec ecSpec = (ECPublicKeySpec)keySpec; ++ return new KAEECPublicKeyImpl( ++ ecSpec.getW(), ++ ecSpec.getParams() ++ ); ++ } else { ++ throw new InvalidKeySpecException("Only ECPublicKeySpec " ++ + "and X509EncodedKeySpec supported for EC public keys"); ++ } ++ } ++ ++ // internal implementation of generatePrivate. See JCA doc ++ private PrivateKey implGeneratePrivate(KeySpec keySpec) ++ throws GeneralSecurityException { ++ if (keySpec instanceof PKCS8EncodedKeySpec) { ++ PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; ++ return new KAEECPrivateKeyImpl(pkcsSpec.getEncoded()); ++ } else if (keySpec instanceof ECPrivateKeySpec) { ++ ECPrivateKeySpec ecSpec = (ECPrivateKeySpec)keySpec; ++ return new KAEECPrivateKeyImpl(ecSpec.getS(), ecSpec.getParams()); ++ } else { ++ throw new InvalidKeySpecException("Only ECPrivateKeySpec " ++ + "and PKCS8EncodedKeySpec supported for EC private keys"); ++ } ++ } ++ ++ protected T engineGetKeySpec(Key key, Class keySpec) ++ throws InvalidKeySpecException { ++ try { ++ // convert key to one of our keys ++ // this also verifies that the key is a valid EC key and ensures ++ // that the encoding is X.509/PKCS#8 for public/private keys ++ key = engineTranslateKey(key); ++ } catch (InvalidKeyException e) { ++ throw new InvalidKeySpecException(e); ++ } ++ if (key instanceof ECPublicKey) { ++ ECPublicKey ecKey = (ECPublicKey)key; ++ if (keySpec.isAssignableFrom(ECPublicKeySpec.class)) { ++ return keySpec.cast(new ECPublicKeySpec( ++ ecKey.getW(), ++ ecKey.getParams() ++ )); ++ } else if (keySpec.isAssignableFrom(X509EncodedKeySpec.class)) { ++ return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); ++ } else { ++ throw new InvalidKeySpecException ++ ("KeySpec must be ECPublicKeySpec or " ++ + "X509EncodedKeySpec for EC public keys"); ++ } ++ } else if (key instanceof ECPrivateKey) { ++ if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)) { ++ return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded())); ++ } else if (keySpec.isAssignableFrom(ECPrivateKeySpec.class)) { ++ ECPrivateKey ecKey = (ECPrivateKey)key; ++ return keySpec.cast(new ECPrivateKeySpec( ++ ecKey.getS(), ++ ecKey.getParams() ++ )); ++ } else { ++ throw new InvalidKeySpecException ++ ("KeySpec must be ECPrivateKeySpec or " ++ + "PKCS8EncodedKeySpec for EC private keys"); ++ } ++ } else { ++ // should not occur, caught in engineTranslateKey() ++ throw new InvalidKeySpecException("Neither public nor private key"); ++ } ++ } ++} +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java +index 812980608..f42844c08 100644 +--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java +@@ -26,9 +26,6 @@ + + package org.openeuler.security.openssl; + +-import sun.security.ec.ECPrivateKeyImpl; +-import sun.security.ec.ECPublicKeyImpl; +- + import java.math.BigInteger; + import java.security.InvalidAlgorithmParameterException; + import java.security.InvalidParameterException; +@@ -44,8 +41,6 @@ import java.security.spec.ECGenParameterSpec; + import java.security.spec.ECParameterSpec; + import java.security.spec.ECPoint; + import java.security.spec.EllipticCurve; +-import java.util.HashMap; +-import java.util.Map; + + public class KAEECKeyPairGenerator extends KeyPairGeneratorSpi { + private ECParameterSpec param = null; +@@ -63,7 +58,7 @@ public class KAEECKeyPairGenerator extends KeyPairGeneratorSpi { + this.param = getParamsByCurve(curveName); + } + +- private ECParameterSpec getParamsByCurve(String curveName) { ++ protected ECParameterSpec getParamsByCurve(String curveName) { + byte[][] params = nativeGenerateParam(curveName); + // check params + checkParams(params, curveName); +@@ -139,11 +134,11 @@ public class KAEECKeyPairGenerator extends KeyPairGeneratorSpi { + BigInteger s = new BigInteger(keys[2]); + ECPoint w = new ECPoint(wX, wY); + +- ECPrivateKeyImpl privateKey = null; +- ECPublicKeyImpl publicKey = null; ++ KAEECPrivateKeyImpl privateKey; ++ KAEECPublicKeyImpl publicKey; + try { +- publicKey = new ECPublicKeyImpl(w, param); +- privateKey = new ECPrivateKeyImpl(s, param); ++ publicKey = new KAEECPublicKeyImpl(w, param); ++ privateKey = new KAEECPrivateKeyImpl(s, param); + } catch (InvalidKeyException e) { + throw new ProviderException(e); + } +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECParameters.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECParameters.java +new file mode 100644 +index 000000000..a867e40ee +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECParameters.java +@@ -0,0 +1,241 @@ ++/* ++ * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2023, Huawei Technologies Co., Ltd. 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import sun.security.util.DerValue; ++import sun.security.util.ECKeySizeParameterSpec; ++import sun.security.util.ObjectIdentifier; ++ ++import java.io.IOException; ++ ++import java.security.*; ++import java.security.spec.*; ++ ++/** ++ * This class implements encoding and decoding of Elliptic Curve parameters ++ * as specified in RFC 3279. ++ * ++ * However, only named curves are currently supported. ++ * ++ * ASN.1 from RFC 3279 follows. Note that X9.62 (2005) has added some additional ++ * options. ++ * ++ *
++ *    EcpkParameters ::= CHOICE {
++ *      ecParameters  ECParameters,
++ *      namedCurve    OBJECT IDENTIFIER,
++ *      implicitlyCA  NULL }
++ *
++ *    ECParameters ::= SEQUENCE {
++ *       version   ECPVer,          -- version is always 1
++ *       fieldID   FieldID,         -- identifies the finite field over
++ *                                  -- which the curve is defined
++ *       curve     Curve,           -- coefficients a and b of the
++ *                                  -- elliptic curve
++ *       base      ECPoint,         -- specifies the base point P
++ *                                  -- on the elliptic curve
++ *       order     INTEGER,         -- the order n of the base point
++ *       cofactor  INTEGER OPTIONAL -- The integer h = #E(Fq)/n
++ *       }
++ *
++ *    ECPVer ::= INTEGER {ecpVer1(1)}
++ *
++ *    Curve ::= SEQUENCE {
++ *       a         FieldElement,
++ *       b         FieldElement,
++ *       seed      BIT STRING OPTIONAL }
++ *
++ *    FieldElement ::= OCTET STRING
++ *
++ *    ECPoint ::= OCTET STRING
++ * 
++ * ++ * @since 1.6 ++ * @author Andreas Sterbenz ++ */ ++public final class KAEECParameters extends AlgorithmParametersSpi { ++ ++ // used by ECPublicKeyImpl and ECPrivateKeyImpl ++ public static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec) ++ throws InvalidKeyException { ++ try { ++ AlgorithmParameters params = ++ AlgorithmParameters.getInstance("EC", "KAEProvider"); ++ params.init(spec); ++ return params; ++ } catch (GeneralSecurityException e) { ++ throw new InvalidKeyException("EC parameters error", e); ++ } ++ } ++ ++ /* ++ * The parameters these AlgorithmParameters object represents. ++ * Currently, it is always an instance of NamedCurve. ++ */ ++ private KAENamedCurve namedCurve; ++ ++ // A public constructor is required by AlgorithmParameters class. ++ public KAEECParameters() { ++ // empty ++ } ++ ++ // AlgorithmParameterSpi methods ++ ++ protected void engineInit(AlgorithmParameterSpec paramSpec) ++ throws InvalidParameterSpecException { ++ ++ if (paramSpec == null) { ++ throw new InvalidParameterSpecException ++ ("paramSpec must not be null"); ++ } ++ ++ if (paramSpec instanceof KAENamedCurve) { ++ namedCurve = (KAENamedCurve)paramSpec; ++ return; ++ } ++ ++ if (paramSpec instanceof ECParameterSpec) { ++ namedCurve = KAECurveDB.lookup((ECParameterSpec)paramSpec); ++ } else if (paramSpec instanceof ECGenParameterSpec) { ++ String name = ((ECGenParameterSpec)paramSpec).getName(); ++ namedCurve = KAECurveDB.lookup(name); ++ } else if (paramSpec instanceof ECKeySizeParameterSpec) { ++ int keySize = ((ECKeySizeParameterSpec)paramSpec).getKeySize(); ++ namedCurve = KAECurveDB.lookup(keySize); ++ } else { ++ throw new InvalidParameterSpecException ++ ("Only ECParameterSpec and ECGenParameterSpec supported"); ++ } ++ ++ if (namedCurve == null) { ++ throw new InvalidParameterSpecException( ++ "Not a supported curve: " + paramSpec); ++ } ++ } ++ ++ protected void engineInit(byte[] params) throws IOException { ++ DerValue encodedParams = new DerValue(params); ++ if (encodedParams.tag == DerValue.tag_ObjectId) { ++ ObjectIdentifier oid = encodedParams.getOID(); ++ KAENamedCurve spec = KAECurveDB.lookup(oid.toString()); ++ if (spec == null) { ++ throw new IOException("Unknown named curve: " + oid); ++ } ++ ++ namedCurve = spec; ++ return; ++ } ++ ++ throw new IOException("Only named ECParameters supported"); ++ ++ // The code below is incomplete. ++ // It is left as a starting point for a complete parsing implementation. ++ ++/* ++ if (encodedParams.tag != DerValue.tag_Sequence) { ++ throw new IOException("Unsupported EC parameters, tag: " + ++ encodedParams.tag); ++ } ++ ++ encodedParams.data.reset(); ++ ++ DerInputStream in = encodedParams.data; ++ ++ int version = in.getInteger(); ++ if (version != 1) { ++ throw new IOException("Unsupported EC parameters version: " + ++ version); ++ } ++ ECField field = parseField(in); ++ EllipticCurve curve = parseCurve(in, field); ++ ECPoint point = parsePoint(in, curve); ++ ++ BigInteger order = in.getBigInteger(); ++ int cofactor = 0; ++ ++ if (in.available() != 0) { ++ cofactor = in.getInteger(); ++ } ++ ++ // XXX HashAlgorithm optional ++ ++ if (encodedParams.data.available() != 0) { ++ throw new IOException("encoded params have " + ++ encodedParams.data.available() + ++ " extra bytes"); ++ } ++ ++ return new ECParameterSpec(curve, point, order, cofactor); ++*/ ++ } ++ ++ protected void engineInit(byte[] params, String decodingMethod) ++ throws IOException { ++ engineInit(params); ++ } ++ ++ protected T ++ engineGetParameterSpec(Class spec) ++ throws InvalidParameterSpecException { ++ ++ if (spec.isAssignableFrom(ECParameterSpec.class)) { ++ return spec.cast(namedCurve); ++ } ++ ++ if (spec.isAssignableFrom(ECGenParameterSpec.class)) { ++ // Ensure the name is the Object ID ++ String name = namedCurve.getObjectId(); ++ return spec.cast(new ECGenParameterSpec(name)); ++ } ++ ++ if (spec.isAssignableFrom(ECKeySizeParameterSpec.class)) { ++ int keySize = namedCurve.getCurve().getField().getFieldSize(); ++ return spec.cast(new ECKeySizeParameterSpec(keySize)); ++ } ++ ++ throw new InvalidParameterSpecException( ++ "Only ECParameterSpec and ECGenParameterSpec supported"); ++ } ++ ++ protected byte[] engineGetEncoded() throws IOException { ++ return namedCurve.getEncoded(); ++ } ++ ++ protected byte[] engineGetEncoded(String encodingMethod) ++ throws IOException { ++ return engineGetEncoded(); ++ } ++ ++ protected String engineToString() { ++ if (namedCurve == null) { ++ return "Not initialized"; ++ } ++ ++ return namedCurve.toString(); ++ } ++} ++ +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECPrivateKeyImpl.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECPrivateKeyImpl.java +new file mode 100644 +index 000000000..599e4c363 +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECPrivateKeyImpl.java +@@ -0,0 +1,232 @@ ++/* ++ * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2023, Huawei Technologies Co., Ltd. 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import java.io.IOException; ++import java.io.InvalidObjectException; ++import java.io.ObjectInputStream; ++import java.math.BigInteger; ++ ++import java.security.*; ++import java.security.interfaces.*; ++import java.security.spec.*; ++ ++import sun.security.util.ArrayUtil; ++import sun.security.util.DerInputStream; ++import sun.security.util.DerOutputStream; ++import sun.security.util.DerValue; ++import sun.security.x509.AlgorithmId; ++import sun.security.pkcs.PKCS8Key; ++ ++/** ++ * Key implementation for EC private keys. ++ *

++ * ASN.1 syntax for EC private keys from SEC 1 v1.5 (draft): ++ * ++ *

++ * EXPLICIT TAGS
++ *
++ * ECPrivateKey ::= SEQUENCE {
++ *   version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
++ *   privateKey OCTET STRING,
++ *   parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL,
++ *   publicKey [1] BIT STRING OPTIONAL
++ * }
++ * 
++ * ++ * We currently ignore the optional parameters and publicKey fields. We ++ * require that the parameters are encoded as part of the AlgorithmIdentifier, ++ * not in the private key structure. ++ * ++ * @since 1.6 ++ * @author Andreas Sterbenz ++ */ ++public final class KAEECPrivateKeyImpl extends PKCS8Key implements ECPrivateKey { ++ ++ private static final long serialVersionUID = 88695385615075129L; ++ ++ private BigInteger s; // private value ++ private byte[] arrayS; // private value as a little-endian array ++ private ECParameterSpec params; ++ ++ /** ++ * Construct a key from its encoding. Called by the ECKeyFactory. ++ */ ++ public KAEECPrivateKeyImpl(byte[] encoded) throws InvalidKeyException { ++ decode(encoded); ++ } ++ ++ /** ++ * Construct a key from its components. Used by the ++ * KeyFactory. ++ */ ++ public KAEECPrivateKeyImpl(BigInteger s, ECParameterSpec params) ++ throws InvalidKeyException { ++ this.s = s; ++ this.params = params; ++ makeEncoding(s); ++ ++ } ++ ++ KAEECPrivateKeyImpl(byte[] s, ECParameterSpec params) ++ throws InvalidKeyException { ++ this.arrayS = s.clone(); ++ this.params = params; ++ makeEncoding(s); ++ } ++ ++ private void makeEncoding(byte[] s) throws InvalidKeyException { ++ algid = new AlgorithmId ++ (AlgorithmId.EC_oid, KAEECParameters.getAlgorithmParameters(params)); ++ try { ++ DerOutputStream out = new DerOutputStream(); ++ out.putInteger(1); // version 1 ++ byte[] privBytes = s.clone(); ++ ArrayUtil.reverse(privBytes); ++ out.putOctetString(privBytes); ++ DerValue val = ++ new DerValue(DerValue.tag_Sequence, out.toByteArray()); ++ key = val.toByteArray(); ++ } catch (IOException exc) { ++ // should never occur ++ throw new InvalidKeyException(exc); ++ } ++ } ++ ++ private void makeEncoding(BigInteger s) throws InvalidKeyException { ++ algid = new AlgorithmId ++ (AlgorithmId.EC_oid, KAEECParameters.getAlgorithmParameters(params)); ++ try { ++ byte[] sArr = s.toByteArray(); ++ // convert to fixed-length array ++ int numOctets = (params.getOrder().bitLength() + 7) / 8; ++ byte[] sOctets = new byte[numOctets]; ++ int inPos = Math.max(sArr.length - sOctets.length, 0); ++ int outPos = Math.max(sOctets.length - sArr.length, 0); ++ int length = Math.min(sArr.length, sOctets.length); ++ System.arraycopy(sArr, inPos, sOctets, outPos, length); ++ ++ DerOutputStream out = new DerOutputStream(); ++ out.putInteger(1); // version 1 ++ out.putOctetString(sOctets); ++ DerValue val = ++ new DerValue(DerValue.tag_Sequence, out.toByteArray()); ++ key = val.toByteArray(); ++ } catch (IOException exc) { ++ // should never occur ++ throw new InvalidKeyException(exc); ++ } ++ } ++ ++ // see JCA doc ++ public String getAlgorithm() { ++ return "EC"; ++ } ++ ++ // see JCA doc ++ public BigInteger getS() { ++ if (s == null) { ++ byte[] arrCopy = arrayS.clone(); ++ ArrayUtil.reverse(arrCopy); ++ s = new BigInteger(1, arrCopy); ++ } ++ return s; ++ } ++ ++ public byte[] getArrayS() { ++ if (arrayS == null) { ++ byte[] arr = getS().toByteArray(); ++ ArrayUtil.reverse(arr); ++ int byteLength = (params.getOrder().bitLength() + 7) / 8; ++ arrayS = new byte[byteLength]; ++ int length = Math.min(byteLength, arr.length); ++ System.arraycopy(arr, 0, arrayS, 0, length); ++ } ++ return arrayS.clone(); ++ } ++ ++ // see JCA doc ++ public ECParameterSpec getParams() { ++ return params; ++ } ++ ++ /** ++ * Parse the key. Called by PKCS8Key. ++ */ ++ protected void parseKeyBits() throws InvalidKeyException { ++ try { ++ DerInputStream in = new DerInputStream(key); ++ DerValue derValue = in.getDerValue(); ++ if (derValue.tag != DerValue.tag_Sequence) { ++ throw new IOException("Not a SEQUENCE"); ++ } ++ DerInputStream data = derValue.data; ++ int version = data.getInteger(); ++ if (version != 1) { ++ throw new IOException("Version must be 1"); ++ } ++ byte[] privData = data.getOctetString(); ++ ArrayUtil.reverse(privData); ++ arrayS = privData; ++ while (data.available() != 0) { ++ DerValue value = data.getDerValue(); ++ if (value.isContextSpecific((byte) 0)) { ++ // ignore for now ++ } else if (value.isContextSpecific((byte) 1)) { ++ // ignore for now ++ } else { ++ throw new InvalidKeyException("Unexpected value: " + value); ++ } ++ } ++ AlgorithmParameters algParams = this.algid.getParameters(); ++ if (algParams == null) { ++ throw new InvalidKeyException("EC domain parameters must be " ++ + "encoded in the algorithm identifier"); ++ } ++ params = algParams.getParameterSpec(ECParameterSpec.class); ++ } catch (IOException e) { ++ throw new InvalidKeyException("Invalid EC private key", e); ++ } catch (InvalidParameterSpecException e) { ++ throw new InvalidKeyException("Invalid EC private key", e); ++ } ++ } ++ ++ /** ++ * Restores the state of this object from the stream. ++ *

++ * Deserialization of this object is not supported. ++ * ++ * @param stream the {@code ObjectInputStream} from which data is read ++ * @throws IOException if an I/O error occurs ++ * @throws ClassNotFoundException if a serialized class cannot be loaded ++ */ ++ private void readObject(ObjectInputStream stream) ++ throws IOException, ClassNotFoundException { ++ throw new InvalidObjectException( ++ "ECPrivateKeyImpl keys are not directly deserializable"); ++ } ++} +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECPublicKeyImpl.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECPublicKeyImpl.java +new file mode 100644 +index 000000000..60d61dd39 +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEECPublicKeyImpl.java +@@ -0,0 +1,148 @@ ++/* ++ * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2023, Huawei Technologies Co., Ltd. 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import java.io.IOException; ++ ++import java.io.InvalidObjectException; ++import java.io.ObjectInputStream; ++import java.security.*; ++import java.security.interfaces.*; ++import java.security.spec.*; ++ ++import sun.security.util.ECUtil; ++ ++import sun.security.x509.*; ++ ++/** ++ * Key implementation for EC public keys. ++ * ++ * @since 1.6 ++ * @author Andreas Sterbenz ++ */ ++public final class KAEECPublicKeyImpl extends X509Key implements ECPublicKey { ++ ++ private static final long serialVersionUID = -2462037275160462289L; ++ ++ private ECPoint w; ++ private ECParameterSpec params; ++ ++ /** ++ * Construct a key from its components. Used by the ++ * ECKeyFactory. ++ */ ++ @SuppressWarnings("deprecation") ++ public KAEECPublicKeyImpl(ECPoint w, ECParameterSpec params) ++ throws InvalidKeyException { ++ this.w = w; ++ this.params = params; ++ // generate the encoding ++ algid = new AlgorithmId ++ (AlgorithmId.EC_oid, KAEECParameters.getAlgorithmParameters(params)); ++ key = ECUtil.encodePoint(w, params.getCurve()); ++ } ++ ++ /** ++ * Construct a key from its encoding. ++ */ ++ public KAEECPublicKeyImpl(byte[] encoded) throws InvalidKeyException { ++ decode(encoded); ++ } ++ ++ // see JCA doc ++ public String getAlgorithm() { ++ return "EC"; ++ } ++ ++ // see JCA doc ++ public ECPoint getW() { ++ return w; ++ } ++ ++ // see JCA doc ++ public ECParameterSpec getParams() { ++ return params; ++ } ++ ++ // Internal API to get the encoded point. Currently used by SunPKCS11. ++ // This may change/go away depending on what we do with the public API. ++ @SuppressWarnings("deprecation") ++ public byte[] getEncodedPublicValue() { ++ return key.clone(); ++ } ++ ++ /** ++ * Parse the key. Called by X509Key. ++ */ ++ @SuppressWarnings("deprecation") ++ protected void parseKeyBits() throws InvalidKeyException { ++ AlgorithmParameters algParams = this.algid.getParameters(); ++ if (algParams == null) { ++ throw new InvalidKeyException("EC domain parameters must be " + ++ "encoded in the algorithm identifier"); ++ } ++ ++ try { ++ params = algParams.getParameterSpec(ECParameterSpec.class); ++ w = ECUtil.decodePoint(key, params.getCurve()); ++ } catch (IOException e) { ++ throw new InvalidKeyException("Invalid EC key", e); ++ } catch (InvalidParameterSpecException e) { ++ throw new InvalidKeyException("Invalid EC key", e); ++ } ++ } ++ ++ // return a string representation of this key for debugging ++ public String toString() { ++ return "Sun EC public key, " + params.getCurve().getField().getFieldSize() ++ + " bits\n public x coord: " + w.getAffineX() ++ + "\n public y coord: " + w.getAffineY() ++ + "\n parameters: " + params; ++ } ++ ++ private Object writeReplace() throws java.io.ObjectStreamException { ++ return new KeyRep(KeyRep.Type.PUBLIC, ++ getAlgorithm(), ++ getFormat(), ++ getEncoded()); ++ } ++ ++ /** ++ * Restores the state of this object from the stream. ++ *

++ * Deserialization of this object is not supported. ++ * ++ * @param stream the {@code ObjectInputStream} from which data is read ++ * @throws IOException if an I/O error occurs ++ * @throws ClassNotFoundException if a serialized class cannot be loaded ++ */ ++ private void readObject(ObjectInputStream stream) ++ throws IOException, ClassNotFoundException { ++ throw new InvalidObjectException( ++ "ECPublicKeyImpl keys are not directly deserializable"); ++ } ++} +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAENamedCurve.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAENamedCurve.java +new file mode 100644 +index 000000000..5251753c0 +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAENamedCurve.java +@@ -0,0 +1,87 @@ ++/* ++ * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2023, Huawei Technologies Co., Ltd. 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import sun.security.util.DerOutputStream; ++import sun.security.util.ObjectIdentifier; ++ ++import java.io.IOException; ++import java.math.BigInteger; ++ ++import java.security.spec.*; ++ ++ ++/** ++ * Contains Elliptic Curve parameters. ++ * ++ * @since 1.6 ++ * @author Andreas Sterbenz ++ */ ++public final class KAENamedCurve extends ECParameterSpec { ++ ++ // friendly name for toString() output ++ private final String name; ++ ++ // well known OID ++ private final String oid; ++ ++ // encoded form (as NamedCurve identified via OID) ++ private final byte[] encoded; ++ ++ KAENamedCurve(String name, String oid, EllipticCurve curve, ++ ECPoint g, BigInteger n, int h) { ++ super(curve, g, n, h); ++ this.name = name; ++ this.oid = oid; ++ ++ DerOutputStream out = new DerOutputStream(); ++ ++ try { ++ out.putOID(new ObjectIdentifier(oid)); ++ } catch (IOException e) { ++ throw new RuntimeException("Internal error", e); ++ } ++ ++ encoded = out.toByteArray(); ++ } ++ ++ public String getName() { ++ return name; ++ } ++ ++ public byte[] getEncoded() { ++ return encoded.clone(); ++ } ++ ++ public String getObjectId() { ++ return oid; ++ } ++ ++ public String toString() { ++ return name + " (" + oid + ")"; ++ } ++} +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java +index 3e7f54638..d6c8e03cf 100644 +--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java +@@ -61,18 +61,29 @@ public class KAEProvider extends Provider { + + // init openssl + private static void initOpenssl() { +- boolean useGlobalMode = useGlobalMode(); + String engineId = getEngineId(); + boolean[] algorithmKaeFlags = KAEConfig.getUseKaeEngineFlags(); + Throwable throwable = null; + try { +- initOpenssl(useGlobalMode, engineId, algorithmKaeFlags); ++ int opensslVersion = useOpensslVersion(); ++ int version = initOpenssl(opensslVersion, engineId, algorithmKaeFlags); ++ if (kaeDebug != null) { ++ kaeDebug.println("Use Openssl " + version); ++ } ++ } catch (ExceptionInInitializerError t) { ++ throwable = (Throwable) t; ++ printKaeLog(engineId, t); ++ throw t; + } catch (Throwable t) { + throwable = t; + if (kaeDebug != null) { + kaeDebug.println("initOpenssl failed : " + throwable.getMessage()); + } + } ++ printKaeLog(engineId, throwable); ++ } ++ ++ private static void printKaeLog(String engineId, Throwable throwable) { + boolean[] engineFlags = getEngineFlags(); + boolean[] kaeProviderFlags = KAEConfig.getUseKaeProviderFlags(); + KAELog.log(engineId, throwable, engineFlags, kaeProviderFlags); +@@ -83,13 +94,26 @@ public class KAEProvider extends Provider { + return KAEConfig.privilegedGetOverridable("kae.engine.id", DEFAULT_ENGINE_ID); + } + +- // whether to set libcrypto.so to GLOBAL mode, by default libcrypto.so is LOCAL mode +- private static boolean useGlobalMode() { ++ // whether prefer use openssl 1 ++ private static int useOpensslVersion() throws ExceptionInInitializerError { + String explicitLoad = KAEConfig.privilegedGetOverridable( +- "kae.libcrypto.useGlobalMode", "false"); +- return Boolean.parseBoolean(explicitLoad); ++ "kae.useOpensslVersion", "0"); ++ int version = 0; ++ try { ++ if (explicitLoad.trim().isEmpty()) { ++ throw new ExceptionInInitializerError("initOpenssl failed : kae.useOpensslVersion set to empty value"); ++ } ++ version = Integer.parseInt(explicitLoad); ++ if (version != 0 && version != 1 && version != 3) { ++ throw new ExceptionInInitializerError("initOpenssl failed : unknown openssl version " + version); ++ } ++ } catch (NumberFormatException e) { ++ throw new ExceptionInInitializerError("initOpenssl failed : cannot convert " + explicitLoad + " to Integer"); ++ } ++ return version; + } + ++ + public KAEProvider() { + super("KAEProvider", 1.8d, "KAE provider"); + if (KAEConfig.useKaeProvider("kae.md5")) { +@@ -123,6 +147,12 @@ public class KAEProvider extends Provider { + if (KAEConfig.useKaeProvider("kae.ec")) { + putEC(); + } ++ if (KAEConfig.useKaeProvider("kae.sm2.cipher")) { ++ putSM2Cipher(); ++ } ++ if (KAEConfig.useKaeProvider("kae.sm2.signature")) { ++ putSM2Signature(); ++ } + } + + private void putAES() { +@@ -312,10 +342,29 @@ public class KAEProvider extends Provider { + put("KeyPairGenerator.EC", "org.openeuler.security.openssl.KAEECKeyPairGenerator"); + put("Alg.Alias.KeyPairGenerator.EllipticCurve", "EC"); + put("KeyAgreement.ECDH", "org.openeuler.security.openssl.KAEECDHKeyAgreement"); ++ ++ put("KeyFactory.EC", "org.openeuler.security.openssl.KAEECKeyFactory"); ++ put("Alg.Alias.KeyFactory.EllipticCurve", "EC"); ++ ++ put("AlgorithmParameters.EC", "org.openeuler.security.openssl.KAEECParameters"); ++ put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC"); ++ put("Alg.Alias.AlgorithmParameters.1.2.840.10045.2.1", "EC"); ++ } ++ ++ private void putSM2Cipher() { ++ put("KeyPairGenerator.SM2", "org.openeuler.security.openssl.KAESM2KeyPairGenerator"); ++ put("KeyFactory.SM2", "org.openeuler.security.openssl.KAEECKeyFactory"); ++ put("AlgorithmParameters.SM2", "org.openeuler.security.openssl.KAEECParameters"); ++ put("Alg.Alias.AlgorithmParameters.1.2.156.10197.1.301", "SM2"); ++ put("Cipher.SM2","org.openeuler.security.openssl.KAESM2Cipher"); ++ } ++ ++ private void putSM2Signature() { ++ put("Signature.SM3withSM2", "org.openeuler.security.openssl.KAESM2Signature$SM3withSM2"); + } + + // init openssl +- static native void initOpenssl(boolean useGlobalMode, String engineId, boolean[] algorithmKaeFlags) ++ static native int initOpenssl(int useOpensslVersion, String engineId, boolean[] algorithmKaeFlags) + throws RuntimeException; + + static native boolean[] getEngineFlags(); +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2Cipher.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2Cipher.java +new file mode 100644 +index 000000000..603783887 +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2Cipher.java +@@ -0,0 +1,385 @@ ++/* ++ * Copyright (c) 2023, Huawei Technologies Co., Ltd. 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. Huawei designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Huawei in the LICENSE file that accompanied this code. ++ * ++ * 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 visit https://gitee.com/openeuler/bgmprovider if you need additional ++ * information or have any questions. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import javax.crypto.*; ++import java.io.ByteArrayOutputStream; ++import java.lang.ref.PhantomReference; ++import java.lang.ref.ReferenceQueue; ++import java.security.*; ++import java.security.interfaces.*; ++import java.security.spec.AlgorithmParameterSpec; ++import java.util.Arrays; ++import java.util.Locale; ++import java.util.Set; ++import java.util.concurrent.ConcurrentSkipListSet; ++ ++import static org.openeuler.security.openssl.KAEUtils.asUnsignedByteArray; ++ ++public class KAESM2Cipher extends CipherSpi { ++ // buffer for the data ++ private KAEByteArrayOutputStream byteBuf = new KAEByteArrayOutputStream(); ++ ++ private ECKey ecKey; ++ private int cipherMode = -1; ++ ++ // sm2 key holder ++ private KAESM2KeyHolder sm2KeyHolder; ++ ++ // see JCE spec ++ @Override ++ protected void engineSetMode(String mode) throws NoSuchAlgorithmException { ++ String modeName = mode.toUpperCase(Locale.ROOT); ++ ++ if (!modeName.equals("NONE")) { ++ throw new IllegalArgumentException("can't support mode " + mode); ++ } ++ } ++ ++ // see JCE spec ++ @Override ++ protected void engineSetPadding(String padding) throws NoSuchPaddingException { ++ String paddingName = padding.toUpperCase(Locale.ROOT); ++ ++ if (!paddingName.equals("NOPADDING")) { ++ throw new NoSuchPaddingException("padding not available with KAESM2Cipher"); ++ } ++ } ++ ++ // see JCE spec ++ @Override ++ protected int engineGetBlockSize() { ++ return 0; ++ } ++ ++ // see JCE spec ++ @Override ++ protected int engineGetOutputSize(int inputLen) { ++ throw new UnsupportedOperationException("engineGetOutputSize"); ++ } ++ ++ // see JCE spec ++ @Override ++ protected byte[] engineGetIV() { ++ return null; ++ } ++ ++ // see JCE spec ++ @Override ++ protected AlgorithmParameters engineGetParameters() { ++ return null; ++ } ++ ++ // see JCE spec ++ @Override ++ protected byte[] engineWrap(Key key) ++ throws IllegalBlockSizeException, InvalidKeyException { ++ if (key == null) { ++ throw new InvalidKeyException("Key cannot be null"); ++ } ++ byte[] encoded = key.getEncoded(); ++ if ((encoded == null) || (encoded.length == 0)) { ++ throw new InvalidKeyException("Cannot get an encoding of " + ++ "the key to be wrapped"); ++ } ++ try { ++ return engineDoFinal(encoded, 0, encoded.length); ++ } catch (BadPaddingException e) { ++ throw new InvalidKeyException("Wrapping failed", e); ++ } ++ } ++ ++ // see JCE spec ++ @Override ++ protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) ++ throws InvalidKeyException, NoSuchAlgorithmException { ++ if (wrappedKey == null || wrappedKey.length == 0) { ++ throw new InvalidKeyException("The wrappedKey cannot be null or empty"); ++ } ++ byte[] unWrappedKey; ++ try { ++ unWrappedKey = engineDoFinal(wrappedKey, 0, wrappedKey.length); ++ } catch (IllegalBlockSizeException | BadPaddingException e) { ++ throw new InvalidKeyException("Unwrapping failed", e); ++ } ++ return KAEUtils.ConstructKeys.constructKey(unWrappedKey, wrappedKeyAlgorithm, wrappedKeyType); ++ } ++ ++ // see JCE spec ++ @Override ++ protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException { ++ try { ++ engineInit(opmode, key, (AlgorithmParameterSpec) null, random); ++ } catch (InvalidAlgorithmParameterException e) { ++ throw new IllegalArgumentException("cannot handle supplied parameter spec: " + e.getMessage()); ++ } ++ } ++ ++ // see JCE spec ++ @Override ++ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { ++ if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) { ++ if (key instanceof KAEECPublicKeyImpl) { ++ this.ecKey = (KAEECPublicKeyImpl) key; ++ } else if (key instanceof ECPublicKey) { ++ this.ecKey = (ECPublicKey) key; ++ } else { ++ throw new InvalidKeyException("must use public EC key for encryption"); ++ } ++ } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) { ++ if (key instanceof KAEECPrivateKeyImpl) { ++ this.ecKey = (KAEECPrivateKeyImpl) key; ++ } else if (key instanceof ECPrivateKey) { ++ this.ecKey = (ECPrivateKey) key; ++ } else { ++ throw new InvalidKeyException("must use private EC key for decryption"); ++ } ++ } else { ++ throw new InvalidParameterException("wrong cipher mode, must be ENCRYPT_MODE or WRAP_MODE or DECRYPT_MODE or UNWRAP_MODE"); ++ } ++ ++ try { ++ sm2KeyHolder = new KAESM2KeyHolder(this, ecKey); ++ } catch (InvalidKeyException e) { ++ throw new RuntimeException(e); ++ } ++ this.cipherMode = opmode; ++ this.byteBuf.reset(); ++ } ++ ++ // see JCE spec ++ @Override ++ protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { ++ AlgorithmParameterSpec paramSpec = null; ++ if (params != null) { ++ throw new InvalidAlgorithmParameterException("cannot recognise parameters: " + params.getClass().getName()); ++ } ++ engineInit(opmode, key, paramSpec, random); ++ } ++ ++ // see JCE spec ++ @Override ++ protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) { ++ byteBuf.write(input, inputOffset, inputLen); ++ return null; ++ } ++ ++ // see JCE spec ++ @Override ++ protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { ++ engineUpdate(input, inputOffset, inputLen); ++ return 0; ++ } ++ ++ // see JCE spec ++ @Override ++ protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) ++ throws IllegalBlockSizeException, BadPaddingException { ++ if (inputLen != 0) { ++ byteBuf.write(input, inputOffset, inputLen); ++ } ++ if(byteBuf.size() == 0){ ++ throw new IllegalBlockSizeException("input buffer too short"); ++ } ++ if (sm2KeyHolder == null) { ++ try { ++ sm2KeyHolder = new KAESM2KeyHolder(this, ecKey); ++ } catch (InvalidKeyException e) { ++ throw new RuntimeException(e); ++ } ++ } ++ ++ long keyAddress = sm2KeyHolder.keyAddress; ++ byte[] out; ++ try { ++ if (cipherMode == Cipher.ENCRYPT_MODE || cipherMode == Cipher.WRAP_MODE) { ++ try { ++ out = nativeSM2Encrypt(keyAddress, byteBuf.toByteArray(), byteBuf.size()); ++ } catch (RuntimeException e) { ++ throw new RuntimeException("KAESM2Cipher native encryption failed: " , e); ++ } ++ } else if (cipherMode == Cipher.DECRYPT_MODE || cipherMode == Cipher.UNWRAP_MODE) { ++ try { ++ out = nativeSM2Decrypt(keyAddress, byteBuf.toByteArray(), byteBuf.size()); ++ } catch (RuntimeException e) { ++ throw new RuntimeException("KAESM2Cipher native decryption failed: " , e); ++ } ++ } else { ++ throw new IllegalStateException("cipher not initialised"); ++ } ++ } finally { ++ byteBuf.reset(); ++ resetKeyHolder(); ++ } ++ return out; ++ } ++ ++ // see JCE spec ++ @Override ++ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) ++ throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { ++ byte[] buffer = engineDoFinal(input, inputOffset, inputLen); ++ System.arraycopy(buffer, 0, output, outputOffset, buffer.length); ++ return buffer.length; ++ } ++ ++ /** ++ * The sm2 openssl key holder , use PhantomReference in case of native memory leaks ++ */ ++ private static class KAESM2KeyHolder extends PhantomReference ++ implements Comparable { ++ private static ReferenceQueue referenceQueue = new ReferenceQueue<>(); ++ private static Set referenceList = new ConcurrentSkipListSet<>(); ++ private final long keyAddress; ++ ++ private static boolean disableKaeDispose = Boolean.getBoolean("kae.disableKaeDispose"); ++ ++ KAESM2KeyHolder(KAESM2Cipher sm2Cipher, ECKey sm2Key) throws InvalidKeyException { ++ super(sm2Cipher, referenceQueue); ++ this.keyAddress = getKeyAddress(sm2Key); ++ if (!disableKaeDispose) { ++ referenceList.add(this); ++ drainRefQueueBounded(); ++ } ++ } ++ ++ private static void drainRefQueueBounded() { ++ while (true) { ++ KAESM2KeyHolder next = (KAESM2KeyHolder) referenceQueue.poll(); ++ if (next == null) { ++ break; ++ } ++ next.dispose(true); ++ } ++ } ++ ++ void dispose(boolean needFree) { ++ if (!disableKaeDispose) { ++ referenceList.remove(this); ++ try { ++ if (needFree) { ++ nativeFreeKey(keyAddress); ++ } ++ } finally { ++ this.clear(); ++ } ++ } else { ++ nativeFreeKey(keyAddress); ++ } ++ } ++ ++ @Override ++ public int compareTo(KAESM2KeyHolder other) { ++ if (this.keyAddress == other.keyAddress) { ++ return 0; ++ } else { ++ return (this.keyAddress < other.keyAddress) ? -1 : 1; ++ } ++ } ++ ++ private long getKeyAddress(ECKey sm2Key) throws InvalidKeyException { ++ long address; ++ if (sm2Key instanceof ECPrivateKey) { // ECPrivateKeyImpl ++ address = getKeyAddress((ECPrivateKey) sm2Key); ++ } else if (sm2Key instanceof ECPublicKey) { // ECPublicKeyImpl ++ address = getKeyAddress((ECPublicKey) sm2Key); ++ } else { ++ throw new InvalidKeyException("Invalid SM2Key implement " + sm2Key.getClass()); ++ } ++ return address; ++ } ++ ++ private long getKeyAddress(ECPrivateKey key) throws InvalidKeyException { ++ checkKey(key); ++ long address; ++ int curveLen = (key.getParams().getCurve().getField().getFieldSize() + 7) / 8; ++ try { ++ address = nativeCreateSM2PrivateKey(asUnsignedByteArray(curveLen, key.getS()), false); ++ return address; ++ } catch (RuntimeException e) { ++ throw new InvalidKeyException(e); ++ } ++ } ++ ++ private long getKeyAddress(ECPublicKey key) throws InvalidKeyException { ++ checkKey(key); ++ long address; ++ int curveLen = (key.getParams().getCurve().getField().getFieldSize() + 7) / 8; ++ try { ++ address = nativeCreateSM2PublicKey( ++ asUnsignedByteArray(curveLen, key.getW().getAffineX()), ++ asUnsignedByteArray(curveLen, key.getW().getAffineY()) ++ ); ++ return address; ++ } catch (RuntimeException e) { ++ throw new InvalidKeyException(e); ++ } ++ } ++ ++ private void checkKey(ECPrivateKey key) throws InvalidKeyException { ++ if (key.getS() == null) { ++ throw new InvalidKeyException("Invalid SM2 private key"); ++ } ++ } ++ ++ private void checkKey(ECPublicKey key) throws InvalidKeyException { ++ if (key.getW() == null || key.getW().getAffineX() == null || key.getW().getAffineY() == null) { ++ throw new InvalidKeyException("Invalid SM2 public key"); ++ } ++ } ++ } ++ ++ // reset the key holder ++ private void resetKeyHolder() { ++ if (sm2KeyHolder != null) { ++ sm2KeyHolder.dispose(true); ++ sm2KeyHolder = null; ++ } ++ } ++ ++ // create KAE sm2 private key ++ protected static native long nativeCreateSM2PublicKey(byte[] x, byte[] y); ++ ++ // create KAE sm2 public key ++ protected static native long nativeCreateSM2PrivateKey(byte[] key, boolean sign); ++ ++ // free the key ++ protected static native void nativeFreeKey(long keyAddress); ++ ++ // Encrypt message using sm2 algorithm ++ protected static native byte[] nativeSM2Encrypt(long keyAddress, byte[] input, int inputLen); ++ ++ // Decrypt message using sm2 algorithm ++ protected static native byte[] nativeSM2Decrypt(long keyAddress, byte[] input, int inputLen); ++ ++ private static class KAEByteArrayOutputStream extends ByteArrayOutputStream { ++ @Override ++ public synchronized void reset() { ++ // Clear data. ++ Arrays.fill(buf, (byte) 0); ++ super.reset(); ++ } ++ } ++} +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2KeyPairGenerator.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2KeyPairGenerator.java +new file mode 100644 +index 000000000..bf59df916 +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2KeyPairGenerator.java +@@ -0,0 +1,108 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import java.math.BigInteger; ++import java.security.InvalidAlgorithmParameterException; ++import java.security.InvalidKeyException; ++import java.security.InvalidParameterException; ++import java.security.KeyPair; ++import java.security.ProviderException; ++import java.security.SecureRandom; ++import java.security.spec.AlgorithmParameterSpec; ++import java.security.spec.ECFieldFp; ++import java.security.spec.ECGenParameterSpec; ++import java.security.spec.ECParameterSpec; ++import java.security.spec.ECPoint; ++import java.security.spec.EllipticCurve; ++ ++public class KAESM2KeyPairGenerator extends KAEECKeyPairGenerator { ++ private static final String SUPPORTED_CURVE_NAME = "sm2p256v1"; ++ private static final int SUPPORTED_KEY_SIZE = 256; ++ private ECParameterSpec param = null; ++ ++ @Override ++ public void initialize(int keysize, SecureRandom random) { ++ if (keysize != SUPPORTED_KEY_SIZE) { ++ throw new InvalidParameterException("unknown key size " + keysize); ++ } ++ String curveName = KAEUtils.getCurveByAlias(SUPPORTED_CURVE_NAME); ++ param = getParamsByCurve(curveName); ++ } ++ ++ @Override ++ public void initialize(AlgorithmParameterSpec param, SecureRandom random) ++ throws InvalidAlgorithmParameterException { ++ if (param instanceof ECParameterSpec) { ++ this.param = (ECParameterSpec) param; ++ } else if (param instanceof ECGenParameterSpec) { ++ ECGenParameterSpec ecParam = (ECGenParameterSpec)param; ++ if (!SUPPORTED_CURVE_NAME.equals(ecParam.getName())) { ++ throw new InvalidAlgorithmParameterException("Only support sm2p256v1"); ++ } ++ String curveName = KAEUtils.getCurveByAlias(SUPPORTED_CURVE_NAME); ++ this.param = getParamsByCurve(curveName); ++ } else { ++ throw new InvalidAlgorithmParameterException("ECParameterSpec or ECGenParameterSpec for EC"); ++ } ++ } ++ ++ @Override ++ public KeyPair generateKeyPair() { ++ if (param == null) { ++ String curveName = KAEUtils.getCurveByAlias(SUPPORTED_CURVE_NAME); ++ param = getParamsByCurve(curveName); ++ } ++ EllipticCurve curve = param.getCurve(); ++ ECFieldFp field = (ECFieldFp) curve.getField(); ++ BigInteger p = field.getP(); ++ BigInteger a = curve.getA(); ++ BigInteger b = curve.getB(); ++ ECPoint generator = param.getGenerator(); ++ BigInteger x = generator.getAffineX(); ++ BigInteger y = generator.getAffineY(); ++ BigInteger order = param.getOrder(); ++ int cofactor = param.getCofactor(); ++ ++ byte[][] keys = nativeGenerateKeyPair(p.toByteArray(), a.toByteArray(), ++ b.toByteArray(), x.toByteArray(), y.toByteArray(), order.toByteArray(), cofactor); ++ if (keys == null) { ++ throw new RuntimeException("nativeGenerateKeyPair failed"); ++ } ++ BigInteger wX = new BigInteger(keys[0]); ++ BigInteger wY = new BigInteger(keys[1]); ++ BigInteger s = new BigInteger(keys[2]); ++ ECPoint w = new ECPoint(wX, wY); ++ ++ KAEECPrivateKeyImpl privateKey; ++ KAEECPublicKeyImpl publicKey; ++ try { ++ publicKey = new KAEECPublicKeyImpl(w, param); ++ privateKey = new KAEECPrivateKeyImpl(s, param); ++ } catch (InvalidKeyException e) { ++ throw new ProviderException(e); ++ } ++ return new KeyPair(publicKey, privateKey); ++ } ++} +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2Signature.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2Signature.java +new file mode 100644 +index 000000000..fc2ac3eb2 +--- /dev/null ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM2Signature.java +@@ -0,0 +1,373 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * 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. ++ */ ++ ++package org.openeuler.security.openssl; ++ ++import java.lang.ref.PhantomReference; ++import java.lang.ref.ReferenceQueue; ++import java.lang.reflect.Field; ++import java.nio.charset.StandardCharsets; ++import java.security.*; ++import java.security.interfaces.ECPrivateKey; ++import java.security.interfaces.ECPublicKey; ++import java.security.spec.AlgorithmParameterSpec; ++import java.util.Set; ++import java.util.concurrent.ConcurrentSkipListSet; ++ ++import static org.openeuler.security.openssl.KAEUtils.asUnsignedByteArray; ++ ++/** ++ * We only support support SM2 signatures with SM3 as the digest algorithm. ++ */ ++public abstract class KAESM2Signature extends SignatureSpi { ++ /** ++ * The current mode, signature or signature verification. ++ */ ++ enum Mode { ++ SIGNATURE, ++ VERIFY ++ } ++ ++ /** ++ * Message digest algorithm name used for signing. Currently, only SM3 is supported. ++ */ ++ enum DigestName { ++ SM3("SM3"); ++ ++ private final String digestName; ++ ++ DigestName(String digestName) { ++ this.digestName = digestName; ++ } ++ ++ public String getDigestValue() { ++ return digestName; ++ } ++ } ++ ++ // message digest algorithm name we use ++ private final DigestName digestName; ++ ++ // private key, if initialized for signing ++ private ECPrivateKey privateKey; ++ ++ // public key, if initialized for verifying ++ private ECPublicKey publicKey; ++ ++ // openssl context, save initialization information and updated messages. ++ private SM2SignCtxHolder ctxHolder; ++ ++ // openssl context copy, reset after signature or verification ++ private SM2SignCtxHolder ctxHolderCopy; ++ ++ // the current mode ++ private Mode mode; ++ ++ // initialized or not ++ private boolean initialized = false; ++ ++ // default value ++ private String id = "1234567812345678"; ++ ++ public KAESM2Signature() throws NoSuchAlgorithmException{ ++ this(DigestName.SM3.getDigestValue()); ++ } ++ ++ public KAESM2Signature(String digest) throws NoSuchAlgorithmException{ ++ if ("SM3".equals(digest)){ ++ this.digestName = DigestName.SM3; ++ }else { ++ throw new NoSuchAlgorithmException("KAESM2Signature not support the " + digest + "digest algorithm"); ++ } ++ } ++ ++ /** ++ * Initializes this signature object with the specified ++ * public key for verification operations. ++ * ++ * @param publicKey the public key of the identity whose signature is ++ * going to be verified. ++ */ ++ @Override ++ protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { ++ this.publicKey = (ECPublicKey) KAEECKeyFactory.toECKey(publicKey); ++ long keyAddress; ++ try { ++ int curveLen = (this.publicKey.getParams().getCurve().getField().getFieldSize() + 7) / 8; ++ keyAddress = KAESM2Cipher.nativeCreateSM2PublicKey( ++ asUnsignedByteArray(curveLen, this.publicKey.getW().getAffineX()), ++ asUnsignedByteArray(curveLen, this.publicKey.getW().getAffineY())); ++ } catch (RuntimeException e) { ++ throw new RuntimeException("KAESM2Signature nativeCreateSM2PublicKey failed", e); ++ } ++ try { ++ long verifyCtx = nativeInitSM2Ctx(keyAddress, digestName.getDigestValue(), id, Boolean.FALSE); ++ if (verifyCtx == 0){ ++ throw new InvalidKeyException("engineInitSign verifyCtx is invalid"); ++ } ++ this.ctxHolder = new SM2SignCtxHolder(this, verifyCtx); ++ } catch (RuntimeException e) { ++ throw new RuntimeException("KAESM2Signature nativeInitSM2Ctx failed", e); ++ }finally { ++ KAESM2Cipher.nativeFreeKey(keyAddress); ++ } ++ this.mode = Mode.VERIFY; ++ this.initialized = true; ++ } ++ ++ /** ++ * Initializes this signature object with the specified ++ * private key for signing operations. ++ * ++ * @param privateKey the private key of the identity whose signature ++ * will be generated. ++ */ ++ @Override ++ protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { ++ this.privateKey = (ECPrivateKey) KAEECKeyFactory.toECKey(privateKey); ++ long keyAddress; ++ try { ++ int curveLen = (this.privateKey.getParams().getCurve().getField().getFieldSize() + 7) / 8; ++ keyAddress = KAESM2Cipher.nativeCreateSM2PrivateKey(asUnsignedByteArray(curveLen, this.privateKey.getS()), true); ++ } catch (RuntimeException e) { ++ throw new InvalidKeyException("KAESM2Signature nativeCreateSM2PrivateKey failed", e); ++ } ++ try { ++ long signCtx = nativeInitSM2Ctx(keyAddress, digestName.getDigestValue(), id, Boolean.TRUE); ++ if (signCtx == 0){ ++ throw new InvalidKeyException("engineInitSign signCtx is invalid"); ++ } ++ this.ctxHolder = new SM2SignCtxHolder(this, signCtx); ++ } catch (RuntimeException e) { ++ throw new RuntimeException("KAESM2Signature nativeInitSM2Ctx failed", e); ++ }finally { ++ KAESM2Cipher.nativeFreeKey(keyAddress); ++ } ++ this.mode = Mode.SIGNATURE; ++ this.initialized = true; ++ } ++ ++ // update the signature with the plaintext data. See JCA doc ++ @Override ++ protected void engineUpdate(byte b) throws SignatureException { ++ byte[] msg = new byte[1]; ++ msg[0] = b; ++ engineUpdate(msg, 0, 1); ++ } ++ ++ // update the signature with the plaintext data. See JCA doc ++ @Override ++ protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { ++ if(!initialized || ctxHolder == null){ ++ throw new SignatureException("The engine is not initialized"); ++ } ++ byte[] msg = new byte[len]; ++ System.arraycopy(b, off, msg, 0, len); ++ if (ctxHolderCopy == null) { ++ ctxHolderCopy = createCtxHolder(this, ctxHolder.ctxAddress); ++ } ++ try { ++ if(this.mode == Mode.SIGNATURE){ ++ nativeSM2Update(ctxHolderCopy.ctxAddress, msg, len, Boolean.TRUE); ++ }else { ++ // Mode.VERIFY ++ nativeSM2Update(ctxHolderCopy.ctxAddress, msg, len, Boolean.FALSE); ++ } ++ } catch (RuntimeException e) { ++ throw new RuntimeException("KAESM2Signature nativeSM2Update Failed", e); ++ } ++ } ++ ++ // see JCE spec ++ @Override ++ protected byte[] engineSign() throws SignatureException { ++ if(!initialized || ctxHolder == null){ ++ throw new SignatureException("The engine is not initialized"); ++ } ++ if (ctxHolderCopy == null) { ++ ctxHolderCopy = createCtxHolder(this, ctxHolder.ctxAddress); ++ } ++ byte[] sigBytes; ++ try { ++ sigBytes = nativeSM2SignFinal(ctxHolderCopy.ctxAddress); ++ } catch (SignatureException e){ ++ throw new RuntimeException("KAESM2Signature nativeSM2SignFinal Failed", e); ++ }finally { ++ resetCtxHolderCopy(); ++ } ++ return sigBytes; ++ } ++ ++ // see JCE spec ++ @Override ++ protected boolean engineVerify(byte[] sigBytes) throws SignatureException { ++ if(!initialized || ctxHolder == null){ ++ throw new SignatureException("The engine is not initialized"); ++ } ++ if (ctxHolderCopy == null) { ++ ctxHolderCopy = createCtxHolder(this, ctxHolder.ctxAddress); ++ } ++ try { ++ return nativeSM2VerifyFinal(ctxHolderCopy.ctxAddress, sigBytes, sigBytes.length); ++ } catch (SignatureException e){ ++ throw new RuntimeException("KAESM2Signature nativeSM2VerifyFinal Failed", e); ++ }finally { ++ resetCtxHolderCopy(); ++ } ++ } ++ ++ // set parameter, not supported. See JCA doc ++ @Deprecated ++ @Override ++ protected void engineSetParameter(String param, Object value) throws InvalidParameterException { ++ throw new UnsupportedOperationException("setParameter() not supported"); ++ } ++ ++ @Override ++ protected void engineSetParameter(AlgorithmParameterSpec params) ++ throws InvalidAlgorithmParameterException { ++ if (params == null) { ++ throw new InvalidAlgorithmParameterException("params is null"); ++ } ++ ++ try { ++ Class clazz = params.getClass(); ++ Field field = clazz.getDeclaredField("id"); ++ field.setAccessible(true); ++ byte[] idValue = (byte[]) field.get(params); ++ this.id = new String(idValue, StandardCharsets.UTF_8); ++ } catch (IllegalAccessException | NoSuchFieldException e) { ++ throw new InvalidAlgorithmParameterException("Failed to get id field from params"); ++ } ++ } ++ ++ // get parameter, not supported. See JCA doc ++ @Deprecated ++ @Override ++ protected Object engineGetParameter(String param) throws InvalidParameterException { ++ throw new UnsupportedOperationException("getParameter() not supported"); ++ } ++ ++ /** ++ * The sm2 sign openssl md_ctx holder , use PhantomReference in case of native memory leaks ++ */ ++ private static class SM2SignCtxHolder extends PhantomReference ++ implements Comparable { ++ private static ReferenceQueue referenceQueue = new ReferenceQueue<>(); ++ private static Set referenceList = new ConcurrentSkipListSet<>(); ++ private final long ctxAddress; ++ ++ private static boolean disableKaeDispose = Boolean.getBoolean("kae.disableKaeDispose"); ++ ++ SM2SignCtxHolder(KAESM2Signature sm2Cipher, long ctxAddress) { ++ super(sm2Cipher, referenceQueue); ++ this.ctxAddress = ctxAddress; ++ if (!disableKaeDispose) { ++ referenceList.add(this); ++ drainRefQueueBounded(); ++ } ++ } ++ ++ private static void drainRefQueueBounded() { ++ while (true) { ++ SM2SignCtxHolder next = (SM2SignCtxHolder) referenceQueue.poll(); ++ if (next == null) { ++ break; ++ } ++ next.dispose(true); ++ } ++ } ++ ++ void dispose(boolean needFree) { ++ if (!disableKaeDispose) { ++ referenceList.remove(this); ++ try { ++ if (needFree) { ++ nativeFreeSM2Ctx(ctxAddress); ++ } ++ } finally { ++ this.clear(); ++ } ++ } else { ++ nativeFreeSM2Ctx(ctxAddress); ++ } ++ } ++ ++ @Override ++ public int compareTo(SM2SignCtxHolder other) { ++ if (this.ctxAddress == other.ctxAddress) { ++ return 0; ++ } else { ++ return (this.ctxAddress < other.ctxAddress) ? -1 : 1; ++ } ++ } ++ } ++ ++ // reset the ctx holder ++ private void resetCtxHolderCopy() { ++ if (ctxHolderCopy != null) { ++ ctxHolderCopy.dispose(true); ++ ctxHolderCopy = null; ++ } ++ } ++ ++ private SM2SignCtxHolder createCtxHolder(KAESM2Signature kaesm2Signature, long ctxAddress) { ++ long addr; ++ try { ++ addr = nativeClone(ctxAddress); ++ } catch (RuntimeException e) { ++ throw new RuntimeException("SM2SignCtxHolder nativeClone failed", e); ++ } ++ if (addr == 0) { ++ throw new RuntimeException("SM2SignCtxHolder nativeClone EVP_MD_CTX failed"); ++ } ++ return new SM2SignCtxHolder(kaesm2Signature, addr); ++ } ++ ++ // clone the sign ctx ++ protected static native long nativeClone(long ctxAddress); ++ ++ // free the sign ctx ++ protected static native void nativeFreeSM2Ctx(long ctxAddress); ++ ++ // init openssl sm2 signature context ++ protected static native long nativeInitSM2Ctx(long keyAddress, String digestName, String id, boolean isSign); ++ ++ // update openssl sm2 signature text ++ protected static native void nativeSM2Update(long ctxAddress, byte[] msg, int msgLen, boolean isSign); ++ ++ // sm2 signature do final ++ protected static native byte[] nativeSM2SignFinal(long ctxAddress) throws SignatureException; ++ ++ // sm2 verification do final ++ protected static native boolean nativeSM2VerifyFinal(long ctxAddress, byte[] sigBytes, int sigLen) throws SignatureException; ++ ++ static public class SM3withSM2 ++ extends KAESM2Signature { ++ public SM3withSM2() throws NoSuchAlgorithmException { ++ super(DigestName.SM3.getDigestValue()); ++ } ++ } ++} +diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEUtils.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEUtils.java +index 21a6116ed..fce1845c9 100644 +--- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEUtils.java ++++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEUtils.java +@@ -27,6 +27,7 @@ package org.openeuler.security.openssl; + import javax.crypto.Cipher; + import javax.crypto.SecretKey; + import javax.crypto.spec.SecretKeySpec; ++import java.math.BigInteger; + import java.security.*; + import java.security.spec.InvalidKeySpecException; + import java.security.spec.PKCS8EncodedKeySpec; +@@ -198,16 +199,50 @@ class KAEUtils { + } + } + ++ /** ++ * Return the passed in value as an unsigned byte array of the specified length, padded with ++ * leading zeros as necessary.. ++ * ++ * @param length the fixed length of the result ++ * @param value the value to be converted. ++ * @return a byte array padded to a fixed length with leading zeros. ++ */ ++ protected static byte[] asUnsignedByteArray(int length, BigInteger value) { ++ byte[] bytes = value.toByteArray(); ++ if (bytes.length == length) { ++ return bytes; ++ } ++ ++ int start = (bytes[0] == 0 && bytes.length != 1) ? 1 : 0; ++ int count = bytes.length - start; ++ ++ if (count > length) { ++ throw new IllegalArgumentException("standard length exceeded for value"); ++ } ++ ++ byte[] tmp = new byte[length]; ++ System.arraycopy(bytes, start, tmp, tmp.length - count, count); ++ return tmp; ++ } ++ + private static void initECDH() { + SIZE_TO_CURVE.put(224, "secp224r1"); + SIZE_TO_CURVE.put(256, "prime256v1"); + SIZE_TO_CURVE.put(384, "secp384r1"); + SIZE_TO_CURVE.put(521, "secp521r1"); ++ ++ CURVE_ALIAS.put("secp224r1", "secp224r1"); ++ CURVE_ALIAS.put("prime256v1", "prime256v1"); ++ CURVE_ALIAS.put("secp384r1", "secp384r1"); ++ CURVE_ALIAS.put("secp521r1", "secp521r1"); ++ + CURVE_ALIAS.put("secp256r1", "prime256v1"); ++ CURVE_ALIAS.put("sm2p256v1", "SM2"); + CURVE_ALIAS.put("1.3.132.0.33", "secp224r1"); + CURVE_ALIAS.put("1.3.132.0.34", "secp384r1"); + CURVE_ALIAS.put("1.3.132.0.35", "secp521r1"); + CURVE_ALIAS.put("1.2.840.10045.3.1.7", "prime256v1"); ++ CURVE_ALIAS.put("1.2.156.10197.1.301", "SM2"); + } + + static String getCurveBySize(int size) { +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c +index d9b16ab9d..542986892 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c +@@ -27,6 +27,7 @@ + #include "kae_log.h" + #include "kae_util.h" + #include "kae_exception.h" ++#include "ssl_utils.h" + #include "org_openeuler_security_openssl_KAERSACipher.h" + + typedef int RSACryptOperation(int, const unsigned char*, unsigned char*, RSA*, int); +@@ -49,7 +50,7 @@ static int RSACryptNotOAEPPadding(JNIEnv* env, jlong keyAddress, jint inLen, jby + EVP_PKEY* pkey = (EVP_PKEY*) keyAddress; + + // rsa = pkey->rsa +- RSA* rsa = EVP_PKEY_get1_RSA(pkey); ++ RSA* rsa = SSL_UTILS_EVP_PKEY_get1_RSA(pkey); + if (rsa == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_get1_RSA", KAE_ThrowRuntimeException); + return 0; +@@ -82,7 +83,7 @@ cleanup: + (*env)->ReleaseByteArrayElements(env, in, inBytes, 0); + } + if (rsa != NULL) { +- RSA_free(rsa); ++ SSL_UTILS_RSA_free(rsa); + } + return resultSize; + } +@@ -91,7 +92,7 @@ cleanup: + * set rsa padding + */ + static bool SetRSAPadding(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, int paddingType) { +- if (EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_padding", KAE_ThrowInvalidAlgorithmParameterException); + return false; + } +@@ -102,12 +103,12 @@ static bool SetRSAPadding(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, int paddingType) { + * set rsa mgf1 md + */ + static bool SetRSAMgf1Md(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, const char* mgf1MdAlgoUTF) { +- EVP_MD* mgf1MD = (EVP_MD*)EVP_get_digestbyname(mgf1MdAlgoUTF); ++ EVP_MD* mgf1MD = (EVP_MD*)SSL_UTILS_EVP_get_digestbyname(mgf1MdAlgoUTF); + if (mgf1MD == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_get_digestbyname", KAE_ThrowInvalidAlgorithmParameterException); + return false; + } +- if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, mgf1MD) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, mgf1MD) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_mgf1_md", KAE_ThrowInvalidAlgorithmParameterException); + return false; + } +@@ -118,12 +119,12 @@ static bool SetRSAMgf1Md(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, const char* mgf1MdA + * set rsa oaep md + */ + static bool SetRSAOaepMd(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, const char* oaepMdAlgoUTF) { +- EVP_MD* oaepMD = (EVP_MD*)EVP_get_digestbyname(oaepMdAlgoUTF); ++ EVP_MD* oaepMD = (EVP_MD*)SSL_UTILS_EVP_get_digestbyname(oaepMdAlgoUTF); + if (oaepMD == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_get_digestbyname", KAE_ThrowInvalidAlgorithmParameterException); + return false; + } +- if (EVP_PKEY_CTX_set_rsa_oaep_md(pkeyCtx, oaepMD) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_rsa_oaep_md(pkeyCtx, oaepMD) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_oaep_md", KAE_ThrowInvalidAlgorithmParameterException); + return false; + } +@@ -134,7 +135,7 @@ static bool SetRSAOaepMd(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, const char* oaepMdA + * set rsa oaep label + */ + static bool SetRSAOaepLabel(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jbyte* labelBytes, jsize labelSize) { +- if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkeyCtx, labelBytes, labelSize) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set0_rsa_oaep_label(pkeyCtx, labelBytes, labelSize) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set0_rsa_oaep_label", KAE_ThrowInvalidAlgorithmParameterException); + return false; + } +@@ -159,7 +160,7 @@ static void ReleaseRSACryptOAEPResource(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, + if (inBytes != NULL) { + (*env)->ReleaseByteArrayElements(env, in, inBytes, 0); + } +- EVP_PKEY_CTX_free(pkeyCtx); ++ SSL_UTILS_EVP_PKEY_CTX_free(pkeyCtx); + } + + static int RSACryptOAEPPadding(JNIEnv* env, jlong keyAddress, jint inLen, jbyteArray in, jbyteArray out, +@@ -184,7 +185,7 @@ static int RSACryptOAEPPadding(JNIEnv* env, jlong keyAddress, jint inLen, jbyteA + + // new ctx + // rsa encrypt/decrypt init +- if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL || cryptInitOperation(pkeyCtx) <= 0) { ++ if ((pkeyCtx = SSL_UTILS_EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL || cryptInitOperation(pkeyCtx) <= 0) { + KAE_ThrowFromOpenssl(env, pkeyCtx == NULL ? "EVP_PKEY_CTX_new" : cryptInitName, KAE_ThrowInvalidKeyException); + goto cleanup; + } +@@ -290,29 +291,30 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC + } + + // new pkey +- pkey = EVP_PKEY_new(); ++ pkey = SSL_UTILS_EVP_PKEY_new(); + if (pkey == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowRuntimeException); + goto cleanup; + } + + // new rsa +- rsa = RSA_new_method(kaeEngine); ++ rsa = SSL_UTILS_RSA_new_method(kaeEngine); + if (rsa == NULL) { + KAE_ThrowFromOpenssl(env, "RSA_new_method", KAE_ThrowRuntimeException); + goto cleanup; + } + + // set rsa private crt key params n,e,d,p,q,dmp1,dmp1,iqmp +- if (RSA_set0_key(rsa, bnN, bnE, bnD) <= 0 || +- RSA_set0_factors(rsa, bnP, bnQ) <= 0 || +- RSA_set0_crt_params(rsa, bnDMP1, bnDMQ1, bnIQMP) <= 0) { ++ if (SSL_UTILS_RSA_set0_key(rsa, bnN, bnE, bnD) <= 0 || ++ SSL_UTILS_RSA_set0_factors(rsa, bnP, bnQ) <= 0 || ++ SSL_UTILS_RSA_set0_crt_params(rsa, bnDMP1, bnDMQ1, bnIQMP) <= 0) { + KAE_ThrowFromOpenssl(env, "RSA set param", KAE_ThrowRuntimeException); + goto cleanup; + } + + // assign rsa to pkey +- int result = EVP_PKEY_assign_RSA(pkey, rsa); ++ //change from macro, "EVP_PKEY_assign_RSA(pkey,rsa)" is same as EVP_PKEY_assign((pkey),EVP_PKEY_RSA, (rsa)) ++ int result = SSL_UTILS_EVP_PKEY_assign_RSA(pkey, rsa); + if (result <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_assign_RSA", KAE_ThrowRuntimeException); + goto cleanup; +@@ -320,8 +322,8 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC + return (jlong)pkey; + cleanup: + ReleaseRSAParams(bnN, bnE, bnD, bnP, bnQ, bnDMP1, bnDMQ1, bnIQMP); +- RSA_free(rsa); +- EVP_PKEY_free(pkey); ++ SSL_UTILS_RSA_free(rsa); ++ SSL_UTILS_EVP_PKEY_free(pkey); + return 0; + } + +@@ -353,27 +355,28 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC + } + + // new rsa +- rsa = RSA_new_method(kaeEngine); ++ rsa = SSL_UTILS_RSA_new_method(kaeEngine); + if (rsa == NULL) { + KAE_ThrowFromOpenssl(env, "RSA_new_method", KAE_ThrowRuntimeException); + goto cleanup; + } + + // new EVP_PKEY +- pkey = EVP_PKEY_new(); ++ pkey = SSL_UTILS_EVP_PKEY_new(); + if (pkey == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowRuntimeException); + goto cleanup; + } + + // set rsa public key params n and e +- if (RSA_set0_key(rsa, bnN, bnE, NULL) <= 0) { ++ if (SSL_UTILS_RSA_set0_key(rsa, bnN, bnE, NULL) <= 0) { + KAE_ThrowFromOpenssl(env, "RSA_set0_key", KAE_ThrowRuntimeException); + goto cleanup; + } + + // assign rsa to pkey +- int result = EVP_PKEY_assign_RSA(pkey, rsa); ++ //change from macro, "EVP_PKEY_assign_RSA(pkey,rsa)" is same as EVP_PKEY_assign((pkey),EVP_PKEY_RSA, (rsa)) ++ int result = SSL_UTILS_EVP_PKEY_assign_RSA(pkey, rsa); + if (result <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_assign_RSA", KAE_ThrowRuntimeException); + goto cleanup; +@@ -382,8 +385,8 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC + cleanup: + KAE_ReleaseBigNumFromByteArray(bnN); + KAE_ReleaseBigNumFromByteArray(bnE); +- RSA_free(rsa); +- EVP_PKEY_free(pkey); ++ SSL_UTILS_RSA_free(rsa); ++ SSL_UTILS_EVP_PKEY_free(pkey); + return 0; + } + +@@ -394,7 +397,7 @@ cleanup: + */ + JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRSAPrivateEncrypt(JNIEnv* env, + jclass cls, jlong keyAddress, jint inLen, jbyteArray in, jbyteArray out, jint paddingType) { +- return RSACryptNotOAEPPadding(env, keyAddress, inLen, in, out, paddingType, RSA_private_encrypt, ++ return RSACryptNotOAEPPadding(env, keyAddress, inLen, in, out, paddingType, SSL_UTILS_RSA_private_encrypt, + "RSA_private_encrypt"); + } + +@@ -405,7 +408,7 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRS + */ + JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRSAPrivateDecrypt(JNIEnv* env, + jclass cls, jlong keyAddress, jint inLen, jbyteArray in, jbyteArray out, jint paddingType) { +- return RSACryptNotOAEPPadding(env, keyAddress, inLen, in, out, paddingType, RSA_private_decrypt, ++ return RSACryptNotOAEPPadding(env, keyAddress, inLen, in, out, paddingType, SSL_UTILS_RSA_private_decrypt, + "RSA_private_decrypt"); + } + +@@ -416,7 +419,7 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRS + */ + JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRSAPublicEncrypt(JNIEnv* env, + jclass cls, jlong keyAddress, jint inLen, jbyteArray in, jbyteArray out, jint paddingType) { +- return RSACryptNotOAEPPadding(env, keyAddress, inLen, in, out, paddingType, RSA_public_encrypt, ++ return RSACryptNotOAEPPadding(env, keyAddress, inLen, in, out, paddingType, SSL_UTILS_RSA_public_encrypt, + "RSA_public_encrypt"); + } + +@@ -427,7 +430,7 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRS + */ + JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRSAPublicDecrypt(JNIEnv* env, + jclass cls, jlong keyAddress, jint inLen, jbyteArray in, jbyteArray out, jint paddingType) { +- return RSACryptNotOAEPPadding(env, keyAddress, inLen, in, out, paddingType, RSA_public_decrypt, ++ return RSACryptNotOAEPPadding(env, keyAddress, inLen, in, out, paddingType, SSL_UTILS_RSA_public_decrypt, + "RSA_public_decrypt"); + } + +@@ -440,8 +443,8 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRS + jclass cls, jlong keyAddress, jint inLen, jbyteArray in, jbyteArray out, + jint paddingType, jstring oaepMdAlgo, jstring mgf1MdAlgo, jbyteArray label) { + return RSACryptOAEPPadding(env, keyAddress, inLen, in, out, paddingType, oaepMdAlgo, mgf1MdAlgo, label, +- EVP_PKEY_encrypt_init, "EVP_PKEY_encrypt_init", +- EVP_PKEY_encrypt, "EVP_PKEY_encrypt"); ++ SSL_UTILS_EVP_PKEY_encrypt_init, "EVP_PKEY_encrypt_init", ++ SSL_UTILS_EVP_PKEY_encrypt, "EVP_PKEY_encrypt"); + } + + /* +@@ -453,8 +456,8 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeRS + jclass cls, jlong keyAddress, jint inLen, jbyteArray in, jbyteArray out, jint paddingType, + jstring oaepMdAlgo, jstring mgf1MdAlgo, jbyteArray label) { + return RSACryptOAEPPadding(env, keyAddress, inLen, in, out, paddingType, oaepMdAlgo, mgf1MdAlgo, label, +- EVP_PKEY_decrypt_init, "EVP_PKEY_decrypt_init", +- EVP_PKEY_decrypt, "EVP_PKEY_decrypt"); ++ SSL_UTILS_EVP_PKEY_decrypt_init, "EVP_PKEY_decrypt_init", ++ SSL_UTILS_EVP_PKEY_decrypt, "EVP_PKEY_decrypt"); + } + + /* +@@ -466,6 +469,6 @@ JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeFr + jclass cls, jlong keyAddress) { + EVP_PKEY* pkey = (EVP_PKEY*) keyAddress; + if (pkey != NULL) { +- EVP_PKEY_free(pkey); ++ SSL_UTILS_EVP_PKEY_free(pkey); + } + } +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_sm2.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_sm2.c +new file mode 100644 +index 000000000..3a53392b4 +--- /dev/null ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_sm2.c +@@ -0,0 +1,368 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include "kae_util.h" ++#include "kae_log.h" ++#include "kae_exception.h" ++#include "org_openeuler_security_openssl_KAESM2Cipher.h" ++#include "ssl_utils.h" ++ ++static void FreeSM2KeyParam(BIGNUM* bn_x, BIGNUM* bn_y, BIGNUM* bn_key, EC_GROUP* group, EC_POINT* pt) ++{ ++ if (bn_x != NULL) { ++ KAE_ReleaseBigNumFromByteArray(bn_x); ++ } ++ if (bn_y != NULL) { ++ KAE_ReleaseBigNumFromByteArray(bn_y); ++ } ++ if (bn_key != NULL) { ++ KAE_ReleaseBigNumFromByteArray_Clear(bn_key); ++ } ++ if (group != NULL) { ++ SSL_UTILS_EC_GROUP_free(group); ++ } ++ if (pt != NULL) { ++ SSL_UTILS_EC_POINT_free(pt); ++ } ++} ++ ++/* ++ * SM2 encrypt or decrypt, follow the steps below ++ */ ++static jbyteArray SM2_Crypt(JNIEnv *env, jlong keyAddress, jbyteArray inArr, jint inLen, bool isEncrypt) { ++ unsigned char* inbytes = NULL; ++ unsigned char* outbytes = NULL; ++ size_t outLen = 0; ++ jbyteArray outArr = NULL; ++ EVP_PKEY* pkey = NULL; ++ EVP_PKEY_CTX* ctx = NULL; ++ ENGINE* kaeEngine = NULL; ++ ++ // init Engine ++ kaeEngine = GetEngineByAlgorithmIndex(SM2_INDEX); ++ KAE_TRACE("SM2_Crypt: kaeEngine => %p", kaeEngine); ++ ++ if ((inbytes = (unsigned char*)malloc(inLen)) == NULL) { ++ KAE_ThrowOOMException(env, "malloc failed"); ++ goto cleanup; ++ } ++ memset(inbytes, 0, inLen); ++ ++ // get inArr bytes ++ (*env)->GetByteArrayRegion(env, inArr, 0, inLen, (jbyte*)inbytes); ++ if (inbytes == NULL) { ++ KAE_ThrowNullPointerException(env, "GetByteArrayRegion failed"); ++ goto cleanup; ++ } ++ ++ pkey = (EVP_PKEY*) keyAddress; ++ ++ // new ctx ++ if ((ctx = SSL_UTILS_EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_new", KAE_ThrowInvalidKeyException); ++ goto cleanup; ++ } ++ ++ // sm2 encrypt/decrypt init ++ if (isEncrypt) { ++ // init encrypt ctx ++ if (SSL_UTILS_EVP_PKEY_encrypt_init(ctx) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_encrypt_init", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // calculated outArr length ++ if (SSL_UTILS_EVP_PKEY_encrypt(ctx, NULL, &outLen, inbytes, inLen) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_encrypt failed. calculated outArr length", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ }else { ++ // init decrypt ctx ++ if (SSL_UTILS_EVP_PKEY_decrypt_init(ctx) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_decrypt_init", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // calculated outArr length ++ if (SSL_UTILS_EVP_PKEY_decrypt(ctx, NULL, &outLen, inbytes, inLen) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_decrypt failed. calculated outArr length", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ } ++ ++ if ((outbytes = (unsigned char*)malloc(outLen)) == NULL) { ++ KAE_ThrowOOMException(env, "malloc failed"); ++ goto cleanup; ++ } ++ memset(outbytes, 0, outLen); ++ ++ if (isEncrypt) { ++ // sm2 encrypt dofinal ++ if (SSL_UTILS_EVP_PKEY_encrypt(ctx, outbytes, &outLen, inbytes, inLen) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_encrypt failed. sm2 encrypt dofinal", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ }else { ++ // sm2 decrypt dofinal ++ if (SSL_UTILS_EVP_PKEY_decrypt(ctx, outbytes, &outLen, inbytes, inLen) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_decrypt failed. sm2 decrypt dofinal", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ } ++ KAE_TRACE("SM2_Crypt: finished"); ++ ++ if ((outArr = (*env)->NewByteArray(env, outLen)) == NULL) { ++ KAE_ThrowNullPointerException(env, "NewByteArray failed"); ++ goto cleanup; ++ } ++ (*env)->SetByteArrayRegion(env, outArr, 0, outLen, (jbyte*)outbytes); ++cleanup: ++ if (inbytes != NULL) { ++ memset(inbytes, 0, inLen); ++ free(inbytes); ++ } ++ if (outbytes != NULL) { ++ memset(outbytes, 0, outLen); ++ free(outbytes); ++ } ++ SSL_UTILS_EVP_PKEY_CTX_free(ctx); ++ return outArr; ++} ++ ++/* ++ * Class: KAESM2Cipher ++ * Method: nativeCreateSM2PublicKey ++ * Signature: ([B[B)J ++ */ ++JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAESM2Cipher_nativeCreateSM2PublicKey(JNIEnv *env, ++ jclass cls, jbyteArray xArr, jbyteArray yArr) { ++ BIGNUM* bn_x = NULL; ++ BIGNUM* bn_y = NULL; ++ EC_GROUP* group = NULL; ++ EC_POINT* pubkey_pt = NULL; ++ EC_KEY* eckey = NULL; ++ EVP_PKEY* pkey = NULL; ++ ++ // convert to big num ++ if ((bn_x = KAE_GetBigNumFromByteArray(env, xArr)) == NULL || ++ (bn_y = KAE_GetBigNumFromByteArray(env, yArr)) == NULL) { ++ goto cleanup; ++ } ++ ++ // new EC_GROUP by curve_name ++ if ((group = SSL_UTILS_EC_GROUP_new_by_curve_name(NID_sm2)) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EC_GROUP_new_by_curve_name", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // new EC_POINT ++ if((pubkey_pt = SSL_UTILS_EC_POINT_new(group)) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EC_POINT_new", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // set the x and y coordinates ++ if(SSL_UTILS_EC_POINT_set_affine_coordinates_GFp(group, pubkey_pt, bn_x, bn_y, NULL) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EC_POINT_set_affine_coordinates_GFp", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // new EC_KEY ++ if ((eckey = SSL_UTILS_EC_KEY_new_by_curve_name(NID_sm2)) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EC_KEY_new_by_curve_name", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ // set ec_key by publickey_point ++ if (SSL_UTILS_EC_KEY_set_public_key(eckey ,pubkey_pt) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EC_KEY_set_public_key", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // new EVP_PKEY ++ if ((pkey = SSL_UTILS_EVP_PKEY_new()) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // set the pkey by the ec_key ++ // Changed from macro, "EVP_PKEY_assign_EC_KEY(pkey,eckey)" is "EVP_PKEY_assign((pkey),EVP_PKEY_EC, (char *)(eckey))" in openssl 1 and 3 ++ if (SSL_UTILS_EVP_PKEY_assign((pkey),EVP_PKEY_EC, (char *)(eckey)) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_assign_EC_KEY", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // set the alias type of the key ++ // TODO EVP_PKEY_set_alias_type is removed since openssl 3 ++ if (SSL_UTILS_EVP_PKEY_set_alias_type(env, pkey, EVP_PKEY_SM2) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_set_alias_type", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ FreeSM2KeyParam(bn_x, bn_y, NULL, group, pubkey_pt); ++ KAE_TRACE("KAESM2Cipher_nativeCreateSM2PublicKey: finished"); ++ return (jlong)pkey; ++cleanup: ++ FreeSM2KeyParam(bn_x, bn_y, NULL, group, pubkey_pt); ++ if (eckey != NULL) { ++ SSL_UTILS_EC_KEY_free(eckey); ++ } ++ if (pkey != NULL) { ++ SSL_UTILS_EVP_PKEY_free(pkey); ++ } ++ return 0; ++} ++ ++/* ++ * Class: KAESM2Cipher ++ * Method: nativeCreateSM2PrivateKey ++ * Signature: ([B[B)J ++ */ ++JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAESM2Cipher_nativeCreateSM2PrivateKey(JNIEnv *env, ++ jclass cls, jbyteArray keyArr, jboolean sign) { ++ BIGNUM* bn_key = NULL; ++ EC_KEY* eckey = NULL; ++ EVP_PKEY* pkey = NULL; ++ EC_GROUP* group = NULL; ++ EC_POINT* pt = NULL; ++ ++ // convert to big num ++ if ((bn_key = KAE_GetBigNumFromByteArray(env, keyArr)) == NULL) { ++ goto cleanup; ++ } ++ ++ // new EC_KEY ++ if ((eckey = SSL_UTILS_EC_KEY_new_by_curve_name(NID_sm2)) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EC_KEY_new_by_curve_name", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // set the ec_key by bn_key ++ if ((SSL_UTILS_EC_KEY_set_private_key(eckey ,bn_key)) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EC_KEY_set_private_key", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // new group by curve_name ++ if ((group = SSL_UTILS_EC_GROUP_new_by_curve_name(NID_sm2)) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EC_GROUP_new_by_curve_name", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ if (sign) { ++ // new EC_POINT ++ if ((pt = SSL_UTILS_EC_POINT_new(group)) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EC_POINT_new", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ // calculation of EC_POINT by EC_POINT_mul functions ++ if (SSL_UTILS_EC_POINT_mul(group, pt, bn_key, NULL, NULL, NULL) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EC_POINT_mul", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ // set ec_key by ec_point ++ if (SSL_UTILS_EC_KEY_set_public_key(eckey ,pt) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EC_KEY_set_public_key", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ } ++ ++ // new EVP_PKEY ++ if ((pkey = SSL_UTILS_EVP_PKEY_new()) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // set the pkey by the ec_key ++ // Changed from macro, "EVP_PKEY_assign_EC_KEY(pkey,eckey)" is "EVP_PKEY_assign((pkey),EVP_PKEY_EC, (char *)(eckey))" in openssl 1 and 3 ++ if (SSL_UTILS_EVP_PKEY_assign_EC_KEY(pkey , eckey) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_assign_EC_KEY", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // set the alias type of the key ++ // TODO EVP_PKEY_set_alias_type is removed since openssl 3 ++ if (SSL_UTILS_EVP_PKEY_set_alias_type(env, pkey, EVP_PKEY_SM2) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_set_alias_type", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ FreeSM2KeyParam(NULL, NULL, bn_key, group, pt); ++ KAE_TRACE("KAESM2Cipher_nativeCreateSM2PrivateKey: finished"); ++ return (jlong)pkey; ++cleanup: ++ FreeSM2KeyParam(NULL, NULL, bn_key, group, pt); ++ if (eckey != NULL) { ++ SSL_UTILS_EC_KEY_free(eckey); ++ } ++ if (pkey != NULL) { ++ SSL_UTILS_EVP_PKEY_free(pkey); ++ } ++ return 0; ++} ++ ++/* ++ * Class: KAESM2Cipher ++ * Method: nativeFreeKey ++ * Signature: (J)V ++ */ ++JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAESM2Cipher_nativeFreeKey(JNIEnv *env, ++ jclass cls, jlong keyAddress) { ++ KAE_TRACE("KAESM2Cipher_nativeFreeKey(keyAddress = %p)", keyAddress); ++ ++ if(keyAddress == 0){ ++ KAE_ThrowInvalidKeyException(env, "nativeFreeKey failed. keyAddress is Invalid"); ++ return; ++ } ++ EVP_PKEY* pkey = (EVP_PKEY*) keyAddress; ++ if (pkey != NULL) { ++ SSL_UTILS_EVP_PKEY_free(pkey); ++ } ++ ++ KAE_TRACE("KAESM2Cipher_nativeFreeKey: finished"); ++} ++ ++/* ++ * Class: KAESM2Cipher ++ * Method: nativeSM2Encrypt ++ * Signature: (J[BI)[B ++ */ ++JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAESM2Cipher_nativeSM2Encrypt(JNIEnv *env, ++ jclass cls, jlong keyAddress, jbyteArray inArr, jint inLen) { ++ KAE_TRACE("KAESM2Cipher_nativeSM2Encrypt(keyAddress = %p, inArr = %p, inLen = %d)", keyAddress, inArr, inLen); ++ return SM2_Crypt(env, keyAddress, inArr, inLen, true); ++} ++ ++/* ++ * Class: KAESM2Cipher ++ * Method: nativeSM2Decrypt ++ * Signature: (J[BI)[B ++ */ ++JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAESM2Cipher_nativeSM2Decrypt(JNIEnv *env, ++ jclass cls, jlong keyAddress, jbyteArray inArr, jint inLen) { ++ KAE_TRACE("KAESM2Cipher_nativeSM2Decrypt(keyAddress = %p, inArr = %p, inLen = %d)", keyAddress, inArr, inLen); ++ return SM2_Crypt(env, keyAddress, inArr, inLen, false); ++} +\ No newline at end of file +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c +index 23b178978..c967c68ef 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c +@@ -27,6 +27,7 @@ + #include "kae_exception.h" + #include "kae_log.h" + #include "kae_util.h" ++#include "ssl_utils.h" + #include "org_openeuler_security_openssl_KAEDigest.h" + + #define DIGEST_STACK_SIZE 1024 +@@ -53,7 +54,7 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls + const char* algo_utf = (*env)->GetStringUTFChars(env, algorithmName, 0); + kaeEngine = GetDigestEngineByAlgorithmName(algo_utf); + KAE_TRACE("KAEDigest_nativeInit: kaeEngine => %p", kaeEngine); +- EVP_MD* md = (EVP_MD*) EVP_get_digestbyname(algo_utf); ++ EVP_MD* md = (EVP_MD*) SSL_UTILS_EVP_get_digestbyname(algo_utf); + (*env)->ReleaseStringUTFChars(env, algorithmName, algo_utf); + if (md == NULL) { + KAE_TRACE("%s not supported", algo_utf); +@@ -61,7 +62,8 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls + } + KAE_TRACE("KAEDigest_nativeInit: create md => %p", md); + +- ctx = EVP_MD_CTX_create(); ++ ctx = SSL_UTILS_EVP_MD_CTX_new(); ++ + if (ctx == NULL) { + KAE_ThrowOOMException(env, "create EVP_MD_CTX fail"); + return 0; +@@ -69,7 +71,7 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls + KAE_TRACE("KAEDigest_nativeInit: create ctx => %p", ctx); + + // EVP_DigestInit_ex +- int result_code = EVP_DigestInit_ex(ctx, md, kaeEngine); ++ int result_code = SSL_UTILS_EVP_DigestInit_ex(ctx, md, kaeEngine); + if (result_code == 0) { + KAE_ThrowFromOpenssl(env, "EVP_DigestInit_ex failed", KAE_ThrowRuntimeException); + goto cleanup; +@@ -80,7 +82,8 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls + return (jlong) ctx; + + cleanup: +- EVP_MD_CTX_destroy(ctx); ++ // changed from macro, "# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))" in openssl 1 and 3 ++ SSL_UTILS_EVP_MD_CTX_destroy(ctx); + return 0; + } + +@@ -105,7 +108,7 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeUpdate(JNIEnv *env, jclass c + if (in_size <= DIGEST_STACK_SIZE) { // allocation on the stack + jbyte buffer[DIGEST_STACK_SIZE]; + (*env)->GetByteArrayRegion(env, input, offset, inLen, buffer); +- result_code = EVP_DigestUpdate(ctx, buffer, inLen); ++ result_code = SSL_UTILS_EVP_DigestUpdate(ctx, buffer, inLen); + } else { // data chunk + jint remaining = in_size; + jint buf_size = (remaining >= DIGEST_CHUNK_SIZE) ? DIGEST_CHUNK_SIZE : remaining; +@@ -117,7 +120,7 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeUpdate(JNIEnv *env, jclass c + while (remaining > 0) { + jint chunk_size = (remaining >= buf_size) ? buf_size : remaining; + (*env)->GetByteArrayRegion(env, input, in_offset, chunk_size, buffer); +- result_code = EVP_DigestUpdate(ctx, buffer, chunk_size); ++ result_code = SSL_UTILS_EVP_DigestUpdate(ctx, buffer, chunk_size); + if (!result_code) { + break; + } +@@ -163,7 +166,7 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeDigest(JNIEnv *env, jclass c + } + + // EVP_DigestFinal_ex +- int result_code = EVP_DigestFinal_ex(ctx, md, &bytesWritten); ++ int result_code = SSL_UTILS_EVP_DigestFinal_ex(ctx, md, &bytesWritten); + if (result_code == 0) { + KAE_ThrowFromOpenssl(env, "EVP_DigestFinal_ex failed", KAE_ThrowRuntimeException); + goto cleanup; +@@ -193,14 +196,15 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeClone(JNIEnv *env, jclass cl + return 0; + } + +- EVP_MD_CTX* ctxCopy = EVP_MD_CTX_create(); ++ // change from macro, "# define EVP_MD_CTX_create() EVP_MD_CTX_new()" in openssl 1 and 3 ++ EVP_MD_CTX* ctxCopy = SSL_UTILS_EVP_MD_CTX_create(); + if (ctxCopy == NULL) { + KAE_ThrowOOMException(env, "create EVP_MD_CTX fail"); + return 0; + } + KAE_TRACE("KAEDigest_nativeClone: create ctxCopy => %p", ctxCopy); + +- int result_code = EVP_MD_CTX_copy_ex(ctxCopy, ctx); ++ int result_code = SSL_UTILS_EVP_MD_CTX_copy_ex(ctxCopy, ctx); + if (result_code == 0) { + KAE_ThrowFromOpenssl(env, "EVP_MD_CTX_copy_ex failed", KAE_ThrowRuntimeException); + goto cleanup; +@@ -210,7 +214,8 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeClone(JNIEnv *env, jclass cl + return (jlong) ctxCopy; + + cleanup: +- EVP_MD_CTX_destroy(ctxCopy); ++ // changed from macro, "# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))" in openssl 1 and 3 ++ SSL_UTILS_EVP_MD_CTX_destroy(ctxCopy); + return 0; + } + +@@ -225,7 +230,8 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeFree(JNIEnv *env, jclass cls + EVP_MD_CTX* ctx = (EVP_MD_CTX*) ctxAddress; + KAE_TRACE("KAEDigest_nativeFree(ctx = %p)", ctx); + if (ctx != NULL) { +- EVP_MD_CTX_destroy(ctx); ++ // changed from macro, "# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))" in openssl 1 and 3 ++ SSL_UTILS_EVP_MD_CTX_destroy(ctx); + } + + KAE_TRACE("KAEDigest_nativeFree: finished"); +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.c +index a43da7b30..1e34edcf0 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.c +@@ -25,6 +25,7 @@ + #include + #include "kae_log.h" + #include "kae_exception.h" ++#include "ssl_utils.h" + + void KAE_ThrowByName(JNIEnv* env, const char* name, const char* msg) { + jclass cls = (*env)->FindClass(env, name); +@@ -56,7 +57,7 @@ void KAE_ThrowEvpException(JNIEnv* env, int reason, const char* msg, void (* def + break; + case EVP_R_BAD_DECRYPT: + case EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH: +- case EVP_F_EVP_PKEY_DECRYPT: ++ case SSL_EVP_F_EVP_PKEY_DECRYPT: + case EVP_R_PUBLIC_KEY_NOT_RSA: + case EVP_R_CTRL_NOT_IMPLEMENTED: + KAE_ThrowByName(env, "javax/crypto/BadPaddingException", msg); +@@ -71,6 +72,10 @@ void KAE_ThrowRuntimeException(JNIEnv* env, const char* msg) { + KAE_ThrowByName(env, "java/lang/RuntimeException", msg); + } + ++void KAE_ThrowExceptionInInitializerError(JNIEnv* env, const char* msg) { ++ KAE_ThrowByName(env, "java/lang/ExceptionInInitializerError", msg); ++} ++ + void KAE_ThrowBadPaddingException(JNIEnv* env, const char* msg) { + KAE_ThrowByName(env, "javax/crypto/BadPaddingException", msg); + } +@@ -91,7 +96,7 @@ void KAE_ThrowFromOpenssl(JNIEnv* env, const char* msg, void (* defaultException + unsigned long err; + static const int ESTRING_SIZE = 256; + +- err = ERR_get_error_line_data(&file, &line, &data, &flags); ++ err = SSL_UTILS_ERR_get_error_line_data(&file, &line, &data, &flags); + if (err == 0) { + defaultException(env, msg); + return; +@@ -99,9 +104,11 @@ void KAE_ThrowFromOpenssl(JNIEnv* env, const char* msg, void (* defaultException + + if (!(*env)->ExceptionCheck(env)) { + char estring[ESTRING_SIZE]; +- ERR_error_string_n(err, estring, ESTRING_SIZE); +- int lib = ERR_GET_LIB(err); +- int reason = ERR_GET_REASON(err); ++ SSL_UTILS_ERR_error_string_n(err, estring, ESTRING_SIZE); ++ // Those functions below are macros ++ int lib = SSL_UTILS_ERR_GET_LIB(err); ++ int func = SSL_UTILS_ERR_GET_FUNC(err); ++ int reason = SSL_UTILS_ERR_GET_REASON(err); + KAE_TRACE("OpenSSL error in %s: err=%lx, lib=%x, reason=%x, file=%s, line=%d, estring=%s, data=%s", msg, err, + lib, reason, file, line, estring, (flags & ERR_TXT_STRING) ? data : "(no data)"); + +@@ -112,7 +119,7 @@ void KAE_ThrowFromOpenssl(JNIEnv* env, const char* msg, void (* defaultException + } + } + +- ERR_clear_error(); ++ SSL_UTILS_ERR_clear_error(); + } + + void KAE_ThrowAEADBadTagException(JNIEnv *env, const char *msg) { +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.h b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.h +index 532953995..662550485 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.h ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_exception.h +@@ -24,6 +24,11 @@ + #ifndef KAE_EXCEPTION_H + #define KAE_EXCEPTION_H + ++// openssl3.0 EVP_F_EVP_PKEY_DECRYPT has been removed ++#ifndef SSL_EVP_F_EVP_PKEY_DECRYPT ++#define SSL_EVP_F_EVP_PKEY_DECRYPT 104 ++#endif ++ + #include + + /* Throw a Java exception by name */ +@@ -41,6 +46,8 @@ void KAE_ThrowEvpException(JNIEnv* env, int reason, const char* msg, void (* def + + void KAE_ThrowRuntimeException(JNIEnv* env, const char* msg); + ++void KAE_ThrowExceptionInInitializerError(JNIEnv* env, const char* msg); ++ + void KAE_ThrowBadPaddingException(JNIEnv* env, const char* msg); + + /* Throw InvalidKeyException */ +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c +index 1efacbb5b..bdc19b843 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c +@@ -27,6 +27,7 @@ + #include "kae_exception.h" + #include "kae_log.h" + #include "kae_util.h" ++#include "ssl_utils.h" + + static const EVP_MD* EVPGetDigestByName(JNIEnv* env, const char* algo) + { +@@ -38,17 +39,17 @@ static const EVP_MD* EVPGetDigestByName(JNIEnv* env, const char* algo) + static const EVP_MD* sha512 = NULL; + + if (strcasecmp(algo, "md5") == 0) { +- return md5 == NULL ? md5 = EVP_get_digestbyname(algo) : md5; ++ return md5 == NULL ? md5 = SSL_UTILS_EVP_get_digestbyname(algo) : md5; + } else if (strcasecmp(algo, "sha1") == 0) { +- return sha1 == NULL ? sha1 = EVP_get_digestbyname(algo) : sha1; ++ return sha1 == NULL ? sha1 = SSL_UTILS_EVP_get_digestbyname(algo) : sha1; + } else if (strcasecmp(algo, "sha224") == 0) { +- return sha224 == NULL ? sha224 = EVP_get_digestbyname(algo) : sha224; ++ return sha224 == NULL ? sha224 = SSL_UTILS_EVP_get_digestbyname(algo) : sha224; + } else if (strcasecmp(algo, "sha256") == 0) { +- return sha256 == NULL ? sha256 = EVP_get_digestbyname(algo) : sha256; ++ return sha256 == NULL ? sha256 = SSL_UTILS_EVP_get_digestbyname(algo) : sha256; + } else if (strcasecmp(algo, "sha384") == 0) { +- return sha384 == NULL ? sha384 = EVP_get_digestbyname(algo) : sha384; ++ return sha384 == NULL ? sha384 = SSL_UTILS_EVP_get_digestbyname(algo) : sha384; + } else if (strcasecmp(algo, "sha512") == 0) { +- return sha512 == NULL ? sha512 = EVP_get_digestbyname(algo) : sha512; ++ return sha512 == NULL ? sha512 = SSL_UTILS_EVP_get_digestbyname(algo) : sha512; + } else { + KAE_ThrowRuntimeException(env, "EVPGetDigestByName error"); + return 0; +@@ -96,14 +97,14 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeInit + (*env)->GetByteArrayRegion(env, key, 0, key_len, key_buffer); + + // create a hmac context +- ctx = HMAC_CTX_new(); ++ ctx = SSL_UTILS_HMAC_CTX_new(); + if (ctx == NULL) { + KAE_ThrowRuntimeException(env, "Hmac_CTX_new invoked failed"); + goto cleanup; + } + + // init hmac context with sc_key and evp_md +- int result_code = HMAC_Init_ex(ctx, key_buffer, key_len, md, kaeEngine); ++ int result_code = SSL_UTILS_HMAC_Init_ex(ctx, key_buffer, key_len, md, kaeEngine); + if (result_code == 0) { + KAE_ThrowRuntimeException(env, "Hmac_Init_ex invoked failed"); + goto cleanup; +@@ -113,7 +114,7 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeInit + + cleanup: + free(key_buffer); +- HMAC_CTX_free(ctx); ++ SSL_UTILS_HMAC_CTX_free(ctx); + return 0; + } + +@@ -146,7 +147,7 @@ JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeUpdate + return; + } + (*env)->GetByteArrayRegion(env, input, in_offset, in_len, buffer); +- if (!HMAC_Update(ctx, (unsigned char*) buffer, in_len)) { ++ if (!SSL_UTILS_HMAC_Update(ctx, (unsigned char*) buffer, in_len)) { + KAE_ThrowRuntimeException(env, "Hmac_Update invoked failed"); + } + free(buffer); +@@ -179,7 +180,7 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeFinal + } + // do final + unsigned int bytesWritten = 0; +- int result_code = HMAC_Final(ctx, (unsigned char*) temp_result, &bytesWritten); ++ int result_code = SSL_UTILS_HMAC_Final(ctx, (unsigned char*) temp_result, &bytesWritten); + if (result_code == 0) { + KAE_ThrowRuntimeException(env, "Hmac_Final invoked failed"); + goto cleanup; +@@ -203,6 +204,6 @@ JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeFree + (JNIEnv* env, jclass cls, jlong hmac_ctx) { + HMAC_CTX* ctx = (HMAC_CTX*) hmac_ctx; + if (ctx != NULL) { +- HMAC_CTX_free(ctx); ++ SSL_UTILS_HMAC_CTX_free(ctx); + } + } +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c +index 74af15a51..3d1eb6b58 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c +@@ -30,6 +30,7 @@ + #include "kae_util.h" + #include "kae_exception.h" + #include "kae_log.h" ++#include "ssl_utils.h" + #include "org_openeuler_security_openssl_KAEDHKeyAgreement.h" + + +@@ -63,7 +64,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyAgreeme + } + memset(secret, 0, pSizeInByte); + +- if ((dh = DH_new_method(kaeEngine)) == NULL) { ++ if ((dh = SSL_UTILS_DH_new_method(kaeEngine)) == NULL) { + KAE_ThrowOOMException(env, "Allocate DH failed in nativeComputeKey."); + goto cleanup; + } +@@ -88,29 +89,29 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyAgreeme + goto cleanup; + } + +- if ((computeKeyRetBn = BN_new()) == NULL) { ++ if ((computeKeyRetBn = SSL_UTILS_BN_new()) == NULL) { + KAE_ThrowOOMException(env, "Allocate BN failed."); + goto cleanup; + } + +- if (!DH_set0_pqg(dh, BN_dup(p_bn), NULL, BN_dup(g_bn))) { ++ if (!SSL_UTILS_DH_set0_pqg(dh, SSL_UTILS_BN_dup(p_bn), NULL, SSL_UTILS_BN_dup(g_bn))) { + KAE_ThrowRuntimeException(env, "DH_set0_pqg failed."); + goto cleanup; + } + +- if (!DH_set0_key(dh, NULL, BN_dup(x_bn))) { ++ if (!SSL_UTILS_DH_set0_key(dh, NULL, SSL_UTILS_BN_dup(x_bn))) { + KAE_ThrowRuntimeException(env, "DH_set0_key failed."); + goto cleanup; + } + +- computekeyLength = DH_compute_key(secret, y_bn, dh); ++ computekeyLength = SSL_UTILS_DH_compute_key(secret, y_bn, dh); + + if (computekeyLength <= 0 ) { + KAE_ThrowRuntimeException(env, "DH_compute_key failed."); + goto cleanup; + } + +- BN_bin2bn(secret, computekeyLength, computeKeyRetBn); ++ SSL_UTILS_BN_bin2bn(secret, computekeyLength, computeKeyRetBn); + + retByteArray = KAE_GetByteArrayFromBigNum(env, computeKeyRetBn); + if (retByteArray == NULL) { +@@ -121,7 +122,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyAgreeme + + cleanup: + if (dh != NULL) +- DH_free(dh); ++ SSL_UTILS_DH_free(dh); + if (y_bn != NULL) + KAE_ReleaseBigNumFromByteArray(y_bn); + if (x_bn != NULL) +@@ -135,7 +136,7 @@ cleanup: + free(secret); + } + if (computeKeyRetBn != NULL) +- BN_free(computeKeyRetBn); ++ SSL_UTILS_BN_free(computeKeyRetBn); + + return retByteArray; +-} ++} +\ No newline at end of file +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c +index 877a915f0..2e7831e3f 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_ecdh.c +@@ -27,6 +27,7 @@ + #include "kae_log.h" + #include "kae_exception.h" + #include "kae_util.h" ++#include "ssl_utils.h" + #include "org_openeuler_security_openssl_KAEECDHKeyAgreement.h" + + static void FreeGenerateSecretParam(BIGNUM* s, BIGNUM* wX, BIGNUM* wY, +@@ -36,13 +37,13 @@ static void FreeGenerateSecretParam(BIGNUM* s, BIGNUM* wX, BIGNUM* wY, + KAE_ReleaseBigNumFromByteArray(wX); + KAE_ReleaseBigNumFromByteArray(wY); + if (pub != NULL) { +- EC_POINT_free(pub); ++ SSL_UTILS_EC_POINT_free(pub); + } + if (eckey != NULL) { +- EC_KEY_free(eckey); ++ SSL_UTILS_EC_KEY_free(eckey); + } + if (group != NULL) { +- EC_GROUP_free(group); ++ SSL_UTILS_EC_GROUP_free(group); + } + if (shareKey != NULL) { + memset(shareKey, 0, shareKeyLen); +@@ -67,9 +68,9 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEECDHKeyAgree + jbyteArray javaBytes = NULL; + unsigned char* shareKey = NULL; + const char *curve = (*env)->GetStringUTFChars(env, curveName, 0); +- int nid = OBJ_sn2nid(curve); ++ int nid = SSL_UTILS_OBJ_sn2nid(curve); + (*env)->ReleaseStringUTFChars(env, curveName, curve); +- if ((nid == NID_undef) || (group = EC_GROUP_new_by_curve_name(nid)) == NULL) { ++ if ((nid == NID_undef) || (group = SSL_UTILS_EC_GROUP_new_by_curve_name(nid)) == NULL) { + goto cleanup; + } + if ((s = KAE_GetBigNumFromByteArray(env, sArr)) == NULL || (wX = KAE_GetBigNumFromByteArray(env, wXArr)) == NULL +@@ -77,21 +78,21 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEECDHKeyAgree + KAE_ThrowOOMException(env, "failed to allocate BN_new"); + goto cleanup; + } +- if ((eckey = EC_KEY_new()) == NULL || !EC_KEY_set_group(eckey, group)) { ++ if ((eckey = SSL_UTILS_EC_KEY_new()) == NULL || !SSL_UTILS_EC_KEY_set_group(eckey, group)) { + goto cleanup; + } +- if ((pub = EC_POINT_new(group)) == NULL) { ++ if ((pub = SSL_UTILS_EC_POINT_new(group)) == NULL) { + goto cleanup; + } +- if (!EC_POINT_set_affine_coordinates_GFp(group, pub, wX, wY, NULL)) { ++ if (!SSL_UTILS_EC_POINT_set_affine_coordinates_GFp(group, pub, wX, wY, NULL)) { + goto cleanup; + } +- if (!EC_KEY_set_public_key(eckey, pub) || !EC_KEY_set_private_key(eckey, s)) { ++ if (!SSL_UTILS_EC_KEY_set_public_key(eckey, pub) || !SSL_UTILS_EC_KEY_set_private_key(eckey, s)) { + goto cleanup; + } + + // Get the length of secret key, in bytes. +- int expectSecretLen = (EC_GROUP_get_degree(group) + 7) / 8; ++ int expectSecretLen = (SSL_UTILS_EC_GROUP_get_degree(group) + 7) / 8; + if ((shareKey = malloc(expectSecretLen)) == NULL) { + KAE_ThrowOOMException(env, "malloc error"); + goto cleanup; +@@ -99,7 +100,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEECDHKeyAgree + memset(shareKey, 0, expectSecretLen); + + // Perform ecdh keyagreement. +- if (ECDH_compute_key(shareKey, expectSecretLen, pub, eckey, NULL) != expectSecretLen) { ++ if (SSL_UTILS_ECDH_compute_key(shareKey, expectSecretLen, pub, eckey, NULL) != expectSecretLen) { + goto cleanup; + } + +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c +index d16b42b41..ae4eadb18 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c +@@ -28,6 +28,7 @@ + #include + #include "kae_util.h" + #include "kae_log.h" ++#include "ssl_utils.h" + #include "org_openeuler_security_openssl_KAEDHKeyPairGenerator.h" + #include "kae_exception.h" + +@@ -55,7 +56,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyPairG + + KAE_TRACE("Java_org_openeuler_security_openssl_KAEDHKeyPairGenerator_nativeGenerateKeyPair start !"); + +- if ((dh = DH_new_method(kaeEngine)) == NULL) { ++ if ((dh = SSL_UTILS_DH_new_method(kaeEngine)) == NULL) { + KAE_ThrowOOMException(env, "Allocate DH failed in nativeGenerateKeyPair!"); + goto cleanup; + } +@@ -70,15 +71,15 @@ JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyPairG + goto cleanup; + } + +- if (!DH_set0_pqg(dh, BN_dup(p_bn), NULL, BN_dup(g_bn))) { ++ if (!SSL_UTILS_DH_set0_pqg(dh, SSL_UTILS_BN_dup(p_bn), NULL, SSL_UTILS_BN_dup(g_bn))) { + KAE_ThrowRuntimeException(env, "DH_set0_pqg failed in nativeGenerateKeyPair."); + goto cleanup; + } + + // Return value is fixed to 1, nothing to check. +- DH_set_length(dh, lSize); ++ SSL_UTILS_DH_set_length(dh, lSize); + +- if (!DH_generate_key(dh)) { ++ if (!SSL_UTILS_DH_generate_key(dh)) { + KAE_ThrowInvalidAlgorithmParameterException(env, "DH generate key failed in nativeGenerateKeyPair."); + goto cleanup; + } +@@ -94,8 +95,8 @@ JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyPairG + } + + // Return the ptr of private key in dh. +- pri_key_bn = DH_get0_priv_key(dh); +- pub_key_bn = DH_get0_pub_key(dh); ++ pri_key_bn = SSL_UTILS_DH_get0_priv_key(dh); ++ pub_key_bn = SSL_UTILS_DH_get0_pub_key(dh); + + pub_key = KAE_GetByteArrayFromBigNum(env, pub_key_bn); + if (pub_key == NULL) { +@@ -116,7 +117,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyPairG + + cleanup: + if (dh != NULL) +- DH_free(dh); ++ SSL_UTILS_DH_free(dh); + if (p_bn != NULL) + KAE_ReleaseBigNumFromByteArray(p_bn); + if (g_bn != NULL) +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_ec.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_ec.c +index fbd168410..00ee84dbb 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_ec.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_ec.c +@@ -27,6 +27,7 @@ + #include "kae_util.h" + #include "kae_exception.h" + #include "kae_log.h" ++#include "ssl_utils.h" + #include "org_openeuler_security_openssl_KAEECKeyPairGenerator.h" + + #define KAE_EC_PARAM_NUM_SIZE 7 +@@ -54,13 +55,13 @@ static void FreeECDHCurveParam(JNIEnv* env, BIGNUM* p, BIGNUM* a, BIGNUM* b, jby + jbyteArray paramA, jbyteArray paramB) + { + if (p != NULL) { +- BN_free(p); ++ SSL_UTILS_BN_free(p); + } + if (a != NULL) { +- BN_free(a); ++ SSL_UTILS_BN_free(a); + } + if (b != NULL) { +- BN_free(b); ++ SSL_UTILS_BN_free(b); + } + if (paramP != NULL) { + (*env)->DeleteLocalRef(env, paramP); +@@ -82,11 +83,11 @@ static bool SetECDHCurve(JNIEnv* env, EC_GROUP* group, jobjectArray params) + jbyteArray paramP = NULL; + jbyteArray paramA = NULL; + jbyteArray paramB = NULL; +- if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || (b = BN_new()) == NULL) { ++ if ((p = SSL_UTILS_BN_new()) == NULL || (a = SSL_UTILS_BN_new()) == NULL || (b = SSL_UTILS_BN_new()) == NULL) { + KAE_ThrowOOMException(env, "failed to allocate BN_new"); + goto cleanup; + } +- if (!EC_GROUP_get_curve_GFp(group, p, a, b, NULL)) { ++ if (!SSL_UTILS_EC_GROUP_get_curve_GFp(group, p, a, b, NULL)) { + goto cleanup; + } + +@@ -123,15 +124,15 @@ static bool SetECDHPoint(JNIEnv* env, EC_GROUP* group, jobjectArray params) + const EC_POINT* generator = NULL; + jbyteArray paramX = NULL; + jbyteArray paramY = NULL; +- if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) { ++ if ((x = SSL_UTILS_BN_new()) == NULL || (y = SSL_UTILS_BN_new()) == NULL) { + KAE_ThrowOOMException(env, "failed to allocate BN_new"); + goto cleanup; + } +- if ((generator = EC_GROUP_get0_generator(group)) == NULL) { ++ if ((generator = SSL_UTILS_EC_GROUP_get0_generator(group)) == NULL) { + KAE_ThrowOOMException(env, "failed to allocate ec generator"); + goto cleanup; + } +- if (!EC_POINT_get_affine_coordinates_GFp(group, generator, x, y, NULL)) { ++ if (!SSL_UTILS_EC_POINT_get_affine_coordinates_GFp(group, generator, x, y, NULL)) { + KAE_ThrowFromOpenssl(env, "EC_POINT_set_affine_coordinates_GFp", KAE_ThrowRuntimeException); + goto cleanup; + } +@@ -147,18 +148,18 @@ static bool SetECDHPoint(JNIEnv* env, EC_GROUP* group, jobjectArray params) + goto cleanup; + } + (*env)->SetObjectArrayElement(env, params, ecdhY, paramY); +- BN_free(x); +- BN_free(y); ++ SSL_UTILS_BN_free(x); ++ SSL_UTILS_BN_free(y); + (*env)->DeleteLocalRef(env, paramX); + (*env)->DeleteLocalRef(env, paramY); + return true; + + cleanup: + if (x != NULL) { +- BN_free(x); ++ SSL_UTILS_BN_free(x); + } + if (y != NULL) { +- BN_free(y); ++ SSL_UTILS_BN_free(y); + } + if (paramX != NULL) { + (*env)->DeleteLocalRef(env, paramX); +@@ -176,10 +177,10 @@ static bool SetECDHOrderAndCofactor(JNIEnv* env, EC_GROUP* group, jobjectArray p + BIGNUM* cofactor = NULL; + jbyteArray paramOrder = NULL; + jbyteArray paramCofactor = NULL; +- if ((order = BN_new()) == NULL || (cofactor = BN_new()) == NULL) { ++ if ((order = SSL_UTILS_BN_new()) == NULL || (cofactor = SSL_UTILS_BN_new()) == NULL) { + goto cleanup; + } +- if (!EC_GROUP_get_order(group, order, NULL)) { ++ if (!SSL_UTILS_EC_GROUP_get_order(group, order, NULL)) { + goto cleanup; + } + +@@ -188,7 +189,7 @@ static bool SetECDHOrderAndCofactor(JNIEnv* env, EC_GROUP* group, jobjectArray p + goto cleanup; + } + (*env)->SetObjectArrayElement(env, params, ecdhOrder, paramOrder); +- if (!EC_GROUP_get_cofactor(group, cofactor, NULL)) { ++ if (!SSL_UTILS_EC_GROUP_get_cofactor(group, cofactor, NULL)) { + goto cleanup; + } + +@@ -197,18 +198,18 @@ static bool SetECDHOrderAndCofactor(JNIEnv* env, EC_GROUP* group, jobjectArray p + goto cleanup; + } + (*env)->SetObjectArrayElement(env, params, ecdhCofactor, paramCofactor); +- BN_free(order); +- BN_free(cofactor); ++ SSL_UTILS_BN_free(order); ++ SSL_UTILS_BN_free(cofactor); + (*env)->DeleteLocalRef(env, paramOrder); + (*env)->DeleteLocalRef(env, paramCofactor); + return true; + + cleanup: + if (order != NULL) { +- BN_free(order); ++ SSL_UTILS_BN_free(order); + } + if (cofactor != NULL) { +- BN_free(cofactor); ++ SSL_UTILS_BN_free(cofactor); + } + if (paramOrder != NULL) { + (*env)->DeleteLocalRef(env, paramOrder); +@@ -223,10 +224,10 @@ static void FreeECDHKeyParam(JNIEnv* env, + BIGNUM* wX, BIGNUM* wY, jbyteArray keyWX, jbyteArray keyWY, jbyteArray keyS) + { + if (wX != NULL) { +- BN_free(wX); ++ SSL_UTILS_BN_free(wX); + } + if (wY != NULL) { +- BN_free(wY); ++ SSL_UTILS_BN_free(wY); + } + if (keyWX != NULL) { + (*env)->DeleteLocalRef(env, keyWX); +@@ -250,16 +251,16 @@ static bool SetECDHKey(JNIEnv* env, const EC_GROUP* group, jobjectArray params, + jbyteArray keyWX = NULL; + jbyteArray keyWY = NULL; + jbyteArray keyS = NULL; +- if ((wX = BN_new()) == NULL || (wY = BN_new()) == NULL) { ++ if ((wX = SSL_UTILS_BN_new()) == NULL || (wY = SSL_UTILS_BN_new()) == NULL) { + KAE_ThrowOOMException(env, "failed to allocate array"); + goto cleanup; + } + +- if ((pub = EC_KEY_get0_public_key(eckey)) == NULL || +- !EC_POINT_get_affine_coordinates_GFp(group, pub, wX, wY, NULL)) { ++ if ((pub = SSL_UTILS_EC_KEY_get0_public_key(eckey)) == NULL || ++ !SSL_UTILS_EC_POINT_get_affine_coordinates_GFp(group, pub, wX, wY, NULL)) { + goto cleanup; + } +- if ((s = EC_KEY_get0_private_key(eckey)) == NULL) { ++ if ((s = SSL_UTILS_EC_KEY_get0_private_key(eckey)) == NULL) { + goto cleanup; + } + +@@ -374,42 +375,42 @@ static EC_GROUP* GetGroupByParam(JNIEnv* env, jbyteArray pArr, jbyteArray aArr, + EC_POINT* generator = NULL; + if ((p = KAE_GetBigNumFromByteArray(env, pArr)) == NULL || (a = KAE_GetBigNumFromByteArray(env, aArr)) == NULL || + (b = KAE_GetBigNumFromByteArray(env, bArr)) == NULL || (x = KAE_GetBigNumFromByteArray(env, xArr)) == NULL || +- (y = KAE_GetBigNumFromByteArray(env, yArr)) == NULL || (cofactor = BN_new()) == NULL || +- (order = KAE_GetBigNumFromByteArray(env, orderArr)) == NULL || !BN_set_word(cofactor, cofactorInt)) { ++ (y = KAE_GetBigNumFromByteArray(env, yArr)) == NULL || (cofactor = SSL_UTILS_BN_new()) == NULL || ++ (order = KAE_GetBigNumFromByteArray(env, orderArr)) == NULL || !SSL_UTILS_BN_set_word(cofactor, cofactorInt)) { + goto cleanup; + } + + // Create the curve. +- if ((ctx = BN_CTX_new()) == NULL || (group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { ++ if ((ctx = SSL_UTILS_BN_CTX_new()) == NULL || (group = SSL_UTILS_EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { + goto cleanup; + } + + // Create the generator and set x, y. +- if ((generator = EC_POINT_new(group)) == NULL || +- !EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) { ++ if ((generator = SSL_UTILS_EC_POINT_new(group)) == NULL || ++ !SSL_UTILS_EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) { + goto cleanup; + } + + // Set the generator, order and cofactor. +- if (!EC_GROUP_set_generator(group, generator, order, cofactor)) { ++ if (!SSL_UTILS_EC_GROUP_set_generator(group, generator, order, cofactor)) { + goto cleanup; + } + + FreeECDHParam(p, a, b, x, y, order, cofactor); +- EC_POINT_free(generator); +- BN_CTX_free(ctx); ++ SSL_UTILS_EC_POINT_free(generator); ++ SSL_UTILS_BN_CTX_free(ctx); + return group; + + cleanup: + FreeECDHParam(p, a, b, x, y, order, cofactor); + if (group != NULL) { +- EC_GROUP_free(group); ++ SSL_UTILS_EC_GROUP_free(group); + } + if (generator != NULL) { +- EC_POINT_free(generator); ++ SSL_UTILS_EC_POINT_free(generator); + } + if (ctx != NULL) { +- BN_CTX_free(ctx); ++ SSL_UTILS_BN_CTX_free(ctx); + } + return NULL; + } +@@ -428,26 +429,26 @@ JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEECKeyPairG + + const char *curve = (*env)->GetStringUTFChars(env, curveName, 0); + KAE_TRACE("KAEECKeyPairGenerator_nativeGenerateParam(curveName = %s)", curve); +- int nid = OBJ_sn2nid(curve); ++ int nid = SSL_UTILS_OBJ_sn2nid(curve); + (*env)->ReleaseStringUTFChars(env, curveName, curve); + if (nid == NID_undef) { + goto cleanup; + } + // Construct a builtin curve. +- if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { ++ if ((group = SSL_UTILS_EC_GROUP_new_by_curve_name(nid)) == NULL) { + goto cleanup; + } + ecdhParam = NewECDHParam(env, group); + + if (group != NULL) { +- EC_GROUP_free(group); ++ SSL_UTILS_EC_GROUP_free(group); + } + KAE_TRACE("KAEECKeyPairGenerator_nativeGenerateParam success, ecdhParam = %p", ecdhParam); + return ecdhParam; + + cleanup: + if (group != NULL) { +- EC_GROUP_free(group); ++ SSL_UTILS_EC_GROUP_free(group); + } + if (ecdhParam != NULL) { + (*env)->DeleteLocalRef(env, ecdhParam); +@@ -471,32 +472,32 @@ JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEECKeyPairG + if ((group = GetGroupByParam(env, pArr, aArr, bArr, xArr, yArr, orderArr, cofactorInt)) == NULL) { + goto cleanup; + } +- if ((eckey = EC_KEY_new()) == NULL) { ++ if ((eckey = SSL_UTILS_EC_KEY_new()) == NULL) { + goto cleanup; + } +- if (!EC_KEY_set_group(eckey, group)) { ++ if (!SSL_UTILS_EC_KEY_set_group(eckey, group)) { + goto cleanup; + } + // Generates a new public and private key for the supplied eckey object. + // Refer to {@link https://www.openssl.org/docs/man1.1.0/man3/EC_KEY_generate_key.html} for details. +- if (!EC_KEY_generate_key(eckey)) { ++ if (!SSL_UTILS_EC_KEY_generate_key(eckey)) { + goto cleanup; + } + + ecdhKey = NewECDHKey(env, group, eckey); + +- EC_KEY_free(eckey); +- EC_GROUP_free(group); ++ SSL_UTILS_EC_KEY_free(eckey); ++ SSL_UTILS_EC_GROUP_free(group); + + KAE_TRACE("KAEECKeyPairGenerator_nativeGenerateKeyPair success, ecdhKey = %p", ecdhKey); + return ecdhKey; + + cleanup: + if (eckey != NULL) { +- EC_KEY_free(eckey); ++ SSL_UTILS_EC_KEY_free(eckey); + } + if (group != NULL) { +- EC_GROUP_free(group); ++ SSL_UTILS_EC_GROUP_free(group); + } + if (ecdhKey != NULL) { + (*env)->DeleteLocalRef(env, ecdhKey); +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c +index 9251b56c4..3919d4849 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c +@@ -27,6 +27,7 @@ + #include "kae_util.h" + #include "kae_exception.h" + #include "org_openeuler_security_openssl_KAERSAKeyPairGenerator.h" ++#include "ssl_utils.h" + #define KAE_RSA_PARAM_SIZE 8 + + // rsa param index +@@ -46,14 +47,14 @@ static const char* rsaParamNames[] = {"n", "e", "d", "p", "q", "dmp1", "dmq1", " + + // rsa get rsa param function list + static const BIGNUM* (* GetRSAParamFunctionList[])(const RSA*) = { +- RSA_get0_n, +- RSA_get0_e, +- RSA_get0_d, +- RSA_get0_p, +- RSA_get0_q, +- RSA_get0_dmp1, +- RSA_get0_dmq1, +- RSA_get0_iqmp ++ SSL_UTILS_RSA_get0_n, ++ SSL_UTILS_RSA_get0_e, ++ SSL_UTILS_RSA_get0_d, ++ SSL_UTILS_RSA_get0_p, ++ SSL_UTILS_RSA_get0_q, ++ SSL_UTILS_RSA_get0_dmp1, ++ SSL_UTILS_RSA_get0_dmq1, ++ SSL_UTILS_RSA_get0_iqmp + }; + + /* +@@ -67,7 +68,7 @@ static RSA* NewRSA(JNIEnv* env, jint keySize, jbyteArray publicExponent) { + KAE_TRACE("NewRSA: kaeEngine => %p", kaeEngine); + + // new rsa +- RSA* rsa = RSA_new_method(kaeEngine); ++ RSA* rsa = SSL_UTILS_RSA_new_method(kaeEngine); + if (rsa == NULL) { + KAE_ThrowFromOpenssl(env, "RSA_new_method", KAE_ThrowRuntimeException); + return NULL; +@@ -80,10 +81,10 @@ static RSA* NewRSA(JNIEnv* env, jint keySize, jbyteArray publicExponent) { + } + + // generate rsa key +- int result_code = RSA_generate_key_ex(rsa, keySize, exponent, NULL); ++ int result_code = SSL_UTILS_RSA_generate_key_ex(rsa, keySize, exponent, NULL); + KAE_ReleaseBigNumFromByteArray(exponent); + if (result_code <= 0) { +- RSA_free(rsa); ++ SSL_UTILS_RSA_free(rsa); + KAE_ThrowFromOpenssl(env, "RSA_generate_key_ex", KAE_ThrowRuntimeException); + return NULL; + } +@@ -95,7 +96,7 @@ static RSA* NewRSA(JNIEnv* env, jint keySize, jbyteArray publicExponent) { + */ + static void ReleaseRSA(RSA* rsa) { + if (rsa != NULL) { +- RSA_free(rsa); ++ SSL_UTILS_RSA_free(rsa); + } + } + +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c +index fca035b04..206c5ab09 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c +@@ -27,69 +27,50 @@ + #include + #include "kae_exception.h" + #include "kae_util.h" ++#include "kae_log.h" ++#include "ssl_utils.h" + #include "org_openeuler_security_openssl_KAEProvider.h" + +-#define KAE_OPENSSL_LIBRARY "libcrypto.so" +- + /* + * Class: Java_org_openeuler_security_openssl_KAEProvider + * Method: initOpenssl + * Signature: ()V + */ +-JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEProvider_initOpenssl +- (JNIEnv *env, jclass cls, jboolean useGlobalMode, jstring engineId, jbooleanArray algorithmKaeFlags) { +- SSL_load_error_strings(); +- ERR_load_BIO_strings(); +- OpenSSL_add_all_algorithms(); +- +- /* +- * If the same shared object is opened again with dlopen(), the same object handle is returned. +- * The dynamic linker maintains reference counts for object handles. +- * An object that was previously opened with RTLD_LOCAL can be promoted to RTLD_GLOBAL in a subsequent dlopen(). +- * +- * RTLD_GLOBAL +- * The symbols defined by this shared object will be made +- * available for symbol resolution of subsequently loaded +- * shared objects. +- * RTLD_LOCAL +- * This is the converse of RTLD_GLOBAL, and the default if +- * neither flag is specified. Symbols defined in this shared +- * object are not made available to resolve references in +- * subsequently loaded shared objects. +- * For more information see https://man7.org/linux/man-pages/man3/dlopen.3.html. +- */ +- if (useGlobalMode) { +- char msg[1024]; +- void *handle = NULL; +- // Promote the flags of the loaded libcrypto.so library from RTLD_LOCAL to RTLD_GLOBAL +- handle = dlopen(KAE_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL); +- if (handle == NULL) { +- snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", KAE_OPENSSL_LIBRARY, dlerror()); +- KAE_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg); +- return; +- } +- dlclose(handle); ++JNIEXPORT int JNICALL Java_org_openeuler_security_openssl_KAEProvider_initOpenssl(JNIEnv *env, jclass cls, ++ jint useOpensslVersion, jstring engineId, jbooleanArray algorithmKaeFlags) ++{ ++ // Load openssl functions by dlsym(), according to current libssl.so file version. ++ jboolean init_result = SSL_UTILS_func_ptr_init(env, useOpensslVersion); ++ if (!init_result) { ++ return -1; + } ++ // Change from macro, SSL_load_error_strings is a macro in openssl 1 and 3. ++ SSL_UTILS_SSL_load_error_strings(); ++ SSL_UTILS_ERR_load_BIO_strings(); ++ // Change from macro, OpenSSL_add_all_algorithms ia a macro, defined by OPENSSL_LOAD_CONF value. ++ SSL_UTILS_OpenSSL_add_all_algorithms(); + + // check if KaeEngine holder is already set + ENGINE* e = GetKaeEngine(); + if (e != NULL) { +- ENGINE_free(e); ++ SSL_UTILS_ENGINE_free(e); + e = NULL; + } + + // determine whether KAE is loaded successfully + const char* id = (*env)->GetStringUTFChars(env, engineId, 0); +- e = ENGINE_by_id(id); ++ e = SSL_UTILS_ENGINE_by_id(id); + (*env)->ReleaseStringUTFChars(env, engineId, id); + if (e == NULL) { + KAE_ThrowFromOpenssl(env, "ENGINE_by_id", KAE_ThrowRuntimeException); +- return; ++ return -1; + } + SetKaeEngine(e); + + // initialize the engine for each algorithm + initEngines(env, algorithmKaeFlags); ++ ++ return get_sslVersion(); + } + + /* +@@ -100,4 +81,4 @@ JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEProvider_initOpens + JNIEXPORT jbooleanArray JNICALL Java_org_openeuler_security_openssl_KAEProvider_getEngineFlags + (JNIEnv *env, jclass cls) { + return getEngineFlags(env); +-} +\ No newline at end of file ++} +\ No newline at end of file +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c +index 6c401356d..9e3ff2a55 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c +@@ -27,11 +27,12 @@ + #include "kae_log.h" + #include "kae_util.h" + #include "kae_exception.h" ++#include "ssl_utils.h" + + // get EVP_MD by digestName + static const EVP_MD* getEvpMd(JNIEnv* env, jstring digestName) { + const char* digestNameUtf = (*env)->GetStringUTFChars(env, digestName, 0); +- const EVP_MD* md = (EVP_MD*)EVP_get_digestbyname(digestNameUtf); ++ const EVP_MD* md = (EVP_MD*)SSL_UTILS_EVP_get_digestbyname(digestNameUtf); + (*env)->ReleaseStringUTFChars(env, digestName, digestNameUtf); + if (md == NULL) { + KAE_ThrowSignatureException(env, "Unsupported digest algorithm."); +@@ -49,7 +50,7 @@ static void signRelease(JNIEnv* env, jbyteArray digestValue, jbyte* digestBytes, + free(sigBytes); + } + if (pkeyCtx != NULL) { +- EVP_PKEY_CTX_free(pkeyCtx); ++ SSL_UTILS_EVP_PKEY_CTX_free(pkeyCtx); + } + } + +@@ -63,14 +64,14 @@ static void verifyRelease(JNIEnv* env, jbyteArray digestValue, jbyte* digestByte + (*env)->ReleaseByteArrayElements(env, sigValue, sigBytes, 0); + } + if (pkeyCtx != NULL) { +- EVP_PKEY_CTX_free(pkeyCtx); ++ SSL_UTILS_EVP_PKEY_CTX_free(pkeyCtx); + } + } + + // set rsa PkeyCtx parameters + static bool setRsaPkeyCtxParameters(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jint paddingType, jstring digestName) { + // set rsa padding +- if (EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_padding", KAE_ThrowSignatureException); + return false; + } +@@ -81,7 +82,7 @@ static bool setRsaPkeyCtxParameters(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jint pad + return false; + } + +- if (EVP_PKEY_CTX_set_signature_md(pkeyCtx, md) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_signature_md(pkeyCtx, md) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_signature_md", KAE_ThrowSignatureException); + return false; + } +@@ -104,13 +105,13 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature + KAE_TRACE("KAERSASignatureNative_rsaSign: kaeEngine => %p", kaeEngine); + + // new EVP_PKEY_CTX +- if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { ++ if ((pkeyCtx = SSL_UTILS_EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException); + goto cleanup; + } + + // sign init +- if (EVP_PKEY_sign_init(pkeyCtx) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_sign_init(pkeyCtx) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign_init", KAE_ThrowSignatureException); + goto cleanup; + } +@@ -121,7 +122,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature + } + + // sign +- size_t sigLen = (size_t)EVP_PKEY_size(pkey); ++ size_t sigLen = (size_t)SSL_UTILS_EVP_PKEY_size(pkey); + if (sigLen <= 0) { + KAE_ThrowSignatureException(env, "The sigLen size cannot be zero or negative"); + goto cleanup; +@@ -135,7 +136,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature + goto cleanup; + } + size_t digestLen = (size_t)(*env)->GetArrayLength(env, digestValue); +- if (EVP_PKEY_sign(pkeyCtx, (unsigned char*)sigBytes, &sigLen, ++ if (SSL_UTILS_EVP_PKEY_sign(pkeyCtx, (unsigned char*)sigBytes, &sigLen, + (const unsigned char*)digestBytes, digestLen) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign", KAE_ThrowSignatureException); + goto cleanup; +@@ -169,13 +170,13 @@ JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNa + KAE_TRACE("KAERSASignatureNative_rsaVerify: kaeEngine => %p", kaeEngine); + + // new EVP_PKEY_CTX +- if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { ++ if ((pkeyCtx = SSL_UTILS_EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException); + goto cleanup; + } + + // verify init +- if (EVP_PKEY_verify_init(pkeyCtx) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_verify_init(pkeyCtx) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign_init", KAE_ThrowSignatureException); + goto cleanup; + } +@@ -196,7 +197,7 @@ JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNa + } + size_t sigLen = (size_t)(*env)->GetArrayLength(env, sigValue); + size_t digestLen = (size_t)(*env)->GetArrayLength(env, digestValue); +- if (EVP_PKEY_verify(pkeyCtx, (const unsigned char*)sigBytes, sigLen, ++ if (SSL_UTILS_EVP_PKEY_verify(pkeyCtx, (const unsigned char*)sigBytes, sigLen, + (const unsigned char*)digestBytes, digestLen) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_verify", KAE_ThrowSignatureException); + goto cleanup; +@@ -212,7 +213,7 @@ cleanup: + static bool setPssPkeyCtxParameters(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jint paddingType, jstring digestName, + jstring mgf1DigestName, jint saltLen) { + // set rsa padding +- if (EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, paddingType) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_padding", KAE_ThrowSignatureException); + return false; + } +@@ -222,7 +223,7 @@ static bool setPssPkeyCtxParameters(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jint pad + if (md == NULL) { + return false; + } +- if (EVP_PKEY_CTX_set_signature_md(pkeyCtx, md) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_signature_md(pkeyCtx, md) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_signature_md", KAE_ThrowSignatureException); + return false; + } +@@ -232,13 +233,13 @@ static bool setPssPkeyCtxParameters(JNIEnv* env, EVP_PKEY_CTX* pkeyCtx, jint pad + if (mgf1Md == NULL) { + return false; + } +- if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, mgf1Md) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_rsa_mgf1_md(pkeyCtx, mgf1Md) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_mgf1_md", KAE_ThrowSignatureException); + return false; + } + + // set salt len +- if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, saltLen) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_CTX_set_rsa_pss_saltlen(pkeyCtx, saltLen) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set_rsa_pss_saltlen", KAE_ThrowSignatureException); + return false; + } +@@ -262,13 +263,13 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature + KAE_TRACE("KAERSASignatureNative_pssSign: kaeEngine => %p", kaeEngine); + + // new EVP_PKEY_CTX +- if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { ++ if ((pkeyCtx = SSL_UTILS_EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException); + goto cleanup; + } + + // sign init +- if (EVP_PKEY_sign_init(pkeyCtx) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_sign_init(pkeyCtx) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign_init", KAE_ThrowSignatureException); + goto cleanup; + } +@@ -279,7 +280,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature + } + + // sign +- size_t sigLen = (size_t)EVP_PKEY_size(pkey); ++ size_t sigLen = (size_t)SSL_UTILS_EVP_PKEY_size(pkey); + if (sigLen <= 0) { + KAE_ThrowSignatureException(env, "The sigLen size cannot be zero or negative"); + goto cleanup; +@@ -293,7 +294,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature + goto cleanup; + } + size_t digestLen = (size_t)(*env)->GetArrayLength(env, digestValue); +- if (EVP_PKEY_sign(pkeyCtx, (unsigned char*)sigBytes, &sigLen, ++ if (SSL_UTILS_EVP_PKEY_sign(pkeyCtx, (unsigned char*)sigBytes, &sigLen, + (const unsigned char*)digestBytes, digestLen) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign", KAE_ThrowSignatureException); + goto cleanup; +@@ -328,13 +329,13 @@ JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNa + KAE_TRACE("KAERSASignatureNative_pssVerify: kaeEngine => %p", kaeEngine); + + // new EVP_PKEY_CTX +- if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { ++ if ((pkeyCtx = SSL_UTILS_EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException); + goto cleanup; + } + + // verify init +- if (EVP_PKEY_verify_init(pkeyCtx) <= 0) { ++ if (SSL_UTILS_EVP_PKEY_verify_init(pkeyCtx) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_sign_init", KAE_ThrowSignatureException); + goto cleanup; + } +@@ -355,7 +356,7 @@ JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNa + } + size_t sigLen = (size_t)(*env)->GetArrayLength(env, sigValue); + size_t digestLen = (size_t)(*env)->GetArrayLength(env, digestValue); +- if (EVP_PKEY_verify(pkeyCtx, (const unsigned char*)sigBytes, sigLen, ++ if (SSL_UTILS_EVP_PKEY_verify(pkeyCtx, (const unsigned char*)sigBytes, sigLen, + (const unsigned char*)digestBytes, digestLen) <= 0) { + KAE_ThrowFromOpenssl(env, "EVP_PKEY_verify", KAE_ThrowSignatureException); + goto cleanup; +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_sm2.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_sm2.c +new file mode 100644 +index 000000000..2eb151f9c +--- /dev/null ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_sm2.c +@@ -0,0 +1,286 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++ ++#include "org_openeuler_security_openssl_KAESM2Signature.h" ++#include "kae_util.h" ++#include "kae_log.h" ++#include "kae_exception.h" ++#include "ssl_utils.h" ++#include ++#include ++#include ++#include ++ ++static const EVP_MD* GetEVP_MDByName(JNIEnv *env, const char* algo) ++{ ++ static const EVP_MD* sm3 = NULL; ++ ++ if (strcasecmp(algo, "SM3") == 0) { ++ return sm3 == NULL ? sm3 = SSL_UTILS_EVP_sm3() : sm3; ++ } else { ++ KAE_ThrowRuntimeException(env, "GetEVP_MDByName error"); ++ return NULL; ++ } ++} ++ ++/* ++* Class: org_openeuler_security_openssl_KAESM2Signature ++* Method: nativeClone ++* Signature: (J)J ++*/ ++JNIEXPORT jlong JNICALL ++Java_org_openeuler_security_openssl_KAESM2Signature_nativeClone(JNIEnv *env, jclass cls, jlong ctxAddress) ++{ ++ EVP_MD_CTX* ctx = (EVP_MD_CTX*) ctxAddress; ++ KAE_TRACE("KAESM2Signature_nativeClone: ctx = %p", ctx); ++ if (ctx == NULL) { ++ return 0; ++ } ++ ++ // EVP_MD_CTX_create is macro in openssl 1 and 3 ++ EVP_MD_CTX* ctxCopy = SSL_UTILS_EVP_MD_CTX_create(); ++ if (ctxCopy == NULL) { ++ KAE_ThrowOOMException(env, "create EVP_MD_CTX fail"); ++ return 0; ++ } ++ KAE_TRACE("KAESM2Signature_nativeClone: create ctxCopy => %p", ctxCopy); ++ ++ int result_code = SSL_UTILS_EVP_MD_CTX_copy_ex(ctxCopy, ctx); ++ if (result_code == 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_MD_CTX_copy_ex failed", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ KAE_TRACE("KAESM2Signature_nativeClone EVP_MD_CTX_copy_ex(ctxCopy = %p, ctx = %p) success", ctxCopy, ctx); ++ KAE_TRACE("KAESM2Signature_nativeClone: finished"); ++ return (jlong) ctxCopy; ++ ++cleanup: ++ if (ctxCopy != NULL) { ++ SSL_UTILS_EVP_MD_CTX_free(ctxCopy); ++ } ++ return 0; ++} ++ ++/* ++ * Class: org_openeuler_security_openssl_KAESM2Signature ++ * Method: nativeFreeSM2Ctx ++ * Signature: (J)V ++ */ ++JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAESM2Signature_nativeFreeSM2Ctx(JNIEnv *env, ++ jclass cls, jlong ctxAddress) ++{ ++ if(ctxAddress == 0){ ++ KAE_ThrowInvalidKeyException(env, "nativeFreeSM2Ctx failed. ctxAddress is Invalid"); ++ } ++ EVP_MD_CTX *md_ctx = (EVP_MD_CTX*) ctxAddress; ++ if (md_ctx != NULL) { ++ SSL_UTILS_EVP_MD_CTX_free(md_ctx); ++ } ++ KAE_TRACE("KAESM2Signature_nativeFreeSM2Ctx: finished"); ++} ++ ++/* ++ * Class: org_openeuler_security_openssl_KAESM2Signature ++ * Method: nativeInitSM2Ctx ++ * Signature: (JLjava/lang/String;Z)J ++ */ ++JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAESM2Signature_nativeInitSM2Ctx(JNIEnv *env, ++ jclass cls, jlong keyAddress, jstring digestName, jstring id, jboolean isSign) ++{ ++ EVP_MD_CTX* md_ctx = NULL; ++ EVP_PKEY_CTX* pctx = NULL; ++ EVP_PKEY* pkey = NULL; ++ pkey = (EVP_PKEY*) keyAddress; ++ ENGINE* kaeEngine = NULL; ++ ++ // init engine ++ kaeEngine = GetEngineByAlgorithmIndex(SM2_INDEX); ++ KAE_TRACE("KAESM2Signature_nativeInitSM2Ctx: kaeEngine => %p", kaeEngine); ++ ++ const char* algo = (*env)->GetStringUTFChars(env, digestName, 0); ++ const char* sm2_id = (*env)->GetStringUTFChars(env, id, 0); ++ ++ // new pkey_ctx ++ if ((pctx = SSL_UTILS_EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_new", KAE_ThrowInvalidKeyException); ++ goto cleanup; ++ } ++ ++ // EVP_PKEY_CTX_set1_id is macro in openssl 1 ++ if (SSL_UTILS_EVP_PKEY_CTX_set1_id(pctx, sm2_id, strlen(sm2_id)) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_PKEY_CTX_set1_id", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // new md_ctx ++ if ((md_ctx = SSL_UTILS_EVP_MD_CTX_new()) == NULL) { ++ KAE_ThrowFromOpenssl(env, "EVP_MD_CTX_new", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ // set pkey_ctx in md_ctx ++ SSL_UTILS_EVP_MD_CTX_set_pkey_ctx(md_ctx, pctx); ++ ++ // init md_ctx ++ if(isSign){ ++ if (SSL_UTILS_EVP_DigestSignInit(md_ctx, NULL, GetEVP_MDByName(env, algo), kaeEngine, pkey) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_DigestSignInit", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ }else { ++ if (SSL_UTILS_EVP_DigestVerifyInit(md_ctx, NULL, GetEVP_MDByName(env, algo), kaeEngine, pkey) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_DigestVerifyInit", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ } ++ (*env)->ReleaseStringUTFChars(env, digestName, algo); ++ (*env)->ReleaseStringUTFChars(env, id, sm2_id); ++ return (jlong)md_ctx; ++cleanup: ++ (*env)->ReleaseStringUTFChars(env, digestName, algo); ++ (*env)->ReleaseStringUTFChars(env, id, sm2_id); ++ if (pctx != NULL) { ++ SSL_UTILS_EVP_PKEY_CTX_free(pctx); ++ } ++ if (md_ctx != NULL) { ++ SSL_UTILS_EVP_MD_CTX_free(md_ctx); ++ } ++ return 0; ++} ++ ++/* ++ * Class: org_openeuler_security_openssl_KAESM2Signature ++ * Method: nativeSM2Update ++ * Signature: (J[BIZ)V ++ */ ++JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAESM2Signature_nativeSM2Update(JNIEnv *env, ++ jclass cls, jlong ctxAddress, jbyteArray msgArr, jint msgLen, jboolean isSign) ++{ ++ EVP_MD_CTX* md_ctx = NULL; ++ unsigned char* msg = NULL; ++ md_ctx = (EVP_MD_CTX*) ctxAddress; ++ ++ if ((msg = (unsigned char*)malloc(msgLen)) == NULL) { ++ KAE_ThrowOOMException(env, "malloc error"); ++ goto cleanup; ++ } ++ memset(msg, 0, msgLen); ++ ++ (*env)->GetByteArrayRegion(env, msgArr, 0, msgLen, (jbyte*)msg); ++ ++ if(isSign){ ++ if (SSL_UTILS_EVP_DigestSignUpdate(md_ctx, msg, msgLen) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_DigestSignUpdate", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ }else { ++ if (SSL_UTILS_EVP_DigestVerifyUpdate(md_ctx, msg, msgLen) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_DigestVerifyUpdate", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ } ++ KAE_TRACE("KAESM2Signature_nativeSM2Update: finished"); ++cleanup: ++ if (msg != NULL) { ++ memset(msg, 0, msgLen); ++ free(msg); ++ } ++} ++ ++/* ++ * Class: org_openeuler_security_openssl_KAESM2Signature ++ * Method: nativeSM2SignFinal ++ * Signature: (J)[B ++ */ ++JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAESM2Signature_nativeSM2SignFinal(JNIEnv *env, ++ jclass cls, jlong ctxAddress) ++{ ++ EVP_MD_CTX* md_ctx = NULL; ++ unsigned char* sig = NULL; ++ size_t sig_len = 0; ++ jbyteArray sigByteArray = NULL; ++ md_ctx = (EVP_MD_CTX*) ctxAddress; ++ ++ // determine the size of the signature ++ if (SSL_UTILS_EVP_DigestSignFinal(md_ctx, NULL, &sig_len) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_DigestSignFinal", KAE_ThrowRuntimeException); ++ goto cleanup; ++ } ++ ++ if ((sig = malloc(sig_len)) == NULL) { ++ KAE_ThrowOOMException(env, "malloc error"); ++ goto cleanup; ++ } ++ memset(sig, 0, sig_len); ++ ++ // sign ++ if (SSL_UTILS_EVP_DigestSignFinal(md_ctx, sig, &sig_len) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_DigestSignFinal", KAE_ThrowSignatureException); ++ goto cleanup; ++ } ++ ++ if ((sigByteArray = (*env)->NewByteArray(env, sig_len)) == NULL) { ++ goto cleanup; ++ } ++ (*env)->SetByteArrayRegion(env, sigByteArray, 0, sig_len, (jbyte*)sig); ++ KAE_TRACE("KAESM2Signature_nativeSM2SignFinal: finished"); ++cleanup: ++ if (sig != NULL) { ++ memset(sig, 0, sig_len); ++ free(sig); ++ } ++ return sigByteArray; ++} ++ ++/* ++ * Class: org_openeuler_security_openssl_KAESM2Signature ++ * Method: nativeSM2VerifyFinal ++ * Signature: (J[B)Z ++ */ ++JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAESM2Signature_nativeSM2VerifyFinal(JNIEnv *env, ++ jclass cls, jlong ctxAddress, jbyteArray sigBytesArr, jint sigLen) ++{ ++ EVP_MD_CTX* md_ctx = NULL; ++ unsigned char* sigBytes = NULL; ++ jboolean isSuccess = JNI_FALSE; ++ md_ctx = (EVP_MD_CTX*) ctxAddress; ++ ++ if ((sigBytes = (unsigned char*)malloc(sigLen)) == NULL) { ++ KAE_ThrowOOMException(env, "malloc error"); ++ goto cleanup; ++ } ++ (*env)->GetByteArrayRegion(env, sigBytesArr, 0, sigLen, (jbyte*)sigBytes); ++ ++ // verify ++ if (SSL_UTILS_EVP_DigestVerifyFinal(md_ctx, sigBytes, sigLen) <= 0) { ++ KAE_ThrowFromOpenssl(env, "EVP_DigestVerifyFinal", KAE_ThrowSignatureException); ++ goto cleanup; ++ } ++ isSuccess = JNI_TRUE; ++cleanup: ++ if (sigBytes != NULL) { ++ memset(sigBytes, 0, sigLen); ++ free(sigBytes); ++ } ++ return isSuccess; ++} +\ No newline at end of file +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c +index 7618d6e16..bf4e93d24 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c +@@ -29,6 +29,7 @@ + #include "kae_exception.h" + #include "kae_log.h" + #include "kae_util.h" ++#include "ssl_utils.h" + #include "org_openeuler_security_openssl_KAESymmetricCipherBase.h" + + bool StartsWith(const char* str1, const char* str2) +@@ -61,13 +62,13 @@ static const EVP_CIPHER* EVPGetSm4CipherByName(JNIEnv* env, const char* algo) + static const EVP_CIPHER* sm4Ofb = NULL; + + if (strcasecmp(algo, "sm4-ecb") == 0) { +- return sm4Ecb == NULL ? sm4Ecb = EVP_get_cipherbyname(algo) : sm4Ecb; ++ return sm4Ecb == NULL ? sm4Ecb = SSL_UTILS_EVP_get_cipherbyname(algo) : sm4Ecb; + } else if (strcasecmp(algo, "sm4-cbc") == 0) { +- return sm4Cbc == NULL ? sm4Cbc = EVP_get_cipherbyname(algo) : sm4Cbc; ++ return sm4Cbc == NULL ? sm4Cbc = SSL_UTILS_EVP_get_cipherbyname(algo) : sm4Cbc; + } else if (strcasecmp(algo, "sm4-ctr") == 0) { +- return sm4Ctr == NULL ? sm4Ctr = EVP_get_cipherbyname(algo) : sm4Ctr; ++ return sm4Ctr == NULL ? sm4Ctr = SSL_UTILS_EVP_get_cipherbyname(algo) : sm4Ctr; + } else if (strcasecmp(algo, "sm4-ofb") == 0) { +- return sm4Ofb == NULL ? sm4Ofb = EVP_get_cipherbyname(algo) : sm4Ofb; ++ return sm4Ofb == NULL ? sm4Ofb = SSL_UTILS_EVP_get_cipherbyname(algo) : sm4Ofb; + } else { + KAE_ThrowRuntimeException(env, "EVPGetSm4CipherByName error"); + return 0; +@@ -90,29 +91,29 @@ static const EVP_CIPHER* EVPGetAesCipherByName(JNIEnv* env, const char* algo) + static const EVP_CIPHER* aes256Gcm = NULL; + + if (strcasecmp(algo, "aes-128-ecb") == 0) { +- return aes128Ecb == NULL ? aes128Ecb = EVP_get_cipherbyname(algo) : aes128Ecb; ++ return aes128Ecb == NULL ? aes128Ecb = SSL_UTILS_EVP_get_cipherbyname(algo) : aes128Ecb; + } else if (strcasecmp(algo, "aes-128-cbc") == 0) { +- return aes128Cbc == NULL ? aes128Cbc = EVP_get_cipherbyname(algo) : aes128Cbc; ++ return aes128Cbc == NULL ? aes128Cbc = SSL_UTILS_EVP_get_cipherbyname(algo) : aes128Cbc; + } else if (strcasecmp(algo, "aes-128-ctr") == 0) { +- return aes128Ctr == NULL ? aes128Ctr = EVP_get_cipherbyname(algo) : aes128Ctr; ++ return aes128Ctr == NULL ? aes128Ctr = SSL_UTILS_EVP_get_cipherbyname(algo) : aes128Ctr; + } else if (strcasecmp(algo, "aes-128-gcm") == 0) { +- return aes128Gcm == NULL ? aes128Gcm = EVP_get_cipherbyname(algo) : aes128Gcm; ++ return aes128Gcm == NULL ? aes128Gcm = SSL_UTILS_EVP_get_cipherbyname(algo) : aes128Gcm; + } else if (strcasecmp(algo, "aes-192-ecb") == 0) { +- return aes192Ecb == NULL ? aes192Ecb = EVP_get_cipherbyname(algo) : aes192Ecb; ++ return aes192Ecb == NULL ? aes192Ecb = SSL_UTILS_EVP_get_cipherbyname(algo) : aes192Ecb; + } else if (strcasecmp(algo, "aes-192-cbc") == 0) { +- return aes192Cbc == NULL ? aes192Cbc = EVP_get_cipherbyname(algo) : aes192Cbc; ++ return aes192Cbc == NULL ? aes192Cbc = SSL_UTILS_EVP_get_cipherbyname(algo) : aes192Cbc; + } else if (strcasecmp(algo, "aes-192-ctr") == 0) { +- return aes192Ctr == NULL ? aes192Ctr = EVP_get_cipherbyname(algo) : aes192Ctr; ++ return aes192Ctr == NULL ? aes192Ctr = SSL_UTILS_EVP_get_cipherbyname(algo) : aes192Ctr; + } else if (strcasecmp(algo, "aes-192-gcm") == 0) { +- return aes192Gcm == NULL ? aes192Gcm = EVP_get_cipherbyname(algo) : aes192Gcm; ++ return aes192Gcm == NULL ? aes192Gcm = SSL_UTILS_EVP_get_cipherbyname(algo) : aes192Gcm; + } else if (strcasecmp(algo, "aes-256-ecb") == 0) { +- return aes256Ecb == NULL ? aes256Ecb = EVP_get_cipherbyname(algo) : aes256Ecb; ++ return aes256Ecb == NULL ? aes256Ecb = SSL_UTILS_EVP_get_cipherbyname(algo) : aes256Ecb; + } else if (strcasecmp(algo, "aes-256-cbc") == 0) { +- return aes256Cbc == NULL ? aes256Cbc = EVP_get_cipherbyname(algo) : aes256Cbc; ++ return aes256Cbc == NULL ? aes256Cbc = SSL_UTILS_EVP_get_cipherbyname(algo) : aes256Cbc; + } else if (strcasecmp(algo, "aes-256-ctr") == 0) { +- return aes256Ctr == NULL ? aes256Ctr = EVP_get_cipherbyname(algo) : aes256Ctr; ++ return aes256Ctr == NULL ? aes256Ctr = SSL_UTILS_EVP_get_cipherbyname(algo) : aes256Ctr; + } else if (strcasecmp(algo, "aes-256-gcm") == 0) { +- return aes256Gcm == NULL ? aes256Gcm = EVP_get_cipherbyname(algo) : aes256Gcm; ++ return aes256Gcm == NULL ? aes256Gcm = SSL_UTILS_EVP_get_cipherbyname(algo) : aes256Gcm; + } else { + KAE_ThrowRuntimeException(env, "EVPGetAesCipherByName error"); + return 0; +@@ -163,7 +164,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en + KAE_ThrowOOMException(env, "create EVP_CIPHER fail"); + goto cleanup; + } +- if ((ctx = EVP_CIPHER_CTX_new()) == NULL) { ++ if ((ctx = SSL_UTILS_EVP_CIPHER_CTX_new()) == NULL) { + KAE_ThrowOOMException(env, "create EVP_CIPHER_CTX fail"); + goto cleanup; + } +@@ -176,7 +177,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en + keyBytes = (*env)->GetByteArrayElements(env, key, NULL); + } + +- if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, NULL, ++ if (!SSL_UTILS_EVP_CipherInit_ex(ctx, cipher, kaeEngine, NULL, + NULL, encrypt ? 1 : 0)) { + KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex failed", KAE_ThrowRuntimeException); + goto cleanup; +@@ -184,19 +185,19 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en + + 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)) { ++ if(!SSL_UTILS_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, ++ if (!SSL_UTILS_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); ++ SSL_UTILS_EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0); + + (*env)->ReleaseStringUTFChars(env, cipherType, algo); + FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength); +@@ -204,7 +205,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en + + cleanup: + if (ctx != NULL) { +- EVP_CIPHER_CTX_free(ctx); ++ SSL_UTILS_EVP_CIPHER_CTX_free(ctx); + } + (*env)->ReleaseStringUTFChars(env, cipherType, algo); + FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength); +@@ -264,13 +265,13 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeUpdate(JNIEnv* + (*env)->GetByteArrayRegion(env, gcmAAD, 0, aadLen, (jbyte*)aad); + + // Specify aad. +- if (EVP_CipherUpdate(ctx, NULL, &bytesWritten, aad, aadLen) == 0) { ++ if (SSL_UTILS_EVP_CipherUpdate(ctx, NULL, &bytesWritten, aad, aadLen) == 0) { + KAE_ThrowFromOpenssl(env, "EVP_CipherUpdate failed", KAE_ThrowRuntimeException); + goto cleanup; + } + } + +- if (EVP_CipherUpdate(ctx, out, &bytesWritten, in, inLen) == 0) { ++ if (SSL_UTILS_EVP_CipherUpdate(ctx, out, &bytesWritten, in, inLen) == 0) { + KAE_ThrowFromOpenssl(env, "EVP_CipherUpdate failed", KAE_ThrowRuntimeException); + goto cleanup; + } +@@ -308,7 +309,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeFinal(JNIEnv* e + } + memset(out, 0, outLen); + int bytesWritten = 0; +- int result_code = EVP_CipherFinal_ex(ctx, out, &bytesWritten); ++ int result_code = SSL_UTILS_EVP_CipherFinal_ex(ctx, out, &bytesWritten); + if (result_code == 0) { + KAE_ThrowFromOpenssl(env, "EVP_CipherFinal_ex failed", KAE_ThrowBadPaddingException); + goto cleanup; +@@ -365,7 +366,7 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAESymmetricCipherBas + goto cleanup; + } + memset(out, 0, outLen); +- if (EVP_CipherFinal_ex(ctx, out, &bytesWritten) == 0) { ++ if (SSL_UTILS_EVP_CipherFinal_ex(ctx, out, &bytesWritten) == 0) { + KAE_ThrowFromOpenssl(env, "EVP_CipherFinal_ex failed", KAE_ThrowBadPaddingException); + goto cleanup; + } +@@ -373,7 +374,7 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAESymmetricCipherBas + + // Writes tagLength bytes of the tag value to the buffer. + // Refer to {@link https://www.openssl.org/docs/man1.1.0/man3/EVP_CIPHER_CTX_ctrl.html} for details. +- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tagLength, out + bytesWritten) == 0) { ++ if (SSL_UTILS_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tagLength, out + bytesWritten) == 0) { + KAE_ThrowFromOpenssl(env, "EVP_CIPHER_CTX_ctrl failed", KAE_ThrowRuntimeException); + goto cleanup; + } +@@ -392,14 +393,14 @@ JNIEXPORT jint JNICALL Java_org_openeuler_security_openssl_KAESymmetricCipherBas + (*env)->GetByteArrayRegion(env, gcmTagArr, 0, tagLength, (jbyte*)gcmTag); + // Sets the expected gcmTag to tagLength bytes from gcmTag. + // Refer to {@link https://www.openssl.org/docs/man1.1.0/man3/EVP_CIPHER_CTX_ctrl.html} for details. +- if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tagLength, gcmTag) == 0) { ++ if (SSL_UTILS_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tagLength, gcmTag) == 0) { + KAE_ThrowFromOpenssl(env, "EVP_CTRL_AEAD_SET_TAG failed", KAE_ThrowRuntimeException); + goto cleanup; + } + + (*env)->GetByteArrayRegion(env, outArr, 0, outOfs, (jbyte*)gcmOut); + // Finalise: note get no output for GCM +- if (EVP_CipherFinal_ex(ctx, gcmOut, &bytesWritten) == 0) { ++ if (SSL_UTILS_EVP_CipherFinal_ex(ctx, gcmOut, &bytesWritten) == 0) { + KAE_ThrowFromOpenssl(env, "EVP_CipherFinal_ex failed", KAE_ThrowAEADBadTagException); + goto cleanup; + } +@@ -424,7 +425,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeFree(JNIEnv* en + EVP_CIPHER_CTX* ctx = (EVP_CIPHER_CTX*)ctxAddress; + KAE_TRACE("KAESymmetricCipherBase_nativeFree(ctx = %p)", ctx); + if (ctx != NULL) { +- EVP_CIPHER_CTX_free(ctx); ++ SSL_UTILS_EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + } + +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c +index a16d944c4..a0e541bdc 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c +@@ -25,6 +25,7 @@ + #include + #include "kae_util.h" + #include "kae_exception.h" ++#include "ssl_utils.h" + + static ENGINE* kaeEngine = NULL; + +@@ -48,7 +49,7 @@ BIGNUM* KAE_GetBigNumFromByteArray(JNIEnv* env, jbyteArray byteArray) { + return NULL; + } + +- BIGNUM* bn = BN_new(); ++ BIGNUM* bn = SSL_UTILS_BN_new(); + if (bn == NULL) { + KAE_ThrowFromOpenssl(env, "BN_new", KAE_ThrowRuntimeException); + return NULL; +@@ -59,7 +60,7 @@ BIGNUM* KAE_GetBigNumFromByteArray(JNIEnv* env, jbyteArray byteArray) { + KAE_ThrowNullPointerException(env, "GetByteArrayElements failed"); + goto cleanup; + } +- BIGNUM* result = BN_bin2bn((const unsigned char*) bytes, len, bn); ++ BIGNUM* result = SSL_UTILS_BN_bin2bn((const unsigned char*) bytes, len, bn); + (*env)->ReleaseByteArrayElements(env, byteArray, bytes, 0); + if (result == NULL) { + KAE_ThrowFromOpenssl(env, "BN_bin2bn", KAE_ThrowRuntimeException); +@@ -68,13 +69,19 @@ BIGNUM* KAE_GetBigNumFromByteArray(JNIEnv* env, jbyteArray byteArray) { + return bn; + + cleanup: +- BN_free(bn); ++ SSL_UTILS_BN_free(bn); + return NULL; + } + + void KAE_ReleaseBigNumFromByteArray(BIGNUM* bn) { + if (bn != NULL) { +- BN_free(bn); ++ SSL_UTILS_BN_free(bn); ++ } ++} ++ ++void KAE_ReleaseBigNumFromByteArray_Clear(BIGNUM* bn) { ++ if (bn != NULL) { ++ SSL_UTILS_BN_clear_free(bn); + } + } + +@@ -83,7 +90,8 @@ jbyteArray KAE_GetByteArrayFromBigNum(JNIEnv* env, const BIGNUM* bn) { + return NULL; + } + // bn size need plus 1, for example 65535 , BN_num_bytes return 2 +- int bnSize = BN_num_bytes(bn); ++ // Changed from macro, BN_num_bytes(bn) is ((BN_num_bits(bn)+7)/8); ++ int bnSize = SSL_UTILS_BN_num_bytes(bn); + if (bnSize <= 0) { + return NULL; + } +@@ -99,7 +107,7 @@ jbyteArray KAE_GetByteArrayFromBigNum(JNIEnv* env, const BIGNUM* bn) { + return NULL; + } + unsigned char* tmp = (unsigned char*) bytes; +- if (BN_bn2bin(bn, tmp + 1) <= 0) { ++ if (SSL_UTILS_BN_bn2bin(bn, tmp + 1) <= 0) { + KAE_ThrowFromOpenssl(env, "BN_bn2bin", KAE_ThrowRuntimeException); + javaBytes = NULL; + goto cleanup; +@@ -111,7 +119,7 @@ cleanup: + return javaBytes; + } + +-#define ENGINE_LENGTH (EC_INDEX + 1) ++#define ENGINE_LENGTH (SM2_INDEX + 1) + static ENGINE* engines[ENGINE_LENGTH] = {NULL}; + static jboolean engineFlags[ENGINE_LENGTH] = {JNI_FALSE}; + static KAEAlgorithm kaeAlgorithms[ENGINE_LENGTH] = { +@@ -143,7 +151,8 @@ static KAEAlgorithm kaeAlgorithms[ENGINE_LENGTH] = { + {HMAC_SHA512_INDEX, "hmac-sha512"}, + {RSA_INDEX, "rsa"}, + {DH_INDEX, "dh"}, +- {EC_INDEX, "ec"} ++ {EC_INDEX, "ec"}, ++ {SM2_INDEX, "sm2"} + }; + + void initEngines(JNIEnv* env, jbooleanArray algorithmKaeFlags) { +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h +index 347337509..a099b4470 100644 +--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h +@@ -56,7 +56,8 @@ typedef enum { + HMAC_SHA512_INDEX, + RSA_INDEX, + DH_INDEX, +- EC_INDEX ++ EC_INDEX, ++ SM2_INDEX + } AlgorithmIndex; + + typedef struct { +@@ -70,6 +71,9 @@ BIGNUM* KAE_GetBigNumFromByteArray(JNIEnv* env, jbyteArray byteArray); + /* release BIGNUM allocat from */ + void KAE_ReleaseBigNumFromByteArray(BIGNUM* bn); + ++/* release BIGNUM allocat from and clear data*/ ++void KAE_ReleaseBigNumFromByteArray_Clear(BIGNUM* bn); ++ + /* BIGNUM convert to jbyteArray */ + jbyteArray KAE_GetByteArrayFromBigNum(JNIEnv* env, const BIGNUM* bn); + +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/openssl1_macro.h b/jdk/src/solaris/native/org/openeuler/security/openssl/openssl1_macro.h +new file mode 100644 +index 000000000..1461a7a25 +--- /dev/null ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/openssl1_macro.h +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++ ++#ifndef OPENSSL1_MACRO_H ++#define OPENSSL1_MACRO_H ++ ++#define SSL1_EVP_PKEY_OP_UNDEFINED 0 ++#define SSL1_EVP_PKEY_OP_PARAMGEN (1 << 1) ++#define SSL1_EVP_PKEY_OP_KEYGEN (1 << 2) ++#define SSL1_EVP_PKEY_OP_SIGN (1 << 3) ++#define SSL1_EVP_PKEY_OP_VERIFY (1 << 4) ++#define SSL1_EVP_PKEY_OP_VERIFYRECOVER (1 << 5) ++#define SSL1_EVP_PKEY_OP_SIGNCTX (1 << 6) ++#define SSL1_EVP_PKEY_OP_VERIFYCTX (1 << 7) ++#define SSL1_EVP_PKEY_OP_ENCRYPT (1 << 8) ++#define SSL1_EVP_PKEY_OP_DECRYPT (1 << 9) ++#define SSL1_EVP_PKEY_OP_DERIVE (1 << 10) ++ ++#define SSL1_EVP_PKEY_ALG_CTRL 0x1000 ++#define SSL1_EVP_PKEY_CTRL_RSA_PADDING (SSL1_EVP_PKEY_ALG_CTRL + 1) ++#define SSL1_EVP_PKEY_OP_TYPE_SIG \ ++ (SSL1_EVP_PKEY_OP_SIGN | SSL1_EVP_PKEY_OP_VERIFY | SSL1_EVP_PKEY_OP_VERIFYRECOVER | SSL1_EVP_PKEY_OP_SIGNCTX | \ ++ SSL1_EVP_PKEY_OP_VERIFYCTX) ++#define SSL1_EVP_PKEY_CTRL_MD 1 ++#define SSL1_EVP_PKEY_OP_TYPE_CRYPT (SSL1_EVP_PKEY_OP_ENCRYPT | SSL1_EVP_PKEY_OP_DECRYPT) ++#define SSL1_EVP_PKEY_CTRL_RSA_MGF1_MD (SSL1_EVP_PKEY_ALG_CTRL + 5) ++#define SSL1_EVP_PKEY_CTRL_RSA_PSS_SALTLEN (SSL1_EVP_PKEY_ALG_CTRL + 2) ++#define SSL1_EVP_PKEY_CTRL_RSA_OAEP_LABEL (SSL1_EVP_PKEY_ALG_CTRL + 10) ++#define SSL1_EVP_PKEY_CTRL_RSA_OAEP_MD (SSL1_EVP_PKEY_ALG_CTRL + 9) ++#define SSL1_EVP_PKEY_CTRL_SET1_ID (SSL1_EVP_PKEY_ALG_CTRL + 11) ++ ++#define SSL1_NID_rsaEncryption 6 ++#define SSL1_EVP_PKEY_RSA SSL1_NID_rsaEncryption ++ ++#endif // OPENSSL1_MACRO_H +\ No newline at end of file +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/openssl3_macro.h b/jdk/src/solaris/native/org/openeuler/security/openssl/openssl3_macro.h +new file mode 100644 +index 000000000..2ad08e407 +--- /dev/null ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/openssl3_macro.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++ ++#ifndef OPENSSL3_MACRO_H ++#define OPENSSL3_MACRO_H ++ ++#define SSL3_ERR_LIB_SYS 2 ++#define SSL3_ERR_LIB_OFFSET 23L ++#define SSL3_ERR_LIB_MASK 0xFF ++#define SSL3_INT_MAX __INT_MAX__ ++#define SSL3_ERR_SYSTEM_FLAG ((unsigned int)SSL3_INT_MAX + 1) ++#define SSL3_ERR_SYSTEM_MASK ((unsigned int)SSL3_INT_MAX) ++#define SSL3_ERR_REASON_MASK 0x7FFFFF ++ ++#define SSL3_ERR_SYSTEM_ERROR(errcode) (((errcode)&SSL3_ERR_SYSTEM_FLAG) != 0) ++ ++#endif // OPENSSL3_MACRO_H +\ No newline at end of file +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/ssl_utils.c b/jdk/src/solaris/native/org/openeuler/security/openssl/ssl_utils.c +new file mode 100644 +index 000000000..1c011adc1 +--- /dev/null ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/ssl_utils.c +@@ -0,0 +1,1372 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++ ++#include ++#include ++#include ++#include "kae_exception.h" ++#include "kae_log.h" ++#include "openssl1_macro.h" ++#include "openssl3_macro.h" ++#include "ssl_utils.h" ++ ++typedef char *(*OpenSSL_version_func_t)(int t); ++typedef RSA *(*RSA_new_method_func_t)(ENGINE *engine); ++typedef int (*RSA_generate_key_ex_func_t)(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); ++typedef void (*RSA_free_func_t)(RSA *rsa); ++typedef int (*OPENSSL_init_ssl_func_t)(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); ++typedef int (*ERR_load_BIO_strings_func_t)(void); ++typedef int (*OPENSSL_init_crypto_func_t)(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); ++typedef int (*ENGINE_free_func_t)(ENGINE *e); ++typedef ENGINE *(*ENGINE_by_id_func_t)(const char *id); ++typedef EVP_MD *(*EVP_get_digestbyname_func_t)(const char *name); ++typedef void (*EVP_PKEY_CTX_free_func_t)(EVP_PKEY_CTX *ctx); ++typedef int (*EVP_PKEY_CTX_set_rsa_padding_func_t)(EVP_PKEY_CTX *ctx, int pad_mode); ++typedef int (*EVP_PKEY_CTX_set_signature_md_func_t)(EVP_PKEY_CTX *ctx, const EVP_MD *md); ++typedef EVP_PKEY_CTX *(*EVP_PKEY_CTX_new_func_t)(EVP_PKEY *pkey, ENGINE *e); ++typedef int (*EVP_PKEY_sign_init_func_t)(EVP_PKEY_CTX *ctx); ++typedef int (*EVP_PKEY_sign_func_t)( ++ EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); ++typedef int (*EVP_PKEY_verify_init_func_t)(EVP_PKEY_CTX *ctx); ++typedef int (*EVP_PKEY_verify_func_t)( ++ EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); ++typedef int (*EVP_PKEY_CTX_set_rsa_mgf1_md_func_t)(EVP_PKEY_CTX *ctx, const EVP_MD *md); ++typedef int (*EVP_PKEY_CTX_set_rsa_pss_saltlen_func_t)(EVP_PKEY_CTX *ctx, int len); ++typedef int (*EVP_PKEY_size_func_t)(const EVP_PKEY *pkey); ++typedef EVP_CIPHER *(*EVP_get_cipherbyname_func_t)(const char *name); ++typedef EVP_CIPHER_CTX *(*EVP_CIPHER_CTX_new_func_t)(void); ++typedef int (*EVP_CipherInit_ex_func_t)(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, ++ const unsigned char *key, const unsigned char *iv, int enc); ++typedef int (*EVP_CIPHER_CTX_set_padding_func_t)(EVP_CIPHER_CTX *ctx, int pad); ++typedef void (*EVP_CIPHER_CTX_free_func_t)(EVP_CIPHER_CTX *ctx); ++typedef int (*EVP_CipherUpdate_func_t)( ++ EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); ++typedef int (*EVP_CipherFinal_ex_func_t)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); ++typedef int (*EVP_CIPHER_CTX_ctrl_func_t)(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); ++typedef BIGNUM *(*BN_new_func_t)(void); ++typedef BIGNUM *(*BN_bin2bn_func_t)(const unsigned char *s, int len, BIGNUM *ret); ++typedef void (*BN_free_func_t)(BIGNUM *a); ++typedef int (*EVP_PKEY_CTX_set0_rsa_oaep_label_func_t)(EVP_PKEY_CTX *ctx, void *label, int llen); ++typedef int (*EVP_PKEY_CTX_set_rsa_oaep_md_func_t)(EVP_PKEY_CTX *ctx, const EVP_MD *md); ++typedef EVP_PKEY *(*EVP_PKEY_new_func_t)(void); ++typedef int (*RSA_set0_key_func_t)(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); ++typedef int (*RSA_set0_factors_func_t)(RSA *r, BIGNUM *p, BIGNUM *q); ++typedef int (*RSA_set0_crt_params_func_t)(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); ++typedef void (*EVP_PKEY_free_func_t)(EVP_PKEY *x); ++typedef int (*RSA_private_encrypt_func_t)( ++ int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); ++typedef int (*RSA_private_decrypt_func_t)( ++ int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); ++typedef int (*RSA_public_encrypt_func_t)(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); ++typedef int (*RSA_public_decrypt_func_t)(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); ++typedef int (*EVP_PKEY_encrypt_init_func_t)(EVP_PKEY_CTX *ctx); ++typedef int (*EVP_PKEY_encrypt_func_t)( ++ EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen); ++typedef int (*EVP_PKEY_decrypt_init_func_t)(EVP_PKEY_CTX *ctx); ++typedef int (*EVP_PKEY_decrypt_func_t)( ++ EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen); ++typedef EVP_MD_CTX *(*EVP_MD_CTX_new_func_t)(void); ++typedef int (*EVP_DigestInit_ex_func_t)(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); ++typedef void (*EVP_MD_CTX_free_func_t)(EVP_MD_CTX *ctx); ++typedef int (*EVP_DigestUpdate_func_t)(EVP_MD_CTX *ctx, const void *data, size_t count); ++typedef int (*EVP_DigestFinal_ex_func_t)(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size); ++typedef int (*EVP_MD_CTX_copy_ex_func_t)(EVP_MD_CTX *out, const EVP_MD_CTX *in); ++typedef unsigned long (*ERR_get_error_line_data_func_t)(const char **file, int *line, const char **data, int *flags); ++typedef void (*ERR_error_string_n_func_t)(unsigned long e, char *buf, size_t len); ++typedef void (*ERR_clear_error_func_t)(void); ++typedef HMAC_CTX *(*HMAC_CTX_new_func_t)(void); ++typedef int (*HMAC_Init_ex_func_t)(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl); ++typedef void (*HMAC_CTX_free_func_t)(HMAC_CTX *ctx); ++typedef int (*HMAC_Update_func_t)(HMAC_CTX *ctx, const unsigned char *data, size_t len); ++typedef int (*HMAC_Final_func_t)(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); ++typedef DH *(*DH_new_method_func_t)(ENGINE *engine); ++typedef int (*DH_set0_pqg_func_t)(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); ++typedef int (*DH_set0_key_func_t)(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); ++typedef int (*DH_compute_key_func_t)(unsigned char *key, const BIGNUM *pub_key, DH *dh); ++typedef void (*DH_free_func_t)(DH *r); ++typedef void (*EC_POINT_free_func_t)(EC_POINT *point); ++typedef void (*EC_KEY_free_func_t)(EC_KEY *r); ++typedef void (*EC_GROUP_free_func_t)(EC_GROUP *group); ++typedef int (*OBJ_sn2nid_func_t)(const char *s); ++typedef EC_GROUP *(*EC_GROUP_new_by_curve_name_func_t)(int nid); ++typedef EC_KEY *(*EC_KEY_new_func_t)(void); ++typedef int (*EC_KEY_set_group_func_t)(EC_KEY *key, const EC_GROUP *group); ++typedef EC_POINT *(*EC_POINT_new_func_t)(const EC_GROUP *group); ++typedef int (*EC_POINT_set_affine_coordinates_GFp_func_t)( ++ const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); ++typedef int (*EC_KEY_set_public_key_func_t)(EC_KEY *key, const EC_POINT *pub_key); ++typedef int (*EC_KEY_set_private_key_func_t)(EC_KEY *key, const BIGNUM *priv_key); ++typedef int (*EC_GROUP_get_degree_func_t)(const EC_GROUP *group); ++typedef int (*ECDH_compute_key_func_t)(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, ++ void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); ++typedef int (*DH_set_length_func_t)(DH *dh, long length); ++typedef int (*DH_generate_key_func_t)(DH *dh); ++typedef BIGNUM *(*DH_get0_priv_key_func_t)(const DH *dh); ++typedef BIGNUM *(*DH_get0_pub_key_func_t)(const DH *dh); ++typedef int (*EC_GROUP_get_curve_GFp_func_t)(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); ++typedef EC_POINT *(*EC_GROUP_get0_generator_func_t)(const EC_GROUP *group); ++typedef int (*EC_POINT_get_affine_coordinates_GFp_func_t)( ++ const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); ++typedef int (*EC_GROUP_get_order_func_t)(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); ++typedef int (*EC_GROUP_get_cofactor_func_t)(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); ++typedef EC_POINT *(*EC_KEY_get0_public_key_func_t)(const EC_KEY *key); ++typedef BIGNUM *(*EC_KEY_get0_private_key_func_t)(const EC_KEY *key); ++typedef int (*BN_set_word_func_t)(BIGNUM *a, BN_ULONG w); ++typedef EC_GROUP *(*EC_GROUP_new_curve_GFp_func_t)(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); ++typedef int (*EC_GROUP_set_generator_func_t)( ++ EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); ++typedef void (*BN_CTX_free_func_t)(BN_CTX *ctx); ++typedef int (*EC_KEY_generate_key_func_t)(EC_KEY *eckey); ++typedef RSA *(*EVP_PKEY_get1_RSA_func_t)(EVP_PKEY *pkey); ++typedef BIGNUM *(*BN_dup_func_t)(const BIGNUM *a); ++typedef BN_CTX *(*BN_CTX_new_func_t)(void); ++typedef int (*EVP_PKEY_assign_func_t)(EVP_PKEY *pkey, int type, void *key); ++typedef int (*BN_bn2bin_func_t)(const BIGNUM *a, unsigned char *to); ++typedef const BIGNUM *(*RSA_get0_n_func_t)(const RSA *r); ++typedef const BIGNUM *(*RSA_get0_e_func_t)(const RSA *r); ++typedef const BIGNUM *(*RSA_get0_d_func_t)(const RSA *r); ++typedef const BIGNUM *(*RSA_get0_p_func_t)(const RSA *r); ++typedef const BIGNUM *(*RSA_get0_q_func_t)(const RSA *r); ++typedef const BIGNUM *(*RSA_get0_dmp1_func_t)(const RSA *r); ++typedef const BIGNUM *(*RSA_get0_dmq1_func_t)(const RSA *r); ++typedef const BIGNUM *(*RSA_get0_iqmp_func_t)(const RSA *r); ++typedef int (*EVP_PKEY_get_size_func_t)(const EVP_PKEY *pkey); ++typedef int (*RSA_pkey_ctx_ctrl_func_t)(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2); ++typedef int (*EVP_PKEY_CTX_ctrl_func_t)(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2); ++typedef int (*BN_num_bits_func_t)(const BIGNUM *a); ++typedef int (*ERR_GET_LIB_func_t)(unsigned long errcode); ++typedef int (*ERR_GET_REASON_func_t)(unsigned long errcode); ++typedef void (*BN_clear_free_func_t)(BIGNUM *a); ++typedef EVP_MD *(*EVP_sm3_func_t)(void); ++typedef int (*EVP_PKEY_CTX_set1_id_func_t)(EVP_PKEY_CTX *ctx, const void *id, int len); ++typedef void (*EVP_MD_CTX_set_pkey_ctx_func_t)(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); ++typedef int (*EVP_DigestSignInit_func_t)( ++ EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); ++typedef int (*EVP_DigestVerifyInit_func_t)( ++ EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); ++typedef int (*EVP_DigestSignUpdate_func_t)(EVP_MD_CTX *ctx, const void *data, size_t dsize); ++typedef int (*EVP_DigestVerifyUpdate_func_t)(EVP_MD_CTX *ctx, const void *data, size_t dsize); ++typedef int (*EVP_DigestSignFinal_func_t)(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen); ++typedef int (*EVP_DigestVerifyFinal_func_t)(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen); ++typedef EC_KEY *(*EC_KEY_new_by_curve_name_func_t)(int nid); ++typedef int (*EC_POINT_mul_func_t)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, ++ const BIGNUM *p_scalar, BN_CTX *ctx); ++typedef int (*EVP_PKEY_set_alias_type_func_t)(EVP_PKEY *pkey, int type); ++ ++static void *_lib_handle; ++static int _sslVersion = 0; ++const int V1 = 1; ++const int V3 = 3; ++const char *OPENSSL_VERSION_1_1 = "OpenSSL 1.1."; ++const char *OPENSSL_VERSION_3_X = "OpenSSL 3."; ++const char *OPENSSL_ENGINES_VERSION_1_1 = "/usr/local/lib/engines-1."; ++const char *OPENSSL_ENGINES_VERSION_3_X = "/usr/local/lib/engines-3."; ++ ++static OpenSSL_version_func_t _OpenSSL_version; ++static RSA_new_method_func_t _RSA_new_method; ++static RSA_generate_key_ex_func_t _RSA_generate_key_ex; ++static RSA_free_func_t _RSA_free; ++static OPENSSL_init_ssl_func_t _OPENSSL_init_ssl; ++static ERR_load_BIO_strings_func_t _ERR_load_BIO_strings; ++static OPENSSL_init_crypto_func_t _OPENSSL_init_crypto; ++static ENGINE_free_func_t _ENGINE_free; ++static ENGINE_by_id_func_t _ENGINE_by_id; ++static EVP_get_digestbyname_func_t _EVP_get_digestbyname; ++static EVP_PKEY_CTX_free_func_t _EVP_PKEY_CTX_free; ++static EVP_PKEY_CTX_set_rsa_padding_func_t _EVP_PKEY_CTX_set_rsa_padding; ++static EVP_PKEY_CTX_set_signature_md_func_t _EVP_PKEY_CTX_set_signature_md; ++static EVP_PKEY_CTX_new_func_t _EVP_PKEY_CTX_new; ++static EVP_PKEY_sign_init_func_t _EVP_PKEY_sign_init; ++static EVP_PKEY_sign_func_t _EVP_PKEY_sign; ++static EVP_PKEY_verify_init_func_t _EVP_PKEY_verify_init; ++static EVP_PKEY_verify_func_t _EVP_PKEY_verify; ++static EVP_PKEY_CTX_set_rsa_mgf1_md_func_t _EVP_PKEY_CTX_set_rsa_mgf1_md; ++static EVP_PKEY_CTX_set_rsa_pss_saltlen_func_t _EVP_PKEY_CTX_set_rsa_pss_saltlen; ++static EVP_PKEY_size_func_t _EVP_PKEY_size; ++static EVP_get_cipherbyname_func_t _EVP_get_cipherbyname; ++static EVP_CIPHER_CTX_new_func_t _EVP_CIPHER_CTX_new; ++static EVP_CipherInit_ex_func_t _EVP_CipherInit_ex; ++static EVP_CIPHER_CTX_set_padding_func_t _EVP_CIPHER_CTX_set_padding; ++static EVP_CIPHER_CTX_free_func_t _EVP_CIPHER_CTX_free; ++static EVP_CipherUpdate_func_t _EVP_CipherUpdate; ++static EVP_CipherFinal_ex_func_t _EVP_CipherFinal_ex; ++static EVP_CIPHER_CTX_ctrl_func_t _EVP_CIPHER_CTX_ctrl; ++static BN_new_func_t _BN_new; ++static BN_bin2bn_func_t _BN_bin2bn; ++static BN_free_func_t _BN_free; ++static EVP_PKEY_CTX_set0_rsa_oaep_label_func_t _EVP_PKEY_CTX_set0_rsa_oaep_label; ++static EVP_PKEY_CTX_set_rsa_oaep_md_func_t _EVP_PKEY_CTX_set_rsa_oaep_md; ++static EVP_PKEY_new_func_t _EVP_PKEY_new; ++static RSA_set0_key_func_t _RSA_set0_key; ++static RSA_set0_factors_func_t _RSA_set0_factors; ++static RSA_set0_crt_params_func_t _RSA_set0_crt_params; ++static EVP_PKEY_free_func_t _EVP_PKEY_free; ++static RSA_private_encrypt_func_t _RSA_private_encrypt; ++static RSA_private_decrypt_func_t _RSA_private_decrypt; ++static RSA_public_encrypt_func_t _RSA_public_encrypt; ++static RSA_public_decrypt_func_t _RSA_public_decrypt; ++static EVP_PKEY_encrypt_init_func_t _EVP_PKEY_encrypt_init; ++static EVP_PKEY_encrypt_func_t _EVP_PKEY_encrypt; ++static EVP_PKEY_decrypt_init_func_t _EVP_PKEY_decrypt_init; ++static EVP_PKEY_decrypt_func_t _EVP_PKEY_decrypt; ++static EVP_MD_CTX_new_func_t _EVP_MD_CTX_new; ++static EVP_DigestInit_ex_func_t _EVP_DigestInit_ex; ++static EVP_MD_CTX_free_func_t _EVP_MD_CTX_free; ++static EVP_DigestUpdate_func_t _EVP_DigestUpdate; ++static EVP_DigestFinal_ex_func_t _EVP_DigestFinal_ex; ++static EVP_MD_CTX_copy_ex_func_t _EVP_MD_CTX_copy_ex; ++static ERR_get_error_line_data_func_t _ERR_get_error_line_data; ++static ERR_error_string_n_func_t _ERR_error_string_n; ++static ERR_clear_error_func_t _ERR_clear_error; ++static HMAC_CTX_new_func_t _HMAC_CTX_new; ++static HMAC_Init_ex_func_t _HMAC_Init_ex; ++static HMAC_CTX_free_func_t _HMAC_CTX_free; ++static HMAC_Update_func_t _HMAC_Update; ++static HMAC_Final_func_t _HMAC_Final; ++static DH_new_method_func_t _DH_new_method; ++static DH_set0_pqg_func_t _DH_set0_pqg; ++static DH_set0_key_func_t _DH_set0_key; ++static DH_compute_key_func_t _DH_compute_key; ++static DH_free_func_t _DH_free; ++static EC_POINT_free_func_t _EC_POINT_free; ++static EC_KEY_free_func_t _EC_KEY_free; ++static EC_GROUP_free_func_t _EC_GROUP_free; ++static OBJ_sn2nid_func_t _OBJ_sn2nid; ++static EC_GROUP_new_by_curve_name_func_t _EC_GROUP_new_by_curve_name; ++static EC_KEY_new_func_t _EC_KEY_new; ++static EC_KEY_set_group_func_t _EC_KEY_set_group; ++static EC_POINT_new_func_t _EC_POINT_new; ++static EC_POINT_set_affine_coordinates_GFp_func_t _EC_POINT_set_affine_coordinates_GFp; ++static EC_KEY_set_public_key_func_t _EC_KEY_set_public_key; ++static EC_KEY_set_private_key_func_t _EC_KEY_set_private_key; ++static EC_GROUP_get_degree_func_t _EC_GROUP_get_degree; ++static ECDH_compute_key_func_t _ECDH_compute_key; ++static DH_set_length_func_t _DH_set_length; ++static DH_generate_key_func_t _DH_generate_key; ++static DH_get0_priv_key_func_t _DH_get0_priv_key; ++static DH_get0_pub_key_func_t _DH_get0_pub_key; ++static EC_GROUP_get_curve_GFp_func_t _EC_GROUP_get_curve_GFp; ++static EC_GROUP_get0_generator_func_t _EC_GROUP_get0_generator; ++static EC_POINT_get_affine_coordinates_GFp_func_t _EC_POINT_get_affine_coordinates_GFp; ++static EC_GROUP_get_order_func_t _EC_GROUP_get_order; ++static EC_GROUP_get_cofactor_func_t _EC_GROUP_get_cofactor; ++static EC_KEY_get0_public_key_func_t _EC_KEY_get0_public_key; ++static EC_KEY_get0_private_key_func_t _EC_KEY_get0_private_key; ++static BN_set_word_func_t _BN_set_word; ++static EC_GROUP_new_curve_GFp_func_t _EC_GROUP_new_curve_GFp; ++static EC_GROUP_set_generator_func_t _EC_GROUP_set_generator; ++static BN_CTX_free_func_t _BN_CTX_free; ++static EC_KEY_generate_key_func_t _EC_KEY_generate_key; ++static EVP_PKEY_get1_RSA_func_t _EVP_PKEY_get1_RSA; ++static BN_dup_func_t _BN_dup; ++static BN_CTX_new_func_t _BN_CTX_new; ++static EVP_PKEY_assign_func_t _EVP_PKEY_assign; ++static BN_bn2bin_func_t _BN_bn2bin; ++static RSA_get0_n_func_t _RSA_get0_n; ++static RSA_get0_e_func_t _RSA_get0_e; ++static RSA_get0_d_func_t _RSA_get0_d; ++static RSA_get0_p_func_t _RSA_get0_p; ++static RSA_get0_q_func_t _RSA_get0_q; ++static RSA_get0_dmp1_func_t _RSA_get0_dmp1; ++static RSA_get0_dmq1_func_t _RSA_get0_dmq1; ++static RSA_get0_iqmp_func_t _RSA_get0_iqmp; ++static EVP_PKEY_get_size_func_t _EVP_PKEY_get_size; ++static RSA_pkey_ctx_ctrl_func_t _RSA_pkey_ctx_ctrl; ++static EVP_PKEY_CTX_ctrl_func_t _EVP_PKEY_CTX_ctrl; ++static BN_num_bits_func_t _BN_num_bits; ++static ERR_GET_LIB_func_t _ERR_GET_LIB; ++static ERR_GET_REASON_func_t _ERR_GET_REASON; ++static BN_clear_free_func_t _BN_clear_free; ++static EVP_sm3_func_t _EVP_sm3; ++static EVP_PKEY_CTX_set1_id_func_t _EVP_PKEY_CTX_set1_id; ++static EVP_MD_CTX_set_pkey_ctx_func_t _EVP_MD_CTX_set_pkey_ctx; ++static EVP_DigestSignInit_func_t _EVP_DigestSignInit; ++static EVP_DigestVerifyInit_func_t _EVP_DigestVerifyInit; ++static EVP_DigestSignUpdate_func_t _EVP_DigestSignUpdate; ++static EVP_DigestVerifyUpdate_func_t _EVP_DigestVerifyUpdate; ++static EVP_DigestSignFinal_func_t _EVP_DigestSignFinal; ++static EVP_DigestVerifyFinal_func_t _EVP_DigestVerifyFinal; ++static EC_KEY_new_by_curve_name_func_t _EC_KEY_new_by_curve_name; ++static EC_POINT_mul_func_t _EC_POINT_mul; ++static EVP_PKEY_set_alias_type_func_t _EVP_PKEY_set_alias_type; ++ ++const int COMMON_FUNC_START_INDEX = 0; ++const int COMMON_FUNC_END_INDEX = 111; ++const int V1_FUNC_START_INDEX = 112; ++const int V1_FUNC_END_INDEX = 113; ++const int V3_FUNC_START_INDEX = 114; ++const int V3_FUNC_END_INDEX = 123; ++ ++const char *SSL_UTILS_OpenSSL_version(int t) ++{ ++ return (*_OpenSSL_version)(t); ++} ++const BIGNUM *SSL_UTILS_RSA_get0_n(const RSA *r) ++{ ++ return (*_RSA_get0_n)(r); ++} ++ ++const BIGNUM *SSL_UTILS_RSA_get0_e(const RSA *r) ++{ ++ return (*_RSA_get0_e)(r); ++} ++ ++const BIGNUM *SSL_UTILS_RSA_get0_d(const RSA *r) ++{ ++ return (*_RSA_get0_d)(r); ++} ++ ++const BIGNUM *SSL_UTILS_RSA_get0_p(const RSA *r) ++{ ++ return (*_RSA_get0_p)(r); ++} ++ ++const BIGNUM *SSL_UTILS_RSA_get0_q(const RSA *r) ++{ ++ return (*_RSA_get0_q)(r); ++} ++ ++const BIGNUM *SSL_UTILS_RSA_get0_dmp1(const RSA *r) ++{ ++ return (*_RSA_get0_dmp1)(r); ++} ++ ++const BIGNUM *SSL_UTILS_RSA_get0_dmq1(const RSA *r) ++{ ++ return (*_RSA_get0_dmq1)(r); ++} ++ ++const BIGNUM *SSL_UTILS_RSA_get0_iqmp(const RSA *r) ++{ ++ return (*_RSA_get0_iqmp)(r); ++} ++ ++RSA *SSL_UTILS_RSA_new_method(ENGINE *engine) ++{ ++ return (*_RSA_new_method)(engine); ++} ++ ++int SSL_UTILS_RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) ++{ ++ return (*_RSA_generate_key_ex)(rsa, bits, e_value, cb); ++} ++ ++void SSL_UTILS_RSA_free(RSA *rsa) ++{ ++ (*_RSA_free)(rsa); ++} ++ ++int SSL_UTILS_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) ++{ ++ return (*_OPENSSL_init_ssl)(opts, settings); ++} ++ ++int SSL_UTILS_ERR_load_BIO_strings() ++{ ++ return (*_ERR_load_BIO_strings)(); ++} ++ ++int SSL_UTILS_OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) ++{ ++ return (*_OPENSSL_init_crypto)(opts, settings); ++} ++ ++int SSL_UTILS_ENGINE_free(ENGINE *e) ++{ ++ return (*_ENGINE_free)(e); ++} ++ ++ENGINE *SSL_UTILS_ENGINE_by_id(const char *id) ++{ ++ return (*_ENGINE_by_id)(id); ++} ++ ++EVP_MD *SSL_UTILS_EVP_get_digestbyname(const char *name) ++{ ++ return (*_EVP_get_digestbyname)(name); ++} ++ ++void SSL_UTILS_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) ++{ ++ (*_EVP_PKEY_CTX_free)(ctx); ++} ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode) ++{ ++ // EVP_PKEY_CTX_set_rsa_padding is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ KAE_TRACE("SSL_UTILS_EVP_PKEY_CTX_set_rsa_padding, openssl version is 1"); ++ return (*_RSA_pkey_ctx_ctrl)(ctx, -1, SSL1_EVP_PKEY_CTRL_RSA_PADDING, pad_mode, NULL); ++ } ++ return (*_EVP_PKEY_CTX_set_rsa_padding)(ctx, pad_mode); ++} ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) ++{ ++ // EVP_PKEY_CTX_set_signature_md is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (*_EVP_PKEY_CTX_ctrl)(ctx, -1, SSL1_EVP_PKEY_OP_TYPE_SIG, SSL1_EVP_PKEY_CTRL_MD, 0, (void *)(md)); ++ } ++ return (*_EVP_PKEY_CTX_set_signature_md)(ctx, md); ++} ++ ++EVP_PKEY_CTX *SSL_UTILS_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) ++{ ++ return (*_EVP_PKEY_CTX_new)(pkey, e); ++} ++ ++int SSL_UTILS_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) ++{ ++ return (*_EVP_PKEY_sign_init)(ctx); ++} ++ ++int SSL_UTILS_EVP_PKEY_sign( ++ EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) ++{ ++ return (*_EVP_PKEY_sign)(ctx, sig, siglen, tbs, tbslen); ++} ++ ++int SSL_UTILS_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) ++{ ++ return (*_EVP_PKEY_verify_init)(ctx); ++} ++ ++int SSL_UTILS_EVP_PKEY_verify( ++ EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) ++{ ++ return (*_EVP_PKEY_verify)(ctx, sig, siglen, tbs, tbslen); ++} ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) ++{ ++ // RSA_pkey_ctx_ctrl is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (*_RSA_pkey_ctx_ctrl)(ctx, ++ SSL1_EVP_PKEY_OP_TYPE_SIG | SSL1_EVP_PKEY_OP_TYPE_CRYPT, ++ SSL1_EVP_PKEY_CTRL_RSA_MGF1_MD, ++ 0, ++ (void *)(md)); ++ } ++ return (*_EVP_PKEY_CTX_set_rsa_mgf1_md)(ctx, md); ++} ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len) ++{ ++ // EVP_PKEY_CTX_set_rsa_pss_saltlen is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (*_RSA_pkey_ctx_ctrl)( ++ ctx, (SSL1_EVP_PKEY_OP_SIGN | SSL1_EVP_PKEY_OP_VERIFY), SSL1_EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL); ++ } ++ return (*_EVP_PKEY_CTX_set_rsa_pss_saltlen)(ctx, len); ++} ++ ++int SSL_UTILS_EVP_PKEY_size(const EVP_PKEY *pkey) ++{ ++ // EVP_PKEY_size is macro in openssl 3 ++ if (get_sslVersion() == V3) { ++ return (*_EVP_PKEY_get_size)(pkey); ++ } ++ return (*_EVP_PKEY_size)(pkey); ++} ++ ++EVP_CIPHER *SSL_UTILS_EVP_get_cipherbyname(const char *name) ++{ ++ return (*_EVP_get_cipherbyname)(name); ++} ++ ++EVP_CIPHER_CTX *SSL_UTILS_EVP_CIPHER_CTX_new(void) ++{ ++ return (*_EVP_CIPHER_CTX_new)(); ++} ++ ++int SSL_UTILS_EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, ++ const unsigned char *iv, int enc) ++{ ++ return (*_EVP_CipherInit_ex)(ctx, type, impl, key, iv, enc); ++} ++ ++int SSL_UTILS_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) ++{ ++ return (*_EVP_CIPHER_CTX_set_padding)(ctx, pad); ++} ++ ++void SSL_UTILS_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) ++{ ++ (*_EVP_CIPHER_CTX_free)(ctx); ++} ++ ++int SSL_UTILS_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) ++{ ++ return (*_EVP_CipherUpdate)(ctx, out, outl, in, inl); ++} ++ ++int SSL_UTILS_EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) ++{ ++ return (*_EVP_CipherFinal_ex)(ctx, out, outl); ++} ++int SSL_UTILS_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) ++{ ++ return (*_EVP_CIPHER_CTX_ctrl)(ctx, type, arg, ptr); ++} ++BIGNUM *SSL_UTILS_BN_new(void) ++{ ++ return (*_BN_new)(); ++} ++BIGNUM *SSL_UTILS_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) ++{ ++ return (*_BN_bin2bn)(s, len, ret); ++} ++void SSL_UTILS_BN_free(BIGNUM *a) ++{ ++ (*_BN_free)(a); ++} ++ ++int SSL_UTILS_EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen) ++{ ++ // EVP_PKEY_CTX_set0_rsa_oaep_label is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (*_EVP_PKEY_CTX_ctrl)(ctx, ++ SSL1_EVP_PKEY_RSA, ++ SSL1_EVP_PKEY_OP_TYPE_CRYPT, ++ SSL1_EVP_PKEY_CTRL_RSA_OAEP_LABEL, ++ llen, ++ (void *)(label)); ++ } ++ return (*_EVP_PKEY_CTX_set0_rsa_oaep_label)(ctx, label, llen); ++} ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) ++{ ++ // EVP_PKEY_CTX_set_rsa_oaep_md is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (*_EVP_PKEY_CTX_ctrl)( ++ ctx, SSL1_EVP_PKEY_RSA, SSL1_EVP_PKEY_OP_TYPE_CRYPT, SSL1_EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md)); ++ } ++ return (*_EVP_PKEY_CTX_set_rsa_oaep_md)(ctx, md); ++} ++EVP_PKEY *SSL_UTILS_EVP_PKEY_new(void) ++{ ++ return (*_EVP_PKEY_new)(); ++} ++int SSL_UTILS_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) ++{ ++ return (*_RSA_set0_key)(r, n, e, d); ++} ++int SSL_UTILS_RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) ++{ ++ return (*_RSA_set0_factors)(r, p, q); ++} ++int SSL_UTILS_RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) ++{ ++ return (*_RSA_set0_crt_params)(r, dmp1, dmq1, iqmp); ++} ++void SSL_UTILS_EVP_PKEY_free(EVP_PKEY *x) ++{ ++ (*_EVP_PKEY_free)(x); ++} ++int SSL_UTILS_RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) ++{ ++ return (*_RSA_private_encrypt)(flen, from, to, rsa, padding); ++} ++int SSL_UTILS_RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) ++{ ++ return (*_RSA_private_decrypt)(flen, from, to, rsa, padding); ++} ++int SSL_UTILS_RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) ++{ ++ return (*_RSA_public_encrypt)(flen, from, to, rsa, padding); ++} ++int SSL_UTILS_RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) ++{ ++ return (*_RSA_public_decrypt)(flen, from, to, rsa, padding); ++} ++int SSL_UTILS_EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) ++{ ++ return (*_EVP_PKEY_encrypt_init)(ctx); ++} ++int SSL_UTILS_EVP_PKEY_encrypt( ++ EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen) ++{ ++ return (*_EVP_PKEY_encrypt)(ctx, out, outlen, in, inlen); ++} ++int SSL_UTILS_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) ++{ ++ return (*_EVP_PKEY_decrypt_init)(ctx); ++} ++int SSL_UTILS_EVP_PKEY_decrypt( ++ EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen) ++{ ++ return (*_EVP_PKEY_decrypt)(ctx, out, outlen, in, inlen); ++} ++EVP_MD_CTX *SSL_UTILS_EVP_MD_CTX_new(void) ++{ ++ return (*_EVP_MD_CTX_new)(); ++} ++int SSL_UTILS_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) ++{ ++ return (*_EVP_DigestInit_ex)(ctx, type, impl); ++} ++void SSL_UTILS_EVP_MD_CTX_free(EVP_MD_CTX *ctx) ++{ ++ return (*_EVP_MD_CTX_free)(ctx); ++} ++int SSL_UTILS_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) ++{ ++ return (*_EVP_DigestUpdate)(ctx, data, count); ++} ++int SSL_UTILS_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) ++{ ++ return (*_EVP_DigestFinal_ex)(ctx, md, size); ++} ++int SSL_UTILS_EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) ++{ ++ return (*_EVP_MD_CTX_copy_ex)(out, in); ++} ++unsigned long SSL_UTILS_ERR_get_error_line_data(const char **file, int *line, const char **data, int *flags) ++{ ++ return (*_ERR_get_error_line_data)(file, line, data, flags); ++} ++void SSL_UTILS_ERR_error_string_n(unsigned long e, char *buf, size_t len) ++{ ++ (*_ERR_error_string_n)(e, buf, len); ++} ++void SSL_UTILS_ERR_clear_error(void) ++{ ++ (*_ERR_clear_error)(); ++} ++HMAC_CTX *SSL_UTILS_HMAC_CTX_new(void) ++{ ++ return (*_HMAC_CTX_new)(); ++} ++int SSL_UTILS_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) ++{ ++ return (*_HMAC_Init_ex)(ctx, key, len, md, impl); ++} ++void SSL_UTILS_HMAC_CTX_free(HMAC_CTX *ctx) ++{ ++ (*_HMAC_CTX_free)(ctx); ++} ++int SSL_UTILS_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) ++{ ++ return (*_HMAC_Update)(ctx, data, len); ++} ++int SSL_UTILS_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) ++{ ++ return (*_HMAC_Final)(ctx, md, len); ++} ++DH *SSL_UTILS_DH_new_method(ENGINE *engine) ++{ ++ return (*_DH_new_method)(engine); ++} ++int SSL_UTILS_DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) ++{ ++ return (*_DH_set0_pqg)(dh, p, q, g); ++} ++int SSL_UTILS_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) ++{ ++ return (*_DH_set0_key)(dh, pub_key, priv_key); ++} ++int SSL_UTILS_DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) ++{ ++ return (*_DH_compute_key)(key, pub_key, dh); ++} ++void SSL_UTILS_DH_free(DH *r) ++{ ++ (*_DH_free)(r); ++} ++void SSL_UTILS_EC_POINT_free(EC_POINT *point) ++{ ++ (*_EC_POINT_free)(point); ++} ++void SSL_UTILS_EC_KEY_free(EC_KEY *r) ++{ ++ (*_EC_KEY_free)(r); ++} ++void SSL_UTILS_EC_GROUP_free(EC_GROUP *group) ++{ ++ (*_EC_GROUP_free)(group); ++} ++int SSL_UTILS_OBJ_sn2nid(const char *s) ++{ ++ return (*_OBJ_sn2nid)(s); ++} ++EC_GROUP *SSL_UTILS_EC_GROUP_new_by_curve_name(int nid) ++{ ++ return (*_EC_GROUP_new_by_curve_name)(nid); ++} ++EC_KEY *SSL_UTILS_EC_KEY_new(void) ++{ ++ return (*_EC_KEY_new)(); ++} ++int SSL_UTILS_EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) ++{ ++ return (*_EC_KEY_set_group)(key, group); ++} ++EC_POINT *SSL_UTILS_EC_POINT_new(const EC_GROUP *group) ++{ ++ return (*_EC_POINT_new)(group); ++} ++int SSL_UTILS_EC_POINT_set_affine_coordinates_GFp( ++ const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) ++{ ++ return (*_EC_POINT_set_affine_coordinates_GFp)(group, point, x, y, ctx); ++} ++int SSL_UTILS_EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) ++{ ++ return (*_EC_KEY_set_public_key)(key, pub_key); ++} ++int SSL_UTILS_EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) ++{ ++ return (*_EC_KEY_set_private_key)(key, priv_key); ++} ++int SSL_UTILS_EC_GROUP_get_degree(const EC_GROUP *group) ++{ ++ return (*_EC_GROUP_get_degree)(group); ++} ++ ++int SSL_UTILS_ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, ++ void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)) ++{ ++ return (*_ECDH_compute_key)(out, outlen, pub_key, eckey, KDF); ++} ++int SSL_UTILS_DH_set_length(DH *dh, long length) ++{ ++ return (*_DH_set_length)(dh, length); ++} ++int SSL_UTILS_DH_generate_key(DH *dh) ++{ ++ return (*_DH_generate_key)(dh); ++} ++const BIGNUM *SSL_UTILS_DH_get0_priv_key(const DH *dh) ++{ ++ return (*_DH_get0_priv_key)(dh); ++} ++const BIGNUM *SSL_UTILS_DH_get0_pub_key(const DH *dh) ++{ ++ return (*_DH_get0_pub_key)(dh); ++} ++int SSL_UTILS_EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) ++{ ++ return (*_EC_GROUP_get_curve_GFp)(group, p, a, b, ctx); ++} ++const EC_POINT *SSL_UTILS_EC_GROUP_get0_generator(const EC_GROUP *group) ++{ ++ return (*_EC_GROUP_get0_generator)(group); ++} ++int SSL_UTILS_EC_POINT_get_affine_coordinates_GFp( ++ const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx) ++{ ++ return (*_EC_POINT_get_affine_coordinates_GFp)(group, point, x, y, ctx); ++} ++int SSL_UTILS_EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) ++{ ++ return (*_EC_GROUP_get_order)(group, order, ctx); ++} ++int SSL_UTILS_EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) ++{ ++ return (*_EC_GROUP_get_cofactor)(group, cofactor, ctx); ++} ++const EC_POINT *SSL_UTILS_EC_KEY_get0_public_key(const EC_KEY *key) ++{ ++ return (*_EC_KEY_get0_public_key)(key); ++} ++const BIGNUM *SSL_UTILS_EC_KEY_get0_private_key(const EC_KEY *key) ++{ ++ return (*_EC_KEY_get0_private_key)(key); ++} ++int SSL_UTILS_BN_set_word(BIGNUM *a, BN_ULONG w) ++{ ++ return (*_BN_set_word)(a, w); ++} ++EC_GROUP *SSL_UTILS_EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) ++{ ++ return (*_EC_GROUP_new_curve_GFp)(p, a, b, ctx); ++} ++int SSL_UTILS_EC_GROUP_set_generator( ++ EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor) ++{ ++ return (*_EC_GROUP_set_generator)(group, generator, order, cofactor); ++} ++void SSL_UTILS_BN_CTX_free(BN_CTX *ctx) ++{ ++ (*_BN_CTX_free)(ctx); ++} ++int SSL_UTILS_EC_KEY_generate_key(EC_KEY *eckey) ++{ ++ return (*_EC_KEY_generate_key)(eckey); ++} ++RSA *SSL_UTILS_EVP_PKEY_get1_RSA(EVP_PKEY *pkey) ++{ ++ return (*_EVP_PKEY_get1_RSA)(pkey); ++} ++BIGNUM *SSL_UTILS_BN_dup(const BIGNUM *a) ++{ ++ return (*_BN_dup)(a); ++} ++BN_CTX *SSL_UTILS_BN_CTX_new(void) ++{ ++ return (*_BN_CTX_new)(); ++} ++int SSL_UTILS_EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) ++{ ++ return (*_EVP_PKEY_assign)(pkey, type, key); ++} ++int SSL_UTILS_BN_bn2bin(const BIGNUM *a, unsigned char *to) ++{ ++ return (*_BN_bn2bin)(a, to); ++} ++int SSL_UTILS_BN_num_bits(const BIGNUM *a) ++{ ++ return (*_BN_num_bits)(a); ++} ++ ++int SSL_UTILS_ERR_GET_REASON(unsigned long errcode) ++{ ++ // ERR_GET_REASON is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (int)((errcode)&0xFFFL); ++ } ++ // ERR_GET_REASON is static in openssl 3. Here is Implementation below. ++ if (SSL3_ERR_SYSTEM_ERROR(errcode)) ++ return errcode & SSL3_ERR_SYSTEM_MASK; ++ return errcode & SSL3_ERR_REASON_MASK; ++} ++ ++int SSL_UTILS_ERR_GET_FUNC(unsigned long errcode) ++{ ++ // ERR_GET_FUNC is a macro in openssl 1,and removed since openssl 3. ++ return (int)(((errcode) >> 12L) & 0xFFFL); ++} ++ ++int SSL_UTILS_ERR_GET_LIB(unsigned long errcode) ++{ ++ // ERR_GET_LIB is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (int)(((errcode) >> 24L) & 0x0FFL); ++ } ++ // ERR_GET_REASON is static in openssl 3. Here is Implementation below. ++ if (SSL3_ERR_SYSTEM_ERROR(errcode)) ++ return SSL3_ERR_LIB_SYS; ++ return (errcode >> SSL3_ERR_LIB_OFFSET) & SSL3_ERR_LIB_MASK; ++} ++ ++void SSL_UTILS_BN_clear_free(BIGNUM *a) ++{ ++ (*_BN_clear_free)(a); ++} ++ ++EVP_MD *SSL_UTILS_EVP_sm3(void) ++{ ++ return (*_EVP_sm3)(); ++} ++ ++int SSL_UTILS_EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, const void *id, int len) ++{ ++ // EVP_PKEY_CTX_set1_id is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (*_EVP_PKEY_CTX_ctrl)(ctx, -1, -1, SSL1_EVP_PKEY_CTRL_SET1_ID, (int)len, (void *)(id)); ++ } ++ return (*_EVP_PKEY_CTX_set1_id)(ctx, id, len); ++} ++ ++void SSL_UTILS_EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) ++{ ++ (*_EVP_MD_CTX_set_pkey_ctx)(ctx, pctx); ++} ++ ++int SSL_UTILS_EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) ++{ ++ return (*_EVP_DigestSignInit)(ctx, pctx, type, e, pkey); ++} ++ ++int SSL_UTILS_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) ++{ ++ return (*_EVP_DigestVerifyInit)(ctx, pctx, type, e, pkey); ++} ++ ++int SSL_UTILS_EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) ++{ ++ // EVP_DigestSignUpdate is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (*_EVP_DigestUpdate)(ctx, data, dsize); ++ } ++ return (*_EVP_DigestSignUpdate)(ctx, data, dsize); ++} ++ ++int SSL_UTILS_EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) ++{ ++ // EVP_DigestVerifyUpdate is macro in openssl 1 ++ if (get_sslVersion() == V1) { ++ return (*_EVP_DigestUpdate)(ctx, data, dsize); ++ } ++ return (*_EVP_DigestVerifyUpdate)(ctx, data, dsize); ++} ++ ++int SSL_UTILS_EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen) ++{ ++ return (*_EVP_DigestSignFinal)(ctx, sigret, siglen); ++} ++ ++int SSL_UTILS_EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen) ++{ ++ return (*_EVP_DigestVerifyFinal)(ctx, sig, siglen); ++} ++ ++EC_KEY *SSL_UTILS_EC_KEY_new_by_curve_name(int nid) ++{ ++ return (*_EC_KEY_new_by_curve_name)(nid); ++} ++ ++int SSL_UTILS_EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, ++ const BIGNUM *p_scalar, BN_CTX *ctx) ++{ ++ return (*_EC_POINT_mul)(group, r, g_scalar, point, p_scalar, ctx); ++} ++ ++int SSL_UTILS_EVP_PKEY_set_alias_type(JNIEnv *env, EVP_PKEY *pkey, int type) ++{ ++ // EVP_PKEY_set_alias_type is removed from openssl 3, it should be supported later. ++ if (get_sslVersion() == V3) { ++ KAE_TRACE("OpenSSL error,SM2 is not supported on openssl 3 yet."); ++ return 1; ++ } ++ return (*_EVP_PKEY_set_alias_type)(pkey, type); ++} ++ ++int SSL_UTILS_EVP_PKEY_assign_RSA(EVP_PKEY *pkey, void *key) ++{ ++ // change from macro, "EVP_PKEY_assign_RSA(pkey,rsa)" is same as EVP_PKEY_assign((pkey),EVP_PKEY_RSA, (rsa)) ++ return SSL_UTILS_EVP_PKEY_assign((pkey), EVP_PKEY_RSA, (char *)(key)); ++} ++ ++int SSL_UTILS_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, void *key) ++{ ++ // Changed from macro, "EVP_PKEY_assign_EC_KEY(pkey,eckey)" is "EVP_PKEY_assign((pkey),EVP_PKEY_EC, (char ++ // *)(eckey))" in openssl 1 and 3 ++ return SSL_UTILS_EVP_PKEY_assign((pkey), EVP_PKEY_EC, (key)); ++} ++ ++void SSL_UTILS_EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) ++{ ++ // changed from macro, "# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))" in openssl 1 and 3 ++ SSL_UTILS_EVP_MD_CTX_free(ctx); ++} ++ ++EVP_MD_CTX *SSL_UTILS_EVP_MD_CTX_create(void) ++{ ++ return SSL_UTILS_EVP_MD_CTX_new(); ++} ++ ++int SSL_UTILS_SSL_load_error_strings() ++{ ++ // Change from macro, SSL_load_error_strings is a macro in openssl 1 and 3. ++ return SSL_UTILS_OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); ++} ++ ++int SSL_UTILS_OpenSSL_add_all_algorithms() ++{ ++// Change from macro, OpenSSL_add_all_algorithms ia a macro, defined by OPENSSL_LOAD_CONF value. ++#ifdef OPENSSL_LOAD_CONF ++ return SSL_UTILS_OPENSSL_init_crypto( ++ OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); ++#else ++ return SSL_UTILS_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); ++#endif ++} ++ ++int SSL_UTILS_BN_num_bytes(const BIGNUM *a) ++{ ++ // Changed from macro, BN_num_bytes(bn) is ((BN_num_bits(bn)+7)/8); ++ return ((SSL_UTILS_BN_num_bits(a) + 7) / 8); ++} ++ ++const char * origin_func_name[] = { ++ "RSA_new_method", ++ "RSA_generate_key_ex", ++ "RSA_free", ++ "OPENSSL_init_ssl", ++ "ERR_load_BIO_strings", ++ "OPENSSL_init_crypto", ++ "ENGINE_free", ++ "ENGINE_by_id", ++ "EVP_get_digestbyname", ++ "EVP_PKEY_CTX_free", ++ "EVP_PKEY_CTX_new", ++ "EVP_PKEY_sign_init", ++ "EVP_PKEY_sign", ++ "EVP_PKEY_verify_init", ++ "EVP_PKEY_verify", ++ "EVP_get_cipherbyname", ++ "EVP_CIPHER_CTX_new", ++ "EVP_CipherInit_ex", ++ "EVP_CIPHER_CTX_set_padding", ++ "EVP_CIPHER_CTX_free", ++ "EVP_CipherUpdate", ++ "EVP_CipherFinal_ex", ++ "EVP_CIPHER_CTX_ctrl", ++ "BN_new", ++ "BN_bin2bn", ++ "BN_free", ++ "EVP_PKEY_new", ++ "RSA_set0_key", ++ "RSA_set0_factors", ++ "RSA_set0_crt_params", ++ "EVP_PKEY_free", ++ "RSA_private_encrypt", ++ "RSA_private_decrypt", ++ "RSA_public_encrypt", ++ "RSA_public_decrypt", ++ "EVP_PKEY_encrypt_init", ++ "EVP_PKEY_encrypt", ++ "EVP_PKEY_decrypt_init", ++ "EVP_PKEY_decrypt", ++ "EVP_MD_CTX_new", ++ "EVP_DigestInit_ex", ++ "EVP_MD_CTX_free", ++ "EVP_DigestUpdate", ++ "EVP_DigestFinal_ex", ++ "EVP_MD_CTX_copy_ex", ++ "ERR_get_error_line_data", ++ "ERR_error_string_n", ++ "ERR_clear_error", ++ "HMAC_CTX_new", ++ "HMAC_Init_ex", ++ "HMAC_CTX_free", ++ "HMAC_Update", ++ "HMAC_Final", ++ "DH_new_method", ++ "DH_set0_pqg", ++ "DH_set0_key", ++ "DH_compute_key", ++ "DH_free", ++ "EC_POINT_free", ++ "EC_KEY_free", ++ "EC_GROUP_free", ++ "OBJ_sn2nid", ++ "EC_GROUP_new_by_curve_name", ++ "EC_KEY_new", ++ "EC_KEY_set_group", ++ "EC_POINT_new", ++ "EC_POINT_set_affine_coordinates_GFp", ++ "EC_KEY_set_public_key", ++ "EC_KEY_set_private_key", ++ "EC_GROUP_get_degree", ++ "ECDH_compute_key", ++ "DH_set_length", ++ "DH_generate_key", ++ "DH_get0_priv_key", ++ "DH_get0_pub_key", ++ "EC_GROUP_get_curve_GFp", ++ "EC_GROUP_get0_generator", ++ "EC_POINT_get_affine_coordinates_GFp", ++ "EC_GROUP_get_order", ++ "EC_GROUP_get_cofactor", ++ "EC_KEY_get0_public_key", ++ "EC_KEY_get0_private_key", ++ "BN_set_word", ++ "EC_GROUP_new_curve_GFp", ++ "EC_GROUP_set_generator", ++ "BN_CTX_free", ++ "EC_KEY_generate_key", ++ "EVP_PKEY_get1_RSA", ++ "BN_dup", ++ "BN_CTX_new", ++ "EVP_PKEY_assign", ++ "BN_bn2bin", ++ "RSA_get0_n", ++ "RSA_get0_e", ++ "RSA_get0_d", ++ "RSA_get0_p", ++ "RSA_get0_q", ++ "RSA_get0_dmp1", ++ "RSA_get0_dmq1", ++ "RSA_get0_iqmp", ++ "RSA_pkey_ctx_ctrl", ++ "EVP_PKEY_CTX_ctrl", ++ "BN_num_bits", ++ "BN_clear_free", ++ "EVP_sm3", ++ "EVP_MD_CTX_set_pkey_ctx", ++ "EVP_DigestSignInit", ++ "EVP_DigestVerifyInit", ++ "EVP_DigestSignFinal", ++ "EVP_DigestVerifyFinal", ++ "EC_KEY_new_by_curve_name", ++ "EC_POINT_mul", ++ "EVP_PKEY_size", ++ "EVP_PKEY_set_alias_type", ++ "EVP_PKEY_get_size", ++ "EVP_PKEY_CTX_set0_rsa_oaep_label", ++ "EVP_PKEY_CTX_set_signature_md", ++ "EVP_PKEY_CTX_set_rsa_oaep_md", ++ "EVP_PKEY_CTX_set_rsa_mgf1_md", ++ "EVP_PKEY_CTX_set_rsa_pss_saltlen", ++ "EVP_PKEY_CTX_set_rsa_padding", ++ "EVP_PKEY_CTX_set1_id", ++ "EVP_DigestSignUpdate", ++ "EVP_DigestVerifyUpdate" ++}; ++ ++void ** kae_ssl_func[] = { ++ (void**)&_RSA_new_method, ++ (void**)&_RSA_generate_key_ex, ++ (void**)&_RSA_free, ++ (void**)&_OPENSSL_init_ssl, ++ (void**)&_ERR_load_BIO_strings, ++ (void**)&_OPENSSL_init_crypto, ++ (void**)&_ENGINE_free, ++ (void**)&_ENGINE_by_id, ++ (void**)&_EVP_get_digestbyname, ++ (void**)&_EVP_PKEY_CTX_free, ++ (void**)&_EVP_PKEY_CTX_new, ++ (void**)&_EVP_PKEY_sign_init, ++ (void**)&_EVP_PKEY_sign, ++ (void**)&_EVP_PKEY_verify_init, ++ (void**)&_EVP_PKEY_verify, ++ (void**)&_EVP_get_cipherbyname, ++ (void**)&_EVP_CIPHER_CTX_new, ++ (void**)&_EVP_CipherInit_ex, ++ (void**)&_EVP_CIPHER_CTX_set_padding, ++ (void**)&_EVP_CIPHER_CTX_free, ++ (void**)&_EVP_CipherUpdate, ++ (void**)&_EVP_CipherFinal_ex, ++ (void**)&_EVP_CIPHER_CTX_ctrl, ++ (void**)&_BN_new, ++ (void**)&_BN_bin2bn, ++ (void**)&_BN_free, ++ (void**)&_EVP_PKEY_new, ++ (void**)&_RSA_set0_key, ++ (void**)&_RSA_set0_factors, ++ (void**)&_RSA_set0_crt_params, ++ (void**)&_EVP_PKEY_free, ++ (void**)&_RSA_private_encrypt, ++ (void**)&_RSA_private_decrypt, ++ (void**)&_RSA_public_encrypt, ++ (void**)&_RSA_public_decrypt, ++ (void**)&_EVP_PKEY_encrypt_init, ++ (void**)&_EVP_PKEY_encrypt, ++ (void**)&_EVP_PKEY_decrypt_init, ++ (void**)&_EVP_PKEY_decrypt, ++ (void**)&_EVP_MD_CTX_new, ++ (void**)&_EVP_DigestInit_ex, ++ (void**)&_EVP_MD_CTX_free, ++ (void**)&_EVP_DigestUpdate, ++ (void**)&_EVP_DigestFinal_ex, ++ (void**)&_EVP_MD_CTX_copy_ex, ++ (void**)&_ERR_get_error_line_data, ++ (void**)&_ERR_error_string_n, ++ (void**)&_ERR_clear_error, ++ (void**)&_HMAC_CTX_new, ++ (void**)&_HMAC_Init_ex, ++ (void**)&_HMAC_CTX_free, ++ (void**)&_HMAC_Update, ++ (void**)&_HMAC_Final, ++ (void**)&_DH_new_method, ++ (void**)&_DH_set0_pqg, ++ (void**)&_DH_set0_key, ++ (void**)&_DH_compute_key, ++ (void**)&_DH_free, ++ (void**)&_EC_POINT_free, ++ (void**)&_EC_KEY_free, ++ (void**)&_EC_GROUP_free, ++ (void**)&_OBJ_sn2nid, ++ (void**)&_EC_GROUP_new_by_curve_name, ++ (void**)&_EC_KEY_new, ++ (void**)&_EC_KEY_set_group, ++ (void**)&_EC_POINT_new, ++ (void**)&_EC_POINT_set_affine_coordinates_GFp, ++ (void**)&_EC_KEY_set_public_key, ++ (void**)&_EC_KEY_set_private_key, ++ (void**)&_EC_GROUP_get_degree, ++ (void**)&_ECDH_compute_key, ++ (void**)&_DH_set_length, ++ (void**)&_DH_generate_key, ++ (void**)&_DH_get0_priv_key, ++ (void**)&_DH_get0_pub_key, ++ (void**)&_EC_GROUP_get_curve_GFp, ++ (void**)&_EC_GROUP_get0_generator, ++ (void**)&_EC_POINT_get_affine_coordinates_GFp, ++ (void**)&_EC_GROUP_get_order, ++ (void**)&_EC_GROUP_get_cofactor, ++ (void**)&_EC_KEY_get0_public_key, ++ (void**)&_EC_KEY_get0_private_key, ++ (void**)&_BN_set_word, ++ (void**)&_EC_GROUP_new_curve_GFp, ++ (void**)&_EC_GROUP_set_generator, ++ (void**)&_BN_CTX_free, ++ (void**)&_EC_KEY_generate_key, ++ (void**)&_EVP_PKEY_get1_RSA, ++ (void**)&_BN_dup, ++ (void**)&_BN_CTX_new, ++ (void**)&_EVP_PKEY_assign, ++ (void**)&_BN_bn2bin, ++ (void**)&_RSA_get0_n, ++ (void**)&_RSA_get0_e, ++ (void**)&_RSA_get0_d, ++ (void**)&_RSA_get0_p, ++ (void**)&_RSA_get0_q, ++ (void**)&_RSA_get0_dmp1, ++ (void**)&_RSA_get0_dmq1, ++ (void**)&_RSA_get0_iqmp, ++ (void**)&_RSA_pkey_ctx_ctrl, ++ (void**)&_EVP_PKEY_CTX_ctrl, ++ (void**)&_BN_num_bits, ++ (void**)&_BN_clear_free, ++ (void**)&_EVP_sm3, ++ (void**)&_EVP_MD_CTX_set_pkey_ctx, ++ (void**)&_EVP_DigestSignInit, ++ (void**)&_EVP_DigestVerifyInit, ++ (void**)&_EVP_DigestSignFinal, ++ (void**)&_EVP_DigestVerifyFinal, ++ (void**)&_EC_KEY_new_by_curve_name, ++ (void**)&_EC_POINT_mul, ++ (void**)&_EVP_PKEY_size, ++ (void**)&_EVP_PKEY_set_alias_type, ++ (void**)&_EVP_PKEY_get_size, ++ (void**)&_EVP_PKEY_CTX_set0_rsa_oaep_label, ++ (void**)&_EVP_PKEY_CTX_set_signature_md, ++ (void**)&_EVP_PKEY_CTX_set_rsa_oaep_md, ++ (void**)&_EVP_PKEY_CTX_set_rsa_mgf1_md, ++ (void**)&_EVP_PKEY_CTX_set_rsa_pss_saltlen, ++ (void**)&_EVP_PKEY_CTX_set_rsa_padding, ++ (void**)&_EVP_PKEY_CTX_set1_id, ++ (void**)&_EVP_DigestSignUpdate, ++ (void**)&_EVP_DigestVerifyUpdate ++}; ++ ++void SSL_UTILS_func_dl(JNIEnv *env) ++{ ++ for(int i = COMMON_FUNC_START_INDEX; i <= COMMON_FUNC_END_INDEX; i++){ ++ *kae_ssl_func[i] = dlsym(_lib_handle, origin_func_name[i]); ++ if (*kae_ssl_func[i] == NULL) { ++ dlclose(_lib_handle); ++ KAE_ThrowExceptionInInitializerError(env, "OpenSSL error while Openssl common function pointer assignment, nullpointer found."); ++ return; ++ } ++ } ++ ++ if (get_sslVersion() == V1) { ++ for(int i = V1_FUNC_START_INDEX; i <= V1_FUNC_END_INDEX; i++){ ++ *kae_ssl_func[i] = dlsym(_lib_handle, origin_func_name[i]); ++ if (*kae_ssl_func[i] == NULL) { ++ dlclose(_lib_handle); ++ KAE_ThrowExceptionInInitializerError(env, "OpenSSL error while Openssl 1 unique function pointer assignment, nullpointer found."); ++ return; ++ } ++ } ++ } ++ ++ if (get_sslVersion() == V3) { ++ for(int i = V3_FUNC_START_INDEX; i <= V3_FUNC_END_INDEX; i++){ ++ *kae_ssl_func[i] = dlsym(_lib_handle, origin_func_name[i]); ++ if (*kae_ssl_func[i] == NULL) { ++ dlclose(_lib_handle); ++ KAE_ThrowExceptionInInitializerError(env, "OpenSSL error while Openssl 3 unique function pointer assignment, nullpointer found."); ++ return; ++ } ++ } ++ } ++} ++ ++jboolean SSL_UTILS_func_ptr_init(JNIEnv *env, jint useOpensslVersion) ++{ ++ jboolean init_result = JNI_TRUE; ++ _lib_handle = open_ssl_lib(env, useOpensslVersion, &init_result); ++ if (!init_result) { ++ return init_result; ++ } ++ SSL_UTILS_func_dl(env); ++ return init_result; ++} ++ ++void *open_ssl_lib(JNIEnv *env, jint useOpensslVersion, jboolean *init_result) ++{ ++ // default priorly use openssl3 ++ _sslVersion = V3; ++ char *lib_name = "libssl.so.3"; ++ if (useOpensslVersion == 1) { ++ _sslVersion = V1; ++ lib_name = "libssl.so.1.1"; ++ } ++ void *res = NULL; ++ // if user changed kae.useOpensslVersion, check openSSL_Engine ++ if (useOpensslVersion != 0) { ++ // check engine with openssl version ++ check_openSSL_Engine(env, init_result, lib_name); ++ if (!*init_result) { ++ return res; ++ } ++ } ++ // set model RTLD_NOW | RTLD_GLOBAL Otherwise openssl3 env cannot get KAEEngine ++ res = dlopen(lib_name, RTLD_NOW | RTLD_GLOBAL); ++ // if useOpensslVersion is default 0, and dlopen openssl failed; re-attempting dlopen openssl1. ++ if (res == NULL && useOpensslVersion == 0) { ++ _sslVersion = V1; ++ lib_name = "libssl.so.1.1"; ++ check_openSSL_Engine(env, init_result, lib_name); ++ if (!*init_result) { ++ return res; ++ } ++ res = dlopen(lib_name, RTLD_NOW | RTLD_GLOBAL); ++ } ++ ++ if (res == NULL) { ++ *init_result = JNI_FALSE; ++ char* prefix = "OpenSSL error while opening openssl lib, no matching libssl found: "; ++ char* msg = (char*)malloc(strlen(prefix) + strlen(lib_name) + 1); ++ strcpy(msg, prefix); ++ strcat(msg, lib_name); ++ KAE_ThrowRuntimeException(env, msg); ++ } ++ ++ check_openSSL_Engine(env, init_result, lib_name); ++ if (!*init_result) { ++ dlclose(res); ++ res = NULL; ++ } ++ ++ return res; ++} ++ ++void check_openSSL_Engine(JNIEnv *env, jboolean *init_result, char *lib_name) ++{ ++ char *openssl_engines_path = getenv("OPENSSL_ENGINES"); ++ // openssl_engines_path == null not use KAE Engine, only user KAE Engine check ++ if (openssl_engines_path != NULL) { ++ if (0 == strncmp("libssl.so.1.1", lib_name, strlen(lib_name)) && 0 != strncmp(openssl_engines_path, OPENSSL_ENGINES_VERSION_1_1, strlen(OPENSSL_ENGINES_VERSION_1_1))) { ++ *init_result = JNI_FALSE; ++ KAE_ThrowExceptionInInitializerError(env, "The version of OPENSSL_ENGINES in the environment is inconsistent with the version of the loaded OpenSSL library. Please check jdk config kae.useOpensslVersion or OPENSSL_ENGINES"); ++ return; ++ } ++ if (0 == strncmp("libssl.so.3", lib_name, strlen(lib_name)) && 0 != strncmp(openssl_engines_path, OPENSSL_ENGINES_VERSION_3_X, strlen(OPENSSL_ENGINES_VERSION_3_X))) { ++ *init_result = JNI_FALSE; ++ KAE_ThrowExceptionInInitializerError(env, "The version of OPENSSL_ENGINES in the environment is inconsistent with the version of the loaded OpenSSL library. Please check jdk config kae.useOpensslVersion or OPENSSL_ENGINES"); ++ return; ++ } ++ } ++} ++ ++int get_sslVersion() ++{ ++ return _sslVersion; ++} +\ No newline at end of file +diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/ssl_utils.h b/jdk/src/solaris/native/org/openeuler/security/openssl/ssl_utils.h +new file mode 100644 +index 000000000..9875884a2 +--- /dev/null ++++ b/jdk/src/solaris/native/org/openeuler/security/openssl/ssl_utils.h +@@ -0,0 +1,313 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++ ++#ifndef SSL_UTILS_H ++#define SSL_UTILS_H ++ ++#include ++ ++const BIGNUM *SSL_UTILS_RSA_get0_n(const RSA *r); ++ ++const BIGNUM *SSL_UTILS_RSA_get0_e(const RSA *r); ++ ++const BIGNUM *SSL_UTILS_RSA_get0_d(const RSA *r); ++ ++const BIGNUM *SSL_UTILS_RSA_get0_p(const RSA *r); ++ ++const BIGNUM *SSL_UTILS_RSA_get0_q(const RSA *r); ++ ++const BIGNUM *SSL_UTILS_RSA_get0_dmp1(const RSA *r); ++ ++const BIGNUM *SSL_UTILS_RSA_get0_dmq1(const RSA *r); ++ ++const BIGNUM *SSL_UTILS_RSA_get0_iqmp(const RSA *r); ++ ++RSA *SSL_UTILS_RSA_new_method(ENGINE *engine); ++ ++int SSL_UTILS_RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); ++ ++void SSL_UTILS_RSA_free(RSA *rsa); ++ ++int SSL_UTILS_ERR_load_BIO_strings(); ++ ++int SSL_UTILS_OpenSSL_add_all_algorithms(); ++ ++int SSL_UTILS_ENGINE_free(ENGINE *e); ++ ++ENGINE *SSL_UTILS_ENGINE_by_id(const char *id); ++ ++EVP_MD *SSL_UTILS_EVP_get_digestbyname(const char *name); ++ ++void SSL_UTILS_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode); ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); ++ ++EVP_PKEY_CTX *SSL_UTILS_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); ++ ++int SSL_UTILS_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); ++ ++int SSL_UTILS_EVP_PKEY_sign( ++ EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); ++ ++int SSL_UTILS_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); ++ ++int SSL_UTILS_EVP_PKEY_verify( ++ EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len); ++ ++int SSL_UTILS_EVP_PKEY_size(const EVP_PKEY *pkey); ++ ++EVP_CIPHER *SSL_UTILS_EVP_get_cipherbyname(const char *name); ++ ++EVP_CIPHER_CTX *SSL_UTILS_EVP_CIPHER_CTX_new(void); ++ ++int SSL_UTILS_EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, ++ const unsigned char *iv, int enc); ++ ++int SSL_UTILS_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad); ++ ++void SSL_UTILS_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); ++ ++int SSL_UTILS_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); ++ ++int SSL_UTILS_EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); ++ ++int SSL_UTILS_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); ++ ++BIGNUM *SSL_UTILS_BN_new(void); ++ ++BIGNUM *SSL_UTILS_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); ++ ++void SSL_UTILS_BN_free(BIGNUM *a); ++ ++int SSL_UTILS_EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen); ++ ++int SSL_UTILS_EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); ++ ++EVP_PKEY *SSL_UTILS_EVP_PKEY_new(void); ++ ++int SSL_UTILS_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); ++ ++int SSL_UTILS_RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); ++ ++int SSL_UTILS_RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); ++ ++void SSL_UTILS_EVP_PKEY_free(EVP_PKEY *x); ++ ++int SSL_UTILS_RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); ++ ++int SSL_UTILS_RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); ++ ++int SSL_UTILS_RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); ++ ++int SSL_UTILS_RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); ++ ++int SSL_UTILS_EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); ++ ++int SSL_UTILS_EVP_PKEY_encrypt( ++ EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen); ++ ++int SSL_UTILS_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); ++ ++int SSL_UTILS_EVP_PKEY_decrypt( ++ EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen); ++ ++EVP_MD_CTX *SSL_UTILS_EVP_MD_CTX_new(void); ++ ++int SSL_UTILS_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); ++ ++void SSL_UTILS_EVP_MD_CTX_free(EVP_MD_CTX *ctx); ++ ++int SSL_UTILS_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count); ++ ++int SSL_UTILS_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size); ++ ++int SSL_UTILS_EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); ++ ++unsigned long SSL_UTILS_ERR_get_error_line_data(const char **file, int *line, const char **data, int *flags); ++ ++void SSL_UTILS_ERR_error_string_n(unsigned long e, char *buf, size_t len); ++ ++void SSL_UTILS_ERR_clear_error(void); ++ ++HMAC_CTX *SSL_UTILS_HMAC_CTX_new(void); ++ ++int SSL_UTILS_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl); ++ ++void SSL_UTILS_HMAC_CTX_free(HMAC_CTX *ctx); ++ ++int SSL_UTILS_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); ++ ++int SSL_UTILS_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); ++ ++DH *SSL_UTILS_DH_new_method(ENGINE *engine); ++ ++int SSL_UTILS_DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); ++ ++int SSL_UTILS_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); ++ ++int SSL_UTILS_DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); ++ ++void SSL_UTILS_DH_free(DH *r); ++ ++void SSL_UTILS_EC_POINT_free(EC_POINT *point); ++ ++void SSL_UTILS_EC_KEY_free(EC_KEY *r); ++ ++void SSL_UTILS_EC_GROUP_free(EC_GROUP *group); ++ ++int SSL_UTILS_OBJ_sn2nid(const char *s); ++ ++EC_GROUP *SSL_UTILS_EC_GROUP_new_by_curve_name(int nid); ++ ++EC_KEY *SSL_UTILS_EC_KEY_new(void); ++ ++int SSL_UTILS_EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); ++ ++EC_POINT *SSL_UTILS_EC_POINT_new(const EC_GROUP *group); ++ ++int SSL_UTILS_EC_POINT_set_affine_coordinates_GFp( ++ const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); ++ ++int SSL_UTILS_EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key); ++ ++int SSL_UTILS_EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key); ++ ++int SSL_UTILS_EC_GROUP_get_degree(const EC_GROUP *group); ++ ++int SSL_UTILS_ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, ++ void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); ++ ++int SSL_UTILS_DH_set_length(DH *dh, long length); ++ ++int SSL_UTILS_DH_generate_key(DH *dh); ++ ++const BIGNUM *SSL_UTILS_DH_get0_priv_key(const DH *dh); ++ ++const BIGNUM *SSL_UTILS_DH_get0_pub_key(const DH *dh); ++ ++int SSL_UTILS_EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); ++ ++const EC_POINT *SSL_UTILS_EC_GROUP_get0_generator(const EC_GROUP *group); ++ ++int SSL_UTILS_EC_POINT_get_affine_coordinates_GFp( ++ const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); ++ ++int SSL_UTILS_EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); ++ ++int SSL_UTILS_EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); ++ ++const EC_POINT *SSL_UTILS_EC_KEY_get0_public_key(const EC_KEY *key); ++ ++const BIGNUM *SSL_UTILS_EC_KEY_get0_private_key(const EC_KEY *key); ++ ++int SSL_UTILS_BN_set_word(BIGNUM *a, BN_ULONG w); ++ ++EC_GROUP *SSL_UTILS_EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); ++ ++int SSL_UTILS_EC_GROUP_set_generator( ++ EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); ++ ++void SSL_UTILS_BN_CTX_free(BN_CTX *ctx); ++ ++int SSL_UTILS_EC_KEY_generate_key(EC_KEY *eckey); ++ ++RSA *SSL_UTILS_EVP_PKEY_get1_RSA(EVP_PKEY *pkey); ++ ++BIGNUM *SSL_UTILS_BN_dup(const BIGNUM *a); ++ ++BN_CTX *SSL_UTILS_BN_CTX_new(void); ++ ++int SSL_UTILS_EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); ++ ++int SSL_UTILS_BN_bn2bin(const BIGNUM *a, unsigned char *to); ++ ++void SSL_UTILS_func_dl(JNIEnv *env); ++ ++jboolean SSL_UTILS_func_ptr_init(JNIEnv *env, jint useOpensslVersion); ++ ++void *open_ssl_lib(JNIEnv *env, jint useOpensslVersion, jboolean *init_result); ++ ++void check_openSSL_Engine(JNIEnv *env, jboolean *init_result, char *lib_name); ++ ++int get_sslVersion(); ++ ++int SSL_UTILS_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); ++ ++int SSL_UTILS_OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); ++ ++int SSL_UTILS_BN_num_bits(const BIGNUM *a); ++ ++int SSL_UTILS_ERR_GET_REASON(unsigned long errcode); ++ ++int SSL_UTILS_ERR_GET_FUNC(unsigned long errcode); ++ ++int SSL_UTILS_ERR_GET_LIB(unsigned long errcode); ++ ++void SSL_UTILS_BN_clear_free(BIGNUM *a); ++ ++EVP_MD *SSL_UTILS_EVP_sm3(void); ++ ++int SSL_UTILS_EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, const void *id, int len); ++ ++void SSL_UTILS_EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); ++ ++int SSL_UTILS_EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); ++ ++int SSL_UTILS_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); ++ ++int SSL_UTILS_EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize); ++ ++int SSL_UTILS_EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize); ++ ++int SSL_UTILS_EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen); ++ ++int SSL_UTILS_EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen); ++ ++EC_KEY *SSL_UTILS_EC_KEY_new_by_curve_name(int nid); ++ ++int SSL_UTILS_EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, ++ const BIGNUM *p_scalar, BN_CTX *ctx); ++ ++int SSL_UTILS_EVP_PKEY_set_alias_type(JNIEnv *env, EVP_PKEY *pkey, int type); ++ ++int SSL_UTILS_EVP_PKEY_assign_RSA(EVP_PKEY *pkey, void *key); ++ ++int SSL_UTILS_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, void *key); ++ ++void SSL_UTILS_EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); ++ ++EVP_MD_CTX *SSL_UTILS_EVP_MD_CTX_create(void); ++ ++int SSL_UTILS_SSL_load_error_strings(); ++ ++int SSL_UTILS_OpenSSL_add_all_algorithms(); ++ ++int SSL_UTILS_BN_num_bytes(const BIGNUM *a); ++ ++#endif // SSL_UTILS_H +\ No newline at end of file +diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/SM2CipherBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/SM2CipherBenchmark.java +new file mode 100644 +index 000000000..eb3b7a09d +--- /dev/null ++++ b/jdk/test/micro/org/openeuler/bench/security/openssl/SM2CipherBenchmark.java +@@ -0,0 +1,117 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++package org.openeuler.bench.security.openssl; ++ ++import org.openeuler.security.openssl.KAEProvider; ++import org.openjdk.jmh.annotations.*; ++ ++import java.security.*; ++import java.util.Random; ++import java.util.concurrent.TimeUnit; ++ ++import javax.crypto.BadPaddingException; ++import javax.crypto.Cipher; ++import javax.crypto.IllegalBlockSizeException; ++import javax.crypto.NoSuchPaddingException; ++ ++/** ++ * SM2 Cipher Benchmark ++ */ ++@BenchmarkMode(Mode.Throughput) ++@OutputTimeUnit(TimeUnit.SECONDS) ++@Warmup(iterations = 3, time = 3, timeUnit = TimeUnit.SECONDS) ++@Measurement(iterations = 8, time = 2, timeUnit = TimeUnit.SECONDS) ++@Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch"}, value = 5) ++@Threads(1) ++@State(Scope.Thread) ++public class SM2CipherBenchmark { ++ public static final int SET_SIZE = 128; ++ byte[][] data; ++ int index = 0; ++ ++ @Param({"SM2"}) ++ private String algorithm; ++ ++ @Param({"" + 1024, "" + 10 * 1024, "" + 100 * 1024, "" + 1024 * 1024}) ++ private int dataSize; ++ ++ @Param({"KAEProvider"}) ++ private String provider; ++ ++ public Provider prov = null; ++ ++ private KeyPair keyPair; ++ ++ private byte[][] encryptedData; ++ private Cipher encryptCipher; ++ private Cipher decryptCipher; ++ ++ @Setup ++ public void setup() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, ++ IllegalBlockSizeException, BadPaddingException { ++ Security.addProvider(new KAEProvider()); ++ prov = Security.getProvider(provider); ++ ++ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("SM2"); ++ keyPair = keyPairGenerator.generateKeyPair(); ++ ++ encryptCipher = (prov == null) ? Cipher.getInstance(algorithm) : Cipher.getInstance(algorithm, prov); ++ encryptCipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); ++ decryptCipher = (prov == null) ? Cipher.getInstance(algorithm) : Cipher.getInstance(algorithm, prov); ++ decryptCipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); ++ ++ data = fillRandom(new byte[SET_SIZE][dataSize]); ++ encryptedData = fillEncrypted(data, encryptCipher); ++ } ++ ++ @Benchmark ++ public byte[] encrypt() throws IllegalBlockSizeException, BadPaddingException { ++ byte[] d = data[index]; ++ index = (index + 1) % SET_SIZE; ++ return encryptCipher.doFinal(d); ++ } ++ ++ @Benchmark ++ public byte[] decrypt() throws IllegalBlockSizeException, BadPaddingException { ++ byte[] e = encryptedData[index]; ++ index = (index + 1) % SET_SIZE; ++ return decryptCipher.doFinal(e); ++ } ++ public static byte[][] fillRandom(byte[][] data) { ++ Random rnd = new Random(); ++ for (byte[] d : data) { ++ rnd.nextBytes(d); ++ } ++ return data; ++ } ++ ++ public static byte[][] fillEncrypted(byte[][] data, Cipher encryptCipher) ++ throws IllegalBlockSizeException, BadPaddingException { ++ byte[][] encryptedData = new byte[data.length][]; ++ for (int i = 0; i < encryptedData.length; i++) { ++ encryptedData[i] = encryptCipher.doFinal(data[i]); ++ } ++ return encryptedData; ++ } ++} ++ +diff --git a/jdk/test/micro/org/openeuler/bench/security/openssl/SM2SignatureBenchmark.java b/jdk/test/micro/org/openeuler/bench/security/openssl/SM2SignatureBenchmark.java +new file mode 100644 +index 000000000..ebe973428 +--- /dev/null ++++ b/jdk/test/micro/org/openeuler/bench/security/openssl/SM2SignatureBenchmark.java +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++package org.openeuler.bench.security.openssl; ++ ++import org.openeuler.security.openssl.KAEProvider; ++import org.openjdk.jmh.annotations.*; ++ ++import java.security.*; ++import java.util.concurrent.TimeUnit; ++ ++/** ++ * SM2 Signature Benchmark ++ */ ++@BenchmarkMode(Mode.Throughput) ++@OutputTimeUnit(TimeUnit.SECONDS) ++@Warmup(iterations = 3, time = 3, timeUnit = TimeUnit.SECONDS) ++@Measurement(iterations = 8, time = 2, timeUnit = TimeUnit.SECONDS) ++@Fork(jvmArgsPrepend = {"-Xms100G", "-Xmx100G", "-XX:+AlwaysPreTouch"}, value = 5) ++@Threads(1) ++@State(Scope.Thread) ++public class SM2SignatureBenchmark { ++ public static final int SET_SIZE = 128; ++ byte[][] data; ++ int index = 0; ++ ++ @Param({"SM3withSM2"}) ++ private String algorithm; ++ ++ @Param({"" + 1024, "" + 10 * 1024, "" + 100 * 1024, "" + 256 * 1024, "" + 1024 * 1024, "" + 10 * 1024 * 1024}) ++ private int dataSize; ++ ++ @Param({"KAEProvider"}) ++ private String provider; ++ ++ public Provider prov = null; ++ ++ private KeyPair keyPair; ++ ++ private byte[][] sigData; ++ ++ @Setup ++ public void setup() throws Exception { ++ Security.addProvider(new KAEProvider()); ++ prov = Security.getProvider(provider); ++ ++ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("SM2"); ++ keyPair = keyPairGenerator.generateKeyPair(); ++ ++ data = new byte[SET_SIZE][dataSize]; ++ sigData = getSigBytes(data); ++ } ++ ++ private byte[][] getSigBytes(byte[][] data) throws Exception { ++ byte[][] sigBytes = new byte[data.length][]; ++ Signature signature = prov != null ? Signature.getInstance(algorithm, prov) : ++ Signature.getInstance(algorithm); ++ signature.initSign(keyPair.getPrivate()); ++ for (int i = 0; i < sigBytes.length; i++) { ++ signature.update(data[i]); ++ sigBytes[i] = signature.sign(); ++ } ++ return sigBytes; ++ } ++ ++ @Benchmark ++ public void sign() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { ++ Signature signature = prov != null ? Signature.getInstance(algorithm, prov) : ++ Signature.getInstance(algorithm); ++ signature.initSign(keyPair.getPrivate()); ++ signature.update(data[index]); ++ signature.sign(); ++ index = (index + 1) % SET_SIZE; ++ } ++ ++ @Benchmark ++ public void verify() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { ++ Signature signature = prov != null ? Signature.getInstance(algorithm, prov) : ++ Signature.getInstance(algorithm); ++ signature.initVerify(keyPair.getPublic()); ++ signature.update(data[index]); ++ signature.verify(sigData[index]); ++ index = (index + 1) % SET_SIZE; ++ } ++} +diff --git a/jdk/test/org/openeuler/security/openssl/ECDHTest.java b/jdk/test/org/openeuler/security/openssl/ECDHTest.java +index 069c32295..2cbb98d68 100644 +--- a/jdk/test/org/openeuler/security/openssl/ECDHTest.java ++++ b/jdk/test/org/openeuler/security/openssl/ECDHTest.java +@@ -21,22 +21,18 @@ + * questions. + */ + ++import org.openeuler.security.openssl.KAEECPrivateKeyImpl; ++import org.openeuler.security.openssl.KAEECPublicKeyImpl; + import org.openeuler.security.openssl.KAEProvider; +-import sun.security.ec.ECPrivateKeyImpl; +-import sun.security.ec.ECPublicKeyImpl; + + import javax.crypto.KeyAgreement; + import java.math.BigInteger; +-import java.security.KeyPair; +-import java.security.KeyPairGenerator; +-import java.security.Provider; +-import java.security.Security; ++import java.security.*; + import java.security.spec.ECFieldFp; + import java.security.spec.ECParameterSpec; + import java.security.spec.ECPoint; + import java.security.spec.EllipticCurve; + import java.util.Arrays; +-import java.nio.charset.StandardCharsets; + + /** + * @test +@@ -70,9 +66,9 @@ public class ECDHTest { + testKeyPairByKeySize(keySize); + } + +- ECPrivateKeyImpl ecPrivKey = new ECPrivateKeyImpl(new BigInteger("20135071615800221517902437867016717688420688735490569283842831828983"), PARAMS); ++ KAEECPrivateKeyImpl ecPrivKey = new KAEECPrivateKeyImpl(new BigInteger("20135071615800221517902437867016717688420688735490569283842831828983"), PARAMS); + ECPoint ecPoint = new ECPoint(new BigInteger("9490267631555585552004372465967099662885480699902812460349461311384"), new BigInteger("1974573604976093871117393045089050409882519645527397292712281520811")); +- ECPublicKeyImpl ecPublicKey = new ECPublicKeyImpl(ecPoint, PARAMS); ++ KAEECPublicKeyImpl ecPublicKey = new KAEECPublicKeyImpl(ecPoint, PARAMS); + testKeyAgreement(ecPrivKey, ecPublicKey, new byte[]{-88, -65, 43, -84, 26, 43, 46, 106, 20, 39, -76, 30, -71, 72, -102, 120, 108, -92, -86, -14, -96, -42, 93, -40, -43, -25, 15, -62}); + + } +@@ -81,19 +77,19 @@ public class ECDHTest { + keyPairGenerator = KeyPairGenerator.getInstance(algorithm); + keyPairGenerator.initialize(PARAMS); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); +- ECPrivateKeyImpl ecPrivKey = (ECPrivateKeyImpl) keyPair.getPrivate(); +- ECPublicKeyImpl ecPublicKey = (ECPublicKeyImpl) keyPair.getPublic(); ++ PrivateKey ecPriKey = keyPair.getPrivate(); ++ PublicKey ecPublicKey = keyPair.getPublic(); + } + + public static void testKeyPairByKeySize(int keySize) throws Exception { + keyPairGenerator = KeyPairGenerator.getInstance(algorithm); + keyPairGenerator.initialize(keySize); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); +- ECPrivateKeyImpl ecPrivKey = (ECPrivateKeyImpl) keyPair.getPrivate(); +- ECPublicKeyImpl ecPublicKey = (ECPublicKeyImpl) keyPair.getPublic(); ++ PrivateKey ecPriKey = keyPair.getPrivate(); ++ PublicKey ecPublicKey = keyPair.getPublic(); + } + +- public static void testKeyAgreement(ECPrivateKeyImpl ecPrivKey, ECPublicKeyImpl ecPublicKey, byte[] expectRes) throws Exception { ++ public static void testKeyAgreement(KAEECPrivateKeyImpl ecPrivKey, KAEECPublicKeyImpl ecPublicKey, byte[] expectRes) throws Exception { + KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH"); + keyAgreement.init(ecPrivKey); + keyAgreement.doPhase(ecPublicKey, true); +diff --git a/jdk/test/org/openeuler/security/openssl/KAEConfTest.java b/jdk/test/org/openeuler/security/openssl/KAEConfTest.java +index 9028d28b5..3b4238576 100644 +--- a/jdk/test/org/openeuler/security/openssl/KAEConfTest.java ++++ b/jdk/test/org/openeuler/security/openssl/KAEConfTest.java +@@ -26,10 +26,16 @@ import org.openeuler.security.openssl.KAEProvider; + + import java.io.File; + import java.io.FileWriter; ++import java.io.BufferedReader; ++import java.io.FileInputStream; ++import java.io.InputStreamReader; ++import java.nio.charset.StandardCharsets; + import java.io.IOException; + import java.nio.file.Files; + import java.util.ArrayList; + import java.util.List; ++import java.util.regex.Matcher; ++import java.util.regex.Pattern; + + /* + * @test +@@ -47,6 +53,7 @@ public class KAEConfTest { + + private static final String SPECIFY_LOG_PATH = System.getProperty("user.dir") + File.separator + "kae.log"; + private static final List files = new ArrayList<>(); ++ private static final Pattern CONFIG_PATTERN = Pattern.compile("^\\s*(?!#.*kae\\.useOpensslVersion)kae\\.useOpensslVersion\\s*=\\s*(.+?)\\s*(#.*)?$"); + + enum Mode { + DEFAULT, +@@ -73,6 +80,16 @@ public class KAEConfTest { + + private static void init(Mode mode) throws IOException { + if (Mode.SPECIFY.equals(mode)) { ++ String default_opensslVersion = "0"; ++ try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(System.getProperty("kae.conf", DEFAULT_CONF)), StandardCharsets.UTF_8))) { ++ String line; ++ while ((line = reader.readLine()) != null) { ++ Matcher matcher = CONFIG_PATTERN.matcher(line); ++ if (matcher.matches()) { ++ default_opensslVersion = matcher.group(1).trim(); ++ } ++ } ++ } + System.setProperty("kae.conf", SPECIFY_CONF); + File file = new File(SPECIFY_CONF); + if (!file.exists()) { +@@ -80,7 +97,9 @@ public class KAEConfTest { + } + files.add(file); + try (FileWriter fileWriter = new FileWriter(file)) { +- fileWriter.write("kae.log=true"); ++ fileWriter.write("kae.log=true\n"); ++ // use same opensslVersion with default conf ++ fileWriter.write("kae.useOpensslVersion=" + default_opensslVersion + "\n"); + fileWriter.flush(); + } + } +diff --git a/jdk/test/org/openeuler/security/openssl/KAETestHelper.java b/jdk/test/org/openeuler/security/openssl/KAETestHelper.java +index 31e22493a..c84a5a3ac 100644 +--- a/jdk/test/org/openeuler/security/openssl/KAETestHelper.java ++++ b/jdk/test/org/openeuler/security/openssl/KAETestHelper.java +@@ -67,7 +67,8 @@ class KAETestHelper { + "hmac-sha512", + "rsa", + "dh", +- "ec" ++ "ec", ++ "sm2" + }; + private static final Map ALGORITHM_NAME_MAP = new HashMap<>(); + +diff --git a/jdk/test/org/openeuler/security/openssl/KAEUseEngineTest.java b/jdk/test/org/openeuler/security/openssl/KAEUseEngineTest.java +index 4e57f775e..cd6857cde 100644 +--- a/jdk/test/org/openeuler/security/openssl/KAEUseEngineTest.java ++++ b/jdk/test/org/openeuler/security/openssl/KAEUseEngineTest.java +@@ -43,7 +43,8 @@ import java.util.Map; + * @run main/othervm -Dkae.log=true -Dkae.rsa.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.dh.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.ec.useKaeEngine=true KAEUseEngineTest +- * @run main/othervm -Dkae.log=true -Dall.test=enable -Dkae.digest.useKaeEngine=true -Dkae.aes.useKaeEngine=true -Dkae.sm4.useKaeEngine=true -Dkae.hmac.useKaeEngine=true -Dkae.rsa.useKaeEngine=true -Dkae.dh.useKaeEngine=true -Dkae.ec.useKaeEngine=true KAEUseEngineTest ++ * @run main/othervm -Dkae.log=true -Dkae.sm2.useKaeEngine=true KAEUseEngineTest ++ * @run main/othervm -Dkae.log=true -Dall.test=enable -Dkae.digest.useKaeEngine=true -Dkae.aes.useKaeEngine=true -Dkae.sm4.useKaeEngine=true -Dkae.hmac.useKaeEngine=true -Dkae.rsa.useKaeEngine=true -Dkae.dh.useKaeEngine=true -Dkae.ec.useKaeEngine=true -Dkae.sm2.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.digest.useKaeEngine=false KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.aes.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.sm4.useKaeEngine=true KAEUseEngineTest +@@ -51,7 +52,8 @@ import java.util.Map; + * @run main/othervm -Dkae.log=true -Dkae.rsa.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.dh.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.ec.useKaeEngine=true KAEUseEngineTest +- * @run main/othervm -Dkae.log=true -Dall.test=disable -Dkae.digest.useKaeEngine=false -Dkae.aes.useKaeEngine=false -Dkae.sm4.useKaeEngine=false -Dkae.hmac.useKaeEngine=false -Dkae.rsa.useKaeEngine=false -Dkae.dh.useKaeEngine=false -Dkae.ec.useKaeEngine=false KAEUseEngineTest ++ * @run main/othervm -Dkae.log=true -Dkae.sm2.useKaeEngine=true KAEUseEngineTest ++ * @run main/othervm -Dkae.log=true -Dall.test=disable -Dkae.digest.useKaeEngine=false -Dkae.aes.useKaeEngine=false -Dkae.sm4.useKaeEngine=false -Dkae.hmac.useKaeEngine=false -Dkae.rsa.useKaeEngine=false -Dkae.dh.useKaeEngine=false -Dkae.ec.useKaeEngine=false -Dkae.sm2.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dall.test=default -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.digest.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.aes.useKaeEngine=true KAEUseEngineTest +@@ -60,7 +62,8 @@ import java.util.Map; + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.rsa.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.dh.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.ec.useKaeEngine=true KAEUseEngineTest +- * @run main/othervm -Dkae.log=true -Dall.test=enable -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.digest.useKaeEngine=true -Dkae.aes.useKaeEngine=true -Dkae.sm4.useKaeEngine=true -Dkae.hmac.useKaeEngine=true -Dkae.rsa.useKaeEngine=true -Dkae.dh.useKaeEngine=true -Dkae.ec.useKaeEngine=true KAEUseEngineTest ++ * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.sm2.useKaeEngine=true KAEUseEngineTest ++ * @run main/othervm -Dkae.log=true -Dall.test=enable -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.digest.useKaeEngine=true -Dkae.aes.useKaeEngine=true -Dkae.sm4.useKaeEngine=true -Dkae.hmac.useKaeEngine=true -Dkae.rsa.useKaeEngine=true -Dkae.dh.useKaeEngine=true -Dkae.ec.useKaeEngine=true -Dkae.sm2.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.digest.useKaeEngine=false KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.aes.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.sm4.useKaeEngine=true KAEUseEngineTest +@@ -68,94 +71,100 @@ import java.util.Map; + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.rsa.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.dh.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.ec.useKaeEngine=true KAEUseEngineTest +- * @run main/othervm -Dkae.log=true -Dall.test=disable -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.digest.useKaeEngine=false -Dkae.aes.useKaeEngine=false -Dkae.sm4.useKaeEngine=false -Dkae.hmac.useKaeEngine=false -Dkae.rsa.useKaeEngine=false -Dkae.dh.useKaeEngine=false -Dkae.ec.useKaeEngine=false KAEUseEngineTest ++ * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.sm2.useKaeEngine=true KAEUseEngineTest ++ * @run main/othervm -Dkae.log=true -Dall.test=disable -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.digest.useKaeEngine=false -Dkae.aes.useKaeEngine=false -Dkae.sm4.useKaeEngine=false -Dkae.hmac.useKaeEngine=false -Dkae.rsa.useKaeEngine=false -Dkae.dh.useKaeEngine=false -Dkae.ec.useKaeEngine=false -Dkae.sm2.useKaeEngine=false KAEUseEngineTest + */ + public class KAEUseEngineTest { + enum Mode { + DEFAULT(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }), + DIGEST_ENABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 0, true), + AES_ENABLE(new boolean[]{ + true, false, false, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 1, true), + SM4_ENABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 2, true), + HMAC_ENABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- true, true, true, true, true, true, true, true, false ++ true, true, true, true, true, true, true, true, false, false + }, 3, true), + RSA_ENABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 4, true), + DH_ENABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 5, true), + EC_ENABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 6, true), + ALL_ENABLE(new boolean[]{ + true, false, false, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, +- true, true, true, true, true, true, true, true, false ++ true, true, true, true, true, true, true, true, false, false + }, true), + DIGEST_DISABLE(new boolean[]{ + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 0, false), + AES_DISABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 1, false), + SM4_DISABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 2, false), + HMAC_DISABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 3, false), + RSA_DISABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, false, true, false ++ false, false, false, false, false, false, false, true, false, false + }, 4, false), + DH_DISABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, false, false ++ false, false, false, false, false, false, true, false, false, false + }, 5, false), + EC_DISABLE(new boolean[]{ + true, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true, true, +- false, false, false, false, false, false, true, true, false ++ false, false, false, false, false, false, true, true, false, false + }, 6, false), ++ SM2_DISABLE(new boolean[]{ ++ true, false, false, true, false, false, false, false, false, false, ++ false, false, false, false, false, false, true, true, true, true, ++ false, false, false, false, false, false, true, true, false, false ++ }, 7, false), + ALL_DISABLE(new boolean[]{ + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, +- false, false, false, false, false, false, false, false, false ++ false, false, false, false, false, false, false, false, false, false + }, false); + private final boolean[] expectedResult; + private final Integer propertyNameIndex; +@@ -207,7 +216,8 @@ public class KAEUseEngineTest { + "kae.hmac.useKaeEngine", + "kae.rsa.useKaeEngine", + "kae.dh.useKaeEngine", +- "kae.ec.useKaeEngine" ++ "kae.ec.useKaeEngine", ++ "kae.sm2.useKaeEngine" + }; + + private static final List files = new ArrayList<>(); +diff --git a/jdk/test/org/openeuler/security/openssl/KaeProviderTest.java b/jdk/test/org/openeuler/security/openssl/KaeProviderTest.java +index d8587891b..dc1478801 100644 +--- a/jdk/test/org/openeuler/security/openssl/KaeProviderTest.java ++++ b/jdk/test/org/openeuler/security/openssl/KaeProviderTest.java +@@ -26,10 +26,7 @@ import org.openeuler.security.openssl.KAEProvider; + import javax.crypto.Cipher; + import javax.crypto.Mac; + import javax.crypto.NoSuchPaddingException; +-import java.security.KeyPairGenerator; +-import java.security.MessageDigest; +-import java.security.NoSuchAlgorithmException; +-import java.security.Security; ++import java.security.*; + + /** + * @test +@@ -53,7 +50,9 @@ public class KaeProviderTest { + "kae.hmac", + "kae.rsa", + "kae.dh", +- "kae.ec" ++ "kae.ec", ++ "kae.sm2.cipher", ++ "kae.sm2.signature" + }; + + private static final String KAE = "KAEProvider"; +@@ -85,6 +84,7 @@ public class KaeProviderTest { + testRsa(); + testDh(); + testEc(); ++ testSM2(); + } + + public static void testMd5() throws NoSuchAlgorithmException { +@@ -150,6 +150,28 @@ public class KaeProviderTest { + judge("kae.ec",keyPairGenerator.getProvider().getName()); + } + ++ public static void testSM2() throws NoSuchAlgorithmException, NoSuchPaddingException { ++ try { ++ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("SM2"); ++ judge("kae.sm2.cipher",keyPairGenerator.getProvider().getName()); ++ Cipher cipher = Cipher.getInstance("SM2"); ++ judge("kae.sm2.cipher",cipher.getProvider().getName()); ++ ++ } catch (NoSuchAlgorithmException e) { ++ if(Boolean.parseBoolean(System.getProperty("kae.sm2.cipher"))){ ++ throw e; ++ } ++ } ++ try { ++ Signature signature = Signature.getInstance("SM3WithSM2"); ++ judge("kae.sm2.signature",signature.getProvider().getName()); ++ } catch (NoSuchAlgorithmException e) { ++ if(Boolean.parseBoolean(System.getProperty("kae.sm2.signature"))){ ++ throw e; ++ } ++ } ++ } ++ + private static void judge(String algorithm , String providerName){ + String value = System.getProperty(algorithm); + if (value == null) { +diff --git a/jdk/test/org/openeuler/security/openssl/SM2Test.java b/jdk/test/org/openeuler/security/openssl/SM2Test.java +new file mode 100644 +index 000000000..e45d524b2 +--- /dev/null ++++ b/jdk/test/org/openeuler/security/openssl/SM2Test.java +@@ -0,0 +1,174 @@ ++/* ++ * Copyright (c) 2024, Huawei Technologies Co., Ltd. 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. ++ */ ++ ++import org.openeuler.security.openssl.KAEProvider; ++ ++import javax.crypto.Cipher; ++import java.security.*; ++import java.security.spec.PKCS8EncodedKeySpec; ++import java.security.spec.X509EncodedKeySpec; ++import java.util.Arrays; ++ ++/** ++ * @test ++ * @summary Basic test for SM2 ++ * @requires os.arch=="aarch64" ++ * @run main SM2Test ++ */ ++ ++public class SM2Test { ++ private static final byte[] INFO = "SM2 test".getBytes(); ++ private static final byte[] PUBLIC_KEY_BYTES = new byte[]{ ++ 48, 89, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 8, 42, ++ -127, 28, -49, 85, 1, -126, 45, 3, 66, 0, 4, 10, -36, -22, -20, 17, ++ 26, 86, -114, -52, -78, 79, -22, 116, -47, -70, -33, 112, 32, -18, 92, -45, ++ -58, 20, 36, -5, 55, 68, -95, -57, -121, 10, 33, -76, 54, 24, -119, -104, ++ 61, -24, -113, 46, -57, 36, -78, -37, -95, -113, -52, -88, -5, 22, -67, 101, ++ 94, 37, 2, -58, 55, -35, 15, -21, 31, -49, -80 ++ }; ++ private static final byte[] PRIVATE_KEY_BYTES = new byte[]{ ++ 48, -127, -109, 2, 1, 0, 48, 19, 6, 7, 42, -122, 72, -50, 61, 2, ++ 1, 6, 8, 42, -127, 28, -49, 85, 1, -126, 45, 4, 121, 48, 119, 2, ++ 1, 1, 4, 32, -104, 71, 54, -41, 24, 66, 82, -45, 114, -113, -121, -105, ++ -35, 35, 9, 49, -8, 119, 44, 118, 80, -20, 47, -38, -69, -47, 121, -8, ++ -73, -33, 4, 54, -96, 10, 6, 8, 42, -127, 28, -49, 85, 1, -126, 45, ++ -95, 68, 3, 66, 0, 4, 10, -36, -22, -20, 17, 26, 86, -114, -52, -78, ++ 79, -22, 116, -47, -70, -33, 112, 32, -18, 92, -45, -58, 20, 36, -5, 55, ++ 68, -95, -57, -121, 10, 33, -76, 54, 24, -119, -104, 61, -24, -113, 46, -57, ++ 36, -78, -37, -95, -113, -52, -88, -5, 22, -67, 101, 94, 37, 2, -58, 55, ++ -35, 15, -21, 31, -49, -80 ++ }; ++ ++ private static final byte[] ENCRYPTED_BYTES = new byte[]{ ++ 48, 113, 2, 33, 0, -91, 51, 29, -122, -26, 120, 43, 27, 115, -57, -98, ++ -124, 114, -30, -83, 69, -69, -38, -54, -38, 127, 90, -89, -40, 114, -9, 99, ++ 111, 121, 55, -81, 109, 2, 32, 6, -103, 108, -59, -11, -108, -7, 116, 34, ++ -8, -29, 58, -43, -109, -121, -66, -62, -82, 92, 117, 100, -28, 63, -103, -32, ++ -81, 10, 4, -46, 114, 49, 34, 4, 32, 18, 66, 110, 22, -3, -101, -122, ++ 46, 21, 25, 29, 35, -82, -119, 38, -10, -19, -30, 69, -100, -118, -105, 116, ++ -105, -65, -110, -24, -42, -17, 84, -66, 82, 4, 8, 7, 14, 4, 64, 95, 31, 87, 93 ++ }; ++ ++ private static PrivateKey privateKey; ++ ++ private static PublicKey publicKey; ++ ++ public static void main(String[] args) throws Exception { ++ init(); ++ testDecryptByPrivateKey(); ++ testEncryptByPublicKey(); ++ testEncryptByPrivateKey(); ++ testSignature(); ++ testWrapAndUnwrap(); ++ } ++ ++ /** ++ * Init private key and public key ++ */ ++ public static void init() throws Exception { ++ Security.insertProviderAt(new KAEProvider(), 1); ++ KeyFactory keyFactory = KeyFactory.getInstance("SM2"); ++ publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(PUBLIC_KEY_BYTES)); ++ privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(PRIVATE_KEY_BYTES)); ++ } ++ ++ /** ++ * Test private key decryption ++ */ ++ public static void testDecryptByPrivateKey() throws Exception { ++ byte[] decryptBytes = decrypt(privateKey, ENCRYPTED_BYTES); ++ if(!Arrays.equals(INFO, decryptBytes)) { ++ throw new RuntimeException("testDecryptByPrivateKey failed"); ++ } ++ } ++ ++ /** ++ * Test public key encryption and private key decryption ++ */ ++ public static void testEncryptByPublicKey() throws Exception { ++ byte[] encryptBytes = encrypt(publicKey, INFO); ++ byte[] decryptBytes = decrypt(privateKey, encryptBytes); ++ if(!Arrays.equals(INFO, decryptBytes)) { ++ throw new RuntimeException("testEncryptByPublicKey failed"); ++ } ++ } ++ ++ /** ++ * Test private key encryption and public key decryption ++ */ ++ public static void testEncryptByPrivateKey() throws Exception { ++ try { ++ encrypt(privateKey, INFO); ++ throw new RuntimeException("testEncryptByPrivateKey failed"); ++ }catch (InvalidKeyException e){ ++ // catch InvalidKeyException is normal ++ } ++ } ++ ++ public static void testSignature() throws Exception { ++ ++ Signature sign = Signature.getInstance("SM3withSM2"); ++ sign.initSign(privateKey); ++ sign.update(INFO); ++ byte[] signInfo = sign.sign(); ++ ++ sign.initVerify(publicKey); ++ sign.update(INFO); ++ if (!sign.verify(signInfo)) { ++ throw new RuntimeException("sm2 testSignature failed."); ++ } ++ } ++ ++ public static void testWrapAndUnwrap() throws Exception { ++ KeyPair keyPair = generateKeyPair(); ++ KeyPair wrapKeyPair = generateKeyPair(); ++ Cipher cipher = Cipher.getInstance("SM2"); ++ cipher.init(Cipher.WRAP_MODE, keyPair.getPublic()); ++ byte[] wrappedKeyBytes = cipher.wrap(wrapKeyPair.getPublic()); ++ cipher.init(Cipher.UNWRAP_MODE, keyPair.getPrivate()); ++ Key unWrappedKey = cipher.unwrap(wrappedKeyBytes, "SM2", Cipher.PUBLIC_KEY); ++ if(!Arrays.equals(wrapKeyPair.getPublic().getEncoded(), unWrappedKey.getEncoded())) { ++ throw new RuntimeException("testWrapAndUnwrap failed"); ++ } ++ } ++ ++ private static KeyPair generateKeyPair() throws Exception { ++ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("SM2"); ++ return keyPairGenerator.generateKeyPair(); ++ } ++ ++ private static byte[] doCrypt(int opmode, Key key, byte[] input) throws Exception { ++ Cipher cipher = Cipher.getInstance("SM2"); ++ cipher.init(opmode, key); ++ cipher.update(input); ++ return cipher.doFinal(); ++ } ++ ++ private static byte[] encrypt(Key key, byte[] input) throws Exception { ++ return doCrypt(Cipher.ENCRYPT_MODE, key, input); ++ } ++ ++ private static byte[] decrypt(Key key, byte[] input) throws Exception { ++ return doCrypt(Cipher.DECRYPT_MODE, key, input); ++ } ++} +-- +2.48.1 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index 1543610..c9c836b 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -953,7 +953,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 2 +Release: 3 # 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 # also included the epoch in their virtual provides. This created a @@ -1388,6 +1388,7 @@ Patch475: 8287432-C2-assert-tn-in-0-__null-failed-must-have-li.patch #472 Patch476: 8268366-C1-Incorrect-calculation-of-has_fpu_register.patch +Patch477: huawei-JDK8-adapts-to-OpenSSL3.patch ############################################# # @@ -2078,6 +2079,7 @@ pushd %{top_level_dir_name} %patch474 -p1 %patch475 -p1 %patch476 -p1 +%patch477 -p1 %endif %ifarch loongarch64 @@ -3062,6 +3064,9 @@ cjc.mainProgram(args) -- the returns from copy_jdk_configs.lua should not affect %endif %changelog +* Fri Nov 28 2025 Benshuai5D -1:1.8.0.472.b08-3 +- add huawei-JDK8-adapts-to-OpenSSL3.patch + * Wed Nov 12 2025 DXwangg -1:1.8.0.472.b08-2 - modified Add-JitProfileCache-feature.patch - modified Add-Dynamic-Max-Heap-feature-for-G1GC.patch -- Gitee