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
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified algorithm from the specified provider.
136f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the algorithm to use
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the provider
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code MessageDigest} that utilizes the
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified algorithm from the specified provider
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not available
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code algorithm} is {@code null}
147897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes     * @throws IllegalArgumentException if {@code provider == null}
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static MessageDigest getInstance(String algorithm, Provider provider)
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException {
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (provider == null) {
152cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes            throw new IllegalArgumentException("provider == null");
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
15586acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("algorithm == null");
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1576cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        Object spi = ENGINE.getInstance(algorithm, provider, null);
1580a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom        if (spi instanceof MessageDigest) {
1590a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            MessageDigest result = (MessageDigest) spi;
1600a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            result.algorithm = algorithm;
1610a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom            result.provider = provider;
1622f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            return result;
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1640a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom        return new MessageDigestImpl((MessageDigestSpi) spi, provider, algorithm);
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Puts this {@code MessageDigest} back in an initial state, such that it is
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ready to compute a one way hash value.
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void reset() {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineReset();
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code byte}.
177f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param arg0
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} to update this {@code MessageDigest} with
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte arg0) {
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(arg0);
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code byte[]}.
188f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the first byte in {@code input} to update from
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes in {@code input} to update from
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset} or {@code len} are not valid in respect to
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code input}
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte[] input, int offset, int len) {
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null ||
2012f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        // offset < 0 || len < 0 ||
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // checks for negative values are commented out intentionally
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // see HARMONY-1120 for details
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                (long) offset + (long) len > input.length) {
205897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input, offset, len);
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code byte[]}.
212f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code input} is {@code null}
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte[] input) {
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null) {
22086acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("input == null");
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input, 0, input.length);
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes and returns the final hash value for this {@link MessageDigest}.
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * After the digest is computed the receiver is reset.
228f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the computed one way hash value
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] digest() {
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return engineDigest();
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes and stores the final hash value for this {@link MessageDigest}.
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * After the digest is computed the receiver is reset.
239f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buf
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer to store the result
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the first byte in {@code buf} to store
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes allocated for the digest
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of bytes written to {@code buf}
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws DigestException
24879f07cc86be9abc27d0da7df3245ba4bab809ae6Elliott Hughes     *             if an error occurs
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset} or {@code len} are not valid in respect to
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code buf}
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int digest(byte[] buf, int offset, int len) throws DigestException {
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (buf == null ||
2562f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        // offset < 0 || len < 0 ||
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // checks for negative values are commented out intentionally
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // see HARMONY-1148 for details
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                (long) offset + (long) len > buf.length) {
260897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return engineDigest(buf, offset, len);
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Performs the final update and then computes and returns the final hash
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value for this {@link MessageDigest}. After the digest is computed the
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * receiver is reset.
269f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the computed one way hash value
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] digest(byte[] input) {
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        update(input);
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return digest();
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable description of this
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code MessageDigest} including the name of its algorithm.
283f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a printable representation for this {@code MessageDigest}
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2862f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
288f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return "MESSAGE DIGEST " + algorithm;
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates whether to digest are equal by performing a simply
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * byte-per-byte compare of the two digests.
294f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param digesta
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the first digest to be compared
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param digestb
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the second digest to be compared
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the two hashes are equal, {@code false} otherwise
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static boolean isEqual(byte[] digesta, byte[] digestb) {
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (digesta.length != digestb.length) {
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < digesta.length; i++) {
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (digesta[i] != digestb[i]) {
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the name of the algorithm of this {@code MessageDigest}.
315f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the name of the algorithm of this {@code MessageDigest}
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final String getAlgorithm() {
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return algorithm;
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the provider associated with this {@code MessageDigest}.
324f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the provider associated with this {@code MessageDigest}
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Provider getProvider() {
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return provider;
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the engine digest length in bytes. If the implementation does not
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implement this function or is not an instance of {@code Cloneable},
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code 0} is returned.
335f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the digest length in bytes, or {@code 0}
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int getDigestLength() {
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int l = engineGetDigestLength();
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (l != 0) {
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return l;
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(this instanceof Cloneable)) {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            MessageDigest md = (MessageDigest) clone();
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return md.digest().length;
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (CloneNotSupportedException e) {
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3542f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object clone() throws CloneNotSupportedException {
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this instanceof Cloneable) {
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return super.clone();
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
3592f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        throw new CloneNotSupportedException();
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code input}.
364f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code ByteBuffer}
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void update(ByteBuffer input) {
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input);
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
373f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The internal MessageDigest implementation
375f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class MessageDigestImpl extends MessageDigest {
3782f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // MessageDigestSpi implementation
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private MessageDigestSpi spiImpl;
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // MessageDigestImpl ctor
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private MessageDigestImpl(MessageDigestSpi messageDigestSpi,
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Provider provider, String algorithm) {
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(algorithm);
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super.provider = provider;
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl = messageDigestSpi;
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineReset() implementation
3912f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineReset() {
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineReset();
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineDigest() implementation
3972f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected byte[] engineDigest() {
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return spiImpl.engineDigest();
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineGetDigestLength() implementation
4032f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected int engineGetDigestLength() {
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return spiImpl.engineGetDigestLength();
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineUpdate() implementation
4092f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineUpdate(byte arg0) {
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(arg0);
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineUpdate() implementation
4152f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineUpdate(byte[] arg0, int arg1, int arg2) {
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(arg0, arg1, arg2);
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Returns a clone if the spiImpl is cloneable
4212f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object clone() throws CloneNotSupportedException {
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (spiImpl instanceof Cloneable) {
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                MessageDigestSpi spi = (MessageDigestSpi) spiImpl.clone();
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return new MessageDigestImpl(spi, getProvider(), getAlgorithm());
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
427f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
4282f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            throw new CloneNotSupportedException();
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
432