using System; using System.Security.Cryptography; using Org.BouncyCastle.Crypto.Paddings; using Renci.SshNet.Security.Cryptography.Ciphers.Modes; namespace Renci.SshNet.Security.Cryptography.Ciphers { /// /// AES cipher implementation. /// public sealed partial class AesCipher : BlockCipher, IDisposable { private readonly BlockCipher _impl; /// /// Initializes a new instance of the class. /// /// The key. /// The IV. /// The mode. /// Enable PKCS7 padding. /// is . /// Keysize is not valid for this algorithm. public AesCipher(byte[] key, byte[] iv, AesCipherMode mode, bool pkcs7Padding = false) : base(key, 16, mode: null, padding: null) { if (mode == AesCipherMode.OFB) { // OFB is not supported on modern .NET _impl = new BlockImpl(key, new OfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null); } #if !NET else if (mode == AesCipherMode.CFB) { // CFB not supported on NetStandard 2.1 _impl = new BlockImpl(key, new CfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null); } #endif else if (mode == AesCipherMode.CTR) { // CTR not supported by the BCL, use an optimized implementation _impl = new CtrImpl(key, iv); } else { _impl = new BclImpl( key, iv, (System.Security.Cryptography.CipherMode)mode, pkcs7Padding ? PaddingMode.PKCS7 : PaddingMode.None); } } /// public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { return _impl.EncryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset); } /// public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { return _impl.EncryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset); } /// public override byte[] Encrypt(byte[] input, int offset, int length) { return _impl.Encrypt(input, offset, length); } /// public override byte[] Decrypt(byte[] input, int offset, int length) { return _impl.Decrypt(input, offset, length); } /// public void Dispose() { if (_impl is IDisposable disposableImpl) { disposableImpl.Dispose(); } } } }