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; } } } }