--- /dev/null	2014-05-03 18:05:47.580612362 +0200
+++ new/src/share/classes/java/security/StandardMessageDigests.java	2014-05-05 13:49:21.951219490 +0200
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2014, Red Hat, Inc.
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package java.security;
+
+/**
+ * This class provides static factory methods for commonly used
+ * message digest algorithms, using the default JCE provider.
+ *
+ * <p>Depending on the cryptography provider, additional message
+ * digest algorithms are available through
+ * {@link MessageDigest#getInstance(String)} and related methods.
+ *
+ * @since 1.9
+ */
+public final class StandardMessageDigests {
+    private StandardMessageDigests() { } // No instances.
+
+    private static volatile MessageDigest sha1;
+    private static volatile MessageDigest sha256;
+    private static volatile MessageDigest sha384;
+    private static volatile MessageDigest sha512;
+
+    /**
+     * Create a new object implementing the SHA-1 message digest.
+     * @return a new message digest
+     * @throws NoSuchAlgorithmException
+     *   the default provider does not support the SHA-1 algorithm
+     */
+    public static MessageDigest newSHA1() throws NoSuchAlgorithmException {
+        MessageDigest md = sha1;
+        if (md == null) {
+            md = createPrototype("SHA-1");
+            sha1 = md;
+        }
+        try {
+            return (MessageDigest) md.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    /**
+     * Create a new object implementing the SHA-256 message digest.
+     * @return a new message digest
+     * @throws NoSuchAlgorithmException
+     *   the default provider does not support the SHA-256 algorithm
+     */
+    public static MessageDigest newSHA256() throws NoSuchAlgorithmException {
+        MessageDigest md = sha256;
+        if (md == null) {
+            md = createPrototype("SHA-256");
+            sha256 = md;
+        }
+        try {
+            return (MessageDigest) md.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    /**
+     * Create a new object implementing the SHA-384 message digest.
+     * @return a new message digest
+     * @throws NoSuchAlgorithmException
+     *   the default provider does not support the SHA-384 algorithm
+     */
+    public static MessageDigest newSHA384() throws NoSuchAlgorithmException {
+        MessageDigest md = sha384;
+        if (md == null) {
+            md = createPrototype("SHA-384");
+            sha384 = md;
+        }
+        try {
+            return (MessageDigest) md.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    /**
+     * Create a new object implementing the SHA-512 message digest.
+     * @return a new message digest
+     * @throws NoSuchAlgorithmException
+     *   the default provider does not support the SHA-512 algorithm
+     */
+    public static MessageDigest newSHA512() throws NoSuchAlgorithmException {
+        MessageDigest md = sha512;
+        if (md == null) {
+            md = createPrototype("SHA-512");
+            sha512 = md;
+        }
+        try {
+            return (MessageDigest) md.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    /**
+     * Internal class which allows non-cloneable message digests to
+     * act as prototype objects.  Only cloning the initial state is
+     * actually implemented.  Instances of this class are never
+     * returned, the {@link #clone()} method is invoked to create the
+     * actual message digest object.
+     */
+    static class MessageDigestPrototype extends MessageDigest {
+        MessageDigestPrototype(String algorithm) {
+            super(algorithm);
+        }
+
+        @Override
+        public Object clone() {
+            try {
+                return MessageDigest.getInstance(getAlgorithm());
+            } catch (NoSuchAlgorithmException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        @Override
+        protected void engineUpdate(byte input) {
+            throw new AssertionError();
+        }
+
+        @Override
+        protected void engineUpdate(byte[] input, int offset, int len) {
+            throw new AssertionError();
+        }
+
+        @Override
+        protected byte[] engineDigest() {
+            throw new AssertionError();
+        }
+
+        @Override
+        protected int engineDigest(byte[] buf, int offset, int len) {
+            throw new AssertionError();
+        }
+
+        @Override
+        protected void engineReset() {
+            throw new AssertionError();
+        }
+    }
+
+    /**
+     * Creates a new cloneable {@code MessageDigest} object.
+     */
+    private static MessageDigest createPrototype(String name)
+        throws NoSuchAlgorithmException {
+        MessageDigest md = MessageDigest.getInstance(name);
+	// The digest object can be a delegate which does not itself
+	// implement Cloneable, but clone() succeeds nevertheless, so
+	// we just call the method to see if it works.
+	try {
+	    md.clone();
+	    return md;
+	} catch (CloneNotSupportedException e) {
+	    return new MessageDigestPrototype(name);
+	}
+    }
+}
