private static void ApplyCipher(Span <byte> packetData, byte[] cipher, bool encrypt) { if (cipher.Length != RequiredLength) { throw new ArgumentException($"The cipher size must be {RequiredLength}, but is {cipher.Length}", nameof(cipher)); } var packet = new PacketView(packetData); if (packet.IsPartial) { throw new ArgumentException("Refusing to apply XOR cipher to partial packet", nameof(packet)); } if (packet.Type.IsEncrypted) { throw new ArgumentException("Refusing to apply XOR cipher to encrypted packet", nameof(packet)); } int start = encrypt ? packet.Type.HeaderLength + 1 : packet.Length - 1; int end = encrypt ? packet.Length : packet.Type.HeaderLength; for (int i = start; i != end; i += encrypt ? 1 : -1) { packetData[i] ^= (byte)(packet.Data[i - 1] ^ cipher[i % cipher.Length]); } }
/// <summary>Throws an exception if the packet header does not match.</summary> public void EnsureMatchingHeader(Span <byte> data, int minimumPayloadSize) { var packet = new PacketView(data); if (!packet.HasIdentifier(this.Identifier)) { // TODO: Specialized exception throw new ArgumentException(nameof(data)); } if (packet.Length < this.PayloadOffset + minimumPayloadSize) { // TODO: Specialized exception throw new ArgumentOutOfRangeException(nameof(data)); } if (packet.Length != this.Type.ReadSize(data)) { // TODO: Specialized exception throw new ArgumentException(nameof(data)); } }