Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Security / Cryptography / BCryptHashAlgorithm.cs / 1305376 / BCryptHashAlgorithm.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
using Microsoft.Win32.SafeHandles;
namespace System.Security.Cryptography {
///
/// Implementation of a generic BCrypt hashing algorithm, concrete HashAlgorithm classes
/// implemented by BCrypt can contain an instance of this class and delegate the work to it.
///
internal sealed class BCryptHashAlgorithm : IDisposable {
private SafeBCryptAlgorithmHandle m_algorithmHandle;
private SafeBCryptHashHandle m_hashHandle;
//
//
//
//
//
//
//
//
//
[System.Security.SecurityCritical]
public BCryptHashAlgorithm(CngAlgorithm algorithm, string implementation) {
Contract.Requires(algorithm != null);
Contract.Requires(!String.IsNullOrEmpty(implementation));
Contract.Ensures(m_algorithmHandle != null && !m_algorithmHandle.IsInvalid && !m_algorithmHandle.IsClosed);
Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed);
// Make sure CNG is supported on this platform
if (!BCryptNative.BCryptSupported) {
throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
}
m_algorithmHandle = BCryptNative.OpenAlgorithm(algorithm.Algorithm, implementation);
Initialize();
}
///
/// Clean up the hash algorithm
///
//
//
//
//
//
//
[System.Security.SecurityCritical]
public void Dispose() {
Contract.Ensures(m_hashHandle == null || m_hashHandle.IsClosed);
Contract.Ensures(m_algorithmHandle == null || m_algorithmHandle.IsClosed);
if (m_hashHandle != null) {
m_hashHandle.Dispose();
}
if (m_algorithmHandle != null) {
m_algorithmHandle.Dispose();
}
}
///
/// Reset the hash algorithm to begin hashing a new set of data
///
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
[System.Security.SecurityCritical]
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")]
public void Initialize() {
Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed);
Contract.Assert(m_algorithmHandle != null);
// Try to create a new hash algorithm to use
SafeBCryptHashHandle newHashAlgorithm = null;
IntPtr hashObjectBuffer = IntPtr.Zero;
// Creating a BCRYPT_HASH_HANDLE requires providing a buffer to hold the hash object in, which
// is tied to the lifetime of the hash handle. Wrap this in a CER so we can tie the lifetimes together
// safely.
RuntimeHelpers.PrepareConstrainedRegions();
try {
int hashObjectSize = BCryptNative.GetInt32Property(m_algorithmHandle,
BCryptNative.ObjectPropertyName.ObjectLength);
Debug.Assert(hashObjectSize > 0, "hashObjectSize > 0");
// Allocate in a CER because we could fail between the alloc and the assignment
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally {
hashObjectBuffer = Marshal.AllocCoTaskMem(hashObjectSize);
}
BCryptNative.ErrorCode error = BCryptNative.UnsafeNativeMethods.BCryptCreateHash(m_algorithmHandle,
out newHashAlgorithm,
hashObjectBuffer,
hashObjectSize,
IntPtr.Zero,
0,
0);
if (error != BCryptNative.ErrorCode.Success) {
throw new CryptographicException((int)error);
}
newHashAlgorithm.HashObject = hashObjectBuffer;
}
finally {
// Make sure we've successfully transfered ownership of the hash object buffer to the safe handle
if (hashObjectBuffer != IntPtr.Zero && (newHashAlgorithm == null || newHashAlgorithm.HashObject == IntPtr.Zero)) {
Marshal.FreeCoTaskMem(hashObjectBuffer);
}
}
// If we could create it, dispose of any old hash handle we had and replace it with the new one
if (m_hashHandle != null) {
m_hashHandle.Dispose();
}
m_hashHandle = newHashAlgorithm;
}
///
/// Hash a block of data
///
//
//
//
//
[System.Security.SecurityCritical]
public void HashCore(byte[] array, int ibStart, int cbSize) {
Contract.Assert(m_hashHandle != null);
if (array == null) {
throw new ArgumentNullException("array");
}
if (ibStart < 0 || ibStart > array.Length - cbSize) {
throw new ArgumentOutOfRangeException("ibStart");
}
if (cbSize < 0 || cbSize > array.Length) {
throw new ArgumentOutOfRangeException("cbSize");
}
byte[] hashData = new byte[cbSize];
Buffer.BlockCopy(array, ibStart, hashData, 0, cbSize);
BCryptNative.ErrorCode error = BCryptNative.UnsafeNativeMethods.BCryptHashData(m_hashHandle,
hashData,
hashData.Length,
0);
if (error != BCryptNative.ErrorCode.Success) {
throw new CryptographicException((int)error);
}
}
///
/// Complete the hash, returning its value
///
//
//
//
//
//
[System.Security.SecurityCritical]
public byte[] HashFinal() {
Contract.Ensures(Contract.Result() != null);
Contract.Assert(m_hashHandle != null);
int hashSize = BCryptNative.GetInt32Property(m_hashHandle, BCryptNative.HashPropertyName.HashLength);
byte[] hashValue = new byte[hashSize];
BCryptNative.ErrorCode error = BCryptNative.UnsafeNativeMethods.BCryptFinishHash(m_hashHandle,
hashValue,
hashValue.Length,
0);
if (error != BCryptNative.ErrorCode.Success) {
throw new CryptographicException((int)error);
}
return hashValue;
}
//
//
//
[System.Security.SecurityCritical]
public void HashStream(Stream stream) {
Contract.Requires(stream != null);
// Read the data 4KB at a time, providing similar read characteristics to a standard HashAlgorithm
byte[] buffer = new byte[4096];
int bytesRead = 0;
do {
bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0) {
HashCore(buffer, 0, bytesRead);
}
} while (bytesRead > 0);
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
using Microsoft.Win32.SafeHandles;
namespace System.Security.Cryptography {
///
/// Implementation of a generic BCrypt hashing algorithm, concrete HashAlgorithm classes
/// implemented by BCrypt can contain an instance of this class and delegate the work to it.
///
internal sealed class BCryptHashAlgorithm : IDisposable {
private SafeBCryptAlgorithmHandle m_algorithmHandle;
private SafeBCryptHashHandle m_hashHandle;
//
//
//
//
//
//
//
//
//
[System.Security.SecurityCritical]
public BCryptHashAlgorithm(CngAlgorithm algorithm, string implementation) {
Contract.Requires(algorithm != null);
Contract.Requires(!String.IsNullOrEmpty(implementation));
Contract.Ensures(m_algorithmHandle != null && !m_algorithmHandle.IsInvalid && !m_algorithmHandle.IsClosed);
Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed);
// Make sure CNG is supported on this platform
if (!BCryptNative.BCryptSupported) {
throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
}
m_algorithmHandle = BCryptNative.OpenAlgorithm(algorithm.Algorithm, implementation);
Initialize();
}
///
/// Clean up the hash algorithm
///
//
//
//
//
//
//
[System.Security.SecurityCritical]
public void Dispose() {
Contract.Ensures(m_hashHandle == null || m_hashHandle.IsClosed);
Contract.Ensures(m_algorithmHandle == null || m_algorithmHandle.IsClosed);
if (m_hashHandle != null) {
m_hashHandle.Dispose();
}
if (m_algorithmHandle != null) {
m_algorithmHandle.Dispose();
}
}
///
/// Reset the hash algorithm to begin hashing a new set of data
///
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
[System.Security.SecurityCritical]
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")]
public void Initialize() {
Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed);
Contract.Assert(m_algorithmHandle != null);
// Try to create a new hash algorithm to use
SafeBCryptHashHandle newHashAlgorithm = null;
IntPtr hashObjectBuffer = IntPtr.Zero;
// Creating a BCRYPT_HASH_HANDLE requires providing a buffer to hold the hash object in, which
// is tied to the lifetime of the hash handle. Wrap this in a CER so we can tie the lifetimes together
// safely.
RuntimeHelpers.PrepareConstrainedRegions();
try {
int hashObjectSize = BCryptNative.GetInt32Property(m_algorithmHandle,
BCryptNative.ObjectPropertyName.ObjectLength);
Debug.Assert(hashObjectSize > 0, "hashObjectSize > 0");
// Allocate in a CER because we could fail between the alloc and the assignment
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally {
hashObjectBuffer = Marshal.AllocCoTaskMem(hashObjectSize);
}
BCryptNative.ErrorCode error = BCryptNative.UnsafeNativeMethods.BCryptCreateHash(m_algorithmHandle,
out newHashAlgorithm,
hashObjectBuffer,
hashObjectSize,
IntPtr.Zero,
0,
0);
if (error != BCryptNative.ErrorCode.Success) {
throw new CryptographicException((int)error);
}
newHashAlgorithm.HashObject = hashObjectBuffer;
}
finally {
// Make sure we've successfully transfered ownership of the hash object buffer to the safe handle
if (hashObjectBuffer != IntPtr.Zero && (newHashAlgorithm == null || newHashAlgorithm.HashObject == IntPtr.Zero)) {
Marshal.FreeCoTaskMem(hashObjectBuffer);
}
}
// If we could create it, dispose of any old hash handle we had and replace it with the new one
if (m_hashHandle != null) {
m_hashHandle.Dispose();
}
m_hashHandle = newHashAlgorithm;
}
///
/// Hash a block of data
///
//
//
//
//
[System.Security.SecurityCritical]
public void HashCore(byte[] array, int ibStart, int cbSize) {
Contract.Assert(m_hashHandle != null);
if (array == null) {
throw new ArgumentNullException("array");
}
if (ibStart < 0 || ibStart > array.Length - cbSize) {
throw new ArgumentOutOfRangeException("ibStart");
}
if (cbSize < 0 || cbSize > array.Length) {
throw new ArgumentOutOfRangeException("cbSize");
}
byte[] hashData = new byte[cbSize];
Buffer.BlockCopy(array, ibStart, hashData, 0, cbSize);
BCryptNative.ErrorCode error = BCryptNative.UnsafeNativeMethods.BCryptHashData(m_hashHandle,
hashData,
hashData.Length,
0);
if (error != BCryptNative.ErrorCode.Success) {
throw new CryptographicException((int)error);
}
}
///
/// Complete the hash, returning its value
///
//
//
//
//
//
[System.Security.SecurityCritical]
public byte[] HashFinal() {
Contract.Ensures(Contract.Result() != null);
Contract.Assert(m_hashHandle != null);
int hashSize = BCryptNative.GetInt32Property(m_hashHandle, BCryptNative.HashPropertyName.HashLength);
byte[] hashValue = new byte[hashSize];
BCryptNative.ErrorCode error = BCryptNative.UnsafeNativeMethods.BCryptFinishHash(m_hashHandle,
hashValue,
hashValue.Length,
0);
if (error != BCryptNative.ErrorCode.Success) {
throw new CryptographicException((int)error);
}
return hashValue;
}
//
//
//
[System.Security.SecurityCritical]
public void HashStream(Stream stream) {
Contract.Requires(stream != null);
// Read the data 4KB at a time, providing similar read characteristics to a standard HashAlgorithm
byte[] buffer = new byte[4096];
int bytesRead = 0;
do {
bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0) {
HashCore(buffer, 0, bytesRead);
}
} while (bytesRead > 0);
}
}
}
// 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
- EdmFunction.cs
- Metafile.cs
- ComMethodElementCollection.cs
- ResolvedKeyFrameEntry.cs
- IgnorePropertiesAttribute.cs
- IdentifierCollection.cs
- ChannelOptions.cs
- NativeMethods.cs
- ClearCollection.cs
- PersonalizablePropertyEntry.cs
- WindowsTab.cs
- METAHEADER.cs
- XamlUtilities.cs
- SqlDataSourceFilteringEventArgs.cs
- CodeAccessSecurityEngine.cs
- MessageQueuePermissionAttribute.cs
- TextBoxBase.cs
- Accessible.cs
- XmlSiteMapProvider.cs
- VirtualPath.cs
- ResourceReferenceExpression.cs
- MenuAutomationPeer.cs
- InputBinder.cs
- AssociationTypeEmitter.cs
- ConfigXmlDocument.cs
- CodeTypeDelegate.cs
- SmiConnection.cs
- BitStack.cs
- WS2007FederationHttpBinding.cs
- SettingsPropertyValueCollection.cs
- DynamicMetaObjectBinder.cs
- NotSupportedException.cs
- ListViewDeletedEventArgs.cs
- SafeEventLogWriteHandle.cs
- GridLength.cs
- BaseContextMenu.cs
- BlobPersonalizationState.cs
- Rotation3DAnimation.cs
- TypeContext.cs
- SQLDouble.cs
- PipeStream.cs
- DataGridViewColumnCollection.cs
- InputScopeAttribute.cs
- FontUnitConverter.cs
- PrintDialog.cs
- SspiSafeHandles.cs
- FakeModelItemImpl.cs
- DesignerActionHeaderItem.cs
- CodeIndexerExpression.cs
- HttpCookie.cs
- WorkflowInstanceQuery.cs
- TextSelectionProcessor.cs
- ZipFileInfo.cs
- AdornedElementPlaceholder.cs
- ChineseLunisolarCalendar.cs
- GridViewUpdateEventArgs.cs
- CrossAppDomainChannel.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- Comparer.cs
- SystemUnicastIPAddressInformation.cs
- XmlAnyElementAttributes.cs
- SamlAuthenticationClaimResource.cs
- Int64KeyFrameCollection.cs
- GeometryGroup.cs
- HostingEnvironmentSection.cs
- GeneralTransform3D.cs
- XmlUnspecifiedAttribute.cs
- DotExpr.cs
- RemoveStoryboard.cs
- PermissionSetTriple.cs
- TranslateTransform.cs
- CodeCommentStatementCollection.cs
- Attributes.cs
- StoreItemCollection.Loader.cs
- BulletDecorator.cs
- DbBuffer.cs
- TranslateTransform.cs
- ListViewEditEventArgs.cs
- TargetParameterCountException.cs
- StrokeSerializer.cs
- IndexingContentUnit.cs
- AssemblyAssociatedContentFileAttribute.cs
- EntitySetBaseCollection.cs
- NotConverter.cs
- EntityContainerRelationshipSetEnd.cs
- AnimatedTypeHelpers.cs
- DocumentStatusResources.cs
- PrintControllerWithStatusDialog.cs
- oledbconnectionstring.cs
- Clock.cs
- TableLayoutCellPaintEventArgs.cs
- URIFormatException.cs
- rsa.cs
- ClientSideQueueItem.cs
- DataGridViewLayoutData.cs
- KerberosSecurityTokenProvider.cs
- ConstructorNeedsTagAttribute.cs
- ChangeProcessor.cs
- ObjectParameterCollection.cs
- MatrixConverter.cs