Exemple #1
0
        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);
        }
Exemple #2
0
        //
        // 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");
        }
Exemple #3
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);
            }
        }
Exemple #4
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));
            }
        }
Exemple #5
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));
            }
        }
Exemple #6
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);
            }
        }
Exemple #7
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);
            }
        }
Exemple #8
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);
            }
        }
Exemple #9
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);
            }
        }
Exemple #10
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);
            }
        }
Exemple #11
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));
            }
        }
        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);
        }
Exemple #13
0
        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);
        }