internal static extern NTSTATUS BCryptCreateHash(SafeBCryptAlgorithmHandle hAlgorithm, out SafeBCryptHashHandle phHash, IntPtr pbHashObject, int cbHashObject, [In, Out] byte[] pbSecret, int cbSecret, BCryptCreateHashFlags dwFlags);
internal static extern unsafe NTSTATUS BCryptHashData(SafeBCryptHashHandle hHash, byte* pbInput, int cbInput, int dwFlags);
public void Initialize() { SafeBCryptHashHandle phHash = null; IntPtr zero = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { int cb = BCryptNative.GetInt32Property<SafeBCryptAlgorithmHandle>(this.m_algorithmHandle, "ObjectLength"); RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { zero = Marshal.AllocCoTaskMem(cb); } BCryptNative.ErrorCode code = BCryptNative.UnsafeNativeMethods.BCryptCreateHash(this.m_algorithmHandle, out phHash, zero, cb, IntPtr.Zero, 0, 0); if (code != BCryptNative.ErrorCode.Success) { throw new CryptographicException((int) code); } phHash.HashObject = zero; } finally { if ((zero != IntPtr.Zero) && ((phHash == null) || (phHash.HashObject == IntPtr.Zero))) { Marshal.FreeCoTaskMem(zero); } } if (this.m_hashHandle != null) { this.m_hashHandle.Dispose(); } this.m_hashHandle = phHash; }
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); } } finally { // Make sure we've successfully transfered ownership of the hash object buffer to the safe handle if (hashObjectBuffer != IntPtr.Zero) { // If we created the safe handle, it needs to own the buffer and free it in release if (newHashAlgorithm != null) { newHashAlgorithm.HashObject = hashObjectBuffer; } else { 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; }
internal static extern NTSTATUS BCryptFinishHash(SafeBCryptHashHandle hHash, [Out] byte[] pbOutput, int cbOutput, int dwFlags);