Skip to content

Commit

Permalink
TKSS-1044: Provide one-shot native crypto implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
johnshajiang committed Jan 14, 2025
1 parent 843f125 commit 34e1150
Show file tree
Hide file tree
Showing 31 changed files with 2,233 additions and 75 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/build-pr.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (C) 2023, 2024, THL A29 Limited, a Tencent company. All rights reserved.
# Copyright (C) 2023, 2025, THL A29 Limited, a Tencent company. 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
Expand Down Expand Up @@ -57,7 +57,10 @@ jobs:
uses: gradle/actions/setup-gradle@v3

- name: Execute tests with the pure Java crypto
run: ./gradlew clean test
run: ./gradlew clean testJavaOnCurrent

- name: Execute tests with the native crypto
run: ./gradlew clean testNativeOnCurrent

- name: Execute tests with the native OneShot crypto
run: ./gradlew clean testNativeOneShotOnCurrent
70 changes: 43 additions & 27 deletions buildSrc/src/main/kotlin/kona-common.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ tasks {
}
}

val testOnCurrent = register("testOnCurrent", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false")
val testJavaOnCurrent = register("testJavaOnCurrent", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))

Expand All @@ -70,7 +70,7 @@ tasks {
}

register("testNativeOnCurrent", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=true")
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Native")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))

Expand All @@ -79,8 +79,18 @@ tasks {
}
}

register("testOnAdop8", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false")
register("testNativeOneShotOnCurrent", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=NativeOneShot")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))

doFirst {
println("Testing JDK: " + javaLauncher.get().metadata.installationPath)
}
}

register("testJavaOnAdop8", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))

Expand All @@ -94,8 +104,8 @@ tasks {
}
}

register("testOnAdop11", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false",
register("testJavaOnAdop11", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java",
"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))
Expand All @@ -110,8 +120,8 @@ tasks {
}
}

register("testOnAdop17", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false",
register("testJavaOnAdop17", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java",
"--add-exports", "java.base/jdk.internal.access=ALL-UNNAMED")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))
Expand All @@ -126,8 +136,8 @@ tasks {
}
}

register("testOnAdop21", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false",
register("testJavaOnAdop21", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java",
"--add-exports", "java.base/jdk.internal.access=ALL-UNNAMED")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))
Expand All @@ -142,8 +152,8 @@ tasks {
}
}

register("testOnKona8", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false");
register("testJavaOnKona8", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java");

systemProperty("test.classpath", classpath.joinToString(separator = ":"))

Expand All @@ -157,8 +167,8 @@ tasks {
}
}

register("testOnKona11", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false",
register("testJavaOnKona11", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java",
"--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))
Expand All @@ -173,8 +183,8 @@ tasks {
}
}

register("testOnKona17", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false",
register("testJavaOnKona17", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java",
"--add-exports", "java.base/jdk.internal.access=ALL-UNNAMED")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))
Expand All @@ -189,8 +199,8 @@ tasks {
}
}

register("testOnKona21", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false",
register("testJavaOnKona21", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java",
"--add-exports", "java.base/jdk.internal.access=ALL-UNNAMED")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))
Expand All @@ -205,8 +215,8 @@ tasks {
}
}

register("testOnGraal17", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false",
register("testJavaOnGraal17", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java",
"--add-exports", "java.base/jdk.internal.access=ALL-UNNAMED")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))
Expand All @@ -221,8 +231,8 @@ tasks {
}
}

