Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIPS Support for Linux x86 RHEL #601

Merged
merged 1 commit into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* ===========================================================================
* (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
* ===========================================================================
*
* 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.
*
* IBM designates this particular file as subject to the "Classpath" exception
* as provided by IBM in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, see <http://www.gnu.org/licenses/>.
*
* ===========================================================================
*/

package openj9.internal.security;

import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Properties;
import java.security.AccessController;
import java.security.PrivilegedAction;

import sun.security.util.Debug;

/**
* Configures the security providers when in FIPS mode.
*/
public final class FIPSConfigurator {

private static final Debug debug = Debug.getInstance("semerufips");

// FIPS mode enable check, only supported on Linux x64.
private static final boolean userEnabledFIPS;
private static final boolean isFIPSSupported;
private static final boolean shouldEnableFIPS;

static {
String[] props = AccessController.doPrivileged(
new PrivilegedAction<String[]>() {
@Override
public String[] run() {
return new String[] {System.getProperty("semeru.fips"),
System.getProperty("os.name"),
System.getProperty("os.arch")};
}
});
userEnabledFIPS = Boolean.parseBoolean(props[0]);
isFIPSSupported = "Linux".equalsIgnoreCase(props[1])
&& "amd64".equalsIgnoreCase(props[2]);
shouldEnableFIPS = userEnabledFIPS && isFIPSSupported;
}

private FIPSConfigurator() {
super();
}

/**
* FIPS mode will be enabled only if the semeru.fips system
* property is true (default as false).
*
* @return true if FIPS is enabled
*/
public static boolean enableFIPS() {
return shouldEnableFIPS;
}

/**
* Remove the security providers and only add the FIPS security providers.
*
* @param props the java.security properties
* @return true if the FIPS properties loaded successfully
*/
public static boolean configureFIPS(Properties props) {
boolean loadedProps = false;

// Check if FIPS is supported on this platform.
if (userEnabledFIPS && !isFIPSSupported) {
throw new RuntimeException("FIPS is not supported on this platform.");
}

try {
if (shouldEnableFIPS) {
if (debug != null) {
debug.println("FIPS mode detected, loading properties");
}

// Remove all security providers.
Iterator<Entry<Object, Object>> i = props.entrySet().iterator();
while (i.hasNext()) {
Entry<Object, Object> e = i.next();
if (((String) e.getKey()).startsWith("security.provider")) {
if (debug != null) {
debug.println("Removing provider: " + e);
}
i.remove();
}
}

// Add FIPS security providers.
props.put("security.provider.1", "sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/nss.fips.cfg");
props.put("security.provider.2", "sun.security.provider.Sun");
props.put("security.provider.3", "sun.security.ec.SunEC");
props.put("security.provider.4", "com.sun.net.ssl.internal.ssl.Provider");
keithc-ca marked this conversation as resolved.
Show resolved Hide resolved

// Add FIPS security properties.
props.put("keystore.type", "PKCS11");
System.setProperty("javax.net.ssl.keyStore", "NONE");

// Add FIPS disabled algorithms.
String disabledAlgorithms = props.get("jdk.tls.disabledAlgorithms")
+ ", X25519, X448"
+ ", SSLv3, TLSv1, TLSv1.1"
+ ", TLS_CHACHA20_POLY1305_SHA256"
+ ", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"
+ ", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"
+ ", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"
+ ", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"
+ ", TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA"
+ ", TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA"
+ ", TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_GCM_SHA256"
+ ", TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256"
+ ", TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA"
+ ", TLS_AES_256_GCM_SHA384, TLS_AES_128_GCM_SHA256"
+ ", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
+ ", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
+ ", TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"
+ ", TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"
+ ", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
+ ", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
+ ", TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
+ ", TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
props.put("jdk.tls.disabledAlgorithms", disabledAlgorithms);

if (debug != null) {
debug.println("FIPS mode properties loaded");
debug.println(props.toString());
}

loadedProps = true;
}
} catch (Exception e) {
if (debug != null) {
debug.println("Unable to load FIPS configuration");
e.printStackTrace();
}
}
return loadedProps;
}
}
25 changes: 25 additions & 0 deletions closed/adds/jdk/src/share/lib/security/nss.fips.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# ===========================================================================
# (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
# ===========================================================================
# 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.
#
# IBM designates this particular file as subject to the "Classpath" exception
# as provided by IBM in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, see <http://www.gnu.org/licenses/>.
# ===========================================================================

name = NSS-FIPS
nssLibraryDirectory = /usr/lib64
nssSecmodDirectory = /etc/pki/nssdb
nssDbMode = readOnly
nssModule = fips
14 changes: 13 additions & 1 deletion closed/make/CopyFiles.gmk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ===========================================================================
# (c) Copyright IBM Corp. 2017, 2020 All Rights Reserved
# (c) Copyright IBM Corp. 2017, 2022 All Rights Reserved
# ===========================================================================
#
# This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -30,3 +30,15 @@ $(JDK_OUTPUTDIR)/include/ibmjvmti.h: $(SRC_ROOT)/openj9/runtime/include/ibmjvmti
$(call install-file)

COPY_FILES += $(JDK_OUTPUTDIR)/include/ibmjvmti.h

# Copy the nss.fips.cfg only on x86 linux

ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), linux-x86)
NSS_FIPS_CFG_SRC := $(TOPDIR)/closed/adds/jdk/src/share/lib/security/nss.fips.cfg
NSS_FIPS_CFG_DST := $(JDK_OUTPUTDIR)/lib/security/nss.fips.cfg

