Exemplo n.º 1
0
        internal HashProviderCng(string hashAlgId, ReadOnlySpan <byte> key, bool isHmac)
        {
            BCryptOpenAlgorithmProviderFlags dwFlags = BCryptOpenAlgorithmProviderFlags.None;

            if (isHmac)
            {
                _key     = key.ToArray();
                dwFlags |= BCryptOpenAlgorithmProviderFlags.BCRYPT_ALG_HANDLE_HMAC_FLAG;
            }

            _hAlgorithm = Interop.BCrypt.BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(hashAlgId, dwFlags, out _hashSize);

            // Win7 won't set hHash, Win8+ will; and both will set _hHash.
            // So keep hHash trapped in this scope to prevent (mis-)use of it.
            {
                SafeBCryptHashHandle?hHash    = null;
                NTSTATUS             ntStatus = Interop.BCrypt.BCryptCreateHash(_hAlgorithm, out hHash, IntPtr.Zero, 0, key, key == null ? 0 : key.Length, BCryptCreateHashFlags.BCRYPT_HASH_REUSABLE_FLAG);
                if (ntStatus == NTSTATUS.STATUS_INVALID_PARAMETER)
                {
                    // If we got here, we're running on a downlevel OS (pre-Win8) that doesn't support reusable CNG hash objects. Fall back to creating a
                    // new HASH object each time.
                    ResetHashObject();
                }
                else if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                {
                    throw Interop.BCrypt.CreateCryptographicException(ntStatus);
                }
                else
                {
                    _hHash    = hHash;
                    _reusable = true;
                }
            }
        }
Exemplo n.º 2
0
        internal LiteHash(string algorithm)
        {
            BCryptOpenAlgorithmProviderFlags algorithmFlags =
                BCryptOpenAlgorithmProviderFlags.None;

            // This is a shared handle, do not put this in a using.
            SafeBCryptAlgorithmHandle algorithmHandle = Interop.BCrypt.BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(
                algorithm,
                algorithmFlags,
                out _hashSizeInBytes);

            SafeBCryptHashHandle hashHandle;

            NTSTATUS ntStatus = Interop.BCrypt.BCryptCreateHash(
                algorithmHandle,
                out hashHandle,
                pbHashObject: IntPtr.Zero,
                cbHashObject: 0,
                secret: ReadOnlySpan <byte> .Empty,
                cbSecret: 0,
                BCryptCreateHashFlags.None);

            if (ntStatus != NTSTATUS.STATUS_SUCCESS)
            {
                hashHandle.Dispose();
                throw Interop.BCrypt.CreateCryptographicException(ntStatus);
            }

            _hashHandle = hashHandle;
        }
Exemplo n.º 3
0
        private static unsafe void FillDeriveKeyPBKDF2(
            ReadOnlySpan <byte> password,
            ReadOnlySpan <byte> salt,
            int iterations,
            string hashAlgorithmName,
            Span <byte> destination)
        {
            const BCryptOpenAlgorithmProviderFlags OpenAlgorithmFlags = BCryptOpenAlgorithmProviderFlags.BCRYPT_ALG_HANDLE_HMAC_FLAG;

            // This code path will only be taken on Windows 7, so we can assume pseudo handles are not supported.
            // Do not dispose handle since it is shared and cached.
            SafeBCryptAlgorithmHandle handle =
                Interop.BCrypt.BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(hashAlgorithmName, OpenAlgorithmFlags, out _);

            fixed(byte *pPassword = password)
            fixed(byte *pSalt        = salt)
            fixed(byte *pDestination = destination)
            {
                NTSTATUS status = Interop.BCrypt.BCryptDeriveKeyPBKDF2(
                    handle,
                    pPassword,
                    password.Length,
                    pSalt,
                    salt.Length,
                    (ulong)iterations,
                    pDestination,
                    destination.Length,
                    dwFlags: 0);

                if (status != NTSTATUS.STATUS_SUCCESS)
                {
                    throw Interop.BCrypt.CreateCryptographicException(status);
                }
            }
        }
Exemplo n.º 4
0
        //
        //   - "hashAlgId" must be a name recognized by BCryptOpenAlgorithmProvider(). Examples: MD5, SHA1, SHA256.
        //
        //   - "key" activates MAC hashing if present. If null, this HashProvider performs a regular old hash.
        //
        public HashProviderCng(string hashAlgId, byte[] key)
        {
            BCryptOpenAlgorithmProviderFlags dwFlags = BCryptOpenAlgorithmProviderFlags.None;

            if (key != null)
            {
                _key     = key.CloneByteArray();
                dwFlags |= BCryptOpenAlgorithmProviderFlags.BCRYPT_ALG_HANDLE_HMAC_FLAG;
            }

            _hAlgorithm = Interop.BCrypt.BCryptAlgorithmCache.GetCachedBCryptAlgorithmHandle(hashAlgId, dwFlags);

            // Win7 won't set hHash, Win8+ will; and both will set _hHash.
            // So keep hHash trapped in this scope to prevent (mis-)use of it.
            {
                SafeBCryptHashHandle hHash    = null;
                NTSTATUS             ntStatus = Interop.BCrypt.BCryptCreateHash(_hAlgorithm, out hHash, IntPtr.Zero, 0, key, key == null ? 0 : key.Length, BCryptCreateHashFlags.BCRYPT_HASH_REUSABLE_FLAG);
                if (ntStatus == NTSTATUS.STATUS_INVALID_PARAMETER)
                {
                    // If we got here, we're running on a downlevel OS (pre-Win8) that doesn't support reusable CNG hash objects. Fall back to creating a
                    // new HASH object each time.
                    ResetHashObject();
                }
                else if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                {
                    throw Interop.BCrypt.CreateCryptographicException(ntStatus);
                }
                else
                {
                    _hHash = hHash;
                    //begin: gost
                    if (hashAlgId != GostConstants.GOST3411_STRING)
                    {
                        //end: gost
                        _reusable = true;
                        //begin: gost
                    }
                    //end: gost
                }
            }

            unsafe
            {
                int      cbSizeOfHashSize;
                int      hashSize;
                NTSTATUS ntStatus = Interop.BCrypt.BCryptGetProperty(_hHash, Interop.BCrypt.BCryptPropertyStrings.BCRYPT_HASH_LENGTH, &hashSize, sizeof(int), out cbSizeOfHashSize, 0);
                if (ntStatus != NTSTATUS.STATUS_SUCCESS)
                {
                    throw Interop.BCrypt.CreateCryptographicException(ntStatus);
                }
                _hashSize = hashSize;
            }
            return;
        }