using System;
using System.Globalization;
namespace Renci.SshNet.Security.Cryptography.Ciphers.Modes
{
///
/// Implements OFB cipher mode.
///
public class OfbCipherMode : CipherMode
{
private readonly byte[] _ivOutput;
///
/// Initializes a new instance of the class.
///
/// The iv.
public OfbCipherMode(byte[] iv)
: base(iv)
{
_ivOutput = new byte[iv.Length];
}
///
/// Encrypts the specified region of the input byte array and copies the encrypted data to the specified region of the output byte array.
///
/// The input data to encrypt.
/// The offset into the input byte array from which to begin using data.
/// The number of bytes in the input byte array to use as data.
/// The output to which to write encrypted data.
/// The offset into the output byte array from which to begin writing data.
///
/// The number of bytes encrypted.
///
public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
if (inputBuffer.Length - inputOffset < _blockSize)
{
throw new ArgumentException("Invalid input buffer");
}
if (outputBuffer.Length - outputOffset < _blockSize)
{
throw new ArgumentException("Invalid output buffer");
}
if (inputCount != _blockSize)
{
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "inputCount must be {0}.", _blockSize));
}
_ = Cipher.EncryptBlock(IV, 0, IV.Length, _ivOutput, 0);
Buffer.BlockCopy(_ivOutput, 0, IV, 0, IV.Length);
for (var i = 0; i < _blockSize; i++)
{
outputBuffer[outputOffset + i] = (byte)(_ivOutput[i] ^ inputBuffer[inputOffset + i]);
}
return _blockSize;
}
///
/// Decrypts the specified region of the input byte array and copies the decrypted data to the specified region of the output byte array.
///
/// The input data to decrypt.
/// The offset into the input byte array from which to begin using data.
/// The number of bytes in the input byte array to use as data.
/// The output to which to write decrypted data.
/// The offset into the output byte array from which to begin writing data.
///
/// The number of bytes decrypted.
///
public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
return EncryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
}
}
}