示例#1
0
        public static byte[] EncryptMessage(byte[] key, byte[] nonce, byte[] message, ulong sessionID, out byte[] signature)
        {
            SMB2TransformHeader transformHeader = CreateTransformHeader(nonce, message.Length, sessionID);

            byte[] associatedata = transformHeader.GetAssociatedData();
            return(AesCcm.Encrypt(key, nonce, message, associatedata, SMB2TransformHeader.SignatureLength, out signature));
        }
示例#2
0
        // Based on #1 test vector from https://docs.microsoft.com/en-us/archive/blogs/openspecification/encryption-in-smb-3-0-a-protocol-perspective
        public void TestEncryption()
        {
            byte[] key   = new byte[] { 0x26, 0x1B, 0x72, 0x35, 0x05, 0x58, 0xF2, 0xE9, 0xDC, 0xF6, 0x13, 0x07, 0x03, 0x83, 0xED, 0xBF };
            byte[] nonce = new byte[] { 0x66, 0xE6, 0x9A, 0x11, 0x18, 0x92, 0x58, 0x4F, 0xB5, 0xED, 0x52 };

            byte[] data = new byte[] { 0xFE, 0x53, 0x4D, 0x42, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x40, 0x00,
                                       0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                       0xFF, 0xFE, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x14, 0x00, 0xE4, 0x08, 0x00,
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                       0x31, 0x00, 0x70, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                       0x15, 0x01, 0x00, 0x00, 0x39, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x39, 0x02, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                       0x53, 0x6D, 0x62, 0x33, 0x20, 0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20,
                                       0x74, 0x65, 0x73, 0x74, 0x69, 0x6E, 0x67 };

            byte[] associatedData = new byte[] { 0x66, 0xE6, 0x9A, 0x11, 0x18, 0x92, 0x58, 0x4F, 0xB5, 0xED, 0x52, 0x4A, 0x74, 0x4D, 0xA3, 0xEE,
                                                 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x14, 0x00, 0xE4, 0x08, 0x00 };

            byte[] expectedEncrypted = new byte[] { 0x25, 0xC8, 0xFE, 0xE1, 0x66, 0x05, 0xA4, 0x37, 0x83, 0x2D, 0x1C, 0xD5, 0x2D, 0xA9, 0xF4, 0x64,
                                                    0x53, 0x33, 0x48, 0x2A, 0x17, 0x5F, 0xE5, 0x38, 0x45, 0x63, 0xF4, 0x5F, 0xCD, 0xAF, 0xAE, 0xF3,
                                                    0x8B, 0xC6, 0x2B, 0xA4, 0xD5, 0xC6, 0x28, 0x97, 0x99, 0x66, 0x25, 0xA4, 0x4C, 0x29, 0xBE, 0x56,
                                                    0x58, 0xDE, 0x2E, 0x61, 0x17, 0x58, 0x57, 0x79, 0xE7, 0xB5, 0x9F, 0xFD, 0x97, 0x12, 0x78, 0xD0,
                                                    0x85, 0x80, 0xD7, 0xFA, 0x89, 0x9E, 0x41, 0x0E, 0x91, 0x0E, 0xAB, 0xF5, 0xAA, 0x1D, 0xB4, 0x30,
                                                    0x50, 0xB3, 0x3B, 0x49, 0x18, 0x26, 0x37, 0x75, 0x9A, 0xC1, 0x5D, 0x84, 0xBF, 0xCD, 0xF5, 0xB6,
                                                    0xB2, 0x38, 0x99, 0x3C, 0x0F, 0x4C, 0xF4, 0xD6, 0x01, 0x20, 0x23, 0xF6, 0xC6, 0x27, 0x29, 0x70,
                                                    0x75, 0xD8, 0x4B, 0x78, 0x03, 0x91, 0x2D, 0x0A, 0x96, 0x39, 0x63, 0x44, 0x53, 0x59, 0x5E, 0xF3,
                                                    0xE3, 0x3F, 0xFE, 0x4E, 0x7A, 0xC2, 0xAB };

            byte[] expectedSignature = new byte[] { 0x81, 0xA2, 0x86, 0x53, 0x54, 0x15, 0x44, 0x5D, 0xAE, 0x39, 0x39, 0x21, 0xE4, 0x4F, 0xA4, 0x2E };

            byte[] calculatedSignature;
            byte[] encrypted = AesCcm.Encrypt(key, nonce, data, associatedData, 16, out calculatedSignature);
            Assert.True(ByteUtils.AreByteArraysEqual(expectedEncrypted, encrypted));
            Assert.True(ByteUtils.AreByteArraysEqual(expectedSignature, calculatedSignature));
        }
