namespace com.hitrust.Security.Cryptography
|
|
{
|
|
using System;
|
|
using System.Security.Cryptography;
|
|
|
|
internal sealed class ARCFourManagedTransform : ICryptoTransform, IDisposable
|
|
{
|
|
private bool m_Disposed;
|
|
private byte m_Index1;
|
|
private byte m_Index2;
|
|
private byte[] m_Key;
|
|
private int m_KeyLen;
|
|
private byte[] m_Permutation;
|
|
|
|
public ARCFourManagedTransform(byte[] key)
|
|
{
|
|
this.m_Key = (byte[]) key.Clone();
|
|
this.m_KeyLen = key.Length;
|
|
this.m_Permutation = new byte[0x100];
|
|
this.m_Disposed = false;
|
|
this.Init();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Array.Clear(this.m_Key, 0, this.m_Key.Length);
|
|
Array.Clear(this.m_Permutation, 0, this.m_Permutation.Length);
|
|
this.m_Index1 = 0;
|
|
this.m_Index2 = 0;
|
|
this.m_Disposed = true;
|
|
try
|
|
{
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
~ARCFourManagedTransform()
|
|
{
|
|
this.Dispose();
|
|
}
|
|
|
|
private void Init()
|
|
{
|
|
for (int i = 0; i < 0x100; i++)
|
|
{
|
|
this.m_Permutation[i] = (byte) i;
|
|
}
|
|
this.m_Index1 = 0;
|
|
this.m_Index2 = 0;
|
|
int index = 0;
|
|
for (int j = 0; j < 0x100; j++)
|
|
{
|
|
index = ((index + this.m_Permutation[j]) + this.m_Key[j % this.m_KeyLen]) % 0x100;
|
|
byte num = this.m_Permutation[j];
|
|
this.m_Permutation[j] = this.m_Permutation[index];
|
|
this.m_Permutation[index] = num;
|
|
}
|
|
}
|
|
|
|
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
|
|
{
|
|
if (this.m_Disposed)
|
|
{
|
|
throw new ObjectDisposedException(base.GetType().FullName);
|
|
}
|
|
if ((inputBuffer == null) || (outputBuffer == null))
|
|
{
|
|
throw new ArgumentNullException();
|
|
}
|
|
if (((inputOffset < 0) || (outputOffset < 0)) || (((inputOffset + inputCount) > inputBuffer.Length) || ((outputOffset + inputCount) > outputBuffer.Length)))
|
|
{
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
int num3 = inputOffset + inputCount;
|
|
while (inputOffset < num3)
|
|
{
|
|
this.m_Index1 = (byte) ((this.m_Index1 + 1) % 0x100);
|
|
this.m_Index2 = (byte) ((this.m_Index2 + this.m_Permutation[this.m_Index1]) % 0x100);
|
|
byte num2 = this.m_Permutation[this.m_Index1];
|
|
this.m_Permutation[this.m_Index1] = this.m_Permutation[this.m_Index2];
|
|
this.m_Permutation[this.m_Index2] = num2;
|
|
byte index = (byte) ((this.m_Permutation[this.m_Index1] + this.m_Permutation[this.m_Index2]) % 0x100);
|
|
outputBuffer[outputOffset] = (byte) (inputBuffer[inputOffset] ^ this.m_Permutation[index]);
|
|
inputOffset++;
|
|
outputOffset++;
|
|
}
|
|
return inputCount;
|
|
}
|
|
|
|
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
|
|
{
|
|
if (this.m_Disposed)
|
|
{
|
|
throw new ObjectDisposedException(base.GetType().FullName);
|
|
}
|
|
byte[] outputBuffer = new byte[inputCount];
|
|
this.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, 0);
|
|
this.Init();
|
|
return outputBuffer;
|
|
}
|
|
|
|
public bool CanReuseTransform
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public bool CanTransformMultipleBlocks
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public int InputBlockSize
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public int OutputBlockSize
|
|
{
|
|
get
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|