You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

126 lines
3.9 KiB

namespace com.hitrust.Security.Cryptography
{
using System;
using System.Security.Cryptography;
public sealed class HMAC : KeyedHashAlgorithm
{
private HashAlgorithm m_HashAlgorithm;
private bool m_IsDisposed;
private bool m_IsHashing;
private byte[] m_KeyBuffer;
public HMAC(HashAlgorithm hash) : this(hash, null)
{
}
public HMAC(HashAlgorithm hash, byte[] rgbKey)
{
if (hash == null)
{
throw new ArgumentNullException();
}
if (rgbKey == null)
{
rgbKey = new byte[hash.HashSize / 8];
new RNGCryptoServiceProvider().GetBytes(rgbKey);
}
this.m_HashAlgorithm = hash;
this.Key = (byte[]) rgbKey.Clone();
this.m_IsDisposed = false;
this.Initialize();
}
protected override void Dispose(bool disposing)
{
this.m_IsDisposed = true;
base.Dispose(true);
this.m_HashAlgorithm.Clear();
try
{
GC.SuppressFinalize(this);
}
catch
{
}
}
~HMAC()
{
this.m_HashAlgorithm.Clear();
}
protected override void HashCore(byte[] rgb, int ib, int cb)
{
if (this.m_IsDisposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (!this.m_IsHashing)
{
byte[] key;
this.m_KeyBuffer = new byte[0x40];
byte[] padded = new byte[0x40];
if (this.Key.Length > 0x40)
{
key = this.m_HashAlgorithm.ComputeHash(this.Key);
}
else
{
key = this.Key;
}
Array.Copy(key, 0, this.m_KeyBuffer, 0, key.Length);
for (int i = 0; i < 0x40; i++)
{
padded[i] = (byte) (this.m_KeyBuffer[i] ^ 0x36);
}
this.m_HashAlgorithm.TransformBlock(padded, 0, padded.Length, padded, 0);
this.m_IsHashing = true;
}
this.m_HashAlgorithm.TransformBlock(rgb, ib, cb, rgb, ib);
}
protected override byte[] HashFinal()
{
if (this.m_IsDisposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
this.m_HashAlgorithm.TransformFinalBlock(new byte[0], 0, 0);
byte[] dataHash = this.m_HashAlgorithm.Hash;
byte[] padded = new byte[0x40];
for (int i = 0; i < 0x40; i++)
{
padded[i] = (byte) (this.m_KeyBuffer[i] ^ 0x5c);
}
this.m_HashAlgorithm.Initialize();
this.m_HashAlgorithm.TransformBlock(padded, 0, padded.Length, padded, 0);
this.m_HashAlgorithm.TransformFinalBlock(dataHash, 0, dataHash.Length);
dataHash = this.m_HashAlgorithm.Hash;
Array.Clear(this.m_KeyBuffer, 0, this.m_KeyBuffer.Length);
this.m_KeyBuffer = null;
this.m_IsHashing = false;
return dataHash;
}
public override void Initialize()
{
if (this.m_IsDisposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
this.m_HashAlgorithm.Initialize();
this.m_IsHashing = false;
base.State = 0;
}
public override int HashSize
{
get
{
return this.m_HashAlgorithm.HashSize;
}
}
}
}