ComputeHash() public method

Computes the hash value.
public ComputeHash ( ReadOnlySpan source, Span destination ) : void
source ReadOnlySpan
destination Span
return void
Beispiel #1
0
        public static void DeriveKey(byte[] password, ReadOnlySpan <byte> salt, Sha2 prf, uint iterationCount, Span <byte> destination)
        {
            Debug.Assert(password != null);
            Debug.Assert(salt != null);
            Debug.Assert(destination.Length > 0);

            int numBytesWritten   = 0;
            int numBytesRemaining = destination.Length;

            Span <byte> saltWithBlockIndex = stackalloc byte[checked (salt.Length + sizeof(uint))];

            salt.CopyTo(saltWithBlockIndex);

            Span <byte> hmacKey       = stackalloc byte[prf.BlockSize * 2];
            var         hashAlgorithm = new Hmac(prf, password, hmacKey);

            int wSize     = prf.GetWorkingSetSize(int.MaxValue);
            int blockSize = hashAlgorithm.BlockSize;

            byte[]? arrayToReturn = null;
            try
            {
                Span <byte> W = wSize > Constants.MaxStackallocBytes
                    ? (arrayToReturn = ArrayPool <byte> .Shared.Rent(wSize))
                    : stackalloc byte[wSize];
                Span <byte> currentBlock          = stackalloc byte[hashAlgorithm.HashSize];
                Span <byte> iterationBlock        = stackalloc byte[hashAlgorithm.HashSize];
                Span <byte> blockIndexDestination = saltWithBlockIndex.Slice(saltWithBlockIndex.Length - sizeof(uint));
                for (uint blockIndex = 1; numBytesRemaining > 0; blockIndex++)
                {
                    BinaryPrimitives.WriteUInt32BigEndian(blockIndexDestination, blockIndex);
                    hashAlgorithm.ComputeHash(saltWithBlockIndex, currentBlock, W); // U_1
                    currentBlock.CopyTo(iterationBlock);
                    for (int iter = 1; iter < iterationCount; iter++)
                    {
                        hashAlgorithm.ComputeHash(currentBlock, currentBlock, W);
                        Xor(src: currentBlock, dest: iterationBlock);
                    }

                    int numBytesToCopy = Math.Min(numBytesRemaining, iterationBlock.Length);
                    iterationBlock.Slice(0, numBytesToCopy).CopyTo(destination.Slice(numBytesWritten));
                    numBytesWritten   += numBytesToCopy;
                    numBytesRemaining -= numBytesToCopy;
                }
            }
            finally
            {
                if (arrayToReturn != null)
                {
                    ArrayPool <byte> .Shared.Return(arrayToReturn);
                }
            }
        }
Beispiel #2
0
        private void ComputeAuthenticationTag(ReadOnlySpan <byte> key, ReadOnlySpan <byte> iv, ReadOnlySpan <byte> associatedData, ReadOnlySpan <byte> ciphertext, Span <byte> authenticationTag, out int authenticationTagBytesWritten)
        {
            byte[]? arrayToReturnToPool = null;
            try
            {
                int         macLength = associatedData.Length + iv.Length + ciphertext.Length + sizeof(long);
                Span <byte> macBytes  = macLength <= Constants.MaxStackallocBytes
                    ? stackalloc byte[macLength]
                    : (arrayToReturnToPool = ArrayPool <byte> .Shared.Rent(macLength)).AsSpan(0, macLength);

                associatedData.CopyTo(macBytes);
                var bytes = macBytes.Slice(associatedData.Length);
                iv.CopyTo(bytes);
                bytes = bytes.Slice(iv.Length);
                ciphertext.CopyTo(bytes);
                bytes = bytes.Slice(ciphertext.Length);
                BinaryPrimitives.WriteInt64BigEndian(bytes, associatedData.Length << 3);

                Sha2        hashAlgorithm = _encryptionAlgorithm.SignatureAlgorithm.Sha;
                Span <byte> hmacKey       = stackalloc byte[hashAlgorithm.BlockSize * 2];
                Hmac        hmac          = new Hmac(hashAlgorithm, key, hmacKey);
                hmac.ComputeHash(macBytes, authenticationTag);
                authenticationTagBytesWritten = authenticationTag.Length >> 1;
            }
            finally
            {
                if (arrayToReturnToPool != null)
                {
                    ArrayPool <byte> .Shared.Return(arrayToReturnToPool);
                }
            }
        }
Beispiel #3
0
        private bool VerifyAuthenticationTag(ReadOnlySpan <byte> key, ReadOnlySpan <byte> iv, ReadOnlySpan <byte> associatedData, ReadOnlySpan <byte> ciphertext, ReadOnlySpan <byte> authenticationTag)
        {
            byte[]? byteArrayToReturnToPool = null;
            int         macLength = associatedData.Length + iv.Length + ciphertext.Length + sizeof(long);
            Span <byte> macBytes  = macLength <= Constants.MaxStackallocBytes
                                    ? stackalloc byte[macLength]
                                    : (byteArrayToReturnToPool = ArrayPool <byte> .Shared.Rent(macLength)).AsSpan(0, macLength);

            try
            {
                associatedData.CopyTo(macBytes);
                var bytes = macBytes.Slice(associatedData.Length);
                iv.CopyTo(bytes);
                bytes = bytes.Slice(iv.Length);
                ciphertext.CopyTo(bytes);
                bytes = bytes.Slice(ciphertext.Length);
                BinaryPrimitives.WriteInt64BigEndian(bytes, associatedData.Length << 3);

                Sha2        hashAlgorithm = _encryptionAlgorithm.SignatureAlgorithm.Sha;
                Span <byte> hmacKey       = stackalloc byte[hashAlgorithm.BlockSize * 2];
                Hmac        hmac          = new Hmac(hashAlgorithm, key, hmacKey);
                Span <byte> hash          = stackalloc byte[authenticationTag.Length * 2];
                hmac.ComputeHash(macBytes, hash);
                CryptographicOperations.ZeroMemory(hmacKey);

                return(CryptographicOperations.FixedTimeEquals(authenticationTag, hash.Slice(0, authenticationTag.Length)));
            }
            finally
            {
                if (byteArrayToReturnToPool != null)
                {
                    ArrayPool <byte> .Shared.Return(byteArrayToReturnToPool);
                }
            }
        }