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