Cleanup obfuscation code

This commit is contained in:
Atlante45 2016-02-22 15:15:15 -08:00
parent 17b4d6fcf9
commit cb4f400c7e
5 changed files with 55 additions and 101 deletions

View file

@ -11,14 +11,35 @@
#include "Packet.h"
#include <LogHandler.h>
#include <array>
#include "SaltShaker.h"
#include <LogHandler.h>
using namespace udt;
static int packetMetaTypeId = qRegisterMetaType<Packet*>("Packet*");
using Key = uint64_t;
static const std::array<Key, 4> 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<Key*>(p) ^= key;
}
for (int i = 0; p < end; ++p || ++i) {
*p ^= *(reinterpret_cast<const char*>(&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<char[]> 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<char[]> 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<PacketPosition>(*messageNumberAndBitField >> PACKET_POSITION_OFFSET);

View file

@ -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);

View file

@ -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 <array>
using namespace udt;
using Key = uint64_t;
static const std::array<Key, 4> 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<Key*>(p) ^= key;
}
for (int i = 0; p < end; ++p || ++i) {
*p ^= *(reinterpret_cast<const char*>(&key) + i);
}
}
std::unique_ptr<Packet> 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]);
}

View file

@ -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<Packet> salt(const Packet& packet, unsigned int saltiness);
void unsalt(Packet& packet, unsigned int saltiness);
};
}
#endif // hifi_SaltShaker_h

View file

@ -18,13 +18,13 @@
#include <QtCore/QDateTime>
#include <QtCore/QThread>
#include <LogHandler.h>
#include <SharedUtil.h>
#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 <LogHandler.h>
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 {