Date: Mon, 8 Dec 2025 21:23:35 +0800
Subject: [PATCH] Add-SM2-and-KAE-for-OpenSSL3

---
 make/modules/jdk.crypto.kaeprovider/Lib.gmk   |    2 +-
 src/java.base/share/classes/module-info.java  |    1 +
 .../classes/sun/security/util/KnownOIDs.java  |    3 +
 .../openeuler/security/openssl/KAEConfig.java |   42 +-
 .../security/openssl/KAECurveDB.java          |  729 +++++++++
 .../security/openssl/KAEECDHKeyAgreement.java |   12 +-
 .../security/openssl/KAEECKeyFactory.java     |  308 ++++
 .../openssl/KAEECKeyPairGenerator.java        |   17 +-
 .../security/openssl/KAEECParameters.java     |  240 +++
 .../security/openssl/KAEECPrivateKeyImpl.java |  214 +++
 .../security/openssl/KAEECPublicKeyImpl.java  |  132 ++
 .../security/openssl/KAENamedCurve.java       |  100 ++
 .../security/openssl/KAEProvider.java         |   63 +-
 .../security/openssl/KAESM2Cipher.java        |  386 +++++
 .../openssl/KAESM2KeyPairGenerator.java       |  108 ++
 .../security/openssl/KAESM2Signature.java     |  373 +++++
 .../openeuler/security/openssl/KAEUtils.java  |   35 +
 .../linux/conf/security/kaeprovider.conf      |   23 +-
 .../security/openssl/kae_cipher_rsa.c         |   69 +-
 .../security/openssl/kae_cipher_sm2.c         |  370 +++++
 .../openeuler/security/openssl/kae_digest.c   |   28 +-
 .../security/openssl/kae_exception.c          |   18 +-
 .../security/openssl/kae_exception.h          |    2 +
 .../org/openeuler/security/openssl/kae_hmac.c |   25 +-
 .../security/openssl/kae_keyagreement_dh.c    |   17 +-
 .../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 |   57 +-
 .../security/openssl/kae_signature_rsa.c      |   47 +-
 .../security/openssl/kae_signature_sm2.c      |  288 ++++
 .../security/openssl/kae_symmetric_cipher.c   |   78 +-
 .../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    | 1368 +++++++++++++++++
 .../openeuler/security/openssl/ssl_utils.h    |  313 ++++
 .../openeuler/security/openssl/ECDHTest.java  |   27 +-
 .../openssl/KAEDisabledAlgorithmsTest.java    |    2 +-
 .../security/openssl/KAEGcmlvLenTest.java     |   53 +
 .../security/openssl/KAETestHelper.java       |    3 +-
 .../security/openssl/KAEUseEngineTest.java    |   60 +-
 .../security/openssl/KaeProviderTest.java     |   32 +-
 .../openeuler/security/openssl/SM2Test.java   |  175 +++
 .../jca/PreferredProviderNegativeTest.java    |    2 +-
 .../security/openssl/SM2CipherBenchmark.java  |  116 ++
 .../openssl/SM2SignatureBenchmark.java        |  104 ++
 49 files changed, 5990 insertions(+), 333 deletions(-)
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAECurveDB.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECKeyFactory.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECParameters.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECPrivateKeyImpl.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECPublicKeyImpl.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAENamedCurve.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2Cipher.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2KeyPairGenerator.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2Signature.java
 create mode 100644 src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_cipher_sm2.c
 create mode 100644 src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_signature_sm2.c
 create mode 100644 src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/openssl1_macro.h
 create mode 100644 src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/openssl3_macro.h
 create mode 100644 src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/ssl_utils.c
 create mode 100644 src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/ssl_utils.h
 create mode 100644 test/jdk/org/openeuler/security/openssl/KAEGcmlvLenTest.java
 create mode 100644 test/jdk/org/openeuler/security/openssl/SM2Test.java
 create mode 100644 test/micro/org/openeuler/bench/security/openssl/SM2CipherBenchmark.java
 create mode 100644 test/micro/org/openeuler/bench/security/openssl/SM2SignatureBenchmark.java

diff --git a/make/modules/jdk.crypto.kaeprovider/Lib.gmk b/make/modules/jdk.crypto.kaeprovider/Lib.gmk
index 2b01e3ed4..02c24ed2e 100644
--- a/make/modules/jdk.crypto.kaeprovider/Lib.gmk
+++ b/make/modules/jdk.crypto.kaeprovider/Lib.gmk
@@ -36,7 +36,7 @@ ifeq ($(ENABLE_KAE), true)
         CXXFLAGS := $(CXXFLAGS_JDKLIB), \
         LDFLAGS := $(LDFLAGS_JDKLIB) \
             $(call SET_SHARED_LIBRARY_ORIGIN), \
-        LIBS_unix := $(LIBDL) -lssl -lcrypto, \
+        LIBS_unix := $(LIBDL) -lm -pthread, \
     ))
 
     TARGETS += $(BUILD_LIBJ2KAE)
diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java
index 8d7441a2e..c2a6b9caf 100644
--- a/src/java.base/share/classes/module-info.java
+++ b/src/java.base/share/classes/module-info.java
@@ -335,6 +335,7 @@ module java.base {
         jdk.crypto.kaeprovider,
         jdk.naming.dns;
     exports sun.security.pkcs to
+        jdk.crypto.kaeprovider,
         jdk.crypto.ec,
         jdk.jartool;
     exports sun.security.provider to
diff --git a/src/java.base/share/classes/sun/security/util/KnownOIDs.java b/src/java.base/share/classes/sun/security/util/KnownOIDs.java
index 8cd0a03a3..97f599c7b 100644
--- a/src/java.base/share/classes/sun/security/util/KnownOIDs.java
+++ b/src/java.base/share/classes/sun/security/util/KnownOIDs.java
@@ -328,6 +328,9 @@ public enum KnownOIDs {
     brainpoolP384r1("1.3.36.3.3.2.8.1.1.11"),
     brainpoolP512r1("1.3.36.3.3.2.8.1.1.13"),
 
+    // sm2
+    sm2p256v1("1.2.156.10197.1.301"),
+
     // Certicom 1.3.132.*
     sect163k1("1.3.132.0.1", "sect163k1", "NIST K-163"),
     sect163r1("1.3.132.0.2"),
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEConfig.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEConfig.java
index a4eb57770..1b185abd5 100644
--- a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEConfig.java
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEConfig.java
@@ -51,7 +51,10 @@ public class KAEConfig {
           "kae.hmac",
           "kae.rsa",
           "kae.dh",
-          "kae.ec"
+          "kae.ec",
+          // sm2 divide into two parts, be careful with offset when adding new algorithms
+          "kae.sm2.cipher",
+          "kae.sm2.signature"
   };
 
   // these property names indicate whether KAE hardware acceleration is enabled for each algorithm
@@ -62,9 +65,17 @@ public class KAEConfig {
           "kae.hmac.useKaeEngine",
           "kae.rsa.useKaeEngine",
           "kae.dh.useKaeEngine",
-          "kae.ec.useKaeEngine"
+          "kae.ec.useKaeEngine",
+          "kae.sm2.useKaeEngine"
   };
 
+  // digestOffset is [kae.md5, kae.sha256, kae.sha384, kae.sm3].length - [kae.digest.useKaeEngine].length
+  private static int digestOffset = 3;
+
+  // digestAlgorithmLen is [kae.md5, kae.sha256, kae.sha384, kae.sm3].length
+  private static int digestAlgorithmLen = 4;
+
+
   // algorithm names
   private static final String[] algorithmNames = new String[]{
           "md5",
@@ -95,7 +106,8 @@ public class KAEConfig {
           "hmac-sha512",
           "rsa",
           "dh",
-          "ec"
+          "ec",
+          "sm2"
   };
 
   // algorithm name and algorithm index mapping
@@ -201,16 +213,20 @@ public class KAEConfig {
       }
       useKaeProviderCategoryMap.put(useKaeProviderPropertyNames[i], categoryFlagsForProvider[i]);
     }
-    int offset = useKaeProviderPropertyNames.length - useKaeEnginePropertyNames.length;
-    int digestAlgorithmLen = offset + 1;
+
     // digest
     System.arraycopy(categoryFlagsForProvider, 0, useKaeProviderFlags, 0, digestAlgorithmLen);
 
     // non-digest
     for (int i = digestAlgorithmLen; i < useKaeProviderFlags.length; i++) {
       Integer algorithmCategoryIndex = algorithmNameCategoryMap.get(algorithmNames[i]);
-      if (categoryFlagsForProvider[algorithmCategoryIndex + offset]) {
-        useKaeProviderFlags[i] = true;
+      // sm2 special treatment
+      if (algorithmNames[i] == "sm2") {
+        // cipher || signature
+        useKaeProviderFlags[i] = categoryFlagsForProvider[algorithmCategoryIndex + digestOffset] || categoryFlagsForProvider[algorithmCategoryIndex + digestOffset + 1];
+      }
+      else {
+        useKaeProviderFlags[i] = categoryFlagsForProvider[algorithmCategoryIndex + digestOffset];
       }
     }
 
@@ -239,7 +255,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]);
@@ -248,8 +265,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]);
@@ -301,6 +319,7 @@ public class KAEConfig {
    * 4 : rsa
    * 5 : dh
    * 6 : ec
+   * 7 : sm2
    */
   private static void initAlgorithmNameCategoryMap() {
     algorithmNameCategoryMap.put("md5", 0);
@@ -332,6 +351,7 @@ public class KAEConfig {
     algorithmNameCategoryMap.put("rsa", 4);
     algorithmNameCategoryMap.put("dh", 5);
     algorithmNameCategoryMap.put("ec", 6);
+    algorithmNameCategoryMap.put("sm2", 7);
   }
 
   private static void initAlgorithmNameMap() {
@@ -341,7 +361,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/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAECurveDB.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAECurveDB.java
new file mode 100644
index 000000000..519045c78
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAECurveDB.java
@@ -0,0 +1,729 @@
+/*
+ * 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.math.BigInteger;
+ 
+import java.security.spec.*;
+ 
+import java.util.*;
+ 
+import sun.security.util.KnownOIDs;
+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 static final int P  = 1; // prime curve
+  private static final int B  = 2; // binary curve
+  private static final int PD = 5; // prime curve, mark as default
+  private static final int BD = 6; // binary curve, mark as default
+ 
+  private static final Map<String,KAENamedCurve> oidMap =
+          new LinkedHashMap<String,KAENamedCurve>();
+  private static final Map<String,KAENamedCurve> nameMap =
+          new HashMap<String,KAENamedCurve>();
+  private static final Map<Integer,KAENamedCurve> lengthMap =
+          new HashMap<Integer,KAENamedCurve>();
+ 
+  private static Collection<? extends KAENamedCurve> specCollection;
+ 
+  // Return a NamedCurve for the specified OID/name or null if unknown.
+  public static KAENamedCurve lookup(String name) {
+    KAENamedCurve spec = oidMap.get(name);
+    if (spec != null) {
+      return spec;
+    }
+ 
+    return nameMap.get(name.toLowerCase(Locale.ENGLISH));
+  }
+ 
+  // 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.
+  public static KAENamedCurve lookup(ECParameterSpec params) {
+    if ((params instanceof KAENamedCurve) || (params == null)) {
+      return (KAENamedCurve)params;
+    }
+ 
+    // This code allows 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(KnownOIDs o, int type, String sfield,
+                          String a, String b, String x, String y, String n, int h) {
+    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));
+ 
+    String oid = o.value();
+    KAENamedCurve params = new KAENamedCurve(o, curve, g, bi(n), h);
+    if (oidMap.put(oid, params) != null) {
+      throw new RuntimeException("Duplication oid: " + oid);
+    }
+ 
+    for (String cn : params.getNameAndAliases()) {
+      if (nameMap.put(cn.toLowerCase(Locale.ENGLISH),
+              params) != null) {
+        throw new RuntimeException("Duplication name: " + cn);
+      }
+    }
+ 
+    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);
+    }
+  }
+ 
+  static {
+    /* SEC2 prime curves */
+    add(KnownOIDs.secp112r1, P,
+            "DB7C2ABF62E35E668076BEAD208B",
+            "DB7C2ABF62E35E668076BEAD2088",
+            "659EF8BA043916EEDE8911702B22",
+            "09487239995A5EE76B55F9C2F098",
+            "A89CE5AF8724C0A23E0E0FF77500",
+            "DB7C2ABF62E35E7628DFAC6561C5",
+            1);
+ 
+    add(KnownOIDs.secp112r2, P,
+            "DB7C2ABF62E35E668076BEAD208B",
+            "6127C24C05F38A0AAAF65C0EF02C",
+            "51DEF1815DB5ED74FCC34C85D709",
+            "4BA30AB5E892B4E1649DD0928643",
+            "adcd46f5882e3747def36e956e97",
+            "36DF0AAFD8B8D7597CA10520D04B",
+            4);
+ 
+    add(KnownOIDs.secp128r1, P,
+            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
+            "E87579C11079F43DD824993C2CEE5ED3",
+            "161FF7528B899B2D0C28607CA52C5B86",
+            "CF5AC8395BAFEB13C02DA292DDED7A83",
+            "FFFFFFFE0000000075A30D1B9038A115",
+            1);
+ 
+    add(KnownOIDs.secp128r2, P,
+            "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
+            "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
+            "5EEEFCA380D02919DC2C6558BB6D8A5D",
+            "7B6AA5D85E572983E6FB32A7CDEBC140",
+            "27B6916A894D3AEE7106FE805FC34B44",
+            "3FFFFFFF7FFFFFFFBE0024720613B5A3",
+            4);
+ 
+    add(KnownOIDs.secp160k1, P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+            "0000000000000000000000000000000000000000",
+            "0000000000000000000000000000000000000007",
+            "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
+            "938CF935318FDCED6BC28286531733C3F03C4FEE",
+            "0100000000000000000001B8FA16DFAB9ACA16B6B3",
+            1);
+ 
+    add(KnownOIDs.secp160r1, P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
+            "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
+            "4A96B5688EF573284664698968C38BB913CBFC82",
+            "23A628553168947D59DCC912042351377AC5FB32",
+            "0100000000000000000001F4C8F927AED3CA752257",
+            1);
+ 
+    add(KnownOIDs.secp160r2, P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
+            "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
+            "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
+            "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
+            "0100000000000000000000351EE786A818F3A1A16B",
+            1);
+ 
+    add(KnownOIDs.secp192k1, P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
+            "000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000003",
+            "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
+            "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
+            "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
+            1);
+ 
+    add(KnownOIDs.secp192r1, PD,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+            "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
+            "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+            "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+            "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
+            1);
+ 
+    add(KnownOIDs.secp224k1, P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
+            "00000000000000000000000000000000000000000000000000000000",
+            "00000000000000000000000000000000000000000000000000000005",
+            "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
+            "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
+            "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
+            1);
+ 
+    add(KnownOIDs.secp224r1, PD,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
+            "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
+            "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
+            "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
+            1);
+ 
+    add(KnownOIDs.secp256k1, P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
+            "0000000000000000000000000000000000000000000000000000000000000000",
+            "0000000000000000000000000000000000000000000000000000000000000007",
+            "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
+            "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
+            1);
+ 
+    add(KnownOIDs.secp256r1, PD,
+            "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+            "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+            "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+            "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+            "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+            "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+            1);
+ 
+    add(KnownOIDs.secp384r1, PD,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+            "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+            "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+            "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+            1);
+ 
+    add(KnownOIDs.secp521r1, PD,
+            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+            "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+            "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+            "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+            1);
+ 
+    /* ANSI X9.62 prime curves */
+    add(KnownOIDs.prime192v2, P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+            "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
+            "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
+            "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
+            "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",
+            1);
+ 
+    add(KnownOIDs.prime192v3, P,
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+            "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
+            "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
+            "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
+            "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",
+            1);
+ 
+    add(KnownOIDs.prime239v1, P,
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+            "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
+            "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
+            "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",
+            1);
+ 
+    add(KnownOIDs.prime239v2, P,
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+            "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
+            "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
+            "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
+            "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",
+            1);
+ 
+    add(KnownOIDs.prime239v3, P,
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+            "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
+            "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
+            "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
+            "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",
+            1);
+ 
+    /* SEC2 binary curves */
+    add(KnownOIDs.sect113r1, B,
+            "020000000000000000000000000201",
+            "003088250CA6E7C7FE649CE85820F7",
+            "00E8BEE4D3E2260744188BE0E9C723",
+            "009D73616F35F4AB1407D73562C10F",
+            "00A52830277958EE84D1315ED31886",
+            "0100000000000000D9CCEC8A39E56F",
+            2);
+ 
+    add(KnownOIDs.sect113r2, B,
+            "020000000000000000000000000201",
+            "00689918DBEC7E5A0DD6DFC0AA55C7",
+            "0095E9A9EC9B297BD4BF36E059184F",
+            "01A57A6A7B26CA5EF52FCDB8164797",
+            "00B3ADC94ED1FE674C06E695BABA1D",
+            "010000000000000108789B2496AF93",
+            2);
+ 
+    add(KnownOIDs.sect131r1, B,
+            "080000000000000000000000000000010D",
+            "07A11B09A76B562144418FF3FF8C2570B8",
+            "0217C05610884B63B9C6C7291678F9D341",
+            "0081BAF91FDF9833C40F9C181343638399",
+            "078C6E7EA38C001F73C8134B1B4EF9E150",
+            "0400000000000000023123953A9464B54D",
+            2);
+ 
+    add(KnownOIDs.sect131r2, B,
+            "080000000000000000000000000000010D",
+            "03E5A88919D7CAFCBF415F07C2176573B2",
+            "04B8266A46C55657AC734CE38F018F2192",
+            "0356DCD8F2F95031AD652D23951BB366A8",
+            "0648F06D867940A5366D9E265DE9EB240F",
+            "0400000000000000016954A233049BA98F",
+            2);
+ 
+    add(KnownOIDs.sect163k1, B,
+            "0800000000000000000000000000000000000000C9",
+            "000000000000000000000000000000000000000001",
+            "000000000000000000000000000000000000000001",
+            "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
+            "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
+            "04000000000000000000020108A2E0CC0D99F8A5EF",
+            2);
+ 
+    add(KnownOIDs.sect163r1, B,
+            "0800000000000000000000000000000000000000C9",
+            "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
+            "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
+            "0369979697AB43897789566789567F787A7876A654",
+            "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
+            "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B",
+            2);
+ 
+    add(KnownOIDs.sect163r2, BD,
+            "0800000000000000000000000000000000000000C9",
+            "000000000000000000000000000000000000000001",
+            "020A601907B8C953CA1481EB10512F78744A3205FD",
+            "03F0EBA16286A2D57EA0991168D4994637E8343E36",
+            "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
+            "040000000000000000000292FE77E70C12A4234C33",
+            2);
+ 
+    add(KnownOIDs.sect193r1, B,
+            "02000000000000000000000000000000000000000000008001",
+            "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
+            "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
+            "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
+            "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
+            "01000000000000000000000000C7F34A778F443ACC920EBA49",
+            2);
+ 
+    add(KnownOIDs.sect193r2, B,
+            "02000000000000000000000000000000000000000000008001",
+            "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
+            "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
+            "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
+            "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
+            "010000000000000000000000015AAB561B005413CCD4EE99D5",
+            2);
+ 
+    add(KnownOIDs.sect233k1, BD,
+            "020000000000000000000000000000000000000004000000000000000001",
+            "000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000001",
+            "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
+            "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
+            "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
+            4);
+ 
+    add(KnownOIDs.sect233r1, B,
+            "020000000000000000000000000000000000000004000000000000000001",
+            "000000000000000000000000000000000000000000000000000000000001",
+            "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
+            "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
+            "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
+            "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
+            2);
+ 
+    add(KnownOIDs.sect239k1, B,
+            "800000000000000000004000000000000000000000000000000000000001",
+            "000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000001",
+            "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
+            "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
+            "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5",
+            4);
+ 
+    add(KnownOIDs.sect283k1, BD,
+            "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+            "000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000001",
+            "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
+            "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
+            "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
+            4);
+ 
+    add(KnownOIDs.sect283r1, B,
+            "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+            "000000000000000000000000000000000000000000000000000000000000000000000001",
+            "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
+            "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
+            "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
+            "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
+            2);
+ 
+    add(KnownOIDs.sect409k1, BD,
+            "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
+            "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
+            "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
+            4);
+ 
+    add(KnownOIDs.sect409r1, B,
+            "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+            "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
+            "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
+            "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
+            "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
+            2);
+ 
+    add(KnownOIDs.sect571k1, BD,
+            "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
+            "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
+            "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
+            4);
+ 
+    add(KnownOIDs.sect571r1, B,
+            "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+            "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+            "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
+            "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
+            "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
+            "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
+            2);
+ 
+    /* ANSI X9.62 binary curves */
+    add(KnownOIDs.c2tnb191v1, B,
+            "800000000000000000000000000000000000000000000201",
+            "2866537B676752636A68F56554E12640276B649EF7526267",
+            "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
+            "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
+            "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
+            "40000000000000000000000004A20E90C39067C893BBB9A5",
+            2);
+ 
+    add(KnownOIDs.c2tnb191v2, B,
+            "800000000000000000000000000000000000000000000201",
+            "401028774D7777C7B7666D1366EA432071274F89FF01E718",
+            "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
+            "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
+            "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
+            "20000000000000000000000050508CB89F652824E06B8173",
+            4);
+ 
+    add(KnownOIDs.c2tnb191v3, B,
+            "800000000000000000000000000000000000000000000201",
+            "6C01074756099122221056911C77D77E77A777E7E7E77FCB",
+            "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
+            "375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
+            "545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
+            "155555555555555555555555610C0B196812BFB6288A3EA3",
+            6);
+ 
+    add(KnownOIDs.c2tnb239v1, B,
+            "800000000000000000000000000000000000000000000000001000000001",
+            "32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
+            "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
+            "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
+            "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
+            "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447",
+            4);
+ 
+    add(KnownOIDs.c2tnb239v2, B,
+            "800000000000000000000000000000000000000000000000001000000001",
+            "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
+            "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
+            "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
+            "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
+            "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D",
+            6);
+ 
+    add(KnownOIDs.c2tnb239v3, B,
+            "800000000000000000000000000000000000000000000000001000000001",
+            "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
+            "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
+            "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
+            "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
+            "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF",
+            0xA);
+ 
+    add(KnownOIDs.c2tnb359v1, B,
+            "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
+            "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557",
+            "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988",
+            "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097",
+            "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD",
+            "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B",
+            0x4C);
+ 
+    add(KnownOIDs.c2tnb431r1, B,
+            "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001",
+            "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F",
+            "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618",
+            "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
+            "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
+            "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91",
+            0x2760);
+ 
+    /* 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(KnownOIDs.c2pnb163v1, B,
+            "080000000000000000000000000000000000000107",
+            "072546B5435234A422E0789675F432C89435DE5242",
+            "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
+            "07AF69989546103D79329FCC3D74880F33BBE803CB",
+            "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
+            "0400000000000000000001E60FC8821CC74DAEAFC1",
+            2);
+ 
+        add(KnownOIDs.c2pnb163v2, B,
+            "080000000000000000000000000000000000000107",
+            "0108B39E77C4B108BED981ED0E890E117C511CF072",
+            "0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
+            "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
+            "079F684DDF6684C5CD258B3890021B2386DFD19FC5",
+            "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7",
+            2);
+ 
+        add(KnownOIDs.c2pnb163v3, B,
+            "080000000000000000000000000000000000000107",
+            "07A526C63D3E25A256A007699F5447E32AE456B50E",
+            "03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
+            "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
+            "05B935590C155E17EA48EB3FF3718B893DF59A05D0",
+            "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309",
+            2);
+ 
+        add(KnownOIDs.c2pnb176w1, B,
+            "0100000000000000000000000000000000080000000007",
+            "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
+            "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
+            "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
+            "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
+            "00010092537397ECA4F6145799D62B0A19CE06FE26AD",
+            0xFF6E);
+ 
+        add(KnownOIDs.c2pnb208w1, B,
+            "010000000000000000000000000000000800000000000000000007",
+            "0000000000000000000000000000000000000000000000000000",
+            "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
+            "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
+            "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
+            "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D",
+            0xFE48);
+ 
+        add(KnownOIDs.c2pnb272w1, B,
+            "010000000000000000000000000000000000000000000000000000010000000000000B",
+            "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
+            "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
+            "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
+            "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
+            "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
+            0xFF06);
+ 
+        add(KnownOIDs.c2pnb304w1, B,
+            "010000000000000000000000000000000000000000000000000000000000000000000000000807",
+            "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681",
+            "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE",
+            "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614",
+            "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B",
+            "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D",
+            0xFE2E);
+ 
+        add(KnownOIDs.c2pnb368w1, B,
+            "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007",
+            "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D",
+            "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A",
+            "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F",
+            "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310",
+            "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967",
+            0xFF70);
+*/
+ 
+    /*
+     * Brainpool curves (RFC 5639)
+     * (Twisted curves are not included)
+     */
+ 
+    add(KnownOIDs.brainpoolP160r1, P,
+            "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
+            "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
+            "1E589A8595423412134FAA2DBDEC95C8D8675E58",
+            "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
+            "1667CB477A1A8EC338F94741669C976316DA6321",
+            "E95E4A5F737059DC60DF5991D45029409E60FC09",
+            1);
+ 
+    add(KnownOIDs.brainpoolP192r1, P,
+            "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
+            "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
+            "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
+            "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
+            "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
+            "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
+            1);
+ 
+    add(KnownOIDs.brainpoolP224r1, P,
+            "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
+            "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
+            "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
+            "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
+            "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
+            "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
+            1);
+ 
+    add(KnownOIDs.brainpoolP256r1, P,
+            "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
+            "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
+            "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
+            "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
+            "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
+            "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
+            1);
+ 
+    add(KnownOIDs.brainpoolP320r1, P,
+            "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
+            "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
+            "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
+            "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
+            "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
+            "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
+            1);
+ 
+    add(KnownOIDs.brainpoolP384r1, P,
+            "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
+            "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
+            "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
+            "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
+            "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
+            "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
+            1);
+ 
+    add(KnownOIDs.brainpoolP512r1, P,
+            "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
+            "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
+            "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
+            "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
+            "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
+            "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
+            1);
+ 
+    /* SM2 prime curves */
+    add(KnownOIDs.sm2p256v1, P,
+            "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",
+            "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",
+            "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",
+            "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
+            "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0",
+            "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
+            1);
+ 
+    specCollection = Collections.unmodifiableCollection(oidMap.values());
+  }
+}
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java
index 29dc09889..9f701c93e 100644
--- a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECDHKeyAgreement.java
+++ b/src/jdk.crypto.kaeprovider/linux/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/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECKeyFactory.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECKeyFactory.java
new file mode 100644
index 000000000..c02d868e3
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECKeyFactory.java
@@ -0,0 +1,308 @@
+/*
+ * 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.util.Arrays;
+
+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())) {
+            byte[] encoded = key.getEncoded();
+            try {
+                return new KAEECPrivateKeyImpl(encoded);
+            } finally {
+                Arrays.fill(encoded, (byte)0);
+            }  
+        } 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;
+            byte[] encoded = pkcsSpec.getEncoded();
+            try {
+                return new KAEECPrivateKeyImpl(encoded);
+            } finally {
+                Arrays.fill(encoded, (byte) 0);
+            }
+        } 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 extends KeySpec> T engineGetKeySpec(Key key, Class<T> 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)) {
+                byte[] encoded = key.getEncoded();
+                try {
+                    return keySpec.cast(new PKCS8EncodedKeySpec(encoded));
+                } finally {
+                    Arrays.fill(encoded, (byte)0);
+                }
+            } 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");
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java
index 73d8551b1..42da07282 100644
--- a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECKeyPairGenerator.java
+++ b/src/jdk.crypto.kaeprovider/linux/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;
@@ -63,7 +60,7 @@ public class KAEECKeyPairGenerator extends KeyPairGeneratorSpi {
         this.param = getParamsByCurve(curveName);
     }
 
-    private ECParameterSpec getParamsByCurve(String curveName) {
+    protected ECParameterSpec getParamsByCurve(String curveName) {
         byte[][] params = nativeGenerateParam(curveName);
         if (params == null) {
             throw new InvalidParameterException("unknown curve " + curveName);
@@ -125,18 +122,18 @@ 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 {
-            Class<?> pubKeyImpl = Class.forName("sun.security.ec.ECPublicKeyImpl");
+            Class<?> pubKeyImpl = Class.forName("org.openeuler.security.openssl.KAEECPublicKeyImpl");
             Constructor<?> conPubKeyImpl = pubKeyImpl.getDeclaredConstructor(ECPoint.class, ECParameterSpec.class);
             conPubKeyImpl.setAccessible(true);
-            publicKey = (ECPublicKeyImpl) conPubKeyImpl.newInstance(w, param);
+            publicKey = (KAEECPublicKeyImpl) conPubKeyImpl.newInstance(w, param);
     
-            Class<?> priKeyImpl = Class.forName("sun.security.ec.ECPrivateKeyImpl");
+            Class<?> priKeyImpl = Class.forName("org.openeuler.security.openssl.KAEECPrivateKeyImpl");
             Constructor<?> conPriKeyImpl = priKeyImpl.getDeclaredConstructor(BigInteger.class, ECParameterSpec.class);
             conPriKeyImpl.setAccessible(true);
-            privateKey = (ECPrivateKeyImpl) conPriKeyImpl.newInstance(s, param);
+            privateKey = (KAEECPrivateKeyImpl) conPriKeyImpl.newInstance(s, param);
         } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
                 IllegalAccessException | InvocationTargetException e) {
             throw new ProviderException(e);
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECParameters.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECParameters.java
new file mode 100644
index 000000000..948106ef9
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECParameters.java
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ *
+ * <pre>
+ *    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
+ * </pre>
+ *
+ * @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 extends AlgorithmParameterSpec> T
+            engineGetParameterSpec(Class<T> 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/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECPrivateKeyImpl.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECPrivateKeyImpl.java
new file mode 100644
index 000000000..23ea8f90d
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECPrivateKeyImpl.java
@@ -0,0 +1,214 @@
+/*
+ * 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.util.Arrays;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import sun.security.util.ECUtil;
+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.
+ * <p>
+ * ASN.1 syntax for EC private keys from SEC 1 v1.5 (draft):
+ *
+ * <pre>
+ * EXPLICIT TAGS
+ *
+ * ECPrivateKey ::= SEQUENCE {
+ *   version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+ *   privateKey OCTET STRING,
+ *   parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL,
+ *   publicKey [1] BIT STRING OPTIONAL
+ * }
+ * </pre>
+ *
+ * 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
+ */
+@SuppressWarnings("serial")
+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 {
+        super(encoded);
+        parseKeyBits();
+    }
+
+    /**
+     * 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);
+            Arrays.fill(privBytes, (byte)0);
+            DerValue val = DerValue.wrap(DerValue.tag_Sequence, out);
+            key = val.toByteArray();
+            val.clear();
+        } catch (Exception 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);
+            Arrays.fill(sArr, (byte)0);
+            DerOutputStream out = new DerOutputStream();
+            out.putInteger(1); // version 1
+            out.putOctetString(sOctets);
+            Arrays.fill(sOctets, (byte)0);
+            DerValue val = DerValue.wrap(DerValue.tag_Sequence, out);
+            key = val.toByteArray();
+            val.clear();
+        } catch (Exception exc) {
+            throw new AssertionError("Should not happen", 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);
+            Arrays.fill(arrCopy, (byte)0);
+        }
+        return s;
+    }
+
+    public byte[] getArrayS() {
+        if (arrayS == null) {
+            arrayS = ECUtil.sArray(getS(), params);
+        }
+        return arrayS.clone();
+    }
+
+    // see JCA doc
+    public ECParameterSpec getParams() {
+        return params;
+    }
+
+    private 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);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECPublicKeyImpl.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECPublicKeyImpl.java
new file mode 100644
index 000000000..99e6e7517
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEECPublicKeyImpl.java
@@ -0,0 +1,132 @@
+/*
+ * 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.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
+ */
+@SuppressWarnings("serial")
+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());
+    }
+}
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAENamedCurve.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAENamedCurve.java
new file mode 100644
index 000000000..e71c1c274
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAENamedCurve.java
@@ -0,0 +1,100 @@
+/*
+ * 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 sun.security.util.DerOutputStream;
+import sun.security.util.ObjectIdentifier;
+import sun.security.util.KnownOIDs;
+
+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 names with stdName followed by aliases
+    private final String[] nameAndAliases;
+
+    // well known OID
+    private final String oid;
+
+    // encoded form (as NamedCurve identified via OID)
+    private final byte[] encoded;
+
+    KAENamedCurve(KnownOIDs ko, EllipticCurve curve,
+                ECPoint g, BigInteger n, int h) {
+        super(curve, g, n, h);
+        String[] aliases = ko.aliases();
+        this.nameAndAliases = new String[aliases.length + 1];
+        nameAndAliases[0] = ko.stdName();
+        System.arraycopy(aliases, 0, nameAndAliases, 1, aliases.length);
+
+        this.oid = ko.value();
+
+        DerOutputStream out = new DerOutputStream();
+        try {
+            out.putOID(ObjectIdentifier.of(ko));
+        } catch (Exception e) {
+            throw new RuntimeException("Internal error", e);
+        }
+        encoded = out.toByteArray();
+    }
+
+    // returns the curve's standard name followed by its aliases
+    public String[] getNameAndAliases() {
+        return nameAndAliases;
+    }
+
+    public byte[] getEncoded() {
+        return encoded.clone();
+    }
+
+    public String getObjectId() {
+        return oid;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder(nameAndAliases[0]);
+        if (nameAndAliases.length > 1) {
+            sb.append(" [");
+            int j = 1;
+            while (j < nameAndAliases.length - 1) {
+                sb.append(nameAndAliases[j++]);
+                sb.append(',');
+            }
+            sb.append(nameAndAliases[j] + "]");
+        }
+        sb.append(" (" + oid + ")");
+        return sb.toString();
+    }
+}
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEProvider.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEProvider.java
index 2b1cb2449..a7085c829 100644
--- a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEProvider.java
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEProvider.java
@@ -64,18 +64,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);
+            Integer useOpensslVersion = useOpensslVersion();
+            int v = initOpenssl(useOpensslVersion, engineId, algorithmKaeFlags);
+            if (kaeDebug != null) {
+                kaeDebug.println("Use Openssl " + v);
+            }
+        } 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);
@@ -86,11 +97,23 @@ 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;
     }
 
     @SuppressWarnings({"deprecation", "this-escape"})
@@ -127,6 +150,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() {
@@ -316,10 +345,30 @@ 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.EC", "org.openeuler.security.openssl.KAEECParameters");
+        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/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2Cipher.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2Cipher.java
new file mode 100644
index 000000000..2cbd5bb51
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2Cipher.java
@@ -0,0 +1,386 @@
+/*
+ * 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<KAESM2Cipher>
+            implements Comparable<KAESM2KeyHolder> {
+        private static ReferenceQueue<KAESM2Cipher> referenceQueue = new ReferenceQueue<>();
+        private static Set<KAESM2KeyHolder> 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();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2KeyPairGenerator.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2KeyPairGenerator.java
new file mode 100644
index 000000000..1bc9365d3
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/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);
+    }
+}
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2Signature.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAESM2Signature.java
new file mode 100644
index 000000000..7e9ad85ce
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/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<KAESM2Signature>
+            implements Comparable<SM2SignCtxHolder> {
+        private static ReferenceQueue<KAESM2Signature> referenceQueue = new ReferenceQueue<>();
+        private static Set<SM2SignCtxHolder> 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());
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEUtils.java b/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEUtils.java
index a4a005285..093905e43 100644
--- a/src/jdk.crypto.kaeprovider/linux/classes/org/openeuler/security/openssl/KAEUtils.java
+++ b/src/jdk.crypto.kaeprovider/linux/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/src/jdk.crypto.kaeprovider/linux/conf/security/kaeprovider.conf b/src/jdk.crypto.kaeprovider/linux/conf/security/kaeprovider.conf
index 49ff98fd8..40c6c2c10 100644
--- a/src/jdk.crypto.kaeprovider/linux/conf/security/kaeprovider.conf
+++ b/src/jdk.crypto.kaeprovider/linux/conf/security/kaeprovider.conf
@@ -18,22 +18,20 @@
 # 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:
 #     true : enable KAE hardware acceleration by default
 #     false: use openssl soft calculation by default
 # The digest/sm4/rsa/dh category algorithm enable KAE hardware acceleration by default.
-# The aes/hmac/ec category algorithm use openssl soft calculation by default.
-# The ec category algorithm configuration does not take effect temporarily. and it
+# The aes/hmac/ec/sm2 category algorithm use openssl soft calculation by default.
+# The ec/sm2 category algorithm configuration does not take effect temporarily. and it
 # currently does not support KAE hardware acceleration, temporarily use openssl soft calculation.
 # kae.digest.useKaeEngine=true
 # kae.aes.useKaeEngine=false
@@ -42,15 +40,17 @@
 # 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
 #
 # Users can disable unsupported algorithms through the following property configuration.
 # Disable algorithm to enable KAE hardware acceleration, use openssl soft algorithm instead.
-# The sha256, sha384 algorithms are disabled by default.
+# The sha256, sha384 , sm2 algorithms are disabled by default.
 # digest : md5,sha256,sha384,sm3
 # aes    : aes-128-ecb,aes-128-cbc,aes-128-ctr,aes-128-gcm,
 #          aes-192-ecb,aes-192-cbc,aes-192-ctr,aes-192-gcm,
@@ -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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_cipher_rsa.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_cipher_rsa.c
index 557d3965b..919595392 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_cipher_rsa.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/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);
     }
 }
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_cipher_sm2.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_cipher_sm2.c
new file mode 100644
index 000000000..915a88dda
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_cipher_sm2.c
@@ -0,0 +1,370 @@
+/*
+ * 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 <openssl/evp.h>
+#include <openssl/ec.h>
+#include <stdbool.h>
+#include <string.h>
+#include "kae_util.h"
+#include "kae_log.h"
+#include "kae_exception.h"
+#include "ssl_utils.h"
+#include "org_openeuler_security_openssl_KAESM2Cipher.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_EC_KEY(pkey , eckey) <= 0) {
+        KAE_ThrowFromOpenssl(env, "EVP_PKEY_assign_EC_KEY", KAE_ThrowRuntimeException);
+        goto cleanup;
+    }
+
+    // set the alias type of the key
+    // EVP_PKEY_set_alias_type is removed since openssl 3
+    if (SSL_UTILS_EVP_PKEY_set_alias_type(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
+    // EVP_PKEY_set_alias_type is removed since openssl 3
+    if (SSL_UTILS_EVP_PKEY_set_alias_type(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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_digest.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_digest.c
index 82bf477da..bd9d4f36e 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_digest.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/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();
+    // change from macro, "# define EVP_MD_CTX_create()     EVP_MD_CTX_new()" in openssl 1 and 3
+    ctx = SSL_UTILS_EVP_MD_CTX_create();
     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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_exception.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_exception.c
index c0579ebf4..277da3208 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_exception.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_exception.c
@@ -27,6 +27,7 @@
 #include "kae_log.h"
 #include "kae_exception.h"
 #include "openssl_ad.h"
+#include "ssl_utils.h"
 
 void KAE_ThrowByName(JNIEnv* env, const char* name, const char* msg) {
     jclass cls = (*env)->FindClass(env, name);
@@ -77,6 +78,10 @@ void KAE_ThrowBadPaddingException(JNIEnv* env, const char* msg) {
     KAE_ThrowByName(env, "javax/crypto/BadPaddingException", msg);
 }
 
+void KAE_ThrowExceptionInInitializerError(JNIEnv* env, const char* msg) {
+    KAE_ThrowByName(env, "java/lang/ExceptionInInitializerError", msg);
+}
+
 void KAE_ThrowInvalidKeyException(JNIEnv* env, const char* msg) {
     KAE_ThrowByName(env, "java/security/InvalidKeyException", msg);
 }
@@ -93,7 +98,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;
@@ -101,10 +106,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 func = ERR_GET_FUNC(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, func=%x, reason=%x, file=%s, line=%d, estring=%s, data=%s", msg, err,
                   lib, func, reason, file, line, estring, (flags & ERR_TXT_STRING) ? data : "(no data)");
         // Ignore exceptions in RSA_verify_PKCS1_PSS_mgf1 function
@@ -119,7 +125,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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_exception.h b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_exception.h
index f33f993e4..b5b328fd3 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_exception.h
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_exception.h
@@ -43,6 +43,8 @@ void KAE_ThrowRuntimeException(JNIEnv* env, const char* msg);
 
 void KAE_ThrowBadPaddingException(JNIEnv* env, const char* msg);
 
+void KAE_ThrowExceptionInInitializerError(JNIEnv* env, const char* msg);
+
 /* Throw InvalidKeyException */
 void KAE_ThrowInvalidKeyException(JNIEnv* env, const char* msg);
 
