using System.Linq;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Renci.SshNet.Common;
using Renci.SshNet.Security.Cryptography.Ciphers;
using Renci.SshNet.Tests.Common;

namespace Renci.SshNet.Tests.Classes.Security.Cryptography.Ciphers
{
    /// <summary>
    ///
    /// </summary>
    [TestClass]
    public class AesCipherTest : TestBase
    {
        [TestMethod]
        public void AES_CTR_Encrypt_Should_Preserve_Cipher_Stream_State()
        {
            var input = new byte[]
            {
                0x9b, 0x6e, 0x1d, 0xf8, 0x07, 0xf9, 0x55, 0xd4, 0xd7, 0x1a, 0xce, 0xca, 0xa8, 0x31, 0x29, 0x0f,
                0x63, 0x4d, 0x52, 0x71, 0xa5, 0x0c, 0x96, 0x08, 0xd6, 0xc5, 0x14, 0xa0, 0xc8, 0x29, 0xb1, 0xd5,
                0x40, 0x2c, 0xe5, 0xa9, 0xb4, 0x31, 0xa9, 0xa8, 0x76, 0xa5, 0x1e, 0x7a, 0xc8, 0x09, 0x32, 0x39,
                0xbc, 0x89, 0x7a, 0x22, 0x42, 0x2c, 0xba, 0x8e, 0xd7, 0x15, 0x22, 0x41, 0xe4, 0xb5, 0x0b, 0xad,
            };
            var key = new byte[]
            {
                0x69, 0xf9, 0x8a, 0x7c, 0x4b, 0x80, 0x5b, 0x31, 0xa4, 0xaa, 0xfa, 0xff, 0xed, 0x1c, 0x3f, 0xcc,
            };
            var iv = new byte[]
            {
                0x92, 0xdb, 0xe4, 0x3e, 0xaf, 0x8f, 0x92, 0x13, 0x71, 0x56, 0xd1, 0x9f, 0x0f, 0x68, 0xc3, 0xc1,
            };

            // echo -n -e '\x9b\x6e\x1d\xf8\x07\xf9\x55\xd4\xd7\x1a\xce\xca\xa8\x31\x29\x0f\x63\x4d\x52\x71\xa5\x0c\x96\x08\xd6\xc5\x14\xa0\xc8\x29\xb1\xd5\x40\x2c\xe5\xa9\xb4\x31\xa9\xa8\x76\xa5\x1e\x7a\xc8\x09\x32\x39\xbc\x89\x7a\x22\x42\x2c\xba\x8e\xd7\x15\x22\x41\xe4\xb5\x0b\xad' | openssl enc -e -aes-128-ctr -K 69F98A7C4B805B31A4AAFAFFED1C3FCC -iv 92DBE43EAF8F92137156D19F0F68C3C1 -nopad | hd
            var expected = new byte[]
            {
                0xc0, 0x69, 0x4b, 0xdb, 0xb2, 0x0c, 0x22, 0x82, 0xf0, 0x85, 0x77, 0x3e, 0xd9, 0x5a, 0xe7, 0x9e,
                0xb0, 0x34, 0xe8, 0x95, 0x8e, 0x93, 0x0a, 0xcf, 0xa4, 0x26, 0xd3, 0x80, 0x12, 0xcc, 0x06, 0x38,
                0x1d, 0x18, 0x55, 0xfc, 0x56, 0x59, 0xaf, 0x0b, 0x2b, 0x80, 0x87, 0x0c, 0x87, 0x45, 0xb0, 0xe2,
                0xec, 0x47, 0x81, 0x82, 0x89, 0x24, 0x76, 0xe2, 0x20, 0x6a, 0x99, 0xe2, 0xa7, 0x5a, 0xb0, 0x40,
            };

            var cipher = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false);
            var actual1 = cipher.Encrypt(input.Take(32));
            var actual2 = cipher.Encrypt(input.Take(32, 32));

            CollectionAssert.AreEqual(expected.Take(32), actual1);
            CollectionAssert.AreEqual(expected.Take(32, 32), actual2);
        }

        [TestMethod]
        public void AES_CTR_Decrypt_Should_Preserve_Cipher_Stream_State()
        {
            var input = new byte[]
            {
                0xc0, 0x69, 0x4b, 0xdb, 0xb2, 0x0c, 0x22, 0x82, 0xf0, 0x85, 0x77, 0x3e, 0xd9, 0x5a, 0xe7, 0x9e,
                0xb0, 0x34, 0xe8, 0x95, 0x8e, 0x93, 0x0a, 0xcf, 0xa4, 0x26, 0xd3, 0x80, 0x12, 0xcc, 0x06, 0x38,
                0x1d, 0x18, 0x55, 0xfc, 0x56, 0x59, 0xaf, 0x0b, 0x2b, 0x80, 0x87, 0x0c, 0x87, 0x45, 0xb0, 0xe2,
                0xec, 0x47, 0x81, 0x82, 0x89, 0x24, 0x76, 0xe2, 0x20, 0x6a, 0x99, 0xe2, 0xa7, 0x5a, 0xb0, 0x40,
            };
            var key = new byte[]
            {
                0x69, 0xf9, 0x8a, 0x7c, 0x4b, 0x80, 0x5b, 0x31, 0xa4, 0xaa, 0xfa, 0xff, 0xed, 0x1c, 0x3f, 0xcc,
            };
            var iv = new byte[]
            {
                0x92, 0xdb, 0xe4, 0x3e, 0xaf, 0x8f, 0x92, 0x13, 0x71, 0x56, 0xd1, 0x9f, 0x0f, 0x68, 0xc3, 0xc1,
            };

            // echo -n -e '\x9b\x6e\x1d\xf8\x07\xf9\x55\xd4\xd7\x1a\xce\xca\xa8\x31\x29\x0f\x63\x4d\x52\x71\xa5\x0c\x96\x08\xd6\xc5\x14\xa0\xc8\x29\xb1\xd5\x40\x2c\xe5\xa9\xb4\x31\xa9\xa8\x76\xa5\x1e\x7a\xc8\x09\x32\x39\xbc\x89\x7a\x22\x42\x2c\xba\x8e\xd7\x15\x22\x41\xe4\xb5\x0b\xad' | openssl enc -e -aes-128-ctr -K 69F98A7C4B805B31A4AAFAFFED1C3FCC -iv 92DBE43EAF8F92137156D19F0F68C3C1 -nopad | hd
            var expected = new byte[]
            {
                0x9b, 0x6e, 0x1d, 0xf8, 0x07, 0xf9, 0x55, 0xd4, 0xd7, 0x1a, 0xce, 0xca, 0xa8, 0x31, 0x29, 0x0f,
                0x63, 0x4d, 0x52, 0x71, 0xa5, 0x0c, 0x96, 0x08, 0xd6, 0xc5, 0x14, 0xa0, 0xc8, 0x29, 0xb1, 0xd5,
                0x40, 0x2c, 0xe5, 0xa9, 0xb4, 0x31, 0xa9, 0xa8, 0x76, 0xa5, 0x1e, 0x7a, 0xc8, 0x09, 0x32, 0x39,
                0xbc, 0x89, 0x7a, 0x22, 0x42, 0x2c, 0xba, 0x8e, 0xd7, 0x15, 0x22, 0x41, 0xe4, 0xb5, 0x0b, 0xad,
            };

            var cipher = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false);
            var actual1 = cipher.Decrypt(input.Take(32));
            var actual2 = cipher.Decrypt(input.Take(32, 32));

