3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // <OWNER>[....]</OWNER>
13 namespace System.Security.Cryptography {
15 using System.Diagnostics.Contracts;
17 [System.Runtime.InteropServices.ComVisible(true)]
18 public abstract class HashAlgorithm : IDisposable, ICryptoTransform {
19 protected int HashSizeValue;
20 protected internal byte[] HashValue;
21 protected int State = 0;
23 private bool m_bDisposed = false;
25 protected HashAlgorithm() {}
31 public virtual int HashSize {
32 get { return HashSizeValue; }
35 public virtual byte[] Hash {
38 throw new ObjectDisposedException(null);
40 throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_HashNotYetFinalized"));
41 return (byte[]) HashValue.Clone();
49 static public HashAlgorithm Create() {
51 return new System.Security.Cryptography.SHA1CryptoServiceProvider ();
53 return Create("System.Security.Cryptography.HashAlgorithm");
57 static public HashAlgorithm Create(String hashName) {
58 return (HashAlgorithm) CryptoConfig.CreateFromName(hashName);
61 public byte[] ComputeHash(Stream inputStream) {
63 throw new ObjectDisposedException(null);
65 // Default the buffer size to 4K.
66 byte[] buffer = new byte[4096];
69 bytesRead = inputStream.Read(buffer, 0, 4096);
71 HashCore(buffer, 0, bytesRead);
73 } while (bytesRead > 0);
75 HashValue = HashFinal();
76 byte[] Tmp = (byte[]) HashValue.Clone();
81 public byte[] ComputeHash(byte[] buffer) {
83 throw new ObjectDisposedException(null);
86 if (buffer == null) throw new ArgumentNullException("buffer");
88 HashCore(buffer, 0, buffer.Length);
89 HashValue = HashFinal();
90 byte[] Tmp = (byte[]) HashValue.Clone();
95 public byte[] ComputeHash(byte[] buffer, int offset, int count) {
98 throw new ArgumentNullException("buffer");
100 throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
101 if (count < 0 || (count > buffer.Length))
102 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
103 if ((buffer.Length - count) < offset)
104 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
105 Contract.EndContractBlock();
108 throw new ObjectDisposedException(null);
110 HashCore(buffer, offset, count);
111 HashValue = HashFinal();
112 byte[] Tmp = (byte[]) HashValue.Clone();
117 // ICryptoTransform methods
119 // we assume any HashAlgorithm can take input a byte at a time
120 public virtual int InputBlockSize {
124 public virtual int OutputBlockSize {
128 public virtual bool CanTransformMultipleBlocks {
129 get { return(true); }
132 public virtual bool CanReuseTransform {
133 get { return(true); }
136 // We implement TransformBlock and TransformFinalBlock here
137 public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
138 // Do some validation, we let BlockCopy do the destination array validation
139 if (inputBuffer == null)
140 throw new ArgumentNullException("inputBuffer");
142 throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
143 if (inputCount < 0 || (inputCount > inputBuffer.Length))
144 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
145 if ((inputBuffer.Length - inputCount) < inputOffset)
146 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
147 Contract.EndContractBlock();
150 throw new ObjectDisposedException(null);
152 // Change the State value
154 HashCore(inputBuffer, inputOffset, inputCount);
155 if ((outputBuffer != null) && ((inputBuffer != outputBuffer) || (inputOffset != outputOffset)))
156 Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
160 public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
161 // Do some validation
162 if (inputBuffer == null)
163 throw new ArgumentNullException("inputBuffer");
165 throw new ArgumentOutOfRangeException("inputOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
166 if (inputCount < 0 || (inputCount > inputBuffer.Length))
167 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"));
168 if ((inputBuffer.Length - inputCount) < inputOffset)
169 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
170 Contract.EndContractBlock();
173 throw new ObjectDisposedException(null);
175 HashCore(inputBuffer, inputOffset, inputCount);
176 HashValue = HashFinal();
180 outputBytes = new byte[inputCount];
181 Buffer.InternalBlockCopy(inputBuffer, inputOffset, outputBytes, 0, inputCount);
185 outputBytes = EmptyArray<Byte>.Value;
187 // reset the State value
192 // IDisposable methods
194 // To keep mscorlib compatibility with Orcas, CoreCLR's HashAlgorithm has an explicit IDisposable
195 // implementation. Post-Orcas the desktop has an implicit IDispoable implementation.
197 void IDisposable.Dispose()
201 #endif // FEATURE_CORECLR
203 public void Dispose()
206 GC.SuppressFinalize(this);
209 public void Clear() {
210 (this as IDisposable).Dispose();
213 protected virtual void Dispose(bool disposing) {
215 if (HashValue != null)
216 Array.Clear(HashValue, 0, HashValue.Length);
223 // abstract public methods
226 public abstract void Initialize();
228 protected abstract void HashCore(byte[] array, int ibStart, int cbSize);
230 protected abstract byte[] HashFinal();