8141039: Test Task: Develop new tests for JEP 273: DRBG-Based SecureRandom Implementations
authorssahoo
Thu, 19 May 2016 04:20:08 -0700
changeset 38423 5d6ff7d76bf4
parent 38422 638589997770
child 38424 abb80b35c9dd
8141039: Test Task: Develop new tests for JEP 273: DRBG-Based SecureRandom Implementations Reviewed-by: weijun
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
--- /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;
-        byte[] ba;
-
-        String urandom = "file:/dev/urandom";
+    /**
+     * 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");
+    }
 
-        System.out.println("Testing new SeedGenerator and EGD");
+    private static void testSecureRandomImpl(String algo, boolean drbg)
+            throws Exception {
 
-        Security.setProperty("securerandom.source", urandom);
-        if (!Security.getProperty("securerandom.source").equals(urandom)) {
-            throw new Exception("Couldn't set securerandom.source");
-        }
+        byte[] ba;
+        final String secureRandomSource
+                = Security.getProperty("securerandom.source");
+        try {
+            String urandom = "file:/dev/urandom";
+
+            System.out.println("Testing new SeedGenerator and EGD");
 
-        /*
-         * 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());
+            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);
         }
-
-        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);
+        }
     }
+
 }