/// <summary>
        /// Reads and decrypts auxiliary channel chunk.
        /// </summary>
        /// <returns>Decrypted chunk.</returns>
        /// <param name="stream">Stream.</param>
        private byte[] ReadAndDecryptChunk(Stream stream)
        {
            var reader = new EndianReader(stream);

            // 0xde, 0xad
            reader.ReadBytes(2);

            var length = reader.ReadUInt16BE();

            var encryptedPayloadLength = length + Padding.CalculatePaddingSize(length, 16);

            var encryptedPayloadBytes    = new byte[encryptedPayloadLength];
            var encryptedPayloadPosition = 0;

            while (encryptedPayloadPosition < encryptedPayloadLength - 1)
            {
                var received = reader.ReadBytes(encryptedPayloadLength - encryptedPayloadPosition);
                received.CopyTo(encryptedPayloadBytes, encryptedPayloadPosition);
                encryptedPayloadPosition += received.Length;
            }

            var signature = reader.ReadBytes(32);

            var bodyWriter = new EndianWriter();

            bodyWriter.Write(new byte[] { 0xde, 0xad });
            bodyWriter.WriteBE(length);
            bodyWriter.Write(encryptedPayloadBytes);

            var messageSignature = _cryptoContext.CalculateMessageSignature(bodyWriter.ToBytes());

            if (!signature.SequenceEqual(messageSignature))
            {
                throw new InvalidDataException("Invalid message signature.");
            }

            var decryptedPayload = _cryptoContext.Decrypt(encryptedPayloadBytes);

            return(decryptedPayload.Take(length).ToArray());
        }