Skip to content

Commit 1c1995a

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 4448d7a commit 1c1995a

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

@@ -1542,6 +1546,9 @@ private String getExistingValue(String property) {
15421546
case "jdkTlsLegacyAlgorithms":
15431547
propertyKey = "jdk.tls.legacyAlgorithms";
15441548
break;
1549+
case "jdkSecureRandomStrongAlgorithms":
1550+
propertyKey = "securerandom.strongAlgorithms";
1551+
break;
15451552
default:
15461553
return null;
15471554
}
@@ -1595,6 +1602,8 @@ private void loadProperties(String profileID, List<String> allInfo) {
15951602
profileID + ".securerandom.provider", allInfo);
15961603
setProperty("jdkSecureRandomAlgorithm",
15971604
profileID + ".securerandom.algorithm", allInfo);
1605+
setProperty("jdkSecureRandomStrongAlgorithms",
1606+
profileID + ".securerandom.strongAlgorithms", allInfo);
15981607
setProperty("jdkFipsMode",
15991608
profileID + ".fips.mode", allInfo);
16001609

@@ -1941,6 +1950,7 @@ private static boolean isPropertyAppendable(String property) {
19411950
case "jdkTlsDisabledAlgorithms":
19421951
case "jdkTlsDisabledNamedCurves":
19431952
case "jdkTlsLegacyAlgorithms":
1953+
case "jdkSecureRandomStrongAlgorithms":
19441954
return true;
19451955
default:
19461956
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)