using System; using System.Collections.Generic; using System.Linq; using System.Text; using Renci.SshNet.Security.Cryptography.Ciphers; namespace Renci.SshNet.Security.Cryptography { /// /// Base class for block cipher implementations. /// public abstract class BlockCipher : SymmetricCipher { private CipherMode _mode; private CipherPadding _padding; /// /// Gets the size of the block in bytes. /// /// /// The size of the block in bytes. /// protected readonly int _blockSize; /// /// Gets the size of the block. /// /// /// The size of the block. /// public int BlockSize { get { return this._blockSize; } } /// /// Initializes a new instance of the class. /// /// The key. /// Size of the block. /// Cipher mode. /// Cipher padding. /// is null. protected BlockCipher(byte[] key, int blockSize, CipherMode mode, CipherPadding padding) : base(key) { this._blockSize = blockSize; this._mode = mode; this._padding = padding; this._mode.Init(this); } /// /// Encrypts the specified data. /// /// The data. /// Encrypted data public override byte[] Encrypt(byte[] data) { var output = new byte[data.Length]; if (data.Length % this._blockSize > 0) { if (this._padding == null) { throw new ArgumentException("data"); } else { data = this._padding.Pad(this._blockSize, data); } } var writtenBytes = 0; for (int i = 0; i < data.Length / this._blockSize; i++) { if (this._mode == null) { writtenBytes += this.EncryptBlock(data, i * this._blockSize, this._blockSize, output, i * this._blockSize); } else { writtenBytes += this._mode.EncryptBlock(data, i * this._blockSize, this._blockSize, output, i * this._blockSize); } } if (writtenBytes < data.Length) { throw new InvalidOperationException("Encryption error."); } return output; } /// /// Decrypts the specified data. /// /// The data. /// Decrypted data public override byte[] Decrypt(byte[] data) { if (data.Length % this._blockSize > 0) { { if (this._padding == null) { throw new ArgumentException("data"); } else { data = this._padding.Pad(this._blockSize, data); } } } var output = new byte[data.Length]; var writtenBytes = 0; for (int i = 0; i < data.Length / this._blockSize; i++) { if (this._mode == null) { writtenBytes += this.DecryptBlock(data, i * this._blockSize, this._blockSize, output, i * this._blockSize); } else { writtenBytes += this._mode.DecryptBlock(data, i * this._blockSize, this._blockSize, output, i * this._blockSize); } } if (writtenBytes < data.Length) { throw new InvalidOperationException("Encryption error."); } return output; } } }