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
- BooleanFunctions.cs
- XamlFrame.cs
- TextEditorSelection.cs
- DownloadProgressEventArgs.cs
- RowUpdatingEventArgs.cs
- StreamGeometryContext.cs
- PrePrepareMethodAttribute.cs
- FixUp.cs
- ThrowHelper.cs
- CookieHandler.cs
- SqlCharStream.cs
- FontDifferentiator.cs
- SessionStateSection.cs
- FontClient.cs
- parserscommon.cs
- WindowsToolbarAsMenu.cs
- ImageSourceValueSerializer.cs
- FixedDocumentSequencePaginator.cs
- OracleNumber.cs
- ListBindingHelper.cs
- SequenceNumber.cs
- XmlFormatWriterGenerator.cs
- TrackingMemoryStream.cs
- FontDifferentiator.cs
- DefaultClaimSet.cs
- TrustLevelCollection.cs
- CodeEntryPointMethod.cs
- SerializerProvider.cs
- WebBrowserHelper.cs
- DirectionalLight.cs
- DeferredTextReference.cs
- EventListener.cs
- UdpSocket.cs
- MimeTypeMapper.cs
- Task.cs
- SynchronousReceiveBehavior.cs
- XPathNavigator.cs
- TemplateEditingFrame.cs
- PersistenceProviderFactory.cs
- StringToken.cs
- HierarchicalDataSourceConverter.cs
- CatalogZoneBase.cs
- JpegBitmapDecoder.cs
- XmlNavigatorStack.cs
- WsiProfilesElement.cs
- PeerInvitationResponse.cs
- CommandConverter.cs
- PassportIdentity.cs
- NonNullItemCollection.cs
- BaseComponentEditor.cs
- ArrayElementGridEntry.cs
- TextTreeTextElementNode.cs
- RegexStringValidator.cs
- WebZone.cs
- GridViewCommandEventArgs.cs
- ExtentKey.cs
- XmlAnyAttributeAttribute.cs
- ScriptControlDescriptor.cs
- PixelShader.cs
- Comparer.cs
- JavaScriptObjectDeserializer.cs
- SafeEventHandle.cs
- DataGridViewCellPaintingEventArgs.cs
- FileVersionInfo.cs
- SqlBulkCopyColumnMappingCollection.cs
- ThemeDirectoryCompiler.cs
- XmlSerializerFactory.cs
- XPathNavigatorReader.cs
- SqlSelectStatement.cs
- EditorZone.cs
- WebResourceUtil.cs
- ValueTypeFixupInfo.cs
- VectorConverter.cs
- PeerValidationBehavior.cs
- CustomPopupPlacement.cs
- DataServiceQueryOfT.cs
- DefaultMemberAttribute.cs
- QilPatternVisitor.cs
- ActivityCodeGenerator.cs
- _KerberosClient.cs
- InfiniteTimeSpanConverter.cs
- TableProvider.cs
- OledbConnectionStringbuilder.cs
- TextEffect.cs
- HwndSourceKeyboardInputSite.cs
- FormViewUpdateEventArgs.cs
- DataGridHeaderBorder.cs
- NativeCompoundFileAPIs.cs
- WindowsFormsHostAutomationPeer.cs
- WebConfigurationFileMap.cs
- TextProviderWrapper.cs
- TitleStyle.cs
- PrimitiveSchema.cs
- CompositeScriptReference.cs
- XmlNamespaceMapping.cs
- ReliableReplySessionChannel.cs
- DataGridColumnFloatingHeader.cs
- Bitmap.cs
- ClientBuildManager.cs
- DataGridViewRowErrorTextNeededEventArgs.cs