The java implementation of crypto is not performing very well with openJ9-OpenJDK build. To improve the crypto performance, native implementation can be used.
OpenSSL is an open source crypto TLS/SSL implementation [https://www.openssl.org/] and it is well established and stable native implementation used with enterprise applications. The source code is available at https://github.com/openssl/openssl.
The proposal is to use the OpenSSL crypto algorithms with OpenJ9-OpenJDK for better performance.
The design approach is to provide a switch in the existing security providers to switch to the native crypto implementation instead of creating a new security provider.
In the first phase, three crypto algorithms from OpenSSL are enabled for the native crypto. They are Digest [only SHA algorithms], Cipher Block Chaining [CBC] and Galois Counter Mode [GCM]. We can consider enabling more algorithms from OpenSSL in future.
The native crypto implementation is disabled by default and can be enabled using one or more of the following properties.
-Djdk.nativeCrypto=true
-Djdk.nativeDigest=true
-Djdk.nativeCBC=true
-Djdk.nativeGCM=true
If all three crypto algorithms from openssl to be enabled, use jdk.nativeCrypto. If any specific crypto algorithms only or its combinations to be enabled, use the corresponding property [jdk.nativeDigest, jdk.nativeCBC or jdk. nativeGCM]. Once the native implementation is stable, we can consider enabling them by default.
From the driver programs of the Digest [sun/security/provider/SunEntries], CBC and GCM [com/sun/crypto/provider/CipherCore] algorithms, check for the new property and switch to the native implementation.
A java interface [jdk.crypto.jniprovider.NativeCrypto] is introduced to call the JNI program [native/jdk/crypto /jniprovider/NativeCrypto.c] which act as a native wrapper program to make openssl calls for the Digest, CBC and GCM algorithms.
The high level design approach for implementing the openssl support is added as an attachment.
OpenJDK_NativeCrypto_DesignApproach.pptx
Specific version of openssl source can be cloned from the github based on the version specified with get_source.sh using --openssl-version=1.1.xx. Currently, only the latest version [1.1.xx] is supported. We can consider supporting other versions later. If openssl-version is not specified, openssl source does not get downloaded. If the openssl-version is specified, it will check if the same version is already available in standard download location SRC_DIR/openssl. If same version exists, it will skip downloading the source. Otherwise, it cleanup the openssl directory and download the source.
While configuring, user can select the openssl directory which is used for building opendk and whether the openssl crypto library [libcrypto.so] needs to be included in jre/lib/arch path.
The configure option --with-openssl can be used to select the openssl directory. The user can specify three options:
fetched - to use the downloaded openssl source.
system - to use the package installed openssl library
path to openssl library - to use a custom openssl library already built.
By default, the openssl crypto library[libcrypto.so] is not bundled with JDK build. If user wants to include the crypto library while building openj9-openjdk, they can use the option --enable-openssl-bundling. The openj9-openjdk8 build systems (AdoptOpenJDK and Eclipse OpenJ9 CI) can use the property --enable-openssl-bundling to include the crypto library with JDK which makes it easier for the Java users to exploit openssl crypto as otherwise, they have to build/install the openssl library in the target system.
A new library libjncrypto [where jn stands for java-native] is introduced to include the NativeCrypto object module. The libcrypto is dynamically linked to libjncrypto so that user has the flexibility to decide whether the crypto libraries need to be bundled with the JDK or not.
With the openssl support, the user is able to build OpenJDK_8-Eclipse_OpenJ9 with and without openssl.
For developers who want to continue without openssl, they can continue to do so without making any changes.
For developers who want to generate JDK with openssl can use the option '--with-openssl=path_to_crypto_library | fetched | system'
For developers who want to generate JDK with openssl and bundle the crypto library with JDK build can use the options -with-openssl= and --enable-openssl-bundling
In order to merge the openssl support change-set, there is no build environment dependency for AdoptOpenJDK and Eclipse OpenJ9. When ever, we install the pre-built openssl binaries in the build system and enable the property, it started building JDK with openssl support. Till then it continue to build the JDK as it was before.