// Sebastien Pouliot (sebastien@ximian.com)
//
// Copyright 2001 by Matthew S. Ford.
-// (C) 2004 Novell (http://www.novell.com)
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004, 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// Mono must provide those two class for binary compatibility.
// In our case both class are wrappers around a managed internal class SHA1Internal.
+using System.Runtime.InteropServices;
+
namespace System.Security.Cryptography {
internal class SHA1Internal {
private const int BLOCK_SIZE_BYTES = 64;
private const int HASH_SIZE_BYTES = 20;
private uint[] _H; // these are my chaining variables
- private uint count;
+ private ulong count;
private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
+ private uint[] buff;
public SHA1Internal ()
{
_H = new uint[5];
_ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
+ buff = new uint[80];
Initialize();
}
private void ProcessBlock(byte[] inputBuffer, int inputOffset)
{
- uint[] buff = new uint[80];
uint a, b, c, d, e;
int i;
private void ProcessFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
{
- int i;
- int paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
+ ulong total = count + (ulong)inputCount;
+ int paddingSize = (56 - (int)(total % BLOCK_SIZE_BYTES));
if (paddingSize < 1)
paddingSize += BLOCK_SIZE_BYTES;
byte[] fooBuffer = new byte[inputCount+paddingSize+8];
- for (i=0; i<inputCount; i++) {
+ for (int i=0; i<inputCount; i++) {
fooBuffer[i] = inputBuffer[i+inputOffset];
}
fooBuffer[inputCount] = 0x80;
- for (i=inputCount+1; i<inputCount+paddingSize; i++) {
+ for (int i=inputCount+1; i<inputCount+paddingSize; i++) {
fooBuffer[i] = 0x00;
}
// I deal in bytes. The algorithm deals in bits.
- uint size = (uint)((count+inputCount) << 3);
-
- fooBuffer[inputCount+paddingSize] = 0x00;
- fooBuffer[inputCount+paddingSize+1] = 0x00;
- fooBuffer[inputCount+paddingSize+2] = 0x00;
- fooBuffer[inputCount+paddingSize+3] = 0x00;
-
- fooBuffer[inputCount+paddingSize+4] = (byte)((size) >> 24);
- fooBuffer[inputCount+paddingSize+5] = (byte)((size) >> 16);
- fooBuffer[inputCount+paddingSize+6] = (byte)((size) >> 8);
- fooBuffer[inputCount+paddingSize+7] = (byte)((size) >> 0);
-
- ProcessBlock(fooBuffer, 0);
+ ulong size = total << 3;
+ AddLength (size, fooBuffer, inputCount+paddingSize);
+ ProcessBlock (fooBuffer, 0);
if (inputCount+paddingSize+8 == 128) {
ProcessBlock(fooBuffer, 64);
}
}
+
+ internal void AddLength (ulong length, byte[] buffer, int position)
+ {
+ buffer [position++] = (byte)(length >> 56);
+ buffer [position++] = (byte)(length >> 48);
+ buffer [position++] = (byte)(length >> 40);
+ buffer [position++] = (byte)(length >> 32);
+ buffer [position++] = (byte)(length >> 24);
+ buffer [position++] = (byte)(length >> 16);
+ buffer [position++] = (byte)(length >> 8);
+ buffer [position] = (byte)(length);
+ }
}
+#if NET_2_0
+ [ComVisible (true)]
+#endif
public sealed class SHA1CryptoServiceProvider : SHA1 {
private SHA1Internal sha;