private void FakeEncrypt(OutgoingPacket packet, byte[] mac) { packet.BuildHeader(); packet.Raw = new byte[packet.Data.Length + MacLen + OutHeaderLen]; // Copy the Mac from [Mac...] to [Mac..., Header..., Data...] Array.Copy(mac, 0, packet.Raw, 0, MacLen); // Copy the Header from packet.Header to [Mac..., Header..., Data...] Array.Copy(packet.Header, 0, packet.Raw, MacLen, OutHeaderLen); // Copy the Data from packet.Data to [Mac..., Header..., Data...] Array.Copy(packet.Data, 0, packet.Raw, MacLen + OutHeaderLen, packet.Data.Length); // Raw is now [Mac..., Header..., Data...] }
internal void Encrypt(OutgoingPacket packet) { if (packet.PacketType == PacketType.Init1) { FakeEncrypt(packet, TS3InitMac); return; } if (packet.UnencryptedFlag) { FakeEncrypt(packet, fakeSignature); return; } var keyNonce = GetKeyNonce(false, packet.PacketId, packet.GenerationId, packet.PacketType); packet.BuildHeader(); ICipherParameters ivAndKey = new AeadParameters(new KeyParameter(keyNonce.Item1), 8 * MacLen, keyNonce.Item2, packet.Header); byte[] result; int len; lock (eaxCipher) { eaxCipher.Init(true, ivAndKey); result = new byte[eaxCipher.GetOutputSize(packet.Size)]; try { len = eaxCipher.ProcessBytes(packet.Data, 0, packet.Size, result, 0); len += eaxCipher.DoFinal(result, len); } catch (Exception ex) { throw new Ts3Exception("Internal encryption error.", ex); } } // result consists of [Data..., Mac...] // to build the final TS3/libtomcrypt we need to copy it into another order // len is Data.Length + Mac.Length packet.Raw = new byte[OutHeaderLen + len]; // Copy the Mac from [Data..., Mac...] to [Mac..., Header..., Data...] Array.Copy(result, len - MacLen, packet.Raw, 0, MacLen); // Copy the Header from packet.Header to [Mac..., Header..., Data...] Array.Copy(packet.Header, 0, packet.Raw, MacLen, OutHeaderLen); // Copy the Data from [Data..., Mac...] to [Mac..., Header..., Data...] Array.Copy(result, 0, packet.Raw, MacLen + OutHeaderLen, len - MacLen); // Raw is now [Mac..., Header..., Data...] }