示例#3
0
        static (byte[] CipherText, byte[] Tag) EncryptCCM(string text, byte[] key, byte[] nonce, byte[] associatedData = null)
        {
            var byteText   = Encoding.ASCII.GetBytes(text);
            var tag        = new byte[16];
            var cipherText = new byte[byteText.Length];

            using var gcm = new AesCcm(key);
            gcm.Encrypt(nonce, byteText, cipherText, tag, associatedData);
            return(cipherText, tag);
        }
示例#4
0
        public static void TwoEncryptionsAndDecryptionsUsingOneInstance()
        {
            byte[] key             = "d5a194ed90cfe08abecd4691997ceb2c".HexToByteArray();
            byte[] originalData1   = Enumerable.Range(1, 15).Select((x) => (byte)x).ToArray();
            byte[] originalData2   = Enumerable.Range(14, 97).Select((x) => (byte)x).ToArray();
            byte[] associatedData2 = Enumerable.Range(100, 109).Select((x) => (byte)x).ToArray();
            byte[] nonce1          = "b41329dd64af2c3036661b46".HexToByteArray();
            byte[] nonce2          = "8ba10892e8b87d031196".HexToByteArray();

            byte[] expectedCiphertext1 = "58457f5939e029b99637c9aef266aa".HexToByteArray();
            byte[] expectedTag1        = "ac5ccedc".HexToByteArray();

            byte[] expectedCiphertext2 = (
                "be4a5174fc244002d8614652d75cad9b464d86709cd9e8c58061add9a7546a1d" +
                "8165b375011bd4d8e188d4d2782ae890aa7ddf335c9759267f813148903c47d1" +
                "de0278c772dc2295bef9bba3bbfde319edbb54b71288c1fd1ddefb4a9b12534d" +
                "15").HexToByteArray();
            byte[] expectedTag2 = "f564b8439dc79ddf7aa1a497bc1f780e".HexToByteArray();

            using (var aesCcm = new AesCcm(key))
            {
                byte[] ciphertext1 = new byte[originalData1.Length];
                byte[] tag1        = new byte[expectedTag1.Length];
                aesCcm.Encrypt(nonce1, originalData1, ciphertext1, tag1);
                Assert.Equal(expectedCiphertext1, ciphertext1);
                Assert.Equal(expectedTag1, tag1);

                byte[] ciphertext2 = new byte[originalData2.Length];
                byte[] tag2        = new byte[expectedTag2.Length];
                aesCcm.Encrypt(nonce2, originalData2, ciphertext2, tag2, associatedData2);
                Assert.Equal(expectedCiphertext2, ciphertext2);
                Assert.Equal(expectedTag2, tag2);

                byte[] plaintext1 = new byte[originalData1.Length];
                aesCcm.Decrypt(nonce1, ciphertext1, tag1, plaintext1);
                Assert.Equal(originalData1, plaintext1);

                byte[] plaintext2 = new byte[originalData2.Length];
                aesCcm.Decrypt(nonce2, ciphertext2, tag2, plaintext2, associatedData2);
                Assert.Equal(originalData2, plaintext2);
            }
        }
示例#5
0
        public void Encrypt_throws_on_too_short_iv(int ivLength)
        {
            var key = new byte[16];

            Exceptions.AssertThrowsInternalError(() => AesCcm.Encrypt(key: key,
                                                                      plaintext: new byte[1],
                                                                      iv: new byte[ivLength],
                                                                      adata: new byte[0],
                                                                      tagLength: 8),
                                                 "IV must be at least 7 bytes long");
        }
