1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.security;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.fortress.Engine;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
2479f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * Uses a one-way hash function to turn an arbitrary number of bytes into a
2579f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * fixed-length byte sequence. The original arbitrary-length sequence is the
2679f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * <i>message</i>, and the fixed-length byte sequence is the <i>digest</i> or
2779f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * <i>message digest</i>.
2879f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *
2979f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * <h4>Sample Code</h4>
3079f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * <p>The basic pattern to digest an {@link java.io.InputStream} looks like this:
3179f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * <pre>
3279f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *  MessageDigest digester = MessageDigest.getInstance("MD5");
3379f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *  byte[] bytes = new byte[8192];
3479f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *  int byteCount;
3579f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *  while ((byteCount = in.read(bytes)) > 0) {
3679f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *    digester.update(bytes, 0, byteCount);
3779f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *  }
3879f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *  byte[] digest = digester.digest();
3979f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * </pre>
4079f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *
4179f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * <p>That is, after creating or resetting a {@code MessageDigest} you should
4279f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * call {@link #update(byte[],int,int)} for each block of input data, and then call {@link #digest}
4379f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * to get the final digest. Note that calling {@code digest} resets the {@code MessageDigest}.
4479f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * Advanced users who want partial digests should clone their {@code MessageDigest} before
4579f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * calling {@code digest}.
4679f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes *
4779f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes * <p>This class is not thread-safe.
482f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes *
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see MessageDigestSpi
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class MessageDigest extends MessageDigestSpi {
522f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Used to access common engine functionality
540a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom    private static final Engine ENGINE = new Engine("MessageDigest");
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The provider
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Provider provider;
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The algorithm.
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String algorithm;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new instance of {@code MessageDigest} with the name of
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the algorithm to use.
65f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of algorithm to use
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected MessageDigest(String algorithm) {
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.algorithm = algorithm;
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code MessageDigest} that utilizes the
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified algorithm.
76f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the algorithm to use
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code MessageDigest} that utilizes the
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified algorithm
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not available
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code algorithm} is {@code null}
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static MessageDigest getInstance(String algorithm)
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException {
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
8986acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("algorithm == null");
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
916cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
926cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        Object spi = sap.spi;
936cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        Provider provider = sap.provider;
940a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom        if (spi instanceof MessageDigest) {
950a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            MessageDigest result = (MessageDigest) spi;
960a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            result.algorithm = algorithm;
970a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            result.provider = provider;
980a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            return result;
990a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom        }
1006cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        return new MessageDigestImpl((MessageDigestSpi) sap.spi, sap.provider, algorithm);
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code MessageDigest} that utilizes the
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified algorithm from the specified provider.
106f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the algorithm to use
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the provider
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code MessageDigest} that utilizes the
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified algorithm from the specified provider
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not available
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchProviderException
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified provider is not available
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code algorithm} is {@code null}
119897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes     * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()}
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static MessageDigest getInstance(String algorithm, String provider)
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException, NoSuchProviderException {
123897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes        if (provider == null || provider.isEmpty()) {
124897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Provider p = Security.getProvider(provider);
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (p == null) {
128897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NoSuchProviderException(provider);
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getInstance(algorithm, p);
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code MessageDigest} that utilizes the
1350a64887ae9127d081fc6e312ba1f06f727453800Kenny Root     * specified algorithm from the specified provider. The
1360a64887ae9127d081fc6e312ba1f06f727453800Kenny Root     * {@code provider} supplied does not have to be registered.
137f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the algorithm to use
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the provider
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code MessageDigest} that utilizes the
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified algorithm from the specified provider
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not available
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code algorithm} is {@code null}
148897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes     * @throws IllegalArgumentException if {@code provider == null}
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static MessageDigest getInstance(String algorithm, Provider provider)
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException {
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (provider == null) {
153cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes            throw new IllegalArgumentException("provider == null");
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
15686acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("algorithm == null");
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1586cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        Object spi = ENGINE.getInstance(algorithm, provider, null);
1590a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom        if (spi instanceof MessageDigest) {
1600a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            MessageDigest result = (MessageDigest) spi;
1610a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            result.algorithm = algorithm;
1620a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            result.provider = provider;
1632f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            return result;
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1650a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom        return new MessageDigestImpl((MessageDigestSpi) spi, provider, algorithm);
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Puts this {@code MessageDigest} back in an initial state, such that it is
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ready to compute a one way hash value.
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void reset() {
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineReset();
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code byte}.
178f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param arg0
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} to update this {@code MessageDigest} with
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte arg0) {
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(arg0);
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code byte[]}.
189f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the first byte in {@code input} to update from
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes in {@code input} to update from
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset} or {@code len} are not valid in respect to
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code input}
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte[] input, int offset, int len) {
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null ||
2022f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        // offset < 0 || len < 0 ||
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // checks for negative values are commented out intentionally
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // see HARMONY-1120 for details
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                (long) offset + (long) len > input.length) {
206897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input, offset, len);
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code byte[]}.
213f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code input} is {@code null}
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte[] input) {
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null) {
22186acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("input == null");
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input, 0, input.length);
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes and returns the final hash value for this {@link MessageDigest}.
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * After the digest is computed the receiver is reset.
229f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the computed one way hash value
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] digest() {
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return engineDigest();
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes and stores the final hash value for this {@link MessageDigest}.
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * After the digest is computed the receiver is reset.
240f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buf
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer to store the result
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the first byte in {@code buf} to store
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes allocated for the digest
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of bytes written to {@code buf}
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws DigestException
24979f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes     *             if an error occurs
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset} or {@code len} are not valid in respect to
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code buf}
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int digest(byte[] buf, int offset, int len) throws DigestException {
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (buf == null ||
2572f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        // offset < 0 || len < 0 ||
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // checks for negative values are commented out intentionally
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // see HARMONY-1148 for details
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                (long) offset + (long) len > buf.length) {
261897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return engineDigest(buf, offset, len);
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Performs the final update and then computes and returns the final hash
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value for this {@link MessageDigest}. After the digest is computed the
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * receiver is reset.
270f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the computed one way hash value
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] digest(byte[] input) {
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        update(input);
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return digest();
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable description of this
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code MessageDigest} including the name of its algorithm.
284f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a printable representation for this {@code MessageDigest}
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
289f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return "MESSAGE DIGEST " + algorithm;
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates whether to digest are equal by performing a simply
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * byte-per-byte compare of the two digests.
295f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param digesta
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the first digest to be compared
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param digestb
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the second digest to be compared
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the two hashes are equal, {@code false} otherwise
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static boolean isEqual(byte[] digesta, byte[] digestb) {
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (digesta.length != digestb.length) {
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
3063e478f0dbd7bb982fb36d96bfec09f14271d9c05Xizhi Zhu (Steven)        // Perform a constant time comparison to avoid timing attacks.
3073e478f0dbd7bb982fb36d96bfec09f14271d9c05Xizhi Zhu (Steven)        int v = 0;
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < digesta.length; i++) {
3093e478f0dbd7bb982fb36d96bfec09f14271d9c05Xizhi Zhu (Steven)            v |= (digesta[i] ^ digestb[i]);
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
3113e478f0dbd7bb982fb36d96bfec09f14271d9c05Xizhi Zhu (Steven)        return v == 0;
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the name of the algorithm of this {@code MessageDigest}.
316f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the name of the algorithm of this {@code MessageDigest}
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final String getAlgorithm() {
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return algorithm;
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the provider associated with this {@code MessageDigest}.
325f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the provider associated with this {@code MessageDigest}
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Provider getProvider() {
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return provider;
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the engine digest length in bytes. If the implementation does not
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implement this function or is not an instance of {@code Cloneable},
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code 0} is returned.
336f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the digest length in bytes, or {@code 0}
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int getDigestLength() {
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int l = engineGetDigestLength();
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (l != 0) {
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return l;
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(this instanceof Cloneable)) {
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            MessageDigest md = (MessageDigest) clone();
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return md.digest().length;
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (CloneNotSupportedException e) {
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code input}.
357f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code ByteBuffer}
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void update(ByteBuffer input) {
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input);
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
366f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The internal MessageDigest implementation
368f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class MessageDigestImpl extends MessageDigest {
3712f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // MessageDigestSpi implementation
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private MessageDigestSpi spiImpl;
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // MessageDigestImpl ctor
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private MessageDigestImpl(MessageDigestSpi messageDigestSpi,
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Provider provider, String algorithm) {
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(algorithm);
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super.provider = provider;
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl = messageDigestSpi;
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineReset() implementation
3842f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineReset() {
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineReset();
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineDigest() implementation
3902f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected byte[] engineDigest() {
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return spiImpl.engineDigest();
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineGetDigestLength() implementation
3962f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected int engineGetDigestLength() {
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return spiImpl.engineGetDigestLength();
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineUpdate() implementation
4022f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineUpdate(byte arg0) {
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(arg0);
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineUpdate() implementation
4082f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineUpdate(byte[] arg0, int arg1, int arg2) {
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(arg0, arg1, arg2);
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Returns a clone if the spiImpl is cloneable
4142f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object clone() throws CloneNotSupportedException {
416875d3c90f395109a30ed12f8f83ad001d2ae7439Kenny Root            MessageDigestSpi spi = (MessageDigestSpi) spiImpl.clone();
417875d3c90f395109a30ed12f8f83ad001d2ae7439Kenny Root            return new MessageDigestImpl(spi, getProvider(), getAlgorithm());
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
421