8202608: CommonSeeder test needs a white-box testing mechanism to replace the default entropy source
Reviewed-by: xuelei
--- a/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java Mon Jun 25 18:49:30 2018 -0700
+++ b/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java Tue Jun 26 10:43:43 2018 +0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -516,7 +516,7 @@
* This object uses {@link SeedGenerator#generateSeed(byte[])} to
* return a byte array containing {@code minLength} bytes. It is
* assumed to support prediction resistance and always contains
- * full-entropy. A trusted application can update this field.
+ * full-entropy.
*/
private final static EntropySource defaultES =
(minE, minLen, maxLen, pr) -> {
--- a/test/jdk/sun/security/provider/SecureRandom/CommonSeeder.java Mon Jun 25 18:49:30 2018 -0700
+++ b/test/jdk/sun/security/provider/SecureRandom/CommonSeeder.java Tue Jun 26 10:43:43 2018 +0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,70 +21,39 @@
* questions.
*/
-import sun.security.provider.AbstractDrbg;
-import sun.security.provider.EntropySource;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
import java.security.DrbgParameters;
import java.security.SecureRandom;
import java.security.Security;
+import sun.security.provider.SeedGenerator;
/**
* @test
- * @bug 8051408
- * @modules java.base/java.lang.reflect:open
- * java.base/sun.security.provider:+open
+ * @bug 8051408 8202608
+ * @modules java.base/sun.security.provider
+ * @build java.base/sun.security.provider.SeedGenerator
* @run main/othervm CommonSeeder
* @summary check entropy reading of DRBGs
*/
public class CommonSeeder {
- static class MyES implements EntropySource {
- int count = 100;
- int lastCount = 100;
-
- @Override
- public byte[] getEntropy(int minEntropy, int minLength,
- int maxLength, boolean pr) {
- count--;
- return new byte[minLength];
- }
-
- /**
- * Confirms genEntropy() has been called {@code less} times
- * since last check.
- */
- public void checkUsage(int less) throws Exception {
- if (lastCount != count + less) {
- throw new Exception(String.format(
- "lastCount = %d, count = %d, less = %d",
- lastCount, count, less));
- }
- lastCount = count;
- }
- }
-
public static void main(String[] args) throws Exception {
byte[] result = new byte[10];
- MyES es = new MyES();
- // Set es as the default entropy source, overriding SeedGenerator.
- setDefaultSeeder(es);
+ // Use patched SeedGenerator in java.base/sun/security/provider/.
// Nothing happened yet
- es.checkUsage(0);
+ SeedGenerator.checkUsage(0);
SecureRandom sr;
sr = SecureRandom.getInstance("DRBG");
// No entropy reading if only getInstance
- es.checkUsage(0);
+ SeedGenerator.checkUsage(0);
// Entropy is read at 1st nextBytes of the 1st DRBG
sr.nextInt();
- es.checkUsage(1);
+ SeedGenerator.checkUsage(1);
for (String mech : new String[]{"Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) {
System.out.println("Testing " + mech + "...");
@@ -96,7 +65,7 @@
sr = SecureRandom.getInstance("DRBG");
sr.nextInt();
sr.reseed();
- es.checkUsage(0);
+ SeedGenerator.checkUsage(0);
// DRBG with pr_true always read from default entropy, and
// its nextBytes always reseed itself
@@ -106,28 +75,19 @@
sr = SecureRandom.getInstance("DRBG");
sr.nextInt();
- es.checkUsage(2); // one instantiate, one reseed
+ SeedGenerator.checkUsage(2); // one instantiate, one reseed
sr.nextInt();
- es.checkUsage(1); // one reseed in nextBytes
+ SeedGenerator.checkUsage(1); // one reseed in nextBytes
sr.reseed();
- es.checkUsage(1); // one reseed
+ SeedGenerator.checkUsage(1); // one reseed
sr.nextBytes(result, DrbgParameters.nextBytes(-1, false, null));
- es.checkUsage(0); // pr_false for this call
+ SeedGenerator.checkUsage(0); // pr_false for this call
sr.nextBytes(result, DrbgParameters.nextBytes(-1, true, null));
- es.checkUsage(1); // pr_true for this call
+ SeedGenerator.checkUsage(1); // pr_true for this call
sr.reseed(DrbgParameters.reseed(true, null));
- es.checkUsage(1); // reseed from es
+ SeedGenerator.checkUsage(1); // reseed from es
sr.reseed(DrbgParameters.reseed(false, null));
- es.checkUsage(0); // reseed from AbstractDrbg.SeederHolder.seeder
+ SeedGenerator.checkUsage(0); // reseed from AbstractDrbg.SeederHolder.seeder
}
}
-
- static void setDefaultSeeder(EntropySource es) throws Exception {
- Field f = AbstractDrbg.class.getDeclaredField("defaultES");
- f.setAccessible(true); // no more private
- Field f2 = Field.class.getDeclaredField("modifiers");
- f2.setAccessible(true);
- f2.setInt(f, f2.getInt(f) - Modifier.FINAL); // no more final
- f.set(null, es);
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/provider/SecureRandom/java.base/sun/security/provider/SeedGenerator.java Tue Jun 26 10:43:43 2018 +0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * 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.
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This is not the real sun.security.provider.SeedGenerator class. Used by
+// ../../../../CommonSeeder.java only.
+package sun.security.provider;
+
+public class SeedGenerator {
+
+ static int count = 100;
+ static int lastCount = 100;
+
+ public static void generateSeed(byte[] result) {
+ count--;
+ }
+
+ /**
+ * Confirms genEntropy() has been called {@code less} times
+ * since last check.
+ */
+ public static void checkUsage(int less) throws Exception {
+ if (lastCount != count + less) {
+ throw new Exception(String.format(
+ "lastCount = %d, count = %d, less = %d",
+ lastCount, count, less));
+ }
+ lastCount = count;
+ }
+
+ // Needed by AbstractDrbg.java
+ static byte[] getSystemEntropy() {
+ return new byte[20];
+ }
+}