示例#6
0
        public void Encrypt_throws_on_invalid_tag_length(int tagLength)
        {
            var key = new byte[16];

            Exceptions.AssertThrowsInternalError(() => AesCcm.Encrypt(key: key,
                                                                      plaintext: new byte[1],
                                                                      iv: new byte[16],
                                                                      adata: new byte[0],
                                                                      tagLength: tagLength),
                                                 "Tag must be 4, 8, 10, 12, 14 or 16 bytes long");
        }
示例#7
0
 /// <summary>
 /// Encrypts or decrypts a byte array with the AES Counter with Cbc-Mac (CCM) mode.
 /// Note that for this algorithm, encryption and decryption are identical. Decryption
 /// consists of encrypting the encrypted byte array again with the same nonce
 /// and key used during encryption.
 /// </summary>
 /// <param name="bytesToEncrypt">
 /// The byte array that will get encrypted.
 /// </param>
 /// <param name="nonce">
 /// The "number used only once" used during encryption.
 /// </param>
 /// <param name="key">The key used during encryption.</param>
 /// <param name="tag">The tag generated during encryption.</param>
 public static void AESCCMEncryptBytes(
     byte[] bytesToEncrypt,
     byte[] nonce,
     byte[] key,
     byte[] tag)
 {
     // Note that this passes the bytesToEncrypt as both the input and output array.
     // This works, since AES-CTR XOR-s the input array with the encrypted counters,
     // so this is equivalent to saying bytesToEncrypt[i + j] ^= encryptedCounter[j]
     using AesCcm ccm = new AesCcm(key);
     ccm.Encrypt(nonce, bytesToEncrypt, bytesToEncrypt, tag);
 }
示例#8
0
        public static void EncryptDecryptNullTag()
        {
            byte[] key        = "d5a194ed90cfe08abecd4691997ceb2c".HexToByteArray();
            byte[] nonce      = new byte[12];
            byte[] plaintext  = new byte[0];
            byte[] ciphertext = new byte[0];

            using (var aesCcm = new AesCcm(key))
            {
                Assert.Throws <ArgumentNullException>("tag", () => aesCcm.Encrypt(nonce, plaintext, ciphertext, (byte[])null));
                Assert.Throws <ArgumentNullException>("tag", () => aesCcm.Decrypt(nonce, ciphertext, (byte[])null, plaintext));
            }
        }
示例#9
0
        public void Test_03_Encrypt_Example3_C3()
        {
            // §C.3
            using (AesCcm AesCcm = new AesCcm(128, 64 / 8, 96 / 8))
            {
                byte[] Ciphertext = AesCcm.Encrypt(
                    new byte[] { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 },                      // P
                    new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 },                                              // A
                    new byte[] { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b },                                                                                              // N
                    new byte[] { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f });                                                                     // K

                AssertEqual(new byte[] { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }, Ciphertext);
            }
        }
示例#10
0
        public void Test_02_Encrypt_Example2_C2()
        {
            // §C.2
            using (AesCcm AesCcm = new AesCcm(128, 48 / 8, 64 / 8))
            {
                byte[] Ciphertext = AesCcm.Encrypt(
                    new byte[] { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f },                      // P
                    new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },                      // A
                    new byte[] { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },                                                                      // N
                    new byte[] { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f });                     // K

                AssertEqual(new byte[] { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, Ciphertext);
            }
        }
示例#11
0
        public void Test_01_Encrypt_Example1_C1()
        {
            // §C.1
            using (AesCcm AesCcm = new AesCcm(128, 32 / 8, 56 / 8))
            {
                byte[] Ciphertext = AesCcm.Encrypt(
                    new byte[] { 0x20, 0x21, 0x22, 0x23 },                                                                                              // P
                    new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },                                                                      // A
                    new byte[] { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 },                                                                            // N
                    new byte[] { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f });                     // K

                AssertEqual(new byte[] { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, Ciphertext);
            }
        }
示例#12
0
        public static void PlaintextAndCiphertextSizeDiffer(int ptLen, int ctLen)
        {
            byte[] key        = new byte[16];
            byte[] nonce      = new byte[12];
            byte[] plaintext  = new byte[ptLen];
            byte[] ciphertext = new byte[ctLen];
            byte[] tag        = new byte[16];

            using (var aesCcm = new AesCcm(key))
            {
                Assert.Throws <ArgumentException>(() => aesCcm.Encrypt(nonce, plaintext, ciphertext, tag));
                Assert.Throws <ArgumentException>(() => aesCcm.Decrypt(nonce, ciphertext, tag, plaintext));
            }
        }