diff --git a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_hmac.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_hmac.c
index ad7b86ecd..440219321 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_hmac.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keyagreement_dh.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keyagreement_dh.c
index e9dfa4094..f9e50fb85 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keyagreement_dh.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keyagreement_ecdh.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keyagreement_ecdh.c
index b0877a25e..49b47c3e8 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keyagreement_ecdh.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/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,13 +68,13 @@ 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);
 
     // Initialization of secret key.
     int expectSecretLen = 0;
 
-    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
@@ -81,21 +82,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.
-    expectSecretLen = (EC_GROUP_get_degree(group) + 7) / 8;
+    expectSecretLen = (SSL_UTILS_EC_GROUP_get_degree(group) + 7) / 8;
 
     if ((shareKey = malloc(expectSecretLen)) == NULL) {
         KAE_ThrowOOMException(env, "malloc error");
@@ -104,7 +105,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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_dh.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_dh.c
index 6315cc6ee..0c7faba86 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_dh.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_dh.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_ec.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_ec.c
index 0449f8a26..63928444b 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_ec.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c
index 84c2ed109..a553d8793 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c
@@ -26,6 +26,7 @@
 #include "kae_log.h"
 #include "kae_util.h"
 #include "kae_exception.h"
+#include "ssl_utils.h"
 #include "org_openeuler_security_openssl_KAERSAKeyPairGenerator.h"
 #define KAE_RSA_PARAM_SIZE 8
 
@@ -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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_provider.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_provider.c
index f4f71005a..ea609bd9b 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_provider.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_provider.c
@@ -27,69 +27,50 @@
 #include <dlfcn.h>
 #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();
 }
 
 /*
diff --git a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_signature_rsa.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_signature_rsa.c
index 496ebc775..6030b7cf7 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_signature_rsa.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/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;
     }
@@ -103,13 +104,13 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature
     static ENGINE* kaeEngine = NULL;
     kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : 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;
     }
@@ -120,7 +121,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;
@@ -134,7 +135,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;
@@ -167,13 +168,13 @@ JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNa
     static ENGINE* kaeEngine = NULL;
     kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : 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;
     }
@@ -194,7 +195,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;
@@ -210,7 +211,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;
     }
@@ -220,7 +221,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;
     }
@@ -230,13 +231,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;
     }
@@ -260,13 +261,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;
     }
@@ -277,7 +278,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;
@@ -291,7 +292,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;
@@ -326,13 +327,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;
     }
@@ -353,7 +354,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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_signature_sm2.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_signature_sm2.c
new file mode 100644
index 000000000..9025911bf
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_signature_sm2.c
@@ -0,0 +1,288 @@
+/*
+ * 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 <openssl/evp.h>
+#include <openssl/ec.h>
+#include <stdbool.h>
+#include <string.h>
+
+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;
+    }
+
+    // set default_sm_id in pkey_ctx
+    // 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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c
index 67151f53a..54a6fb52e 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_symmetric_cipher.c
@@ -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;
@@ -146,6 +147,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
     const EVP_CIPHER* cipher = NULL;
     ENGINE* kaeEngine = NULL;
     int keyLength = (*env)->GetArrayLength(env, key);
+    int ivLength = 0;
 
     const char* algo = (*env)->GetStringUTFChars(env, cipherType, 0);
     if (StartsWith("aes", algo)) {
@@ -158,38 +160,54 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
 
     KAE_TRACE("KAESymmetricCipherBase_nativeInit: kaeEngine => %p", kaeEngine);
 
-    (*env)->ReleaseStringUTFChars(env, cipherType, algo);
     if (cipher == NULL) {
         KAE_ThrowOOMException(env, "create EVP_CIPHER fail");
         goto cleanup;
     }
-    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;
     }
 
     if (iv != NULL) {
         ivBytes = (*env)->GetByteArrayElements(env, iv, NULL);
+        ivLength = (*env)->GetArrayLength(env, iv);
     }
     if (key != NULL) {
         keyBytes = (*env)->GetByteArrayElements(env, key, NULL);
     }
 
-    if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, (const unsigned char*)keyBytes,
-                           (const unsigned char*)ivBytes, encrypt ? 1 : 0)) {
+    if (!SSL_UTILS_EVP_CipherInit_ex(ctx, cipher, kaeEngine, NULL,
+                           NULL, encrypt ? 1 : 0)) {
         KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex failed", KAE_ThrowRuntimeException);
         goto cleanup;
     }
 
-    EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0);
+    if (strcasecmp(algo + 8, "gcm") == 0) {
+        /* Set IV length if default 12 bytes (96 bits) is not appropriate */
+        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 (!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;
+    }
+
+    SSL_UTILS_EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0);
+
+    (*env)->ReleaseStringUTFChars(env, cipherType, algo);
     FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength);
     return (jlong)ctx;
 
 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);
     return 0;
 }
