Skip to content

Commit d655244

Browse files
authored
Merge pull request ibmruntimes#867 from KostasTsiounis/skip_native_fips
Check if OpenSSL is in FIPS mode and use Java for some algorithms
2 parents bce7efc + d8d7ce5 commit d655244

File tree

4 files changed

+97
-4
lines changed

4 files changed

+97
-4
lines changed

closed/src/java.base/share/classes/jdk/crypto/jniprovider/NativeCrypto.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ private static final class InstanceHolder {
7979
// or one of the OPENSSL_VERSION_x_x_x constants
8080
private final long ossl_ver;
8181

82+
private final boolean isOpenSSLFIPS;
83+
8284
private static long loadCryptoLibraries() {
8385
long osslVersion;
8486

@@ -105,6 +107,11 @@ private static long loadCryptoLibraries() {
105107
@SuppressWarnings("removal")
106108
private NativeCrypto() {
107109
ossl_ver = AccessController.doPrivileged((PrivilegedAction<Long>) () -> loadCryptoLibraries()).longValue();
110+
if (ossl_ver != -1) {
111+
isOpenSSLFIPS = isOpenSSLFIPS();
112+
} else {
113+
isOpenSSLFIPS = false;
114+
}
108115
}
109116

110117
/**
@@ -178,6 +185,54 @@ public static final boolean isTraceEnabled() {
178185
return traceEnabled;
179186
}
180187

188+
public static final boolean isOpenSSLFIPSVersion() {
189+
return InstanceHolder.instance.isOpenSSLFIPS;
190+
}
191+
192+
/**
193+
* Check whether a native implementation is available in the loaded OpenSSL library.
194+
* Note that, an algorithm could be unavailable due to options used to build the
195+
* OpenSSL version utilized, or using a FIPS version that doesn't allow it.
196+
*
197+
* @param algorithm the algorithm checked
198+
* @return whether a native implementation of the given crypto algorithm is available
199+
*/
200+
public static final boolean isAlgorithmAvailable(String algorithm) {
201+
boolean isAlgorithmAvailable = false;
202+
if (isAllowedAndLoaded()) {
203+
if (isOpenSSLFIPSVersion()) {
204+
switch (algorithm) {
205+
case "ChaCha20":
206+
case "MD5":
207+
// not available
208+
break;
209+
default:
210+
isAlgorithmAvailable = true;
211+
break;
212+
}
213+
} else {
214+
switch (algorithm) {
215+
case "MD5":
216+
isAlgorithmAvailable = isMD5Available();
217+
break;
218+
default:
219+
isAlgorithmAvailable = true;
220+
break;
221+
}
222+
}
223+
}
224+
225+
// Issue a message indicating whether the crypto implementation is available.
226+
if (traceEnabled) {
227+
if (isAlgorithmAvailable) {
228+
System.err.println(algorithm + " native crypto implementation is available.");
229+
} else {
230+
System.err.println(algorithm + " native crypto implementation is not available.");
231+
}
232+
}
233+
return isAlgorithmAvailable;
234+
}
235+
181236
@CallerSensitive
182237
public static NativeCrypto getNativeCrypto() {
183238
ClassLoader callerClassLoader = Reflection.getCallerClass().getClassLoader();
@@ -204,6 +259,8 @@ public void run() {
204259

205260
public static final native boolean isMD5Available();
206261

262+
private static final native boolean isOpenSSLFIPS();
263+
207264
public final native long DigestCreateContext(long nativeBuffer,
208265
int algoIndex);
209266

closed/src/java.base/share/native/libjncrypto/NativeCrypto.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ int OSSL102_RSA_set0_crt_params(RSA *, BIGNUM *, BIGNUM *, BIGNUM *);
8282
#define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG
8383
#endif
8484

85+
/* Whether loaded library is in FIPS mode. */
86+
static jboolean OSSL_IS_FIPS;
87+
8588
/* Header for EC algorithm */
8689
jboolean OSSL_ECGF2M;
8790
int setECPublicCoordinates(EC_KEY *, BIGNUM *, BIGNUM *, int);
@@ -365,6 +368,18 @@ static jlong extractVersionToJlong(const char *astring)
365368
}
366369

367370
static void *crypto_library = NULL;
371+
372+
/*
373+
* Class: jdk_crypto_jniprovider_NativeCrypto
374+
* Method: isOpenSSLFIPS
375+
* Signature: ()Z
376+
*/
377+
JNIEXPORT jboolean JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_isOpenSSLFIPS
378+
(JNIEnv *env, jclass clazz)
379+
{
380+
return OSSL_IS_FIPS;
381+
}
382+
368383
/*
369384
* Class: jdk_crypto_jniprovider_NativeCrypto
370385
* Method: loadCrypto
@@ -440,6 +455,25 @@ JNIEXPORT jlong JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
440455
}
441456
}
442457

458+
/* Check whether the loaded OpenSSL library is in FIPS mode. */
459+
if (ossl_ver >= OPENSSL_VERSION_3_0_0) {
460+
typedef int OSSL_fipsmode_t(OSSL_LIB_CTX *);
461+
OSSL_fipsmode_t *ossl_fipsmode = (OSSL_fipsmode_t *)find_crypto_symbol(crypto_library, "EVP_default_properties_is_fips_enabled");
462+
if ((NULL != ossl_fipsmode) && (1 == (*ossl_fipsmode)(NULL))) {
463+
OSSL_IS_FIPS = JNI_TRUE;
464+
} else {
465+
OSSL_IS_FIPS = JNI_FALSE;
466+
}
467+
} else {
468+
typedef int OSSL_fipsmode_t(void);
469+
OSSL_fipsmode_t *ossl_fipsmode = (OSSL_fipsmode_t *)find_crypto_symbol(crypto_library, "FIPS_mode");
470+
if ((NULL != ossl_fipsmode) && (1 == (*ossl_fipsmode)())) {
471+
OSSL_IS_FIPS = JNI_TRUE;
472+
} else {
473+
OSSL_IS_FIPS = JNI_FALSE;
474+
}
475+
}
476+
443477
/* Load the function symbols for OpenSSL errors. */
444478
OSSL_error_string_n = (OSSL_error_string_n_t*)find_crypto_symbol(crypto_library, "ERR_error_string_n");
445479
OSSL_error_string = (OSSL_error_string_t*)find_crypto_symbol(crypto_library, "ERR_error_string");

src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
/*
2626
* ===========================================================================
27-
* (c) Copyright IBM Corp. 2018, 2023 All Rights Reserved
27+
* (c) Copyright IBM Corp. 2018, 2024 All Rights Reserved
2828
* ===========================================================================
2929
*/
3030

@@ -340,7 +340,10 @@ void putEntries() {
340340
attrs.clear();
341341
attrs.put("SupportedKeyFormats", "RAW");
342342

343-
if (useNativeChaCha20Cipher && (NativeCrypto.getVersionIfAvailable() >= NativeCrypto.OPENSSL_VERSION_1_1_0)) {
343+
if (useNativeChaCha20Cipher
344+
&& NativeCrypto.isAlgorithmAvailable("ChaCha20")
345+
&& (NativeCrypto.getVersionIfAvailable() >= NativeCrypto.OPENSSL_VERSION_1_1_0)
346+
) {
344347
ps("Cipher", "ChaCha20",
345348
"com.sun.crypto.provider.NativeChaCha20Cipher$ChaCha20Only",
346349
null, attrs);

src/java.base/share/classes/sun/security/provider/SunEntries.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,7 @@ public final class SunEntries {
330330
*/
331331
/* Don't use native MD5 on AIX due to an observed performance regression. */
332332
if (useNativeMD5
333-
&& NativeCrypto.isAllowedAndLoaded()
334-
&& NativeCrypto.isMD5Available()
333+
&& NativeCrypto.isAlgorithmAvailable("MD5")
335334
&& !OperatingSystem.isAix()
336335
) {
337336
providerMD5 = "sun.security.provider.NativeMD5";

0 commit comments

Comments
 (0)