Ejemplo n.º 1
0
        public override void Close()
        {
            if (sourceStream.CanWrite)
            {
                if (forEncryption)
                {
                    int offset = bufEnd;

                    if (offset == blockSize)
                    {
                        sourceStream.Write(buffer, 0, blockSize);
                        offset = 0;
                    }

                    padding.AddPadding(buffer, offset);

                    sourceStream.Write(buffer, 0, blockSize);
                }
                else
                {
                    bufEnd -= padding.PadCount(buffer);

                    sourceStream.Write(buffer, 0, bufEnd);
                }
            }

            sourceStream.Close();
        }
Ejemplo n.º 2
0
        /**
         * Process the last block in the buffer. If the buffer is currently
         * full and padding needs to be added a call to doFinal will produce
         * 2 * GetBlockSize() bytes.
         *
         * @param out the array the block currently being held is copied into.
         * @param outOff the offset at which the copying starts.
         * @return the number of output bytes copied to out.
         * @exception DataLengthException if there is insufficient space in out for
         * the output or we are decrypting and the input is not block size aligned.
         * @exception InvalidOperationException if the underlying cipher is not
         * initialised.
         * @exception InvalidCipherTextException if padding is expected and not found.
         */

        public override int DoFinal(
            byte[] output,
            int outOff)
        {
            int blockSize = cipher.GetBlockSize();
            int resultLen = 0;

            if (forEncryption)
            {
                if (bufOff == blockSize)
                {
                    if ((outOff + 2 * blockSize) > output.Length)
                    {
                        Reset();

                        throw new OutputLengthException("output buffer too short");
                    }

                    resultLen = cipher.ProcessBlock(buf, 0, output, outOff);
                    bufOff    = 0;
                }

                padding.AddPadding(buf, bufOff);

                resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen);

                Reset();
            }
            else
            {
                if (bufOff == blockSize)
                {
                    resultLen = cipher.ProcessBlock(buf, 0, buf, 0);
                    bufOff    = 0;
                }
                else
                {
                    Reset();

                    throw new DataLengthException("last block incomplete in decryption");
                }

                try
                {
                    resultLen -= padding.PadCount(buf);

                    Array.Copy(buf, 0, output, outOff, resultLen);
                }
                finally
                {
                    Reset();
                }
            }

            return(resultLen);
        }
Ejemplo n.º 3
0
        public override int DoFinal(byte[] output, int outOff)
        {
            int blockSize = cipher.GetBlockSize();
            int num       = 0;

            if (forEncryption)
            {
                if (bufOff == blockSize)
                {
                    if (outOff + 2 * blockSize > output.Length)
                    {
                        Reset();
                        throw new OutputLengthException("output buffer too short");
                    }
                    num    = cipher.ProcessBlock(buf, 0, output, outOff);
                    bufOff = 0;
                }
                padding.AddPadding(buf, bufOff);
                num += cipher.ProcessBlock(buf, 0, output, outOff + num);
                Reset();
                return(num);
            }
            if (bufOff == blockSize)
            {
                num    = cipher.ProcessBlock(buf, 0, buf, 0);
                bufOff = 0;
                try
                {
                    num -= padding.PadCount(buf);
                    global::System.Array.Copy((global::System.Array)buf, 0, (global::System.Array)output, outOff, num);
                    return(num);
                }
                finally
                {
                    Reset();
                }
            }
            Reset();
            throw new DataLengthException("last block incomplete in decryption");
        }
Ejemplo n.º 4
0
        /// <inheritdoc />
        public int ProcessFinal(byte[] input, int inputOffset, int length, byte[] output, int outputOffset)
        {
            var workingBlock = new byte[_blockSize];

            if (Encrypting)
            {
                if (_cipherCompound.IsPartialBlockOkay)
                {
                    // Output block is truncated size
                    // Padding is pointless if cipher supports partial blocks, so we won't even support it
                    _cipherCompound.ProcessBlock(input, inputOffset, workingBlock, 0);
                    workingBlock.DeepCopy_NoChecks(0, output, outputOffset, length);
                }
                else
                {
                    // Output block is full block size
                    // Padding is required
                    input.DeepCopy_NoChecks(inputOffset, workingBlock, 0, _blockSize);
                    length += _padding.AddPadding(workingBlock, length);
                    _cipherCompound.ProcessBlock(workingBlock, 0, output, outputOffset);
                }
                Reset();
            }
            else
            {
                if (_cipherCompound.IsPartialBlockOkay)
                {
                    _cipherCompound.ProcessBlock(input, inputOffset, workingBlock, 0);
                    workingBlock.DeepCopy_NoChecks(0, output, outputOffset, length);
                    Reset();
                }
                else
                {
                    if (length != _blockSize)
                    {
                        if (length == 0 && _padding != null)
                        {
                            // Overran the end
                            if (outputOffset >= _blockSize)
                            {
                                outputOffset -= _blockSize;
                            }
                            output.DeepCopy_NoChecks(outputOffset, workingBlock, 0, _blockSize);
                        }
                        else
                        {
                            throw new CryptoException();
                        }
                    }
                    else
                    {
                        // Normal padded block
                        _cipherCompound.ProcessBlock(input, inputOffset, workingBlock, 0);
                    }
                    try {
                        // Determine the number of padding bytes
                        var paddingByteCount = _padding.PadCount(workingBlock);
                        workingBlock.DeepCopy_NoChecks(0, output, outputOffset, _blockSize - paddingByteCount);
                        length -= paddingByteCount;
                    }
                    finally {
                        Reset();
                    }
                }
            }

            return(length);
        }