@@ -247,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;
     }
@@ -291,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;
@@ -348,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;
         }
@@ -356,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;
         }
@@ -375,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;
         }
@@ -407,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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_util.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_util.c
index 471ae834b..6bdd9b5ad 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_util.c
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_util.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_util.h b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_util.h
index 6eb980d62..5df310ba7 100644
--- a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/kae_util.h
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/openssl1_macro.h b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/openssl1_macro.h
new file mode 100644
index 000000000..2bc3ad3f5
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/openssl1_macro.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2025, 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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/openssl3_macro.h b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/openssl3_macro.h
new file mode 100644
index 000000000..b0fe3fa95
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/openssl3_macro.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2025, 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/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/ssl_utils.c b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/ssl_utils.c
new file mode 100644
index 000000000..be752b5eb
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/ssl_utils.c
@@ -0,0 +1,1368 @@
+/*
+ * Copyright (c) 2025, 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 <dlfcn.h>
+#include <openssl/rsa.h>
+#include <string.h>
+#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(EVP_PKEY *pkey, int type)
+{
+    // EVP_PKEY_set_alias_type is removed from openssl 3.
+    if (get_sslVersion() == V3) {
+        // https://github.com/openssl/openssl/issues/14379
+        KAE_TRACE("OpenSSL hint: EVP_PKEY_set_alias_type is deprecated on openssl 3.");
+        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, (char *)(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[] = {
+        // COMMOM_FUNC
+        "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",
+        // V1_FUNC
+        "EVP_PKEY_size",
+        "EVP_PKEY_set_alias_type",
+        // V3_FUNC
+        "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[] = {
+        // COMMON_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,
+        // V1_FUNC
+        (void**)&_EVP_PKEY_size,
+        (void**)&_EVP_PKEY_set_alias_type,
+        // V3_FUNC
+        (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;
+    // set model RTLD_NOW | RTLD_GLOBAL Otherwise openssl3 env cannot get KAEEngine
+    res = dlopen(lib_name, RTLD_NOW | RTLD_GLOBAL);
+    if (res == NULL && useOpensslVersion == 0) {
+        _sslVersion = V1;
+        lib_name = "libssl.so.1.1";
+        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_ThrowExceptionInInitializerError(env, msg);
+        free(msg);
+        return res;
+    }
+
+    // check engine with openssl version
+    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(libssl.so.1.1). 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(libssl.so.3). Please check jdk config kae.useOpensslVersion or OPENSSL_ENGINES");
+            return;
+        }
+    }
+}
+
+int get_sslVersion()
+{
+    return _sslVersion;
+}
\ No newline at end of file
diff --git a/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/ssl_utils.h b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/ssl_utils.h
new file mode 100644
index 000000000..b49c79cdb
--- /dev/null
+++ b/src/jdk.crypto.kaeprovider/linux/native/libj2kae/org/openeuler/security/openssl/ssl_utils.h
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2025, 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 <openssl/ssl.h>
+
+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(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/test/jdk/org/openeuler/security/openssl/ECDHTest.java b/test/jdk/org/openeuler/security/openssl/ECDHTest.java
index 791fec252..9a229a311 100644
--- a/test/jdk/org/openeuler/security/openssl/ECDHTest.java
+++ b/test/jdk/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;
 import java.security.spec.*;
 import java.security.KeyFactory;
 import java.security.interfaces.ECPrivateKey;
@@ -78,31 +74,30 @@ public class ECDHTest {
 
         KeyFactory keyFactory = KeyFactory.getInstance("EC");
         ECPrivateKeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger("20135071615800221517902437867016717688420688735490569283842831828983"), PARAMS);
-        ECPrivateKeyImpl ecPrivKey = (ECPrivateKeyImpl)keyFactory.generatePrivate(privateKeySpec);
-
+        ECPrivateKey ecPrivKey = (ECPrivateKey) keyFactory.generatePrivate(privateKeySpec);
         ECPoint ecPoint = new ECPoint(new BigInteger("9490267631555585552004372465967099662885480699902812460349461311384"), new BigInteger("1974573604976093871117393045089050409882519645527397292712281520811"));
         ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(ecPoint,PARAMS);
-        ECPublicKeyImpl ecPublicKey = (ECPublicKeyImpl)keyFactory.generatePublic(publicKeySpec);
-        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});
+        ECPublicKey ecPublicKey = (ECPublicKey)keyFactory.generatePublic(publicKeySpec);
+        testKeyAgreement((KAEECPrivateKeyImpl) ecPrivKey, (KAEECPublicKeyImpl) 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});
     }
 
     public static void testKeyPairByParam(ECParameterSpec PARAMS) throws Exception {
         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/test/jdk/org/openeuler/security/openssl/KAEDisabledAlgorithmsTest.java b/test/jdk/org/openeuler/security/openssl/KAEDisabledAlgorithmsTest.java
index e8d767f0c..a6839283f 100644
--- a/test/jdk/org/openeuler/security/openssl/KAEDisabledAlgorithmsTest.java
+++ b/test/jdk/org/openeuler/security/openssl/KAEDisabledAlgorithmsTest.java
@@ -150,7 +150,7 @@ public class KAEDisabledAlgorithmsTest {
         }
 
         // test other algorithms that are not disabled (except ec)
-        for (int i = 0; i < useKaeEngineFlags.length - 1; i++) {
+        for (int i = 0; i < useKaeEngineFlags.length - 2; i++) {
             if (!disabledAlgorithmIndexSet.contains(i) && !useKaeEngineFlags[i]) {
                 throw new RuntimeException(KAETestHelper.getAlgorithmName(i) + " algorithm is not disabled");
             }
diff --git a/test/jdk/org/openeuler/security/openssl/KAEGcmlvLenTest.java b/test/jdk/org/openeuler/security/openssl/KAEGcmlvLenTest.java
new file mode 100644
index 000000000..935e4f889
--- /dev/null
+++ b/test/jdk/org/openeuler/security/openssl/KAEGcmlvLenTest.java
@@ -0,0 +1,53 @@
+import org.openeuler.security.openssl.KAEProvider;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.security.Security;
+import java.util.Arrays;
+
+/**
+ * @test
+ * @summary Basic test for AES/GCM Iv
+ * @modules jdk.crypto.kaeprovider/org.openeuler.security.openssl
+ * @requires os.arch=="aarch64"
+ * @run main KAEGcmIvLenTest
+ */
+public class KAEGcmIvLenTest {
+    private static String plainText = "helloworldhellow";  // 16bytes for NoPadding
+    private static String shortPlainText = "helloworld"; // 5 bytes for padding
+    private static SecretKeySpec ks = new SecretKeySpec("AESEncryptionKey".getBytes(StandardCharsets.UTF_8), "AES");  // key has 16 bytes
+    private static int[] ivLens = {12, 16};
+    public static void main(String[] args) throws Exception {
+        Security.addProvider(new KAEProvider());
+        for (int ivLen : ivLens) {
+            testGcm(plainText,"AES/GCM/NoPadding", "KAEProvider", "SunJCE", ivLen);
+            testGcm(plainText,"AES/GCM/NoPadding", "SunJCE", "KAEProvider", ivLen);
+            testGcm(shortPlainText,"AES/GCM/NoPadding", "KAEProvider", "SunJCE", ivLen);
+            testGcm(shortPlainText,"AES/GCM/NoPadding", "SunJCE", "KAEProvider", ivLen);
+        }
+
+    }
+
+    private static void testGcm(String plainText, String algo, String encryptProvider, String decryptProvider, int ivLen) throws Exception {
+        Cipher enCipher = Cipher.getInstance(algo, encryptProvider);
+        enCipher.init(Cipher.ENCRYPT_MODE, ks, getIv(ivLen));
+        byte[] cipherText = enCipher.doFinal(plainText.getBytes());
+
+        Cipher deCipher = Cipher.getInstance(algo, decryptProvider);
+        deCipher.init(Cipher.DECRYPT_MODE, ks, getIv(ivLen));
+        byte[] origin = deCipher.doFinal(cipherText);
+
+        if (!Arrays.equals(plainText.getBytes(), origin)) {
+            throw new RuntimeException("gcm decryption failed, algo = " + algo);
+        }
+    }
+
+    private static GCMParameterSpec getIv(int ivLen) {
+        if (ivLen == 16) {
+            return new GCMParameterSpec(128, "abcdefghabcdefgh".getBytes(StandardCharsets.UTF_8));
+        }
+        return new GCMParameterSpec(96, "abcdefghabcd".getBytes(StandardCharsets.UTF_8));
+    }
+}
\ No newline at end of file
diff --git a/test/jdk/org/openeuler/security/openssl/KAETestHelper.java b/test/jdk/org/openeuler/security/openssl/KAETestHelper.java
index 59ad91ddc..27a75290a 100644
--- a/test/jdk/org/openeuler/security/openssl/KAETestHelper.java
+++ b/test/jdk/org/openeuler/security/openssl/KAETestHelper.java
@@ -67,7 +67,8 @@ class KAETestHelper {
             "hmac-sha512",
             "rsa",
             "dh",
-            "ec"
+            "ec",
+            "sm2"
     };
     private static final Map<String, Integer> ALGORITHM_NAME_MAP = new HashMap<>();
 
