From cb4f400c7ee567b505daf320d80f0529ef78c037 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 22 Feb 2016 15:15:15 -0800 Subject: [PATCH] Cleanup obfuscation code --- libraries/networking/src/udt/Packet.cpp | 53 ++++++++++++++++----- libraries/networking/src/udt/Packet.h | 5 +- libraries/networking/src/udt/SaltShaker.cpp | 52 -------------------- libraries/networking/src/udt/SaltShaker.h | 27 ----------- libraries/networking/src/udt/SendQueue.cpp | 19 ++++---- 5 files changed, 55 insertions(+), 101 deletions(-) delete mode 100644 libraries/networking/src/udt/SaltShaker.cpp delete mode 100644 libraries/networking/src/udt/SaltShaker.h diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index b06f7ba847..f6bff06173 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -11,14 +11,35 @@ #include "Packet.h" -#include +#include -#include "SaltShaker.h" +#include using namespace udt; static int packetMetaTypeId = qRegisterMetaType("Packet*"); +using Key = uint64_t; +static const std::array KEYS {{ + 0x0, + 0x6362726973736574, + 0x7362697261726461, + 0x72687566666d616e, +}}; + +void xorHelper(char* start, int size, Key key) { + const auto end = start + size; + + auto p = start; + for (; p + sizeof(Key) < end; p += sizeof(Key)) { + *reinterpret_cast(p) ^= key; + } + + for (int i = 0; p < end; ++p || ++i) { + *p ^= *(reinterpret_cast(&key) + i); + } +} + int Packet::localHeaderSize(bool isPartOfMessage) { return sizeof(Packet::SequenceNumberAndBitField) + (isPartOfMessage ? sizeof(Packet::MessageNumberAndBitField) + sizeof(MessagePartNumber) : 0); @@ -72,11 +93,9 @@ Packet::Packet(std::unique_ptr data, qint64 size, const HifiSockAddr& se { readHeader(); - if (getObfuscationLevel() != Packet::NoObfuscation) { - SaltShaker shaker; - shaker.unsalt(*this, getObfuscationLevel()); - readHeader(); // read packet header again as some of the data was obfuscated + adjustPayloadStartAndCapacity(Packet::localHeaderSize(_isPartOfMessage), _payloadSize > 0); + if (getObfuscationLevel() != Packet::NoObfuscation) { QString debugString = "Unobfuscating packet %1 with level %2"; debugString = debugString.arg(QString::number((uint32_t)getSequenceNumber()), QString::number(getObfuscationLevel())); @@ -90,9 +109,9 @@ Packet::Packet(std::unique_ptr data, qint64 size, const HifiSockAddr& se static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("^Unobfuscating packet .{0,1000}"); qDebug() << qPrintable(debugString); - } - adjustPayloadStartAndCapacity(Packet::localHeaderSize(_isPartOfMessage), _payloadSize > 0); + obfuscate(NoObfuscation); // Undo obfuscation + } } Packet::Packet(const Packet& other) : BasePacket(other) { @@ -119,7 +138,7 @@ Packet& Packet::operator=(Packet&& other) { return *this; } -void Packet::writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePartNumber messagePartNumber) { +void Packet::writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePartNumber messagePartNumber) const { _isPartOfMessage = true; _messageNumber = messageNumber; _packetPosition = position; @@ -127,12 +146,23 @@ void Packet::writeMessageNumber(MessageNumber messageNumber, PacketPosition posi writeHeader(); } -void Packet::writeSequenceNumber(SequenceNumber sequenceNumber, ObfuscationLevel level) const { +void Packet::writeSequenceNumber(SequenceNumber sequenceNumber) const { _sequenceNumber = sequenceNumber; - _obfuscationLevel = level; writeHeader(); } +void Packet::obfuscate(ObfuscationLevel level) { + auto obfuscationKey = KEYS[getObfuscationLevel()] ^ KEYS[level]; // Undo old and apply new one. + if (obfuscationKey != 0) { + xorHelper(getData() + localHeaderSize(isPartOfMessage()), + getDataSize() - localHeaderSize(isPartOfMessage()), obfuscationKey); + + // Update members and header + _obfuscationLevel = level; + writeHeader(); + } +} + void Packet::copyMembers(const Packet& other) { _isReliable = other._isReliable; _isPartOfMessage = other._isPartOfMessage; @@ -155,6 +185,7 @@ void Packet::readHeader() const { if (_isPartOfMessage) { MessageNumberAndBitField* messageNumberAndBitField = seqNumBitField + 1; + _messageNumber = *messageNumberAndBitField & MESSAGE_NUMBER_MASK; _packetPosition = static_cast(*messageNumberAndBitField >> PACKET_POSITION_OFFSET); diff --git a/libraries/networking/src/udt/Packet.h b/libraries/networking/src/udt/Packet.h index bfd1b9a3cd..c0da3a0781 100644 --- a/libraries/networking/src/udt/Packet.h +++ b/libraries/networking/src/udt/Packet.h @@ -90,8 +90,9 @@ public: PacketPosition getPacketPosition() const { return _packetPosition; } MessagePartNumber getMessagePartNumber() const { return _messagePartNumber; } - void writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePartNumber messagePartNumber); - void writeSequenceNumber(SequenceNumber sequenceNumber, ObfuscationLevel level = NoObfuscation) const; + void writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePartNumber messagePartNumber) const; + void writeSequenceNumber(SequenceNumber sequenceNumber) const; + void obfuscate(ObfuscationLevel level); protected: Packet(qint64 size, bool isReliable = false, bool isPartOfMessage = false); diff --git a/libraries/networking/src/udt/SaltShaker.cpp b/libraries/networking/src/udt/SaltShaker.cpp deleted file mode 100644 index 4febaa789a..0000000000 --- a/libraries/networking/src/udt/SaltShaker.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// SaltShaker.cpp -// libraries/networking/src/udt -// -// Created by Clement on 2/18/16. -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "SaltShaker.h" - -#include - -using namespace udt; - -using Key = uint64_t; -static const std::array KEYS {{ - 0x0, - 0xd6ea42f07644016a, - 0x700f7e3414dc4d8c, - 0x54c92e8d2c871642 -}}; - -void saltingHelper(char* start, int size, Key key) { - const auto end = start + size; - - auto p = start; - for (; p + sizeof(Key) < end; p += sizeof(Key)) { - *reinterpret_cast(p) ^= key; - } - - for (int i = 0; p < end; ++p || ++i) { - *p ^= *(reinterpret_cast(&key) + i); - } -} - -std::unique_ptr SaltShaker::salt(const Packet& packet, unsigned int saltiness) { - Q_ASSERT_X(saltiness < KEYS.size(), Q_FUNC_INFO, ""); - - auto copy = Packet::createCopy(packet); - copy->writeSequenceNumber(copy->getSequenceNumber(), (Packet::ObfuscationLevel)saltiness); - saltingHelper(copy->getData() + 4, copy->getDataSize() - 4, KEYS[saltiness]); - return copy; -} - -void SaltShaker::unsalt(Packet& packet, unsigned int saltiness) { - Q_ASSERT_X(saltiness < KEYS.size(), Q_FUNC_INFO, ""); - - saltingHelper(packet.getData() + 4, packet.getDataSize() - 4, KEYS[saltiness]); -} \ No newline at end of file diff --git a/libraries/networking/src/udt/SaltShaker.h b/libraries/networking/src/udt/SaltShaker.h deleted file mode 100644 index 4cdf5fdbe3..0000000000 --- a/libraries/networking/src/udt/SaltShaker.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// SaltShaker.h -// libraries/networking/src/udt -// -// Created by Clement on 2/18/16. -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_SaltShaker_h -#define hifi_SaltShaker_h - -#include "Packet.h" - -namespace udt { - -class SaltShaker { -public: - std::unique_ptr salt(const Packet& packet, unsigned int saltiness); - void unsalt(Packet& packet, unsigned int saltiness); -}; - -} - -#endif // hifi_SaltShaker_h \ No newline at end of file diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index da3727b214..d3051377d3 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -18,13 +18,13 @@ #include #include +#include #include #include "../NetworkLogging.h" #include "ControlPacket.h" #include "Packet.h" #include "PacketList.h" -#include "SaltShaker.h" #include "Socket.h" using namespace udt; @@ -338,8 +338,6 @@ bool SendQueue::maybeSendNewPacket() { return false; } -#include - bool SendQueue::maybeResendPacket() { // the following while makes sure that we find a packet to re-send, if there is one @@ -364,13 +362,12 @@ bool SendQueue::maybeResendPacket() { auto& resendPacket = *(entry.second); ++entry.first; // Add 1 resend - auto saltiness = entry.first < 2 ? 0 : (entry.first - 2) % 4; + Packet::ObfuscationLevel level = (Packet::ObfuscationLevel)(entry.first < 2 ? 0 : (entry.first - 2) % 4); - if (saltiness != 0) { + if (level != Packet::NoObfuscation) { QString debugString = "Obfuscating packet %1 with level %2"; debugString = debugString.arg(QString::number((uint32_t)resendPacket.getSequenceNumber()), - QString::number(saltiness)); - + QString::number(level)); if (resendPacket.isPartOfMessage()) { debugString += "\n"; debugString += " Message Number: %1, Part Number: %2."; @@ -382,12 +379,16 @@ bool SendQueue::maybeResendPacket() { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("^Obfuscating packet .{0,1000}"); qCritical() << qPrintable(debugString); - SaltShaker shaker; - auto packet = shaker.salt(resendPacket, saltiness); + + // Create copy of the packet + auto packet = Packet::createCopy(resendPacket); // unlock the sent packets sentLocker.unlock(); + // Obfuscate packet + packet->obfuscate(level); + // send it off sendPacket(*packet); } else {