Projects
Mega:23.09
openjdk-1.8.0
_service:tar_scm:kae-usability-enhancement.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:kae-usability-enhancement.patch of Package openjdk-1.8.0
From 8545f560d406db592303b09fc576c13ba9a8caa0 Mon Sep 17 00:00:00 2001 From: kuenking111 <wangkun49@huawei.com> Date: Sat, 3 Sep 2022 14:18:42 +0000 Subject: [PATCH 2/6] kae-usability-enhancement --- jdk/make/CopyFiles.gmk | 2 +- jdk/make/mapfiles/libj2kae/mapfile-vers | 1 + jdk/src/share/lib/security/kaeprovider.conf | 65 ++- .../openeuler/security/openssl/KAEConfig.java | 386 ++++++++++++++++++ .../openeuler/security/openssl/KAELog.java | 183 +++++++++ .../security/openssl/KAEProvider.java | 151 ++++--- .../security/openssl/KAESM4Cipher.java | 181 ++++++++ .../security/openssl/kae_cipher_rsa.c | 13 +- .../openeuler/security/openssl/kae_digest.c | 9 +- .../org/openeuler/security/openssl/kae_hmac.c | 9 +- .../security/openssl/kae_keyagreement_dh.c | 4 +- .../openssl/kae_keypairgenerator_dh.c | 4 +- .../openssl/kae_keypairgenerator_rsa.c | 6 +- .../openeuler/security/openssl/kae_provider.c | 54 ++- .../security/openssl/kae_signature_rsa.c | 21 +- .../security/openssl/kae_symmetric_cipher.c | 9 +- .../org/openeuler/security/openssl/kae_util.c | 138 ++++++- .../org/openeuler/security/openssl/kae_util.h | 51 ++- .../openeuler/security/openssl/AESTest.java | 114 ++++++ .../openeuler/security/openssl/DHTest.java | 9 +- .../security/openssl/DigestTest.java | 60 +++ .../openeuler/security/openssl/ECDHTest.java | 1 + .../openeuler/security/openssl/HmacTest.java | 88 ++++ .../security/openssl/KAEConfTest.java | 121 ++++++ .../openssl/KAEDisabledAlgorithmsTest.java | 164 ++++++++ .../security/openssl/KAEEngineIdTest.java | 76 ++++ .../security/openssl/KAELogTest.java | 126 ++++++ .../security/openssl/KAETestHelper.java | 209 ++++++++++ .../security/openssl/KAEUseEngineTest.java | 262 ++++++++++++ .../security/openssl/KaeDebugLogTest.java | 88 ++++ .../security/openssl/KaeProviderTest.java | 170 ++++++++ .../openeuler/security/openssl/RSATest.java | 137 +++++++ .../openeuler/security/openssl/SM3Test.java | 54 --- .../openeuler/security/openssl/SM4Test.java | 62 ++- 34 files changed, 2844 insertions(+), 184 deletions(-) create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAEConfig.java create mode 100644 jdk/src/solaris/classes/org/openeuler/security/openssl/KAELog.java create mode 100644 jdk/test/org/openeuler/security/openssl/AESTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/DigestTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/HmacTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/KAEConfTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/KAEDisabledAlgorithmsTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/KAEEngineIdTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/KAELogTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/KAETestHelper.java create mode 100644 jdk/test/org/openeuler/security/openssl/KAEUseEngineTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/KaeDebugLogTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/KaeProviderTest.java create mode 100644 jdk/test/org/openeuler/security/openssl/RSATest.java delete mode 100644 jdk/test/org/openeuler/security/openssl/SM3Test.java diff --git a/jdk/make/CopyFiles.gmk b/jdk/make/CopyFiles.gmk index 2a6fc0932..806d7bec1 100644 --- a/jdk/make/CopyFiles.gmk +++ b/jdk/make/CopyFiles.gmk @@ -634,7 +634,7 @@ endif ifeq ($(ENABLE_KAE), true) ifeq ($(OPENJDK_TARGET_CPU_ARCH), aarch64) - KAE_CONF_PATH= $(JDK_OUTPUTDIR)/lib/ext + KAE_CONF_PATH= $(JDK_OUTPUTDIR)/lib $(KAE_CONF_PATH)/kaeprovider.conf: $(JDK_TOPDIR)/src/share/lib/security/kaeprovider.conf $(call install-file) diff --git a/jdk/make/mapfiles/libj2kae/mapfile-vers b/jdk/make/mapfiles/libj2kae/mapfile-vers index 128d1e322..a1bdb830b 100644 --- a/jdk/make/mapfiles/libj2kae/mapfile-vers +++ b/jdk/make/mapfiles/libj2kae/mapfile-vers @@ -27,6 +27,7 @@ SUNWprivate_1.1 { global: JNI_OnLoad; Java_org_openeuler_security_openssl_KAEProvider_initOpenssl; + Java_org_openeuler_security_openssl_KAEProvider_getEngineFlags; Java_org_openeuler_security_openssl_KAEDigest_nativeInit; Java_org_openeuler_security_openssl_KAEDigest_nativeUpdate; Java_org_openeuler_security_openssl_KAEDigest_nativeDigest; diff --git a/jdk/src/share/lib/security/kaeprovider.conf b/jdk/src/share/lib/security/kaeprovider.conf index a48969669..cc50611d1 100644 --- a/jdk/src/share/lib/security/kaeprovider.conf +++ b/jdk/src/share/lib/security/kaeprovider.conf @@ -1,9 +1,13 @@ # -# This is the config file for KAEProvider +# This is the config file for KAEProvider. +# These configuration properties support the use of jdk system properties, +# and jdk system properties take precedence over file configuration properties. +# For detailed usage, please refer to the user manual: +# https://gitee.com/openeuler/bishengjdk-8/wikis/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3/KAE%20Provider%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C # -# Algorithms are enabled by default if KAEProvider is used. -# Delete # if you want to disable certain algorithm. +# Algorithms are enabled by default if KAEProvider is used. +# Delete # if you want to disable certain algorithm. # kae.md5=false # kae.sha256=false # kae.sha384=false @@ -15,5 +19,58 @@ # kae.dh=false # kae.ec=false -# enable KAEProvider log setting +# 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 +# currently does not support KAE hardware acceleration, temporarily use openssl soft calculation. +# kae.digest.useKaeEngine=true +# kae.aes.useKaeEngine=false +# kae.sm4.useKaeEngine=true +# kae.hmac.useKaeEngine=false +# kae.rsa.useKaeEngine=true +# kae.dh.useKaeEngine=true +# kae.ec.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: +# 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. +# 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, +# aes-256-ecb,aes-256-cbc,aes-256-ctr,aes-256-gcm +# sm4 : sm4-ecb,sm4-cbc,sm4-ctr,sm4-ofb +# hmac : hmac-md5,hmac-sha1,hmac-sha224,hmac-sha256,hmac-sha384,hmac-sha512 +# rsa : rsa +# dh : dh +# ec : ec +# kae.engine.disabledAlgorithms=sha256,sha384 + +# 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 + +# Enable engine load log. # kae.log=true +# +# It only takes effect when the property kae.log value is true. +# Configure log file path, default value is System.getProperty("user.dir") + "/ + "kae.log". +# kae.log.file=/home/user/kae.log + diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEConfig.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEConfig.java new file mode 100644 index 000000000..07294dbd6 --- /dev/null +++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEConfig.java @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2022, 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 sun.security.util.Debug; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +public class KAEConfig { + private static final Debug kaeDebug = Debug.getInstance("kae"); + + // these property names indicates whether each algorithm uses KAEProvider + private static final String[] useKaeProviderPropertyNames = new String[]{ + "kae.md5", + "kae.sha256", + "kae.sha384", + "kae.sm3", + "kae.aes", + "kae.sm4", + "kae.hmac", + "kae.rsa", + "kae.dh", + "kae.ec" + }; + + // these property names indicate whether KAE hardware acceleration is enabled for each algorithm + private static final String[] useKaeEnginePropertyNames = new String[]{ + "kae.digest.useKaeEngine", + "kae.aes.useKaeEngine", + "kae.sm4.useKaeEngine", + "kae.hmac.useKaeEngine", + "kae.rsa.useKaeEngine", + "kae.dh.useKaeEngine", + "kae.ec.useKaeEngine" + }; + + // algorithm names + private static final String[] algorithmNames = new String[]{ + "md5", + "sha256", + "sha384", + "sm3", + "aes-128-ecb", + "aes-128-cbc", + "aes-128-ctr", + "aes-128-gcm", + "aes-192-ecb", + "aes-192-cbc", + "aes-192-ctr", + "aes-192-gcm", + "aes-256-ecb", + "aes-256-cbc", + "aes-256-ctr", + "aes-256-gcm", + "sm4-ecb", + "sm4-cbc", + "sm4-ctr", + "sm4-ofb", + "hmac-md5", + "hmac-sha1", + "hmac-sha224", + "hmac-sha256", + "hmac-sha384", + "hmac-sha512", + "rsa", + "dh", + "ec" + }; + + // algorithm name and algorithm index mapping + private static final Map<String, Integer> algorithmNameIndexMap = new HashMap<>(); + + // algorithm name and algorithm category index mapping + private static final Map<String, Integer> algorithmNameCategoryMap = new HashMap<>(); + + // whether use KAEProvider for each algorithm + private static final boolean[] useKaeProviderFlags = new boolean[algorithmNames.length]; + + // whether use KAEProvider for each category algorithm + private static final Map<String, Boolean> useKaeProviderCategoryMap = new HashMap<>(); + + // whether enable the Kunpeng acceleration engine for each algorithm + private static final boolean[] useKaeEngineFlags = new boolean[algorithmNames.length]; + + // The kaeprovider.cnf properties + private static Properties props; + + private KAEConfig() { + + } + + static { + AccessController.doPrivileged(new PrivilegedAction<Void>() { + public Void run() { + initialize(); + return null; + } + }); + } + + private static File kaePropFile(String filename) { + String sep = File.separator; + String defaultKaeConf = System.getProperty("java.home") + sep + "lib" + sep + filename; + String kaeConf = System.getProperty("kae.conf", defaultKaeConf); + return new File(kaeConf); + } + + private static void initialize() { + initProperties(); + initAlgorithmNameMap(); + initUseKaeProviderFlags(); + initUseKaeEngineFlags(); + } + + private static void initProperties() { + props = new Properties(); + File propFile = kaePropFile("kaeprovider.conf"); + if (propFile.exists()) { + InputStream is = null; + try { + FileInputStream fis = new FileInputStream(propFile); + is = new BufferedInputStream(fis); + props.load(is); + + if (kaeDebug != null) { + kaeDebug.println("reading kae properties file: " + + propFile); + } + } catch (IOException e) { + if (kaeDebug != null) { + kaeDebug.println("unable to load kae properties from " + + propFile); + e.printStackTrace(); + } + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException ioe) { + if (kaeDebug != null) { + kaeDebug.println("unable to close input stream"); + } + } + } + } + } else { + if (kaeDebug != null) { + kaeDebug.println("not found kae properties file: " + + propFile); + } + } + } + + public static Boolean useKaeProvider(String key) { + return useKaeProviderCategoryMap.getOrDefault(key, Boolean.TRUE); + } + + private static void initUseKaeProviderFlags() { + boolean[] categoryFlagsForProvider = new boolean[useKaeProviderPropertyNames.length]; + Arrays.fill(categoryFlagsForProvider, true); + for (int i = 0; i < useKaeProviderPropertyNames.length; i++) { + String configValue = privilegedGetOverridable(useKaeProviderPropertyNames[i]); + if (configValue != null) { + categoryFlagsForProvider[i] = Boolean.parseBoolean(configValue); + } + 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; + } + } + + if (kaeDebug != null) { + kaeDebug.println("useKaeProviderPropertyNames: "); + for (int i = 0; i < categoryFlagsForProvider.length; i++) { + kaeDebug.println(useKaeProviderPropertyNames[i] + "=" + categoryFlagsForProvider[i]); + } + + kaeDebug.println("useKaeProviderFlags: "); + for (int i = 0; i < useKaeProviderFlags.length; i++) { + kaeDebug.println(algorithmNames[i] + "=" + useKaeProviderFlags[i]); + } + } + } + + public static boolean[] getUseKaeProviderFlags() { + return useKaeProviderFlags; + } + + private static void initUseKaeEngineFlags() { + boolean[] categoryFlagsForEngine = new boolean[]{ + true, // digest + false, // aes + true, // sm4 + false, // hmac + true, // rsa + true, // dh + false // ec + }; + for (int i = 0; i < useKaeEnginePropertyNames.length; i++) { + String configValue = privilegedGetOverridable(useKaeEnginePropertyNames[i]); + if (configValue != null) { + categoryFlagsForEngine[i] = Boolean.parseBoolean(configValue); + } + } + + // EC algorithm currently does not support KAE hardware acceleration, temporarily use openssl soft calculation. + categoryFlagsForEngine[useKaeEnginePropertyNames.length - 1] = false; + + for (int i = 0; i < useKaeEngineFlags.length; i++) { + Integer algorithmCategoryIndex = algorithmNameCategoryMap.get(algorithmNames[i]); + if (categoryFlagsForEngine[algorithmCategoryIndex]) { + useKaeEngineFlags[i] = true; + } + } + + String[] disabledAlgorithms = getDisabledAlgorithms(); + for (String disabledAlgorithm : disabledAlgorithms) { + Integer algorithmIndex = algorithmNameIndexMap.get(disabledAlgorithm); + if (algorithmIndex != null) { + useKaeEngineFlags[algorithmIndex] = false; + } + } + if (kaeDebug != null) { + kaeDebug.println("useKaeEnginePropertyNames: "); + for (int i = 0; i < categoryFlagsForEngine.length; i++) { + kaeDebug.println(useKaeEnginePropertyNames[i] + "=" + categoryFlagsForEngine[i]); + } + + kaeDebug.println("disabledAlgorithms: "); + for (int i = 0; i < disabledAlgorithms.length; i++) { + kaeDebug.println(disabledAlgorithms[i]); + } + + kaeDebug.println("useKaeEngineFlags: "); + for (int i = 0; i < useKaeEngineFlags.length; i++) { + kaeDebug.println(algorithmNames[i] + "=" + useKaeEngineFlags[i]); + } + } + } + + public static boolean[] getUseKaeEngineFlags() { + return useKaeEngineFlags; + } + + private static void initAlgorithmNameIndexMap() { + for (int i = 0; i < algorithmNames.length; i++) { + algorithmNameIndexMap.put(algorithmNames[i], i); + } + } + + /* + * 0 : digest + * 1 : aes + * 2 : sm4 + * 3 : hmac + * 4 : rsa + * 5 : dh + * 6 : ec + */ + private static void initAlgorithmNameCategoryMap() { + algorithmNameCategoryMap.put("md5", 0); + algorithmNameCategoryMap.put("sha256", 0); + algorithmNameCategoryMap.put("sha384", 0); + algorithmNameCategoryMap.put("sm3", 0); + algorithmNameCategoryMap.put("aes-128-ecb", 1); + algorithmNameCategoryMap.put("aes-128-cbc", 1); + algorithmNameCategoryMap.put("aes-128-ctr", 1); + algorithmNameCategoryMap.put("aes-128-gcm", 1); + algorithmNameCategoryMap.put("aes-192-ecb", 1); + algorithmNameCategoryMap.put("aes-192-cbc", 1); + algorithmNameCategoryMap.put("aes-192-ctr", 1); + algorithmNameCategoryMap.put("aes-192-gcm", 1); + algorithmNameCategoryMap.put("aes-256-ecb", 1); + algorithmNameCategoryMap.put("aes-256-cbc", 1); + algorithmNameCategoryMap.put("aes-256-ctr", 1); + algorithmNameCategoryMap.put("aes-256-gcm", 1); + algorithmNameCategoryMap.put("sm4-ecb", 2); + algorithmNameCategoryMap.put("sm4-cbc", 2); + algorithmNameCategoryMap.put("sm4-ctr", 2); + algorithmNameCategoryMap.put("sm4-ofb", 2); + algorithmNameCategoryMap.put("hmac-md5", 3); + algorithmNameCategoryMap.put("hmac-sha1", 3); + algorithmNameCategoryMap.put("hmac-sha224", 3); + algorithmNameCategoryMap.put("hmac-sha256", 3); + algorithmNameCategoryMap.put("hmac-sha384", 3); + algorithmNameCategoryMap.put("hmac-sha512", 3); + algorithmNameCategoryMap.put("rsa", 4); + algorithmNameCategoryMap.put("dh", 5); + algorithmNameCategoryMap.put("ec", 6); + } + + private static void initAlgorithmNameMap() { + initAlgorithmNameIndexMap(); + initAlgorithmNameCategoryMap(); + } + + private static String[] getDisabledAlgorithms() { + String disabledAlgorithms = privilegedGetOverridable("kae.engine.disabledAlgorithms", + "sha256,sha384"); + return disabledAlgorithms.replaceAll(" ", "").split("\\,"); + } + + public static String privilegedGetProperty(String key) { + if (System.getSecurityManager() == null) { + return getProperty(key); + } else { + return AccessController.doPrivileged((PrivilegedAction<String>) () -> getOverridableProperty(key)); + } + } + + public static String privilegedGetOverridable(String key) { + if (System.getSecurityManager() == null) { + return getOverridableProperty(key); + } else { + return AccessController.doPrivileged((PrivilegedAction<String>) () -> getOverridableProperty(key)); + } + } + + public static String privilegedGetOverridable(String key, String defaultValue) { + String val = privilegedGetOverridable(key); + return (val == null) ? defaultValue : val; + } + + private static String getProperty(String key) { + String val = props.getProperty(key); + if (val != null) + val = val.trim(); + return val; + } + + private static String getOverridableProperty(String key) { + String val = System.getProperty(key); + if (val == null) { + return getProperty(key); + } else { + return val; + } + } + + public static String getAlgorithmName(int index) { + if (index < 0 || index >= algorithmNames.length) { + throw new IndexOutOfBoundsException(); + } + return algorithmNames[index]; + } +} diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAELog.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAELog.java new file mode 100644 index 000000000..434f773a1 --- /dev/null +++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAELog.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2022, 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 sun.security.util.Debug; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; + +public class KAELog { + private static final Debug kaeDebug = Debug.getInstance("kae"); + private static File logFile; + private static boolean exist; + + private KAELog() { + + } + + static { + AccessController.doPrivileged(new PrivilegedAction<Void>() { + public Void run() { + initialize(); + return null; + } + }); + } + + private static void initialize() { + if (!enableKaeLog()) { + if (kaeDebug != null) { + kaeDebug.println("kae logging is not enabled"); + } + return; + } + + logFile = kaeLogFile("kae.log"); + File parentFile = logFile.getParentFile(); + if (!parentFile.exists()) { + try { + Files.createDirectories(parentFile.toPath()); + } catch (IOException e) { + if (kaeDebug != null) { + kaeDebug.println("failed to create directory :" + parentFile); + e.printStackTrace(); + } + return; + } + } + + if (logFile.exists()) { + if (kaeDebug != null) { + kaeDebug.println("found kae log file :" + logFile); + } + exist = true; + } else { + if (kaeDebug != null) { + kaeDebug.println("not found kae log file :" + logFile); + } + try { + Path path = Files.createFile(logFile.toPath()); + if (path != null) { + exist = true; + } + } catch (IOException e) { + if (kaeDebug != null) { + kaeDebug.println("unable to create new kae log file :" + logFile); + e.printStackTrace(); + } + } + + if (exist) { + if (kaeDebug != null) { + kaeDebug.println("create new kae log file :" + logFile); + } + } + } + } + + public static boolean enableKaeLog() { + String debug = KAEConfig.privilegedGetOverridable("kae.log"); + return Boolean.parseBoolean(debug); + } + + private static File kaeLogFile(String filename) { + String sep = File.separator; + String defaultKaeLog = System.getProperty("user.dir") + sep + filename; + String kaeLog = KAEConfig.privilegedGetOverridable("kae.log.file", defaultKaeLog); + return new File(kaeLog); + } + + private static String getLogTime() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return simpleDateFormat.format(new Date()); + } + + public static void log(String engineId, Throwable throwable, boolean[] engineFlags, boolean[] kaeProviderFlags) { + if (engineFlags.length != kaeProviderFlags.length) { + if (kaeDebug != null) { + kaeDebug.println("The length of engineFlags is not equal to the length of kaeProviderFlags."); + kaeDebug.println(String.format("engineFlags : %s", Arrays.toString(engineFlags))); + kaeDebug.println(String.format("kaeProviderFlags : %s", Arrays.toString(kaeProviderFlags))); + } + return; + } + if (!exist) { + return; + } + + try (BufferedWriter writer = Files.newBufferedWriter(logFile.toPath(), + StandardOpenOption.APPEND)) { + logEngine(writer, engineId, throwable); + writer.newLine(); + logAlgorithmStrategy(writer, engineFlags, kaeProviderFlags); + writer.newLine(); + } catch (IOException e) { + if (kaeDebug != null) { + kaeDebug.println("write kae log failed"); + e.printStackTrace(); + } + } + } + + // log engine + private static void logEngine(BufferedWriter writer, String engineId, Throwable throwable) throws IOException { + writer.write(String.format("[%s] ", getLogTime())); + if (throwable == null) { + writer.write(String.format("%s engine was found.", engineId)); + } else if (throwable instanceof RuntimeException) { + writer.write(String.format("%s engine was not found. %s", engineId, throwable.getMessage())); + } else { + writer.write(throwable.getMessage()); + } + } + + // log algorithm strategy + private static void logAlgorithmStrategy(BufferedWriter writer, boolean[] engineFlags, boolean[] kaeProviderFlags) + throws IOException { + writer.write(String.format("[%s] ", getLogTime())); + writer.write("The implementation strategy of each algorithm is as follows : "); + for (int i = 0; i < engineFlags.length; i++) { + writer.newLine(); + String algorithmName = KAEConfig.getAlgorithmName(i); + String message; + if (kaeProviderFlags[i]) { + String detail = engineFlags[i] ? "enable KAE hardware acceleration" : "Use openssl soft calculation"; + message = String.format(" %-11s => %s: %s", algorithmName, "KAEProvider", detail); + } else { + message = String.format(" %-11s => %s", algorithmName, "Non-KAEProvider"); + } + writer.write(message); + } + } +} diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java index 83ed8649c..3e7f54638 100644 --- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java +++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAEProvider.java @@ -24,116 +24,103 @@ package org.openeuler.security.openssl; -import java.io.BufferedWriter; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.Date; -import java.util.Properties; +import sun.security.util.Debug; + +import java.security.AccessController; +import java.security.PrivilegedAction; import java.security.Provider; /** * KAE Provider */ public class KAEProvider extends Provider { - private static Throwable excp; - private static boolean needLog = true; + private static final Debug kaeDebug = Debug.getInstance("kae"); + + // default engine id + private static final String DEFAULT_ENGINE_ID = "kae"; static { - Throwable status = null; - try { - System.loadLibrary("j2kae"); - initOpenssl(); - } catch (UnsatisfiedLinkError t) { - status = t; - } catch (RuntimeException e) { - status = e; - } - excp = status; + initialize(); } - private void logStart(Throwable excp) { - File file = new File(System.getProperty("user.dir"), "kae.log"); - Path fpath = file.toPath(); - if (!Files.exists(fpath)) { - try { - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } + private static void initialize() { + loadLibrary(); + initOpenssl(); + } - try (BufferedWriter writer = Files.newBufferedWriter(fpath, StandardOpenOption.APPEND)) { - if (excp != null) { - writer.write(excp.getMessage()); - } else { - writer.write("KAE Engine was found"); + // load kae.so + private static void loadLibrary() { + AccessController.doPrivileged(new PrivilegedAction<Object>() { + @Override + public Object run() { + System.loadLibrary("j2kae"); + return null; } - writer.write(" " + new Date()); - writer.newLine(); - } catch (IOException e) { - e.initCause(excp).printStackTrace(); - } - KAEProvider.excp = null; // Exception already logged, clean it. + }); } - private Properties getProp() { - Properties props = new Properties(); - String sep = File.separator; - File propFile = new File(System.getProperty("java.home") + sep + "lib" + sep + - "ext" + sep + "kaeprovider.conf"); - if (propFile.exists()) { - try (InputStream is = new BufferedInputStream(new FileInputStream(propFile))) { - props.load(is); - } catch (IOException e) { - e.printStackTrace(); + // init openssl + private static void initOpenssl() { + boolean useGlobalMode = useGlobalMode(); + String engineId = getEngineId(); + boolean[] algorithmKaeFlags = KAEConfig.getUseKaeEngineFlags(); + Throwable throwable = null; + try { + initOpenssl(useGlobalMode, engineId, algorithmKaeFlags); + } catch (Throwable t) { + throwable = t; + if (kaeDebug != null) { + kaeDebug.println("initOpenssl failed : " + throwable.getMessage()); } } - return props; + boolean[] engineFlags = getEngineFlags(); + boolean[] kaeProviderFlags = KAEConfig.getUseKaeProviderFlags(); + KAELog.log(engineId, throwable, engineFlags, kaeProviderFlags); + } + + // get engine id + private static String getEngineId() { + 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() { + String explicitLoad = KAEConfig.privilegedGetOverridable( + "kae.libcrypto.useGlobalMode", "false"); + return Boolean.parseBoolean(explicitLoad); } public KAEProvider() { super("KAEProvider", 1.8d, "KAE provider"); - Properties props = getProp(); - if (needLog && "true".equalsIgnoreCase(props.getProperty("kae.log"))) { - logStart(excp); - needLog = false; // Log only once - } - if (!"false".equalsIgnoreCase(props.getProperty("kae.md5"))) { + if (KAEConfig.useKaeProvider("kae.md5")) { putMD5(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.sha256"))) { + if (KAEConfig.useKaeProvider("kae.sha256")) { putSHA256(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.sha384"))) { + if (KAEConfig.useKaeProvider("kae.sha384")) { putSHA384(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.sm3"))) { + if (KAEConfig.useKaeProvider("kae.sm3")) { putSM3(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.aes"))) { + if (KAEConfig.useKaeProvider("kae.aes")) { putAES(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.sm4"))) { + if (KAEConfig.useKaeProvider("kae.sm4")) { putSM4(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.hmac"))) { + if (KAEConfig.useKaeProvider("kae.hmac")) { putHMAC(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.rsa"))) { + if (KAEConfig.useKaeProvider("kae.rsa")) { putRSA(); putSignatureRSA(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.dh"))) { + if (KAEConfig.useKaeProvider("kae.dh")) { putDH(); } - if (!"false".equalsIgnoreCase(props.getProperty("kae.ec"))) { + if (KAEConfig.useKaeProvider("kae.ec")) { putEC(); } } @@ -285,28 +272,28 @@ public class KAEProvider extends Provider { "org.openeuler.security.openssl.KAERSASignature$SHA512withRSA"); // alias - put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA"); - put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA"); + put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.14", "SHA224withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.14", "SHA224withRSA"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.14", "SHA224withRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA"); put("Signature.RSASSA-PSS", "org.openeuler.security.openssl.KAERSAPSSSignature"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.10", "RSASSA-PSS"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.10", "RSASSA-PSS"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.10", "RSASSA-PSS"); // attributes for supported key classes @@ -326,6 +313,10 @@ public class KAEProvider extends Provider { put("Alg.Alias.KeyPairGenerator.EllipticCurve", "EC"); put("KeyAgreement.ECDH", "org.openeuler.security.openssl.KAEECDHKeyAgreement"); } + // init openssl - static native void initOpenssl() throws RuntimeException; + static native void initOpenssl(boolean useGlobalMode, String engineId, boolean[] algorithmKaeFlags) + throws RuntimeException; + + static native boolean[] getEngineFlags(); } diff --git a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java index b189bea3a..cca619e1a 100644 --- a/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java +++ b/jdk/src/solaris/classes/org/openeuler/security/openssl/KAESM4Cipher.java @@ -26,13 +26,20 @@ package org.openeuler.security.openssl; +import sun.security.util.Debug; + +import java.nio.ByteBuffer; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Key; +import java.security.ProviderException; import java.util.Locale; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; +import javax.crypto.ShortBufferException; /* * This class currently supports: @@ -46,6 +53,55 @@ import javax.crypto.NoSuchPaddingException; */ abstract class KAESM4Cipher extends KAESymmetricCipherBase { + private static final Debug debug = Debug.getInstance("kae"); + + /* + * SM4 max chunk size of each encryption or decryption + * when input data does not have an accessible byte[] + */ + private static final int DEFAULT_KAE_SM4_MAX_CHUNK_SIZE = 4096; + private static int KAE_SM4_MAX_CHUNK_SIZE; + static { + initSM4MaxChunkSize(); + } + + private static void initSM4MaxChunkSize() { + String maxChunkSize = KAEConfig.privilegedGetOverridable("kae.sm4.maxChunkSize", + DEFAULT_KAE_SM4_MAX_CHUNK_SIZE + ""); + try { + KAE_SM4_MAX_CHUNK_SIZE = Integer.parseInt(maxChunkSize); + } catch (NumberFormatException e) { + // When parsing string argument to signed decimal integer fails, uses the default chunk size (4096) + KAE_SM4_MAX_CHUNK_SIZE = DEFAULT_KAE_SM4_MAX_CHUNK_SIZE; + if (debug != null) { + debug.println("The configured block size (" + maxChunkSize + ") cannot be converted to an integer, " + + "uses the default chunk size (" + DEFAULT_KAE_SM4_MAX_CHUNK_SIZE + ")"); + e.printStackTrace(); + } + return; + } + // when the configured chunk size is less than or equal to 0, uses the default chunk size (4096) + if (KAE_SM4_MAX_CHUNK_SIZE <= 0) { + KAE_SM4_MAX_CHUNK_SIZE = DEFAULT_KAE_SM4_MAX_CHUNK_SIZE; + if (debug != null) { + debug.println("The configured chunk size (" + KAE_SM4_MAX_CHUNK_SIZE + ") is less than " + + "or equal to 0, uses the default chunk size (" + DEFAULT_KAE_SM4_MAX_CHUNK_SIZE + ")"); + } + return; + } + if (debug != null) { + debug.println("The configured chunk size is " + KAE_SM4_MAX_CHUNK_SIZE); + } + } + + /** + * Used by the engineUpdate(ByteBuffer, ByteBuffer) and + * engineDoFinal(ByteBuffer, ByteBuffer) methods. + */ + private static int getSM4MaxChunkSize(int totalSize) { + return Math.min(KAE_SM4_MAX_CHUNK_SIZE, totalSize); + } + public static class Sm4 extends KAESM4Cipher { public Sm4(Mode mode, Padding padding) { super(mode, padding, 16); @@ -170,6 +226,131 @@ abstract class KAESM4Cipher extends KAESymmetricCipherBase { } } + @Override + protected int engineUpdate(ByteBuffer input, ByteBuffer output) throws ShortBufferException { + try { + return bufferCrypt(input, output, true); + } catch (IllegalBlockSizeException e) { + // never thrown for engineUpdate() + throw new ProviderException("Internal error in update()"); + } catch (BadPaddingException e) { + // never thrown for engineUpdate() + throw new ProviderException("Internal error in update()"); + } + } + + @Override + protected int engineDoFinal(ByteBuffer input, ByteBuffer output) + throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { + return bufferCrypt(input, output, false); + } + + /** + * Implementation for encryption using ByteBuffers. Used for both + * engineUpdate() and engineDoFinal(). + */ + private int bufferCrypt(ByteBuffer input, ByteBuffer output, + boolean isUpdate) throws ShortBufferException, + IllegalBlockSizeException, BadPaddingException { + if ((input == null) || (output == null)) { + throw new NullPointerException + ("Input and output buffers must not be null"); + } + int inPos = input.position(); + int inLimit = input.limit(); + int inLen = inLimit - inPos; + if (isUpdate && (inLen == 0)) { + return 0; + } + int outLenNeeded = engineGetOutputSize(inLen); + + if (output.remaining() < outLenNeeded) { + throw new ShortBufferException("Need at least " + outLenNeeded + + " bytes of space in output buffer"); + } + + // detecting input and output buffer overlap may be tricky + // we can only write directly into output buffer when we + // are 100% sure it's safe to do so + + boolean a1 = input.hasArray(); + boolean a2 = output.hasArray(); + int total = 0; + + if (a1) { // input has an accessible byte[] + byte[] inArray = input.array(); + int inOfs = input.arrayOffset() + inPos; + + byte[] outArray; + if (a2) { // output has an accessible byte[] + outArray = output.array(); + int outPos = output.position(); + int outOfs = output.arrayOffset() + outPos; + + // check array address and offsets and use temp output buffer + // if output offset is larger than input offset and + // falls within the range of input data + boolean useTempOut = false; + if (inArray == outArray && + ((inOfs < outOfs) && (outOfs < inOfs + inLen))) { + useTempOut = true; + outArray = new byte[outLenNeeded]; + outOfs = 0; + } + if (isUpdate) { + total = engineUpdate(inArray, inOfs, inLen, outArray, outOfs); + } else { + total = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs); + } + if (useTempOut) { + output.put(outArray, outOfs, total); + } else { + // adjust output position manually + output.position(outPos + total); + } + } else { // output does not have an accessible byte[] + if (isUpdate) { + outArray = engineUpdate(inArray, inOfs, inLen); + } else { + outArray = engineDoFinal(inArray, inOfs, inLen); + } + if (outArray != null && outArray.length != 0) { + output.put(outArray); + total = outArray.length; + } + } + // adjust input position manually + input.position(inLimit); + } else { // input does not have an accessible byte[] + // have to assume the worst, since we have no way of determine + // if input and output overlaps or not + byte[] tempOut = new byte[outLenNeeded]; + int outOfs = 0; + + byte[] tempIn = new byte[getSM4MaxChunkSize(inLen)]; + do { + int chunk = Math.min(inLen, tempIn.length); + if (chunk > 0) { + input.get(tempIn, 0, chunk); + } + int n; + if (isUpdate || (inLen > chunk)) { + n = engineUpdate(tempIn, 0, chunk, tempOut, outOfs); + } else { + n = engineDoFinal(tempIn, 0, chunk, tempOut, outOfs); + } + outOfs += n; + total += n; + inLen -= chunk; + } while (inLen > 0); + if (total > 0) { + output.put(tempOut, 0, total); + } + } + + return total; + } + protected void checkIvBytes(byte[] ivBytes) throws InvalidAlgorithmParameterException { if (ivBytes == null) { throw new InvalidAlgorithmParameterException("Wrong IV length: iv is null "); diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c index 80a0e58b9..d9b16ab9d 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_cipher_rsa.c @@ -24,12 +24,11 @@ #include <stdbool.h> #include <openssl/rsa.h> #include <openssl/evp.h> +#include "kae_log.h" #include "kae_util.h" #include "kae_exception.h" #include "org_openeuler_security_openssl_KAERSACipher.h" -static ENGINE* kaeEngine = NULL; - typedef int RSACryptOperation(int, const unsigned char*, unsigned char*, RSA*, int); typedef int EvpPkeyCryptOperation(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t); @@ -176,7 +175,9 @@ static int RSACryptOAEPPadding(JNIEnv* env, jlong keyAddress, jint inLen, jbyteA // outLen type should be size_t // EVP_PKEY_encrypt takes the outLen address as a parameter, and the parameter type is size_t* size_t outLen = 0; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(RSA_INDEX); + KAE_TRACE("RSACryptOAEPPadding: kaeEngine => %p", kaeEngine); + EVP_PKEY* pkey = (EVP_PKEY*) keyAddress; @@ -272,7 +273,8 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC BIGNUM* bnIQMP = NULL; RSA* rsa = NULL; EVP_PKEY* pkey = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(RSA_INDEX); + KAE_TRACE("KAERSACipher_nativeCreateRSAPrivateCrtKey: kaeEngine => %p", kaeEngine); // convert to big num if ((bnN = KAE_GetBigNumFromByteArray(env, n)) == NULL || @@ -334,7 +336,8 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAERSACipher_nativeC BIGNUM* bnE = NULL; RSA* rsa = NULL; EVP_PKEY* pkey = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(RSA_INDEX); + KAE_TRACE("KAERSACipher_nativeCreateRSAPublicKey: kaeEngine => %p", kaeEngine); // get public key param n bnN = KAE_GetBigNumFromByteArray(env, n); diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c index f0e7b0be4..23b178978 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_digest.c @@ -42,7 +42,7 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls, jstring algorithmName) { EVP_MD_CTX* ctx = NULL; - static ENGINE* kaeEngine = NULL; + ENGINE* kaeEngine = NULL; if (algorithmName == NULL) { KAE_ThrowNullPointerException(env, "algorithm is null"); @@ -51,11 +51,8 @@ Java_org_openeuler_security_openssl_KAEDigest_nativeInit(JNIEnv *env, jclass cls // EVP_get_digestbyname const char* algo_utf = (*env)->GetStringUTFChars(env, algorithmName, 0); - if ((strcasecmp(algo_utf, "md5") == 0) || (strcasecmp(algo_utf, "sm3") == 0)) { - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; - } else { - kaeEngine = NULL; - } + kaeEngine = GetDigestEngineByAlgorithmName(algo_utf); + KAE_TRACE("KAEDigest_nativeInit: kaeEngine => %p", kaeEngine); EVP_MD* md = (EVP_MD*) EVP_get_digestbyname(algo_utf); (*env)->ReleaseStringUTFChars(env, algorithmName, algo_utf); if (md == NULL) { diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c index 554a9750c..1efacbb5b 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_hmac.c @@ -73,9 +73,14 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeInit HMAC_CTX* ctx = NULL; jbyte* key_buffer = NULL; const EVP_MD* md = NULL; + ENGINE* kaeEngine = NULL; const char* algo = (*env)->GetStringUTFChars(env, algoStr, 0); - md = EVPGetDigestByName(env, algo); + md = EVPGetDigestByName(env, algo); + + kaeEngine = GetHmacEngineByAlgorithmName(algo); + KAE_TRACE("KAEHMac_nativeInit: kaeEngine => %p", kaeEngine); + (*env)->ReleaseStringUTFChars(env, algoStr, algo); if (md == NULL) { KAE_ThrowRuntimeException(env, "algorithm unsupport"); @@ -98,7 +103,7 @@ JNIEXPORT jlong JNICALL Java_org_openeuler_security_openssl_KAEHMac_nativeInit } // init hmac context with sc_key and evp_md - int result_code = HMAC_Init_ex(ctx, key_buffer, key_len, md, NULL); + int result_code = HMAC_Init_ex(ctx, key_buffer, key_len, md, kaeEngine); if (result_code == 0) { KAE_ThrowRuntimeException(env, "Hmac_Init_ex invoked failed"); goto cleanup; diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c index 7cdf790cb..d8d2ee7cb 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keyagreement_dh.c @@ -51,8 +51,8 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyAgreeme int computekeyLength = 0; unsigned char* secret = NULL; jbyteArray retByteArray = NULL; - static ENGINE* kaeEngine = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(DH_INDEX); + KAE_TRACE("KAEDHKeyAgreement_nativeComputeKey: kaeEngine => %p", kaeEngine); // bits to Bytes int pSizeInByte = (pSize +7) >> 3; diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c index 54dc07edd..d16b42b41 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_dh.c @@ -50,8 +50,8 @@ JNIEXPORT jobjectArray JNICALL Java_org_openeuler_security_openssl_KAEDHKeyPairG jobjectArray keys = NULL; jbyteArray pri_key = NULL; jbyteArray pub_key = NULL; - static ENGINE* kaeEngine = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(DH_INDEX); + KAE_TRACE("KAEDHKeyPairGenerator_nativeGenerateKeyPair: kaeEngine => %p", kaeEngine); KAE_TRACE("Java_org_openeuler_security_openssl_KAEDHKeyPairGenerator_nativeGenerateKeyPair start !"); diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c index 2ca978bbe..9251b56c4 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_keypairgenerator_rsa.c @@ -23,6 +23,7 @@ #include <stdbool.h> #include <openssl/rsa.h> +#include "kae_log.h" #include "kae_util.h" #include "kae_exception.h" #include "org_openeuler_security_openssl_KAERSAKeyPairGenerator.h" @@ -62,8 +63,9 @@ static const BIGNUM* (* GetRSAParamFunctionList[])(const RSA*) = { * step 3.Generate rsa key, and all key information is stored in RSA */ static RSA* NewRSA(JNIEnv* env, jint keySize, jbyteArray publicExponent) { - static ENGINE* kaeEngine = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(RSA_INDEX); + KAE_TRACE("NewRSA: kaeEngine => %p", kaeEngine); + // new rsa RSA* rsa = RSA_new_method(kaeEngine); if (rsa == NULL) { diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c index aa46e737e..fca035b04 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_provider.c @@ -24,21 +24,53 @@ #include <openssl/bio.h> #include <openssl/ssl.h> #include <openssl/engine.h> +#include <dlfcn.h> #include "kae_exception.h" #include "kae_util.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) { + (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); + } + // check if KaeEngine holder is already set ENGINE* e = GetKaeEngine(); if (e != NULL) { @@ -47,11 +79,25 @@ JNIEXPORT void JNICALL Java_org_openeuler_security_openssl_KAEProvider_initOpens } // determine whether KAE is loaded successfully - e = ENGINE_by_id("kae"); + const char* id = (*env)->GetStringUTFChars(env, engineId, 0); + e = ENGINE_by_id(id); + (*env)->ReleaseStringUTFChars(env, engineId, id); if (e == NULL) { - ERR_clear_error(); - KAE_ThrowRuntimeException(env, "kae engine not found"); + KAE_ThrowFromOpenssl(env, "ENGINE_by_id", KAE_ThrowRuntimeException); return; } SetKaeEngine(e); + + // initialize the engine for each algorithm + initEngines(env, algorithmKaeFlags); } + +/* + * Class: Java_org_openeuler_security_openssl_KAEProvider + * Method: getEngineFlags + * Signature: ()V + */ +JNIEXPORT jbooleanArray JNICALL Java_org_openeuler_security_openssl_KAEProvider_getEngineFlags + (JNIEnv *env, jclass cls) { + return getEngineFlags(env); +} \ No newline at end of file diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c index e81dc1406..6c401356d 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_signature_rsa.c @@ -24,6 +24,7 @@ #include <string.h> #include <openssl/rsa.h> #include <openssl/evp.h> +#include "kae_log.h" #include "kae_util.h" #include "kae_exception.h" @@ -99,8 +100,9 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature jbyte* digestBytes = NULL; jbyte* sigBytes = NULL; jbyteArray sigByteArray = NULL; - static ENGINE* kaeEngine = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(RSA_INDEX); + KAE_TRACE("KAERSASignatureNative_rsaSign: kaeEngine => %p", kaeEngine); + // new EVP_PKEY_CTX if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException); @@ -163,8 +165,9 @@ JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNa jbyte* digestBytes = NULL; jbyte* sigBytes = NULL; jboolean isSuccess = JNI_FALSE; - static ENGINE* kaeEngine = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(RSA_INDEX); + KAE_TRACE("KAERSASignatureNative_rsaVerify: kaeEngine => %p", kaeEngine); + // new EVP_PKEY_CTX if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException); @@ -255,8 +258,9 @@ JNIEXPORT jbyteArray JNICALL Java_org_openeuler_security_openssl_KAERSASignature jbyte* digestBytes = NULL; jbyte* sigBytes = NULL; jbyteArray sigByteArray = NULL; - static ENGINE* kaeEngine = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(RSA_INDEX); + KAE_TRACE("KAERSASignatureNative_pssSign: kaeEngine => %p", kaeEngine); + // new EVP_PKEY_CTX if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException); @@ -320,8 +324,9 @@ JNIEXPORT jboolean JNICALL Java_org_openeuler_security_openssl_KAERSASignatureNa jbyte* digestBytes = NULL; jbyte* sigBytes = NULL; jboolean isSuccess = JNI_FALSE; - static ENGINE* kaeEngine = NULL; - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + ENGINE* kaeEngine = GetEngineByAlgorithmIndex(RSA_INDEX); + KAE_TRACE("KAERSASignatureNative_pssVerify: kaeEngine => %p", kaeEngine); + // new EVP_PKEY_CTX if ((pkeyCtx = EVP_PKEY_CTX_new(pkey, kaeEngine)) == NULL) { KAE_ThrowFromOpenssl(env, "EVP_PKEY_new", KAE_ThrowSignatureException); diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c index 71c28bdea..43f6326b2 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c @@ -142,16 +142,19 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en jbyte* keyBytes = NULL; jbyte* ivBytes = NULL; const EVP_CIPHER* cipher = NULL; - static ENGINE* kaeEngine = NULL; + ENGINE* kaeEngine = NULL; const char* algo = (*env)->GetStringUTFChars(env, cipherType, 0); if (StartsWith("aes", algo)) { cipher = EVPGetAesCipherByName(env, algo); - kaeEngine = NULL; + kaeEngine = GetAesEngineByAlgorithmName(algo); } else { cipher = EVPGetSm4CipherByName(env, algo); - kaeEngine = (kaeEngine == NULL) ? GetKaeEngine() : kaeEngine; + kaeEngine = GetSm4EngineByAlgorithmName(algo); } + + KAE_TRACE("KAESymmetricCipherBase_nativeInit: kaeEngine => %p", kaeEngine); + (*env)->ReleaseStringUTFChars(env, cipherType, algo); if (cipher == NULL) { KAE_ThrowOOMException(env, "create EVP_CIPHER fail"); diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c index 0e656a834..a16d944c4 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.c @@ -22,6 +22,7 @@ */ #include <openssl/evp.h> +#include <string.h> #include "kae_util.h" #include "kae_exception.h" @@ -55,7 +56,7 @@ BIGNUM* KAE_GetBigNumFromByteArray(JNIEnv* env, jbyteArray byteArray) { jbyte* bytes = (*env)->GetByteArrayElements(env, byteArray, NULL); if (bytes == NULL) { - KAE_ThrowNullPointerException(env,"GetByteArrayElements failed"); + KAE_ThrowNullPointerException(env, "GetByteArrayElements failed"); goto cleanup; } BIGNUM* result = BN_bin2bn((const unsigned char*) bytes, len, bn); @@ -109,3 +110,138 @@ cleanup: (*env)->ReleaseByteArrayElements(env, javaBytes, bytes, 0); return javaBytes; } + +#define ENGINE_LENGTH (EC_INDEX + 1) +static ENGINE* engines[ENGINE_LENGTH] = {NULL}; +static jboolean engineFlags[ENGINE_LENGTH] = {JNI_FALSE}; +static KAEAlgorithm kaeAlgorithms[ENGINE_LENGTH] = { + {MD5_INDEX, "md5"}, + {SHA256_INDEX, "sha256"}, + {SHA384_INDEX, "sha384"}, + {SM3_INDEX, "sm3"}, + {AES_128_ECB_INDEX, "aes-128-ecb"}, + {AES_128_CBC_INDEX, "aes-128-cbc"}, + {AES_128_CTR_INDEX, "aes-128-ctr"}, + {AES_128_GCM_INDEX, "aes-128-gcm"}, + {AES_192_ECB_INDEX, "aes-192-ecb"}, + {AES_192_CBC_INDEX, "aes-192-cbc"}, + {AES_192_CTR_INDEX, "aes-192-ctr"}, + {AES_192_GCM_INDEX, "aes-192-gcm"}, + {AES_256_ECB_INDEX, "aes-256-ecb"}, + {AES_256_CBC_INDEX, "aes-256-cbc"}, + {AES_256_CTR_INDEX, "aes-256-ctr"}, + {AES_256_GCM_INDEX, "aes-256-gcm"}, + {SM4_ECB_INDEX, "sm4-ecb"}, + {SM4_CBC_INDEX, "sm4-cbc"}, + {SM4_CTR_INDEX, "sm4-ctr"}, + {SM4_OFB_INDEX, "sm4-ofb"}, + {HMAC_MD5_INDEX, "hmac-md5"}, + {HMAC_SHA1_INDEX, "hmac-sha1"}, + {HMAC_SHA224_INDEX, "hmac-sha224"}, + {HMAC_SHA256_INDEX, "hmac-sha256"}, + {HMAC_SHA384_INDEX, "hmac-sha384"}, + {HMAC_SHA512_INDEX, "hmac-sha512"}, + {RSA_INDEX, "rsa"}, + {DH_INDEX, "dh"}, + {EC_INDEX, "ec"} +}; + +void initEngines(JNIEnv* env, jbooleanArray algorithmKaeFlags) { + if (algorithmKaeFlags == NULL) { + return; + } + + // get jTemp + jboolean* jTemp = NULL; + int length = (*env)->GetArrayLength(env, algorithmKaeFlags); + jTemp = (jboolean*) malloc(length); + if (jTemp == NULL) { + KAE_ThrowOOMException(env, "initEngines GetArrayLength error"); + return; + } + (*env)->GetBooleanArrayRegion(env, algorithmKaeFlags, 0, length, jTemp); + + // assign engines + int minLen = length < ENGINE_LENGTH ? length : ENGINE_LENGTH; + int i; + for (i = 0; i < minLen; i++) { + if (jTemp[i]) { + engines[i] = kaeEngine; + engineFlags[i] = JNI_TRUE; + } + } + if (length < ENGINE_LENGTH) { + for (i = minLen; i < ENGINE_LENGTH; i++) { + engines[i] = kaeEngine; + engineFlags[i] = JNI_TRUE; + } + } + + // free jTemp + if (jTemp != NULL) { + free(jTemp); + } +} + +jbooleanArray getEngineFlags(JNIEnv* env) { + jbooleanArray array = (*env)->NewBooleanArray(env, ENGINE_LENGTH); + (*env)->SetBooleanArrayRegion(env, array, 0, ENGINE_LENGTH, engineFlags); + return array; +} + +ENGINE* GetEngineByAlgorithmIndex(AlgorithmIndex algorithmIndex) { + return engines[algorithmIndex]; +} + +/* + * Get the engine used by the specified algorithm. + * @param beginIndex the beginning index, inclusive. + * @param endIndex the ending index, exclusive. + * @param algorithmName algorithm name + * @return engine + */ +ENGINE* GetEngineByBeginIndexAndEndIndex(int beginIndex, int endIndex, + const char* algorithmName) { + if (beginIndex < 0 || endIndex > ENGINE_LENGTH) { + return NULL; + } + + int i; + for (i = beginIndex; i < endIndex; i++) { + if (strcasecmp(kaeAlgorithms[i].algorithmName, algorithmName) == 0) { + return engines[kaeAlgorithms[i].algorithmIndex]; + } + } + return NULL; +} + +ENGINE* GetHmacEngineByAlgorithmName(const char* algorithmName) { + char prefix[] = {"hmac-"}; + int len = strlen(algorithmName); + int newLen = strlen(algorithmName) + strlen(prefix) + 1; + char* newAlgorithmName = NULL; + newAlgorithmName = malloc(newLen); + if (newAlgorithmName == NULL) { + return NULL; + } + strcpy(newAlgorithmName, prefix); + strcat(newAlgorithmName, algorithmName); + ENGINE* engine = GetEngineByBeginIndexAndEndIndex(HMAC_MD5_INDEX, HMAC_SHA512_INDEX + 1, newAlgorithmName); + if (newAlgorithmName != NULL) { + free(newAlgorithmName); + } + return engine; +} + +ENGINE* GetDigestEngineByAlgorithmName(const char* algorithmName) { + return GetEngineByBeginIndexAndEndIndex(MD5_INDEX, SM3_INDEX + 1, algorithmName); +} + +ENGINE* GetAesEngineByAlgorithmName(const char* algorithmName) { + return GetEngineByBeginIndexAndEndIndex(AES_128_ECB_INDEX, AES_256_GCM_INDEX + 1, algorithmName); +} + +ENGINE* GetSm4EngineByAlgorithmName(const char* algorithmName) { + return GetEngineByBeginIndexAndEndIndex(SM4_ECB_INDEX, SM4_OFB_INDEX + 1, algorithmName); +} + diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h index 13bd5976d..347337509 100644 --- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h +++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_util.h @@ -27,6 +27,43 @@ #include <openssl/bn.h> #include <jni.h> +typedef enum { + MD5_INDEX, + SHA256_INDEX, + SHA384_INDEX, + SM3_INDEX, + AES_128_ECB_INDEX, + AES_128_CBC_INDEX, + AES_128_CTR_INDEX, + AES_128_GCM_INDEX, + AES_192_ECB_INDEX, + AES_192_CBC_INDEX, + AES_192_CTR_INDEX, + AES_192_GCM_INDEX, + AES_256_ECB_INDEX, + AES_256_CBC_INDEX, + AES_256_CTR_INDEX, + AES_256_GCM_INDEX, + SM4_ECB_INDEX, + SM4_CBC_INDEX, + SM4_CTR_INDEX, + SM4_OFB_INDEX, + HMAC_MD5_INDEX, + HMAC_SHA1_INDEX, + HMAC_SHA224_INDEX, + HMAC_SHA256_INDEX, + HMAC_SHA384_INDEX, + HMAC_SHA512_INDEX, + RSA_INDEX, + DH_INDEX, + EC_INDEX +} AlgorithmIndex; + +typedef struct { + AlgorithmIndex algorithmIndex; + const char* algorithmName; +} KAEAlgorithm; + /* jbyteArray convert to BIGNUM */ BIGNUM* KAE_GetBigNumFromByteArray(JNIEnv* env, jbyteArray byteArray); @@ -40,8 +77,18 @@ void SetKaeEngine(ENGINE* engine); ENGINE* GetKaeEngine(); -void SetKaeEngine(ENGINE* engine); +void initEngines(JNIEnv* env, jbooleanArray algorithmKaeFlags); -ENGINE* GetKaeEngine(); +jbooleanArray getEngineFlags(JNIEnv* env); + +ENGINE* GetEngineByAlgorithmIndex(AlgorithmIndex algorithmIndex); + +ENGINE* GetHmacEngineByAlgorithmName(const char* algorithmName); + +ENGINE* GetDigestEngineByAlgorithmName(const char* algorithmName); + +ENGINE* GetAesEngineByAlgorithmName(const char* algorithmName); + +ENGINE* GetSm4EngineByAlgorithmName(const char* algorithmName); #endif diff --git a/jdk/test/org/openeuler/security/openssl/AESTest.java b/jdk/test/org/openeuler/security/openssl/AESTest.java new file mode 100644 index 000000000..77da5ecc2 --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/AESTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2022, 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 java.nio.charset.StandardCharsets; +import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; + +/** + * @test + * @summary Basic test for AES + * @requires os.arch=="aarch64" + * @run main AESTest + */ + +public class AESTest { + private static final String[] ALGORITHM = {"AES", "AES_128", "AES_192", "AES_256"}; + private static final String[] MODES = {"ECB", "CBC", "CTR", "GCM"}; + private static final String[] PADDING = {"NoPadding", "PKCS5Padding"}; + private static final int AES_128_KEY_LENGTH = 128; + private static final int AES_192_KEY_LENGTH = 192; + private static final int AES_256_KEY_LENGTH = 256; + private static String plainText = "helloworldhellow"; // 16bytes for NoPadding + private static String shortPlainText = "helloworld"; // 5 bytes for padding + + public static void main(String[] args) throws Exception { + Security.insertProviderAt(new KAEProvider(), 1); + for (String algo : ALGORITHM) { + for (String mode : MODES) { + int padKinds = 2; + if (mode.equalsIgnoreCase("CTR")) { + padKinds = 1; + } + for (int k = 0; k < padKinds; k++) { + test(algo, mode, PADDING[k]); + } + } + } + } + + public static void test(String algo, String mo, String pad) throws Exception { + AlgorithmParameterSpec aps = null; + + Cipher cipher = Cipher.getInstance(algo + "/" + mo + "/" + pad); + + KeyGenerator kg = KeyGenerator.getInstance("AES"); + if (algo.equalsIgnoreCase("AES_192")) { + kg.init(AES_192_KEY_LENGTH); + } else if (algo.equalsIgnoreCase("AES_256")) { + kg.init(AES_256_KEY_LENGTH); + } else { + kg.init(AES_128_KEY_LENGTH); + } + + SecretKey key = kg.generateKey(); + + // encrypt + if (!mo.equalsIgnoreCase("GCM")) { + cipher.init(Cipher.ENCRYPT_MODE, key, aps); + } else { + cipher.init(Cipher.ENCRYPT_MODE, key); + } + + String cipherString = null; + if (!pad.equalsIgnoreCase("NoPadding")) { + cipherString = shortPlainText; + } else { + cipherString = plainText; + } + byte[] cipherText = cipher.doFinal(cipherString.getBytes(StandardCharsets.UTF_8)); + if (!mo.equalsIgnoreCase("ECB")) { + aps = new IvParameterSpec(cipher.getIV()); + } else { + aps = null; + } + + if (!mo.equalsIgnoreCase("GCM")) { + cipher.init(Cipher.DECRYPT_MODE, key, aps); + } else { + cipher.init(Cipher.DECRYPT_MODE, key, cipher.getParameters()); + } + + String decryptPlainText = new String(cipher.doFinal(cipherText)); + + if (!cipherString.equals(decryptPlainText)) { + throw new RuntimeException("aes decryption failed, algo = " + algo + ", mo = " + mo + ", pad = " + pad); + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/DHTest.java b/jdk/test/org/openeuler/security/openssl/DHTest.java index 6eb5e7c96..ee5d63684 100644 --- a/jdk/test/org/openeuler/security/openssl/DHTest.java +++ b/jdk/test/org/openeuler/security/openssl/DHTest.java @@ -28,7 +28,6 @@ import java.io.Serializable; import java.math.BigInteger; import java.security.*; import java.util.Arrays; -import java.util.Date; import javax.crypto.KeyAgreement; import javax.crypto.spec.*; import org.openeuler.security.openssl.KAEProvider; @@ -75,18 +74,16 @@ import org.openeuler.security.openssl.KAEProvider; /** * @test * @summary Basic test for DH + * @requires os.arch=="aarch64" * @run main DHTest */ -final class DHTest implements Serializable { - private static int bitLength = 8192; +public class DHTest implements Serializable { private static BigInteger g512; private static BigInteger p512; - Throwable t = null; private static volatile Provider sunJceProvider; private static volatile Provider kaeProvider; - Date d = new Date(); public static void main(String[] args) throws Exception { Security.addProvider(new KAEProvider()); @@ -97,8 +94,6 @@ final class DHTest implements Serializable { p512 = new BigInteger("27672987386729926592037876826877634387173876890702920770064392919138769821035856568775311919542560094764667151024449425954917954337048895981297730855891532066350935045229294626339548842381843985759061682551900379979643117695834175891578650111093016914264824311693147701566019122696621248493126219217339690346346921463135605151471303957324058301097079967414639146647429422884520134312590056632178576758580657240245655739869017244657144448267757255018625514803292549109401806336918448001843022629625467069714240279603204909633404992842479161100500474744098408277938070656334892106100534117209709263785505019003765693651"); - DHTest.bitLength = 0; - DHParameterSpec dhParams = new DHParameterSpec(p512, g512); KeyPairGenerator SunJCEkeyGen = KeyPairGenerator.getInstance("DH", sunJceProvider); KeyPairGenerator KAEkeyGen = KeyPairGenerator.getInstance("DH", kaeProvider); diff --git a/jdk/test/org/openeuler/security/openssl/DigestTest.java b/jdk/test/org/openeuler/security/openssl/DigestTest.java new file mode 100644 index 000000000..a293f7268 --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/DigestTest.java @@ -0,0 +1,60 @@ +import org.openeuler.security.openssl.KAEProvider; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.Security; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * @test + * @summary Basic test for MD5 SHA256 SHA384 + * @requires os.arch=="aarch64" + * @run main/othervm DigestTest + */ +public class DigestTest { + private static String PLAIN_TEXT = "hello world"; + + private static Map<String, byte[]> alg = new HashMap<String, byte[]>(); + + static { + alg.put("MD5", new byte[] {94, -74, 59, -69, -32, 30, -18, -48, -109, -53, 34, -69, -113, 90, -51, -61}); + alg.put( + "SHA-256", + new byte[] { + -71, 77, 39, -71, -109, 77, 62, 8, -91, 46, 82, -41, -38, 125, -85, -6, + -60, -124, -17, -29, 122, 83, -128, -18, -112, -120, -9, -84, -30, -17, -51, -23 + }); + alg.put( + "SHA-384", + new byte[] { + -3, -67, -114, 117, -90, 127, 41, -9, 1, -92, -32, 64, 56, 94, 46, 35, + -104, 99, 3, -22, 16, 35, -110, 17, -81, -112, 127, -53, -72, 53, 120, -77, + -28, 23, -53, 113, -50, 100, 110, -3, 8, 25, -35, -116, 8, -115, -31, -67 + }); + alg.put( + "SM3", + new byte[] { + 68, -16, 6, 30, 105, -6, 111, -33, -62, -112, -60, -108, 101, 74, 5, + -36, 12, 5, 61, -89, -27, -59, 43, -124, -17, -109, -87, -42, 125, 63, + -1, -120 + }); + } + + public static void main(String[] args) throws Exception { + Security.insertProviderAt(new KAEProvider(), 1); + for (String key : alg.keySet()) { + test(PLAIN_TEXT, key, alg.get(key)); + } + } + + public static void test(String plainText, String algo, byte[] expectRes) throws Exception { + MessageDigest md = MessageDigest.getInstance(algo); + md.update(plainText.getBytes(StandardCharsets.UTF_8)); + byte[] res = md.digest(); + if (!Arrays.equals(res, expectRes)) { + throw new RuntimeException(algo + " failed"); + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/ECDHTest.java b/jdk/test/org/openeuler/security/openssl/ECDHTest.java index 590c31154..069c32295 100644 --- a/jdk/test/org/openeuler/security/openssl/ECDHTest.java +++ b/jdk/test/org/openeuler/security/openssl/ECDHTest.java @@ -41,6 +41,7 @@ import java.nio.charset.StandardCharsets; /** * @test * @summary Basic test for ECDH + * @requires os.arch=="aarch64" * @run main ECDHTest */ diff --git a/jdk/test/org/openeuler/security/openssl/HmacTest.java b/jdk/test/org/openeuler/security/openssl/HmacTest.java new file mode 100644 index 000000000..9ff328629 --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/HmacTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022, 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.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.security.Key; +import java.security.Security; +import java.util.Arrays; + +/** + * @test + * @summary test for Hmac + * @requires os.arch=="aarch64" + * @run main/othervm HmacTest + */ +public class HmacTest { + private static final byte[] PLAIN_BYTES = "hello world".getBytes(); + private static final String[] ALGORITHMS = new String[]{ + "HmacMD5", + "HmacSHA1", + "HmacSHA224", + "HmacSHA256", + "HmacSHA384", + "HmacSHA512", + }; + private static final byte[][] EXPECTED_BYTES = { + {-40, 63, -96, 13, 107, -33, -1, -53, -116, 117, 75, -6, 85, -88, -112, -90}, + {-68, 104, 112, -36, 123, 123, -92, 104, 89, -90, 63, 56, 84, 45, 12, -7, 41, 103, -105, -27}, + {-31, 0, 103, 51, -119, -61, 2, -76, -83, -113, 95, 86, 8, 46, 91, 20, + -15, -23, -71, 62, -50, 86, -54, 71, -94, -47, -103, 43}, + {-69, -83, -3, 7, 61, 38, -122, -59, 7, -53, 106, 114, 58, 102, 65, -118, + 54, -50, 116, -56, 110, 54, -71, 36, 60, 84, 14, 97, 78, 18, -119, -24}, + {100, -58, 106, 64, -96, 91, 99, -33, 36, -78, -53, -50, -78, 116, -110, 85, + 84, -5, -63, 17, 51, -69, -39, -122, 65, 8, -122, -43, 39, 13, -41, -52, + 45, -38, -59, 70, 17, -87, -63, -126, 4, 120, -77, 71, 119, 96, -2, -68}, + {-89, 47, -98, -12, 110, -88, 23, 2, 28, 26, -71, 53, -108, 54, -52, 1, + -121, -121, 87, 6, -78, 123, -14, -86, 127, 114, 124, -73, -98, 79, -122, 69, + -32, 50, 48, -79, -110, 66, 38, 70, -3, -76, 95, 55, 74, 48, 57, -121, + 22, 60, -83, -109, 59, 79, 0, -49, 107, 88, -82, -35, 87, -36, 49, -54} + }; + private static final Key key = new SecretKeySpec("mac".getBytes(), ""); + + public static void main(String[] args) throws Exception { + Security.insertProviderAt(new KAEProvider(), 1); + for (int i = 0; i < ALGORITHMS.length; i++) { + test(ALGORITHMS[i], key, PLAIN_BYTES, EXPECTED_BYTES[i]); + } + } + + private static void test(String algorithm, Key key, byte[] inputBytes, byte[] expectedBytes) throws Exception { + Mac mac = Mac.getInstance(algorithm); + mac.init(key); + mac.update(inputBytes); + byte[] bytes = mac.doFinal(); + if (!(mac.getProvider() instanceof KAEProvider)) { + throw new RuntimeException(algorithm + " failed," + + "provider=" + mac.getProvider().getClass() + "," + + "expectedProvider=" + KAEProvider.class); + } + if (!Arrays.equals(bytes, expectedBytes)) { + throw new RuntimeException(algorithm + " failed," + + "bytes=" + Arrays.toString(bytes) + "," + + "expectedBytes=" + Arrays.toString(expectedBytes)); + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/KAEConfTest.java b/jdk/test/org/openeuler/security/openssl/KAEConfTest.java new file mode 100644 index 000000000..9028d28b5 --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/KAEConfTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2022, 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.KAEConfig; +import org.openeuler.security.openssl.KAEProvider; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @summary Test KAE Conf + * @requires os.arch=="aarch64" + * @run main/othervm KAEConfTest DEFAULT + * @run main/othervm KAEConfTest SPECIFY + */ +public class KAEConfTest { + private static final String DEFAULT_CONF = System.getProperty("java.home") + + File.separator + "lib" + File.separator + "kaeprovider.conf"; + + private static final String SPECIFY_CONF = System.getProperty("user.dir") + + File.separator + "kaeprovider.conf"; + + private static final String SPECIFY_LOG_PATH = System.getProperty("user.dir") + File.separator + "kae.log"; + private static final List<File> files = new ArrayList<>(); + + enum Mode { + DEFAULT, + SPECIFY + } + + public static void main(String[] args) throws IOException { + Mode mode = getMode(args); + try { + init(mode); + new KAEProvider(); + test(mode); + } finally { + KAETestHelper.cleanUp(files); + } + } + + private static Mode getMode(String[] args) { + if (args.length <= 0) { + return Mode.DEFAULT; + } + return Mode.valueOf(args[0]); + } + + private static void init(Mode mode) throws IOException { + if (Mode.SPECIFY.equals(mode)) { + System.setProperty("kae.conf", SPECIFY_CONF); + File file = new File(SPECIFY_CONF); + if (!file.exists()) { + Files.createFile(file.toPath()); + } + files.add(file); + try (FileWriter fileWriter = new FileWriter(file)) { + fileWriter.write("kae.log=true"); + fileWriter.flush(); + } + } + } + + private static void testDefault() { + File file = new File(DEFAULT_CONF); + if (!file.exists()) { + throw new RuntimeException("test failed"); + } + } + + private static void testSpecify() { + String value = KAEConfig.privilegedGetOverridable("kae.log"); + if (!"true".equals(value)) { + throw new RuntimeException("test failed : kae.log=" + value); + } + File file = new File(SPECIFY_LOG_PATH); + if (!file.exists()) { + throw new RuntimeException(SPECIFY_LOG_PATH + "does not exist"); + } + // kae log file + files.add(file); + } + + private static void test(Mode mode) { + switch (mode) { + case DEFAULT: + testDefault(); + break; + case SPECIFY: + testSpecify(); + break; + default: + throw new IllegalArgumentException("invalid mode"); + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/KAEDisabledAlgorithmsTest.java b/jdk/test/org/openeuler/security/openssl/KAEDisabledAlgorithmsTest.java new file mode 100644 index 000000000..6301b6d76 --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/KAEDisabledAlgorithmsTest.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2022, 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.KAEConfig; +import org.openeuler.security.openssl.KAEProvider; + +import java.util.HashSet; +import java.util.Set; + +/* + * @test + * @summary Test property kae.engine.disableAlgorithms + * @requires os.arch=="aarch64" + * @run main/othervm -Dkae.engine.disabledAlgorithms=md5 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=sha256 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=sha384 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=sm3 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-128-ecb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-128-cbc KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-128-ctr KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-128-gcm KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-192-ecb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-192-cbc KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-192-ctr KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-192-gcm KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-256-ecb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-256-cbc KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-256-ctr KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-256-gcm KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=sm4-ecb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=sm4-cbc KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=sm4-ctr KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=sm4-ofb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=hmac-md5 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=hmac-sha1 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=hmac-sha224 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=hmac-sha256 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=hmac-sha384 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=hmac-sha512 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=rsa KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=dh KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=ec KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=aes-128-gcm,aes-192-gcm,aes-256-gcm KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.disabledAlgorithms=md5,aes-128-ecb,sm4-ecb,hmac-sha1,rsa,dh,ec KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=md5 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=sha256 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=sha384 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=sm3 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-128-ecb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-128-cbc KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-128-ctr KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-128-gcm KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-192-ecb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-192-cbc KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-192-ctr KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-192-gcm KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-256-ecb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-256-cbc KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-256-ctr KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-256-gcm KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=sm4-ecb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=sm4-cbc KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=sm4-ctr KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=sm4-ofb KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=hmac-md5 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=hmac-sha1 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=hmac-sha224 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=hmac-sha256 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=hmac-sha384 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=hmac-sha512 KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=rsa KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=dh KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=ec KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=aes-128-gcm,aes-192-gcm,aes-256-gcm KAEDisabledAlgorithmsTest + * @run main/othervm -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.engine.disabledAlgorithms=md5,aes-128-ecb,sm4-ecb,hmac-sha1,rsa,dh,ec KAEDisabledAlgorithmsTest + */ +public class KAEDisabledAlgorithmsTest { + + public static void main(String[] args) { + KAETestHelper.Engine engine = KAETestHelper.getEngine(); + if (!engine.isValid()) { + System.out.println("Skip test, engine " + engine.getEngineId() + " does not exist."); + return; + } + String[] disabledAlgorithms = getDisabledAlgorithms(); + init(); + new KAEProvider(); + test(disabledAlgorithms); + } + + private static final String[] PROPERTY_NAMES = new String[]{ + "kae.digest.useKaeEngine", + "kae.aes.useKaeEngine", + "kae.sm4.useKaeEngine", + "kae.hmac.useKaeEngine", + "kae.rsa.useKaeEngine", + "kae.dh.useKaeEngine", + "kae.ec.useKaeEngine" + }; + + private static String[] getDisabledAlgorithms() { + String value = System.getProperty("kae.engine.disabledAlgorithms"); + if (value == null) { + return new String[0]; + } + return value.split(","); + } + + private static void init() { + for (String propertyName : PROPERTY_NAMES) { + System.setProperty(propertyName, "true"); + } + } + + private static void test(String[] disabledAlgorithms) { + boolean[] useKaeEngineFlags = KAEConfig.getUseKaeEngineFlags(); + Set<Integer> disabledAlgorithmIndexSet = new HashSet<>(); + + // test disabled algorithms + for (String disabledAlgorithm : disabledAlgorithms) { + Integer index = KAETestHelper.getAlgorithmIndex(disabledAlgorithm); + if (index == null || index < 0 || index >= useKaeEngineFlags.length) { + continue; + } + if (useKaeEngineFlags[index]) { + throw new RuntimeException("test failed"); + } + disabledAlgorithmIndexSet.add(index); + } + + // test other algorithms that are not disabled (except ec) + for (int i = 0; i < useKaeEngineFlags.length - 1; i++) { + if (!disabledAlgorithmIndexSet.contains(i) && !useKaeEngineFlags[i]) { + throw new RuntimeException(KAETestHelper.getAlgorithmName(i) + " algorithm is not disabled"); + } + } + + // test whether the ec algorithm is disabled by default + if (useKaeEngineFlags[useKaeEngineFlags.length - 1]) { + throw new RuntimeException(KAETestHelper.getAlgorithmName(useKaeEngineFlags.length - 1) + + " algorithm is disabled by default"); + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/KAEEngineIdTest.java b/jdk/test/org/openeuler/security/openssl/KAEEngineIdTest.java new file mode 100644 index 000000000..2ddaf6712 --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/KAEEngineIdTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, 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 java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @summary Test KAE property kae.engine.id and kae.libcrypto.useGlobalMode + * @requires os.arch=="aarch64" + * @run main/othervm -Dkae.log=true KAEEngineIdTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=kae KAEEngineIdTest + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true KAEEngineIdTest + */ +public class KAEEngineIdTest { + + private static final String LOG_PATH = System.getProperty("user.dir") + + File.separator + "kae.log"; + + private static final List<File> files = new ArrayList<>(); + + public static void main(String[] args) throws IOException { + KAETestHelper.Engine engine = KAETestHelper.getEngine(); + if (!engine.isValid()) { + System.out.println("Skip test, engine " + engine.getEngineId() + " does not exist."); + return; + } + + try { + new KAEProvider(); + test(engine); + } finally { + KAETestHelper.cleanUp(files); + } + } + + private static void test(KAETestHelper.Engine engine) throws IOException { + File file = new File(LOG_PATH); + if (!file.exists()) { + throw new RuntimeException(LOG_PATH + " does not exist"); + } + files.add(file); + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { + String s = bufferedReader.readLine(); + if (!s.contains(engine.getEngineId() + " engine was found")) { + throw new RuntimeException("test failed"); + } + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/KAELogTest.java b/jdk/test/org/openeuler/security/openssl/KAELogTest.java new file mode 100644 index 000000000..31c8f5d99 --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/KAELogTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022, 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 java.io.File; +import java.util.ArrayList; +import java.util.List; + +/* + * @test + * @summary Test KAE log + * @requires os.arch=="aarch64" + * @run main/othervm KAELogTest + * @run main/othervm -Dkae.log=false KAELogTest + * @run main/othervm -Dkae.log=true KAELogTest + * @run main/othervm -Dkae.log=true -Dkae.log.file=./KAELogTest/kae.log KAELogTest + */ +public class KAELogTest { + private static final String DEFAULT_LOG_PATH = System.getProperty("user.dir") + + File.separator + "kae.log"; + + private static final String SPECIFY_LOG_PATH = System.getProperty("user.dir") + + File.separator + "KAELogTest" + File.separator + "kae.log"; + + private static final List<File> files = new ArrayList<>(); + + enum Mode { + DEFAULT, + DISABLE, + ENABLE, + SPECIFY + } + + public static void main(String[] args) { + Mode mode = getMode(); + try { + new KAEProvider(); + test(mode); + } finally { + KAETestHelper.cleanUp(files); + } + } + + private static Mode getMode() { + String enableKaeLog = System.getProperty("kae.log"); + if (enableKaeLog == null) { + return Mode.DEFAULT; + } else if ("false".equals(enableKaeLog)) { + return Mode.DISABLE; + } else { + String logPath = System.getProperty("kae.log.file"); + if (logPath == null) { + return Mode.ENABLE; + } + return Mode.SPECIFY; + } + } + + private static void testDefault() { + testDisable(); + } + + private static void testDisable() { + File file = new File(DEFAULT_LOG_PATH); + if (file.exists()) { + throw new RuntimeException("test failed"); + } + } + + private static void testEnable() { + File file = new File(DEFAULT_LOG_PATH); + if (!file.exists()) { + throw new RuntimeException("test failed"); + } + files.add(file); + } + + private static void testSpecify() { + File file = new File(KAELogTest.SPECIFY_LOG_PATH); + if (!file.exists()) { + throw new RuntimeException("test failed"); + } + files.add(file); + files.add(file.getParentFile()); + } + + private static void test(Mode mode) { + switch (mode) { + case DEFAULT: + testDefault(); + break; + case DISABLE: + testDisable(); + break; + case ENABLE: + testEnable(); + break; + case SPECIFY: + testSpecify(); + break; + default: + throw new IllegalArgumentException("invalid mode"); + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/KAETestHelper.java b/jdk/test/org/openeuler/security/openssl/KAETestHelper.java new file mode 100644 index 000000000..31e22493a --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/KAETestHelper.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2022, 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 java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class KAETestHelper { + private static final String KAE_ENGINE_ID = "kae"; + private static final String UADK_ENGINE_ID = "uadk_engine"; + private static boolean hasKaeEngine; + private static boolean hasUadkEngine; + + private static String engineRootPath; + + // algorithm names + private static final String[] ALGORITHM_NAMES = new String[]{ + "md5", + "sha256", + "sha384", + "sm3", + "aes-128-ecb", + "aes-128-cbc", + "aes-128-ctr", + "aes-128-gcm", + "aes-192-ecb", + "aes-192-cbc", + "aes-192-ctr", + "aes-192-gcm", + "aes-256-ecb", + "aes-256-cbc", + "aes-256-ctr", + "aes-256-gcm", + "sm4-ecb", + "sm4-cbc", + "sm4-ctr", + "sm4-ofb", + "hmac-md5", + "hmac-sha1", + "hmac-sha224", + "hmac-sha256", + "hmac-sha384", + "hmac-sha512", + "rsa", + "dh", + "ec" + }; + private static final Map<String, Integer> ALGORITHM_NAME_MAP = new HashMap<>(); + + private static final String PROVIDER_NAME = "KAEProvider"; + private static final String USE_OPENSSL_MSG = "Use openssl soft calculation"; + private static final String USE_KAE_HARDWARE_MSG = "enable KAE hardware acceleration"; + private static final Map<String, Boolean> ALGORITHM_MSG_MAP = new HashMap<>(); + + static { + init(); + } + + enum Engine { + default_engine(hasKaeEngine, KAE_ENGINE_ID), + kae(hasKaeEngine, KAE_ENGINE_ID), + uadk_engine(hasUadkEngine, UADK_ENGINE_ID); + private final boolean isValid; + private final String engineId; + + Engine(boolean isValid, String engineId) { + this.isValid = isValid; + this.engineId = engineId; + } + + public boolean isValid() { + return isValid; + } + + public String getEngineId() { + return engineId; + } + } + + private static void init() { + engineRootPath = System.getenv("OPENSSL_ENGINES"); + if (engineRootPath == null || engineRootPath.equals("")) { + System.out.println("Environment variable OPENSSL_ENGINES is not configured"); + } + hasKaeEngine = hasEngine(KAE_ENGINE_ID); + hasUadkEngine = hasEngine(UADK_ENGINE_ID); + + for (int i = 0; i < ALGORITHM_NAMES.length; i++) { + ALGORITHM_NAME_MAP.put(ALGORITHM_NAMES[i], i); + } + + ALGORITHM_MSG_MAP.put(USE_OPENSSL_MSG, false); + ALGORITHM_MSG_MAP.put(USE_KAE_HARDWARE_MSG, true); + } + + static Integer getAlgorithmIndex(String algorithmName) { + return ALGORITHM_NAME_MAP.get(algorithmName); + } + + static String getAlgorithmName(Integer algorithmIndex) { + return ALGORITHM_NAMES[algorithmIndex]; + } + + private static boolean hasEngine(String engineId) { + String filePath = engineRootPath + File.separator + engineId + ".so"; + File file = new File(filePath); + return file.exists(); + } + + static boolean hasKaeEngine() { + return hasKaeEngine; + } + + static boolean hasUadkEngine() { + return hasUadkEngine; + } + + static void cleanUp(List<File> files) { + for (File file : files) { + System.out.println("delete file : " + file); + file.delete(); + } + } + + static boolean[] parseLog(Engine engine, File file) throws IOException { + boolean[] kaeUseEngineFlags; + String expectedEngineMsg = engine.getEngineId() + " engine was found"; + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + // load engine message + String engineMsg = reader.readLine(); + if (engineMsg == null || !engineMsg.contains(expectedEngineMsg)) { + throw new RuntimeException("test failed : actual message :" + engineMsg); + } + + // summary message + String summaryMessage = reader.readLine(); + if (summaryMessage == null) { + throw new RuntimeException("test failed : summary message is null"); + } + + kaeUseEngineFlags = new boolean[ALGORITHM_NAMES.length]; + // strategy of each algorithm + String strategy; + while ((strategy = reader.readLine()) != null) { + String[] splitArray = strategy.split("=>"); + if (splitArray.length < 2) { + throw new RuntimeException("test failed : strategy = " + strategy); + } + + // algorithm Index + String algorithm = splitArray[0].replace(" ", ""); + Integer algorithmIndex = ALGORITHM_NAME_MAP.get(algorithm); + if (algorithmIndex == null) { + throw new RuntimeException("test failed : illegal algorithm " + algorithm); + } + + // provider and algorithm value + String detail = splitArray[1]; + String[] detailArray = detail.split(":"); + if (detailArray.length < 2) { + throw new RuntimeException("test failed : detail=" + strategy); + } + String provider = detailArray[0].replace(" ", ""); + if (!PROVIDER_NAME.equals(provider)) { + throw new RuntimeException("test failed : provider= " + provider); + } + String algorithmMsg = detailArray[1].trim(); + Boolean algorithmValue = ALGORITHM_MSG_MAP.get(algorithmMsg); + if (algorithmValue == null) { + throw new RuntimeException("test failed : algorithmMsg= " + algorithmMsg); + } + kaeUseEngineFlags[algorithmIndex] = algorithmValue; + } + } + return kaeUseEngineFlags; + } + + static KAETestHelper.Engine getEngine() { + String engineId = System.getProperty("kae.engine.id"); + if (engineId == null) { + return KAETestHelper.Engine.default_engine; + } + return KAETestHelper.Engine.valueOf(engineId); + } +} diff --git a/jdk/test/org/openeuler/security/openssl/KAEUseEngineTest.java b/jdk/test/org/openeuler/security/openssl/KAEUseEngineTest.java new file mode 100644 index 000000000..4e57f775e --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/KAEUseEngineTest.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2022, 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 java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/* + * @test + * @summary Test KAE property kae.<algorithm>.useKaeEngine + * @requires os.arch=="aarch64" + * @run main/othervm -Dkae.log=true -Dall.test=default KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.digest.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.aes.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.sm4.useKaeEngine=true KAEUseEngineTest + * @run main/othervm -Dkae.log=true -Dkae.hmac.useKaeEngine=true KAEUseEngineTest + * @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.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 + * @run main/othervm -Dkae.log=true -Dkae.hmac.useKaeEngine=true KAEUseEngineTest + * @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.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 + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.hmac.useKaeEngine=true KAEUseEngineTest + * @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.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 + * @run main/othervm -Dkae.log=true -Dkae.engine.id=uadk_engine -Dkae.libcrypto.useGlobalMode=true -Dkae.hmac.useKaeEngine=true KAEUseEngineTest + * @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 + */ +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 + }), + 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 + }, 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 + }, 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 + }, 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 + }, 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 + }, 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 + }, 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 + }, 6, true), + ALL_ENABLE(new boolean[]{ + true, false, false, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, false + }, true), + 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 + }, 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 + }, 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 + }, 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 + }, 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 + }, 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 + }, 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 + }, 6, 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); + private final boolean[] expectedResult; + private final Integer propertyNameIndex; + private final boolean enable; + private static final Map<String, Mode> modeMap = new HashMap<>(); + + static { + Mode[] modes = Mode.values(); + for (Mode mode : modes) { + if (mode.propertyNameIndex != null) { + modeMap.put(PROPERTY_NAMES[mode.propertyNameIndex] + ":" + mode.enable, mode); + } + } + modeMap.put("default", DEFAULT); + modeMap.put("disable", ALL_DISABLE); + modeMap.put("enable", ALL_ENABLE); + } + + Mode(boolean[] expectedResult) { + this(expectedResult, false); + } + + Mode(boolean[] expectedResult, boolean enable) { + this(expectedResult, null, enable); + } + + Mode(boolean[] expectedResult, Integer propertyNameIndex, boolean enable) { + this.expectedResult = expectedResult; + this.propertyNameIndex = propertyNameIndex; + this.enable = enable; + } + + static Mode getMode(String name, Boolean enable) { + return modeMap.get(name + ":" + enable); + } + + static Mode getMode(String key) { + return modeMap.get(key); + } + } + + private static final String KAE_LOG_PATH = System.getProperty("user.dir") + + File.separator + "kae.log"; + + private static final String[] PROPERTY_NAMES = new String[]{ + "kae.digest.useKaeEngine", + "kae.aes.useKaeEngine", + "kae.sm4.useKaeEngine", + "kae.hmac.useKaeEngine", + "kae.rsa.useKaeEngine", + "kae.dh.useKaeEngine", + "kae.ec.useKaeEngine" + }; + + private static final List<File> files = new ArrayList<>(); + + public static void main(String[] args) throws IOException { + KAETestHelper.Engine engine = KAETestHelper.getEngine(); + if (!engine.isValid()) { + System.out.println("Skip test, engine " + engine.getEngineId() + " does not exist."); + return; + } + Mode mode = getMode(); + if (mode == null) { + throw new RuntimeException("test failed: mode is null"); + } + + try { + new KAEProvider(); + test(mode, engine); + } finally { + KAETestHelper.cleanUp(files); + } + } + + private static Mode getMode() { + String value = System.getProperty("all.test"); + if (value != null) { + return Mode.getMode(value); + } + for (String propertyName : PROPERTY_NAMES) { + String property = System.getProperty(propertyName); + Boolean enable = null; + if (property != null) { + enable = Boolean.valueOf(property); + } + Mode mode = Mode.getMode(propertyName, enable); + if (mode != null) { + return mode; + } + } + return null; + } + + private static void test(Mode mode, KAETestHelper.Engine engine) throws IOException { + File file = new File(KAE_LOG_PATH); + files.add(file); + boolean[] kaeUseEngineFlags = KAETestHelper.parseLog(engine, file); + if (!Arrays.equals(mode.expectedResult, kaeUseEngineFlags)) { + throw new RuntimeException("test failed : expected : " + Arrays.toString(mode.expectedResult) + "," + + "actual:" + Arrays.toString(kaeUseEngineFlags)); + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/KaeDebugLogTest.java b/jdk/test/org/openeuler/security/openssl/KaeDebugLogTest.java new file mode 100644 index 000000000..bcce9cb8b --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/KaeDebugLogTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021, 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 javax.crypto.spec.SecretKeySpec; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.Security; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @test + * @summary test for KaeDebugLogTest + * @requires os.arch=="aarch64" + * @run main/othervm -Djava.security.debug=kae -Dkae.sm4.maxChunkSize=65536 KaeDebugLogTest + * @run main/othervm -Djava.security.debug=kae KaeDebugLogTest + * @run main/othervm -Djava.security.auth.debug=kae KaeDebugLogTest + * @run main/othervm KaeDebugLogTest + */ + +public class KaeDebugLogTest { + + private static final PrintStream err = System.err; + + public static void main(String[] args) throws Exception { + PrintStream printStream = new PrintStream("kaetest.out"); + System.setErr(printStream); + testDebugLog(); + System.setErr(printStream); + testSm4ChunkSize(); + } + + public static void testDebugLog() throws Exception { + new KAEProvider(); + Stream<String> lines = Files.lines(Paths.get("kaetest.out")); + System.setErr(err); + String content = lines.collect(Collectors.joining(System.lineSeparator())); + if(("kae".equals(System.getProperty("java.security.debug")) + || "kae".equals(System.getProperty("java.security..auth.debug"))) + && !content.contains("reading kae properties file:")){ + throw new RuntimeException("KaeDebugLogTest Failed! Failed to set the debug log."); + } + lines.close(); + } + + public static void testSm4ChunkSize() throws Exception { + Security.insertProviderAt(new KAEProvider(), 1); + Cipher cipher = Cipher.getInstance("SM4"); + cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec("sm4EncryptionKey".getBytes(StandardCharsets.UTF_8), "SM4")); + Stream<String> lines = Files.lines(Paths.get("kaetest.out")); + System.setErr(err); + String content = lines.collect(Collectors.joining(System.lineSeparator())); + String log = "The configured chunk size is " + System.getProperty("kae.sm4.maxChunkSize"); + if(("kae".equals(System.getProperty("java.security.debug")) + || "kae".equals(System.getProperty("java.security..auth.debug"))) + && Objects.nonNull(System.getProperty("kae.sm4.maxChunkSize")) &&!content.contains(log)){ + throw new RuntimeException("KaeDebugLogTest Failed! Failed to set the kae.sm4.maxChunkSize = " + System.getProperty("kae.sm4.maxChunkSize")); + } + lines.close(); + } + +} diff --git a/jdk/test/org/openeuler/security/openssl/KaeProviderTest.java b/jdk/test/org/openeuler/security/openssl/KaeProviderTest.java new file mode 100644 index 000000000..d8587891b --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/KaeProviderTest.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2021, 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 javax.crypto.Mac; +import javax.crypto.NoSuchPaddingException; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.Security; + +/** + * @test + * @requires os.arch=="aarch64" + * @summary test for KaeProviderTest + * @run main/othervm KaeProviderTest + * @run main/othervm KaeProviderTest true + * @run main/othervm KaeProviderTest false + * @run main/othervm KaeProviderTest wrong + */ + +public class KaeProviderTest { + + private static final String[] algorithmKaeProviderPropertyNames = new String[]{ + "kae.md5", + "kae.sha256", + "kae.sha384", + "kae.sm3", + "kae.aes", + "kae.sm4", + "kae.hmac", + "kae.rsa", + "kae.dh", + "kae.ec" + }; + + private static final String KAE = "KAEProvider"; + + public static void main(String[] args) throws Exception { + initProperty(args); + Security.insertProviderAt(new KAEProvider(), 1); + testALL(); + } + + private static void initProperty(String[] args) { + if (args.length <= 0) { + return; + } + String value = args[0]; + for (String name : algorithmKaeProviderPropertyNames){ + System.setProperty(name,value); + } + } + + public static void testALL() throws Exception { + testMd5(); + testSha256(); + testSha384(); + testSm3(); + testAes(); + testSm4(); + testHmac(); + testRsa(); + testDh(); + testEc(); + } + + public static void testMd5() throws NoSuchAlgorithmException { + MessageDigest messageDigest = MessageDigest.getInstance("MD5"); + judge("kae.md5",messageDigest.getProvider().getName()); + + } + + public static void testSha256() throws NoSuchAlgorithmException { + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); + judge("kae.sha256",messageDigest.getProvider().getName()); + } + + public static void testSha384() throws NoSuchAlgorithmException { + MessageDigest messageDigest = MessageDigest.getInstance("SHA-384"); + judge("kae.sha384",messageDigest.getProvider().getName()); + } + + public static void testSm3() throws NoSuchAlgorithmException { + try{ + MessageDigest messageDigest = MessageDigest.getInstance("SM3"); + judge("kae.sm3",messageDigest.getProvider().getName()); + }catch (NoSuchAlgorithmException e){ + if(Boolean.parseBoolean(System.getProperty("kae.sm3"))){ + throw e; + } + } + } + + public static void testAes() throws NoSuchAlgorithmException, NoSuchPaddingException { + Cipher cipher = Cipher.getInstance("AES"); + judge("kae.aes",cipher.getProvider().getName()); + } + + public static void testSm4() throws NoSuchAlgorithmException, NoSuchPaddingException { + try{ + Cipher cipher = Cipher.getInstance("SM4"); + judge("kae.sm4",cipher.getProvider().getName()); + }catch (NoSuchAlgorithmException e){ + if(Boolean.parseBoolean(System.getProperty("kae.sm4"))){ + throw e; + } + } + } + + public static void testHmac() throws NoSuchAlgorithmException { + Mac mac = Mac.getInstance("HmacMD5"); + judge("kae.hmac",mac.getProvider().getName()); + } + + public static void testRsa() throws NoSuchAlgorithmException, NoSuchPaddingException { + Cipher cipher = Cipher.getInstance("RSA"); + judge("kae.rsa",cipher.getProvider().getName()); + } + + public static void testDh() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH"); + judge("kae.dh",keyPairGenerator.getProvider().getName()); + } + + public static void testEc() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); + judge("kae.ec",keyPairGenerator.getProvider().getName()); + } + + private static void judge(String algorithm , String providerName){ + String value = System.getProperty(algorithm); + if (value == null) { + if (!KAE.equals(providerName)) { + throw new RuntimeException("KaeProviderTest Failed! default Provider.name is not right!"); + } + } else { + if (Boolean.parseBoolean(value) && !KAE.equals(providerName)) { + throw new RuntimeException("KaeProviderTest Failed! " + algorithm + " is " + value + "," + + " Provider.name is not right!"); + } + if (!Boolean.parseBoolean(value) && KAE.equals(providerName)) { + throw new RuntimeException("KaeProviderTest Failed! " + algorithm + " is " + value + ", " + + " Provider.name is not right!"); + } + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/RSATest.java b/jdk/test/org/openeuler/security/openssl/RSATest.java new file mode 100644 index 000000000..1f740af0b --- /dev/null +++ b/jdk/test/org/openeuler/security/openssl/RSATest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2022, 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 java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.spec.*; +import javax.crypto.Cipher; + +/** + * @test + * @summary Basic test for RSA + * @run main RSATest + */ + +public class RSATest { + private static final String algorithm = "RSA"; + private static KeyPairGenerator keyPairGenerator; + private static byte[] privateKey; + private static byte[] publicKey; + private static String plainText = "helloworld"; + // 512, 768, + private static int[] keySizes = {1024, 2048, 4096, 5120, 6144}; + private static String[] signAlgorithms = { + "MD2withRSA", "MD5withRSA", "SHA1withRSA", "SHA224withRSA", "SHA256withRSA", "SHA384withRSA", "SHA512withRSA" + }; + private static String[] signAlgorithmsPSS = {"SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"}; + + public static void main(String[] args) throws Exception { + Security.insertProviderAt(new KAEProvider(), 1); + + for (int keySize : keySizes) { + testKeyPairByKeySize(keySize); + testRSACipher(keySize); + testSignature(); + testPSSSignature(keySize); + } + } + + public static void testKeyPairByKeySize(int keySize) throws Exception { + keyPairGenerator = KeyPairGenerator.getInstance(algorithm); + keyPairGenerator.initialize(keySize); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + + PrivateKey pairPrivate = keyPair.getPrivate(); + PublicKey pairPublic = keyPair.getPublic(); + + privateKey = pairPrivate.getEncoded(); + publicKey = pairPublic.getEncoded(); + } + + public static void testRSACipher(int keySize) throws Exception { + PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKey)); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, pubKey); + + byte[] cipherText = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)); + + PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKey)); + + cipher.init(Cipher.DECRYPT_MODE, priKey); + + String decryptText = new String(cipher.doFinal(cipherText)); + + if (!plainText.equals(decryptText)) { + throw new RuntimeException("rsa decryption failed. keySize = " + keySize); + } + } + + public static void testSignature() throws Exception { + PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKey)); + PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKey)); + + for (String algorithm : signAlgorithms) { + Signature sign = Signature.getInstance(algorithm); + sign.initSign(priKey); + sign.update(plainText.getBytes()); + byte[] signInfo = sign.sign(); + + sign.initVerify(pubKey); + sign.update(plainText.getBytes()); + if (!sign.verify(signInfo)) { + throw new RuntimeException("rsa testSignature failed. digest algorithm = " + algorithm); + } + } + } + + public static void testPSSSignature(int keySize) throws Exception { + PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(privateKey)); + PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKey)); + + Signature sign = Signature.getInstance("RSASSA-PSS"); + + for (String algorithm : signAlgorithmsPSS) { + if (algorithm.equals(signAlgorithmsPSS[4]) && keySize <= 1024) { + continue; + } + sign.initSign(priKey); + + MessageDigest digest = MessageDigest.getInstance(algorithm); + byte[] digestByte = digest.digest(plainText.getBytes()); + sign.setParameter( + new PSSParameterSpec(algorithm, "MGF1", new MGF1ParameterSpec(algorithm), digestByte.length, 1)); + + sign.update(plainText.getBytes()); + byte[] signInfo = sign.sign(); + + sign.initVerify(pubKey); + + sign.update(plainText.getBytes()); + if (!sign.verify(signInfo)) { + throw new RuntimeException("rsa testPSSSignature failed. digest algorithm = " + algorithm); + } + } + } +} diff --git a/jdk/test/org/openeuler/security/openssl/SM3Test.java b/jdk/test/org/openeuler/security/openssl/SM3Test.java deleted file mode 100644 index 181f708ff..000000000 --- a/jdk/test/org/openeuler/security/openssl/SM3Test.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021, 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 java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.security.MessageDigest; -import java.security.Security; - -/** - * @test - * @summary Basic test for sm3 - * @run main SM3Test - */ - -public class SM3Test { - - private static String plainText = "helloworldhellow"; - - public static void main(String[] args) throws Exception { - Security.insertProviderAt(new KAEProvider(), 1); - test(plainText, "SM3", new byte[]{40, -103, -71, 4, -80, -49, 94, 112, 11, -75, -66, 121, 63, 80, 62, -14, -45, -75, -34, 66, -77, -34, -26, 26, 33, -23, 45, 52, -74, 67, -18, 118}); - } - - public static void test(String plainText, String algo, byte[] expectRes) throws Exception { - MessageDigest md = MessageDigest.getInstance(algo); - md.update(plainText.getBytes(StandardCharsets.UTF_8)); - byte[] res = md.digest(); - if (!Arrays.equals(res, expectRes)) { - throw new RuntimeException("sm3 failed"); - } - } - -} diff --git a/jdk/test/org/openeuler/security/openssl/SM4Test.java b/jdk/test/org/openeuler/security/openssl/SM4Test.java index 4c28dc5b6..1029fe897 100644 --- a/jdk/test/org/openeuler/security/openssl/SM4Test.java +++ b/jdk/test/org/openeuler/security/openssl/SM4Test.java @@ -22,9 +22,10 @@ */ import org.openeuler.security.openssl.KAEProvider; + +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.security.NoSuchAlgorithmException; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; @@ -55,6 +56,25 @@ public class SM4Test { test(shortPlainText, "SM4/OFB/PKCS5Padding", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110}); testCtrShortIv(plainText, "SM4/CTR/NOPADDING", new byte[]{-13, 73, 40, -36, -64, -67, 75, -72, 90, 58, 73, -4, -36, 115, 126, -48}); + + testByteBuffer(plainText, "SM4/CBC/NOPADDING", new byte[]{86, 69, 47, -115, -63, 54, 35, 24, -2, 114, 113, 102, 82, 20, 69, 59}); + testByteBuffer(shortPlainText, "SM4/CBC/PKCS5Padding", new byte[]{10, 105, 75, -80, -85, -68, 13, -53, 42, 91, -64, 99, 104, 35, -85, 8}); + testByteBuffer(plainText, "SM4/ECB/NOPADDING", new byte[]{103, 36, -31, -53, -109, -12, -71, -79, -54, 106, 10, -3, -35, -22, -122, -67}); + testByteBuffer(shortPlainText, "SM4/ECB/PKCS5Padding", new byte[]{-10, 99, -9, 90, 58, -36, -109, 54, -55, -52, 7, -49, 110, -88, 72, 40}); + testByteBuffer(plainText, "SM4/CTR/NOPADDING", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110, -100, -113, -46, -29, -11, 71}); + testByteBuffer(plainText, "SM4/OFB/NOPADDING", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110, -100, -113, -46, -29, -11, 71}); + testByteBuffer(shortPlainText, "SM4/OFB/PKCS5Padding", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110}); + + System.setProperty("kae.sm4.maxChunkSize", "65536"); + testByteBuffer(plainText, "SM4/CBC/NOPADDING", new byte[]{86, 69, 47, -115, -63, 54, 35, 24, -2, 114, 113, 102, 82, 20, 69, 59}); + testByteBuffer(shortPlainText, "SM4/CBC/PKCS5Padding", new byte[]{10, 105, 75, -80, -85, -68, 13, -53, 42, 91, -64, 99, 104, 35, -85, 8}); + testByteBuffer(plainText, "SM4/ECB/NOPADDING", new byte[]{103, 36, -31, -53, -109, -12, -71, -79, -54, 106, 10, -3, -35, -22, -122, -67}); + testByteBuffer(shortPlainText, "SM4/ECB/PKCS5Padding", new byte[]{-10, 99, -9, 90, 58, -36, -109, 54, -55, -52, 7, -49, 110, -88, 72, 40}); + testByteBuffer(plainText, "SM4/CTR/NOPADDING", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110, -100, -113, -46, -29, -11, 71}); + testByteBuffer(plainText, "SM4/OFB/NOPADDING", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110, -100, -113, -46, -29, -11, 71}); + testByteBuffer(shortPlainText, "SM4/OFB/PKCS5Padding", new byte[]{32, 108, 35, 108, -16, 119, -111, 114, 94, 110}); + + } public static void test(String plainText, String algo, byte[] expectRes) throws Exception { @@ -92,4 +112,44 @@ public class SM4Test { throw new RuntimeException("sm4 decryption failed, algo = " + algo); } } + + public static void testByteBuffer(String plainText, String algo, byte[] expectRes) throws Exception { + // encrypt + Cipher encryptCipher = Cipher.getInstance(algo); + if (algo.contains("ECB")) { + encryptCipher.init(Cipher.ENCRYPT_MODE, ks); + } else { + encryptCipher.init(Cipher.ENCRYPT_MODE, ks, iv); + } + int inputLen = plainText.length(); + ByteBuffer sourceByteBuffer = ByteBuffer.allocateDirect(inputLen); + sourceByteBuffer.put(plainText.getBytes()); + sourceByteBuffer.flip(); + int outputLen = encryptCipher.getOutputSize(inputLen); + ByteBuffer encryptedByteBuffer = ByteBuffer.allocate(outputLen); + encryptCipher.doFinal(sourceByteBuffer,encryptedByteBuffer); + encryptedByteBuffer.flip(); + byte[] encryptedBytes = new byte[encryptedByteBuffer.limit()]; + encryptedByteBuffer.get(encryptedBytes); + if (!Arrays.equals(encryptedBytes, expectRes)) { + throw new RuntimeException("sm4 encryption failed, algo = " + algo); + } + sourceByteBuffer.clear(); + encryptedByteBuffer.flip(); + + // decrypt + Cipher decryptCipher = Cipher.getInstance(algo); + decryptCipher.init(Cipher.DECRYPT_MODE, ks, encryptCipher.getParameters()); + outputLen = decryptCipher.getOutputSize(encryptedBytes.length); + ByteBuffer decryptedByteBuffer = ByteBuffer.allocate(outputLen); + decryptCipher.doFinal(encryptedByteBuffer, decryptedByteBuffer); + decryptedByteBuffer.flip(); + byte[] decryptedBytes = new byte[decryptedByteBuffer.limit()]; + decryptedByteBuffer.get(decryptedBytes); + if (!Arrays.equals(plainText.getBytes(), decryptedBytes)) { + throw new RuntimeException("sm4 decryption failed, algo = " + algo); + } + encryptedByteBuffer.clear(); + decryptedByteBuffer.clear(); + } } -- 2.17.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2