Frames | No Frames |
1: /* BaseHash.java -- 2: Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. 3: 4: This file is a part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2 of the License, or (at 9: your option) any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; if not, write to the Free Software 18: Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 19: USA 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package gnu.java.security.hash; 40: 41: /** 42: * A base abstract class to facilitate hash implementations. 43: */ 44: public abstract class BaseHash 45: implements IMessageDigest 46: { 47: /** The canonical name prefix of the hash. */ 48: protected String name; 49: 50: /** The hash (output) size in bytes. */ 51: protected int hashSize; 52: 53: /** The hash (inner) block size in bytes. */ 54: protected int blockSize; 55: 56: /** Number of bytes processed so far. */ 57: protected long count; 58: 59: /** Temporary input buffer. */ 60: protected byte[] buffer; 61: 62: /** 63: * Trivial constructor for use by concrete subclasses. 64: * 65: * @param name the canonical name prefix of this instance. 66: * @param hashSize the block size of the output in bytes. 67: * @param blockSize the block size of the internal transform. 68: */ 69: protected BaseHash(String name, int hashSize, int blockSize) 70: { 71: super(); 72: 73: this.name = name; 74: this.hashSize = hashSize; 75: this.blockSize = blockSize; 76: this.buffer = new byte[blockSize]; 77: 78: resetContext(); 79: } 80: 81: public String name() 82: { 83: return name; 84: } 85: 86: public int hashSize() 87: { 88: return hashSize; 89: } 90: 91: public int blockSize() 92: { 93: return blockSize; 94: } 95: 96: public void update(byte b) 97: { 98: // compute number of bytes still unhashed; ie. present in buffer 99: int i = (int) (count % blockSize); 100: count++; 101: buffer[i] = b; 102: if (i == (blockSize - 1)) 103: transform(buffer, 0); 104: } 105: 106: public void update(byte[] b) 107: { 108: update(b, 0, b.length); 109: } 110: 111: public void update(byte[] b, int offset, int len) 112: { 113: int n = (int) (count % blockSize); 114: count += len; 115: int partLen = blockSize - n; 116: int i = 0; 117: 118: if (len >= partLen) 119: { 120: System.arraycopy(b, offset, buffer, n, partLen); 121: transform(buffer, 0); 122: for (i = partLen; i + blockSize - 1 < len; i += blockSize) 123: transform(b, offset + i); 124: 125: n = 0; 126: } 127: 128: if (i < len) 129: System.arraycopy(b, offset + i, buffer, n, len - i); 130: } 131: 132: public byte[] digest() 133: { 134: byte[] tail = padBuffer(); // pad remaining bytes in buffer 135: update(tail, 0, tail.length); // last transform of a message 136: byte[] result = getResult(); // make a result out of context 137: 138: reset(); // reset this instance for future re-use 139: 140: return result; 141: } 142: 143: public void reset() 144: { // reset this instance for future re-use 145: count = 0L; 146: for (int i = 0; i < blockSize;) 147: buffer[i++] = 0; 148: 149: resetContext(); 150: } 151: 152: public abstract Object clone(); 153: 154: public abstract boolean selfTest(); 155: 156: /** 157: * Returns the byte array to use as padding before completing a hash 158: * operation. 159: * 160: * @return the bytes to pad the remaining bytes in the buffer before 161: * completing a hash operation. 162: */ 163: protected abstract byte[] padBuffer(); 164: 165: /** 166: * Constructs the result from the contents of the current context. 167: * 168: * @return the output of the completed hash operation. 169: */ 170: protected abstract byte[] getResult(); 171: 172: /** Resets the instance for future re-use. */ 173: protected abstract void resetContext(); 174: 175: /** 176: * The block digest transformation per se. 177: * 178: * @param in the <i>blockSize</i> long block, as an array of bytes to digest. 179: * @param offset the index where the data to digest is located within the 180: * input buffer. 181: */ 182: protected abstract void transform(byte[] in, int offset); 183: }