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(); }
/** * 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); }
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"); }
/// <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); }