151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.security;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.*;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.ByteArrayOutputStream;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.PrintStream;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.InputStream;
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.ByteArrayInputStream;
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.ByteBuffer;
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This MessageDigest class provides applications the functionality of a
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * message digest algorithm, such as SHA-1 or SHA-256.
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Message digests are secure one-way hash functions that take arbitrary-sized
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data and output a fixed-length hash value.
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>A MessageDigest object starts out initialized. The data is
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * processed through it using the {@link #update(byte) update}
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * methods. At any point {@link #reset() reset} can be called
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to reset the digest. Once all the data to be updated has been
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * updated, one of the {@link #digest() digest} methods should
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be called to complete the hash computation.
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>The <code>digest</code> method can be called once for a given number
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of updates. After <code>digest</code> has been called, the MessageDigest
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object is reset to its initialized state.
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Implementations are free to implement the Cloneable interface.
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Client applications can test cloneability by attempting cloning
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and catching the CloneNotSupportedException: <p>
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski* <pre>
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski* MessageDigest md = MessageDigest.getInstance("SHA");
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski*
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski* try {
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski*     md.update(toChapter1);
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski*     MessageDigest tc1 = md.clone();
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski*     byte[] toChapter1Digest = tc1.digest();
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski*     md.update(toChapter2);
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski*     ...etc.
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski* } catch (CloneNotSupportedException cnse) {
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski*     throw new DigestException("couldn't make digest of partial content");
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski* }
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski* </pre>
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Note that if a given implementation is not cloneable, it is
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * still possible to compute intermediate digests by instantiating
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * several instances, if the number of digests is known in advance.
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Note that this class is abstract and extends from
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>MessageDigestSpi</code> for historical reasons.
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Application developers should only take notice of the methods defined in
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this <code>MessageDigest</code> class; all the methods in
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the superclass are intended for cryptographic service providers who wish to
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * supply their own implementations of message digest algorithms.
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
84fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak * <p> Android provides the following <code>MessageDigest</code> algorithms:
85fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak * <table>
86fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *     <thead>
87fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         <tr>
88fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <th>Name</th>
89fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <th>Supported (API Levels)</th>
90fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         </tr>
91fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *     </thead>
92fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *     <tbody>
93fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         <tr>
94fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>MD5</td>
95fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>1+</td>
96fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         </tr>
97fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         <tr>
98fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>SHA-1</td>
99fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>1+</td>
100fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         </tr>
101fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         <tr>
102fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>SHA-224</td>
103fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>1&ndash;8,22+</td>
104fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         </tr>
105fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         <tr>
106fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>SHA-256</td>
107fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>1+</td>
108fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         </tr>
109fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         <tr>
110fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>SHA-384</td>
111fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>1+</td>
112fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         </tr>
113fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         <tr>
114fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>SHA-512</td>
115fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *             <td>1+</td>
116fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *         </tr>
117fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *     </tbody>
118fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak * </table>
119fba165684d995ea7afe39bb1fc15a4d09beeba71Przemyslaw Szczepaniak *
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * These algorithms are described in the <a href=
121d2449bb576ad1e3a3877364e5e1ae28625f69e35Yi Kong * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * MessageDigest section</a> of the
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Java Cryptography Architecture Standard Algorithm Name Documentation.
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Benjamin Renaud
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see DigestInputStream
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see DigestOutputStream
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic abstract class MessageDigest extends MessageDigestSpi {
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private String algorithm;
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // The state of this digest
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int INITIAL = 0;
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int IN_PROGRESS = 1;
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int state = INITIAL;
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // The provider
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Provider provider;
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a message digest with the specified algorithm name.
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param algorithm the standard name of the digest algorithm.
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * See the MessageDigest section in the <a href=
148d2449bb576ad1e3a3877364e5e1ae28625f69e35Yi Kong     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for information about standard algorithm names.
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    protected MessageDigest(String algorithm) {
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.algorithm = algorithm;
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a MessageDigest object that implements the specified digest
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * algorithm.
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> This method traverses the list of registered security Providers,
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * starting with the most preferred Provider.
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * A new MessageDigest object encapsulating the
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * MessageDigestSpi implementation from the first
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Provider that supports the specified algorithm is returned.
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Note that the list of registered providers may be retrieved via
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the {@link Security#getProviders() Security.getProviders()} method.
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param algorithm the name of the algorithm requested.
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * See the MessageDigest section in the <a href=
171d2449bb576ad1e3a3877364e5e1ae28625f69e35Yi Kong     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for information about standard algorithm names.
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a Message Digest object that implements the specified algorithm.
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NoSuchAlgorithmException if no Provider supports a
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          MessageDigestSpi implementation for the
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          specified algorithm.
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see Provider
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static MessageDigest getInstance(String algorithm)
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    throws NoSuchAlgorithmException {
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Object[] objs = Security.getImpl(algorithm, "MessageDigest",
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                             (String)null);
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (objs[0] instanceof MessageDigest) {
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                MessageDigest md = (MessageDigest)objs[0];
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                md.provider = (Provider)objs[1];
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return md;
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                MessageDigest delegate =
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    new Delegate((MessageDigestSpi)objs[0], algorithm);
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                delegate.provider = (Provider)objs[1];
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return delegate;
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch(NoSuchProviderException e) {
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NoSuchAlgorithmException(algorithm + " not found");
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a MessageDigest object that implements the specified digest
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * algorithm.
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> A new MessageDigest object encapsulating the
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * MessageDigestSpi implementation from the specified provider
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is returned.  The specified provider must be registered
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in the security provider list.
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Note that the list of registered providers may be retrieved via
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the {@link Security#getProviders() Security.getProviders()} method.
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param algorithm the name of the algorithm requested.
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * See the MessageDigest section in the <a href=
217d2449bb576ad1e3a3877364e5e1ae28625f69e35Yi Kong     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for information about standard algorithm names.
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param provider the name of the provider.
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a MessageDigest object that implements the specified algorithm.
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NoSuchAlgorithmException if a MessageDigestSpi
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          implementation for the specified algorithm is not
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          available from the specified provider.
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NoSuchProviderException if the specified provider is not
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          registered in the security provider list.
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IllegalArgumentException if the provider name is null
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          or empty.
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see Provider
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static MessageDigest getInstance(String algorithm, String provider)
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws NoSuchAlgorithmException, NoSuchProviderException
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (provider == null || provider.length() == 0)
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("missing provider");
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (objs[0] instanceof MessageDigest) {
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            MessageDigest md = (MessageDigest)objs[0];
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            md.provider = (Provider)objs[1];
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return md;
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            MessageDigest delegate =
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                new Delegate((MessageDigestSpi)objs[0], algorithm);
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            delegate.provider = (Provider)objs[1];
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return delegate;
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a MessageDigest object that implements the specified digest
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * algorithm.
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> A new MessageDigest object encapsulating the
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * MessageDigestSpi implementation from the specified Provider
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * object is returned.  Note that the specified Provider object
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * does not have to be registered in the provider list.
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param algorithm the name of the algorithm requested.
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * See the MessageDigest section in the <a href=
266d2449bb576ad1e3a3877364e5e1ae28625f69e35Yi Kong     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for information about standard algorithm names.
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param provider the provider.
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a MessageDigest object that implements the specified algorithm.
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NoSuchAlgorithmException if a MessageDigestSpi
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          implementation for the specified algorithm is not available
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          from the specified Provider object.
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IllegalArgumentException if the specified provider is null.
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see Provider
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static MessageDigest getInstance(String algorithm,
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                            Provider provider)
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws NoSuchAlgorithmException
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (provider == null)
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("missing provider");
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (objs[0] instanceof MessageDigest) {
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            MessageDigest md = (MessageDigest)objs[0];
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            md.provider = (Provider)objs[1];
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return md;
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            MessageDigest delegate =
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                new Delegate((MessageDigestSpi)objs[0], algorithm);
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            delegate.provider = (Provider)objs[1];
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return delegate;
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the provider of this message digest object.
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the provider of this message digest object
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final Provider getProvider() {
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return this.provider;
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Updates the digest using the specified byte.
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param input the byte with which to update the digest.
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void update(byte input) {
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        engineUpdate(input);
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        state = IN_PROGRESS;
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Updates the digest using the specified array of bytes, starting
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * at the specified offset.
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param input the array of bytes.
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param offset the offset to start from in the array of bytes.
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param len the number of bytes to use, starting at
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>offset</code>.
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void update(byte[] input, int offset, int len) {
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (input == null) {
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("No input buffer given");
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (input.length - offset < len) {
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Input buffer too short");
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        engineUpdate(input, offset, len);
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        state = IN_PROGRESS;
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Updates the digest using the specified array of bytes.
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param input the array of bytes.
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void update(byte[] input) {
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        engineUpdate(input, 0, input.length);
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        state = IN_PROGRESS;
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Update the digest using the specified ByteBuffer. The digest is
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * updated using the <code>input.remaining()</code> bytes starting
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * at <code>input.position()</code>.
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Upon return, the buffer's position will be equal to its limit;
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * its limit will not have changed.
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param input the ByteBuffer
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.5
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final void update(ByteBuffer input) {
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (input == null) {
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException();
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        engineUpdate(input);
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        state = IN_PROGRESS;
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Completes the hash computation by performing final operations
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * such as padding. The digest is reset after this call is made.
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the array of bytes for the resulting hash value.
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public byte[] digest() {
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /* Resetting is the responsibility of implementors. */
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        byte[] result = engineDigest();
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        state = INITIAL;
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return result;
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Completes the hash computation by performing final operations
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * such as padding. The digest is reset after this call is made.
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param buf output buffer for the computed digest
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param offset offset into the output buffer to begin storing the digest
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param len number of bytes within buf allotted for the digest
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the number of bytes placed into <code>buf</code>
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception DigestException if an error occurs.
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int digest(byte[] buf, int offset, int len) throws DigestException {
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (buf == null) {
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("No output buffer given");
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (buf.length - offset < len) {
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ("Output buffer too small for specified offset and length");
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int numBytes = engineDigest(buf, offset, len);
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        state = INITIAL;
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return numBytes;
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Performs a final update on the digest using the specified array
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of bytes, then completes the digest computation. That is, this
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * method first calls {@link #update(byte[]) update(input)},
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * passing the <i>input</i> array to the <code>update</code> method,
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then calls {@link #digest() digest()}.
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param input the input to be updated before the digest is
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * completed.
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the array of bytes for the resulting hash value.
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public byte[] digest(byte[] input) {
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        update(input);
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return digest();
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a string representation of this message digest object.
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString() {
433f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath        StringBuilder builder = new StringBuilder();
434f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath        builder.append(algorithm);
435f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath        builder.append(" Message Digest from ");
436f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath        builder.append(provider.getName());
437f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath        builder.append(", ");
438f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        switch (state) {
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        case INITIAL:
441f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath            builder.append("<initialized>");
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            break;
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        case IN_PROGRESS:
444f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath            builder.append("<in progress>");
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            break;
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
447f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath
448f8e1027ce0a759a6669b38830876115c4b77e557Narayan Kamath        return builder.toString();
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Compares two digests for equality. Does a simple byte compare.
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param digesta one of the digests to compare.
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param digestb the other digest to compare.
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true if the digests are equal, false otherwise.
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static boolean isEqual(byte[] digesta, byte[] digestb) {
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (digesta.length != digestb.length) {
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int result = 0;
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // time-constant comparison
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < digesta.length; i++) {
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            result |= digesta[i] ^ digestb[i];
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return result == 0;
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Resets the digest for further use.
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void reset() {
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        engineReset();
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        state = INITIAL;
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a string that identifies the algorithm, independent of
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * implementation details. The name should be a standard
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Java Security name (such as "SHA", "MD5", and so on).
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * See the MessageDigest section in the <a href=
486d2449bb576ad1e3a3877364e5e1ae28625f69e35Yi Kong     * "{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/security/StandardNames.html#MessageDigest">
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for information about standard algorithm names.
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the name of the algorithm
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final String getAlgorithm() {
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return this.algorithm;
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the length of the digest in bytes, or 0 if this operation is
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * not supported by the provider and the implementation is not cloneable.
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the digest length in bytes, or 0 if this operation is not
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * supported by the provider and the implementation is not cloneable.
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.2
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final int getDigestLength() {
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int digestLen = engineGetDigestLength();
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (digestLen == 0) {
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                MessageDigest md = (MessageDigest)clone();
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                byte[] digest = md.digest();
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return digest.length;
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (CloneNotSupportedException e) {
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return digestLen;
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return digestLen;
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a clone if the implementation is cloneable.
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a clone if the implementation is cloneable.
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception CloneNotSupportedException if this is called on an
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * implementation that does not support <code>Cloneable</code>.
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Object clone() throws CloneNotSupportedException {
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (this instanceof Cloneable) {
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return super.clone();
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new CloneNotSupportedException();
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The following class allows providers to extend from MessageDigestSpi
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * rather than from MessageDigest. It represents a MessageDigest with an
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * encapsulated, provider-supplied SPI object (of type MessageDigestSpi).
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the provider implementation is an instance of MessageDigestSpi,
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the getInstance() methods above return an instance of this class, with
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the SPI object encapsulated.
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Note: All SPI methods from the original MessageDigest class have been
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * moved up the hierarchy into a new class (MessageDigestSpi), which has
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * been interposed in the hierarchy between the API (MessageDigest)
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and its original parent (Object).
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static class Delegate extends MessageDigest {
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // The provider implementation (delegate)
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private MessageDigestSpi digestSpi;
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // constructor
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public Delegate(MessageDigestSpi digestSpi, String algorithm) {
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            super(algorithm);
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.digestSpi = digestSpi;
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /**
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Returns a clone if the delegate is cloneable.
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * @return a clone if the delegate is cloneable.
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * @exception CloneNotSupportedException if this is called on a
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * delegate that does not support <code>Cloneable</code>.
57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public Object clone() throws CloneNotSupportedException {
57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (digestSpi instanceof Cloneable) {
57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                MessageDigestSpi digestSpiClone =
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    (MessageDigestSpi)digestSpi.clone();
57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Because 'algorithm', 'provider', and 'state' are private
57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // members of our supertype, we must perform a cast to
57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // access them.
57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                MessageDigest that =
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    new Delegate(digestSpiClone,
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 ((MessageDigest)this).algorithm);
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                that.provider = ((MessageDigest)this).provider;
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                that.state = ((MessageDigest)this).state;
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return that;
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new CloneNotSupportedException();
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        protected int engineGetDigestLength() {
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return digestSpi.engineGetDigestLength();
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        protected void engineUpdate(byte input) {
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digestSpi.engineUpdate(input);
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        protected void engineUpdate(byte[] input, int offset, int len) {
59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digestSpi.engineUpdate(input, offset, len);
59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        protected void engineUpdate(ByteBuffer input) {
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digestSpi.engineUpdate(input);
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        protected byte[] engineDigest() {
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return digestSpi.engineDigest();
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        protected int engineDigest(byte[] buf, int offset, int len)
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throws DigestException {
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return digestSpi.engineDigest(buf, offset, len);
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        protected void engineReset() {
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digestSpi.engineReset();
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
619