public int TransformBlock(byte[] inputBuffer,
int inputOffset,
int inputCount,
byte[] outputBuffer,
int outputOffset)
{
if (_disposed) {
throw new ObjectDisposedException(GetType().FullName);
}
if (inputBuffer == null)
throw new ArgumentNullException("inputBuffer");
if (inputOffset < 0 || inputOffset >= inputBuffer.Length)
throw new ArgumentOutOfRangeException("inputOffset");
if (inputCount < 0 || inputCount > inputBuffer.Length-inputOffset)
throw new ArgumentOutOfRangeException("inputCount");
if (inputCount % _blockSize != 0)
throw new CryptographicException("inputCount");
if (outputBuffer == null)
throw new ArgumentNullException("outputBuffer");
if (outputOffset < 0 || outputOffset > outputBuffer.Length-inputCount)
throw new ArgumentOutOfRangeException("outputOffset");
// This is manual CBC handling
for (int i=0; i<inputCount; i+=_blockSize) {
if (_encrypting) {
for (int j=0; j<_blockSize; j++) {
_currentIV[j] ^= inputBuffer[inputOffset+i+j];
}
_cipher.Encrypt(_currentIV, 0, outputBuffer, outputOffset+i);
Array.Copy(outputBuffer, outputOffset+i, _currentIV, 0, _blockSize);
} else {
_cipher.Decrypt(inputBuffer, inputOffset+i, outputBuffer, outputOffset+i);
for (int j=0; j<_blockSize; j++) {
outputBuffer[outputOffset+i+j] ^= _currentIV[j];
}
Array.Copy(inputBuffer, inputOffset+i, _currentIV, 0, _blockSize);
}
}
return inputCount;
}