2 // System.Security.Cryptography SHA1CryptoServiceProvider Class implementation
5 // Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
6 // Sebastien Pouliot (sebastien@ximian.com)
8 // Copyright 2001 by Matthew S. Ford.
9 // Copyright (C) 2004, 2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 // The MS Framework includes two (almost) identical class for SHA1.
33 // SHA1Managed is a 100% managed implementation.
34 // SHA1CryptoServiceProvider (this file) is a wrapper on CryptoAPI.
35 // Mono must provide those two class for binary compatibility.
36 // In our case both class are wrappers around a managed internal class SHA1Internal.
38 using System.Runtime.InteropServices;
40 namespace System.Security.Cryptography {
42 internal class SHA1Internal {
44 private const int BLOCK_SIZE_BYTES = 64;
45 private const int HASH_SIZE_BYTES = 20;
46 private uint[] _H; // these are my chaining variables
48 private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
49 private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
52 public SHA1Internal ()
55 _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
61 public void HashCore (byte[] rgb, int start, int size)
65 if (_ProcessingBufferCount != 0) {
66 if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
67 System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
68 _ProcessingBufferCount += size;
72 i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
73 System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
74 ProcessBlock (_ProcessingBuffer, 0);
75 _ProcessingBufferCount = 0;
81 for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
82 ProcessBlock (rgb, start+i);
85 if (size%BLOCK_SIZE_BYTES != 0) {
86 System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
87 _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
91 public byte[] HashFinal ()
93 byte[] hash = new byte[20];
95 ProcessFinalBlock (_ProcessingBuffer, 0, _ProcessingBufferCount);
97 for (int i=0; i<5; i++) {
98 for (int j=0; j<4; j++) {
99 hash [i*4+j] = (byte)(_H[i] >> (8*(3-j)));
106 public void Initialize ()
109 _ProcessingBufferCount = 0;
118 private void ProcessBlock(byte[] inputBuffer, int inputOffset)
123 count += BLOCK_SIZE_BYTES;
125 for (i=0; i<16; i++) {
126 buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)
127 | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)
128 | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)
129 | ((uint)(inputBuffer[inputOffset+4*i+3]));
132 for (i=16; i<80; i++) {
133 buff[i] = ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) << 1)
134 | ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) >> 31);
143 // This function was unrolled because it seems to be doubling our performance with current compiler/VM.
144 // Possibly roll up if this changes.
146 // ---- Round 1 --------
148 e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[0];
149 b = (b << 30) | (b >> 2);
151 d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[1];
152 a = (a << 30) | (a >> 2);
154 c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[2];
155 e = (e << 30) | (e >> 2);
157 b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[3];
158 d = (d << 30) | (d >> 2);
160 a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[4];
161 c = (c << 30) | (c >> 2);
163 e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[5];
164 b = (b << 30) | (b >> 2);
166 d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[6];
167 a = (a << 30) | (a >> 2);
169 c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[7];
170 e = (e << 30) | (e >> 2);
172 b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[8];
173 d = (d << 30) | (d >> 2);
175 a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[9];
176 c = (c << 30) | (c >> 2);
178 e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[10];
179 b = (b << 30) | (b >> 2);
181 d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[11];
182 a = (a << 30) | (a >> 2);
184 c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[12];
185 e = (e << 30) | (e >> 2);
187 b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[13];
188 d = (d << 30) | (d >> 2);
190 a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[14];
191 c = (c << 30) | (c >> 2);
193 e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[15];
194 b = (b << 30) | (b >> 2);
196 d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[16];
197 a = (a << 30) | (a >> 2);
199 c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[17];
200 e = (e << 30) | (e >> 2);
202 b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[18];
203 d = (d << 30) | (d >> 2);
205 a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[19];
206 c = (c << 30) | (c >> 2);
208 // ---- Round 2 --------
210 e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[20];
211 b = (b << 30) | (b >> 2);
213 d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[21];
214 a = (a << 30) | (a >> 2);
216 c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[22];
217 e = (e << 30) | (e >> 2);
219 b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[23];
220 d = (d << 30) | (d >> 2);
222 a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[24];
223 c = (c << 30) | (c >> 2);
225 e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[25];
226 b = (b << 30) | (b >> 2);
228 d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[26];
229 a = (a << 30) | (a >> 2);
231 c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[27];
232 e = (e << 30) | (e >> 2);
234 b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[28];
235 d = (d << 30) | (d >> 2);
237 a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[29];
238 c = (c << 30) | (c >> 2);
240 e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[30];
241 b = (b << 30) | (b >> 2);
243 d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[31];
244 a = (a << 30) | (a >> 2);
246 c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[32];
247 e = (e << 30) | (e >> 2);
249 b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[33];
250 d = (d << 30) | (d >> 2);
252 a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[34];
253 c = (c << 30) | (c >> 2);
255 e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[35];
256 b = (b << 30) | (b >> 2);
258 d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[36];
259 a = (a << 30) | (a >> 2);
261 c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[37];
262 e = (e << 30) | (e >> 2);
264 b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[38];
265 d = (d << 30) | (d >> 2);
267 a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[39];
268 c = (c << 30) | (c >> 2);
270 // ---- Round 3 --------
272 e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[40];
273 b = (b << 30) | (b >> 2);
275 d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[41];
276 a = (a << 30) | (a >> 2);
278 c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[42];
279 e = (e << 30) | (e >> 2);
281 b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[43];
282 d = (d << 30) | (d >> 2);
284 a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[44];
285 c = (c << 30) | (c >> 2);
287 e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[45];
288 b = (b << 30) | (b >> 2);
290 d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[46];
291 a = (a << 30) | (a >> 2);
293 c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[47];
294 e = (e << 30) | (e >> 2);
296 b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[48];
297 d = (d << 30) | (d >> 2);
299 a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[49];
300 c = (c << 30) | (c >> 2);
302 e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[50];
303 b = (b << 30) | (b >> 2);
305 d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[51];
306 a = (a << 30) | (a >> 2);
308 c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[52];
309 e = (e << 30) | (e >> 2);
311 b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[53];
312 d = (d << 30) | (d >> 2);
314 a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[54];
315 c = (c << 30) | (c >> 2);
317 e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[55];
318 b = (b << 30) | (b >> 2);
320 d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[56];
321 a = (a << 30) | (a >> 2);
323 c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[57];
324 e = (e << 30) | (e >> 2);
326 b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[58];
327 d = (d << 30) | (d >> 2);
329 a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[59];
330 c = (c << 30) | (c >> 2);
332 // ---- Round 4 --------
334 e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[60];
335 b = (b << 30) | (b >> 2);
337 d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[61];
338 a = (a << 30) | (a >> 2);
340 c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[62];
341 e = (e << 30) | (e >> 2);
343 b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[63];
344 d = (d << 30) | (d >> 2);
346 a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[64];
347 c = (c << 30) | (c >> 2);
349 e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[65];
350 b = (b << 30) | (b >> 2);
352 d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[66];
353 a = (a << 30) | (a >> 2);
355 c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[67];
356 e = (e << 30) | (e >> 2);
358 b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[68];
359 d = (d << 30) | (d >> 2);
361 a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[69];
362 c = (c << 30) | (c >> 2);
364 e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[70];
365 b = (b << 30) | (b >> 2);
367 d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[71];
368 a = (a << 30) | (a >> 2);
370 c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[72];
371 e = (e << 30) | (e >> 2);
373 b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[73];
374 d = (d << 30) | (d >> 2);
376 a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[74];
377 c = (c << 30) | (c >> 2);
379 e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[75];
380 b = (b << 30) | (b >> 2);
382 d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[76];
383 a = (a << 30) | (a >> 2);
385 c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[77];
386 e = (e << 30) | (e >> 2);
388 b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[78];
389 d = (d << 30) | (d >> 2);
391 a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[79];
392 c = (c << 30) | (c >> 2);
402 private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
404 ulong total = count + (ulong)inputCount;
405 int paddingSize = (56 - (int)(total % BLOCK_SIZE_BYTES));
408 paddingSize += BLOCK_SIZE_BYTES;
410 byte[] fooBuffer = new byte[inputCount+paddingSize+8];
412 for (int i=0; i<inputCount; i++) {
413 fooBuffer[i] = inputBuffer[i+inputOffset];
416 fooBuffer[inputCount] = 0x80;
417 for (int i=inputCount+1; i<inputCount+paddingSize; i++) {
421 // I deal in bytes. The algorithm deals in bits.
422 ulong size = total << 3;
423 AddLength (size, fooBuffer, inputCount+paddingSize);
424 ProcessBlock (fooBuffer, 0);
426 if (inputCount+paddingSize+8 == 128) {
427 ProcessBlock(fooBuffer, 64);
431 internal void AddLength (ulong length, byte[] buffer, int position)
433 buffer [position++] = (byte)(length >> 56);
434 buffer [position++] = (byte)(length >> 48);
435 buffer [position++] = (byte)(length >> 40);
436 buffer [position++] = (byte)(length >> 32);
437 buffer [position++] = (byte)(length >> 24);
438 buffer [position++] = (byte)(length >> 16);
439 buffer [position++] = (byte)(length >> 8);
440 buffer [position] = (byte)(length);
447 public sealed class SHA1CryptoServiceProvider : SHA1 {
449 private SHA1Internal sha;
451 public SHA1CryptoServiceProvider ()
453 sha = new SHA1Internal ();
456 ~SHA1CryptoServiceProvider ()
461 protected override void Dispose (bool disposing)
463 // nothing new to do (managed implementation)
464 base.Dispose (disposing);
467 protected override void HashCore (byte[] rgb, int start, int size)
470 sha.HashCore (rgb, start, size);
473 protected override byte[] HashFinal ()
476 return sha.HashFinal ();
479 public override void Initialize ()