Skip to content

Commit 203ebbe

Browse files
Support SecureRandom strong algorithms in FIPS mode
This change overrides the default securerandom.strongAlgorithms configuration used by SecureRandom.getInstanceStrong() when it runs in FIPS mode. Signed-off-by: Mohit Rajbhar <mohit.rajbhar@ibm.com>
1 parent 80066e7 commit 203ebbe

4 files changed

Lines changed: 252 additions & 2 deletions

File tree

closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,7 @@ private static void setProperties(Properties props) {
613613
propsMapping.put("jdk.tls.legacyAlgorithms", restricts.jdkTlsLegacyAlgorithms);
614614
propsMapping.put("jdk.certpath.disabledAlgorithms", restricts.jdkCertpathDisabledAlgorithms);
615615
propsMapping.put("jdk.security.legacyAlgorithms", restricts.jdkSecurityLegacyAlgorithms);
616+
propsMapping.put("securerandom.strongAlgorithms", restricts.jdkSecureRandomStrongAlgorithms);
616617

617618
if (restricts.descIsFIPS) {
618619
if (restricts.jdkFipsMode == null) {
@@ -808,6 +809,7 @@ private static final class RestrictedSecurityProperties {
808809
// For SecureRandom.
809810
final String jdkSecureRandomProvider;
810811
final String jdkSecureRandomAlgorithm;
812+
final String jdkSecureRandomStrongAlgorithms;
811813

812814
final String jdkFipsMode;
813815

@@ -842,6 +844,7 @@ private RestrictedSecurityProperties(String profileID, ProfileParser parser) {
842844
// For SecureRandom.
843845
this.jdkSecureRandomProvider = parser.getProperty("jdkSecureRandomProvider");
844846
this.jdkSecureRandomAlgorithm = parser.getProperty("jdkSecureRandomAlgorithm");
847+
this.jdkSecureRandomStrongAlgorithms = parser.getProperty("jdkSecureRandomStrongAlgorithms");
845848

846849
this.jdkFipsMode = parser.getProperty("jdkFipsMode");
847850

@@ -1136,6 +1139,7 @@ private void listUsedProfile() {
11361139
printProperty(profileID + ".javax.net.ssl.keyStore: ", keyStore);
11371140
printProperty(profileID + ".securerandom.provider: ", jdkSecureRandomProvider);
11381141
printProperty(profileID + ".securerandom.algorithm: ", jdkSecureRandomAlgorithm);
1142+
printProperty(profileID + ".securerandom.strongAlgorithms: ", jdkSecureRandomStrongAlgorithms);
11391143
System.out.println();
11401144
}
11411145

@@ -1539,6 +1543,9 @@ private String getExistingValue(String property) {
15391543
case "jdkTlsLegacyAlgorithms":
15401544
propertyKey = "jdk.tls.legacyAlgorithms";
15411545
break;
1546+
case "jdkSecureRandomStrongAlgorithms":
1547+
propertyKey = "securerandom.strongAlgorithms";
1548+
break;
15421549
default:
15431550
return null;
15441551
}
@@ -1592,6 +1599,8 @@ private void loadProperties(String profileID, List<String> allInfo) {
15921599
profileID + ".securerandom.provider", allInfo);
15931600
setProperty("jdkSecureRandomAlgorithm",
15941601
profileID + ".securerandom.algorithm", allInfo);
1602+
setProperty("jdkSecureRandomStrongAlgorithms",
1603+
profileID + ".securerandom.strongAlgorithms", allInfo);
15951604
setProperty("jdkFipsMode",
15961605
profileID + ".fips.mode", allInfo);
15971606

@@ -1937,6 +1946,7 @@ private static boolean isPropertyAppendable(String property) {
19371946
case "jdkTlsDisabledAlgorithms":
19381947
case "jdkTlsDisabledNamedCurves":
19391948
case "jdkTlsLegacyAlgorithms":
1949+
case "jdkSecureRandomStrongAlgorithms":
19401950
return true;
19411951
default:
19421952
return false;

closed/test/jdk/openj9/internal/security/TestProperties.java

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* ===========================================================================
3-
* (c) Copyright IBM Corp. 2024, 2025 All Rights Reserved
3+
* (c) Copyright IBM Corp. 2024, 2026 All Rights Reserved
44
* ===========================================================================
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -202,6 +202,71 @@ private static Stream<Arguments> patternMatches_propertiesList() {
202202
return tests.build();
203203
}
204204

205+
private static Stream<Arguments> patternMatches_strongAlgorithms() {
206+
Stream.Builder<Arguments> tests = Stream.builder();
207+
208+
if (isProviderPresent("OpenJCEPlusFIPS")) {
209+
// 1 - Test property - base profile with securerandom.strongAlgorithms loads successfully.
210+
tests.add(Arguments.of("Test-Profile-strongAlgorithms",
211+
System.getProperty("test.src") + "/property-java.security",
212+
"(?s)(?=.*OpenJCEPlusFIPS)(?=.*SUN)(?=.*SunJSSE)",
213+
0));
214+
// 2 - Test property - securerandom.strongAlgorithms property with multiple algorithms.
215+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-MultipleEntries",
216+
System.getProperty("test.src") + "/property-java.security",
217+
"securerandom\\.strongAlgorithms: SHA512DRBG:OpenJCEPlusFIPS, SHA256DRBG:OpenJCEPlusFIPS",
218+
0));
219+
// 3 - Test property - securerandom.strongAlgorithms append algorithm in extended profile.
220+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-Extension_1",
221+
System.getProperty("test.src") + "/property-java.security",
222+
"securerandom\\.strongAlgorithms: SHA512DRBG:OpenJCEPlusFIPS, SHA256DRBG:OpenJCEPlusFIPS",
223+
0));
224+
// 4 - Test property - securerandom.strongAlgorithms remove algorithm in extended profile.
225+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-Extension_2",
226+
System.getProperty("test.src") + "/property-java.security",
227+
"securerandom\\.strongAlgorithms: (?=.*NativePRNGBlocking:SUN)(?=.*DRBG:SUN)",
228+
0));
229+
// 5 - Test property - securerandom.strongAlgorithms invalid algorithm.
230+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-InvalidFormat",
231+
System.getProperty("test.src") + "/property-java.security",
232+
"FAILED: No strong SecureRandom impls available: .*",
233+
0));
234+
// 6 - Test property - securerandom.strongAlgorithms missing algorithm.
235+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-MissingAlgo",
236+
System.getProperty("test.src") + "/property-java.security",
237+
"FAILED: No strong SecureRandom impls available: .*",
238+
0));
239+
// 7 - Test property - securerandom.strongAlgorithms missing provider.
240+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-MissingProvider",
241+
System.getProperty("test.src") + "/property-java.security",
242+
"FAILED: missing provider",
243+
0));
244+
// 8 - Test property - set invalid provider.
245+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-InvalidProvider",
246+
System.getProperty("test.src") + "/property-java.security",
247+
"FAILED: No strong SecureRandom impls available: .*",
248+
0));
249+
// 9 - Test property - securerandom.strongAlgorithms when only algorithm is present.
250+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-Specify-Algo-Only",
251+
System.getProperty("test.src") + "/property-java.security",
252+
"securerandom\\.strongAlgorithms: SHA(256|512)DRBG$",
253+
0));
254+
// 10 - Test property - invalid algorithm.
255+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-InvalidAlgorithm",
256+
System.getProperty("test.src") + "/property-java.security",
257+
"FAILED: No strong SecureRandom impls available: .*",
258+
0));
259+
// 11 - Test property - securerandom.strongAlgorithms misspelled property name.
260+
tests.add(Arguments.of("Test-Profile-strongAlgorithms-MisspelledPropertyName",
261+
System.getProperty("test.src") + "/property-java.security",
262+
"The property names: RestrictedSecurity.Test-Profile-strongAlgorithms-MisspelledPropertyName.securerandom.strongAlgorithmsWrong "
263+
+ "in profile RestrictedSecurity.Test-Profile-strongAlgorithms-MisspelledPropertyName \\(or a base profile\\) are not recognized",
264+
1));
265+
}
266+
267+
return tests.build();
268+
}
269+
205270
@ParameterizedTest
206271
@MethodSource("patternMatches_expectedExitValue0")
207272
public void shouldContain_expectedExitValue0(String customprofile, String securityPropertyFile, String expected) throws Exception {
@@ -241,6 +306,19 @@ public void shouldContain_propertiesList(String customprofile, String securityPr
241306
outputAnalyzer.shouldHaveExitValue(exitValue).shouldMatch(expected);
242307
}
243308

309+
@ParameterizedTest
310+
@MethodSource("patternMatches_strongAlgorithms")
311+
public void shouldContain_strongAlgorithms(String customprofile, String securityPropertyFile, String expected, int exitValue) throws Exception {
312+
OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava(
313+
"-Dsemeru.fips=true",
314+
"-Dsemeru.customprofile=" + customprofile,
315+
"-Djava.security.properties=" + securityPropertyFile,
316+
"TestProperties"
317+
);
318+
outputAnalyzer.reportDiagnosticSummary();
319+
outputAnalyzer.shouldHaveExitValue(exitValue).shouldMatch(expected);
320+
}
321+
244322
private static boolean isProviderPresent(String providerName) {
245323
for (Provider provider : Security.getProviders()) {
246324
if (provider.getName().equalsIgnoreCase(providerName)) {
@@ -250,13 +328,28 @@ private static boolean isProviderPresent(String providerName) {
250328
return false;
251329
}
252330

331+
private static void testStrongAlgorithms() {
332+
if (isProviderPresent("OpenJCEPlusFIPS")) {
333+
String strongAlgorithms = Security.getProperty("securerandom.strongAlgorithms");
334+
if ((strongAlgorithms != null) && !strongAlgorithms.isEmpty()) {
335+
try {
336+
java.security.SecureRandom.getInstanceStrong();
337+
System.out.println("securerandom.strongAlgorithms: " + strongAlgorithms);
338+
} catch (java.security.NoSuchAlgorithmException | IllegalArgumentException e) {
339+
System.out.println("FAILED: " + e.getMessage());
340+
}
341+
}
342+
}
343+
}
344+
253345
public static void main(String[] args) {
254346
// Something to trigger "properties" debug output.
255347
try {
256348
for (Provider provider : Security.getProviders()) {
257349
System.out.println("Provider Name: " + provider.getName());
258350
System.out.println("Provider Version: " + provider.getVersionStr());
259351
}
352+
testStrongAlgorithms();
260353
} catch (Exception e) {
261354
System.out.println(e);
262355
}

0 commit comments

Comments
 (0)