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.
24 // Comment: Removed the ICryptoTransform implementation as this interface may be not supported by
27 internal abstract class HashAlgorithm
: IDisposable
29 protected byte[] HashValue
; // Caches the hash after it is calculated. Accessed through the Hash property.
30 protected int HashSizeValue
; // The size of the hash in bits.
31 protected int State
; // nonzero when in use; zero when not in use
32 private bool disposed
;
35 /// Called from constructor of derived class.
37 protected HashAlgorithm ()
43 /// Finalizer for HashAlgorithm
51 /// Get whether or not the hash can transform multiple blocks at a time.
52 /// Note: MUST be overriden if descendant can transform multiple block
55 public virtual bool CanTransformMultipleBlocks
{
62 public virtual bool CanReuseTransform
{
71 // same as System.IDisposable.Dispose() which is documented
76 /// Computes the entire hash of all the bytes in the byte array.
78 public byte[] ComputeHash (byte[] input
)
80 return ComputeHash (input
, 0, input
.Length
);
83 public byte[] ComputeHash (byte[] buffer
, int offset
, int count
)
86 throw new ObjectDisposedException ("HashAlgorithm");
88 HashCore (buffer
, offset
, count
);
89 HashValue
= HashFinal ();
95 public byte[] ComputeHash (Stream inputStream
)
97 // don't read stream unless object is ready to use
99 throw new ObjectDisposedException ("HashAlgorithm");
101 int l
= (int) (inputStream
.Length
- inputStream
.Position
);
102 byte[] buffer
= new byte [l
];
103 inputStream
.Read (buffer
, 0, l
);
105 return ComputeHash (buffer
, 0, l
);
108 // Commented out because it uses the CryptoConfig which can't be available in all platforms
112 /// Creates the default implementation of the default hash algorithm (SHA1).
114 public static HashAlgorithm Create ()
116 return Create ("System.Security.Cryptography.HashAlgorithm");
121 /// Creates a specific implementation of the general hash idea.
123 /// <param name="hashName">Specifies which derived class to create.</param>
124 public static HashAlgorithm Create (string hashName)
126 return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
131 // Changed Exception type because it uses the CryptographicUnexpectedOperationException
132 // which can't be available in all platforms.
134 /// Gets the previously computed hash.
136 public virtual byte[] Hash
{
139 if (HashValue
== null)
140 throw new NullReferenceException("HashValue is null");
146 /// When overridden in a derived class, drives the hashing function.
148 /// <param name="rgb"></param>
149 /// <param name="start"></param>
150 /// <param name="size"></param>
151 protected abstract void HashCore (byte[] rgb
, int start
, int size
);
154 /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
156 protected abstract byte[] HashFinal ();
159 /// Returns the size in bits of the hash.
161 public virtual int HashSize
{
164 return HashSizeValue
;
169 /// When overridden in a derived class, initializes the object to prepare for hashing.
171 public abstract void Initialize ();
173 protected virtual void Dispose (bool disposing
)
179 /// Must be overriden if not 1
181 public virtual int InputBlockSize
{
189 /// Must be overriden if not 1
191 public virtual int OutputBlockSize
{
198 void IDisposable
.Dispose ()
201 GC
.SuppressFinalize (this); // Finalization is now unnecessary
205 /// Used for stream chaining. Computes hash as data passes through it.
207 /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
208 /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
209 /// <param name="inputCount">The number of bytes to be copied.</param>
210 /// <param name="outputBuffer">The buffer to write the copied data to.</param>
211 /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
212 public int TransformBlock (byte[] inputBuffer
, int inputOffset
, int inputCount
, byte[] outputBuffer
, int outputOffset
)
214 Buffer
.BlockCopy (inputBuffer
, inputOffset
, outputBuffer
, outputOffset
, inputCount
);
215 HashCore (inputBuffer
, inputOffset
, inputCount
);
221 /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
223 /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
224 /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
225 /// <param name="inputCount">The number of bytes to be copied.</param>
226 public byte[] TransformFinalBlock (byte[] inputBuffer
, int inputOffset
, int inputCount
)
228 byte[] outputBuffer
= new byte[inputCount
];
230 Buffer
.BlockCopy (inputBuffer
, inputOffset
, outputBuffer
, 0, inputCount
);
232 HashCore (inputBuffer
, inputOffset
, inputCount
);
233 HashValue
= HashFinal ();