AesCipher.cs 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.Security.Cryptography;
  3. using Org.BouncyCastle.Crypto.Paddings;
  4. using Renci.SshNet.Security.Cryptography.Ciphers.Modes;
  5. namespace Renci.SshNet.Security.Cryptography.Ciphers
  6. {
  7. /// <summary>
  8. /// AES cipher implementation.
  9. /// </summary>
  10. public sealed partial class AesCipher : BlockCipher, IDisposable
  11. {
  12. private readonly BlockCipher _impl;
  13. /// <summary>
  14. /// Initializes a new instance of the <see cref="AesCipher"/> class.
  15. /// </summary>
  16. /// <param name="key">The key.</param>
  17. /// <param name="iv">The IV.</param>
  18. /// <param name="mode">The mode.</param>
  19. /// <param name="pkcs7Padding">Enable PKCS7 padding.</param>
  20. /// <exception cref="ArgumentNullException"><paramref name="key"/> is <see langword="null"/>.</exception>
  21. /// <exception cref="ArgumentException">Keysize is not valid for this algorithm.</exception>
  22. public AesCipher(byte[] key, byte[] iv, AesCipherMode mode, bool pkcs7Padding = false)
  23. : base(key, 16, mode: null, padding: null)
  24. {
  25. if (mode == AesCipherMode.OFB)
  26. {
  27. // OFB is not supported on modern .NET
  28. _impl = new BlockImpl(key, new OfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null);
  29. }
  30. #if !NET
  31. else if (mode == AesCipherMode.CFB)
  32. {
  33. // CFB not supported on NetStandard 2.1
  34. _impl = new BlockImpl(key, new CfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null);
  35. }
  36. #endif
  37. else if (mode == AesCipherMode.CTR)
  38. {
  39. // CTR not supported by the BCL, use an optimized implementation
  40. _impl = new CtrImpl(key, iv);
  41. }
  42. else
  43. {
  44. _impl = new BclImpl(
  45. key,
  46. iv,
  47. (System.Security.Cryptography.CipherMode)mode,
  48. pkcs7Padding ? PaddingMode.PKCS7 : PaddingMode.None);
  49. }
  50. }
  51. /// <inheritdoc/>
  52. public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
  53. {
  54. return _impl.EncryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
  55. }
  56. /// <inheritdoc/>
  57. public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
  58. {
  59. return _impl.EncryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
  60. }
  61. /// <inheritdoc/>
  62. public override byte[] Encrypt(byte[] input, int offset, int length)
  63. {
  64. return _impl.Encrypt(input, offset, length);
  65. }
  66. /// <inheritdoc/>
  67. public override byte[] Decrypt(byte[] input, int offset, int length)
  68. {
  69. return _impl.Decrypt(input, offset, length);
  70. }
  71. /// <inheritdoc/>
  72. public void Dispose()
  73. {
  74. if (_impl is IDisposable disposableImpl)
  75. {
  76. disposableImpl.Dispose();
  77. }
  78. }
  79. }
  80. }