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)); }
// 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)); }
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); }
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); } }
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"); }
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"); }
/// <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); }
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)); } }
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); } }
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); } }
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); } }
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)); } }
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); } }
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)); } }
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); } }
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); } }
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)); }
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); } }
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); } }
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); } }
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); }
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); }