MessageDigest.java revision 897538a36c18f4db8f9f68ee566aec0bda842e9f
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 Project
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.fortress.Engine;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code MessageDigest} is an engine class which is capable of generating one
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * way hash values for arbitrary input, utilizing the algorithm it was
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialized with.
282f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes *
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see MessageDigestSpi
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class MessageDigest extends MessageDigestSpi {
322f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The service name
34f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    private static final String SERVICE = "MessageDigest";
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Used to access common engine functionality
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static Engine engine = new Engine(SERVICE);
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The provider
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Provider provider;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The algorithm.
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String algorithm;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new instance of {@code MessageDigest} with the name of
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the algorithm to use.
48f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of algorithm to use
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected MessageDigest(String algorithm) {
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.algorithm = algorithm;
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code MessageDigest} that utilizes the
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified algorithm.
59f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the algorithm to use
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code MessageDigest} that utilizes the
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified algorithm
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not available
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code algorithm} is {@code null}
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static MessageDigest getInstance(String algorithm)
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException {
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
72897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException();
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        MessageDigest result;
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (engine) {
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            engine.getInstance(algorithm, null);
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (engine.spi instanceof MessageDigest) {
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = (MessageDigest) engine.spi;
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.algorithm = algorithm;
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.provider = engine.provider;
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return result;
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
832f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            return new MessageDigestImpl((MessageDigestSpi) engine.spi,
842f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                    engine.provider, algorithm);
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code MessageDigest} that utilizes the
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified algorithm from the specified provider.
91f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the algorithm to use
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the provider
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code MessageDigest} that utilizes the
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified algorithm from the specified provider
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not available
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchProviderException
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified provider is not available
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code algorithm} is {@code null}
104897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes     * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()}
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static MessageDigest getInstance(String algorithm, String provider)
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException, NoSuchProviderException {
108897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes        if (provider == null || provider.isEmpty()) {
109897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Provider p = Security.getProvider(provider);
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (p == null) {
113897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NoSuchProviderException(provider);
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getInstance(algorithm, p);
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a new instance of {@code MessageDigest} that utilizes the
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified algorithm from the specified provider.
121f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the algorithm to use
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the provider
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a new instance of {@code MessageDigest} that utilizes the
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         specified algorithm from the specified provider
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not available
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code algorithm} is {@code null}
132897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes     * @throws IllegalArgumentException if {@code provider == null}
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static MessageDigest getInstance(String algorithm, Provider provider)
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException {
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (provider == null) {
137897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
140897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException();
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        MessageDigest result;
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (engine) {
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            engine.getInstance(algorithm, provider, null);
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (engine.spi instanceof MessageDigest) {
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result = (MessageDigest) engine.spi;
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.algorithm = algorithm;
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                result.provider = provider;
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return result;
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1512f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            result = new MessageDigestImpl((MessageDigestSpi) engine.spi,
1522f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes                    provider, algorithm);
1532f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            return result;
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Puts this {@code MessageDigest} back in an initial state, such that it is
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ready to compute a one way hash value.
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void reset() {
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineReset();
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code byte}.
167f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param arg0
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} to update this {@code MessageDigest} with
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte arg0) {
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(arg0);
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 input
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the first byte in {@code input} to update from
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes in {@code input} to update from
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset} or {@code len} are not valid in respect to
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code input}
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte[] input, int offset, int len) {
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null ||
1912f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        // offset < 0 || len < 0 ||
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // checks for negative values are commented out intentionally
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // see HARMONY-1120 for details
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                (long) offset + (long) len > input.length) {
195897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input, offset, len);
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code byte[]}.
202f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code input} is {@code null}
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void update(byte[] input) {
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null) {
210897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new NullPointerException();
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input, 0, input.length);
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes and returns the final hash value for this {@link MessageDigest}.
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * After the digest is computed the receiver is reset.
218f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the computed one way hash value
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] digest() {
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return engineDigest();
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes and stores 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     * @param buf
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer to store the result
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the first byte in {@code buf} to store
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes allocated for the digest
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of bytes written to {@code buf}
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws DigestException
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occures
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset} or {@code len} are not valid in respect to
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code buf}
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int digest(byte[] buf, int offset, int len) throws DigestException {
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (buf == null ||
2462f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        // offset < 0 || len < 0 ||
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // checks for negative values are commented out intentionally
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // see HARMONY-1148 for details
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                (long) offset + (long) len > buf.length) {
250897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes            throw new IllegalArgumentException();
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return engineDigest(buf, offset, len);
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Performs the final update and then computes and returns the final hash
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value for this {@link MessageDigest}. After the digest is computed the
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * receiver is reset.
259f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code byte} array
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the computed one way hash value
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #reset()
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] digest(byte[] input) {
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        update(input);
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return digest();
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string containing a concise, human-readable description of this
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code MessageDigest} including the name of its algorithm.
273f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a printable representation for this {@code MessageDigest}
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2762f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
278f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return "MESSAGE DIGEST " + algorithm;
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates whether to digest are equal by performing a simply
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * byte-per-byte compare of the two digests.
284f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param digesta
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the first digest to be compared
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param digestb
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the second digest to be compared
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the two hashes are equal, {@code false} otherwise
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static boolean isEqual(byte[] digesta, byte[] digestb) {
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (digesta.length != digestb.length) {
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i = 0; i < digesta.length; i++) {
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (digesta[i] != digestb[i]) {
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the name of the algorithm of this {@code MessageDigest}.
305f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the name of the algorithm of this {@code MessageDigest}
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final String getAlgorithm() {
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return algorithm;
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the provider associated with this {@code MessageDigest}.
314f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the provider associated with this {@code MessageDigest}
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Provider getProvider() {
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return provider;
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the engine digest length in bytes. If the implementation does not
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implement this function or is not an instance of {@code Cloneable},
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code 0} is returned.
325f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the digest length in bytes, or {@code 0}
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int getDigestLength() {
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int l = engineGetDigestLength();
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (l != 0) {
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return l;
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(this instanceof Cloneable)) {
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            MessageDigest md = (MessageDigest) clone();
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return md.digest().length;
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (CloneNotSupportedException e) {
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
3442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes    @Override
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object clone() throws CloneNotSupportedException {
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this instanceof Cloneable) {
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return super.clone();
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
3492f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        throw new CloneNotSupportedException();
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code MessageDigest} using the given {@code input}.
354f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the {@code ByteBuffer}
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void update(ByteBuffer input) {
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        engineUpdate(input);
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
363f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The internal MessageDigest implementation
365f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class MessageDigestImpl extends MessageDigest {
3682f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // MessageDigestSpi implementation
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private MessageDigestSpi spiImpl;
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // MessageDigestImpl ctor
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private MessageDigestImpl(MessageDigestSpi messageDigestSpi,
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Provider provider, String algorithm) {
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(algorithm);
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super.provider = provider;
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl = messageDigestSpi;
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineReset() implementation
3812f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineReset() {
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineReset();
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineDigest() implementation
3872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected byte[] engineDigest() {
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return spiImpl.engineDigest();
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineGetDigestLength() implementation
3932f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected int engineGetDigestLength() {
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return spiImpl.engineGetDigestLength();
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineUpdate() implementation
3992f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineUpdate(byte arg0) {
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(arg0);
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // engineUpdate() implementation
4052f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected void engineUpdate(byte[] arg0, int arg1, int arg2) {
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(arg0, arg1, arg2);
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Returns a clone if the spiImpl is cloneable
4112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        @Override
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public Object clone() throws CloneNotSupportedException {
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (spiImpl instanceof Cloneable) {
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                MessageDigestSpi spi = (MessageDigestSpi) spiImpl.clone();
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return new MessageDigestImpl(spi, getProvider(), getAlgorithm());
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
417f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
4182f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes            throw new CloneNotSupportedException();
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
422