2
0

BlockCipherTest.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using System;
  2. using System.Linq;
  3. using Microsoft.VisualStudio.TestTools.UnitTesting;
  4. using Org.BouncyCastle.Crypto.Paddings;
  5. using Renci.SshNet.Security.Cryptography;
  6. using Renci.SshNet.Security.Cryptography.Ciphers;
  7. using Renci.SshNet.Security.Cryptography.Ciphers.Modes;
  8. using Renci.SshNet.Tests.Common;
  9. namespace Renci.SshNet.Tests.Classes.Security.Cryptography
  10. {
  11. [TestClass]
  12. public class BlockCipherTest : TestBase
  13. {
  14. [TestMethod]
  15. public void EncryptShouldTakeIntoAccountPaddingForLengthOfInputBufferPassedToEncryptBlock_InputNotDivisible()
  16. {
  17. var input = new byte[] { 0x2c, 0x1a, 0x05, 0x00, 0x68 };
  18. var output = new byte[] { 0x0a, 0x00, 0x03, 0x02, 0x06, 0x08, 0x07, 0x05 };
  19. var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
  20. var blockCipher = new BlockCipherStub(key, 8, null, new Pkcs7Padding())
  21. {
  22. EncryptBlockDelegate = (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset) =>
  23. {
  24. Assert.AreEqual(8, inputBuffer.Length);
  25. Buffer.BlockCopy(output, 0, outputBuffer, 0, output.Length);
  26. return inputBuffer.Length;
  27. }
  28. };
  29. var actual = blockCipher.Encrypt(input);
  30. Assert.IsTrue(output.SequenceEqual(actual));
  31. }
  32. [TestMethod]
  33. public void EncryptShouldTakeIntoAccountPaddingForLengthOfInputBufferPassedToEncryptBlock_InputDivisible()
  34. {
  35. var input = new byte[0];
  36. var output = new byte[] { 0x0a, 0x00, 0x03, 0x02, 0x06, 0x08, 0x07, 0x05 };
  37. var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
  38. var blockCipher = new BlockCipherStub(key, 8, null, new Pkcs7Padding())
  39. {
  40. EncryptBlockDelegate = (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset) =>
  41. {
  42. Assert.AreEqual(8, inputBuffer.Length);
  43. Buffer.BlockCopy(output, 0, outputBuffer, 0, output.Length);
  44. return inputBuffer.Length;
  45. }
  46. };
  47. var actual = blockCipher.Encrypt(input);
  48. Assert.IsTrue(output.SequenceEqual(actual));
  49. }
  50. [TestMethod]
  51. public void EncryptShouldTakeIntoAccountManualPaddingForLengthOfInputBufferPassedToDecryptBlockAndUnPaddingForTheFinalOutput_CFB()
  52. {
  53. var input = new byte[] { 0x0a, 0x00, 0x03, 0x02, 0x06 };
  54. var output = new byte[] { 0x2c, 0x1a, 0x05, 0x00, 0x68 };
  55. var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
  56. var blockCipher = new BlockCipherStub(key, 8, new CfbCipherModeStub(new byte[8]), null)
  57. {
  58. EncryptBlockDelegate = (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset) =>
  59. {
  60. Assert.AreEqual(8, inputBuffer.Length);
  61. Buffer.BlockCopy(output, 0, outputBuffer, 0, output.Length);
  62. return inputBuffer.Length;
  63. }
  64. };
  65. var actual = blockCipher.Encrypt(input);
  66. Assert.IsTrue(output.SequenceEqual(actual));
  67. }
  68. [TestMethod]
  69. public void DecryptShouldTakeIntoAccountUnPaddingForTheFinalOutput()
  70. {
  71. var input = new byte[] { 0x0a, 0x00, 0x03, 0x02, 0x06, 0x08, 0x07, 0x05 };
  72. var output = new byte[] { 0x2c, 0x1a, 0x05, 0x00, 0x68 };
  73. var padding = new byte[] { 0x03, 0x03, 0x03 };
  74. var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
  75. var blockCipher = new BlockCipherStub(key, 8, null, new Pkcs7Padding())
  76. {
  77. DecryptBlockDelegate = (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset) =>
  78. {
  79. Assert.AreEqual(8, outputBuffer.Length);
  80. Buffer.BlockCopy(output, 0, outputBuffer, 0, output.Length);
  81. Buffer.BlockCopy(padding, 0, outputBuffer, output.Length, padding.Length);
  82. return inputBuffer.Length;
  83. }
  84. };
  85. var actual = blockCipher.Decrypt(input);
  86. Assert.IsTrue(output.SequenceEqual(actual));
  87. }
  88. [TestMethod]
  89. public void DecryptShouldTakeIntoAccountManualPaddingForLengthOfInputBufferPassedToDecryptBlockAndUnPaddingForTheFinalOutput_CFB()
  90. {
  91. var input = new byte[] { 0x0a, 0x00, 0x03, 0x02, 0x06 };
  92. var output = new byte[] { 0x2c, 0x1a, 0x05, 0x00, 0x68 };
  93. var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
  94. var blockCipher = new BlockCipherStub(key, 8, new CfbCipherModeStub(new byte[8]), null)
  95. {
  96. DecryptBlockDelegate = (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset) =>
  97. {
  98. Assert.AreEqual(8, inputBuffer.Length);
  99. Buffer.BlockCopy(output, 0, outputBuffer, 0, output.Length);
  100. return inputBuffer.Length;
  101. }
  102. };
  103. var actual = blockCipher.Decrypt(input);
  104. Assert.IsTrue(output.SequenceEqual(actual));
  105. }
  106. private class BlockCipherStub : BlockCipher
  107. {
  108. public Func<byte[], int, int, byte[], int, int> EncryptBlockDelegate;
  109. public Func<byte[], int, int, byte[], int, int> DecryptBlockDelegate;
  110. public BlockCipherStub(byte[] key, byte blockSize, CipherMode mode, IBlockCipherPadding padding) : base(key, blockSize, mode, padding)
  111. {
  112. }
  113. public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
  114. {
  115. return EncryptBlockDelegate(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
  116. }
  117. public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
  118. {
  119. return DecryptBlockDelegate(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
  120. }
  121. }
  122. private class CfbCipherModeStub : CfbCipherMode
  123. {
  124. public CfbCipherModeStub(byte[] iv)
  125. : base(iv)
  126. {
  127. }
  128. public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
  129. {
  130. return Cipher.EncryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
  131. }
  132. public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
  133. {
  134. return Cipher.DecryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
  135. }
  136. }
  137. }
  138. }