示例#13
0
        public static void AesCcmNistTests(AEADTest testCase)
        {
            using (var aesCcm = new AesCcm(testCase.Key))
            {
                byte[] ciphertext = new byte[testCase.Plaintext.Length];
                byte[] tag        = new byte[testCase.Tag.Length];
                aesCcm.Encrypt(testCase.Nonce, testCase.Plaintext, ciphertext, tag, testCase.AssociatedData);
                Assert.Equal(testCase.Ciphertext, ciphertext);
                Assert.Equal(testCase.Tag, tag);

                byte[] plaintext = new byte[testCase.Plaintext.Length];
                aesCcm.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData);
                Assert.Equal(testCase.Plaintext, plaintext);
            }
        }
示例#14
0
        public static void InvalidNonceSize(int nonceSize)
        {
            int dataLength = 30;
            byte[] plaintext = Enumerable.Range(1, dataLength).Select((x) => (byte)x).ToArray();
            byte[] ciphertext = new byte[dataLength];
            byte[] key = new byte[16];
            byte[] nonce = new byte[nonceSize];
            byte[] tag = new byte[AesCcm.TagByteSizes.MinSize];
            RandomNumberGenerator.Fill(key);
            RandomNumberGenerator.Fill(nonce);

            using (var aesCcm = new AesCcm(key))
            {
                Assert.Throws<ArgumentException>("nonce", () => aesCcm.Encrypt(nonce, plaintext, ciphertext, tag));
            }
        }
示例#15
0
        public static void InplaceEncryptDecrypt()
        {
            byte[] key               = "d5a194ed90cfe08abecd4691997ceb2c".HexToByteArray();
            byte[] nonce             = new byte[12];
            byte[] originalPlaintext = new byte[] { 1, 2, 8, 12, 16, 99, 0 };
            byte[] data              = (byte[])originalPlaintext.Clone();
            byte[] tag               = new byte[16];
            RandomNumberGenerator.Fill(nonce);

            using (var aesCcm = new AesCcm(key))
            {
                aesCcm.Encrypt(nonce, data, data, tag);
                Assert.NotEqual(originalPlaintext, data);

                aesCcm.Decrypt(nonce, data, tag, data);
                Assert.Equal(originalPlaintext, data);
            }
        }
示例#16
0
        public static void AesCcmNistTestsTamperCiphertext(AEADTest testCase)
        {
            using (var aesCcm = new AesCcm(testCase.Key))
            {
                byte[] ciphertext = new byte[testCase.Plaintext.Length];
                byte[] tag        = new byte[testCase.Tag.Length];
                aesCcm.Encrypt(testCase.Nonce, testCase.Plaintext, ciphertext, tag, testCase.AssociatedData);
                Assert.Equal(testCase.Ciphertext, ciphertext);
                Assert.Equal(testCase.Tag, tag);

                ciphertext[0] ^= 1;

                byte[] plaintext = new byte[testCase.Plaintext.Length];
                RandomNumberGenerator.Fill(plaintext);
                Assert.Throws <CryptographicException>(
                    () => aesCcm.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData));
                Assert.Equal(new byte[plaintext.Length], plaintext);
            }
        }
示例#17
0
        public void TestEncryption_Rfc3610_Packet_Vector1()
        {
            byte[] key = { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };

            byte[] nonce = { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 };

            byte[] data           = { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E };
            byte[] associatedData = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };

            byte[] expectedEncrypted = { 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
                                         0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 };

            byte[] expectedSignature = { 0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0 };

            byte[] encrypted = AesCcm.Encrypt(key, nonce, data, associatedData, 8, out byte[] calculatedSignature);

            Assert.True(ByteUtils.AreByteArraysEqual(expectedEncrypted, encrypted));
            Assert.True(ByteUtils.AreByteArraysEqual(expectedSignature, calculatedSignature));
        }