diff --git a/test/jdk/org/openeuler/security/openssl/KAEUseEngineTest.java b/test/jdk/org/openeuler/security/openssl/KAEUseEngineTest.java
index a5b9b5386..8ebb7b7f6 100644
--- a/test/jdk/org/openeuler/security/openssl/KAEUseEngineTest.java
+++ b/test/jdk/org/openeuler/security/openssl/KAEUseEngineTest.java
@@ -44,7 +44,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
@@ -52,8 +53,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 -Dall.test=default -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true 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 -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
  * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.sm4.useKaeEngine=true KAEUseEngineTest
@@ -61,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
@@ -69,94 +71,105 @@ 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),
+    SM2_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
+    }, 7, 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;
@@ -208,7 +221,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<File> files = new ArrayList<>();
diff --git a/test/jdk/org/openeuler/security/openssl/KaeProviderTest.java b/test/jdk/org/openeuler/security/openssl/KaeProviderTest.java
index 0f4425b6d..f4fb07d50 100644
--- a/test/jdk/org/openeuler/security/openssl/KaeProviderTest.java
+++ b/test/jdk/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
@@ -54,7 +51,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";
@@ -86,6 +85,7 @@ public class KaeProviderTest {
     testRsa();
     testDh();
     testEc();
+    testSM2();
   }
 
   public static void testMd5() throws NoSuchAlgorithmException {
@@ -151,6 +151,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/test/jdk/org/openeuler/security/openssl/SM2Test.java b/test/jdk/org/openeuler/security/openssl/SM2Test.java
new file mode 100644
index 000000000..d7b4a5d56
--- /dev/null
+++ b/test/jdk/org/openeuler/security/openssl/SM2Test.java
@@ -0,0 +1,175 @@
+/*
+ * 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
+ * @modules jdk.crypto.kaeprovider/org.openeuler.security.openssl
+ * @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);
+    }
+}
\ No newline at end of file
diff --git a/test/jdk/sun/security/jca/PreferredProviderNegativeTest.java b/test/jdk/sun/security/jca/PreferredProviderNegativeTest.java
index 52cfbab4e..3b5544ac2 100644
--- a/test/jdk/sun/security/jca/PreferredProviderNegativeTest.java
+++ b/test/jdk/sun/security/jca/PreferredProviderNegativeTest.java
@@ -108,7 +108,7 @@ public class PreferredProviderNegativeTest {
         String expected;
         String value = args[1];
 
-        if (Security.getProperty("security.provider.1").equals("KAEProvider")) {
+        if (Security.getProperty("security.provider.1").equals("org.openeuler.security.openssl.KAEProvider")) {
             expected = "KAEProvider";
         } else {
             expected = "SunJCE";
diff --git a/test/micro/org/openeuler/bench/security/openssl/SM2CipherBenchmark.java b/test/micro/org/openeuler/bench/security/openssl/SM2CipherBenchmark.java
new file mode 100644
index 000000000..0171504ed
--- /dev/null
+++ b/test/micro/org/openeuler/bench/security/openssl/SM2CipherBenchmark.java
@@ -0,0 +1,116 @@
+/*
+ * 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;
+    }
+}
\ No newline at end of file
diff --git a/test/micro/org/openeuler/bench/security/openssl/SM2SignatureBenchmark.java b/test/micro/org/openeuler/bench/security/openssl/SM2SignatureBenchmark.java
new file mode 100644
index 000000000..3fef9e505
--- /dev/null
+++ b/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;
+    }
+}
\ No newline at end of file
-- 
2.43.0