Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Security / Cryptography / AesCryptoServiceProvider.cs / 1305376 / AesCryptoServiceProvider.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Diagnostics.Contracts; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { ////// AES wrapper around the CAPI implementation. /// [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class AesCryptoServiceProvider : Aes { private static KeySizes[] s_supportedKeySizes; private static int s_defaultKeySize; private SafeCspHandle m_cspHandle; // Note that keys are stored in CAPI rather than directly in the KeyValue property, which should not // be used to retrieve the key value directly. private SafeCapiKeyHandle m_key; //// [System.Security.SecurityCritical] public AesCryptoServiceProvider () { Contract.Ensures(m_cspHandle != null && !m_cspHandle.IsInvalid && !m_cspHandle.IsClosed); // On Windows XP the AES CSP has the prototype name, but on newer operating systems it has the // standard name string providerName = CapiNative.ProviderNames.MicrosoftEnhancedRsaAes; if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1) { providerName = CapiNative.ProviderNames.MicrosoftEnhancedRsaAesPrototype; } m_cspHandle = CapiNative.AcquireCsp(null, providerName, CapiNative.ProviderType.RsaAes, CapiNative.CryptAcquireContextFlags.VerifyContext, true); // CAPI will not allow feedback sizes greater than 64 bits FeedbackSizeValue = 8; // Get the different AES key sizes supported by this platform, raising an error if there are no // supported key sizes. int defaultKeySize = 0; KeySizes[] keySizes = FindSupportedKeySizes(m_cspHandle, out defaultKeySize); if (keySizes.Length != 0) { Debug.Assert(defaultKeySize > 0, "defaultKeySize > 0"); KeySizeValue = defaultKeySize; } else { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } } ///// // // // // /// Value of the symmetric key used for encryption / decryption /// public override byte[] Key { //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] get { Contract.Ensures(m_key != null && !m_key.IsInvalid && !m_key.IsClosed); Contract.Ensures(Contract.Result// // // // () != null && Contract.Result ().Length == KeySizeValue / 8); if (m_key == null || m_key.IsInvalid || m_key.IsClosed) { GenerateKey(); } // We don't hold onto a key value directly, so we need to export it from CAPI when the user // wants a byte array representation. byte[] keyValue = CapiNative.ExportSymmetricKey(m_key); return keyValue; } // // [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] set { Contract.Ensures(m_key != null && !m_key.IsInvalid && !m_key.IsClosed); if (value == null) { throw new ArgumentNullException("value"); } byte[] keyValue = (byte[])value.Clone(); if (!ValidKeySize(keyValue.Length * 8)) { throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidKeySize)); } // Import the key, then close any current key and replace with the new one. We need to make // sure the import is successful before closing the current key to avoid having an algorithm // with no valid keys. SafeCapiKeyHandle importedKey = CapiNative.ImportSymmetricKey(m_cspHandle, GetAlgorithmId(keyValue.Length * 8), keyValue); if (m_key != null) { m_key.Dispose(); } m_key = importedKey; KeySizeValue = keyValue.Length * 8; } } ///// // // // // // // /// Size, in bits, of the key /// public override int KeySize { get { return base.KeySize; } //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] set { base.KeySize = value; // Since the key size is being reset, we need to reset the key itself as well if (m_key != null) { m_key.Dispose(); } } } ///// // /// Create an object to perform AES decryption with the current key and IV /// ///// // [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] public override ICryptoTransform CreateDecryptor() { Contract.Ensures(Contract.Result// // // // () != null); if (m_key == null || m_key.IsInvalid || m_key.IsClosed) { throw new CryptographicException(SR.GetString(SR.Cryptography_DecryptWithNoKey)); } return CreateDecryptor(m_key, IVValue); } /// /// Create an object to perform AES decryption with the given key and IV /// //// [System.Security.SecurityCritical] public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv) { Contract.Ensures(Contract.Result// // // // () != null); if (key == null) { throw new ArgumentNullException("key"); } if (!ValidKeySize(key.Length * 8)) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidKeySize), "key"); } if (iv != null && iv.Length * 8 != BlockSizeValue) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidIVSize), "iv"); } byte[] keyCopy = (byte[])key.Clone(); byte[] ivCopy = null; if (iv != null) { ivCopy = (byte[])iv.Clone(); } using (SafeCapiKeyHandle importedKey = CapiNative.ImportSymmetricKey(m_cspHandle, GetAlgorithmId(keyCopy.Length * 8), keyCopy)) { return CreateDecryptor(importedKey, ivCopy); } } /// /// Create an object to perform AES decryption /// //// [System.Security.SecurityCritical] private ICryptoTransform CreateDecryptor(SafeCapiKeyHandle key, byte[] iv) { Contract.Requires(key != null); Contract.Ensures(Contract.Result// // // () != null); return new CapiSymmetricAlgorithm(BlockSizeValue, FeedbackSizeValue, m_cspHandle, key, iv, Mode, PaddingValue, EncryptionMode.Decrypt); } /// /// Create an object to do AES encryption with the current key and IV /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] public override ICryptoTransform CreateEncryptor() { Contract.Ensures(Contract.Result// // // // () != null); if (m_key == null || m_key.IsInvalid || m_key.IsClosed) { GenerateKey(); } // ECB is the only mode which does not require an IV -- generate one here if we don't have one yet. if (Mode != CipherMode.ECB && IVValue == null) { GenerateIV(); } return CreateEncryptor(m_key, IVValue); } /// /// Create an object to do AES encryption with the given key and IV /// //// [System.Security.SecurityCritical] public override ICryptoTransform CreateEncryptor(byte[] key, byte[] iv) { Contract.Ensures(Contract.Result// // // // () != null); if (key == null) { throw new ArgumentNullException("key"); } if (!ValidKeySize(key.Length * 8)) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidKeySize), "key"); } if (iv != null && iv.Length * 8 != BlockSizeValue) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidIVSize), "iv"); } byte[] keyCopy = (byte[])key.Clone(); byte[] ivCopy = null; if (iv != null) { ivCopy = (byte[])iv.Clone(); } using (SafeCapiKeyHandle importedKey = CapiNative.ImportSymmetricKey(m_cspHandle, GetAlgorithmId(keyCopy.Length * 8), keyCopy)) { return CreateEncryptor(importedKey, ivCopy); } } /// /// Create an object to perform AES encryption /// //// [System.Security.SecurityCritical] private ICryptoTransform CreateEncryptor(SafeCapiKeyHandle key, byte[] iv) { Contract.Requires(key != null); Contract.Ensures(Contract.Result// // // () != null); return new CapiSymmetricAlgorithm(BlockSizeValue, FeedbackSizeValue, m_cspHandle, key, iv, Mode, PaddingValue, EncryptionMode.Encrypt); } /// /// Release any CAPI handles we're holding onto /// //// [System.Security.SecurityCritical] protected override void Dispose(bool disposing) { Contract.Ensures(!disposing || m_key == null || m_key.IsClosed); Contract.Ensures(!disposing || m_cspHandle == null || m_cspHandle.IsClosed); try { if (disposing) { if (m_key != null) { m_key.Dispose(); } if (m_cspHandle != null) { m_cspHandle.Dispose(); } } } finally { base.Dispose(disposing); } } ///// // // // /// Get the size of AES keys supported by the given CSP, and which size should be used by default. /// /// We assume that the same CSP will always be used by all instances of the AesCryptoServiceProvider /// in the current AppDomain. If we add the ability for users to choose which CSP to use on a /// per-instance basis, we need to update the code to account for the CSP when checking the cached /// key size values. /// //// [System.Security.SecurityCritical] private static KeySizes[] FindSupportedKeySizes(SafeCspHandle csp, out int defaultKeySize) { Contract.Requires(csp != null); Contract.Ensures(Contract.Result// // () != null); // If this platform has any supported algorithm sizes, then the default key size should be set to a // reasonable value. Contract.Ensures(Contract.Result ().Length == 0 || (Contract.ValueAtReturn (out defaultKeySize) > 0 && Contract.ValueAtReturn (out defaultKeySize) % 8 == 0)); if (s_supportedKeySizes == null) { List keySizes = new List (); int maxKeySize = 0; // // Enumerate the CSP's supported algorithms to see what key sizes it supports for AES // CapiNative.PROV_ENUMALGS algorithm = CapiNative.GetProviderParameterStruct (csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.RestartEnumeration); // Translate between CAPI AES algorithm IDs and supported key sizes while (algorithm.aiAlgId != CapiNative.AlgorithmId.None) { switch (algorithm.aiAlgId) { case CapiNative.AlgorithmId.Aes128: keySizes.Add(new KeySizes(128, 128, 0)); if (128 > maxKeySize) { maxKeySize = 128; } break; case CapiNative.AlgorithmId.Aes192: keySizes.Add(new KeySizes(192, 192, 0)); if (192 > maxKeySize) { maxKeySize = 192; } break; case CapiNative.AlgorithmId.Aes256: keySizes.Add(new KeySizes(256, 256, 0)); if (256 > maxKeySize) { maxKeySize = 256; } break; default: break; } algorithm = CapiNative.GetProviderParameterStruct (csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.None); } s_supportedKeySizes = keySizes.ToArray(); s_defaultKeySize = maxKeySize; } defaultKeySize = s_defaultKeySize; return s_supportedKeySizes; } /// /// Generate a new random key /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] public override void GenerateKey() { Contract.Ensures(m_key != null && !m_key.IsInvalid & !m_key.IsClosed); Contract.Assert(m_cspHandle != null); SafeCapiKeyHandle key = null; if (!CapiNative.UnsafeNativeMethods.CryptGenKey(m_cspHandle, GetAlgorithmId(KeySizeValue), CapiNative.KeyFlags.Exportable, out key)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } if (m_key != null) { m_key.Dispose(); } m_key = key; } ///// // // // // // // // /// Generate a random initialization vector /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] public override void GenerateIV() { Contract.Ensures(IVValue != null && IVValue.Length == BlockSizeValue / 8); Contract.Assert(m_cspHandle != null); Contract.Assert(BlockSizeValue % 8 == 0); byte[] iv = new byte[BlockSizeValue / 8]; if (!CapiNative.UnsafeNativeMethods.CryptGenRandom(m_cspHandle, iv.Length, iv)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } IVValue = iv; } ///// // // /// Map an AES key size to the corresponding CAPI algorithm ID /// private static CapiNative.AlgorithmId GetAlgorithmId(int keySize) { // We should always return either a data encryption algorithm ID or None if we don't recognize the key size Contract.Ensures( ((((int)Contract.Result()) & (int)CapiNative.AlgorithmClass.DataEncryption) == (int)CapiNative.AlgorithmClass.DataEncryption) || Contract.Result () == CapiNative.AlgorithmId.None); switch (keySize) { case 128: return CapiNative.AlgorithmId.Aes128; case 192: return CapiNative.AlgorithmId.Aes192; case 256: return CapiNative.AlgorithmId.Aes256; default: return CapiNative.AlgorithmId.None; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Diagnostics.Contracts; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography { /// /// AES wrapper around the CAPI implementation. /// [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] public sealed class AesCryptoServiceProvider : Aes { private static KeySizes[] s_supportedKeySizes; private static int s_defaultKeySize; private SafeCspHandle m_cspHandle; // Note that keys are stored in CAPI rather than directly in the KeyValue property, which should not // be used to retrieve the key value directly. private SafeCapiKeyHandle m_key; //// [System.Security.SecurityCritical] public AesCryptoServiceProvider () { Contract.Ensures(m_cspHandle != null && !m_cspHandle.IsInvalid && !m_cspHandle.IsClosed); // On Windows XP the AES CSP has the prototype name, but on newer operating systems it has the // standard name string providerName = CapiNative.ProviderNames.MicrosoftEnhancedRsaAes; if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1) { providerName = CapiNative.ProviderNames.MicrosoftEnhancedRsaAesPrototype; } m_cspHandle = CapiNative.AcquireCsp(null, providerName, CapiNative.ProviderType.RsaAes, CapiNative.CryptAcquireContextFlags.VerifyContext, true); // CAPI will not allow feedback sizes greater than 64 bits FeedbackSizeValue = 8; // Get the different AES key sizes supported by this platform, raising an error if there are no // supported key sizes. int defaultKeySize = 0; KeySizes[] keySizes = FindSupportedKeySizes(m_cspHandle, out defaultKeySize); if (keySizes.Length != 0) { Debug.Assert(defaultKeySize > 0, "defaultKeySize > 0"); KeySizeValue = defaultKeySize; } else { throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported)); } } ///// // // // // /// Value of the symmetric key used for encryption / decryption /// public override byte[] Key { //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] get { Contract.Ensures(m_key != null && !m_key.IsInvalid && !m_key.IsClosed); Contract.Ensures(Contract.Result// // // // () != null && Contract.Result ().Length == KeySizeValue / 8); if (m_key == null || m_key.IsInvalid || m_key.IsClosed) { GenerateKey(); } // We don't hold onto a key value directly, so we need to export it from CAPI when the user // wants a byte array representation. byte[] keyValue = CapiNative.ExportSymmetricKey(m_key); return keyValue; } // // [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] set { Contract.Ensures(m_key != null && !m_key.IsInvalid && !m_key.IsClosed); if (value == null) { throw new ArgumentNullException("value"); } byte[] keyValue = (byte[])value.Clone(); if (!ValidKeySize(keyValue.Length * 8)) { throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidKeySize)); } // Import the key, then close any current key and replace with the new one. We need to make // sure the import is successful before closing the current key to avoid having an algorithm // with no valid keys. SafeCapiKeyHandle importedKey = CapiNative.ImportSymmetricKey(m_cspHandle, GetAlgorithmId(keyValue.Length * 8), keyValue); if (m_key != null) { m_key.Dispose(); } m_key = importedKey; KeySizeValue = keyValue.Length * 8; } } ///// // // // // // // /// Size, in bits, of the key /// public override int KeySize { get { return base.KeySize; } //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] set { base.KeySize = value; // Since the key size is being reset, we need to reset the key itself as well if (m_key != null) { m_key.Dispose(); } } } ///// // /// Create an object to perform AES decryption with the current key and IV /// ///// // [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] public override ICryptoTransform CreateDecryptor() { Contract.Ensures(Contract.Result// // // // () != null); if (m_key == null || m_key.IsInvalid || m_key.IsClosed) { throw new CryptographicException(SR.GetString(SR.Cryptography_DecryptWithNoKey)); } return CreateDecryptor(m_key, IVValue); } /// /// Create an object to perform AES decryption with the given key and IV /// //// [System.Security.SecurityCritical] public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv) { Contract.Ensures(Contract.Result// // // // () != null); if (key == null) { throw new ArgumentNullException("key"); } if (!ValidKeySize(key.Length * 8)) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidKeySize), "key"); } if (iv != null && iv.Length * 8 != BlockSizeValue) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidIVSize), "iv"); } byte[] keyCopy = (byte[])key.Clone(); byte[] ivCopy = null; if (iv != null) { ivCopy = (byte[])iv.Clone(); } using (SafeCapiKeyHandle importedKey = CapiNative.ImportSymmetricKey(m_cspHandle, GetAlgorithmId(keyCopy.Length * 8), keyCopy)) { return CreateDecryptor(importedKey, ivCopy); } } /// /// Create an object to perform AES decryption /// //// [System.Security.SecurityCritical] private ICryptoTransform CreateDecryptor(SafeCapiKeyHandle key, byte[] iv) { Contract.Requires(key != null); Contract.Ensures(Contract.Result// // // () != null); return new CapiSymmetricAlgorithm(BlockSizeValue, FeedbackSizeValue, m_cspHandle, key, iv, Mode, PaddingValue, EncryptionMode.Decrypt); } /// /// Create an object to do AES encryption with the current key and IV /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] public override ICryptoTransform CreateEncryptor() { Contract.Ensures(Contract.Result// // // // () != null); if (m_key == null || m_key.IsInvalid || m_key.IsClosed) { GenerateKey(); } // ECB is the only mode which does not require an IV -- generate one here if we don't have one yet. if (Mode != CipherMode.ECB && IVValue == null) { GenerateIV(); } return CreateEncryptor(m_key, IVValue); } /// /// Create an object to do AES encryption with the given key and IV /// //// [System.Security.SecurityCritical] public override ICryptoTransform CreateEncryptor(byte[] key, byte[] iv) { Contract.Ensures(Contract.Result// // // // () != null); if (key == null) { throw new ArgumentNullException("key"); } if (!ValidKeySize(key.Length * 8)) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidKeySize), "key"); } if (iv != null && iv.Length * 8 != BlockSizeValue) { throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidIVSize), "iv"); } byte[] keyCopy = (byte[])key.Clone(); byte[] ivCopy = null; if (iv != null) { ivCopy = (byte[])iv.Clone(); } using (SafeCapiKeyHandle importedKey = CapiNative.ImportSymmetricKey(m_cspHandle, GetAlgorithmId(keyCopy.Length * 8), keyCopy)) { return CreateEncryptor(importedKey, ivCopy); } } /// /// Create an object to perform AES encryption /// //// [System.Security.SecurityCritical] private ICryptoTransform CreateEncryptor(SafeCapiKeyHandle key, byte[] iv) { Contract.Requires(key != null); Contract.Ensures(Contract.Result// // // () != null); return new CapiSymmetricAlgorithm(BlockSizeValue, FeedbackSizeValue, m_cspHandle, key, iv, Mode, PaddingValue, EncryptionMode.Encrypt); } /// /// Release any CAPI handles we're holding onto /// //// [System.Security.SecurityCritical] protected override void Dispose(bool disposing) { Contract.Ensures(!disposing || m_key == null || m_key.IsClosed); Contract.Ensures(!disposing || m_cspHandle == null || m_cspHandle.IsClosed); try { if (disposing) { if (m_key != null) { m_key.Dispose(); } if (m_cspHandle != null) { m_cspHandle.Dispose(); } } } finally { base.Dispose(disposing); } } ///// // // // /// Get the size of AES keys supported by the given CSP, and which size should be used by default. /// /// We assume that the same CSP will always be used by all instances of the AesCryptoServiceProvider /// in the current AppDomain. If we add the ability for users to choose which CSP to use on a /// per-instance basis, we need to update the code to account for the CSP when checking the cached /// key size values. /// //// [System.Security.SecurityCritical] private static KeySizes[] FindSupportedKeySizes(SafeCspHandle csp, out int defaultKeySize) { Contract.Requires(csp != null); Contract.Ensures(Contract.Result// // () != null); // If this platform has any supported algorithm sizes, then the default key size should be set to a // reasonable value. Contract.Ensures(Contract.Result ().Length == 0 || (Contract.ValueAtReturn (out defaultKeySize) > 0 && Contract.ValueAtReturn (out defaultKeySize) % 8 == 0)); if (s_supportedKeySizes == null) { List keySizes = new List (); int maxKeySize = 0; // // Enumerate the CSP's supported algorithms to see what key sizes it supports for AES // CapiNative.PROV_ENUMALGS algorithm = CapiNative.GetProviderParameterStruct (csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.RestartEnumeration); // Translate between CAPI AES algorithm IDs and supported key sizes while (algorithm.aiAlgId != CapiNative.AlgorithmId.None) { switch (algorithm.aiAlgId) { case CapiNative.AlgorithmId.Aes128: keySizes.Add(new KeySizes(128, 128, 0)); if (128 > maxKeySize) { maxKeySize = 128; } break; case CapiNative.AlgorithmId.Aes192: keySizes.Add(new KeySizes(192, 192, 0)); if (192 > maxKeySize) { maxKeySize = 192; } break; case CapiNative.AlgorithmId.Aes256: keySizes.Add(new KeySizes(256, 256, 0)); if (256 > maxKeySize) { maxKeySize = 256; } break; default: break; } algorithm = CapiNative.GetProviderParameterStruct (csp, CapiNative.ProviderParameter.EnumerateAlgorithms, CapiNative.ProviderParameterFlags.None); } s_supportedKeySizes = keySizes.ToArray(); s_defaultKeySize = maxKeySize; } defaultKeySize = s_defaultKeySize; return s_supportedKeySizes; } /// /// Generate a new random key /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] public override void GenerateKey() { Contract.Ensures(m_key != null && !m_key.IsInvalid & !m_key.IsClosed); Contract.Assert(m_cspHandle != null); SafeCapiKeyHandle key = null; if (!CapiNative.UnsafeNativeMethods.CryptGenKey(m_cspHandle, GetAlgorithmId(KeySizeValue), CapiNative.KeyFlags.Exportable, out key)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } if (m_key != null) { m_key.Dispose(); } m_key = key; } ///// // // // // // // // /// Generate a random initialization vector /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] public override void GenerateIV() { Contract.Ensures(IVValue != null && IVValue.Length == BlockSizeValue / 8); Contract.Assert(m_cspHandle != null); Contract.Assert(BlockSizeValue % 8 == 0); byte[] iv = new byte[BlockSizeValue / 8]; if (!CapiNative.UnsafeNativeMethods.CryptGenRandom(m_cspHandle, iv.Length, iv)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } IVValue = iv; } ///// // // /// Map an AES key size to the corresponding CAPI algorithm ID /// private static CapiNative.AlgorithmId GetAlgorithmId(int keySize) { // We should always return either a data encryption algorithm ID or None if we don't recognize the key size Contract.Ensures( ((((int)Contract.Result()) & (int)CapiNative.AlgorithmClass.DataEncryption) == (int)CapiNative.AlgorithmClass.DataEncryption) || Contract.Result () == CapiNative.AlgorithmId.None); switch (keySize) { case 128: return CapiNative.AlgorithmId.Aes128; case 192: return CapiNative.AlgorithmId.Aes192; case 256: return CapiNative.AlgorithmId.Aes256; default: return CapiNative.AlgorithmId.None; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ValidationErrorCollection.cs
- WebGetAttribute.cs
- QueryPageSettingsEventArgs.cs
- safex509handles.cs
- RenderOptions.cs
- DbUpdateCommandTree.cs
- AuthorizationRuleCollection.cs
- VoiceChangeEventArgs.cs
- UserPersonalizationStateInfo.cs
- ObjectMemberMapping.cs
- HttpBrowserCapabilitiesWrapper.cs
- FormViewDeleteEventArgs.cs
- TypedTableHandler.cs
- PersistenceContext.cs
- UInt64.cs
- RawContentTypeMapper.cs
- ThaiBuddhistCalendar.cs
- ProxyGenerationError.cs
- NetNamedPipeSecurityElement.cs
- IdentitySection.cs
- WinEventTracker.cs
- TransactionalPackage.cs
- InvalidOperationException.cs
- ClassData.cs
- NotSupportedException.cs
- VirtualDirectoryMappingCollection.cs
- XmlException.cs
- ObjectIDGenerator.cs
- DefaultExpressionVisitor.cs
- BamlTreeNode.cs
- UniformGrid.cs
- LineServicesCallbacks.cs
- EmbeddedObject.cs
- StrongTypingException.cs
- ListViewVirtualItemsSelectionRangeChangedEvent.cs
- DispatcherTimer.cs
- ActivationArguments.cs
- RadioButton.cs
- LayoutInformation.cs
- EventWaitHandle.cs
- ISCIIEncoding.cs
- UrlAuthFailedErrorFormatter.cs
- SHA384Managed.cs
- XmlSchemaAttributeGroup.cs
- WebPartHeaderCloseVerb.cs
- BufferModeSettings.cs
- ButtonChrome.cs
- XmlException.cs
- HTMLTagNameToTypeMapper.cs
- DashStyles.cs
- CompilationLock.cs
- EtwTrace.cs
- TextHidden.cs
- UnsettableComboBox.cs
- ModifiableIteratorCollection.cs
- WinFormsSecurity.cs
- Image.cs
- ImagingCache.cs
- AutomationProperty.cs
- ParameterRefs.cs
- DBCommandBuilder.cs
- DataGridColumnDropSeparator.cs
- PanningMessageFilter.cs
- ParamArrayAttribute.cs
- AdapterUtil.cs
- Paragraph.cs
- LocalBuilder.cs
- LogExtentCollection.cs
- DataViewSetting.cs
- NewItemsContextMenuStrip.cs
- Vector3DCollectionValueSerializer.cs
- SQLInt32.cs
- HttpCapabilitiesSectionHandler.cs
- sqlpipe.cs
- XmlSchemaGroup.cs
- dataprotectionpermission.cs
- DateTimeFormatInfo.cs
- GridItemPattern.cs
- DesignConnectionCollection.cs
- TemplatingOptionsDialog.cs
- ScaleTransform3D.cs
- Component.cs
- Color.cs
- CustomErrorCollection.cs
- HttpApplication.cs
- FormClosedEvent.cs
- BitmapEffectInputData.cs
- RecognizerInfo.cs
- HttpCachePolicyWrapper.cs
- CustomLineCap.cs
- SessionEndedEventArgs.cs
- QuaternionRotation3D.cs
- SvcMapFileLoader.cs
- CodeAccessSecurityEngine.cs
- PerformanceCountersElement.cs
- AdapterDictionary.cs
- Token.cs
- CodeCommentStatementCollection.cs
- LinqDataSourceStatusEventArgs.cs
- Models.cs