OpenJDK / jdk / jdk
changeset 38423:5d6ff7d76bf4
8141039: Test Task: Develop new tests for JEP 273: DRBG-Based SecureRandom Implementations
Reviewed-by: weijun
author | ssahoo |
---|---|
date | Thu, 19 May 2016 04:20:08 -0700 |
parents | 638589997770 |
children | abb80b35c9dd |
files | jdk/test/java/security/SecureRandom/ApiTest.java jdk/test/java/security/SecureRandom/EnoughSeedTest.java jdk/test/java/security/SecureRandom/GetAlgorithm.java jdk/test/java/security/SecureRandom/GetInstanceTest.java jdk/test/java/security/SecureRandom/MultiThreadTest.java jdk/test/java/security/SecureRandom/SerializedSeedTest.java jdk/test/sun/security/provider/SecureRandom/StrongSecureRandom.java jdk/test/sun/security/provider/SeedGenerator/SeedGeneratorChoice.java |
diffstat | 8 files changed, 1297 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/SecureRandom/ApiTest.java Thu May 19 04:20:08 2016 -0700 @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2016, 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. + */ + +/* + * @test + * @bug 8141039 + * @library /lib/testlibrary + * @summary This test do API coverage for SecureRandom. It covers most of + * supported operations along with possible positive and negative + * parameters for DRBG mechanism. + * @run main ApiTest Hash_DRBG + * @run main ApiTest HMAC_DRBG + * @run main ApiTest CTR_DRBG + * @run main ApiTest SHA1PRNG + * @run main ApiTest NATIVE + */ +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.SecureRandomParameters; +import java.security.DrbgParameters; +import java.security.DrbgParameters.Instantiation; +import java.security.DrbgParameters.Capability; +import javax.crypto.Cipher; + +public class ApiTest { + + private static final boolean SHOULD_PASS = true; + private static final long SEED = 1l; + private static final String INVALID_ALGO = "INVALID"; + private static final String DRBG_CONFIG = "securerandom.drbg.config"; + private static final String DRBG_CONFIG_VALUE + = Security.getProperty(DRBG_CONFIG); + + public static void main(String[] args) throws Exception { + + if (args == null || args.length < 1) { + throw new RuntimeException("No mechanism available to run test."); + } + String mech + = "NATIVE".equals(args[0]) ? supportedNativeAlgo() : args[0]; + String[] algs = null; + boolean success = true; + + try { + if (!isDRBG(mech)) { + SecureRandom random = SecureRandom.getInstance(mech); + verifyAPI(random, mech); + return; + } else if (mech.equals("CTR_DRBG")) { + algs = new String[]{"AES-128", "AES-192", "AES-256", + INVALID_ALGO}; + } else if (mech.equals("Hash_DRBG") || mech.equals("HMAC_DRBG")) { + algs = new String[]{"SHA-224", "SHA-256", "SHA-512/224", + "SHA-512/256", "SHA-384", "SHA-512", INVALID_ALGO}; + } else { + throw new RuntimeException( + String.format("Not a valid mechanism '%s'", mech)); + } + runForEachMech(mech, algs); + } catch (Exception e) { + e.printStackTrace(System.out); + success = false; + } + + if (!success) { + throw new RuntimeException("At least one test failed."); + } + } + + /** + * Run the test for a DRBG mechanism with a possible set of parameter + * combination. + * @param mech DRBG mechanism name + * @param algs Algorithm supported by each mechanism + * @throws Exception + */ + private static void runForEachMech(String mech, String[] algs) + throws Exception { + for (String alg : algs) { + runForEachAlg(mech, alg); + } + } + + private static void runForEachAlg(String mech, String alg) + throws Exception { + for (int strength : new int[]{Integer.MIN_VALUE, -1, 0, 1, 223, 224, + 192, 255, 256}) { + for (Capability cp : Capability.values()) { + for (byte[] pr : new byte[][]{null, new byte[]{}, + "personal".getBytes()}) { + SecureRandomParameters param + = DrbgParameters.instantiation(strength, cp, pr); + runForEachParam(mech, alg, param); + } + } + } + } + + private static void runForEachParam(String mech, String alg, + SecureRandomParameters param) throws Exception { + + for (boolean df : new Boolean[]{true, false}) { + try { + Security.setProperty(DRBG_CONFIG, mech + "," + alg + "," + + (df ? "use_df" : "no_df")); + System.out.printf("%nParameter for SecureRandom " + + "mechanism: %s is (param:%s, algo:%s, df:%s)", + mech, param, alg, df); + SecureRandom sr = SecureRandom.getInstance("DRBG", param); + verifyAPI(sr, mech); + } catch (NoSuchAlgorithmException e) { + // Verify exception status for current test. + checkException(getDefaultAlg(mech, alg), param, e); + } finally { + Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE); + } + } + } + + /** + * Returns the algorithm supported for input mechanism. + * @param mech Mechanism name + * @param alg Algorithm name + * @return Algorithm name + */ + private static String getDefaultAlg(String mech, String alg) + throws NoSuchAlgorithmException { + if (alg == null) { + switch (mech) { + case "Hash_DRBG": + case "HMAC_DRBG": + return "SHA-256"; + case "CTR_DRBG": + return (Cipher.getMaxAllowedKeyLength("AES") < 256) + ? "AES-128" : "AES-256"; + default: + throw new RuntimeException("Mechanism not supported"); + } + } + return alg; + } + + /** + * Verify the exception type either it is expected to occur or not. + * @param alg Algorithm name + * @param param DRBG parameter + * @param e Exception to verify + * @throws NoSuchAlgorithmException + */ + private static void checkException(String alg, SecureRandomParameters param, + NoSuchAlgorithmException e) throws NoSuchAlgorithmException { + + int strength = ((Instantiation) param).getStrength(); + boolean error = true; + switch (alg) { + case INVALID_ALGO: + error = false; + break; + case "SHA-224": + case "SHA-512/224": + if (strength > 192) { + error = false; + } + break; + case "SHA-256": + case "SHA-512/256": + case "SHA-384": + case "SHA-512": + if (strength > 256) { + error = false; + } + break; + case "AES-128": + case "AES-192": + case "AES-256": + int algoStrength = Integer.parseInt(alg.replaceAll("AES-", "")); + int maxStrengthSupported = Cipher.getMaxAllowedKeyLength("AES"); + if (strength > maxStrengthSupported + || algoStrength > maxStrengthSupported) { + error = false; + } + break; + } + if (error) { + throw new RuntimeException("Unknown :", e); + } + } + + /** + * Find if the mechanism is a DRBG mechanism. + * @param mech Mechanism name + * @return True for DRBG mechanism else False + */ + private static boolean isDRBG(String mech) { + return mech.contains("_DRBG"); + } + + /** + * Find the name of supported native mechanism name for current platform. + */ + private static String supportedNativeAlgo() { + String nativeSr = "Windows-PRNG"; + try { + SecureRandom.getInstance(nativeSr); + } catch (NoSuchAlgorithmException e) { + nativeSr = "NativePRNG"; + } + return nativeSr; + } + + /** + * Test a possible set of SecureRandom API for a SecureRandom instance. + * @param random SecureRandom instance + * @param mech Mechanism used to create SecureRandom instance + */ + private static void verifyAPI(SecureRandom random, String mech) + throws Exception { + + System.out.printf("%nTest SecureRandom mechanism: %s for provider: %s", + mech, random.getProvider().getName()); + byte[] output = new byte[2]; + + // Generate random number. + random.nextBytes(output); + + // Seed the SecureRandom with a generated seed value of lesser size. + byte[] seed = random.generateSeed(1); + random.setSeed(seed); + random.nextBytes(output); + + // Seed the SecureRandom with a fixed seed value. + random.setSeed(SEED); + random.nextBytes(output); + + // Seed the SecureRandom with a larger seed value. + seed = random.generateSeed(128); + random.setSeed(seed); + random.nextBytes(output); + + // Additional operation only supported for DRBG based SecureRandom. + // Execute the code block and expect to pass for DRBG. If it will fail + // then it should fail with specified exception type. Else the case + // will be considered as a test case failure. + matchExc(() -> { + random.reseed(); + random.nextBytes(output); + }, + isDRBG(mech), + UnsupportedOperationException.class, + String.format("PASS - Unsupported reseed() method for " + + "SecureRandom Algorithm %s ", mech)); + + matchExc(() -> { + random.reseed(DrbgParameters.reseed(false, new byte[]{})); + random.nextBytes(output); + }, + isDRBG(mech), + UnsupportedOperationException.class, + String.format("PASS - Unsupported reseed(param) method for " + + "SecureRandom Algorithm %s ", mech)); + + matchExc(() -> { + random.reseed(DrbgParameters.reseed(true, new byte[]{})); + random.nextBytes(output); + }, + isDRBG(mech), + !isSupportPR(mech, random) ? IllegalArgumentException.class + : UnsupportedOperationException.class, + String.format("PASS - Unsupported or illegal reseed(param) " + + "method for SecureRandom Algorithm %s ", mech)); + + matchExc(() -> random.nextBytes(output, + DrbgParameters.nextBytes(-1, false, new byte[]{})), + isDRBG(mech), + UnsupportedOperationException.class, + String.format("PASS - Unsupported nextBytes(out, nextByteParam)" + + " method for SecureRandom Algorithm %s ", mech)); + + matchExc(() -> random.nextBytes(output, + DrbgParameters.nextBytes(-1, true, new byte[]{})), + isDRBG(mech), + !isSupportPR(mech, random) ? IllegalArgumentException.class + : UnsupportedOperationException.class, + String.format("PASS - Unsupported or illegal " + + "nextBytes(out, nextByteParam) method for " + + "SecureRandom Algorithm %s ", mech)); + + matchExc(() -> { + random.reseed(null); + random.nextBytes(output); + }, + !SHOULD_PASS, + IllegalArgumentException.class, + "PASS - Test is expected to fail when parameter for reseed() " + + "is null"); + + matchExc(() -> random.nextBytes(output, null), + !SHOULD_PASS, + IllegalArgumentException.class, + "PASS - Test is expected to fail when parameter for nextBytes()" + + " is null"); + + } + + private static boolean isSupportPR(String mech, SecureRandom random) { + return (isDRBG(mech) && ((Instantiation) random.getParameters()) + .getCapability() + .supportsPredictionResistance()); + } + + private interface RunnableCode { + + void run() throws Exception; + } + + /** + * Execute a given code block and verify, if the exception type is expected. + * @param r Code block to run + * @param ex Expected exception type + * @param shouldPass If the code execution expected to pass without failure + * @param msg Message to log in case of expected failure + */ + private static void matchExc(RunnableCode r, boolean shouldPass, Class ex, + String msg) { + try { + r.run(); + if (!shouldPass) { + throw new RuntimeException("Excecution should fail here."); + } + } catch (Exception e) { + System.out.printf("%nOccured exception: %s - Expected exception: " + + "%s : ", e.getClass(), ex.getCanonicalName()); + if (ex.isAssignableFrom(e.getClass())) { + System.out.printf("%n%s : Expected Exception occured: %s : ", + e.getClass(), msg); + } else if (shouldPass) { + throw new RuntimeException(e); + } else { + System.out.printf("Ignore the following exception: %s%n", + e.getMessage()); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/SecureRandom/EnoughSeedTest.java Thu May 19 04:20:08 2016 -0700 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016, 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. + */ + +/* + * @test + * @bug 8141039 + * @library /lib/testlibrary + * @summary Check SecureRandom generate expected seed counts what the caller + * asked for. + * @run main EnoughSeedTest + */ +import java.security.SecureRandom; +import java.security.Security; +import static java.lang.Math.*; + +public class EnoughSeedTest { + + private static final String DRBG_CONFIG = "securerandom.drbg.config"; + private static final String DRBG_CONFIG_VALUE + = Security.getProperty(DRBG_CONFIG); + + public static void main(String[] args) { + + boolean success = true; + for (String mech : new String[]{ + "SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) { + System.out.printf("%nTest for SecureRandom algorithm: '%s'", mech); + try { + SecureRandom sr = null; + if (!mech.contains("_DRBG")) { + sr = SecureRandom.getInstance(mech); + } else { + Security.setProperty(DRBG_CONFIG, mech); + sr = SecureRandom.getInstance("DRBG"); + } + + success &= forEachSeedBytes(sr); + System.out.printf("%nCompleted test for SecureRandom " + + "mechanism: '%s'", mech); + } catch (Exception e) { + success &= false; + e.printStackTrace(System.out); + } finally { + Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE); + } + } + if (!success) { + throw new RuntimeException("At least one test failed."); + } + } + + /** + * Generates fixed number of seed bytes through a SecureRandom instance + * to verify it's seed generation status. + * @param sr SecureRandom instance + * @return The test success indicator + */ + private static boolean forEachSeedBytes(SecureRandom sr) { + boolean success = true; + sr.setSeed(1l); + for (int seedByte : new int[]{Integer.MIN_VALUE, -1, 0, 1, 256, 1024, + Short.MAX_VALUE, (int) pow(2, 20)}) { + try { + byte[] seed = sr.generateSeed(seedByte); + if (seed.length != seedByte) { + throw new RuntimeException("Not able to produce expected " + + "seed size."); + } + } catch (IllegalArgumentException e) { + if (seedByte >= 0) { + throw new RuntimeException("Unknown Exception occured.", e); + } + System.out.printf("%nPASS - Exception expected when required " + + "seed size requested is negative: %s", seedByte); + } + } + return success; + } + +}
--- a/jdk/test/java/security/SecureRandom/GetAlgorithm.java Thu May 19 11:13:52 2016 +0200 +++ b/jdk/test/java/security/SecureRandom/GetAlgorithm.java Thu May 19 04:20:08 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -23,49 +23,54 @@ /** * @test - * @bug 4915392 + * @bug 4915392 8141039 * @summary test that the getAlgorithm() method works correctly * @author Andreas Sterbenz + * @run main GetAlgorithm */ - import java.io.*; - import java.security.*; +import java.util.Arrays; +import java.util.List; public class GetAlgorithm { - private final static String BASE = System.getProperty("test.src", "."); + private static final String BASE = System.getProperty("test.src", "."); + private static final String DRBG_CONFIG = "securerandom.drbg.config"; + private static final String DRBG_CONFIG_VALUE + = Security.getProperty(DRBG_CONFIG); public static void main(String[] args) throws Exception { - SecureRandom sr; - - sr = new SecureRandom(); + SecureRandom sr = new SecureRandom(); if (sr.getAlgorithm().equals("unknown")) { throw new Exception("Unknown: " + sr.getAlgorithm()); } - sr = SecureRandom.getInstance("SHA1PRNG"); - check("SHA1PRNG", sr); + for (String mech : new String[]{supportedNativeAlgo(), "SHA1PRNG", + "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) { + if (!mech.contains("_DRBG")) { + check(mech, SecureRandom.getInstance(mech)); + } else { + try { + Security.setProperty(DRBG_CONFIG, mech); + check("DRBG", SecureRandom.getInstance("DRBG")); + } finally { + Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE); + } + } + } + check("unknown", new MySecureRandom()); -// OutputStream out = new FileOutputStream("sha1prng.bin"); -// ObjectOutputStream oout = new ObjectOutputStream(out); -// sr.nextInt(); -// oout.writeObject(sr); -// oout.flush(); -// oout.close(); - - sr = new MySecureRandom(); - check("unknown", sr); - - InputStream in = new FileInputStream(new File(BASE, "sha1prng-old.bin")); + InputStream in = new FileInputStream( + new File(BASE, "sha1prng-old.bin")); ObjectInputStream oin = new ObjectInputStream(in); - sr = (SecureRandom)oin.readObject(); + sr = (SecureRandom) oin.readObject(); oin.close(); check("unknown", sr); in = new FileInputStream(new File(BASE, "sha1prng-new.bin")); oin = new ObjectInputStream(in); - sr = (SecureRandom)oin.readObject(); + sr = (SecureRandom) oin.readObject(); oin.close(); check("SHA1PRNG", sr); @@ -83,4 +88,17 @@ } + /** + * Find the name of supported native mechanism name for current platform. + */ + private static String supportedNativeAlgo() { + String nativeSr = "Windows-PRNG"; + try { + SecureRandom.getInstance(nativeSr); + } catch (NoSuchAlgorithmException e) { + nativeSr = "NativePRNG"; + } + return nativeSr; + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/SecureRandom/GetInstanceTest.java Thu May 19 04:20:08 2016 -0700 @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2016, 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. + */ + +/* + * @test + * @bug 8141039 + * @library /lib/testlibrary + * @summary SecureRandom supports multiple getInstance method including + * getInstanceStrong() method. This test verifies a set of possible + * cases for getInstance with different SecureRandom mechanism + * supported in Java. + * @run main GetInstanceTest + */ +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.SecureRandomParameters; +import java.security.DrbgParameters; + +import static java.security.DrbgParameters.Capability.*; + +import java.security.Security; +import java.util.Arrays; + +import jdk.testlibrary.Asserts; + +public class GetInstanceTest { + + private static final boolean PASS = true; + private static final String INVALID_ALGO = "INVALID"; + private static final String SUN_PROVIDER = "SUN"; + private static final String INVALID_PROVIDER = "INVALID"; + private static final String STRONG_ALG_SEC_PROP + = "securerandom.strongAlgorithms"; + private static final String DRBG_CONFIG = "securerandom.drbg.config"; + private static final String DRBG_CONFIG_VALUE + = Security.getProperty(DRBG_CONFIG); + + public static void main(String[] args) throws Exception { + + boolean success = true; + // Only accepted failure is NoSuchAlgorithmException. + // For any other failure the test case will fail here. + SecureRandom sr = matchExc(() -> SecureRandom.getInstanceStrong(), + PASS, NoSuchAlgorithmException.class, + "PASS - Undefined security Property " + + "'securerandom.strongAlgorithms'"); + System.out.format("Current platform supports mechanism: '%s' through " + + "provider: '%s' for the method getInstanceStrong().", + sr.getAlgorithm(), sr.getProvider().getName()); + + // DRBG name should appear with "securerandom.strongAlgorithms" + // security property. + String origDRBGConfig = Security.getProperty(STRONG_ALG_SEC_PROP); + if (!origDRBGConfig.contains("DRBG")) { + throw new RuntimeException("DRBG is not associated with default " + + "strong algorithm through security Property: " + + "'securerandom.strongAlgorithms'."); + } + Security.setProperty(STRONG_ALG_SEC_PROP, "DRBG:SUN"); + sr = matchExc(() -> SecureRandom.getInstanceStrong(), + PASS, NoSuchAlgorithmException.class, + "PASS - Undefined security Property " + + "'securerandom.strongAlgorithms'"); + checkAttributes(sr, "DRBG"); + Security.setProperty(STRONG_ALG_SEC_PROP, origDRBGConfig); + + for (String mech : new String[]{ + "SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG", INVALID_ALGO,}) { + System.out.printf("%nTest SecureRandom mechanism: '%s'", mech); + try { + if (isDRBG(mech)) { + Security.setProperty(DRBG_CONFIG, mech); + } + verifyInstance(mech); + } catch (Exception e) { + e.printStackTrace(System.out); + success = false; + } finally { + Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE); + } + } + if (!success) { + throw new RuntimeException("At least one test failed."); + } + } + + private static void verifyInstance(String mech) throws Exception { + + String srAlgo = isDRBG(mech) ? "DRBG" : mech; + + // Test for getInstance(algorithm) method. + // It should pass for all case other than invalid algorithm name. + // If it fails then the expected exception type should be + // NoSuchAlgorithmException. Any other Exception type occured will be + // treated as failure. + checkAttributes( + matchExc(() -> SecureRandom.getInstance(srAlgo), !(nsa(mech)), + NoSuchAlgorithmException.class, + String.format("PASS - It is expected to fail for" + + " getInstance(algorithm) when algorithm: '%s'" + + " is null or invalid.", mech)), mech); + // Test for getInstance(algorithm, provider) method. + checkAttributes( + matchExc(() -> SecureRandom.getInstance(srAlgo, + Security.getProvider(SUN_PROVIDER)), + !(nsa(mech)), + NoSuchAlgorithmException.class, + String.format("PASS - It is expected to fail for" + + " getInstance(algorithm, provider) when" + + " algorithm:'%s' is null or invalid.", mech)), + mech); + // Test for getInstance(algorithm, providerName) method. + checkAttributes( + matchExc(() -> SecureRandom.getInstance(srAlgo, SUN_PROVIDER), + !(nsa(mech)), NoSuchAlgorithmException.class, + String.format("PASS - It is expected to fail for " + + "getInstance(algorithm, providerName) when " + + "algorithm: '%s' is null or invalid.", mech)), + mech); + // Test for getInstance(algorithm, providerName) method. + checkAttributes( + matchExc(() -> SecureRandom.getInstance( + srAlgo, INVALID_PROVIDER), + !PASS, NoSuchProviderException.class, + String.format("PASS - It is expected to fail for " + + "getInstance(algorithm, providerName) when " + + "provider name: '%s' is invalid and " + + "algorithm: '%s'", INVALID_PROVIDER, mech)), + mech); + + // Run the test for a set of SecureRandomParameters + for (SecureRandomParameters param : Arrays.asList(null, + DrbgParameters.instantiation(-1, NONE, null))) { + + System.out.printf("%nRunning DRBG param getInstance() methods " + + "for algorithm: %s and DRBG param type: %s", mech, + (param != null) ? param.getClass().getName() : param); + + // Following Test are applicable for new DRBG methods only. + // Test for getInstance(algorithm, params) method. + // Tests are expected to pass for DRBG type with valid parameter + // If it fails the expected exception type is derived from + // getExcType(mech, param) method. If exception type is not + // expected then the test will be considered as failure. + checkAttributes( + matchExc(() -> SecureRandom.getInstance(srAlgo, param), + (isDRBG(mech)) && (isValidDRBGParam(param)), + getExcType(mech, param), + String.format("PASS - It is expected to fail " + + "for getInstance(algorithm, params) " + + "for algorithm: %s and parameter: %s", + mech, param)), + mech); + // Test for getInstance(algorithm, params, provider) method. + checkAttributes( + matchExc(() -> SecureRandom.getInstance(srAlgo, param, + Security.getProvider(SUN_PROVIDER)), + (isDRBG(mech)) && (isValidDRBGParam(param)), + getExcType(mech, param), + String.format("PASS - It is expected to fail " + + "for getInstance(algorithm, params, " + + "provider) for algorithm: %s and " + + "parameter: %s", mech, param)), + mech); + // Test for getInstance(algorithm, params, providerName) method. + checkAttributes( + matchExc(() -> SecureRandom.getInstance(srAlgo, param, + SUN_PROVIDER), + (isDRBG(mech)) && (isValidDRBGParam(param)), + getExcType(mech, param), + String.format("PASS - It is expected to fail " + + "for getInstance(algorithm, params, " + + "providerName) for algorithm: %s and " + + "parameter: %s", mech, param)), mech); + // getInstance(algorithm, params, providerName) when + // providerName is invalid + checkAttributes( + matchExc(() -> SecureRandom.getInstance(srAlgo, param, + INVALID_PROVIDER), + !PASS, ((param == null) + ? IllegalArgumentException.class + : NoSuchProviderException.class), + String.format("PASS - It is expected to fail " + + "for getInstance(algorithm, params, " + + "providerName) when param is null or" + + " provider: %s is invalid for " + + "algorithm: '%s'", INVALID_PROVIDER, + mech)), mech); + // getInstance(algorithm, params, provider) when provider=null + checkAttributes( + matchExc(() -> SecureRandom.getInstance(srAlgo, param, + (String) null), + !PASS, IllegalArgumentException.class, + String.format("PASS - It is expected to fail " + + "for getInstance(algorithm, params, " + + "providerName) when provider name " + + "is null")), mech); + // getInstance(algorithm, params, providerName) when + // providerName is empty. + checkAttributes( + matchExc(() -> SecureRandom.getInstance( + srAlgo, param, ""), + !PASS, IllegalArgumentException.class, + String.format("PASS - It is expected to fail " + + "for getInstance(algorithm, params, " + + "providerName) when provider name " + + "is empty")), mech); + } + } + + private static boolean isValidDRBGParam(SecureRandomParameters param) { + return (param instanceof DrbgParameters.Instantiation); + } + + /** + * If the mechanism should occur NoSuchAlgorithmException. + */ + private static boolean nsa(String mech) { + return mech.equals(INVALID_ALGO); + } + + /** + * Verify if the mechanism is DRBG type. + * @param mech Mechanism name + * @return True if the mechanism name is DRBG type else False. + */ + private static boolean isDRBG(String mech) { + return mech.contains("_DRBG"); + } + + /** + * Type of exception expected for a SecureRandom instance when exception + * occurred while calling getInstance method with a fixed set of parameter. + * @param mech Mechanism used to create a SecureRandom instance + * @param param Parameter to getInstance() method + * @return Exception type expected + */ + private static Class getExcType(String mech, SecureRandomParameters param) { + return ((isDRBG(mech) && !isValidDRBGParam(param)) || param == null) + ? IllegalArgumentException.class + : NoSuchAlgorithmException.class; + } + + private interface RunnableCode { + + SecureRandom run() throws Exception; + } + + /** + * Execute a given code block and verify, if the exception type is expected. + * @param r Code block to run + * @param ex Expected exception type + * @param shouldPass If the code execution expected to pass without failure + * @param msg Message to log in case of expected failure + */ + private static SecureRandom matchExc(RunnableCode r, boolean shouldPass, + Class ex, String msg) { + SecureRandom sr = null; + try { + sr = r.run(); + if (!shouldPass) { + throw new RuntimeException("Excecution should fail here."); + } + } catch (Exception e) { + System.out.printf("%nOccured exception: %s - Expected exception: %s" + + " : ", e.getClass(), ex.getCanonicalName()); + if (ex.isAssignableFrom(e.getClass())) { + System.out.printf("%n%s : Expected Exception: %s : ", + e.getClass(), msg); + } else if (shouldPass) { + throw new RuntimeException(e); + } else { + System.out.printf("%nIgnore the following exception: %s%n", + e.getMessage()); + } + } + return sr; + } + + /** + * Check specific attributes of a SecureRandom instance. + */ + private static void checkAttributes(SecureRandom sr, String mech) { + if (sr == null) { + return; + } + Asserts.assertEquals(sr.getAlgorithm(), (isDRBG(mech) ? "DRBG" : mech)); + Asserts.assertEquals(sr.getProvider().getName(), SUN_PROVIDER); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/SecureRandom/MultiThreadTest.java Thu May 19 04:20:08 2016 -0700 @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2016, 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. + */ + +import java.math.BigInteger; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.Security; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import static java.lang.Math.*; + +/* + * @test + * @bug 8141039 + * @library /lib/testlibrary + * @summary Test behavior of a shared SecureRandom object when it is operated + * by multiple threads concurrently. + * @run main MultiThreadTest + */ +public class MultiThreadTest { + + private static final byte[] GEN_RND_BYTES = {1}; + private static final String DRBG_CONFIG = "securerandom.drbg.config"; + private static final String DRBG_CONFIG_VALUE + = Security.getProperty(DRBG_CONFIG); + + private enum SEED { + + NONE, RESEED, SETSEED + } + + public static void main(String[] args) { + + boolean success = true; + for (int byteLen : GEN_RND_BYTES) { + for (SEED reSeed : SEED.values()) { + for (String mech : new String[]{ + "SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) { + try { + forEachMech(mech, byteLen, reSeed); + } catch (Exception e) { + success = false; + e.printStackTrace(System.out); + } finally { + Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE); + } + } + } + } + + if (!success) { + throw new RuntimeException("At least one test failed."); + } + } + + /** + * Generate a number of threads to fetch random numbers of certain bits + * generated through a shared SecureRandom instance. + * @param mech Mechanism name + * @param byteLen Number of bytes of random number to produce + * @param reSeed Call reseed() before generating random numbers + * @throws NoSuchAlgorithmException + * @throws InterruptedException + * @throws ExecutionException + */ + private static void forEachMech(String mech, int byteLen, SEED reSeed) + throws NoSuchAlgorithmException, InterruptedException, + ExecutionException { + + if ("SHA1PRNG".equals(mech) && SEED.RESEED.equals(reSeed)) { + System.out.printf( + "%nreseed() api is not supported for '%s'", mech); + return; + } + System.out.printf("%nTest SecureRandom mechanism: '%s' with support of" + + " reseed: '%s'", mech, reSeed); + int threadCount = (int) pow(2, 8 * byteLen); + System.out.printf("%nCreating %s number of threads to generate secure " + + "random numbers concurrently.", threadCount); + + ExecutorService executor + = Executors.newCachedThreadPool(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread t = Executors.defaultThreadFactory() + .newThread(r); + t.setDaemon(true); + return t; + } + }); + CompletionService<Integer> completionService + = new ExecutorCompletionService<Integer>(executor); + + CountDownLatch latch = new CountDownLatch(1); + SecureRandom rnd = null; + if (!mech.contains("_DRBG")) { + rnd = SecureRandom.getInstance(mech); + } else { + Security.setProperty(DRBG_CONFIG, mech); + rnd = SecureRandom.getInstance("DRBG"); + } + try { + for (int i = 0; i < threadCount; i++) { + completionService.submit(new Task(rnd, latch, byteLen, reSeed)); + } + latch.countDown(); + + for (int i = 0; i < threadCount; i++) { + completionService.take(); + } + } finally { + executor.shutdown(); + } + System.out.printf("%nCompleted Test for algorithm '%s' with thread " + + "counts to '%s' using reseeding '%s'", + mech, threadCount, reSeed); + + } + + /** + * Define a Task to be executed by multiple thread to produce random numbers + * from a shared SecureRandom instance. + */ + private static class Task implements Callable<Integer> { + + private final SecureRandom random; + private final CountDownLatch latch; + private final SEED reSeed; + private final int byteSize; + + public Task(SecureRandom random, CountDownLatch latch, int byteSize, + SEED reSeed) { + this.random = random; + this.latch = latch; + this.byteSize = byteSize; + this.reSeed = reSeed; + } + + @Override + public Integer call() throws Exception { + latch.await(); + switch (this.reSeed) { + case RESEED: + this.random.reseed(); + break; + case SETSEED: + this.random.setSeed(1l); + break; + } + byte[] bytes = new byte[byteSize]; + random.nextBytes(bytes); + return new BigInteger(bytes).intValue(); + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/SecureRandom/SerializedSeedTest.java Thu May 19 04:20:08 2016 -0700 @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2016, 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. + */ + +/* + * @test + * @bug 8141039 + * @library /lib/testlibrary + * @summary When random number is generated through the a SecureRandom instance + * as well from it's serialized instance in the same time then the + * generated random numbers should be different when one or both are + * reseeded. + * @run main SerializedSeedTest + */ +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ByteArrayInputStream; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.Security; +import jdk.testlibrary.Asserts; + +public class SerializedSeedTest { + + private static final byte[] SEED = "seed".getBytes(); + private static final String DRBG_CONFIG = "securerandom.drbg.config"; + private static final String DRBG_CONFIG_VALUE + = Security.getProperty(DRBG_CONFIG); + + public static void main(String[] args) { + boolean success = true; + + for (String mech : new String[]{ + "SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) { + System.out.printf( + "%nRunning test for SecureRandom mechanism: '%s'", mech); + try { + // Serialize without seed and compare generated random numbers + // produced through original and serialized instances. + SecureRandom orig = getSRInstance(mech); + SecureRandom copy = deserializedCopy(orig); + System.out.printf("%nSerialize without seed. Generated random" + + " numbers should be different."); + check(orig, copy, false, mech); + + // Serialize after default seed and compare generated random + // numbers produced through original and serialized instances. + orig = getSRInstance(mech); + orig.nextInt(); // Default seeded + copy = deserializedCopy(orig); + System.out.printf("%nSerialize after default seed. Generated" + + " random numbers should be same till 20-bytes."); + check(orig, copy, !isDRBG(mech), mech); + + // Serialize after explicit seed and compare generated random + // numbers produced through original and serialized instances. + orig = getSRInstance(mech); + orig.setSeed(SEED); // Explicitly seeded + copy = deserializedCopy(orig); + System.out.printf("%nSerialize after explicit seed. Generated " + + "random numbers should be same till 20-bytes."); + check(orig, copy, !isDRBG(mech), mech); + + // Serialize without seed but original is explicitly seeded + // before generating any random number. Then compare generated + // random numbers produced through original and serialized + // instances. + orig = getSRInstance(mech); + copy = deserializedCopy(orig); + orig.setSeed(SEED); // Explicitly seeded + System.out.printf("%nSerialize without seed. When original is " + + "explicitly seeded before generating random numbers," + + " Generated random numbers should be different."); + check(orig, copy, false, mech); + + // Serialize after default seed but original is explicitly + // seeded before generating any random number. Then compare + // generated random numbers produced through original and + // serialized instances. + orig = getSRInstance(mech); + orig.nextInt(); // Default seeded + copy = deserializedCopy(orig); + orig.setSeed(SEED); // Explicitly seeded + System.out.printf("%nSerialize after default seed but original " + + "is explicitly seeded before generating random number" + + ". Generated random numbers should be different."); + check(orig, copy, false, mech); + + // Serialize after explicit seed but original is explicitly + // seeded again before generating random number. Then compare + // generated random numbers produced through original and + // serialized instances. + orig = getSRInstance(mech); + orig.setSeed(SEED); // Explicitly seeded + copy = deserializedCopy(orig); + orig.setSeed(SEED); // Explicitly seeded + System.out.printf("%nSerialize after explicit seed but " + + "original is explicitly seeded again before " + + "generating random number. Generated random " + + "numbers should be different."); + check(orig, copy, false, mech); + + } catch (Exception e) { + e.printStackTrace(System.out); + success = false; + } finally { + Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE); + } + System.out.printf("%n------Completed Test for %s------", mech); + } + + if (!success) { + throw new RuntimeException("At least one test failed."); + } + } + + /** + * Find if the mechanism is a DRBG mechanism. + * @param mech Mechanism name + * @return True for DRBG mechanism else False + */ + private static boolean isDRBG(String mech) { + return mech.contains("_DRBG"); + } + + /** + * Verify the similarity of random numbers generated though both original + * as well as deserialized instance. + */ + private static void check(SecureRandom orig, SecureRandom copy, + boolean equal, String mech) { + int o = orig.nextInt(); + int c = copy.nextInt(); + System.out.printf("%nRandom number generated for mechanism: '%s' " + + "from original instance as: '%s' and from serialized " + + "instance as: '%s'", mech, o, c); + if (equal) { + Asserts.assertEquals(o, c, mech); + } else { + Asserts.assertNotEquals(o, c, mech); + } + } + + /** + * Get a copy of SecureRandom instance through deserialization. + * @param orig Original SecureRandom instance + * @return Deserialized SecureRandom instance + * @throws IOException + * @throws ClassNotFoundException + */ + private static SecureRandom deserializedCopy(SecureRandom orig) + throws IOException, ClassNotFoundException { + return deserialize(serialize(orig)); + } + + /** + * Deserialize the SecureRandom object. + */ + private static SecureRandom deserialize(byte[] serialized) + throws IOException, ClassNotFoundException { + SecureRandom sr = null; + try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized); + ObjectInputStream ois = new ObjectInputStream(bis)) { + sr = (SecureRandom) ois.readObject(); + } + return sr; + } + + /** + * Serialize the given SecureRandom object. + */ + private static byte[] serialize(SecureRandom sr) throws IOException { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(sr); + return bos.toByteArray(); + } + } + + /** + * Create a SecureRandom instance for a given mechanism. + */ + private static SecureRandom getSRInstance(String mech) + throws NoSuchAlgorithmException { + if (!isDRBG(mech)) { + return SecureRandom.getInstance(mech); + } else { + Security.setProperty(DRBG_CONFIG, mech); + return SecureRandom.getInstance("DRBG"); + } + } + +}
--- a/jdk/test/sun/security/provider/SecureRandom/StrongSecureRandom.java Thu May 19 11:13:52 2016 +0200 +++ b/jdk/test/sun/security/provider/SecureRandom/StrongSecureRandom.java Thu May 19 04:20:08 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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,11 +21,11 @@ * questions. */ -/** +/* * @test - * @bug 6425477 + * @bug 6425477 8141039 * @summary Better support for generation of high entropy random numbers - * @run main/othervm StrongSecureRandom + * @run main StrongSecureRandom */ import java.security.*; import java.util.*; @@ -35,7 +35,10 @@ */ public class StrongSecureRandom { - private static String os = System.getProperty("os.name", "unknown"); + private static final String os = System.getProperty("os.name", "unknown"); + private static final String DRBG_CONFIG = "securerandom.drbg.config"; + private static final String DRBG_CONFIG_VALUE + = Security.getProperty(DRBG_CONFIG); private static void testDefaultEgd() throws Exception { // No SecurityManager installed. @@ -47,31 +50,53 @@ } } - private static void testSHA1PRNGImpl() throws Exception { - SecureRandom sr; + /** + * Verify if the mechanism is DRBG type. + * @param mech Mechanism name + * @return True if the mechanism name is DRBG type else False. + */ + private static boolean isDRBG(String mech) { + return mech.contains("_DRBG"); + } + + private static void testSecureRandomImpl(String algo, boolean drbg) + throws Exception { + byte[] ba; + final String secureRandomSource + = Security.getProperty("securerandom.source"); + try { + String urandom = "file:/dev/urandom"; - String urandom = "file:/dev/urandom"; + System.out.println("Testing new SeedGenerator and EGD"); - System.out.println("Testing new SeedGenerator and EGD"); + Security.setProperty("securerandom.source", urandom); + if (!Security.getProperty("securerandom.source").equals(urandom)) { + throw new Exception("Couldn't set securerandom.source"); + } - Security.setProperty("securerandom.source", urandom); - if (!Security.getProperty("securerandom.source").equals(urandom)) { - throw new Exception("Couldn't set securerandom.source"); + /* + * Take out a large number of bytes in hopes of blocking. + * Don't expect this to happen, unless something is broken on Linux + */ + SecureRandom sr = null; + if (drbg) { + Security.setProperty(DRBG_CONFIG, algo); + sr = SecureRandom.getInstance("DRBG"); + } else { + sr = SecureRandom.getInstance(algo); + } + if (!sr.getAlgorithm().equals(isDRBG(algo) ? "DRBG" : algo)) { + throw new Exception("sr.getAlgorithm(): " + sr.getAlgorithm()); + } + + ba = sr.generateSeed(4096); + sr.nextBytes(ba); + sr.setSeed(ba); + } finally { + Security.setProperty("securerandom.source", secureRandomSource); + Security.setProperty(DRBG_CONFIG, DRBG_CONFIG_VALUE); } - - /* - * Take out a large number of bytes in hopes of blocking. - * Don't expect this to happen, unless something is broken on Linux - */ - sr = SecureRandom.getInstance("SHA1PRNG"); - if (!sr.getAlgorithm().equals("SHA1PRNG")) { - throw new Exception("sr.getAlgorithm(): " + sr.getAlgorithm()); - } - - ba = sr.generateSeed(4096); - sr.nextBytes(ba); - sr.setSeed(ba); } private static void testNativePRNGImpls() throws Exception { @@ -85,7 +110,7 @@ return; } - System.out.println(" Testing regular"); + System.out.println("Testing regular"); sr = SecureRandom.getInstance("NativePRNG"); if (!sr.getAlgorithm().equals("NativePRNG")) { throw new Exception("sr.getAlgorithm(): " + sr.getAlgorithm()); @@ -94,7 +119,7 @@ sr.nextBytes(ba); sr.setSeed(ba); - System.out.println(" Testing NonBlocking"); + System.out.println("Testing NonBlocking"); sr = SecureRandom.getInstance("NativePRNGNonBlocking"); if (!sr.getAlgorithm().equals("NativePRNGNonBlocking")) { throw new Exception("sr.getAlgorithm(): " + sr.getAlgorithm()); @@ -108,7 +133,7 @@ return; } - System.out.println(" Testing Blocking"); + System.out.println("Testing Blocking"); sr = SecureRandom.getInstance("NativePRNGBlocking"); if (!sr.getAlgorithm().equals("NativePRNGBlocking")) { throw new Exception("sr.getAlgorithm(): " + sr.getAlgorithm()); @@ -141,9 +166,15 @@ throws Exception { System.out.println("Testing: '" + property + "' " + expected); - - Security.setProperty("securerandom.strongAlgorithms", property); - testStrongInstance(expected); + final String origStrongAlgoProp + = Security.getProperty("securerandom.strongAlgorithms"); + try { + Security.setProperty("securerandom.strongAlgorithms", property); + testStrongInstance(expected); + } finally { + Security.setProperty( + "securerandom.strongAlgorithms", origStrongAlgoProp); + } } private static void testProperties() throws Exception { @@ -228,7 +259,10 @@ public static void main(String args[]) throws Exception { testDefaultEgd(); - testSHA1PRNGImpl(); + for (String algo : new String[]{ + "SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", "CTR_DRBG"}) { + testSecureRandomImpl(algo, isDRBG(algo)); + } testNativePRNGImpls(); testAllImpls();
--- a/jdk/test/sun/security/provider/SeedGenerator/SeedGeneratorChoice.java Thu May 19 11:13:52 2016 +0200 +++ b/jdk/test/sun/security/provider/SeedGenerator/SeedGeneratorChoice.java Thu May 19 04:20:08 2016 -0700 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2011, 2016, 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 @@ -23,7 +24,7 @@ /* * @test - * @bug 6998583 + * @bug 6998583 8141039 * @summary NativeSeedGenerator is making 8192 byte read requests from * entropy pool on each init. * @run main SeedGeneratorChoice @@ -39,14 +40,24 @@ * We should always fall back to the ThreadedSeedGenerator if exceptions * are encountered with user defined source of entropy. */ - import java.security.SecureRandom; +import java.security.Security; public class SeedGeneratorChoice { public static void main(String... arguments) throws Exception { - byte[] bytes; - SecureRandom prng = SecureRandom.getInstance("SHA1PRNG"); - bytes = prng.generateSeed(1); + for (String mech : new String[]{"SHA1PRNG", "Hash_DRBG", "HMAC_DRBG", + "CTR_DRBG"}) { + + SecureRandom prng = null; + if (!mech.contains("_DRBG")) { + prng = SecureRandom.getInstance(mech); + } else { + Security.setProperty("securerandom.drbg.config", mech); + prng = SecureRandom.getInstance("DRBG"); + } + prng.generateSeed(1); + } } + }