$(NSS_FIPS_CFG_DST) : $(NSS_FIPS_CFG_SRC)
$(call install-file)

COPY_FILES += $(NSS_FIPS_CFG_DST)
endif
26 changes: 25 additions & 1 deletion jdk/src/share/classes/java/security/SecureRandom.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
* questions.
*/

/*
* ===========================================================================
* (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
* ===========================================================================
*/

package java.security;

import java.util.*;
Expand All @@ -34,6 +40,8 @@
import sun.security.jca.GetInstance.Instance;
import sun.security.util.Debug;

import openj9.internal.security.FIPSConfigurator;

/**
* This class provides a cryptographically strong random number
* generator (RNG).
Expand Down Expand Up @@ -191,7 +199,23 @@ public SecureRandom(byte seed[]) {
}

private void getDefaultPRNG(boolean setSeed, byte[] seed) {
String prng = getPrngAlgorithm();
String prng;

// If in FIPS mode, use the SecureRandom from the FIPS provider.
if (FIPSConfigurator.enableFIPS()) {
Provider p = Security.getProvider("SunPKCS11-NSS-FIPS");
prng = "PKCS11";
if (p == null) {
throw new RuntimeException("could not find SunPKCS11-NSS-FIPS provider for FIPS mode");
}
Service prngService = p.getService("SecureRandom", prng);
if (prngService == null) {
throw new RuntimeException("could not find SecureRandom implementation from SunPKCS11-NSS-FIPS");
}
} else {
prng = getPrngAlgorithm();
}

if (prng == null) {
// bummer, get the SUN implementation
prng = "SHA1PRNG";
Expand Down
19 changes: 19 additions & 0 deletions jdk/src/share/classes/java/security/Security.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
* questions.
*/

/*
* ===========================================================================
* (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
* ===========================================================================
*/

package java.security;

import java.lang.reflect.*;
Expand All @@ -35,6 +41,8 @@

import sun.security.jca.*;

import openj9.internal.security.FIPSConfigurator;

/**
* <p>This class centralizes all security properties and common security
* methods. One of its primary uses is to manage providers.
Expand Down Expand Up @@ -187,6 +195,17 @@ private static void initialize() {
}
}

// Load FIPS properties
if (loadedProps) {
boolean fipsEnabled = FIPSConfigurator.configureFIPS(props);
if (sdebug != null) {
if (fipsEnabled) {
sdebug.println("FIPS mode enabled.");
} else {
sdebug.println("FIPS mode disabled.");
}
}
}
}

/*
Expand Down
Loading