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
- MarkedHighlightComponent.cs
- InputBindingCollection.cs
- WorkflowOwnershipException.cs
- TextTreeObjectNode.cs
- PageVisual.cs
- ConnectionPoint.cs
- SoapElementAttribute.cs
- IItemProperties.cs
- OperationAbortedException.cs
- ViewManager.cs
- AdornerDecorator.cs
- AppDomainShutdownMonitor.cs
- WsrmTraceRecord.cs
- ConnectionStringEditor.cs
- FrameAutomationPeer.cs
- ExpressionsCollectionConverter.cs
- DropShadowBitmapEffect.cs
- TextBlock.cs
- RemoveStoryboard.cs
- DeviceFiltersSection.cs
- ObjectViewListener.cs
- TextServicesCompartmentContext.cs
- TreeNodeEventArgs.cs
- DetailsViewCommandEventArgs.cs
- ManualResetEvent.cs
- FileDialog_Vista_Interop.cs
- BamlTreeMap.cs
- Label.cs
- BaseAddressElement.cs
- formatter.cs
- SmtpAuthenticationManager.cs
- CollectionContainer.cs
- RMEnrollmentPage2.cs
- SmtpReplyReader.cs
- ObjectAnimationUsingKeyFrames.cs
- ObjectHelper.cs
- SnapLine.cs
- FocusManager.cs
- Propagator.JoinPropagator.cs
- PrintPreviewGraphics.cs
- DragSelectionMessageFilter.cs
- TextEditorCharacters.cs
- SamlAttribute.cs
- ApplicationServicesHostFactory.cs
- DataFormats.cs
- ZipIOZip64EndOfCentralDirectoryLocatorBlock.cs
- RuntimeEnvironment.cs
- SystemBrushes.cs
- XamlBrushSerializer.cs
- SHA512Managed.cs
- FixedTextContainer.cs
- SharedStream.cs
- ComponentEditorForm.cs
- HwndHostAutomationPeer.cs
- SessionEndingCancelEventArgs.cs
- ListenerConstants.cs
- FileChangesMonitor.cs
- ControlPersister.cs
- JsonSerializer.cs
- DirectoryNotFoundException.cs
- ProfileManager.cs
- AutomationPeer.cs
- IntegerFacetDescriptionElement.cs
- ModuleElement.cs
- SynchronizedPool.cs
- FixedElement.cs
- TextEndOfSegment.cs
- BindValidator.cs
- ToolStripRenderer.cs
- MeshGeometry3D.cs
- SemanticResultValue.cs
- OlePropertyStructs.cs
- ReservationCollection.cs
- PointKeyFrameCollection.cs
- XmlSiteMapProvider.cs
- GridSplitter.cs
- ModuleConfigurationInfo.cs
- BindingElementExtensionElement.cs
- TransferRequestHandler.cs
- ArrayWithOffset.cs
- WebEventCodes.cs
- Vector3DAnimation.cs
- SqlXml.cs
- HtmlInputPassword.cs
- HtmlInputPassword.cs
- InvalidPrinterException.cs
- X509Certificate.cs
- SimpleType.cs
- smtppermission.cs
- VersionedStream.cs
- ActivitySurrogateSelector.cs
- InfoCardTraceRecord.cs
- PnrpPermission.cs
- RbTree.cs
- DbConnectionPool.cs
- ConfigDefinitionUpdates.cs
- ViewBox.cs
- RuntimeVariableList.cs
- ClientApiGenerator.cs
- SafeFileMappingHandle.cs