Beispiel #1
0
        // This function is defined as follows:
        // Func (S, i) = HMAC(S || i) ^ HMAC2(S || i) ^ ... ^ HMAC(iterations) (S || i)
        // where i is the block number.
        private void Func()
        {
            // Block number is going to overflow, exceeding the maximum total possible bytes
            // that can be extracted.
            if (_block == uint.MaxValue)
            {
                throw new CryptographicException(SR.Cryptography_ExceedKdfExtractLimit);
            }

            BinaryPrimitives.WriteUInt32BigEndian(_salt.AsSpan(_salt.Length - sizeof(uint)), _block + 1);
            Debug.Assert(_blockSize == _buffer.Length);

            // The biggest _blockSize we have is from SHA512, which is 64 bytes.
            // Since we have a closed set of supported hash algorithms (OpenHmac())
            // we can know this always fits.
            //
            Span <byte> uiSpan = stackalloc byte[64];

            uiSpan = uiSpan.Slice(0, _blockSize);

            if (!_hmac.TryComputeHash(_salt, uiSpan, out int bytesWritten) || bytesWritten != _blockSize)
            {
                throw new CryptographicException();
            }

            uiSpan.CopyTo(_buffer);

            for (int i = 2; i <= _iterations; i++)
            {
                if (!_hmac.TryComputeHash(uiSpan, uiSpan, out bytesWritten) || bytesWritten != _blockSize)
                {
                    throw new CryptographicException();
                }

                for (int j = _buffer.Length - 1; j >= 0; j--)
                {
                    _buffer[j] ^= uiSpan[j];
                }
            }

            // increment the block count.
            _block++;
        }
        // This function is defined as follows:
        // Func (S, i) = HMAC(S || i) ^ HMAC2(S || i) ^ ... ^ HMAC(iterations) (S || i)
        // where i is the block number.
        private byte[] Func()
        {
            byte[] temp = new byte[_salt.Length + sizeof(uint)];
            Buffer.BlockCopy(_salt, 0, temp, 0, _salt.Length);
            Helpers.WriteInt(_block, temp, _salt.Length);

            byte[] ui = ArrayPool <byte> .Shared.Rent(_blockSize);

            try
            {
                Span <byte> uiSpan = new Span <byte>(ui, 0, _blockSize);

                if (!_hmac.TryComputeHash(temp, uiSpan, out int bytesWritten) || bytesWritten != _blockSize)
                {
                    throw new CryptographicException();
                }

                byte[] ret = new byte[_blockSize];
                uiSpan.CopyTo(ret);

                for (int i = 2; i <= _iterations; i++)
                {
                    if (!_hmac.TryComputeHash(uiSpan, uiSpan, out bytesWritten) || bytesWritten != _blockSize)
                    {
                        throw new CryptographicException();
                    }

                    for (int j = 0; j < _blockSize; j++)
                    {
                        ret[j] ^= ui[j];
                    }
                }

                // increment the block count.
                _block++;
                return(ret);
            }
            finally
            {
                Array.Clear(ui, 0, _blockSize);
                ArrayPool <byte> .Shared.Return(ui);
            }
        }
Beispiel #3
0
        // This function is defined as follows:
        // Func (S, i) = HMAC(S || i) ^ HMAC2(S || i) ^ ... ^ HMAC(iterations) (S || i)
        // where i is the block number.
        private void Func()
        {
            Helpers.WriteInt(_block, _salt, _salt.Length - sizeof(uint));
            Debug.Assert(_blockSize == _buffer.Length);

            // The biggest _blockSize we have is from SHA512, which is 64 bytes.
            // Since we have a closed set of supported hash algorithms (OpenHmac())
            // we can know this always fits.
            //
            Span <byte> uiSpan = stackalloc byte[64];

            uiSpan = uiSpan.Slice(0, _blockSize);

            if (!_hmac.TryComputeHash(_salt, uiSpan, out int bytesWritten) || bytesWritten != _blockSize)
            {
                throw new CryptographicException();
            }

            uiSpan.CopyTo(_buffer);

            for (int i = 2; i <= _iterations; i++)
            {
                if (!_hmac.TryComputeHash(uiSpan, uiSpan, out bytesWritten) || bytesWritten != _blockSize)
                {
                    throw new CryptographicException();
                }

                for (int j = _buffer.Length - 1; j >= 0; j--)
                {
                    _buffer[j] ^= uiSpan[j];
                }
            }

            // increment the block count.
            _block++;
        }