# HG changeset patch # User weijun # Date 1529981023 -28800 # Node ID 11e7eb8cb5831741afc7cb70cc0db20b2b0125d0 # Parent cf0898a6441ec191974edb702b3121cea50a68e8 8202608: CommonSeeder test needs a white-box testing mechanism to replace the default entropy source Reviewed-by: xuelei diff -r cf0898a6441e -r 11e7eb8cb583 src/java.base/share/classes/sun/security/provider/AbstractDrbg.java --- 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) -> { diff -r cf0898a6441e -r 11e7eb8cb583 test/jdk/sun/security/provider/SecureRandom/CommonSeeder.java --- 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); - } } diff -r cf0898a6441e -r 11e7eb8cb583 test/jdk/sun/security/provider/SecureRandom/java.base/sun/security/provider/SeedGenerator.java --- /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]; + } +}