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 Project/** 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code MessageDigestSpi} is the Service Provider Interface (SPI) definition 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for {@link MessageDigest}. Examples of digest algorithms are MD5 and SHA. A 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * digest is a secure one way hash function for a stream of bytes. It acts like 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a fingerprint for a stream of bytes. 27f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see MessageDigest 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class MessageDigestSpi { 31f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the engine digest length in bytes. If the implementation does not 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implement this function {@code 0} is returned. 35f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the digest length in bytes, or {@code 0}. 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected int engineGetDigestLength() { 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 41f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Updates this {@code MessageDigestSpi} using the given {@code byte}. 44f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code byte} to update this {@code MessageDigestSpi} with. 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #engineReset() 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void engineUpdate(byte input); 50f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Updates this {@code MessageDigestSpi} using the given {@code byte[]}. 53f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code byte} array. 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the index of the first byte in {@code input} to update from. 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param len 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes in {@code input} to update from. 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset} or {@code len} are not valid in respect to 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code input}. 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void engineUpdate(byte[] input, int offset, int len); 65f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Updates this {@code MessageDigestSpi} using the given {@code input}. 68f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the {@code ByteBuffer}. 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected void engineUpdate(ByteBuffer input) { 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!input.hasRemaining()) { 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] tmp; 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input.hasArray()) { 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project tmp = input.array(); 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int offset = input.arrayOffset(); 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int position = input.position(); 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int limit = input.limit(); 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineUpdate(tmp, offset+position, limit - position); 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project input.position(limit); 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project tmp = new byte[input.limit() - input.position()]; 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project input.get(tmp); 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineUpdate(tmp, 0, tmp.length); 88f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes } 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 90f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Computes and returns the final hash value for this 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link MessageDigestSpi}. After the digest is computed the receiver is 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reset. 95f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the computed one way hash value. 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #engineReset() 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract byte[] engineDigest(); 100f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Computes and stores the final hash value for this 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link MessageDigestSpi}. After the digest is computed the receiver is 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reset. 105f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buf 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the buffer to store the result in. 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the index of the first byte in {@code buf} to store in. 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param len 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes allocated for the digest. 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes written to {@code buf}. 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws DigestException 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occures. 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset} or {@code len} are not valid in respect to 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buf}. 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #engineReset() 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 120897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes protected int engineDigest(byte[] buf, int offset, int len) throws DigestException { 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (len < engineGetDigestLength()) { 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineReset(); 123897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new DigestException("The value of len parameter is less than the actual digest length"); 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset < 0) { 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineReset(); 127897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new DigestException("offset < 0"); 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (offset + len > buf.length) { 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engineReset(); 131897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new DigestException("offset + len > buf.length"); 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133171dc20afe5071d5cbfad7103903bfa2c1f8d00fElliott Hughes byte[] tmp = engineDigest(); 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (len < tmp.length) { 135897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new DigestException("The value of len parameter is less than the actual digest length"); 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(tmp, 0, buf, offset, tmp.length); 138f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes return tmp.length; 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 140f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Puts this {@code MessageDigestSpi} back in an initial state, such that it 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is ready to compute a one way hash value. 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void engineReset(); 146f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 1472f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Object clone() throws CloneNotSupportedException { 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return super.clone(); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 152