TransformBlock() public method

Implement the ICryptoTransform method.
public TransformBlock ( byte inputBuffer, int inputOffset, int inputCount, byte outputBuffer, int outputOffset ) : int
inputBuffer byte
inputOffset int
inputCount int
outputBuffer byte
outputOffset int
return int
示例#1
0
        public override int Read(byte[] outBuffer, int offset, int count)
        {
            int num = 0;

            while (num < count)
            {
                int num2 = _slideBufFreePos - _slideBufStartPos;
                int num3 = _blockAndAuth - num2;
                if (_slideBuffer.Length - _slideBufFreePos < num3)
                {
                    int num4 = 0;
                    int num5 = _slideBufStartPos;
                    while (num5 < _slideBufFreePos)
                    {
                        _slideBuffer[num4] = _slideBuffer[num5];
                        num5++;
                        num4++;
                    }
                    _slideBufFreePos -= _slideBufStartPos;
                    _slideBufStartPos = 0;
                }
                int num6 = _stream.Read(_slideBuffer, _slideBufFreePos, num3);
                _slideBufFreePos += num6;
                num2              = _slideBufFreePos - _slideBufStartPos;
                if (num2 >= _blockAndAuth)
                {
                    _transform.TransformBlock(_slideBuffer, _slideBufStartPos, 16, outBuffer, offset);
                    num               += 16;
                    offset            += 16;
                    _slideBufStartPos += 16;
                    continue;
                }
                if (num2 > 10)
                {
                    int num7 = num2 - 10;
                    _transform.TransformBlock(_slideBuffer, _slideBufStartPos, num7, outBuffer, offset);
                    num += num7;
                    _slideBufStartPos += num7;
                }
                else if (num2 < 10)
                {
                    throw new Exception("Internal error missed auth code");
                }
                byte[] authCode = _transform.GetAuthCode();
                for (int i = 0; i < 10; i++)
                {
                    if (authCode[i] != _slideBuffer[_slideBufStartPos + i])
                    {
                        throw new Exception("AES Authentication Code does not match. This is a super-CRC check on the data in the file after compression and encryption. \r\nThe file may be damaged.");
                    }
                }
                break;
            }
            return(num);
        }
示例#2
0
        // Perform the crypto transform, and buffer the data if less than one block has been requested.
        private int TransformAndBufferBlock(byte[] buffer, int offset, int count, int blockSize)
        {
            // If the requested data is greater than one block, transform it directly into the output
            // If it's smaller, do it into a temporary buffer and copy the requested part
            bool bufferRequired = (blockSize > count);

            if (bufferRequired && _transformBuffer == null)
            {
                _transformBuffer = new byte[CRYPTO_BLOCK_SIZE];
            }

            var targetBuffer = bufferRequired ? _transformBuffer : buffer;
            var targetOffset = bufferRequired ? 0 : offset;

            // Transform the data
            _transform.TransformBlock(_slideBuffer,
                                      _slideBufStartPos,
                                      blockSize,
                                      targetBuffer,
                                      targetOffset);

            _slideBufStartPos += blockSize;

            if (!bufferRequired)
            {
                return(blockSize);
            }
            else
            {
                Array.Copy(_transformBuffer, 0, buffer, offset, count);
                _transformBufferStartPos = count;
                _transformBufferFreePos  = blockSize;

                return(count);
            }
        }
示例#3
0
        // Blocksize is always 16 here, even for AES-256 which has transform.InputBlockSize of 32.

        /// <summary>
        /// Reads a sequence of bytes from the current CryptoStream into buffer,
        /// and advances the position within the stream by the number of bytes read.
        /// </summary>
        public override int Read(byte[] outBuffer, int offset, int count)
        {
            int nBytes = 0;

            while (nBytes < count)
            {
                // Calculate buffer quantities vs read-ahead size, and check for sufficient free space
                int byteCount = _slideBufFreePos - _slideBufStartPos;

                // Need to handle final block and Auth Code specially, but don't know total data length.
                // Maintain a read-ahead equal to the length of (crypto block + Auth Code).
                // When that runs out we can detect these final sections.
                int lengthToRead = _blockAndAuth - byteCount;
                if (_slideBuffer.Length - _slideBufFreePos < lengthToRead)
                {
                    // Shift the data to the beginning of the buffer
                    int iTo = 0;
                    for (int iFrom = _slideBufStartPos; iFrom < _slideBufFreePos; iFrom++, iTo++)
                    {
                        _slideBuffer[iTo] = _slideBuffer[iFrom];
                    }
                    _slideBufFreePos -= _slideBufStartPos;                     // Note the -=
                    _slideBufStartPos = 0;
                }
                int obtained = _stream.Read(_slideBuffer, _slideBufFreePos, lengthToRead);
                _slideBufFreePos += obtained;

                // Recalculate how much data we now have
                byteCount = _slideBufFreePos - _slideBufStartPos;
                if (byteCount >= _blockAndAuth)
                {
                    // At least a 16 byte block and an auth code remains.
                    _transform.TransformBlock(_slideBuffer,
                                              _slideBufStartPos,
                                              CRYPTO_BLOCK_SIZE,
                                              outBuffer,
                                              offset);
                    nBytes            += CRYPTO_BLOCK_SIZE;
                    offset            += CRYPTO_BLOCK_SIZE;
                    _slideBufStartPos += CRYPTO_BLOCK_SIZE;
                }
                else
                {
                    // Last round.
                    if (byteCount > AUTH_CODE_LENGTH)
                    {
                        // At least one byte of data plus auth code
                        int finalBlock = byteCount - AUTH_CODE_LENGTH;
                        _transform.TransformBlock(_slideBuffer,
                                                  _slideBufStartPos,
                                                  finalBlock,
                                                  outBuffer,
                                                  offset);

                        nBytes            += finalBlock;
                        _slideBufStartPos += finalBlock;
                    }
                    else if (byteCount < AUTH_CODE_LENGTH)
                    {
                        throw new Exception("Internal error missed auth code");                         // Coding bug
                    }
                    // Final block done. Check Auth code.
                    byte[] calcAuthCode = _transform.GetAuthCode();
                    for (int i = 0; i < AUTH_CODE_LENGTH; i++)
                    {
                        if (calcAuthCode[i] != _slideBuffer[_slideBufStartPos + i])
                        {
                            throw new Exception("AES Authentication Code does not match. This is a super-CRC check on the data in the file after compression and encryption. \r\n"
                                                + "The file may be damaged.");
                        }
                    }

                    break;                     // Reached the auth code
                }
            }
            return(nBytes);
        }