            CollectionAssert.AreEqual(expected.Take(32), actual1);
            CollectionAssert.AreEqual(expected.Take(32, 32), actual2);
        }

        [TestMethod]
        public void AES_CTR_IV_Overflow()
        {
            var input = new byte[]
            {
                0x03, 0xe1, 0xe1, 0xaa, 0xa5, 0xbc, 0xa1, 0x9f, 0xba, 0x8c, 0x42, 0x05, 0x8b, 0x4a, 0xbf, 0x28,
                0x96, 0x39, 0xec, 0x0d, 0xfc, 0x2d, 0xb2, 0x7c, 0xe9, 0x74, 0x8e, 0x5f, 0xb9, 0xf3, 0x99, 0xce,
                0xe1, 0x1a, 0x5c, 0x51, 0xa3, 0x1d, 0xd7, 0x1b, 0x15, 0x8c, 0xad, 0xa6, 0xaf, 0x63, 0x0d, 0x8c,
                0x1a, 0xf1, 0x3a, 0x35, 0x8c, 0xca, 0x3f, 0xd6, 0x2f, 0x65, 0xc1, 0x31, 0x2d, 0x41, 0xe5, 0xc7,
            };
            var key = new byte[]
            {
                0xf3, 0x74, 0x23, 0x71, 0xed, 0x6d, 0x84, 0x79, 0x61, 0xd0, 0xf8, 0x6f, 0x7f, 0x0c, 0xcc, 0x86,
                0x67, 0x02, 0x45, 0xc8, 0xb8, 0x64, 0x42, 0x17, 0xda, 0x85, 0x21, 0x3e, 0x5c, 0xa6, 0xee, 0xd4,
            };
            var iv = new byte[]
            {
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
            };

            // echo -n -e '\x03\xe1\xe1\xaa\xa5\xbc\xa1\x9f\xba\x8c\x42\x05\x8b\x4a\xbf\x28\x96\x39\xec\x0d\xfc\x2d\xb2\x7c\xe9\x74\x8e\x5f\xb9\xf3\x99\xce\xe1\x1a\x5c\x51\xa3\x1d\xd7\x1b\x15\x8c\xad\xa6\xaf\x63\x0d\x8c\x1a\xf1\x3a\x35\x8c\xca\x3f\xd6\x2f\x65\xc1\x31\x2d\x41\xe5\xc7' | openssl enc -e -aes-256-ctr -K F3742371ED6D847961D0F86F7F0CCC86670245C8B8644217DA85213E5CA6EED4 -iv FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -nopad | hd
            var expected = new byte[]
            {
                0x4e, 0xfa, 0xa2, 0x01, 0x5c, 0x5f, 0x3a, 0x55, 0x33, 0x53, 0x51, 0xda, 0xdf, 0xa5, 0xab, 0x7e,
                0x57, 0x93, 0x2d, 0xe6, 0x99, 0x4a, 0x58, 0x56, 0xcb, 0x19, 0x9f, 0x88, 0xe1, 0xa8, 0x7b, 0xcd,
                0x3d, 0x8e, 0xdd, 0x10, 0xc8, 0xb3, 0x60, 0xb0, 0x2b, 0xaf, 0x92, 0xfe, 0x39, 0x47, 0x35, 0xcc,
                0xfd, 0x34, 0xc5, 0x81, 0xfa, 0xb9, 0xe3, 0xc4, 0x10, 0xed, 0x06, 0x6e, 0x91, 0x5e, 0xfc, 0x47,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }


        [TestMethod]
        public void Encrypt_InputAndOffsetAndLength_128_CBC()
        {
            // 2 dummy bytes before and 3 after the input from test case above
            var input = new byte[] { 0x05, 0x07, 0x00, 0x00, 0x00, 0x2c, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x73, 0x73, 0x68, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x61, 0x75, 0x74, 0x68, 0x30, 0x9e, 0xe0, 0x9c, 0x12, 0xee, 0x3a, 0x30, 0x03, 0x52, 0x1c, 0x1a, 0xe7, 0x3e, 0x0b, 0x9a, 0xcf, 0x9a, 0x57, 0x42, 0x0b, 0x4f, 0x4a, 0x15, 0xa0, 0xf5, 0x0f, 0x0d, 0x03 };
            var key = new byte[] { 0xe4, 0x94, 0xf9, 0xb1, 0x00, 0x4f, 0x16, 0x2a, 0x80, 0x11, 0xea, 0x73, 0x0d, 0xb9, 0xbf, 0x64 };
            var iv = new byte[] { 0x74, 0x8b, 0x4f, 0xe6, 0xc1, 0x29, 0xb3, 0x54, 0xec, 0x77, 0x92, 0xf3, 0x15, 0xa0, 0x41, 0xa8 };
            var expected = new byte[] { 0x19, 0x7f, 0x80, 0xd8, 0xc9, 0x89, 0xc4, 0xa7, 0xc6, 0xc6, 0x3f, 0x9f, 0x1e, 0x00, 0x1f, 0x72, 0xa7, 0x5e, 0xde, 0x40, 0x88, 0xa2, 0x72, 0xf2, 0xed, 0x3f, 0x81, 0x45, 0xb6, 0xbd, 0x45, 0x87, 0x15, 0xa5, 0x10, 0x92, 0x4a, 0x37, 0x9e, 0xa9, 0x80, 0x1c, 0x14, 0x83, 0xa3, 0x39, 0x45, 0x28 };
            var testCipher = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false);

            var actual = testCipher.Encrypt(input, 2, input.Length - 5);

            Assert.IsTrue(actual.IsEqualTo(expected));
        }

        [TestMethod]
        public void Encrypt_Input_128_CTR()
        {
            var input = new byte[] { 0x00, 0x00, 0x00, 0x2c, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x73, 0x73, 0x68, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x61, 0x75, 0x74, 0x68, 0xb0, 0x74, 0x21, 0x87, 0x16, 0xb9, 0x69, 0x48, 0x33, 0xce, 0xb3, 0xe7, 0xdc, 0x3f, 0x50, 0xdc, 0xcc, 0xd5, 0x27, 0xb7, 0xfe, 0x7a, 0x78, 0x22, 0xae, 0xc8 };
            var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
            var iv = new byte[] { 0xe6, 0x65, 0x36, 0x0d, 0xdd, 0xd7, 0x50, 0xc3, 0x48, 0xdb, 0x48, 0x07, 0xa1, 0x30, 0xd2, 0x38 };
            var expected = new byte[] { 0xca, 0xfb, 0x1c, 0x49, 0xbf, 0x82, 0x2a, 0xbb, 0x1c, 0x52, 0xc7, 0x86, 0x22, 0x8a, 0xe5, 0xa4, 0xf3, 0xda, 0x4e, 0x1c, 0x3a, 0x87, 0x41, 0x1c, 0xd2, 0x6e, 0x76, 0xdc, 0xc2, 0xe9, 0xc2, 0x0e, 0xf5, 0xc7, 0xbd, 0x12, 0x85, 0xfa, 0x0e, 0xda, 0xee, 0x50, 0xd7, 0xfd, 0x81, 0x34, 0x25, 0x6d };
            var testCipher = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false);

            var actual = testCipher.Encrypt(input);

            Assert.IsTrue(actual.IsEqualTo(expected));
        }

        [TestMethod]
        public void Decrypt_Input_128_CTR()
        {
            var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
            var iv = new byte[] { 0xe6, 0x65, 0x36, 0x0d, 0xdd, 0xd7, 0x50, 0xc3, 0x48, 0xdb, 0x48, 0x07, 0xa1, 0x30, 0xd2, 0x38 };
            var input = new byte[] { 0xca, 0xfb, 0x1c, 0x49, 0xbf, 0x82, 0x2a, 0xbb, 0x1c, 0x52, 0xc7, 0x86, 0x22, 0x8a, 0xe5, 0xa4, 0xf3, 0xda, 0x4e, 0x1c, 0x3a, 0x87, 0x41, 0x1c, 0xd2, 0x6e, 0x76, 0xdc, 0xc2, 0xe9, 0xc2, 0x0e, 0xf5, 0xc7, 0xbd, 0x12, 0x85, 0xfa, 0x0e, 0xda, 0xee, 0x50, 0xd7, 0xfd, 0x81, 0x34, 0x25, 0x6d };
            var expected = new byte[] { 0x00, 0x00, 0x00, 0x2c, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x73, 0x73, 0x68, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x61, 0x75, 0x74, 0x68, 0xb0, 0x74, 0x21, 0x87, 0x16, 0xb9, 0x69, 0x48, 0x33, 0xce, 0xb3, 0xe7, 0xdc, 0x3f, 0x50, 0xdc, 0xcc, 0xd5, 0x27, 0xb7, 0xfe, 0x7a, 0x78, 0x22, 0xae, 0xc8 };
            var testCipher = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false);

            var actual = testCipher.Decrypt(input);

            Assert.IsTrue(expected.IsEqualTo(actual));
        }

        [TestMethod]
        public void Decrypt_InputAndOffsetAndLength_128_CTR()
        {
            var key = new byte[] { 0x17, 0x78, 0x56, 0xe1, 0x3e, 0xbd, 0x3e, 0x50, 0x1d, 0x79, 0x3f, 0x0f, 0x55, 0x37, 0x45, 0x54 };
            var iv = new byte[] { 0xe6, 0x65, 0x36, 0x0d, 0xdd, 0xd7, 0x50, 0xc3, 0x48, 0xdb, 0x48, 0x07, 0xa1, 0x30, 0xd2, 0x38 };
            var input = new byte[] { 0x0a, 0xca, 0xfb, 0x1c, 0x49, 0xbf, 0x82, 0x2a, 0xbb, 0x1c, 0x52, 0xc7, 0x86, 0x22, 0x8a, 0xe5, 0xa4, 0xf3, 0xda, 0x4e, 0x1c, 0x3a, 0x87, 0x41, 0x1c, 0xd2, 0x6e, 0x76, 0xdc, 0xc2, 0xe9, 0xc2, 0x0e, 0xf5, 0xc7, 0xbd, 0x12, 0x85, 0xfa, 0x0e, 0xda, 0xee, 0x50, 0xd7, 0xfd, 0x81, 0x34, 0x25, 0x6d, 0x0a, 0x05 };
            var expected = new byte[] { 0x00, 0x00, 0x00, 0x2c, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x73, 0x73, 0x68, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x61, 0x75, 0x74, 0x68, 0xb0, 0x74, 0x21, 0x87, 0x16, 0xb9, 0x69, 0x48, 0x33, 0xce, 0xb3, 0xe7, 0xdc, 0x3f, 0x50, 0xdc, 0xcc, 0xd5, 0x27, 0xb7, 0xfe, 0x7a, 0x78, 0x22, 0xae, 0xc8 };
            var testCipher = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false);

            var actual = testCipher.Decrypt(input, 1, input.Length - 3);

            Assert.IsTrue(expected.IsEqualTo(actual));
        }

        // All tests below this line were generated by the script in AesCipherTest.Gen.cs.txt
        [TestMethod]
        public void AES_ECB_128_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x03, 0xe1, 0xe1, 0xaa, 0xa5, 0xbc, 0xa1, 0x9f, 0xba, 0x8c, 0x42, 0x05, 0x8b, 0x4a, 0xbf, 0x28,
            };
            var key = new byte[]
            {
                0x96, 0x39, 0xec, 0x0d, 0xfc, 0x2d, 0xb2, 0x7c, 0xe9, 0x74, 0x8e, 0x5f, 0xb9, 0xf3, 0x99, 0xce,
            };

            // echo -n -e '\x03\xe1\xe1\xaa\xa5\xbc\xa1\x9f\xba\x8c\x42\x05\x8b\x4a\xbf\x28' | openssl enc -e -aes-128-ecb -K 9639EC0DFC2DB27CE9748E5FB9F399CE -nopad | hd
            var expected = new byte[]
            {
                0x9d, 0x55, 0x05, 0x4e, 0xe9, 0x50, 0xb5, 0x93, 0x50, 0x93, 0x69, 0x96, 0xa6, 0xdd, 0x1e, 0x15,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_128_Length16_Pad()
        {
            var input = new byte[]
            {
                0x1a, 0xf1, 0x3a, 0x35, 0x8c, 0xca, 0x3f, 0xd6, 0x2f, 0x65, 0xc1, 0x31, 0x2d, 0x41, 0xe5, 0xc7,
            };
            var key = new byte[]
            {
                0xf3, 0x74, 0x23, 0x71, 0xed, 0x6d, 0x84, 0x79, 0x61, 0xd0, 0xf8, 0x6f, 0x7f, 0x0c, 0xcc, 0x86,
            };

            // echo -n -e '\x1a\xf1\x3a\x35\x8c\xca\x3f\xd6\x2f\x65\xc1\x31\x2d\x41\xe5\xc7' | openssl enc -e -aes-128-ecb -K F3742371ED6D847961D0F86F7F0CCC86 | hd
            var expected = new byte[]
            {
                0x98, 0xe4, 0x1f, 0x67, 0xe2, 0x4c, 0x0b, 0x7a, 0x73, 0x1e, 0x14, 0xd3, 0x04, 0x1e, 0xe7, 0x4e,
                0x5b, 0x27, 0x39, 0x52, 0x46, 0x1d, 0x16, 0x28, 0xc7, 0xec, 0x1f, 0x65, 0x7f, 0x67, 0x76, 0x70,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_128_Length35_Pad()
        {
            var input = new byte[]
            {
                0xa7, 0xe6, 0xb3, 0x3b, 0x3f, 0x9c, 0x9e, 0xac, 0x6c, 0xc1, 0xd3, 0xbb, 0xd2, 0xd0, 0x57, 0x22,
                0x99, 0x3a, 0xc9, 0x2b, 0xfb, 0x1d, 0x0e, 0x8e, 0x31, 0x0c, 0x96, 0x68, 0x4c, 0x46, 0x1d, 0xbb,
                0xe1, 0x23, 0xc8,
            };
            var key = new byte[]
            {
                0x99, 0x59, 0x90, 0x47, 0xcb, 0x63, 0x99, 0x5b, 0xf7, 0x91, 0x87, 0x44, 0x09, 0x2e, 0xff, 0xa4,
            };

            // echo -n -e '\xa7\xe6\xb3\x3b\x3f\x9c\x9e\xac\x6c\xc1\xd3\xbb\xd2\xd0\x57\x22\x99\x3a\xc9\x2b\xfb\x1d\x0e\x8e\x31\x0c\x96\x68\x4c\x46\x1d\xbb\xe1\x23\xc8' | openssl enc -e -aes-128-ecb -K 99599047CB63995BF7918744092EFFA4 | hd
            var expected = new byte[]
            {
                0x11, 0x02, 0x21, 0xec, 0xd6, 0x55, 0x22, 0x24, 0x8f, 0x64, 0xb5, 0x89, 0xc3, 0x4e, 0x8a, 0x18,
                0x6d, 0xf6, 0x39, 0x72, 0xae, 0x4d, 0x6e, 0x3f, 0xf7, 0x30, 0x88, 0xa7, 0xd7, 0xa6, 0x23, 0xed,
                0xb1, 0xe2, 0x80, 0xcc, 0x21, 0x98, 0xa1, 0x26, 0x28, 0xac, 0x0b, 0x61, 0x19, 0x9d, 0xda, 0xaa,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_128_Length64_NoPad()
        {
            var input = new byte[]
            {
                0xaf, 0x08, 0xbe, 0xc9, 0x08, 0xf3, 0xfe, 0xc7, 0x61, 0xc2, 0x17, 0xfd, 0xaa, 0xc7, 0x8d, 0x3a,
                0x4c, 0xa2, 0xfb, 0xde, 0x1e, 0x49, 0x3e, 0xc1, 0x34, 0x86, 0x14, 0xc6, 0x2d, 0x39, 0x35, 0x52,
                0x79, 0xad, 0x95, 0x01, 0x6f, 0x36, 0x9b, 0x2e, 0xde, 0xfc, 0x77, 0xc7, 0xc0, 0x27, 0x60, 0x6b,
                0x78, 0xfc, 0x13, 0x83, 0xa8, 0x38, 0xbb, 0x65, 0xca, 0xfd, 0x94, 0x82, 0xde, 0x38, 0x99, 0x28,
            };
            var key = new byte[]
            {
                0x8c, 0xc4, 0x84, 0xfd, 0x32, 0x8c, 0xca, 0x16, 0x06, 0xcc, 0x00, 0x22, 0xd2, 0x76, 0x00, 0x0d,
            };

            // echo -n -e '\xaf\x08\xbe\xc9\x08\xf3\xfe\xc7\x61\xc2\x17\xfd\xaa\xc7\x8d\x3a\x4c\xa2\xfb\xde\x1e\x49\x3e\xc1\x34\x86\x14\xc6\x2d\x39\x35\x52\x79\xad\x95\x01\x6f\x36\x9b\x2e\xde\xfc\x77\xc7\xc0\x27\x60\x6b\x78\xfc\x13\x83\xa8\x38\xbb\x65\xca\xfd\x94\x82\xde\x38\x99\x28' | openssl enc -e -aes-128-ecb -K 8CC484FD328CCA1606CC0022D276000D -nopad | hd
            var expected = new byte[]
            {
                0x10, 0xd6, 0x91, 0xf1, 0x57, 0x19, 0xf5, 0x64, 0x28, 0x15, 0xcc, 0xfe, 0x65, 0x6c, 0x65, 0xca,
                0x1b, 0x93, 0xe2, 0xfd, 0xfc, 0x0b, 0x1d, 0xe5, 0x94, 0x08, 0xb4, 0xd8, 0x8a, 0x0a, 0x38, 0xb7,
                0x3a, 0x8d, 0x4c, 0x6b, 0x80, 0x18, 0x61, 0xb8, 0x97, 0x02, 0x63, 0xcc, 0xe1, 0x98, 0xf3, 0xe4,
                0x5a, 0xf4, 0xf8, 0x16, 0xc6, 0xf2, 0xdd, 0x6d, 0x51, 0x4d, 0x42, 0xa9, 0x59, 0xdc, 0xb2, 0x01,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_128_Length64_Pad()
        {
            var input = new byte[]
            {
                0x62, 0x4f, 0x3b, 0xfb, 0xa3, 0x63, 0x38, 0xec, 0x32, 0xfd, 0x7d, 0xdb, 0x38, 0x99, 0x93, 0x53,
                0xfc, 0x86, 0x5d, 0x35, 0xe9, 0x68, 0x02, 0xda, 0x1a, 0x43, 0x0b, 0x02, 0x55, 0x57, 0x74, 0xed,
                0x7d, 0x5a, 0xbf, 0x82, 0x3b, 0x05, 0x6a, 0xc2, 0x70, 0x62, 0xff, 0x28, 0x34, 0xce, 0x08, 0x58,
                0x9c, 0xe3, 0x76, 0x1b, 0xbb, 0x1a, 0xbc, 0xf9, 0x4c, 0x60, 0xe1, 0x5f, 0x57, 0x35, 0x96, 0xda,
            };
            var key = new byte[]
            {
                0x89, 0x8f, 0x5e, 0xde, 0xd9, 0x10, 0x17, 0xf6, 0x1b, 0x9a, 0xc4, 0x87, 0x69, 0xda, 0xa5, 0x4b,
            };

            // echo -n -e '\x62\x4f\x3b\xfb\xa3\x63\x38\xec\x32\xfd\x7d\xdb\x38\x99\x93\x53\xfc\x86\x5d\x35\xe9\x68\x02\xda\x1a\x43\x0b\x02\x55\x57\x74\xed\x7d\x5a\xbf\x82\x3b\x05\x6a\xc2\x70\x62\xff\x28\x34\xce\x08\x58\x9c\xe3\x76\x1b\xbb\x1a\xbc\xf9\x4c\x60\xe1\x5f\x57\x35\x96\xda' | openssl enc -e -aes-128-ecb -K 898F5EDED91017F61B9AC48769DAA54B | hd
            var expected = new byte[]
            {
                0x32, 0x60, 0x39, 0xf6, 0x08, 0xc9, 0xd4, 0xed, 0x52, 0xca, 0x50, 0x4e, 0xaa, 0x09, 0x8c, 0x82,
                0x40, 0xe3, 0xe6, 0x06, 0x35, 0xa8, 0xd4, 0xae, 0xdb, 0xa3, 0xb8, 0x8a, 0xf3, 0xb6, 0x21, 0x8e,
                0x77, 0xad, 0xdb, 0x3c, 0xca, 0x06, 0xff, 0x50, 0xa7, 0x87, 0x35, 0xf7, 0x22, 0xd8, 0x39, 0x51,
                0x31, 0x06, 0x1f, 0x6d, 0x63, 0x9b, 0x0f, 0xe6, 0xc0, 0xc6, 0x22, 0x08, 0xff, 0x87, 0xaf, 0xbb,
                0x3d, 0xc3, 0x0b, 0x2e, 0x7b, 0xd4, 0x20, 0x23, 0xb4, 0xb9, 0x2e, 0x07, 0x73, 0x37, 0x92, 0x80,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_192_Length16_NoPad()
        {
            var input = new byte[]
            {
                0xcb, 0x24, 0x9f, 0xa4, 0x6f, 0x29, 0x7e, 0x8b, 0xcb, 0x7f, 0xff, 0x21, 0x56, 0x34, 0x90, 0x72,
            };
            var key = new byte[]
            {
                0xba, 0x95, 0x23, 0xa3, 0xcf, 0x25, 0xfa, 0x30, 0x5e, 0xfc, 0x40, 0x13, 0xda, 0x3d, 0xd3, 0x10,
                0x2f, 0x89, 0xbc, 0x44, 0x3a, 0x01, 0xdb, 0x11,
            };

            // echo -n -e '\xcb\x24\x9f\xa4\x6f\x29\x7e\x8b\xcb\x7f\xff\x21\x56\x34\x90\x72' | openssl enc -e -aes-192-ecb -K BA9523A3CF25FA305EFC4013DA3DD3102F89BC443A01DB11 -nopad | hd
            var expected = new byte[]
            {
                0x6b, 0x19, 0xbc, 0x1a, 0xe8, 0xf5, 0x3c, 0x9a, 0xbb, 0xaf, 0xb2, 0x28, 0xe1, 0x99, 0xd4, 0x81,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_192_Length16_Pad()
        {
            var input = new byte[]
            {
                0x2a, 0x6f, 0x46, 0x73, 0xe9, 0x6b, 0xb1, 0x8e, 0xac, 0xef, 0xf1, 0xcc, 0x78, 0x4b, 0x38, 0xb9,
            };
            var key = new byte[]
            {
                0xba, 0x12, 0x6e, 0xf4, 0x7f, 0x99, 0xd7, 0x4d, 0xef, 0xd7, 0xdd, 0x16, 0x1d, 0x45, 0x29, 0x67,
                0x1d, 0x16, 0x1a, 0xcb, 0xba, 0x67, 0x28, 0xc9,
            };

            // echo -n -e '\x2a\x6f\x46\x73\xe9\x6b\xb1\x8e\xac\xef\xf1\xcc\x78\x4b\x38\xb9' | openssl enc -e -aes-192-ecb -K BA126EF47F99D74DEFD7DD161D4529671D161ACBBA6728C9 | hd
            var expected = new byte[]
            {
                0x58, 0xfc, 0x36, 0xd8, 0xc1, 0x97, 0x8e, 0x7a, 0x1a, 0x77, 0xcf, 0x2f, 0xa1, 0x9b, 0x7b, 0x0b,
                0x95, 0x9a, 0x5d, 0x23, 0x23, 0x58, 0x25, 0x2d, 0x5f, 0x33, 0xc1, 0x9e, 0x6b, 0x68, 0xa2, 0x1e,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_192_Length35_Pad()
        {
            var input = new byte[]
            {
                0x97, 0xf9, 0x84, 0x12, 0x8e, 0x9b, 0x71, 0x66, 0xc6, 0x8a, 0xaf, 0x61, 0x31, 0x6c, 0xff, 0x52,
                0xea, 0xa5, 0xcb, 0x68, 0xe4, 0x6e, 0x2e, 0xb0, 0xe6, 0xf3, 0x8a, 0xb7, 0x72, 0x53, 0x0e, 0xa6,
                0xf0, 0x89, 0x33,
            };
            var key = new byte[]
            {
                0xc1, 0xe3, 0x16, 0x3b, 0x8d, 0xa6, 0x4d, 0xa3, 0x94, 0x8f, 0x8f, 0xb8, 0x1f, 0x66, 0x81, 0xeb,
                0xb3, 0xab, 0xbe, 0xac, 0x29, 0xca, 0xd3, 0x2b,
            };

            // echo -n -e '\x97\xf9\x84\x12\x8e\x9b\x71\x66\xc6\x8a\xaf\x61\x31\x6c\xff\x52\xea\xa5\xcb\x68\xe4\x6e\x2e\xb0\xe6\xf3\x8a\xb7\x72\x53\x0e\xa6\xf0\x89\x33' | openssl enc -e -aes-192-ecb -K C1E3163B8DA64DA3948F8FB81F6681EBB3ABBEAC29CAD32B | hd
            var expected = new byte[]
            {
                0xb3, 0x36, 0x3c, 0x9a, 0x84, 0x76, 0xa5, 0x0e, 0x4c, 0xed, 0x54, 0xbd, 0x33, 0x5b, 0x15, 0xfc,
                0x1d, 0x4f, 0x3b, 0x64, 0x99, 0x9a, 0xfb, 0xc7, 0x4d, 0xe1, 0x91, 0xe0, 0x4e, 0x8d, 0x1e, 0x51,
                0x40, 0xae, 0x13, 0xd6, 0xc1, 0xfc, 0x2b, 0xc0, 0xa0, 0x90, 0x9a, 0xfb, 0x96, 0xc7, 0xa0, 0x16,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_192_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x96, 0xca, 0x9a, 0x20, 0x56, 0x3a, 0x6b, 0x50, 0xf0, 0x68, 0x5b, 0xfa, 0x32, 0xdc, 0x0a, 0xf6,
                0x10, 0xea, 0xa0, 0x7c, 0xec, 0x58, 0x30, 0x19, 0x86, 0x1f, 0x10, 0xe6, 0x28, 0x12, 0x17, 0x49,
                0x6c, 0xfc, 0x15, 0x5e, 0x30, 0xb3, 0xd5, 0x5f, 0xa5, 0x69, 0x03, 0x09, 0x1f, 0x0e, 0x3e, 0xcb,
                0x2e, 0x47, 0x5e, 0xe9, 0xc8, 0xc2, 0xd5, 0x3e, 0x9a, 0x80, 0x9a, 0x37, 0x2a, 0x85, 0x28, 0xdd,
            };
            var key = new byte[]
            {
                0x51, 0x11, 0x8d, 0x36, 0xc6, 0xab, 0xc6, 0x5c, 0x14, 0x41, 0xd7, 0x82, 0x55, 0x26, 0xf9, 0x77,
                0xe0, 0x44, 0xb7, 0xe0, 0xb4, 0x2d, 0x80, 0xaa,
            };

            // echo -n -e '\x96\xca\x9a\x20\x56\x3a\x6b\x50\xf0\x68\x5b\xfa\x32\xdc\x0a\xf6\x10\xea\xa0\x7c\xec\x58\x30\x19\x86\x1f\x10\xe6\x28\x12\x17\x49\x6c\xfc\x15\x5e\x30\xb3\xd5\x5f\xa5\x69\x03\x09\x1f\x0e\x3e\xcb\x2e\x47\x5e\xe9\xc8\xc2\xd5\x3e\x9a\x80\x9a\x37\x2a\x85\x28\xdd' | openssl enc -e -aes-192-ecb -K 51118D36C6ABC65C1441D7825526F977E044B7E0B42D80AA -nopad | hd
            var expected = new byte[]
            {
                0xf8, 0xa6, 0xb9, 0xe9, 0x34, 0x48, 0x9c, 0x57, 0x4a, 0x88, 0xf7, 0x06, 0xe7, 0xb4, 0xca, 0xdd,
                0xb6, 0x14, 0xdb, 0x1e, 0x01, 0x15, 0xa3, 0x40, 0xaf, 0xaf, 0xed, 0xb9, 0x7e, 0x19, 0x5f, 0x1e,
                0x82, 0x64, 0x20, 0x35, 0x23, 0xab, 0x82, 0x57, 0x26, 0x86, 0x60, 0x29, 0xbb, 0xa4, 0x8a, 0xc8,
                0xa5, 0xd7, 0x6e, 0x76, 0x4f, 0x45, 0xef, 0xfe, 0xb2, 0x9f, 0xbc, 0x96, 0xd5, 0x49, 0x55, 0x31,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_192_Length64_Pad()
        {
            var input = new byte[]
            {
                0x81, 0x01, 0xd4, 0x87, 0xea, 0x53, 0xe8, 0x73, 0x87, 0x22, 0x56, 0xe6, 0xcd, 0x47, 0x29, 0x23,
                0x91, 0xe3, 0x0f, 0xee, 0xe7, 0x16, 0x43, 0x76, 0x0c, 0xb7, 0x41, 0x2f, 0x6e, 0xeb, 0xf6, 0xd8,
                0x3e, 0x35, 0x5f, 0xb3, 0x59, 0xf9, 0xbf, 0xd2, 0xee, 0x50, 0x28, 0xf6, 0x48, 0x4e, 0x52, 0xf9,
                0xfc, 0x94, 0x7c, 0x9e, 0xf8, 0x16, 0x9b, 0x6a, 0xbe, 0x5e, 0x7a, 0x33, 0x11, 0xb9, 0x04, 0x9b,
            };
            var key = new byte[]
            {
                0x2c, 0x7d, 0xa7, 0x98, 0xe7, 0x75, 0xca, 0x98, 0x23, 0x3c, 0x00, 0x96, 0xed, 0x4c, 0x2d, 0xbe,
                0x64, 0x47, 0x32, 0xda, 0x6f, 0x58, 0xe0, 0x28,
            };

            // echo -n -e '\x81\x01\xd4\x87\xea\x53\xe8\x73\x87\x22\x56\xe6\xcd\x47\x29\x23\x91\xe3\x0f\xee\xe7\x16\x43\x76\x0c\xb7\x41\x2f\x6e\xeb\xf6\xd8\x3e\x35\x5f\xb3\x59\xf9\xbf\xd2\xee\x50\x28\xf6\x48\x4e\x52\xf9\xfc\x94\x7c\x9e\xf8\x16\x9b\x6a\xbe\x5e\x7a\x33\x11\xb9\x04\x9b' | openssl enc -e -aes-192-ecb -K 2C7DA798E775CA98233C0096ED4C2DBE644732DA6F58E028 | hd
            var expected = new byte[]
            {
                0xdf, 0x78, 0xfe, 0x06, 0xa3, 0xb7, 0x43, 0x04, 0x43, 0xb6, 0x64, 0x45, 0x81, 0x08, 0x76, 0xd1,
                0xd1, 0x50, 0xb1, 0x15, 0x4e, 0xbe, 0x72, 0xd3, 0xa8, 0x4f, 0x57, 0xce, 0x2b, 0xa3, 0x8e, 0x43,
                0x16, 0xdc, 0xd3, 0xf3, 0x4b, 0xfe, 0x0c, 0x29, 0xd0, 0xce, 0x2c, 0x1d, 0x4d, 0xb0, 0x29, 0x11,
                0x07, 0x2c, 0x91, 0x70, 0xe0, 0xa9, 0xe3, 0x8f, 0x16, 0x12, 0xcb, 0x9a, 0x73, 0x06, 0xa9, 0x65,
                0xa0, 0xec, 0xa8, 0x7e, 0x68, 0xb7, 0x63, 0x7b, 0xc2, 0x5e, 0xc4, 0x33, 0xfa, 0xf2, 0x76, 0x83,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_256_Length16_NoPad()
        {
            var input = new byte[]
            {
                0xca, 0xe3, 0x7a, 0xbb, 0x16, 0x04, 0x7c, 0x71, 0x30, 0xbc, 0xce, 0xc9, 0x86, 0x2a, 0x2b, 0xd4,
            };
            var key = new byte[]
            {
                0x9c, 0x7e, 0xfe, 0xf2, 0x80, 0xcf, 0x19, 0x96, 0x7b, 0xca, 0x4a, 0x60, 0x82, 0x62, 0x17, 0xaa,
                0x35, 0xab, 0x10, 0x8b, 0xdd, 0x25, 0x12, 0x95, 0x78, 0x83, 0xca, 0xc2, 0xbd, 0xf7, 0xae, 0x21,
            };

            // echo -n -e '\xca\xe3\x7a\xbb\x16\x04\x7c\x71\x30\xbc\xce\xc9\x86\x2a\x2b\xd4' | openssl enc -e -aes-256-ecb -K 9C7EFEF280CF19967BCA4A60826217AA35AB108BDD2512957883CAC2BDF7AE21 -nopad | hd
            var expected = new byte[]
            {
                0xf5, 0x94, 0x26, 0x13, 0x73, 0x7c, 0x20, 0xc4, 0xc4, 0xd3, 0x46, 0xb6, 0x0c, 0xd4, 0x29, 0xf2,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_256_Length16_Pad()
        {
            var input = new byte[]
            {
                0xa4, 0x23, 0x94, 0xdb, 0x1a, 0x9f, 0xf7, 0x77, 0x6c, 0x69, 0x79, 0xfc, 0x05, 0x57, 0xd9, 0x84,
            };
            var key = new byte[]
            {
                0x1c, 0x29, 0xfe, 0x8c, 0x34, 0xef, 0xef, 0x15, 0xa4, 0x15, 0xc1, 0xf9, 0xe5, 0xc6, 0xdb, 0x5c,
                0x94, 0xfc, 0x1d, 0x99, 0x63, 0xd3, 0x06, 0xc2, 0xfe, 0xb7, 0xbb, 0x51, 0xa6, 0x09, 0xf4, 0x72,
            };

            // echo -n -e '\xa4\x23\x94\xdb\x1a\x9f\xf7\x77\x6c\x69\x79\xfc\x05\x57\xd9\x84' | openssl enc -e -aes-256-ecb -K 1C29FE8C34EFEF15A415C1F9E5C6DB5C94FC1D9963D306C2FEB7BB51A609F472 | hd
            var expected = new byte[]
            {
                0xbb, 0x82, 0xae, 0x6f, 0xb3, 0x48, 0xe5, 0x4c, 0xba, 0x04, 0x99, 0xb5, 0x00, 0xe4, 0x7f, 0xc4,
                0xbb, 0x89, 0x9c, 0xcb, 0x62, 0x32, 0x82, 0xb2, 0x58, 0xe2, 0x69, 0xd5, 0xce, 0x1d, 0xd0, 0xa9,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_256_Length35_Pad()
        {
            var input = new byte[]
            {
                0x8d, 0x1d, 0x68, 0x08, 0x39, 0x40, 0x21, 0x48, 0x22, 0x3c, 0x8e, 0x7d, 0x33, 0x9e, 0x6f, 0x9b,
                0x21, 0x4f, 0xee, 0x2a, 0x96, 0x4a, 0x3e, 0x32, 0x63, 0x68, 0x65, 0xe4, 0x9c, 0x01, 0xe4, 0x00,
                0x26, 0x15, 0xc3,
            };
            var key = new byte[]
            {
                0x88, 0xa1, 0xeb, 0x38, 0xca, 0x99, 0xe6, 0x6e, 0xe2, 0xd4, 0x1c, 0x81, 0x96, 0x0f, 0x9b, 0xe3,
                0x8e, 0x0f, 0x66, 0x0f, 0x43, 0xdf, 0x36, 0xa5, 0xd1, 0xda, 0x3c, 0xac, 0x20, 0x57, 0x8d, 0x57,
            };

            // echo -n -e '\x8d\x1d\x68\x08\x39\x40\x21\x48\x22\x3c\x8e\x7d\x33\x9e\x6f\x9b\x21\x4f\xee\x2a\x96\x4a\x3e\x32\x63\x68\x65\xe4\x9c\x01\xe4\x00\x26\x15\xc3' | openssl enc -e -aes-256-ecb -K 88A1EB38CA99E66EE2D41C81960F9BE38E0F660F43DF36A5D1DA3CAC20578D57 | hd
            var expected = new byte[]
            {
                0x2b, 0xcf, 0xfe, 0xee, 0x2a, 0xd7, 0xb3, 0xcb, 0x87, 0x6d, 0xa3, 0xee, 0xab, 0xb8, 0x46, 0xe6,
                0xce, 0xe8, 0xa2, 0x30, 0x82, 0xa5, 0x6e, 0x8c, 0x82, 0xaf, 0x29, 0x1c, 0x73, 0xae, 0x8c, 0x01,
                0xe4, 0xd5, 0x5d, 0x03, 0x40, 0x5a, 0xd8, 0x91, 0x30, 0x89, 0xdf, 0xcf, 0x74, 0x54, 0x43, 0x31,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_256_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x00, 0x1e, 0x55, 0xf1, 0xbf, 0x05, 0x80, 0xa9, 0x6a, 0x46, 0x67, 0xef, 0x5c, 0x3a, 0x4e, 0x8a,
                0x46, 0xc5, 0x63, 0xbb, 0x28, 0xa1, 0xae, 0x78, 0xeb, 0xd4, 0x5f, 0x67, 0x82, 0xd8, 0x5e, 0xe9,
                0x0b, 0x67, 0xab, 0x02, 0x02, 0x9b, 0x97, 0x18, 0x59, 0x3c, 0x8e, 0xee, 0xae, 0x33, 0x34, 0x75,
                0x8d, 0xd2, 0x17, 0x82, 0x84, 0x13, 0xac, 0x5f, 0x6f, 0xdc, 0x06, 0xea, 0xa5, 0x18, 0x27, 0x92,
            };
            var key = new byte[]
            {
                0xe8, 0x7e, 0xe4, 0xf4, 0x8e, 0x4c, 0x87, 0xab, 0x2d, 0x4a, 0x61, 0xeb, 0x12, 0xc0, 0xca, 0xb7,
                0xa0, 0xea, 0xda, 0xb0, 0xc0, 0xdb, 0x65, 0xf8, 0xbb, 0x4c, 0x92, 0x26, 0x95, 0xac, 0x72, 0x41,
            };

            // echo -n -e '\x00\x1e\x55\xf1\xbf\x05\x80\xa9\x6a\x46\x67\xef\x5c\x3a\x4e\x8a\x46\xc5\x63\xbb\x28\xa1\xae\x78\xeb\xd4\x5f\x67\x82\xd8\x5e\xe9\x0b\x67\xab\x02\x02\x9b\x97\x18\x59\x3c\x8e\xee\xae\x33\x34\x75\x8d\xd2\x17\x82\x84\x13\xac\x5f\x6f\xdc\x06\xea\xa5\x18\x27\x92' | openssl enc -e -aes-256-ecb -K E87EE4F48E4C87AB2D4A61EB12C0CAB7A0EADAB0C0DB65F8BB4C922695AC7241 -nopad | hd
            var expected = new byte[]
            {
                0x7c, 0xac, 0x06, 0xc2, 0x81, 0xd5, 0x81, 0xe4, 0x79, 0x66, 0x29, 0x0c, 0xee, 0x2a, 0xd5, 0x1a,
                0xef, 0xb4, 0xc2, 0x7f, 0x57, 0x7e, 0x9b, 0x21, 0x23, 0x78, 0xec, 0x33, 0x42, 0x16, 0x48, 0x5a,
                0xd6, 0x41, 0xef, 0x08, 0xe7, 0x0a, 0xf2, 0x0e, 0xf1, 0x91, 0x26, 0x01, 0x2c, 0xc7, 0x2a, 0x2f,
                0x4e, 0xd4, 0xc2, 0x5d, 0x32, 0x33, 0x1a, 0xb0, 0x12, 0xa7, 0x60, 0x31, 0x6a, 0xed, 0xa2, 0x2b,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_ECB_256_Length64_Pad()
        {
            var input = new byte[]
            {
                0x11, 0x4e, 0x4a, 0xbb, 0x3e, 0x76, 0xd2, 0x0c, 0x18, 0xeb, 0x39, 0x42, 0xb9, 0x61, 0x15, 0x81,
                0xd7, 0x20, 0xd6, 0x16, 0xba, 0x9a, 0x67, 0x60, 0x04, 0x9a, 0x66, 0x55, 0x87, 0x2c, 0x46, 0xfa,
                0xff, 0xe3, 0x14, 0x47, 0x62, 0xb7, 0x03, 0x9f, 0x29, 0xf9, 0x18, 0x63, 0x06, 0xa3, 0x86, 0xe9,
                0x55, 0xd3, 0x62, 0x90, 0xea, 0x36, 0xf4, 0x77, 0xe6, 0xea, 0xb7, 0xa4, 0x10, 0x7c, 0x85, 0xec,
            };
            var key = new byte[]
            {
                0xa5, 0x3e, 0x43, 0xd6, 0x4d, 0xce, 0x1f, 0x1f, 0x1d, 0x37, 0xec, 0xc0, 0x82, 0x03, 0x5a, 0x60,
                0x13, 0x7c, 0xff, 0xb3, 0xc9, 0xb5, 0x10, 0xc9, 0xee, 0x9c, 0x60, 0x77, 0x00, 0x5f, 0x8e, 0xac,
            };

            // echo -n -e '\x11\x4e\x4a\xbb\x3e\x76\xd2\x0c\x18\xeb\x39\x42\xb9\x61\x15\x81\xd7\x20\xd6\x16\xba\x9a\x67\x60\x04\x9a\x66\x55\x87\x2c\x46\xfa\xff\xe3\x14\x47\x62\xb7\x03\x9f\x29\xf9\x18\x63\x06\xa3\x86\xe9\x55\xd3\x62\x90\xea\x36\xf4\x77\xe6\xea\xb7\xa4\x10\x7c\x85\xec' | openssl enc -e -aes-256-ecb -K A53E43D64DCE1F1F1D37ECC082035A60137CFFB3C9B510C9EE9C6077005F8EAC | hd
            var expected = new byte[]
            {
                0x2c, 0xa4, 0x8d, 0x68, 0xc0, 0xf9, 0x7d, 0xc2, 0xb3, 0xe3, 0xe4, 0xf2, 0x0c, 0x06, 0x39, 0x49,
                0x51, 0xd1, 0x6b, 0x3f, 0x54, 0xb5, 0x85, 0x66, 0x09, 0x27, 0x24, 0x76, 0x24, 0x5e, 0x5d, 0x75,
                0xfe, 0xcf, 0x8d, 0x06, 0xdc, 0x39, 0xb8, 0x4a, 0x34, 0xfe, 0x3e, 0x20, 0x8b, 0xdb, 0xfd, 0x56,
                0x9e, 0x20, 0xf2, 0x95, 0xd7, 0xd2, 0xfe, 0x31, 0xb0, 0x5e, 0x7e, 0x7d, 0x41, 0x13, 0xc1, 0x09,
                0x62, 0xa7, 0x55, 0xf1, 0xc7, 0x6a, 0x0d, 0xb6, 0x67, 0xee, 0x09, 0xcc, 0xae, 0xe8, 0x13, 0x0f,
            };

            var actual = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, iv: null, AesCipherMode.ECB, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_128_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x90, 0x56, 0x90, 0x93, 0x7d, 0xd2, 0x22, 0xef, 0x2d, 0x7a, 0xe7, 0xb0, 0x6e, 0xa7, 0x1f, 0xbe,
            };
            var key = new byte[]
            {
                0xa8, 0x3f, 0x4d, 0x56, 0x45, 0x92, 0x00, 0x63, 0xe0, 0x78, 0xfe, 0x87, 0x42, 0x5d, 0x7f, 0xba,
            };
            var iv = new byte[]
            {
                0xa7, 0x7d, 0xe7, 0xaa, 0xce, 0xfb, 0x2f, 0xa1, 0x09, 0xcf, 0x99, 0xe5, 0xc8, 0xec, 0x18, 0x0d,
            };

            // echo -n -e '\x90\x56\x90\x93\x7d\xd2\x22\xef\x2d\x7a\xe7\xb0\x6e\xa7\x1f\xbe' | openssl enc -e -aes-128-cbc -K A83F4D5645920063E078FE87425D7FBA -iv A77DE7AACEFB2FA109CF99E5C8EC180D -nopad | hd
            var expected = new byte[]
            {
                0xbd, 0x17, 0x7d, 0x43, 0xf9, 0x66, 0x21, 0xf3, 0x3f, 0xc1, 0x89, 0xd7, 0x8d, 0x11, 0xf0, 0x52,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_128_Length16_Pad()
        {
            var input = new byte[]
            {
                0x22, 0xb4, 0x0a, 0x09, 0xe6, 0x9e, 0x9d, 0xfd, 0x55, 0x2d, 0xb2, 0x05, 0xd3, 0x9a, 0xad, 0xd0,
            };
            var key = new byte[]
            {
                0xfa, 0x2d, 0x08, 0xf0, 0xbf, 0x75, 0xf0, 0xac, 0x10, 0xab, 0x4c, 0x76, 0xf8, 0x1a, 0x9b, 0xf4,
            };
            var iv = new byte[]
            {
                0x5f, 0xf1, 0x64, 0x8d, 0x52, 0x75, 0xd3, 0x08, 0xe0, 0xea, 0x54, 0xa1, 0x48, 0x29, 0xcd, 0x6e,
            };

            // echo -n -e '\x22\xb4\x0a\x09\xe6\x9e\x9d\xfd\x55\x2d\xb2\x05\xd3\x9a\xad\xd0' | openssl enc -e -aes-128-cbc -K FA2D08F0BF75F0AC10AB4C76F81A9BF4 -iv 5FF1648D5275D308E0EA54A14829CD6E | hd
            var expected = new byte[]
            {
                0x94, 0x0d, 0x77, 0x43, 0x66, 0xb4, 0x57, 0xb5, 0xbc, 0x11, 0xff, 0x88, 0x4b, 0x10, 0x8a, 0xfb,
                0x97, 0xb2, 0xf2, 0xbf, 0xde, 0x3e, 0x6b, 0xee, 0x78, 0xf5, 0x77, 0xc9, 0x1a, 0x56, 0x01, 0x56,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_128_Length35_Pad()
        {
            var input = new byte[]
            {
                0x21, 0xc9, 0xeb, 0x9a, 0xe3, 0x28, 0x4e, 0xad, 0xc4, 0x5e, 0xf9, 0x3a, 0x52, 0x26, 0x04, 0x3b,
                0x91, 0xbd, 0xa6, 0xe2, 0x36, 0x1f, 0x7d, 0x85, 0x59, 0xff, 0x0f, 0xd5, 0x21, 0x4e, 0x63, 0xe7,
                0xde, 0xdd, 0x54,
            };
            var key = new byte[]
            {
                0x2f, 0x2f, 0x00, 0x11, 0x36, 0xa3, 0xb7, 0xc8, 0xf4, 0x7c, 0x98, 0xb6, 0xb9, 0xe5, 0x18, 0x0f,
            };
            var iv = new byte[]
            {
                0x8b, 0x82, 0xeb, 0x38, 0x02, 0x4b, 0x65, 0x40, 0xe3, 0x19, 0x78, 0x8b, 0x76, 0xfa, 0x12, 0x5c,
            };

            // echo -n -e '\x21\xc9\xeb\x9a\xe3\x28\x4e\xad\xc4\x5e\xf9\x3a\x52\x26\x04\x3b\x91\xbd\xa6\xe2\x36\x1f\x7d\x85\x59\xff\x0f\xd5\x21\x4e\x63\xe7\xde\xdd\x54' | openssl enc -e -aes-128-cbc -K 2F2F001136A3B7C8F47C98B6B9E5180F -iv 8B82EB38024B6540E319788B76FA125C | hd
            var expected = new byte[]
            {
                0x9a, 0x9f, 0xd3, 0xa0, 0xbb, 0x19, 0x6c, 0x25, 0x93, 0x65, 0x97, 0x9e, 0xab, 0xc4, 0xb7, 0xa2,
                0xe4, 0xcb, 0x60, 0xbe, 0xa0, 0x38, 0xb0, 0x65, 0x26, 0xaf, 0x45, 0x72, 0x17, 0xa9, 0x24, 0xe3,
                0xc8, 0x60, 0x05, 0xde, 0x81, 0xe4, 0xc6, 0xcd, 0x31, 0x7f, 0x9e, 0x5d, 0x4b, 0x03, 0x5f, 0x71,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_128_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x74, 0xd2, 0xd5, 0x0c, 0x90, 0xac, 0x70, 0x3e, 0x7e, 0x57, 0x88, 0x09, 0xc1, 0x48, 0x55, 0xf0,
                0x08, 0x3f, 0xd8, 0x64, 0xf2, 0xa4, 0x52, 0xe3, 0xc9, 0xc0, 0x2d, 0x1d, 0x2a, 0x2b, 0x52, 0xf9,
                0x69, 0x3c, 0x42, 0xe7, 0x0f, 0x0c, 0x7f, 0xde, 0x12, 0xad, 0xb9, 0xab, 0xc2, 0x5c, 0x7f, 0x9b,
                0xc3, 0x88, 0x83, 0x37, 0x22, 0xad, 0x6a, 0xcf, 0x7f, 0xf1, 0x42, 0xd0, 0x7f, 0x53, 0x13, 0x53,
            };
            var key = new byte[]
            {
                0x04, 0x8f, 0x9f, 0x84, 0x06, 0x6e, 0xe0, 0xfc, 0xbf, 0xfa, 0x51, 0x44, 0xea, 0xa7, 0x20, 0x6c,
            };
            var iv = new byte[]
            {
                0x40, 0x92, 0x59, 0xa2, 0xa8, 0x1b, 0xd7, 0xbc, 0xd1, 0x72, 0x67, 0x1d, 0xc9, 0xae, 0x5e, 0xbf,
            };

            // echo -n -e '\x74\xd2\xd5\x0c\x90\xac\x70\x3e\x7e\x57\x88\x09\xc1\x48\x55\xf0\x08\x3f\xd8\x64\xf2\xa4\x52\xe3\xc9\xc0\x2d\x1d\x2a\x2b\x52\xf9\x69\x3c\x42\xe7\x0f\x0c\x7f\xde\x12\xad\xb9\xab\xc2\x5c\x7f\x9b\xc3\x88\x83\x37\x22\xad\x6a\xcf\x7f\xf1\x42\xd0\x7f\x53\x13\x53' | openssl enc -e -aes-128-cbc -K 048F9F84066EE0FCBFFA5144EAA7206C -iv 409259A2A81BD7BCD172671DC9AE5EBF -nopad | hd
            var expected = new byte[]
            {
                0x40, 0x3a, 0xb3, 0x62, 0x76, 0x30, 0x81, 0x97, 0x59, 0xc6, 0x51, 0x4e, 0xb6, 0x9f, 0x73, 0xa5,
                0xe8, 0x21, 0xb0, 0xc9, 0xaf, 0x32, 0xd1, 0xaa, 0x21, 0xc8, 0x0f, 0xb0, 0xfa, 0xf2, 0x04, 0x83,
                0x5c, 0xc6, 0x52, 0x4e, 0x05, 0x19, 0x2d, 0x89, 0xce, 0x47, 0xe5, 0x90, 0x13, 0x7c, 0xee, 0x9b,
                0xe9, 0x40, 0x33, 0xc1, 0x3f, 0xb8, 0xf6, 0x69, 0x6b, 0x78, 0xaf, 0x4f, 0x58, 0x4c, 0xe6, 0x74,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_128_Length64_Pad()
        {
            var input = new byte[]
            {
                0x99, 0x66, 0xa6, 0x33, 0xbd, 0xfa, 0x94, 0x55, 0xa8, 0x87, 0x77, 0x28, 0x5b, 0x25, 0xe4, 0xd8,
                0xd1, 0xd6, 0x8f, 0xed, 0xf9, 0x71, 0xab, 0xe8, 0xb7, 0xe2, 0xb3, 0x94, 0x06, 0xc2, 0x32, 0x11,
                0x9b, 0x92, 0xab, 0x84, 0x00, 0xec, 0xae, 0x46, 0xfe, 0x04, 0xf9, 0x21, 0xa4, 0xaf, 0x60, 0xab,
                0x8d, 0x8e, 0x4c, 0xf3, 0x1f, 0x71, 0xc6, 0x27, 0xbb, 0xbe, 0x7c, 0xda, 0x47, 0xff, 0x4e, 0xe5,
            };
            var key = new byte[]
            {
                0x54, 0x65, 0x8d, 0xc9, 0x7a, 0x60, 0xd7, 0xe4, 0x27, 0x49, 0xef, 0xf4, 0x78, 0x89, 0x44, 0x07,
            };
            var iv = new byte[]
            {
                0x82, 0x07, 0x06, 0x77, 0x76, 0x3e, 0xf1, 0x29, 0xcc, 0x84, 0xc8, 0x42, 0x70, 0xd3, 0xff, 0xfe,
            };

            // echo -n -e '\x99\x66\xa6\x33\xbd\xfa\x94\x55\xa8\x87\x77\x28\x5b\x25\xe4\xd8\xd1\xd6\x8f\xed\xf9\x71\xab\xe8\xb7\xe2\xb3\x94\x06\xc2\x32\x11\x9b\x92\xab\x84\x00\xec\xae\x46\xfe\x04\xf9\x21\xa4\xaf\x60\xab\x8d\x8e\x4c\xf3\x1f\x71\xc6\x27\xbb\xbe\x7c\xda\x47\xff\x4e\xe5' | openssl enc -e -aes-128-cbc -K 54658DC97A60D7E42749EFF478894407 -iv 82070677763EF129CC84C84270D3FFFE | hd
            var expected = new byte[]
            {
                0xf1, 0x31, 0x58, 0x0b, 0xde, 0x17, 0x25, 0xf6, 0x43, 0x2d, 0x22, 0xe9, 0xf0, 0x6c, 0x58, 0x48,
                0xcc, 0x45, 0x46, 0xaa, 0x1c, 0x5f, 0xce, 0xfe, 0x41, 0xf6, 0x7d, 0xfc, 0xd8, 0xf6, 0xfc, 0xbe,
                0x08, 0xee, 0xcb, 0xa2, 0xf0, 0xf7, 0x42, 0xb0, 0xdb, 0x30, 0x2e, 0x60, 0x5e, 0xa9, 0xa9, 0x98,
                0x12, 0xf8, 0x35, 0x02, 0x6d, 0xd4, 0x5e, 0xdd, 0x50, 0x80, 0x71, 0xeb, 0xfa, 0x43, 0xd8, 0x18,
                0xb4, 0x20, 0xcb, 0xb8, 0xb1, 0x7f, 0x0c, 0xf6, 0x17, 0x00, 0x0d, 0xde, 0x41, 0x46, 0x14, 0xae,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_192_Length16_NoPad()
        {
            var input = new byte[]
            {
                0xb6, 0x13, 0xcc, 0x3e, 0x22, 0x96, 0x31, 0x2d, 0xb6, 0x67, 0xcb, 0xd6, 0x82, 0xd1, 0xaf, 0x31,
            };
            var key = new byte[]
            {
                0x79, 0x74, 0x58, 0x3f, 0xf9, 0xd6, 0x6f, 0x16, 0x73, 0x63, 0xfc, 0xf6, 0x97, 0x95, 0x73, 0x54,
                0x4a, 0xf0, 0x3d, 0x64, 0xbd, 0x05, 0xe5, 0xeb,
            };
            var iv = new byte[]
            {
                0xd5, 0xd8, 0xc0, 0x0e, 0x73, 0x1b, 0xa7, 0xfa, 0xd4, 0x97, 0xc8, 0xfb, 0x7b, 0xbf, 0x05, 0xe0,
            };

            // echo -n -e '\xb6\x13\xcc\x3e\x22\x96\x31\x2d\xb6\x67\xcb\xd6\x82\xd1\xaf\x31' | openssl enc -e -aes-192-cbc -K 7974583FF9D66F167363FCF6979573544AF03D64BD05E5EB -iv D5D8C00E731BA7FAD497C8FB7BBF05E0 -nopad | hd
            var expected = new byte[]
            {
                0x1f, 0x5a, 0xe4, 0x2d, 0x8b, 0x65, 0x70, 0x71, 0x26, 0x25, 0x3e, 0x46, 0x54, 0x3a, 0x99, 0x93,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_192_Length16_Pad()
        {
            var input = new byte[]
            {
                0xa4, 0xb6, 0xca, 0xbf, 0x9a, 0x3b, 0x96, 0x21, 0xf3, 0x77, 0x8b, 0x91, 0x94, 0x4a, 0x73, 0x74,
            };
            var key = new byte[]
            {
                0x8f, 0x6c, 0x6a, 0x20, 0x15, 0x61, 0xa3, 0x57, 0xbc, 0x02, 0x21, 0x00, 0xcc, 0x78, 0xd9, 0x8a,
                0xeb, 0x5d, 0xc0, 0x07, 0x3a, 0x26, 0x51, 0x9a,
            };
            var iv = new byte[]
            {
                0x42, 0x9f, 0x1a, 0xfb, 0x90, 0x15, 0x66, 0x89, 0x23, 0x54, 0x6c, 0x0f, 0x55, 0xe4, 0xca, 0x43,
            };

            // echo -n -e '\xa4\xb6\xca\xbf\x9a\x3b\x96\x21\xf3\x77\x8b\x91\x94\x4a\x73\x74' | openssl enc -e -aes-192-cbc -K 8F6C6A201561A357BC022100CC78D98AEB5DC0073A26519A -iv 429F1AFB9015668923546C0F55E4CA43 | hd
            var expected = new byte[]
            {
                0x5f, 0x73, 0xef, 0x97, 0x3a, 0x28, 0x80, 0x12, 0xaa, 0xcd, 0x83, 0x31, 0x81, 0x59, 0x07, 0xdb,
                0x26, 0xac, 0x95, 0x24, 0xb5, 0x20, 0x37, 0x0b, 0x38, 0x72, 0x02, 0x19, 0x46, 0xfc, 0x63, 0xc7,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_192_Length35_Pad()
        {
            var input = new byte[]
            {
                0x12, 0x72, 0x02, 0x98, 0x1a, 0x96, 0x54, 0x7b, 0x9e, 0x01, 0xa6, 0x36, 0x8a, 0x6c, 0x3a, 0x69,
                0x1a, 0xcf, 0xdd, 0x76, 0x46, 0xa7, 0xc7, 0xa7, 0x9b, 0x97, 0xdc, 0x78, 0x0b, 0xca, 0x35, 0x06,
                0x93, 0x7c, 0xf4,
            };
            var key = new byte[]
            {
                0xc7, 0x23, 0xb9, 0x7f, 0xac, 0x4a, 0x9e, 0x5d, 0x8e, 0x6f, 0x2f, 0xff, 0xb6, 0x19, 0x03, 0xf4,
                0x85, 0x07, 0x53, 0xfc, 0x6b, 0xab, 0x5b, 0xfc,
            };
            var iv = new byte[]
            {
                0x83, 0xb9, 0xdc, 0x70, 0xd4, 0xcb, 0x9f, 0xa3, 0x0d, 0x77, 0x72, 0x45, 0x61, 0x50, 0x31, 0x2c,
            };

            // echo -n -e '\x12\x72\x02\x98\x1a\x96\x54\x7b\x9e\x01\xa6\x36\x8a\x6c\x3a\x69\x1a\xcf\xdd\x76\x46\xa7\xc7\xa7\x9b\x97\xdc\x78\x0b\xca\x35\x06\x93\x7c\xf4' | openssl enc -e -aes-192-cbc -K C723B97FAC4A9E5D8E6F2FFFB61903F4850753FC6BAB5BFC -iv 83B9DC70D4CB9FA30D7772456150312C | hd
            var expected = new byte[]
            {
                0x98, 0xbb, 0x25, 0x41, 0xaf, 0xf9, 0x4b, 0xbd, 0xbc, 0x3e, 0x61, 0x50, 0x15, 0x76, 0x0d, 0x10,
                0xf1, 0x1d, 0x73, 0x1b, 0x12, 0x6b, 0xa3, 0xc9, 0x83, 0xa8, 0x96, 0xd2, 0xf5, 0x28, 0x96, 0x80,
                0x10, 0x33, 0xf9, 0xe5, 0x3c, 0x5e, 0x35, 0x63, 0x5f, 0xbd, 0x35, 0x30, 0xbf, 0x9d, 0x1f, 0x9f,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_192_Length64_NoPad()
        {
            var input = new byte[]
            {
                0xa8, 0x4a, 0x38, 0x37, 0x6b, 0x98, 0x26, 0x5e, 0x08, 0xd5, 0xb0, 0xff, 0x3f, 0x80, 0x88, 0x1c,
                0xc8, 0xbc, 0xfc, 0xf3, 0x6d, 0x2d, 0x89, 0xc3, 0xcf, 0x8c, 0xf1, 0x3e, 0xa7, 0xbe, 0x93, 0x34,
                0xd6, 0x27, 0x53, 0x21, 0x72, 0x23, 0x90, 0xeb, 0x93, 0x7d, 0x68, 0xfe, 0x1b, 0xa0, 0x63, 0x8d,
                0xee, 0x56, 0x7c, 0xa4, 0x54, 0x3d, 0xbe, 0x7a, 0xc0, 0x75, 0x68, 0xdf, 0xa6, 0xe7, 0xb7, 0x49,
            };
            var key = new byte[]
            {
                0x42, 0x7b, 0x28, 0x18, 0x2d, 0x67, 0xaa, 0xa5, 0x2c, 0x11, 0x60, 0xf0, 0xc5, 0x8a, 0xa7, 0x2f,
                0x28, 0x64, 0x4f, 0x50, 0x41, 0xee, 0xe0, 0x98,
            };
            var iv = new byte[]
            {
                0x68, 0xd9, 0x60, 0xfc, 0xbb, 0xb1, 0x44, 0xab, 0xc6, 0x1e, 0xbb, 0xa0, 0x77, 0x4b, 0x5f, 0x87,
            };

            // echo -n -e '\xa8\x4a\x38\x37\x6b\x98\x26\x5e\x08\xd5\xb0\xff\x3f\x80\x88\x1c\xc8\xbc\xfc\xf3\x6d\x2d\x89\xc3\xcf\x8c\xf1\x3e\xa7\xbe\x93\x34\xd6\x27\x53\x21\x72\x23\x90\xeb\x93\x7d\x68\xfe\x1b\xa0\x63\x8d\xee\x56\x7c\xa4\x54\x3d\xbe\x7a\xc0\x75\x68\xdf\xa6\xe7\xb7\x49' | openssl enc -e -aes-192-cbc -K 427B28182D67AAA52C1160F0C58AA72F28644F5041EEE098 -iv 68D960FCBBB144ABC61EBBA0774B5F87 -nopad | hd
            var expected = new byte[]
            {
                0xc9, 0x11, 0xe2, 0xfd, 0x83, 0x5f, 0xf4, 0x7a, 0xe9, 0x39, 0x66, 0x5e, 0x4d, 0xfb, 0xdf, 0xf5,
                0x99, 0x02, 0xf0, 0x2e, 0xd0, 0xcf, 0x8b, 0x94, 0x0b, 0xce, 0xd1, 0xb4, 0xcf, 0x20, 0x68, 0xa0,
                0x45, 0x0c, 0xfc, 0x45, 0xeb, 0x38, 0x0e, 0xee, 0x17, 0x64, 0xdd, 0x93, 0xf3, 0x86, 0xba, 0x62,
                0x8a, 0x64, 0x2a, 0x96, 0x82, 0xaa, 0xac, 0x8e, 0x88, 0x63, 0x28, 0x52, 0x5a, 0xfa, 0x8a, 0x5d,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_192_Length64_Pad()
        {
            var input = new byte[]
            {
                0xac, 0xd7, 0x78, 0x42, 0xdd, 0xce, 0xb5, 0x36, 0xcd, 0x38, 0xb7, 0x42, 0x97, 0x66, 0x08, 0x53,
                0x9a, 0x90, 0xaf, 0x54, 0x06, 0xad, 0xe9, 0x7a, 0xcc, 0xb4, 0x29, 0xa7, 0xce, 0x07, 0xb7, 0xdc,
                0x04, 0xc8, 0xa4, 0x69, 0x76, 0x9e, 0xbb, 0x9a, 0x24, 0x2a, 0x2e, 0x82, 0xfa, 0x01, 0x14, 0x5f,
                0x16, 0x67, 0x06, 0xe7, 0x9c, 0x0b, 0x80, 0xfe, 0xed, 0xfd, 0x75, 0x28, 0xa4, 0x0d, 0x67, 0xc6,
            };
            var key = new byte[]
            {
                0x80, 0xda, 0x3e, 0xcf, 0xc2, 0x9e, 0xdd, 0xfc, 0xd4, 0x15, 0x30, 0xdc, 0x7f, 0x67, 0x80, 0xcb,
                0xa0, 0xca, 0x91, 0x66, 0x01, 0xd0, 0x40, 0xf8,
            };
            var iv = new byte[]
            {
                0x47, 0xa5, 0x7b, 0x78, 0x28, 0x93, 0xf5, 0x16, 0xc2, 0x68, 0x01, 0x20, 0xc3, 0x45, 0x9c, 0x77,
            };

            // echo -n -e '\xac\xd7\x78\x42\xdd\xce\xb5\x36\xcd\x38\xb7\x42\x97\x66\x08\x53\x9a\x90\xaf\x54\x06\xad\xe9\x7a\xcc\xb4\x29\xa7\xce\x07\xb7\xdc\x04\xc8\xa4\x69\x76\x9e\xbb\x9a\x24\x2a\x2e\x82\xfa\x01\x14\x5f\x16\x67\x06\xe7\x9c\x0b\x80\xfe\xed\xfd\x75\x28\xa4\x0d\x67\xc6' | openssl enc -e -aes-192-cbc -K 80DA3ECFC29EDDFCD41530DC7F6780CBA0CA916601D040F8 -iv 47A57B782893F516C2680120C3459C77 | hd
            var expected = new byte[]
            {
                0x9a, 0xf3, 0x81, 0xfa, 0xed, 0x05, 0xbb, 0xec, 0x8d, 0x8a, 0x95, 0x70, 0xe6, 0x86, 0x87, 0xec,
                0x95, 0x55, 0x58, 0x5d, 0x11, 0x4b, 0x63, 0x85, 0x98, 0xf7, 0x75, 0xd4, 0x59, 0x96, 0x55, 0x79,
                0x89, 0x3e, 0xe4, 0xd7, 0xe0, 0x44, 0x03, 0xd8, 0x20, 0xfb, 0xda, 0x75, 0x0e, 0x66, 0xee, 0xe4,
                0x7e, 0xb1, 0x8a, 0xb1, 0xcf, 0xee, 0xae, 0x37, 0xfd, 0x16, 0xa4, 0xdb, 0x2e, 0x0b, 0x1c, 0x6b,
                0xe5, 0xa1, 0x39, 0x09, 0x9c, 0xdd, 0xea, 0x04, 0xb9, 0x60, 0x34, 0xbe, 0x65, 0x9c, 0x15, 0x98,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_256_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x8a, 0x09, 0x12, 0x86, 0xdb, 0xa3, 0x7f, 0x86, 0x7d, 0xaa, 0x88, 0xd9, 0x7c, 0x01, 0xc4, 0xb0,
            };
            var key = new byte[]
            {
                0x99, 0x45, 0x87, 0x1c, 0x23, 0x65, 0xd3, 0x41, 0x1f, 0x1a, 0x1a, 0x16, 0x65, 0x60, 0x07, 0x5a,
                0x2e, 0x19, 0xdc, 0xf7, 0xbe, 0xb9, 0x1d, 0xa4, 0x26, 0xf5, 0xfa, 0x7d, 0x0a, 0x1c, 0x99, 0xc0,
            };
            var iv = new byte[]
            {
                0xa4, 0x51, 0x86, 0x7e, 0xbe, 0x7f, 0x54, 0x24, 0x35, 0xd1, 0x67, 0xc1, 0x89, 0x68, 0x20, 0x1d,
            };

            // echo -n -e '\x8a\x09\x12\x86\xdb\xa3\x7f\x86\x7d\xaa\x88\xd9\x7c\x01\xc4\xb0' | openssl enc -e -aes-256-cbc -K 9945871C2365D3411F1A1A166560075A2E19DCF7BEB91DA426F5FA7D0A1C99C0 -iv A451867EBE7F542435D167C18968201D -nopad | hd
            var expected = new byte[]
            {
                0x3e, 0x7c, 0xdd, 0x13, 0x85, 0x57, 0x34, 0x61, 0xe6, 0x6e, 0xcd, 0x87, 0xd9, 0xaa, 0xf8, 0xe3,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_256_Length16_Pad()
        {
            var input = new byte[]
            {
                0xa2, 0x2d, 0xab, 0x63, 0x25, 0xcc, 0xf1, 0xe0, 0x27, 0xe3, 0xf6, 0x2d, 0x6a, 0x56, 0x36, 0x03,
            };
            var key = new byte[]
            {
                0x81, 0x59, 0x72, 0x13, 0xd9, 0x89, 0x9c, 0xae, 0xc5, 0xb7, 0xc1, 0xec, 0x52, 0x5c, 0x1a, 0xbd,
                0xd4, 0xdd, 0xda, 0xdd, 0x70, 0x35, 0x9b, 0xd7, 0x5f, 0xa6, 0x56, 0xda, 0x89, 0x26, 0xba, 0xdf,
            };
            var iv = new byte[]
            {
                0x9a, 0x63, 0x3f, 0x2f, 0xf6, 0x0c, 0x43, 0x19, 0x90, 0xfc, 0x9d, 0x6d, 0x0a, 0x04, 0x8d, 0xcb,
            };

            // echo -n -e '\xa2\x2d\xab\x63\x25\xcc\xf1\xe0\x27\xe3\xf6\x2d\x6a\x56\x36\x03' | openssl enc -e -aes-256-cbc -K 81597213D9899CAEC5B7C1EC525C1ABDD4DDDADD70359BD75FA656DA8926BADF -iv 9A633F2FF60C431990FC9D6D0A048DCB | hd
            var expected = new byte[]
            {
                0xb3, 0x4b, 0xbb, 0x73, 0xa6, 0x1b, 0xb4, 0xdc, 0xfa, 0xb4, 0x02, 0xe2, 0x78, 0x72, 0x04, 0x9a,
                0x3e, 0x08, 0x87, 0x8c, 0xae, 0x30, 0xbc, 0x4f, 0x89, 0x16, 0x30, 0x42, 0x2a, 0xd9, 0xe6, 0xac,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_256_Length35_Pad()
        {
            var input = new byte[]
            {
                0xc8, 0x38, 0x58, 0x8d, 0x7b, 0x59, 0x92, 0x4b, 0xbe, 0x9a, 0xb4, 0x33, 0x33, 0xc2, 0x25, 0x9f,
                0xfd, 0xe2, 0x52, 0xee, 0x1c, 0xeb, 0xc6, 0xc7, 0x99, 0xc1, 0x4d, 0x74, 0x98, 0x2e, 0xcc, 0x5a,
                0x18, 0x8a, 0x12,
            };
            var key = new byte[]
            {
                0x50, 0xcd, 0x2c, 0x63, 0x41, 0xd0, 0xf4, 0x71, 0x5b, 0x58, 0x0f, 0xe5, 0xce, 0xd7, 0xfd, 0x70,
                0x28, 0xb2, 0x9e, 0xae, 0xdc, 0x71, 0x91, 0xf3, 0xba, 0x0b, 0x1e, 0xb2, 0x8f, 0xce, 0x59, 0x1b,
            };
            var iv = new byte[]
            {
                0xa8, 0xaf, 0xd4, 0xd1, 0xd0, 0x7e, 0x11, 0x1e, 0x28, 0x7a, 0x6a, 0x6f, 0x89, 0xdb, 0x7f, 0x9d,
            };

            // echo -n -e '\xc8\x38\x58\x8d\x7b\x59\x92\x4b\xbe\x9a\xb4\x33\x33\xc2\x25\x9f\xfd\xe2\x52\xee\x1c\xeb\xc6\xc7\x99\xc1\x4d\x74\x98\x2e\xcc\x5a\x18\x8a\x12' | openssl enc -e -aes-256-cbc -K 50CD2C6341D0F4715B580FE5CED7FD7028B29EAEDC7191F3BA0B1EB28FCE591B -iv A8AFD4D1D07E111E287A6A6F89DB7F9D | hd
            var expected = new byte[]
            {
                0x26, 0x79, 0xc3, 0x69, 0xd9, 0x39, 0xaf, 0x83, 0xb4, 0x14, 0x17, 0x0a, 0x79, 0x4e, 0x2e, 0x02,
                0xa3, 0xb7, 0x68, 0x50, 0xfd, 0x05, 0x7b, 0xff, 0xe3, 0x74, 0x6f, 0x91, 0xec, 0x43, 0x5a, 0xf9,
                0x88, 0x46, 0x53, 0x42, 0x98, 0x69, 0x4b, 0x91, 0x9e, 0x5f, 0x69, 0x22, 0x58, 0xff, 0x48, 0xca,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_256_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x9a, 0xbd, 0xa3, 0xa8, 0x79, 0xdc, 0x36, 0xde, 0x3c, 0x38, 0xa9, 0x35, 0xb2, 0x41, 0xe1, 0x8d,
                0xff, 0xf4, 0x3d, 0x1e, 0x02, 0x2c, 0xa0, 0xaa, 0xa1, 0x80, 0x86, 0x61, 0x07, 0x21, 0x6a, 0xde,
                0x8c, 0x80, 0x17, 0xd1, 0x2a, 0xb1, 0xa1, 0xcc, 0x79, 0xf6, 0x95, 0x97, 0xd4, 0xdb, 0x6b, 0xe6,
                0x99, 0xdd, 0x70, 0x95, 0x9e, 0x60, 0x9b, 0x6e, 0x1d, 0xf8, 0x07, 0xf9, 0x55, 0xd4, 0xd7, 0x1a,
            };
            var key = new byte[]
            {
                0xce, 0xca, 0xa8, 0x31, 0x29, 0x0f, 0x63, 0x4d, 0x52, 0x71, 0xa5, 0x0c, 0x96, 0x08, 0xd6, 0xc5,
                0x14, 0xa0, 0xc8, 0x29, 0xb1, 0xd5, 0x40, 0x2c, 0xe5, 0xa9, 0xb4, 0x31, 0xa9, 0xa8, 0x76, 0xa5,
            };
            var iv = new byte[]
            {
                0x1e, 0x7a, 0xc8, 0x09, 0x32, 0x39, 0xbc, 0x89, 0x7a, 0x22, 0x42, 0x2c, 0xba, 0x8e, 0xd7, 0x15,
            };

            // echo -n -e '\x9a\xbd\xa3\xa8\x79\xdc\x36\xde\x3c\x38\xa9\x35\xb2\x41\xe1\x8d\xff\xf4\x3d\x1e\x02\x2c\xa0\xaa\xa1\x80\x86\x61\x07\x21\x6a\xde\x8c\x80\x17\xd1\x2a\xb1\xa1\xcc\x79\xf6\x95\x97\xd4\xdb\x6b\xe6\x99\xdd\x70\x95\x9e\x60\x9b\x6e\x1d\xf8\x07\xf9\x55\xd4\xd7\x1a' | openssl enc -e -aes-256-cbc -K CECAA831290F634D5271A50C9608D6C514A0C829B1D5402CE5A9B431A9A876A5 -iv 1E7AC8093239BC897A22422CBA8ED715 -nopad | hd
            var expected = new byte[]
            {
                0xde, 0xdc, 0xe6, 0x24, 0xcb, 0xa0, 0x97, 0x6b, 0xe4, 0x2d, 0x38, 0xc2, 0xa0, 0x56, 0x3b, 0x38,
                0xe8, 0x34, 0x9c, 0x9c, 0x10, 0x01, 0x72, 0x4e, 0xae, 0xcf, 0x2a, 0x98, 0x75, 0x2d, 0xee, 0xbd,
                0x42, 0xe8, 0x17, 0x85, 0x23, 0x1e, 0xf7, 0xf9, 0x9f, 0x2e, 0x4f, 0xaa, 0x18, 0x1b, 0x01, 0xf7,
                0xfe, 0xa4, 0x71, 0xef, 0x33, 0x6b, 0x4f, 0x86, 0xe1, 0xa9, 0xf8, 0xc3, 0x40, 0xa4, 0x56, 0xc4,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CBC_256_Length64_Pad()
        {
            var input = new byte[]
            {
                0x22, 0x41, 0xe4, 0xb5, 0x0b, 0xad, 0x69, 0xf9, 0x8a, 0x7c, 0x4b, 0x80, 0x5b, 0x31, 0xa4, 0xaa,
                0xfa, 0xff, 0xed, 0x1c, 0x3f, 0xcc, 0x92, 0xdb, 0xe4, 0x3e, 0xaf, 0x8f, 0x92, 0x13, 0x71, 0x56,
                0xd1, 0x9f, 0x0f, 0x68, 0xc3, 0xc1, 0x9a, 0x70, 0x11, 0xcf, 0x7f, 0xb6, 0xee, 0x3b, 0x2e, 0x48,
                0x7e, 0x97, 0x32, 0xbb, 0xa1, 0xbb, 0xd5, 0x56, 0xaf, 0x09, 0xd0, 0xcc, 0xfe, 0xda, 0x66, 0x76,
            };
            var key = new byte[]
            {
                0x0a, 0xf5, 0xaf, 0xbc, 0x22, 0x3b, 0xe6, 0x39, 0x65, 0x7d, 0x0a, 0x70, 0x4c, 0xdc, 0xec, 0xa8,
                0x10, 0x66, 0x10, 0xfb, 0xe1, 0xb6, 0xb5, 0x15, 0xca, 0xb9, 0xb9, 0xba, 0xf0, 0xcd, 0x72, 0x37,
            };
            var iv = new byte[]
            {
                0x68, 0x09, 0xab, 0xf9, 0x8c, 0x72, 0x26, 0x42, 0xb1, 0xf9, 0x55, 0x24, 0xb1, 0x64, 0x09, 0xd2,
            };

            // echo -n -e '\x22\x41\xe4\xb5\x0b\xad\x69\xf9\x8a\x7c\x4b\x80\x5b\x31\xa4\xaa\xfa\xff\xed\x1c\x3f\xcc\x92\xdb\xe4\x3e\xaf\x8f\x92\x13\x71\x56\xd1\x9f\x0f\x68\xc3\xc1\x9a\x70\x11\xcf\x7f\xb6\xee\x3b\x2e\x48\x7e\x97\x32\xbb\xa1\xbb\xd5\x56\xaf\x09\xd0\xcc\xfe\xda\x66\x76' | openssl enc -e -aes-256-cbc -K 0AF5AFBC223BE639657D0A704CDCECA8106610FBE1B6B515CAB9B9BAF0CD7237 -iv 6809ABF98C722642B1F95524B16409D2 | hd
            var expected = new byte[]
            {
                0x8f, 0x52, 0x10, 0x0a, 0xa6, 0x14, 0xfb, 0x31, 0x74, 0xc6, 0xd4, 0x39, 0x67, 0x6b, 0xd9, 0x67,
                0x23, 0xf9, 0xd3, 0xba, 0x1d, 0x9d, 0x93, 0x4e, 0xab, 0xe4, 0xd7, 0xf4, 0x02, 0xd8, 0x8c, 0x64,
                0xc9, 0x21, 0x18, 0x19, 0xee, 0xa2, 0x50, 0x73, 0xe9, 0x14, 0xba, 0x69, 0x0d, 0x6b, 0xff, 0x48,
                0xec, 0x60, 0x9f, 0x18, 0x5d, 0xb1, 0x8d, 0x49, 0xac, 0x5e, 0x50, 0x9b, 0x9d, 0x13, 0x2c, 0x41,
                0xbc, 0xcc, 0x5a, 0x91, 0x8a, 0xbb, 0xe9, 0x70, 0x39, 0x42, 0x8d, 0xb1, 0x02, 0x53, 0xa7, 0x88,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CBC, pkcs7Padding: true).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_128_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x1c, 0x28, 0xbb, 0x97, 0xc9, 0x6b, 0x94, 0x54, 0x3f, 0x9a, 0xf2, 0x69, 0x82, 0x2b, 0x48, 0x97,
            };
            var key = new byte[]
            {
                0x0a, 0xd3, 0x07, 0x43, 0x30, 0xf3, 0x1c, 0x9d, 0x40, 0xce, 0x49, 0xe8, 0x60, 0x91, 0x64, 0x65,
            };
            var iv = new byte[]
            {
                0xaf, 0xe6, 0x9e, 0xc8, 0x12, 0xdb, 0x6d, 0xfd, 0x74, 0x57, 0xb9, 0xf2, 0x80, 0xbd, 0xbf, 0x85,
            };

            // echo -n -e '\x1c\x28\xbb\x97\xc9\x6b\x94\x54\x3f\x9a\xf2\x69\x82\x2b\x48\x97' | openssl enc -e -aes-128-cfb -K 0AD3074330F31C9D40CE49E860916465 -iv AFE69EC812DB6DFD7457B9F280BDBF85 -nopad | hd
            var expected = new byte[]
            {
                0x8c, 0x75, 0xf1, 0xba, 0xf9, 0xe6, 0x66, 0x7d, 0x14, 0x4a, 0x9f, 0xfc, 0x31, 0xf7, 0x98, 0xcb,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_128_Length35_NoPad()
        {
            var input = new byte[]
            {
                0xb0, 0xbd, 0x19, 0xdd, 0x5d, 0xc6, 0xa2, 0x28, 0x0b, 0x1e, 0x56, 0xfb, 0x21, 0xac, 0xf3, 0xae,
                0x35, 0x8c, 0xb9, 0x9c, 0x8d, 0x80, 0x85, 0x2f, 0x66, 0x09, 0xce, 0xd8, 0x3a, 0x2a, 0x1d, 0x82,
                0x0e, 0xc4, 0x37,
            };
            var key = new byte[]
            {
                0xa3, 0x77, 0x86, 0x07, 0xe9, 0x43, 0x75, 0xbc, 0xf3, 0x84, 0x72, 0xdb, 0xc8, 0x63, 0x0b, 0xbc,
            };
            var iv = new byte[]
            {
                0xf3, 0x03, 0x23, 0xf7, 0x30, 0x38, 0xea, 0x77, 0x53, 0xf7, 0xc9, 0xee, 0xe0, 0x00, 0xd4, 0xec,
            };

            // echo -n -e '\xb0\xbd\x19\xdd\x5d\xc6\xa2\x28\x0b\x1e\x56\xfb\x21\xac\xf3\xae\x35\x8c\xb9\x9c\x8d\x80\x85\x2f\x66\x09\xce\xd8\x3a\x2a\x1d\x82\x0e\xc4\x37' | openssl enc -e -aes-128-cfb -K A3778607E94375BCF38472DBC8630BBC -iv F30323F73038EA7753F7C9EEE000D4EC -nopad | hd
            var expected = new byte[]
            {
                0xea, 0x51, 0x2a, 0x19, 0xd1, 0xc0, 0xcf, 0x4d, 0x81, 0x92, 0xc8, 0x69, 0xdd, 0x37, 0x89, 0x11,
                0xeb, 0x39, 0xf7, 0xfd, 0xbf, 0xa7, 0x2c, 0xb3, 0x69, 0x6a, 0x3a, 0x22, 0xe1, 0x83, 0xc9, 0x71,
                0xfc, 0x42, 0x49,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_128_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x5d, 0x75, 0x50, 0x36, 0xaf, 0x84, 0xcf, 0x58, 0x17, 0xc3, 0x91, 0xaa, 0xf3, 0x2d, 0x06, 0x74,
                0x2e, 0x6e, 0x29, 0x7e, 0xeb, 0xcc, 0x06, 0x6b, 0x8d, 0x0f, 0xb4, 0xf1, 0x7a, 0x87, 0xdb, 0xf3,
                0xb0, 0x86, 0x7e, 0x52, 0x13, 0xd4, 0x0c, 0x6f, 0x34, 0xca, 0xe0, 0x6d, 0xa6, 0x3f, 0x83, 0x25,
                0xf1, 0x54, 0xbf, 0x72, 0xd7, 0x55, 0x00, 0x90, 0x6f, 0xe5, 0xa9, 0x9f, 0xd0, 0xde, 0xde, 0x8f,
            };
            var key = new byte[]
            {
                0xe7, 0x9e, 0xfa, 0x6d, 0xaf, 0xb3, 0x61, 0x5a, 0x61, 0xba, 0x4a, 0x21, 0xec, 0x98, 0xc4, 0x4d,
            };
            var iv = new byte[]
            {
                0x8b, 0x8e, 0x00, 0x25, 0xc8, 0x69, 0x1b, 0x5b, 0x85, 0xee, 0xe3, 0x2e, 0x2b, 0x6d, 0x9e, 0x56,
            };

            // echo -n -e '\x5d\x75\x50\x36\xaf\x84\xcf\x58\x17\xc3\x91\xaa\xf3\x2d\x06\x74\x2e\x6e\x29\x7e\xeb\xcc\x06\x6b\x8d\x0f\xb4\xf1\x7a\x87\xdb\xf3\xb0\x86\x7e\x52\x13\xd4\x0c\x6f\x34\xca\xe0\x6d\xa6\x3f\x83\x25\xf1\x54\xbf\x72\xd7\x55\x00\x90\x6f\xe5\xa9\x9f\xd0\xde\xde\x8f' | openssl enc -e -aes-128-cfb -K E79EFA6DAFB3615A61BA4A21EC98C44D -iv 8B8E0025C8691B5B85EEE32E2B6D9E56 -nopad | hd
            var expected = new byte[]
            {
                0x99, 0xe7, 0xd8, 0xbf, 0x94, 0x24, 0x5c, 0xef, 0x8e, 0xe7, 0x2e, 0x7b, 0x3d, 0x9f, 0x88, 0x56,
                0x97, 0xb4, 0xff, 0xdb, 0x7f, 0x00, 0xe0, 0xaa, 0x46, 0x4d, 0x3f, 0x96, 0x04, 0xc9, 0x6b, 0xfe,
                0xb6, 0xdb, 0x01, 0x3c, 0x29, 0x78, 0xc0, 0xc5, 0x29, 0x1b, 0x1e, 0x70, 0x8e, 0xe1, 0x1a, 0xbc,
                0xd7, 0x15, 0xa4, 0x00, 0x33, 0xe6, 0x07, 0x1a, 0x6c, 0xc7, 0x95, 0x95, 0xb2, 0x52, 0x51, 0xc8,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_192_Length16_NoPad()
        {
            var input = new byte[]
            {
                0xeb, 0x50, 0x85, 0x07, 0x45, 0x16, 0x76, 0x3d, 0xf3, 0x64, 0x11, 0x1d, 0x0a, 0xdf, 0xa4, 0xd6,
            };
            var key = new byte[]
            {
                0x20, 0x5c, 0x14, 0x41, 0xdd, 0xb9, 0xc6, 0x7e, 0x83, 0x9f, 0xe7, 0xc0, 0xd0, 0x32, 0x2f, 0xf4,
                0x1b, 0xf4, 0x35, 0x9b, 0x13, 0xbd, 0x08, 0x74,
            };
            var iv = new byte[]
            {
                0x18, 0xc2, 0x32, 0x64, 0x58, 0xfe, 0x51, 0xa5, 0x49, 0x0c, 0x0d, 0xcf, 0x58, 0x5d, 0x78, 0x32,
            };

            // echo -n -e '\xeb\x50\x85\x07\x45\x16\x76\x3d\xf3\x64\x11\x1d\x0a\xdf\xa4\xd6' | openssl enc -e -aes-192-cfb -K 205C1441DDB9C67E839FE7C0D0322FF41BF4359B13BD0874 -iv 18C2326458FE51A5490C0DCF585D7832 -nopad | hd
            var expected = new byte[]
            {
                0x57, 0x7a, 0x4f, 0x03, 0x6e, 0x76, 0x43, 0x2d, 0xc0, 0x23, 0x26, 0x19, 0x58, 0x2e, 0x77, 0x83,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_192_Length35_NoPad()
        {
            var input = new byte[]
            {
                0x8a, 0x07, 0x84, 0xa5, 0x2f, 0xb5, 0x6d, 0xc0, 0x35, 0x1c, 0x01, 0x15, 0xaa, 0x09, 0xc3, 0x63,
                0x53, 0xa0, 0x28, 0x1a, 0x87, 0x62, 0x25, 0x84, 0x4e, 0x41, 0x76, 0xc3, 0x24, 0x5f, 0x9b, 0xbe,
                0x7c, 0x02, 0x11,
            };
            var key = new byte[]
            {
                0x0b, 0x38, 0x62, 0x45, 0x62, 0x55, 0x71, 0x2e, 0x3b, 0xfc, 0x3b, 0xfb, 0x40, 0x49, 0xaa, 0x7b,
                0xb8, 0x34, 0x5d, 0xab, 0x27, 0xe1, 0xff, 0x57,
            };
            var iv = new byte[]
            {
                0xed, 0x3e, 0xa9, 0x9b, 0xd5, 0x80, 0x43, 0x98, 0xa7, 0xf7, 0xb7, 0x2a, 0xf0, 0x5a, 0xc6, 0xc4,
            };

            // echo -n -e '\x8a\x07\x84\xa5\x2f\xb5\x6d\xc0\x35\x1c\x01\x15\xaa\x09\xc3\x63\x53\xa0\x28\x1a\x87\x62\x25\x84\x4e\x41\x76\xc3\x24\x5f\x9b\xbe\x7c\x02\x11' | openssl enc -e -aes-192-cfb -K 0B3862456255712E3BFC3BFB4049AA7BB8345DAB27E1FF57 -iv ED3EA99BD5804398A7F7B72AF05AC6C4 -nopad | hd
            var expected = new byte[]
            {
                0xf1, 0xbe, 0xde, 0x5d, 0x2f, 0x39, 0x84, 0x26, 0x11, 0xfa, 0x38, 0xa8, 0x51, 0x85, 0xfe, 0xfd,
                0x89, 0xf8, 0xd1, 0x7b, 0xed, 0x96, 0x7f, 0x13, 0xad, 0xdf, 0xbc, 0x15, 0xcc, 0xa3, 0xbf, 0xbf,
                0x05, 0xcb, 0xad,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_192_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x15, 0x34, 0xea, 0x88, 0x12, 0x46, 0x36, 0x79, 0x7a, 0xe4, 0xe3, 0x89, 0x1e, 0x57, 0xe9, 0x29,
                0x39, 0x0b, 0x58, 0x23, 0xac, 0xd6, 0x58, 0xba, 0xb9, 0xa2, 0x53, 0x48, 0x92, 0x7f, 0x8b, 0x5d,
                0x6e, 0x98, 0x96, 0xf3, 0xf7, 0x77, 0x44, 0xa6, 0x08, 0x2f, 0x20, 0xf1, 0x9d, 0xb9, 0x7a, 0x50,
                0x0e, 0x8e, 0xf1, 0xe5, 0x02, 0xa2, 0x18, 0x3e, 0xdb, 0x2f, 0xcf, 0x6f, 0xf2, 0xed, 0xe7, 0xfb,
            };
            var key = new byte[]
            {
                0x59, 0x86, 0x1b, 0x85, 0xc1, 0xf5, 0x32, 0xc2, 0xc7, 0xb1, 0x1b, 0x7c, 0xb5, 0x66, 0x1d, 0xff,
                0x28, 0x03, 0x3a, 0x03, 0x8d, 0xa6, 0x5b, 0xcc,
            };
            var iv = new byte[]
            {
                0x80, 0x57, 0x18, 0xc8, 0xa7, 0xd4, 0xb3, 0x1b, 0x48, 0x25, 0x98, 0x16, 0x9e, 0xf4, 0x8e, 0x19,
            };

            // echo -n -e '\x15\x34\xea\x88\x12\x46\x36\x79\x7a\xe4\xe3\x89\x1e\x57\xe9\x29\x39\x0b\x58\x23\xac\xd6\x58\xba\xb9\xa2\x53\x48\x92\x7f\x8b\x5d\x6e\x98\x96\xf3\xf7\x77\x44\xa6\x08\x2f\x20\xf1\x9d\xb9\x7a\x50\x0e\x8e\xf1\xe5\x02\xa2\x18\x3e\xdb\x2f\xcf\x6f\xf2\xed\xe7\xfb' | openssl enc -e -aes-192-cfb -K 59861B85C1F532C2C7B11B7CB5661DFF28033A038DA65BCC -iv 805718C8A7D4B31B482598169EF48E19 -nopad | hd
            var expected = new byte[]
            {
                0x8e, 0x1e, 0xad, 0x77, 0xa8, 0xf6, 0xb8, 0x9f, 0x4a, 0xa5, 0x04, 0xcc, 0x33, 0x54, 0xca, 0x76,
                0xd6, 0x25, 0x08, 0x22, 0x5b, 0x5f, 0xff, 0xbf, 0x10, 0x63, 0xf1, 0x6b, 0xf8, 0xfa, 0x02, 0x6a,
                0x3e, 0xa6, 0x66, 0xbf, 0x56, 0x2e, 0x5c, 0xbb, 0x94, 0x5c, 0x3b, 0x54, 0xde, 0x63, 0x24, 0x2c,
                0x08, 0x4e, 0x2b, 0xbd, 0xbb, 0x0a, 0xdc, 0x25, 0xe5, 0x10, 0x6c, 0x3c, 0x89, 0x03, 0xa7, 0x63,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_256_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x5c, 0x2f, 0x1d, 0x50, 0x86, 0x9c, 0x89, 0x74, 0x11, 0xd0, 0x46, 0xef, 0xb2, 0xe3, 0x6d, 0xb3,
            };
            var key = new byte[]
            {
                0x2a, 0x4f, 0x05, 0x69, 0xdd, 0x69, 0x1a, 0xf2, 0xfe, 0xff, 0x34, 0x8f, 0xcd, 0x06, 0x60, 0x34,
                0x74, 0x21, 0xa7, 0x5d, 0x88, 0x0a, 0x45, 0xe4, 0xcd, 0xa3, 0xb7, 0xd7, 0x8e, 0xc4, 0x68, 0x64,
            };
            var iv = new byte[]
            {
                0xb8, 0xe5, 0xec, 0x4e, 0xee, 0x24, 0x3b, 0xf2, 0x15, 0x2b, 0x52, 0x86, 0x67, 0xf9, 0xa7, 0x0a,
            };

            // echo -n -e '\x5c\x2f\x1d\x50\x86\x9c\x89\x74\x11\xd0\x46\xef\xb2\xe3\x6d\xb3' | openssl enc -e -aes-256-cfb -K 2A4F0569DD691AF2FEFF348FCD0660347421A75D880A45E4CDA3B7D78EC46864 -iv B8E5EC4EEE243BF2152B528667F9A70A -nopad | hd
            var expected = new byte[]
            {
                0xd4, 0x21, 0xc2, 0xf2, 0x06, 0xcf, 0xa6, 0x65, 0x5d, 0xb0, 0x13, 0x3c, 0x87, 0x04, 0x5c, 0x59,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_256_Length35_NoPad()
        {
            var input = new byte[]
            {
                0x6f, 0x12, 0x7a, 0x91, 0x3b, 0x0f, 0x2b, 0x20, 0x0a, 0x21, 0x9c, 0x39, 0xb2, 0x43, 0x64, 0x39,
                0x97, 0xd0, 0xd7, 0xe8, 0x1a, 0x11, 0x45, 0x4f, 0xe5, 0xb5, 0x48, 0x5c, 0xb7, 0xbe, 0x7c, 0xd4,
                0xfc, 0xac, 0x68,
            };
            var key = new byte[]
            {
                0x7b, 0x49, 0xd7, 0x28, 0xa8, 0xba, 0xcb, 0x44, 0xcd, 0x88, 0x01, 0x3f, 0xd2, 0xc7, 0x19, 0xef,
                0x97, 0x21, 0xbe, 0xef, 0x5d, 0xcc, 0x2b, 0xac, 0x86, 0xc7, 0xce, 0x69, 0x4b, 0xa4, 0xc7, 0x3d,
            };
            var iv = new byte[]
            {
                0x05, 0xda, 0xe8, 0xf0, 0xc0, 0xa7, 0x2f, 0x2d, 0x4f, 0xcd, 0x77, 0xc6, 0xe3, 0x75, 0x76, 0x94,
            };

            // echo -n -e '\x6f\x12\x7a\x91\x3b\x0f\x2b\x20\x0a\x21\x9c\x39\xb2\x43\x64\x39\x97\xd0\xd7\xe8\x1a\x11\x45\x4f\xe5\xb5\x48\x5c\xb7\xbe\x7c\xd4\xfc\xac\x68' | openssl enc -e -aes-256-cfb -K 7B49D728A8BACB44CD88013FD2C719EF9721BEEF5DCC2BAC86C7CE694BA4C73D -iv 05DAE8F0C0A72F2D4FCD77C6E3757694 -nopad | hd
            var expected = new byte[]
            {
                0x6f, 0x5b, 0x27, 0x08, 0x46, 0x96, 0xf4, 0x30, 0x2e, 0x61, 0x1c, 0x5d, 0x7d, 0xa6, 0x7b, 0xdb,
                0x98, 0x78, 0x77, 0x04, 0xdb, 0xb0, 0xa7, 0xc8, 0x20, 0x20, 0x77, 0x10, 0x79, 0x16, 0x26, 0x7c,
                0xb5, 0xcb, 0x97,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CFB_256_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x9e, 0xce, 0xe5, 0xb2, 0x3d, 0xbd, 0x0a, 0xae, 0x1e, 0x2b, 0xa2, 0xe1, 0xeb, 0x61, 0xf8, 0x28,
                0xc1, 0xc4, 0x39, 0xf7, 0xdf, 0x28, 0x2f, 0xef, 0xf2, 0x91, 0x9f, 0x90, 0x54, 0x64, 0xc8, 0x10,
                0x50, 0x3a, 0xcb, 0x7d, 0xbf, 0x14, 0x00, 0x48, 0xd0, 0x39, 0xd2, 0x94, 0x05, 0x4d, 0x41, 0xed,
                0xd4, 0x4f, 0x05, 0x1f, 0x3c, 0x7e, 0xb5, 0x75, 0x9e, 0xf5, 0xc0, 0xab, 0x1d, 0x79, 0x59, 0xba,
            };
            var key = new byte[]
            {
                0x62, 0x91, 0x90, 0xb1, 0x96, 0x7b, 0x69, 0xac, 0xc3, 0xf1, 0x26, 0xa5, 0x56, 0x9a, 0xe9, 0xa4,
                0x4f, 0xb1, 0xbc, 0x05, 0x5e, 0xa9, 0xd4, 0xd2, 0x85, 0x55, 0xde, 0xc9, 0x54, 0x54, 0x2a, 0x56,
            };
            var iv = new byte[]
            {
                0xe0, 0x17, 0x32, 0x74, 0xbd, 0x90, 0x57, 0x58, 0xe5, 0x59, 0x5b, 0x4a, 0x58, 0x0f, 0x1f, 0x04,
            };

            // echo -n -e '\x9e\xce\xe5\xb2\x3d\xbd\x0a\xae\x1e\x2b\xa2\xe1\xeb\x61\xf8\x28\xc1\xc4\x39\xf7\xdf\x28\x2f\xef\xf2\x91\x9f\x90\x54\x64\xc8\x10\x50\x3a\xcb\x7d\xbf\x14\x00\x48\xd0\x39\xd2\x94\x05\x4d\x41\xed\xd4\x4f\x05\x1f\x3c\x7e\xb5\x75\x9e\xf5\xc0\xab\x1d\x79\x59\xba' | openssl enc -e -aes-256-cfb -K 629190B1967B69ACC3F126A5569AE9A44FB1BC055EA9D4D28555DEC954542A56 -iv E0173274BD905758E5595B4A580F1F04 -nopad | hd
            var expected = new byte[]
            {
                0x9a, 0x12, 0x90, 0xd7, 0x30, 0x9e, 0x66, 0x42, 0xf4, 0xe7, 0x8e, 0x80, 0xfb, 0xfc, 0x14, 0x5e,
                0x53, 0x4c, 0x08, 0xea, 0xdd, 0x17, 0xa8, 0x63, 0xa4, 0x34, 0x7a, 0x57, 0xdc, 0x92, 0xc3, 0xfb,
                0xf1, 0xba, 0x31, 0x82, 0x77, 0x57, 0x1c, 0x0c, 0x87, 0x05, 0x3a, 0xfb, 0xa7, 0xce, 0xb6, 0x09,
                0xbe, 0x24, 0x47, 0xeb, 0xe5, 0x0a, 0x24, 0x6d, 0xc2, 0x1e, 0xca, 0x52, 0x8d, 0x9a, 0xe7, 0x49,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_128_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x0b, 0x1b, 0x5c, 0x6b, 0xbd, 0x54, 0x5b, 0xb9, 0xbd, 0xbe, 0x2c, 0x41, 0x9c, 0x9f, 0x57, 0x6e,
            };
            var key = new byte[]
            {
                0xc6, 0xd0, 0xc5, 0x3e, 0x68, 0x75, 0xe6, 0xbf, 0x5a, 0x63, 0x1f, 0x05, 0x4d, 0x89, 0x79, 0x75,
            };
            var iv = new byte[]
            {
                0x36, 0xda, 0xbd, 0x39, 0xf8, 0xbe, 0x98, 0x8c, 0xbc, 0x79, 0xb6, 0xff, 0x64, 0x15, 0xbc, 0x46,
            };

            // echo -n -e '\x0b\x1b\x5c\x6b\xbd\x54\x5b\xb9\xbd\xbe\x2c\x41\x9c\x9f\x57\x6e' | openssl enc -e -aes-128-ctr -K C6D0C53E6875E6BF5A631F054D897975 -iv 36DABD39F8BE988CBC79B6FF6415BC46 -nopad | hd
            var expected = new byte[]
            {
                0xee, 0x28, 0x3f, 0x2e, 0xd9, 0xac, 0x08, 0x36, 0x8a, 0xc0, 0x44, 0x90, 0x4d, 0x1f, 0x35, 0x06,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_128_Length35_NoPad()
        {
            var input = new byte[]
            {
                0x01, 0xed, 0x84, 0x87, 0x4a, 0xe0, 0x9c, 0x96, 0x34, 0x9d, 0x11, 0x5a, 0x34, 0x56, 0x6b, 0x33,
                0x44, 0xb7, 0x0b, 0xc2, 0xe1, 0x1e, 0x76, 0x07, 0x37, 0x39, 0x82, 0xee, 0xbe, 0xe7, 0x5b, 0x44,
                0xa7, 0xd9, 0x03,
            };
            var key = new byte[]
            {
                0x60, 0x04, 0xf1, 0x2a, 0x55, 0x3e, 0x27, 0x04, 0x5a, 0xad, 0x3e, 0x57, 0x65, 0x0d, 0x83, 0xbb,
            };
            var iv = new byte[]
            {
                0xac, 0x0a, 0xf9, 0x64, 0xe2, 0x76, 0x7d, 0x50, 0x11, 0x5e, 0xad, 0xd7, 0x4d, 0x42, 0xcc, 0xb3,
            };

            // echo -n -e '\x01\xed\x84\x87\x4a\xe0\x9c\x96\x34\x9d\x11\x5a\x34\x56\x6b\x33\x44\xb7\x0b\xc2\xe1\x1e\x76\x07\x37\x39\x82\xee\xbe\xe7\x5b\x44\xa7\xd9\x03' | openssl enc -e -aes-128-ctr -K 6004F12A553E27045AAD3E57650D83BB -iv AC0AF964E2767D50115EADD74D42CCB3 -nopad | hd
            var expected = new byte[]
            {
                0xeb, 0x79, 0x85, 0x5c, 0xc2, 0x5a, 0x10, 0xad, 0x7d, 0x50, 0x3a, 0xcf, 0x72, 0x29, 0x2e, 0x27,
                0x57, 0x44, 0x52, 0xf0, 0x3d, 0xe9, 0x0b, 0x65, 0xba, 0xfd, 0x3b, 0xf3, 0x8b, 0x47, 0x5d, 0x6a,
                0x17, 0xf1, 0x16,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_128_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x5a, 0x52, 0x0b, 0x2e, 0x52, 0x8c, 0xb5, 0x84, 0xb9, 0x1a, 0x1c, 0x59, 0xf9, 0xe1, 0x1c, 0xe0,
                0x3b, 0x2c, 0xae, 0x39, 0xad, 0x74, 0x21, 0xea, 0x87, 0xa1, 0x18, 0xf6, 0x91, 0x50, 0xb7, 0x18,
                0xe1, 0x8a, 0xfd, 0x13, 0x02, 0x54, 0x68, 0x20, 0x55, 0x75, 0xab, 0xc8, 0x5a, 0x23, 0x57, 0x30,
                0x42, 0xcc, 0x9c, 0x20, 0x94, 0x92, 0x06, 0xe6, 0x31, 0x21, 0xa6, 0xb1, 0x73, 0xbf, 0xf2, 0x69,
            };
            var key = new byte[]
            {
                0x63, 0x03, 0x78, 0x6e, 0xe4, 0x08, 0xde, 0xe6, 0xc3, 0x8d, 0xe4, 0x37, 0xc9, 0x58, 0x8f, 0x64,
            };
            var iv = new byte[]
            {
                0x4a, 0xe8, 0xb4, 0xc4, 0xb4, 0x96, 0x84, 0x4e, 0x84, 0x16, 0xe1, 0xe1, 0xad, 0xb7, 0xac, 0x95,
            };

            // echo -n -e '\x5a\x52\x0b\x2e\x52\x8c\xb5\x84\xb9\x1a\x1c\x59\xf9\xe1\x1c\xe0\x3b\x2c\xae\x39\xad\x74\x21\xea\x87\xa1\x18\xf6\x91\x50\xb7\x18\xe1\x8a\xfd\x13\x02\x54\x68\x20\x55\x75\xab\xc8\x5a\x23\x57\x30\x42\xcc\x9c\x20\x94\x92\x06\xe6\x31\x21\xa6\xb1\x73\xbf\xf2\x69' | openssl enc -e -aes-128-ctr -K 6303786EE408DEE6C38DE437C9588F64 -iv 4AE8B4C4B496844E8416E1E1ADB7AC95 -nopad | hd
            var expected = new byte[]
            {
                0x00, 0x49, 0x7c, 0x09, 0x2a, 0xc2, 0x0f, 0xc2, 0x89, 0x54, 0x8c, 0xbc, 0x03, 0xb0, 0xc8, 0xff,
                0xa8, 0x5d, 0x54, 0x0e, 0x54, 0xb2, 0x6d, 0x16, 0x8a, 0x41, 0x39, 0xf0, 0x55, 0xd2, 0x4b, 0x91,
                0xa4, 0xb7, 0x37, 0x5f, 0xb2, 0x58, 0x78, 0x5c, 0xed, 0xdb, 0xa8, 0x15, 0x3f, 0xda, 0x24, 0x57,
                0x0d, 0x1a, 0x30, 0x6d, 0xa7, 0xbd, 0x2b, 0x9b, 0x05, 0x05, 0xad, 0x92, 0x9a, 0xd6, 0x8e, 0x28,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_192_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x82, 0x41, 0x65, 0x56, 0xab, 0xe9, 0x4c, 0x39, 0xed, 0xb5, 0x5c, 0x06, 0xae, 0xce, 0x1d, 0xd8,
            };
            var key = new byte[]
            {
                0x91, 0x42, 0x67, 0x8b, 0x0b, 0x2e, 0xb5, 0xcd, 0x7f, 0x29, 0xe9, 0xcd, 0x26, 0xfd, 0x39, 0x0c,
                0xe1, 0x4e, 0xb4, 0x87, 0xf3, 0x39, 0xb9, 0x60,
            };
            var iv = new byte[]
            {
                0x9c, 0x7a, 0xd6, 0xfe, 0x39, 0x7d, 0xa0, 0xb6, 0xf9, 0x09, 0x4f, 0x6b, 0x50, 0x20, 0x8a, 0x54,
            };

            // echo -n -e '\x82\x41\x65\x56\xab\xe9\x4c\x39\xed\xb5\x5c\x06\xae\xce\x1d\xd8' | openssl enc -e -aes-192-ctr -K 9142678B0B2EB5CD7F29E9CD26FD390CE14EB487F339B960 -iv 9C7AD6FE397DA0B6F9094F6B50208A54 -nopad | hd
            var expected = new byte[]
            {
                0x27, 0x94, 0x39, 0x4c, 0xab, 0x94, 0xd5, 0xfe, 0x0a, 0xc4, 0xf6, 0x33, 0x4c, 0x8c, 0xa5, 0xe1,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_192_Length35_NoPad()
        {
            var input = new byte[]
            {
                0x8c, 0x97, 0xd6, 0x81, 0xff, 0x7e, 0x12, 0xf0, 0x7b, 0x50, 0x24, 0x5f, 0x19, 0x95, 0xe5, 0x58,
                0x89, 0x06, 0xef, 0x90, 0x57, 0xb6, 0x94, 0x02, 0x89, 0x32, 0xd4, 0x1d, 0xad, 0xce, 0xbc, 0xc0,
                0xc4, 0x60, 0xfb,
            };
            var key = new byte[]
            {
                0x5b, 0x62, 0x37, 0x61, 0x1d, 0x68, 0xe6, 0x82, 0xe8, 0x58, 0x41, 0x9d, 0x63, 0x23, 0xf7, 0xe1,
                0x49, 0x31, 0xfa, 0xfd, 0xd5, 0x03, 0xd4, 0xf8,
            };
            var iv = new byte[]
            {
                0xcd, 0xaa, 0xf4, 0x43, 0xad, 0x93, 0x64, 0x9b, 0xb8, 0x9a, 0x89, 0xf6, 0x51, 0xa5, 0xd1, 0x28,
            };

            // echo -n -e '\x8c\x97\xd6\x81\xff\x7e\x12\xf0\x7b\x50\x24\x5f\x19\x95\xe5\x58\x89\x06\xef\x90\x57\xb6\x94\x02\x89\x32\xd4\x1d\xad\xce\xbc\xc0\xc4\x60\xfb' | openssl enc -e -aes-192-ctr -K 5B6237611D68E682E858419D6323F7E14931FAFDD503D4F8 -iv CDAAF443AD93649BB89A89F651A5D128 -nopad | hd
            var expected = new byte[]
            {
                0xb9, 0xbd, 0x6a, 0x7a, 0xd6, 0xca, 0x4d, 0x75, 0xb9, 0x36, 0xd3, 0xe6, 0xf3, 0xe5, 0x42, 0xe2,
                0xf7, 0x2f, 0x5a, 0xd6, 0x4b, 0x24, 0xd1, 0xca, 0x9f, 0x49, 0x68, 0x34, 0x15, 0x73, 0xf9, 0x93,
                0xf4, 0xfc, 0x58,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_192_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x71, 0x34, 0xab, 0xa9, 0x47, 0x95, 0x70, 0xf9, 0xb5, 0xec, 0x72, 0x8f, 0xc9, 0x63, 0x26, 0x57,
                0x8d, 0x3f, 0x94, 0x73, 0x73, 0xa3, 0xd5, 0x54, 0xf4, 0xa6, 0xe4, 0xc9, 0x9a, 0x01, 0x8f, 0xa4,
                0x60, 0xd1, 0x8b, 0xa1, 0x58, 0x2b, 0xb0, 0x37, 0x39, 0xfa, 0x8d, 0xc1, 0x21, 0xd5, 0xd1, 0x55,
                0x74, 0x31, 0x68, 0x12, 0x10, 0x5d, 0xb4, 0xcd, 0x5e, 0x56, 0xb5, 0xa1, 0xb1, 0xa6, 0x5f, 0xb4,
            };
            var key = new byte[]
            {
                0x5c, 0xcd, 0x2e, 0xf8, 0xd7, 0x84, 0xff, 0x62, 0x8f, 0x5c, 0x39, 0x78, 0x15, 0x14, 0x33, 0x1f,
                0xd4, 0x8e, 0x55, 0x68, 0x98, 0x7d, 0x93, 0x02,
            };
            var iv = new byte[]
            {
                0x1d, 0xbe, 0x42, 0x01, 0x75, 0x0e, 0x86, 0x92, 0x9a, 0xd8, 0x64, 0x53, 0xa6, 0xd9, 0x7e, 0xef,
            };

            // echo -n -e '\x71\x34\xab\xa9\x47\x95\x70\xf9\xb5\xec\x72\x8f\xc9\x63\x26\x57\x8d\x3f\x94\x73\x73\xa3\xd5\x54\xf4\xa6\xe4\xc9\x9a\x01\x8f\xa4\x60\xd1\x8b\xa1\x58\x2b\xb0\x37\x39\xfa\x8d\xc1\x21\xd5\xd1\x55\x74\x31\x68\x12\x10\x5d\xb4\xcd\x5e\x56\xb5\xa1\xb1\xa6\x5f\xb4' | openssl enc -e -aes-192-ctr -K 5CCD2EF8D784FF628F5C39781514331FD48E5568987D9302 -iv 1DBE4201750E86929AD86453A6D97EEF -nopad | hd
            var expected = new byte[]
            {
                0x25, 0x22, 0x5e, 0xe7, 0xe7, 0x5c, 0x9e, 0x37, 0xb7, 0x28, 0x8e, 0x1d, 0xd3, 0xa7, 0x97, 0xa4,
                0xcb, 0x15, 0x8f, 0xf3, 0x4d, 0x39, 0xb6, 0xe1, 0x00, 0x4e, 0x6d, 0xee, 0x03, 0xc4, 0x20, 0x2f,
                0x14, 0xa9, 0x8a, 0x9b, 0xdc, 0x69, 0x33, 0x56, 0x91, 0xec, 0x3a, 0xe0, 0x99, 0x7e, 0x68, 0x66,
                0xe3, 0x39, 0xd5, 0xb8, 0x18, 0xe7, 0x1b, 0x0a, 0xdc, 0x63, 0xee, 0x3f, 0x59, 0xad, 0x76, 0xc1,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_256_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x32, 0x06, 0x83, 0xb4, 0x23, 0x3b, 0xb8, 0x4a, 0x22, 0x96, 0xcc, 0x22, 0x51, 0xf7, 0x1b, 0xdf,
            };
            var key = new byte[]
            {
                0x39, 0x2c, 0xdb, 0x19, 0x42, 0xfd, 0xec, 0x80, 0xd6, 0xa6, 0xdd, 0x3c, 0xaf, 0xdf, 0x78, 0xfb,
                0x10, 0x66, 0x35, 0x92, 0xf9, 0xdf, 0xde, 0xe1, 0x05, 0xf7, 0xdf, 0xdf, 0x41, 0x63, 0x41, 0xa3,
            };
            var iv = new byte[]
            {
                0xbd, 0x84, 0x19, 0x7a, 0xfd, 0x64, 0xac, 0x35, 0x1a, 0x02, 0xdd, 0x7d, 0x5e, 0x7b, 0x9a, 0x42,
            };

            // echo -n -e '\x32\x06\x83\xb4\x23\x3b\xb8\x4a\x22\x96\xcc\x22\x51\xf7\x1b\xdf' | openssl enc -e -aes-256-ctr -K 392CDB1942FDEC80D6A6DD3CAFDF78FB10663592F9DFDEE105F7DFDF416341A3 -iv BD84197AFD64AC351A02DD7D5E7B9A42 -nopad | hd
            var expected = new byte[]
            {
                0xc8, 0x8a, 0x9b, 0xd7, 0x03, 0xfa, 0x95, 0x61, 0x95, 0x69, 0x81, 0xa8, 0x2d, 0x0d, 0xfe, 0x4a,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_256_Length35_NoPad()
        {
            var input = new byte[]
            {
                0x1d, 0xd0, 0x11, 0xea, 0xc2, 0x89, 0xe5, 0x5a, 0x4d, 0xf9, 0x13, 0x4b, 0x1e, 0x0c, 0x3e, 0x72,
                0x65, 0x3a, 0x7f, 0x2b, 0xc6, 0xfe, 0xfd, 0xac, 0xba, 0x00, 0x77, 0xf6, 0x01, 0x61, 0x83, 0x8a,
                0x5c, 0x9c, 0xc2,
            };
            var key = new byte[]
            {
                0x70, 0x52, 0x56, 0xe1, 0x33, 0x9e, 0xbf, 0x2c, 0x04, 0x51, 0x61, 0x16, 0x0e, 0xc4, 0x6b, 0x17,
                0x23, 0xfb, 0x6f, 0x7c, 0x1e, 0xd2, 0x65, 0x30, 0xc1, 0x12, 0xee, 0x58, 0xec, 0x76, 0x89, 0xee,
            };
            var iv = new byte[]
            {
                0x82, 0x49, 0xcd, 0x20, 0x0e, 0x59, 0x4b, 0x8c, 0x06, 0xd2, 0xf9, 0x5b, 0x58, 0xe9, 0x68, 0x32,
            };

            // echo -n -e '\x1d\xd0\x11\xea\xc2\x89\xe5\x5a\x4d\xf9\x13\x4b\x1e\x0c\x3e\x72\x65\x3a\x7f\x2b\xc6\xfe\xfd\xac\xba\x00\x77\xf6\x01\x61\x83\x8a\x5c\x9c\xc2' | openssl enc -e -aes-256-ctr -K 705256E1339EBF2C045161160EC46B1723FB6F7C1ED26530C112EE58EC7689EE -iv 8249CD200E594B8C06D2F95B58E96832 -nopad | hd
            var expected = new byte[]
            {
                0x51, 0xef, 0xbb, 0x59, 0xad, 0xbf, 0xa3, 0x76, 0x99, 0x52, 0x0c, 0x2c, 0xc1, 0x77, 0xe7, 0x54,
                0xc9, 0x0b, 0xc4, 0x4a, 0xfc, 0xe1, 0x6a, 0x29, 0x92, 0xbc, 0xe5, 0x27, 0x5f, 0xb1, 0xb8, 0x6c,
                0x46, 0xd7, 0x46,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_CTR_256_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x96, 0x49, 0x5f, 0x8e, 0xec, 0x1f, 0xa3, 0x9e, 0xec, 0x26, 0x1f, 0x21, 0xb0, 0x66, 0x3f, 0x8d,
                0xc8, 0x72, 0x94, 0xc4, 0xf6, 0x4a, 0x09, 0xc9, 0xb0, 0xe2, 0x76, 0x4c, 0xd8, 0x0a, 0xd7, 0xd7,
                0xa9, 0xbc, 0xc2, 0xa2, 0x17, 0xfa, 0x02, 0x62, 0xa6, 0x2f, 0x33, 0xe7, 0x3a, 0x29, 0xdc, 0x9f,
                0x92, 0x6c, 0x93, 0xe6, 0x55, 0xa4, 0x3c, 0x4b, 0x3f, 0x96, 0xde, 0x0a, 0xa9, 0x57, 0xc5, 0xe2,
            };
            var key = new byte[]
            {
                0x4e, 0x47, 0x78, 0xf3, 0xa4, 0x9d, 0x76, 0xcd, 0x70, 0x31, 0x1e, 0xc6, 0x16, 0x21, 0x8f, 0x86,
                0x06, 0xd6, 0xb9, 0x6c, 0x77, 0xf0, 0x82, 0x04, 0x7f, 0x77, 0x62, 0x80, 0x1c, 0xf7, 0xb9, 0x4f,
            };
            var iv = new byte[]
            {
                0x6a, 0x51, 0x99, 0xf2, 0xb1, 0xe8, 0xfb, 0xf5, 0xf6, 0xc5, 0x76, 0x23, 0x86, 0x75, 0x34, 0x1e,
            };

            // echo -n -e '\x96\x49\x5f\x8e\xec\x1f\xa3\x9e\xec\x26\x1f\x21\xb0\x66\x3f\x8d\xc8\x72\x94\xc4\xf6\x4a\x09\xc9\xb0\xe2\x76\x4c\xd8\x0a\xd7\xd7\xa9\xbc\xc2\xa2\x17\xfa\x02\x62\xa6\x2f\x33\xe7\x3a\x29\xdc\x9f\x92\x6c\x93\xe6\x55\xa4\x3c\x4b\x3f\x96\xde\x0a\xa9\x57\xc5\xe2' | openssl enc -e -aes-256-ctr -K 4E4778F3A49D76CD70311EC616218F8606D6B96C77F082047F7762801CF7B94F -iv 6A5199F2B1E8FBF5F6C576238675341E -nopad | hd
            var expected = new byte[]
            {
                0x0a, 0xbb, 0xc8, 0xd1, 0xdb, 0xa6, 0x4c, 0x6b, 0x5f, 0x63, 0xbf, 0x78, 0x97, 0xc8, 0xa8, 0x00,
                0xee, 0x20, 0x4c, 0xa8, 0xbc, 0x87, 0x22, 0x73, 0xa0, 0xc0, 0xdf, 0xe0, 0x65, 0x5b, 0x1f, 0x11,
                0x1d, 0xe6, 0xfb, 0xc2, 0x3d, 0xdc, 0xeb, 0x51, 0xdb, 0xd2, 0x87, 0x79, 0x39, 0x79, 0x35, 0xb1,
                0x8e, 0x53, 0xc7, 0x0a, 0xf9, 0x9f, 0x3c, 0xbe, 0x37, 0x6f, 0xd7, 0xd6, 0x5e, 0x94, 0x6a, 0x22,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.CTR, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_128_Length16_NoPad()
        {
            var input = new byte[]
            {
                0x06, 0x57, 0x03, 0xd3, 0x9d, 0x58, 0x6b, 0x5d, 0xc5, 0x73, 0x74, 0x2d, 0x3a, 0xf5, 0xb1, 0x78,
            };
            var key = new byte[]
            {
                0x78, 0xcf, 0x5b, 0xc5, 0x88, 0x9c, 0xd5, 0x1d, 0xda, 0xc4, 0x75, 0xb1, 0x7a, 0x5f, 0x7e, 0x0a,
            };
            var iv = new byte[]
            {
                0x42, 0x44, 0x79, 0xc4, 0xf3, 0xe6, 0xb1, 0x11, 0xe6, 0x3b, 0x2d, 0x3d, 0x74, 0xce, 0xbb, 0x01,
            };

            // echo -n -e '\x06\x57\x03\xd3\x9d\x58\x6b\x5d\xc5\x73\x74\x2d\x3a\xf5\xb1\x78' | openssl enc -e -aes-128-ofb -K 78CF5BC5889CD51DDAC475B17A5F7E0A -iv 424479C4F3E6B111E63B2D3D74CEBB01 -nopad | hd
            var expected = new byte[]
            {
                0xf4, 0x71, 0xef, 0x7a, 0xa2, 0xef, 0x90, 0x25, 0x18, 0x3e, 0x24, 0xc1, 0x40, 0xe4, 0xff, 0xb6,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_128_Length35_NoPad()
        {
            var input = new byte[]
            {
                0x14, 0xfe, 0xab, 0xb6, 0x19, 0x6f, 0x95, 0x69, 0x82, 0xe6, 0xf8, 0xd9, 0xe3, 0xb9, 0xe3, 0x65,
                0xf4, 0x69, 0xea, 0xf5, 0x7b, 0xec, 0x84, 0x91, 0x1d, 0x49, 0xde, 0x4d, 0x6f, 0x97, 0xa8, 0x0c,
                0x08, 0x74, 0x9d,
            };
            var key = new byte[]
            {
                0x7c, 0xb3, 0xc7, 0xf0, 0xd3, 0xaf, 0x0f, 0x42, 0x0d, 0xee, 0xd7, 0x2e, 0x2d, 0x58, 0xc7, 0x49,
            };
            var iv = new byte[]
            {
                0x0a, 0xe3, 0xc6, 0x85, 0x27, 0x79, 0x19, 0x99, 0xd0, 0x90, 0x48, 0xfa, 0xea, 0x3d, 0xec, 0xd0,
            };

            // echo -n -e '\x14\xfe\xab\xb6\x19\x6f\x95\x69\x82\xe6\xf8\xd9\xe3\xb9\xe3\x65\xf4\x69\xea\xf5\x7b\xec\x84\x91\x1d\x49\xde\x4d\x6f\x97\xa8\x0c\x08\x74\x9d' | openssl enc -e -aes-128-ofb -K 7CB3C7F0D3AF0F420DEED72E2D58C749 -iv 0AE3C68527791999D09048FAEA3DECD0 -nopad | hd
            var expected = new byte[]
            {
                0x96, 0x88, 0x4d, 0x4e, 0x85, 0xde, 0x53, 0x86, 0x4f, 0x63, 0x8e, 0x2e, 0x9a, 0xe7, 0x60, 0xda,
                0xae, 0x7a, 0xec, 0x54, 0x84, 0xe9, 0xba, 0x22, 0x79, 0x5f, 0x46, 0x2f, 0xbe, 0x6f, 0x1a, 0xe9,
                0x33, 0xf5, 0xcd,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_128_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x6e, 0x1b, 0x66, 0xb2, 0x2c, 0x79, 0x16, 0x45, 0x6b, 0xaa, 0x76, 0xa3, 0x46, 0x1b, 0xb1, 0xf4,
                0xa7, 0x4e, 0x9d, 0x28, 0x42, 0xee, 0x75, 0x02, 0x99, 0x2e, 0x20, 0x43, 0x66, 0x15, 0x57, 0xcf,
                0x01, 0x06, 0xbf, 0x11, 0xf1, 0x15, 0x1c, 0x90, 0xcc, 0x80, 0x19, 0x7d, 0x03, 0x76, 0x52, 0xb4,
                0xde, 0x53, 0x52, 0x9c, 0xa0, 0xc4, 0x8e, 0x80, 0xa5, 0x64, 0x18, 0xfd, 0x59, 0xd3, 0xde, 0x56,
            };
            var key = new byte[]
            {
                0x52, 0xa7, 0xa1, 0x3f, 0x5b, 0xa0, 0x03, 0x92, 0x31, 0x0c, 0x5b, 0xc1, 0xd4, 0xf8, 0xff, 0x23,
            };
            var iv = new byte[]
            {
                0xdb, 0x6b, 0x64, 0x13, 0xc2, 0xba, 0x2f, 0x3d, 0x78, 0x3f, 0x6b, 0x8c, 0xfd, 0x1e, 0x37, 0xf9,
            };

            // echo -n -e '\x6e\x1b\x66\xb2\x2c\x79\x16\x45\x6b\xaa\x76\xa3\x46\x1b\xb1\xf4\xa7\x4e\x9d\x28\x42\xee\x75\x02\x99\x2e\x20\x43\x66\x15\x57\xcf\x01\x06\xbf\x11\xf1\x15\x1c\x90\xcc\x80\x19\x7d\x03\x76\x52\xb4\xde\x53\x52\x9c\xa0\xc4\x8e\x80\xa5\x64\x18\xfd\x59\xd3\xde\x56' | openssl enc -e -aes-128-ofb -K 52A7A13F5BA00392310C5BC1D4F8FF23 -iv DB6B6413C2BA2F3D783F6B8CFD1E37F9 -nopad | hd
            var expected = new byte[]
            {
                0xc7, 0x9c, 0x09, 0xe1, 0x99, 0x28, 0x56, 0xe8, 0x16, 0x44, 0x79, 0x84, 0xed, 0x39, 0x3f, 0xc7,
                0xaa, 0x11, 0xde, 0xc5, 0x32, 0xf2, 0xea, 0xd5, 0x81, 0xee, 0x47, 0x8a, 0x10, 0xee, 0xa1, 0x83,
                0x7d, 0xef, 0x5e, 0xe1, 0xf6, 0x92, 0x05, 0xdc, 0x6f, 0x84, 0xed, 0x4e, 0xaa, 0x9b, 0x37, 0xd0,
                0x43, 0xe2, 0x0c, 0x6f, 0x22, 0x31, 0xcb, 0x7d, 0x4d, 0xd7, 0xa1, 0xa4, 0xd9, 0x7e, 0x55, 0xd2,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_192_Length16_NoPad()
        {
            var input = new byte[]
            {
                0xa1, 0xc3, 0x2b, 0x5b, 0xd4, 0x13, 0x58, 0x3e, 0x50, 0xc0, 0x6b, 0x93, 0x68, 0xcc, 0xab, 0xad,
            };
            var key = new byte[]
            {
                0x65, 0xf4, 0x21, 0xee, 0x6f, 0xcb, 0x93, 0x97, 0x78, 0x63, 0xc7, 0x1c, 0x34, 0x76, 0x95, 0x12,
                0xd5, 0x62, 0x20, 0x11, 0xcd, 0xa3, 0x4e, 0xc8,
            };
            var iv = new byte[]
            {
                0x12, 0x26, 0xc2, 0x02, 0x4f, 0x9c, 0xd5, 0xab, 0x94, 0xbd, 0x27, 0x08, 0xfd, 0x48, 0x8a, 0xd5,
            };

            // echo -n -e '\xa1\xc3\x2b\x5b\xd4\x13\x58\x3e\x50\xc0\x6b\x93\x68\xcc\xab\xad' | openssl enc -e -aes-192-ofb -K 65F421EE6FCB93977863C71C34769512D5622011CDA34EC8 -iv 1226C2024F9CD5AB94BD2708FD488AD5 -nopad | hd
            var expected = new byte[]
            {
                0x49, 0xc5, 0x2c, 0x55, 0x4c, 0x74, 0xb0, 0x3e, 0xba, 0xd0, 0xcf, 0xdc, 0xd2, 0x44, 0xcb, 0x04,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_192_Length35_NoPad()
        {
            var input = new byte[]
            {
                0x2f, 0x93, 0xe3, 0x70, 0x4c, 0x3c, 0x09, 0xd9, 0x2a, 0x58, 0xbd, 0x06, 0xac, 0x99, 0xe0, 0xc1,
                0xa5, 0x59, 0xdb, 0x48, 0x08, 0x91, 0x47, 0xdb, 0x8e, 0x1b, 0x88, 0x76, 0x4f, 0x8c, 0x15, 0x8d,
                0xd7, 0x4a, 0xe1,
            };
            var key = new byte[]
            {
                0x39, 0xc0, 0xdd, 0x7b, 0xd6, 0x1c, 0xe9, 0xd7, 0xf6, 0xdf, 0xce, 0xfe, 0xfa, 0xdd, 0x66, 0x62,
                0xa3, 0x6c, 0x41, 0xcc, 0x9e, 0x4b, 0x07, 0xe2,
            };
            var iv = new byte[]
            {
                0x30, 0xb3, 0x93, 0x8a, 0x9e, 0x43, 0x2f, 0x2e, 0x61, 0xb8, 0xa6, 0x01, 0xc7, 0xdd, 0x05, 0x2c,
            };

            // echo -n -e '\x2f\x93\xe3\x70\x4c\x3c\x09\xd9\x2a\x58\xbd\x06\xac\x99\xe0\xc1\xa5\x59\xdb\x48\x08\x91\x47\xdb\x8e\x1b\x88\x76\x4f\x8c\x15\x8d\xd7\x4a\xe1' | openssl enc -e -aes-192-ofb -K 39C0DD7BD61CE9D7F6DFCEFEFADD6662A36C41CC9E4B07E2 -iv 30B3938A9E432F2E61B8A601C7DD052C -nopad | hd
            var expected = new byte[]
            {
                0xc9, 0xc3, 0x2f, 0x5e, 0x4e, 0xd1, 0x37, 0x02, 0x83, 0xe1, 0xb8, 0x85, 0x9d, 0xdb, 0x0e, 0xd0,
                0xd9, 0xcd, 0xf9, 0x5b, 0xbd, 0x81, 0x63, 0x3a, 0xac, 0xde, 0xf8, 0x5b, 0x2e, 0x2a, 0x8e, 0x84,
                0x09, 0x88, 0x44,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_192_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x1f, 0xb9, 0x51, 0xfc, 0xc0, 0x1d, 0x8e, 0x99, 0xe8, 0x29, 0x71, 0x20, 0x96, 0x7d, 0x42, 0xed,
                0xb8, 0xfb, 0x4b, 0x23, 0x88, 0x5e, 0x39, 0xb2, 0xaf, 0x9f, 0x9c, 0x42, 0x36, 0x64, 0x9b, 0xc6,
                0x67, 0x14, 0xac, 0xe5, 0xfa, 0x0b, 0x21, 0x13, 0x25, 0xfa, 0xa1, 0x74, 0xd2, 0x0e, 0x98, 0xe4,
                0x75, 0xb9, 0x48, 0xcc, 0x91, 0xe2, 0xa3, 0xc1, 0x80, 0x9e, 0x4d, 0x20, 0x80, 0x4b, 0x62, 0x83,
            };
            var key = new byte[]
            {
                0x8e, 0xaa, 0xb9, 0x81, 0xd0, 0x5d, 0xf3, 0xad, 0xda, 0x38, 0xfd, 0x8e, 0xbc, 0xc4, 0xe0, 0xa0,
                0x07, 0xb8, 0xcc, 0x7d, 0x1c, 0xcf, 0x34, 0x85,
            };
            var iv = new byte[]
            {
                0x70, 0xeb, 0x65, 0x5b, 0xbd, 0x00, 0x92, 0xd9, 0x97, 0x1e, 0xe6, 0x27, 0x55, 0x16, 0x13, 0x18,
            };

            // echo -n -e '\x1f\xb9\x51\xfc\xc0\x1d\x8e\x99\xe8\x29\x71\x20\x96\x7d\x42\xed\xb8\xfb\x4b\x23\x88\x5e\x39\xb2\xaf\x9f\x9c\x42\x36\x64\x9b\xc6\x67\x14\xac\xe5\xfa\x0b\x21\x13\x25\xfa\xa1\x74\xd2\x0e\x98\xe4\x75\xb9\x48\xcc\x91\xe2\xa3\xc1\x80\x9e\x4d\x20\x80\x4b\x62\x83' | openssl enc -e -aes-192-ofb -K 8EAAB981D05DF3ADDA38FD8EBCC4E0A007B8CC7D1CCF3485 -iv 70EB655BBD0092D9971EE62755161318 -nopad | hd
            var expected = new byte[]
            {
                0x01, 0x8f, 0x85, 0x93, 0xb4, 0x7d, 0x43, 0x4c, 0xac, 0x96, 0xd3, 0xf5, 0xcd, 0x39, 0x29, 0x08,
                0x91, 0x43, 0xe4, 0x87, 0xa0, 0xfe, 0xde, 0x05, 0x5d, 0xfb, 0x1e, 0xe2, 0xea, 0x76, 0x0a, 0x53,
                0xd5, 0xfb, 0x02, 0x9c, 0x08, 0x30, 0x6d, 0x7b, 0x53, 0xd6, 0x9f, 0xbc, 0x1b, 0x76, 0x05, 0x55,
                0xb8, 0xa8, 0x9d, 0x3b, 0x4d, 0x82, 0x9b, 0x8c, 0x96, 0xeb, 0x4e, 0x9d, 0x91, 0xda, 0x6e, 0x9e,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_256_Length16_NoPad()
        {
            var input = new byte[]
            {
                0xc5, 0x9b, 0xf1, 0x59, 0xe4, 0x14, 0x05, 0xbb, 0xbe, 0xac, 0x19, 0xc8, 0x7e, 0xe4, 0x67, 0xbf,
            };
            var key = new byte[]
            {
                0x76, 0x33, 0x10, 0xe5, 0xf7, 0x98, 0xef, 0xd9, 0xa5, 0x23, 0xf7, 0x9e, 0xde, 0xb8, 0x4a, 0xf1,
                0xa4, 0xb4, 0xb8, 0x80, 0xdd, 0xda, 0xa0, 0x5c, 0xe6, 0xa9, 0x9c, 0x10, 0xe7, 0xca, 0x5a, 0xb2,
            };
            var iv = new byte[]
            {
                0xb6, 0x26, 0xb1, 0x21, 0x05, 0x2e, 0x20, 0x2d, 0xac, 0x18, 0xb4, 0xc0, 0x1d, 0x66, 0xdd, 0x05,
            };

            // echo -n -e '\xc5\x9b\xf1\x59\xe4\x14\x05\xbb\xbe\xac\x19\xc8\x7e\xe4\x67\xbf' | openssl enc -e -aes-256-ofb -K 763310E5F798EFD9A523F79EDEB84AF1A4B4B880DDDAA05CE6A99C10E7CA5AB2 -iv B626B121052E202DAC18B4C01D66DD05 -nopad | hd
            var expected = new byte[]
            {
                0xd4, 0xef, 0xb1, 0x5d, 0x7c, 0x7e, 0x36, 0x89, 0xd2, 0x18, 0xbb, 0x8c, 0x1f, 0x07, 0x1d, 0x49,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_256_Length35_NoPad()
        {
            var input = new byte[]
            {
                0x62, 0x28, 0x23, 0xc9, 0x2c, 0xe7, 0xe2, 0x9b, 0x92, 0xb4, 0xff, 0x4e, 0xfb, 0xde, 0xf1, 0xda,
                0xc9, 0x44, 0xe8, 0xb7, 0x07, 0x28, 0xeb, 0x76, 0x94, 0x8a, 0xd4, 0xc4, 0x26, 0xe0, 0x3e, 0x7f,
                0xcc, 0x97, 0xae,
            };
            var key = new byte[]
            {
                0xbf, 0xa7, 0x90, 0x86, 0xcf, 0x44, 0x15, 0x8e, 0x50, 0x2f, 0xd1, 0x32, 0xcd, 0x26, 0xd9, 0xf7,
                0xd9, 0x7e, 0x25, 0xfe, 0x39, 0x3c, 0xac, 0x35, 0xa1, 0x12, 0x1d, 0x75, 0xb2, 0x76, 0x7f, 0x82,
            };
            var iv = new byte[]
            {
                0x64, 0x30, 0x32, 0x33, 0x38, 0xbd, 0x18, 0x73, 0xf2, 0x99, 0x9b, 0x47, 0xc2, 0x58, 0x07, 0x9d,
            };

            // echo -n -e '\x62\x28\x23\xc9\x2c\xe7\xe2\x9b\x92\xb4\xff\x4e\xfb\xde\xf1\xda\xc9\x44\xe8\xb7\x07\x28\xeb\x76\x94\x8a\xd4\xc4\x26\xe0\x3e\x7f\xcc\x97\xae' | openssl enc -e -aes-256-ofb -K BFA79086CF44158E502FD132CD26D9F7D97E25FE393CAC35A1121D75B2767F82 -iv 6430323338BD1873F2999B47C258079D -nopad | hd
            var expected = new byte[]
            {
                0xf9, 0x43, 0x63, 0x96, 0x35, 0x46, 0x21, 0xac, 0x84, 0x43, 0x44, 0x17, 0xfc, 0x78, 0x41, 0x12,
                0x4e, 0x69, 0xbb, 0x71, 0x37, 0x12, 0xb1, 0x8f, 0xe0, 0xf7, 0xcf, 0x8c, 0xb0, 0x9b, 0x3e, 0x20,
                0x15, 0x7a, 0xce,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }

        [TestMethod]
        public void AES_OFB_256_Length64_NoPad()
        {
            var input = new byte[]
            {
                0x4d, 0xe8, 0x64, 0x00, 0xa6, 0x98, 0x75, 0x82, 0xfa, 0x5b, 0xe4, 0xbc, 0x26, 0xa0, 0xdc, 0xd9,
                0xaf, 0x4f, 0xce, 0x9d, 0xf4, 0xa5, 0xbf, 0x1b, 0x65, 0xb2, 0x0c, 0x9f, 0xa1, 0x65, 0x72, 0x49,
                0x0b, 0x80, 0x27, 0xc9, 0x11, 0x7e, 0xdc, 0xcb, 0xbb, 0xb0, 0x38, 0xdc, 0xd9, 0x5c, 0x4d, 0x51,
                0xbd, 0xc1, 0x97, 0x73, 0x8a, 0x69, 0xa9, 0xa7, 0x29, 0x49, 0x9a, 0xf3, 0x8c, 0xd5, 0xe1, 0x95,
            };
            var key = new byte[]
            {
                0xe9, 0x9a, 0xb0, 0xa5, 0x78, 0x12, 0xc8, 0x30, 0x73, 0x02, 0xe2, 0x44, 0x6d, 0xe2, 0x41, 0x09,
                0x65, 0xba, 0xe2, 0xdf, 0xcd, 0xff, 0xbe, 0xa1, 0xd7, 0x80, 0xa0, 0xc8, 0xe3, 0xe8, 0x3e, 0xe5,
            };
            var iv = new byte[]
            {
                0xce, 0xa2, 0xf3, 0x3e, 0xab, 0xa7, 0xd9, 0xaa, 0xf9, 0x66, 0xff, 0x87, 0x87, 0x65, 0x39, 0x46,
            };

            // echo -n -e '\x4d\xe8\x64\x00\xa6\x98\x75\x82\xfa\x5b\xe4\xbc\x26\xa0\xdc\xd9\xaf\x4f\xce\x9d\xf4\xa5\xbf\x1b\x65\xb2\x0c\x9f\xa1\x65\x72\x49\x0b\x80\x27\xc9\x11\x7e\xdc\xcb\xbb\xb0\x38\xdc\xd9\x5c\x4d\x51\xbd\xc1\x97\x73\x8a\x69\xa9\xa7\x29\x49\x9a\xf3\x8c\xd5\xe1\x95' | openssl enc -e -aes-256-ofb -K E99AB0A57812C8307302E2446DE2410965BAE2DFCDFFBEA1D780A0C8E3E83EE5 -iv CEA2F33EABA7D9AAF966FF8787653946 -nopad | hd
            var expected = new byte[]
            {
                0xc0, 0xf7, 0xb0, 0x88, 0xc2, 0xe6, 0x70, 0x12, 0xea, 0x47, 0x5c, 0x01, 0xd9, 0x1b, 0xaf, 0xc2,
                0x92, 0x8e, 0x63, 0xed, 0xe5, 0xd4, 0x31, 0x6e, 0xe3, 0xe6, 0xc6, 0x39, 0x6e, 0x6a, 0x92, 0xbe,
                0x00, 0x13, 0x66, 0x7d, 0xa7, 0x01, 0x07, 0xd4, 0xdb, 0x21, 0xac, 0x1f, 0x12, 0xcf, 0xc8, 0xbf,
                0xf0, 0x1e, 0x04, 0x78, 0x6a, 0x90, 0x95, 0x80, 0x16, 0x8c, 0x7c, 0x86, 0xca, 0x26, 0x78, 0xab,
            };

            var actual = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Encrypt(input);

            CollectionAssert.AreEqual(expected, actual);

            var decrypted = new AesCipher(key, (byte[])iv.Clone(), AesCipherMode.OFB, pkcs7Padding: false).Decrypt(actual);

            CollectionAssert.AreEqual(input, decrypted);
        }
    }
}