示例#18
0
        public static void ValidNonceSize(int nonceSize)
        {
            const int dataLength = 35;
            byte[] plaintext = Enumerable.Range(1, dataLength).Select((x) => (byte)x).ToArray();
            byte[] ciphertext = new byte[dataLength];
            byte[] key = new byte[16];
            byte[] nonce = new byte[nonceSize];
            byte[] tag = new byte[AesCcm.TagByteSizes.MinSize];
            RandomNumberGenerator.Fill(key);
            RandomNumberGenerator.Fill(nonce);

            using (var aesCcm = new AesCcm(key))
            {
                aesCcm.Encrypt(nonce, plaintext, ciphertext, tag);

                byte[] decrypted = new byte[dataLength];
                aesCcm.Decrypt(nonce, ciphertext, tag, decrypted);
                Assert.Equal(plaintext, decrypted);
            }
        }
示例#19
0
        public static void InplaceEncryptTamperTagDecrypt()
        {
            byte[] key               = "d5a194ed90cfe08abecd4691997ceb2c".HexToByteArray();
            byte[] nonce             = new byte[12];
            byte[] originalPlaintext = new byte[] { 1, 2, 8, 12, 16, 99, 0 };
            byte[] data              = (byte[])originalPlaintext.Clone();
            byte[] tag               = new byte[16];
            RandomNumberGenerator.Fill(nonce);

            using (var aesCcm = new AesCcm(key))
            {
                aesCcm.Encrypt(nonce, data, data, tag);
                Assert.NotEqual(originalPlaintext, data);

                tag[0] ^= 1;

                Assert.Throws <CryptographicException>(
                    () => aesCcm.Decrypt(nonce, data, tag, data));
                Assert.Equal(new byte[data.Length], data);
            }
        }
示例#20
0
        public void Test_04_Encrypt_Example4_C4()
        {
            // §C.4
            using (AesCcm AesCcm = new AesCcm(128, 112 / 8, 104 / 8))
            {
                byte[] AD = new byte[65536];
                int    i;

                for (i = 0; i < 65536; i++)
                {
                    AD[i] = (byte)i;
                }

                byte[] Ciphertext = AesCcm.Encrypt(
                    new byte[] { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f },                      // P
                    AD,                                                                                                                                                                                                                                 // A
                    new byte[] { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c },                                                                                                                                        // N
                    new byte[] { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f });                                                                                                                     // K

                AssertEqual(new byte[] { 0x69, 0x91, 0x5d, 0xad, 0x1e, 0x84, 0xc6, 0x37, 0x6a, 0x68, 0xc2, 0x96, 0x7e, 0x4d, 0xab, 0x61, 0x5a, 0xe0, 0xfd, 0x1f, 0xae, 0xc4, 0x4c, 0xc4, 0x84, 0x82, 0x85, 0x29, 0x46, 0x3c, 0xcf, 0x72, 0xb4, 0xac, 0x6b, 0xec, 0x93, 0xe8, 0x59, 0x8e, 0x7f, 0x0d, 0xad, 0xbc, 0xea, 0x5b }, Ciphertext);
            }
        }
