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