/// <summary>
        /// Gets the hash parameter.  This method wraps the underlying
        /// api to obtain the length of the result and appropriately
        /// size a result byte buffer.
        /// </summary>
        /// 
        /// <param name="hashHandle">
        /// The hash handle.
        /// </param>
        /// 
        /// <param name="hashParameter">
        /// The hash parameter.
        /// </param>
        /// 
        /// <returns>
        /// <c>true</c> if successful, otherwise <c>false</c>.
        /// </returns>
        internal static byte[] GetHashParameterWrapper(
            SafeCryptoHashHandle hashHandle,
            HashParameter hashParameter)
        {
            int hashLength = 0;
            if (!UnsafeNativeMethods.CryptGetHashParam(
                hashHandle, hashParameter, null, ref hashLength, 0))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            byte[] hash = new byte[hashLength];
            if (!UnsafeNativeMethods.CryptGetHashParam(
                hashHandle, hashParameter, hash, ref hashLength, 0))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            return hash;
        }
        /// <summary>
        /// Initializes this instance.
        /// </summary>
        internal void Initialize()
        {
            Reset();

            if (!UnsafeNativeMethods.CryptAcquireContext(
                out _cryptoContextHandle,
                null,
                _provider,
                _providerType,
                CryptoAcquireContextFlags.None
                    | CryptoAcquireContextFlags.VerifyContext))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            _cryptoHashHandle = NewHashHandle();
        }
 internal static extern bool CryptSetHashParam(
     SafeCryptoHashHandle hash,
     HashParameter paramter,
     [In, Out] ref HMAC_INFO hmacInfo,
     uint flags
 );
        /// <summary>
        /// Wraps the CryptHashData method to marshal the correct
        /// byte pointer.
        /// </summary>
        /// 
        /// <param name="hash">
        /// The hash handle.
        /// </param>
        /// 
        /// <param name="data">
        /// The data to hash.
        /// </param>
        /// 
        /// <param name="offset">
        /// The offset into the data.
        /// </param>
        /// 
        /// <param name="count">
        /// The count of bytes to hash.
        /// </param>
        internal static void CryptHashDataWrapper(
            SafeCryptoHashHandle hash,
            byte[] data, 
            int offset, 
            int count)
        {
            // We could marshal the data as UnmanagedType.LPArray but we would
            // have to copy the array so that the first byte is at pos 0.  This
            // way we can take correct the region of the array in situ.
            unsafe
            {
                fixed (byte* b = &data[offset])
                {
                    IntPtr intPtr = new IntPtr((void*)b);

                    if (!UnsafeNativeMethods.CryptHashData(
                        hash, intPtr, count, 0))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                }
            }
        }
 internal static extern bool CryptHashData(
     SafeCryptoHashHandle hash,
     IntPtr plainText,
     int length,
     int flags);
 internal static extern bool CryptGetHashParam(
     SafeCryptoHashHandle hash,
     HashParameter hashParameter,
     [Out, MarshalAs(UnmanagedType.LPArray)] byte[] hashValue,
     [In, Out] ref int length,
     int flags);
 internal static extern bool CryptCreateHash(
     SafeCryptoContextHandle cryptoContext,
     AlgorithmId algorithmId,
     SafeCryptoKeyHandle key,
     int flags,
     out SafeCryptoHashHandle hash);