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
- FocusTracker.cs
- InvariantComparer.cs
- GridViewRow.cs
- RequestQueue.cs
- EndpointAddressProcessor.cs
- CacheHelper.cs
- XNodeValidator.cs
- EntityKey.cs
- ActivityFunc.cs
- GlyphElement.cs
- ActivityDesignerLayoutSerializers.cs
- CallbackHandler.cs
- ListenerElementsCollection.cs
- ZipIOExtraFieldPaddingElement.cs
- ListViewGroupConverter.cs
- SqlDataSourceRefreshSchemaForm.cs
- PagePropertiesChangingEventArgs.cs
- PrintPreviewControl.cs
- ChangesetResponse.cs
- PenContexts.cs
- TraceHandlerErrorFormatter.cs
- DuplicateWaitObjectException.cs
- HandlerBase.cs
- SerialPort.cs
- SHA256CryptoServiceProvider.cs
- MarkupExtensionParser.cs
- FlowLayoutSettings.cs
- MemberAssignment.cs
- ThaiBuddhistCalendar.cs
- DecoderReplacementFallback.cs
- XmlSerializationWriter.cs
- DefaultBinder.cs
- ServiceOperation.cs
- DataRelation.cs
- HtmlControl.cs
- FixedSOMElement.cs
- XamlClipboardData.cs
- EncryptedXml.cs
- SByteStorage.cs
- BindingMAnagerBase.cs
- Typography.cs
- SqlSupersetValidator.cs
- MarkerProperties.cs
- TabItem.cs
- AuthStoreRoleProvider.cs
- EntityConnection.cs
- HashCryptoHandle.cs
- ArgIterator.cs
- TemplatePartAttribute.cs
- RangeValidator.cs
- MonthChangedEventArgs.cs
- CommonDialog.cs
- NameTable.cs
- ChannelReliableSession.cs
- Timer.cs
- MenuItemStyleCollection.cs
- ImmComposition.cs
- CommandID.cs
- ExcCanonicalXml.cs
- StylusButton.cs
- CurrentChangingEventManager.cs
- ContextInformation.cs
- DesignerTransactionCloseEvent.cs
- XmlSerializationReader.cs
- Expander.cs
- Console.cs
- MetadataPropertyCollection.cs
- TextParagraphView.cs
- SessionEndingCancelEventArgs.cs
- InnerItemCollectionView.cs
- ListViewGroupCollectionEditor.cs
- WebPartMenu.cs
- CommandBindingCollection.cs
- CacheVirtualItemsEvent.cs
- TextBlock.cs
- DataGridrowEditEndingEventArgs.cs
- WindowsTab.cs
- CanonicalXml.cs
- CheckedPointers.cs
- HtmlTableCell.cs
- ComplexTypeEmitter.cs
- CompilerErrorCollection.cs
- PrimitiveType.cs
- PrivilegeNotHeldException.cs
- CodeTypeConstructor.cs
- rsa.cs
- SqlTypesSchemaImporter.cs
- ObjectSet.cs
- NavigationService.cs
- ObjectDataSourceFilteringEventArgs.cs
- ResourcePool.cs
- Base64WriteStateInfo.cs
- EventLog.cs
- WrappedIUnknown.cs
- MaskedTextBoxDesigner.cs
- SerializationObjectManager.cs
- Run.cs
- OperatorExpressions.cs
- StatusBarItem.cs