register("testOnGraal21", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false",
register("testJavaOnGraal21", CommonTest::class) {
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java",
"--add-exports", "java.base/jdk.internal.access=ALL-UNNAMED")

systemProperty("test.classpath", classpath.joinToString(separator = ":"))
Expand All @@ -238,24 +248,30 @@ tasks {
}

test {
dependsOn(testOnCurrent)
dependsOn(testJavaOnCurrent)
}

javadoc {
options.locale = "en_US"
isFailOnError = false
}

register("jmh", type=JavaExec::class) {
register("jmhJava", type=JavaExec::class) {
mainClass.set("org.openjdk.jmh.Main")
classpath(sourceSets["jmh"].runtimeClasspath)
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=false")
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Java")
}

register("jmhNative", type=JavaExec::class) {
mainClass.set("org.openjdk.jmh.Main")
classpath(sourceSets["jmh"].runtimeClasspath)
jvmArgs("-Dcom.tencent.kona.useNativeCrypto=true")
jvmArgs("-Dcom.tencent.kona.defaultCrypto=Native")
}

register("jmhNativeOneShot", type=JavaExec::class) {
mainClass.set("org.openjdk.jmh.Main")
classpath(sourceSets["jmh"].runtimeClasspath)
jvmArgs("-Dcom.tencent.kona.defaultCrypto=NativeOneShot")
}
}

Expand Down
25 changes: 20 additions & 5 deletions kona-crypto/src/main/java/com/tencent/kona/crypto/CryptoInsts.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022, 2024, THL A29 Limited, a Tencent company. All rights reserved.
* Copyright (C) 2022, 2025, THL A29 Limited, a Tencent company. 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
Expand Down Expand Up @@ -33,9 +33,18 @@

public class CryptoInsts {

public static final Provider PROV = CryptoUtils.useNativeCrypto()
? KonaCryptoNativeProvider.instance()
: KonaCryptoProvider.instance();
public static final Provider PROV = provider();

private static Provider provider() {
String provName = CryptoUtils.defaultCrypto();
if ("Native".equalsIgnoreCase(provName)) {
return KonaCryptoNativeProvider.instance();
} else if ("NativeOneShot".equalsIgnoreCase(provName)) {
return KonaCryptoNativeOneShotProvider.instance();
} else {
return KonaCryptoProvider.instance();
}
}

private static final Set<String> ALGO_PARAMS_ALGOS
= new HashSet<>(Arrays.asList("EC", "SM4", "PBES2"));
Expand Down Expand Up @@ -114,7 +123,13 @@ public static Cipher getCipher(String algorithm, Provider prov)

public static Cipher getCipher(String algorithm)
throws NoSuchPaddingException, NoSuchAlgorithmException {
return getCipher(algorithm, PROV);
if ("SM4".equalsIgnoreCase(algorithm)) {
return getCipher(algorithm,
// use pure Java-based SM4 for TLCP/TLS protocol
KonaCryptoProvider.instance());
} else {
return getCipher(algorithm, PROV);
}
}

private static final Set<String> MESSAGE_DIGEST_ALGOS
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022, 2024, THL A29 Limited, a Tencent company. All rights reserved.
* Copyright (C) 2022, 2025, THL A29 Limited, a Tencent company. 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
Expand Down Expand Up @@ -44,8 +44,9 @@ public final class CryptoUtils {
private static final String JDK_VENDOR = privilegedGetProperty(
"java.specification.vendor");

private static final boolean USE_NATIVE_CRYPTO = privilegedGetBoolProperty(
"com.tencent.kona.useNativeCrypto", "false");
// Java, Native or NativeOneShot
private static final String DEFAULT_CRYPTO = privilegedGetProperty(
"com.tencent.kona.defaultCrypto", "Java");

public static String privilegedGetProperty(String key, String def) {
return AccessController.doPrivileged(
Expand Down Expand Up @@ -86,8 +87,8 @@ public static boolean isAndroid() {
return JDK_VENDOR.contains("Android");
}

public static boolean useNativeCrypto() {
return USE_NATIVE_CRYPTO && isLinux() && !isAndroid();
public static String defaultCrypto() {
return isLinux() && !isAndroid() ? DEFAULT_CRYPTO : "Java";
}

public static boolean isLinux() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (C) 2024, 2025, THL A29 Limited, a Tencent company. 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 as
* published by the Free Software Foundation. THL A29 Limited designates
* this particular file as subject to the "Classpath" exception as provided
* in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License version 2 for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package com.tencent.kona.crypto;

import com.tencent.kona.sun.security.rsa.SunRsaSignEntries;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Provider;

/**
* The Kona Crypto Provider based on OpenSSL.
*/
public class KonaCryptoNativeOneShotProvider extends Provider {

static final String NAME = "KonaCrypto-NativeOneShot";

private static final double VERSION_NUM = 1.0D;

private static final String INFO = "Kona crypto provider based on OpenSSL "
+ "(implements SM2, SM3 and SM4 algorithms)";

private static volatile KonaCryptoNativeOneShotProvider instance = null;

public KonaCryptoNativeOneShotProvider() {
super(NAME, VERSION_NUM, INFO);

AccessController.doPrivileged(
(PrivilegedAction<Void>) () -> {
putEntries(this);

return null;
});
}

private static void putEntries(Provider provider) {
putSMEntries(provider);
KonaCryptoProvider.putSMPBES2Entries(provider);
KonaCryptoProvider.putECEntries(provider);
SunRsaSignEntries.putEntries(provider);
}

private static void putSMEntries(Provider provider) {
provider.put("Cipher.SM4 SupportedPaddings", "NOPADDING|PKCS7PADDING");
provider.put("Cipher.SM4 SupportedModes", "CBC|CTR|ECB|GCM");
provider.put("Cipher.SM4",
"com.tencent.kona.crypto.provider.nativeImpl.SM4Cipher");;
provider.put("AlgorithmParameters.SM4",
"com.tencent.kona.crypto.provider.SM4Parameters");
provider.put("AlgorithmParameterGenerator.SM4",
"com.tencent.kona.crypto.provider.SM4ParameterGenerator");
provider.put("KeyGenerator.SM4",
"com.tencent.kona.crypto.provider.SM4KeyGenerator");

provider.put("Alg.Alias.MessageDigest.OID.1.2.156.10197.1.401", "SM3");
provider.put("MessageDigest.SM3",
"com.tencent.kona.crypto.provider.nativeImpl.SM3OneShotMessageDigest");
provider.put("Mac.HmacSM3",
"com.tencent.kona.crypto.provider.nativeImpl.SM3OneShotHMac");
provider.put("Alg.Alias.Mac.SM3HMac", "HmacSM3");
provider.put("KeyGenerator.HmacSM3",
"com.tencent.kona.crypto.provider.SM3HMacKeyGenerator");
provider.put("Alg.Alias.KeyGenerator.SM3HMac", "HmacSM3");

provider.put("Alg.Alias.Cipher.OID.1.2.156.10197.1.301", "SM2");
provider.put("Alg.Alias.Signature.OID.1.2.156.10197.1.501", "SM2");
provider.put("KeyPairGenerator.SM2",
"com.tencent.kona.crypto.provider.nativeImpl.SM2OneShotKeyPairGenerator");
provider.put("Cipher.SM2", "com.tencent.kona.crypto.provider.nativeImpl.SM2OneShotCipher");
provider.put("Signature.SM2", "com.tencent.kona.crypto.provider.nativeImpl.SM2OneShotSignature");
provider.put("Alg.Alias.Signature.SM3withSM2", "SM2");
provider.put("KeyAgreement.SM2", "com.tencent.kona.crypto.provider.nativeImpl.SM2OneShotKeyAgreement");
provider.put("KeyFactory.SM2", "com.tencent.kona.crypto.provider.SM2KeyFactory");
}

public static KonaCryptoNativeOneShotProvider instance() {
if (instance == null) {
instance = new KonaCryptoNativeOneShotProvider();
}
return instance;
}
}
Loading

0 comments on commit 34e1150

Please sign in to comment.