2 // System.Security.Cryptography HashAlgorithm Class implementation
5 // Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
6 // Sebastien Pouliot (spouliot@motus.com)
8 // Copyright 2001 by Matthew S. Ford.
9 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
11 // Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
12 // support of Npgsql MD5 authentication in platforms which don't have support for MD5 algorithm.
21 // Comment: Removed the ICryptoTransform implementation as this interface may be not supported by
24 internal abstract class HashAlgorithm : IDisposable
26 protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.
27 protected int HashSizeValue; // The size of the hash in bits.
28 protected int State; // nonzero when in use; zero when not in use
29 private bool disposed;
32 /// Called from constructor of derived class.
34 protected HashAlgorithm()
40 /// Finalizer for HashAlgorithm
48 /// Get whether or not the hash can transform multiple blocks at a time.
49 /// Note: MUST be overriden if descendant can transform multiple block
52 public virtual bool CanTransformMultipleBlocks
57 public virtual bool CanReuseTransform
64 // same as System.IDisposable.Dispose() which is documented
69 /// Computes the entire hash of all the bytes in the byte array.
71 public byte[] ComputeHash(byte[] input)
73 return ComputeHash(input, 0, input.Length);
76 public byte[] ComputeHash(byte[] buffer, int offset, int count)
80 throw new ObjectDisposedException("HashAlgorithm");
83 HashCore(buffer, offset, count);
84 HashValue = HashFinal();
90 public byte[] ComputeHash(Stream inputStream)
92 // don't read stream unless object is ready to use
95 throw new ObjectDisposedException("HashAlgorithm");
98 int l = (int) (inputStream.Length - inputStream.Position);
99 byte[] buffer = new byte[l];
100 inputStream.Read(buffer, 0, l);
102 return ComputeHash(buffer, 0, l);
105 // Commented out because it uses the CryptoConfig which can't be available in all platforms
109 /// Creates the default implementation of the default hash algorithm (SHA1).
111 public static HashAlgorithm Create ()
113 return Create ("System.Security.Cryptography.HashAlgorithm");
118 /// Creates a specific implementation of the general hash idea.
120 /// <param name="hashName">Specifies which derived class to create.</param>
121 public static HashAlgorithm Create (string hashName)
123 return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
127 // Changed Exception type because it uses the CryptographicUnexpectedOperationException
128 // which can't be available in all platforms.
130 /// Gets the previously computed hash.
132 public virtual byte[] Hash
136 if (HashValue == null)
138 throw new NullReferenceException("HashValue is null");
145 /// When overridden in a derived class, drives the hashing function.
147 /// <param name="rgb"></param>
148 /// <param name="start"></param>
149 /// <param name="size"></param>
150 protected abstract void HashCore(byte[] rgb, int start, int size);
153 /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
155 protected abstract byte[] HashFinal();
158 /// Returns the size in bits of the hash.
160 public virtual int HashSize
162 get { return HashSizeValue; }
166 /// When overridden in a derived class, initializes the object to prepare for hashing.
168 public abstract void Initialize();
170 protected virtual void Dispose(bool disposing)
176 /// Must be overriden if not 1
178 public virtual int InputBlockSize
184 /// Must be overriden if not 1
186 public virtual int OutputBlockSize
191 void IDisposable.Dispose()
194 GC.SuppressFinalize(this); // Finalization is now unnecessary
198 /// Used for stream chaining. Computes hash as data passes through it.
200 /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
201 /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
202 /// <param name="inputCount">The number of bytes to be copied.</param>
203 /// <param name="outputBuffer">The buffer to write the copied data to.</param>
204 /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
205 public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
207 Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
208 HashCore(inputBuffer, inputOffset, inputCount);
214 /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
216 /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
217 /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
218 /// <param name="inputCount">The number of bytes to be copied.</param>
219 public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
221 byte[] outputBuffer = new byte[inputCount];
223 Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, 0, inputCount);
225 HashCore(inputBuffer, inputOffset, inputCount);
226 HashValue = HashFinal();