示例#21
0
        public static void EncryptTamperAADDecrypt(int dataLength, int additionalDataLength)
        {
            byte[] additionalData = new byte[additionalDataLength];
            RandomNumberGenerator.Fill(additionalData);

            byte[] plaintext  = Enumerable.Range(1, dataLength).Select((x) => (byte)x).ToArray();
            byte[] ciphertext = new byte[dataLength];
            byte[] key        = new byte[16];
            byte[] nonce      = new byte[AesCcm.NonceByteSizes.MinSize];
            byte[] tag        = new byte[AesCcm.TagByteSizes.MinSize];
            RandomNumberGenerator.Fill(key);
            RandomNumberGenerator.Fill(nonce);

            using (var aesCcm = new AesCcm(key))
            {
                aesCcm.Encrypt(nonce, plaintext, ciphertext, tag, additionalData);

                additionalData[0] ^= 1;

                byte[] decrypted = new byte[dataLength];
                Assert.Throws <CryptographicException>(
                    () => aesCcm.Decrypt(nonce, ciphertext, tag, decrypted, additionalData));
            }
        }
        private static Smb2EncryptedPacket Encrypt(ulong sessionId, Smb2CryptoInfo cryptoInfo, Smb2Role role, Smb2Packet packet, Smb2Packet packetBeforCompression)
        {
            Packet_Header header;

            if (packetBeforCompression is Smb2SinglePacket)
            {
                header = (packetBeforCompression as Smb2SinglePacket).Header;
            }
            else if (packetBeforCompression is Smb2CompoundPacket)
            {
                header = (packetBeforCompression as Smb2CompoundPacket).Packets[0].Header;
            }
            else
            {
                throw new InvalidOperationException("Unsupported SMB2 packet type!");
            }

            // Encrypt all messages after session setup if global encryption enabled.
            // Encrypt all messages after tree connect if global encryption disabled but share encryption enabled.
            if ((cryptoInfo.EnableSessionEncryption ||
                 (cryptoInfo.EnableTreeEncryption.Contains(header.TreeId) &&
                  header.Command != Smb2Command.TREE_CONNECT
                 )
                 )
                )
            {
                byte[]           originalBinary  = packet.ToBytes();
                Transform_Header transformHeader = new Transform_Header
                {
                    ProtocolId          = Smb2Consts.ProtocolIdInTransformHeader,
                    OriginalMessageSize = (uint)originalBinary.Length,
                    SessionId           = sessionId,
                    Signature           = new byte[16]
                };

                if (cryptoInfo.Dialect == DialectRevision.Smb311)
                {
                    transformHeader.Flags = TransformHeaderFlags.Encrypted;
                }
                else
                {
                    transformHeader.EncryptionAlgorithm = EncryptionAlgorithm.ENCRYPTION_AES128_CCM;
                }

                byte[] encrypted = new byte[originalBinary.Length];
                byte[] tag       = new byte[16];
                byte[] key       = role == Smb2Role.Server ? cryptoInfo.ServerOutKey : cryptoInfo.ServerInKey;

                // The reserved field (5 bytes for CCM, 4 bytes for GCM) must be set to zero.
                byte[] nonce = new byte[16];

                if (cryptoInfo.CipherId == EncryptionAlgorithm.ENCRYPTION_AES128_CCM)
                {
                    int nonceLength = Smb2Consts.AES128CCM_Nonce_Length;
                    Buffer.BlockCopy(Guid.NewGuid().ToByteArray(), 0, nonce, 0, nonceLength);
                    transformHeader.Nonce = new Guid(nonce);

                    using (var cipher = new AesCcm(key))
                    {
                        cipher.Encrypt(
                            transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(),
                            originalBinary,
                            encrypted,
                            tag,
                            // Use the fields including and after Nonce field as auth data
                            Smb2Utility.MarshalStructure(transformHeader).Skip(20).ToArray());
                    }
                }
                else if (cryptoInfo.CipherId == EncryptionAlgorithm.ENCRYPTION_AES128_GCM)
                {
                    int nonceLength = Smb2Consts.AES128GCM_Nonce_Length;
                    Buffer.BlockCopy(Guid.NewGuid().ToByteArray(), 0, nonce, 0, nonceLength);
                    transformHeader.Nonce = new Guid(nonce);

                    using (var cipher = new AesGcm(key))
                    {
                        cipher.Encrypt(
                            transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(),
                            originalBinary,
                            encrypted,
                            tag,
                            // Use the fields including and after Nonce field as auth data
                            Smb2Utility.MarshalStructure(transformHeader).Skip(20).ToArray());
                    }
                }
                else
                {
                    throw new InvalidOperationException(String.Format(
                                                            "Invalid encryption algorithm is set in Smb2CryptoInfo when encrypting: {0}", cryptoInfo.CipherId));
                }

                transformHeader.Signature = tag;

                var encryptedPacket = new Smb2EncryptedPacket();
                encryptedPacket.Header       = transformHeader;
                encryptedPacket.EncryptdData = encrypted;

                return(encryptedPacket);
            }

            // Return null if the message is not required to be encrypted.
            return(null);
        }
示例#23
0
        public void Encrypt_returns_correct_value(CcmTestCase tc)
        {
            var ciphertext = AesCcm.Encrypt(tc.Key, tc.Plaintext, tc.Iv, tc.Adata, tc.TagLength);

            Assert.Equal(tc.Ciphertext, ciphertext);
        }