static byte[] DecryptCCM(byte[] cipherText, byte[] key, byte[] nonce, byte[] tag, byte[] associatedData = null) { var decryptedData = new byte[cipherText.Length]; using var gcm = new AesCcm(key); gcm.Decrypt(nonce, cipherText, tag, decryptedData, associatedData); return(decryptedData); }
// // Helpers // private static void VerifyCcmMismatchThrown(byte[] key, byte[] ciphertext, byte[] iv, byte[] adata, int tagLength) { Exceptions.AssertThrowsInternalError(() => AesCcm.Decrypt(key, ciphertext, iv, adata, tagLength), "CCM tag doesn't match"); }
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 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 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 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 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 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)); } }
public static byte[] Decrypt(byte[] bytes, Dictionary <ulong, Smb2CryptoInfo> cryptoInfoTable, Smb2Role role, out Transform_Header transformHeader) { var encryptedPacket = new Smb2EncryptedPacket(); int consumedLen; int expectedLen; encryptedPacket.FromBytes(bytes, out consumedLen, out expectedLen); transformHeader = encryptedPacket.Header; // For client: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the client MUST discard the message. // For server: If the Flags/EncryptionAlgorithm in the SMB2 TRANSFORM_HEADER is not 0x0001, the server MUST disconnect the connection. if (transformHeader.Flags != TransformHeaderFlags.Encrypted) { throw new InvalidOperationException( String.Format( "Flags/EncryptionAlgorithm field is invalid for encrypted message. Expected value 0x0001, actual {0}.", (ushort)transformHeader.Flags ) ); } if (transformHeader.SessionId == 0 || !cryptoInfoTable.ContainsKey(transformHeader.SessionId)) { throw new InvalidOperationException("Invalid SessionId in TRANSFORM_HEADER."); } Smb2CryptoInfo cryptoInfo = cryptoInfoTable[transformHeader.SessionId]; byte[] decrypted = new byte[encryptedPacket.EncryptdData.Length]; byte[] key = role == Smb2Role.Server ? cryptoInfo.ServerInKey : cryptoInfo.ServerOutKey; // Auth data is Transform_Header start from Nonce, excluding ProtocolId and Signature. var authData = Smb2Utility.MarshalStructure(transformHeader).Skip((int)Marshal.OffsetOf <Transform_Header>("Nonce")).ToArray(); if (cryptoInfo.CipherId == EncryptionAlgorithm.ENCRYPTION_AES128_CCM) { int nonceLength = Smb2Consts.AES128CCM_Nonce_Length; using (var cipher = new AesCcm(key)) { cipher.Decrypt( transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), encryptedPacket.EncryptdData, transformHeader.Signature, decrypted, authData); } } else if (cryptoInfo.CipherId == EncryptionAlgorithm.ENCRYPTION_AES128_GCM) { int nonceLength = Smb2Consts.AES128GCM_Nonce_Length; using (var cipher = new AesGcm(key)) { cipher.Decrypt( transformHeader.Nonce.ToByteArray().Take(nonceLength).ToArray(), encryptedPacket.EncryptdData, transformHeader.Signature, decrypted, authData); } } else { throw new InvalidOperationException(String.Format( "Invalid encryption algorithm is set in Smb2CryptoInfo when decrypting: {0}", cryptoInfo.CipherId)); } return(decrypted); }
public void Decrypt_returns_correct_value(CcmTestCase tc) { var plaintext = AesCcm.Decrypt(tc.Key, tc.Ciphertext, tc.Iv, tc.Adata, tc.TagLength); Assert.Equal(tc.Plaintext, plaintext); }