namespace com.hitrust.Security.Cryptography
|
|
{
|
|
using com.hitrust.Security;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Cryptography;
|
|
|
|
public sealed class RijndaelCryptoServiceProvider : Rijndael
|
|
{
|
|
private bool m_Disposed;
|
|
private RijndaelManaged m_Managed;
|
|
private int m_Provider = 0;
|
|
|
|
public RijndaelCryptoServiceProvider()
|
|
{
|
|
if ((SspiProvider.CryptAcquireContext(ref this.m_Provider, IntPtr.Zero, null, 0x18, 0) == 0) && (Marshal.GetLastWin32Error() == -2146893802))
|
|
{
|
|
SspiProvider.CryptAcquireContext(ref this.m_Provider, IntPtr.Zero, null, 0x18, 8);
|
|
}
|
|
this.m_Managed = new RijndaelManaged();
|
|
}
|
|
|
|
private bool CanUseUnmanaged()
|
|
{
|
|
return this.CanUseUnmanaged(this.KeySize, this.BlockSize, this.Padding);
|
|
}
|
|
|
|
private bool CanUseUnmanaged(int keySize, int blockSize, PaddingMode padding)
|
|
{
|
|
return ((((this.m_Provider != 0) && (blockSize == 0x80)) && ((padding == PaddingMode.PKCS7) || (padding == PaddingMode.None))) && (((keySize == 0x80) || (keySize == 0xc0)) || (keySize == 0x100)));
|
|
}
|
|
|
|
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
|
|
{
|
|
if (this.m_Disposed)
|
|
{
|
|
throw new ObjectDisposedException(base.GetType().FullName);
|
|
}
|
|
if ((rgbKey == null) || (rgbIV == null))
|
|
{
|
|
throw new ArgumentNullException();
|
|
}
|
|
if (((this.Mode == CipherMode.CTS) || (this.Mode == CipherMode.OFB)) || (this.Mode == CipherMode.CFB))
|
|
{
|
|
throw new CryptographicException(this.Mode.ToString() + " is not supported by this implementation.");
|
|
}
|
|
try
|
|
{
|
|
if (this.CanUseUnmanaged(rgbKey.Length * 8, rgbIV.Length * 8, this.Padding))
|
|
{
|
|
return new RijndaelUnmanagedTransform(this.GetKeyType(rgbKey.Length * 8), CryptoMethod.Decrypt, rgbKey, rgbIV, this.Mode, this.FeedbackSize, this.Padding);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
return this.m_Managed.CreateDecryptor(rgbKey, rgbIV);
|
|
}
|
|
|
|
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
|
|
{
|
|
if (this.m_Disposed)
|
|
{
|
|
throw new ObjectDisposedException(base.GetType().FullName);
|
|
}
|
|
if ((rgbKey == null) || (rgbIV == null))
|
|
{
|
|
throw new ArgumentNullException();
|
|
}
|
|
if (((this.Mode == CipherMode.CTS) || (this.Mode == CipherMode.OFB)) || (this.Mode == CipherMode.CFB))
|
|
{
|
|
throw new CryptographicException(this.Mode.ToString() + " is not supported by this implementation.");
|
|
}
|
|
try
|
|
{
|
|
if (this.CanUseUnmanaged(rgbKey.Length * 8, rgbIV.Length * 8, this.Padding))
|
|
{
|
|
return new RijndaelUnmanagedTransform(this.GetKeyType(rgbKey.Length * 8), CryptoMethod.Encrypt, rgbKey, rgbIV, this.Mode, this.FeedbackSize, this.Padding);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
return this.m_Managed.CreateEncryptor(rgbKey, rgbIV);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (this.m_Managed != null)
|
|
{
|
|
this.m_Managed.Clear();
|
|
this.m_Managed = null;
|
|
}
|
|
if (this.m_Provider != 0)
|
|
{
|
|
SspiProvider.CryptReleaseContext(this.m_Provider, 0);
|
|
this.m_Provider = 0;
|
|
}
|
|
try
|
|
{
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
this.m_Disposed = true;
|
|
}
|
|
|
|
~RijndaelCryptoServiceProvider()
|
|
{
|
|
this.Dispose(true);
|
|
}
|
|
|
|
public override void GenerateIV()
|
|
{
|
|
this.m_Managed.GenerateIV();
|
|
}
|
|
|
|
public override void GenerateKey()
|
|
{
|
|
this.m_Managed.GenerateKey();
|
|
}
|
|
|
|
private CryptoAlgorithm GetKeyType(int size)
|
|
{
|
|
if (size == 0x80)
|
|
{
|
|
return CryptoAlgorithm.Rijndael128;
|
|
}
|
|
if (size == 0xc0)
|
|
{
|
|
return CryptoAlgorithm.Rijndael192;
|
|
}
|
|
if (size != 0x100)
|
|
{
|
|
throw new CryptographicException("Invalid keysize!");
|
|
}
|
|
return CryptoAlgorithm.Rijndael256;
|
|
}
|
|
|
|
public override int BlockSize
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.BlockSize;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.BlockSize = value;
|
|
}
|
|
}
|
|
|
|
public override int FeedbackSize
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.FeedbackSize;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.FeedbackSize = value;
|
|
}
|
|
}
|
|
|
|
public override byte[] IV
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.IV;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.IV = value;
|
|
}
|
|
}
|
|
|
|
public override byte[] Key
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.Key;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.Key = value;
|
|
}
|
|
}
|
|
|
|
public override int KeySize
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.KeySize;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.KeySize = value;
|
|
}
|
|
}
|
|
|
|
private CryptoAlgorithm KeyType
|
|
{
|
|
get
|
|
{
|
|
return this.GetKeyType(this.KeySize);
|
|
}
|
|
}
|
|
|
|
public override KeySizes[] LegalBlockSizes
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.LegalBlockSizes;
|
|
}
|
|
}
|
|
|
|
public override KeySizes[] LegalKeySizes
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.LegalKeySizes;
|
|
}
|
|
}
|
|
|
|
public override CipherMode Mode
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.Mode;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.Mode = value;
|
|
}
|
|
}
|
|
|
|
public override PaddingMode Padding
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.Padding;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.Padding = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|