Move out UDP obfuscator to a separate class
This commit is contained in:
parent
6a55ec778b
commit
6e09191bf5
9 changed files with 157 additions and 74 deletions
|
@ -480,6 +480,9 @@ bool UdpSocketBsd::DoRead() {
|
||||||
read_packet->size = r;
|
read_packet->size = r;
|
||||||
read_packet->protocol = kPacketProtocolUdp;
|
read_packet->protocol = kPacketProtocolUdp;
|
||||||
network_->read_packet_ = NULL;
|
network_->read_packet_ = NULL;
|
||||||
|
|
||||||
|
if (processor_->dev().packet_obfuscator().enabled())
|
||||||
|
processor_->dev().packet_obfuscator().DeobfuscatePacket(read_packet);
|
||||||
processor_->HandleUdpPacket(read_packet, network_->overload_);
|
processor_->HandleUdpPacket(read_packet, network_->overload_);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -961,6 +961,13 @@ void PacketProcessorUdpCb::OnQueuedItemDelete(QueuedItem *qi) {
|
||||||
FreePacket(static_cast<Packet*>(qi));
|
FreePacket(static_cast<Packet*>(qi));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PacketProcessorDeobfuscateUdpCb::OnQueuedItemEvent(QueuedItem *qi, uintptr_t extra) {
|
||||||
|
PacketProcessor::QueueContext *context = (PacketProcessor::QueueContext *)extra;
|
||||||
|
Packet *packet = static_cast<Packet*>(qi);
|
||||||
|
context->wg->dev().packet_obfuscator().DeobfuscatePacket(packet);
|
||||||
|
PacketProcessorUdpCb::OnQueuedItemEvent(qi, extra);
|
||||||
|
}
|
||||||
|
|
||||||
void PacketProcessor::PostExit(int exit_code) {
|
void PacketProcessor::PostExit(int exit_code) {
|
||||||
mutex_.Acquire();
|
mutex_.Acquire();
|
||||||
// Avoid race condition where mode_tun_failed is set during thread exit.
|
// Avoid race condition where mode_tun_failed is set during thread exit.
|
||||||
|
|
|
@ -30,6 +30,10 @@ struct PacketProcessorUdpCb : QueuedItemCallback {
|
||||||
virtual void OnQueuedItemDelete(QueuedItem *ow) override;
|
virtual void OnQueuedItemDelete(QueuedItem *ow) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PacketProcessorDeobfuscateUdpCb : PacketProcessorUdpCb {
|
||||||
|
virtual void OnQueuedItemEvent(QueuedItem *ow, uintptr_t extra) override;
|
||||||
|
};
|
||||||
|
|
||||||
class PacketProcessor {
|
class PacketProcessor {
|
||||||
public:
|
public:
|
||||||
explicit PacketProcessor();
|
explicit PacketProcessor();
|
||||||
|
@ -41,11 +45,20 @@ public:
|
||||||
void PostPackets(Packet *first, Packet **end, int count);
|
void PostPackets(Packet *first, Packet **end, int count);
|
||||||
void ForcePost(QueuedItem *item);
|
void ForcePost(QueuedItem *item);
|
||||||
void PostExit(int exit_code);
|
void PostExit(int exit_code);
|
||||||
|
void EnableDeobfuscation() {
|
||||||
|
udp_cb_maybe_deobfuscate_ = &udp_cb_deobfuscate_;
|
||||||
|
}
|
||||||
|
|
||||||
const uint32 *posted_exit_code() { return &exit_code_; }
|
const uint32 *posted_exit_code() { return &exit_code_; }
|
||||||
|
|
||||||
|
// Handler for tun packets
|
||||||
QueuedItemCallback *tun_queue() { return &tun_cb_; }
|
QueuedItemCallback *tun_queue() { return &tun_cb_; }
|
||||||
QueuedItemCallback *udp_queue() { return &udp_cb_; }
|
|
||||||
|
// Handler for udp packets
|
||||||
|
QueuedItemCallback *udp_queue() { return udp_cb_maybe_deobfuscate_; }
|
||||||
|
|
||||||
|
// Incoming queue for tcp packets that do not use deobfuscation
|
||||||
|
QueuedItemCallback *tcp_queue() { return &udp_cb_; }
|
||||||
|
|
||||||
struct QueueContext {
|
struct QueueContext {
|
||||||
WireguardProcessor *wg;
|
WireguardProcessor *wg;
|
||||||
|
@ -65,8 +78,11 @@ private:
|
||||||
uint32 exit_code_;
|
uint32 exit_code_;
|
||||||
bool timer_interrupt_;
|
bool timer_interrupt_;
|
||||||
|
|
||||||
|
QueuedItemCallback *udp_cb_maybe_deobfuscate_;
|
||||||
|
|
||||||
PacketProcessorTunCb tun_cb_;
|
PacketProcessorTunCb tun_cb_;
|
||||||
PacketProcessorUdpCb udp_cb_;
|
PacketProcessorUdpCb udp_cb_;
|
||||||
|
PacketProcessorDeobfuscateUdpCb udp_cb_deobfuscate_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetworkWin32;
|
class NetworkWin32;
|
||||||
|
|
|
@ -773,6 +773,8 @@ void TunsafeBackendBsdImpl::WriteUdpPacket(Packet *packet) {
|
||||||
if (packet->protocol & kPacketProtocolTcp) {
|
if (packet->protocol & kPacketProtocolTcp) {
|
||||||
WriteTcpPacket(packet);
|
WriteTcpPacket(packet);
|
||||||
} else {
|
} else {
|
||||||
|
if (processor_.dev().packet_obfuscator().enabled())
|
||||||
|
processor_.dev().packet_obfuscator().ObfuscatePacket(packet);
|
||||||
udp_.WritePacket(packet);
|
udp_.WritePacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -857,7 +859,6 @@ void TunsafeBackendBsdImpl::CloseOrphanTcpConnections() {
|
||||||
for(const auto &it : lookup)
|
for(const auto &it : lookup)
|
||||||
delete (TcpSocketBsd *)it.second;
|
delete (TcpSocketBsd *)it.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
CommandLineOutput cmd = {0};
|
CommandLineOutput cmd = {0};
|
||||||
|
|
||||||
|
|
|
@ -95,10 +95,6 @@ void WireguardProcessor::SetInternetBlocking(InternetBlockState internet_blockin
|
||||||
internet_blocking_ = internet_blocking;
|
internet_blocking_ = internet_blocking;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WireguardProcessor::SetHeaderObfuscation(const char *key) {
|
|
||||||
dev_.SetHeaderObfuscation(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
const WgProcessorStats &WireguardProcessor::GetStats() {
|
const WgProcessorStats &WireguardProcessor::GetStats() {
|
||||||
// todo: only supports one peer but i want this in the ui for now.
|
// todo: only supports one peer but i want this in the ui for now.
|
||||||
stats_.endpoint.sin.sin_family = 0;
|
stats_.endpoint.sin.sin_family = 0;
|
||||||
|
@ -573,42 +569,10 @@ getout_discard:
|
||||||
return kPacketResult_Free;
|
return kPacketResult_Free;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This scrambles the initial 16 bytes of the packet with the
|
|
||||||
// next 8 bytes of the packet as a seed.
|
|
||||||
static void ScrambleUnscramblePacket(Packet *packet, ScramblerSiphashKeys *keys) {
|
|
||||||
uint8 *data = packet->data;
|
|
||||||
size_t data_size = packet->size;
|
|
||||||
|
|
||||||
if (data_size <= 8)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint64 last_uint64 = ReadLE64(data_size >= 24 ? data + 16 : data + data_size - 8);
|
|
||||||
uint64 a = siphash_u64_u32(last_uint64, (uint32)data_size, (siphash_key_t*)&keys->keys[0]);
|
|
||||||
uint64 b = siphash_u64_u32(last_uint64, (uint32)data_size, (siphash_key_t*)&keys->keys[2]);
|
|
||||||
a = ToLE64(a);
|
|
||||||
b = ToLE64(b);
|
|
||||||
if (data_size >= 24) {
|
|
||||||
((uint64*)data)[0] ^= a;
|
|
||||||
((uint64*)data)[1] ^= b;
|
|
||||||
} else {
|
|
||||||
union {
|
|
||||||
uint64 d[2];
|
|
||||||
uint8 s[16];
|
|
||||||
} scrambler = {{a,b}};
|
|
||||||
for (size_t i = 0; i < data_size - 8; i++)
|
|
||||||
data[i] ^= scrambler.s[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WireguardProcessor::PrepareOutgoingHandshakePacket(WgPeer *peer, Packet *packet) {
|
void WireguardProcessor::PrepareOutgoingHandshakePacket(WgPeer *peer, Packet *packet) {
|
||||||
assert(dev_.IsMainThread());
|
assert(dev_.IsMainThread());
|
||||||
|
|
||||||
stats_.udp_packets_out++;
|
stats_.udp_packets_out++;
|
||||||
stats_.udp_bytes_out += packet->size;
|
stats_.udp_bytes_out += packet->size;
|
||||||
#if WITH_HEADER_OBFUSCATION
|
|
||||||
if (dev_.header_obfuscation_)
|
|
||||||
ScrambleUnscramblePacket(packet, &dev_.header_obfuscation_key_);
|
|
||||||
#endif // WITH_HEADER_OBFUSCATION
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WireguardProcessor::RunAllMainThreadScheduled() {
|
void WireguardProcessor::RunAllMainThreadScheduled() {
|
||||||
|
@ -694,12 +658,6 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleUdpPacket2(Packet *pa
|
||||||
uint32 type;
|
uint32 type;
|
||||||
assert(packet->protocol != 0xCD && (uint16)packet->addr.sin.sin_family != 0xCDCD); // catch msvc uninit mem
|
assert(packet->protocol != 0xCD && (uint16)packet->addr.sin.sin_family != 0xCDCD); // catch msvc uninit mem
|
||||||
|
|
||||||
// Unscramble incoming packets
|
|
||||||
#if WITH_HEADER_OBFUSCATION
|
|
||||||
if (dev_.header_obfuscation_)
|
|
||||||
ScrambleUnscramblePacket(packet, &dev_.header_obfuscation_key_);
|
|
||||||
#endif // WITH_HEADER_OBFUSCATION
|
|
||||||
|
|
||||||
stats_.udp_bytes_in += packet->size;
|
stats_.udp_bytes_in += packet->size;
|
||||||
stats_.udp_packets_in++;
|
stats_.udp_packets_in++;
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,6 @@ public:
|
||||||
void SetAddRoutesMode(bool mode);
|
void SetAddRoutesMode(bool mode);
|
||||||
void SetDnsBlocking(bool dns_blocking);
|
void SetDnsBlocking(bool dns_blocking);
|
||||||
void SetInternetBlocking(InternetBlockState internet_blocking);
|
void SetInternetBlocking(InternetBlockState internet_blocking);
|
||||||
void SetHeaderObfuscation(const char *key);
|
|
||||||
|
|
||||||
void HandleTunPacket(Packet *packet);
|
void HandleTunPacket(Packet *packet);
|
||||||
void HandleUdpPacket(Packet *packet, bool overload);
|
void HandleUdpPacket(Packet *packet, bool overload);
|
||||||
|
|
|
@ -170,7 +170,7 @@ bool WgFileParser::ParseFlag(const char *group, const char *key, char *value) {
|
||||||
|
|
||||||
wg_->SetInternetBlocking((InternetBlockState)v);
|
wg_->SetInternetBlocking((InternetBlockState)v);
|
||||||
} else if (strcmp(key, "HeaderObfuscation") == 0) {
|
} else if (strcmp(key, "HeaderObfuscation") == 0) {
|
||||||
wg_->SetHeaderObfuscation(value);
|
wg_->dev().packet_obfuscator().SetKey((uint8*)value, strlen(value));
|
||||||
} else if (strcmp(key, "PostUp") == 0) {
|
} else if (strcmp(key, "PostUp") == 0) {
|
||||||
wg_->prepost().post_up.emplace_back(value);
|
wg_->prepost().post_up.emplace_back(value);
|
||||||
} else if (strcmp(key, "PostDown") == 0) {
|
} else if (strcmp(key, "PostDown") == 0) {
|
||||||
|
|
|
@ -55,7 +55,6 @@ WgDevice::WgDevice() {
|
||||||
peers_ = NULL;
|
peers_ = NULL;
|
||||||
last_peer_ptr_ = &peers_;
|
last_peer_ptr_ = &peers_;
|
||||||
plugin_ = NULL;
|
plugin_ = NULL;
|
||||||
header_obfuscation_ = false;
|
|
||||||
is_private_key_initialized_ = false;
|
is_private_key_initialized_ = false;
|
||||||
next_rng_slot_ = 0;
|
next_rng_slot_ = 0;
|
||||||
main_thread_scheduled_ = NULL;
|
main_thread_scheduled_ = NULL;
|
||||||
|
@ -331,18 +330,6 @@ void WgDevice::UpdateKeypairAddrEntry_Locked(const IpAddr &addr, WgKeypair *keyp
|
||||||
keypair->broadcast_short_key = 1;
|
keypair->broadcast_short_key = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//>> > hashlib.sha256('TunSafe Header Obfuscation Key').hexdigest()
|
|
||||||
//'2444423e33eb5bb875961224c6441f54c5dea95a3a4e1139509ffa6992bdb278'
|
|
||||||
static const uint8 kHeaderObfuscationKey[32] = {36, 68, 66, 62, 51, 235, 91, 184, 117, 150, 18, 36, 198, 68, 31, 84, 197, 222, 169, 90, 58, 78, 17, 57, 80, 159, 250, 105, 146, 189, 178, 120};
|
|
||||||
|
|
||||||
void WgDevice::SetHeaderObfuscation(const char *key) {
|
|
||||||
#if WITH_HEADER_OBFUSCATION
|
|
||||||
header_obfuscation_ = (key != NULL);
|
|
||||||
if (key)
|
|
||||||
blake2s_hmac((uint8*)&header_obfuscation_key_, sizeof(header_obfuscation_key_), (uint8*)key, strlen(key), kHeaderObfuscationKey, sizeof(kHeaderObfuscationKey));
|
|
||||||
#endif // WITH_HEADER_OBFUSCATION
|
|
||||||
}
|
|
||||||
|
|
||||||
WgPeer::WgPeer(WgDevice *dev) {
|
WgPeer::WgPeer(WgDevice *dev) {
|
||||||
assert(dev->IsMainThread());
|
assert(dev->IsMainThread());
|
||||||
dev_ = dev;
|
dev_ = dev;
|
||||||
|
@ -1056,7 +1043,7 @@ void WgPeer::WriteMacToPacket(const uint8 *data, MessageMacs *dst) {
|
||||||
} else {
|
} else {
|
||||||
has_mac2_cookie_ = false;
|
has_mac2_cookie_ = false;
|
||||||
|
|
||||||
if (dev_->header_obfuscation_) {
|
if (dev_->packet_obfuscator().enabled()) {
|
||||||
// when obfuscation is enabled just make the top bits random
|
// when obfuscation is enabled just make the top bits random
|
||||||
for (size_t i = 0; i < 4; i++)
|
for (size_t i = 0; i < 4; i++)
|
||||||
((uint32*)dst->mac2)[i] = dev_->GetRandomNumber();
|
((uint32*)dst->mac2)[i] = dev_->GetRandomNumber();
|
||||||
|
@ -1482,10 +1469,104 @@ static RandomSiphashKey random_siphash_key;
|
||||||
|
|
||||||
size_t WgAddrEntry::IpPortHasher::operator()(const WgAddrEntry::IpPort &a) const {
|
size_t WgAddrEntry::IpPortHasher::operator()(const WgAddrEntry::IpPort &a) const {
|
||||||
uint32 xx = Read32(a.bytes + 16);
|
uint32 xx = Read32(a.bytes + 16);
|
||||||
return siphash13_2u64(Read64(a.bytes) + xx, Read64(a.bytes + 8) + xx, &random_siphash_key.key);
|
return (size_t)siphash13_2u64(Read64(a.bytes) + xx, Read64(a.bytes + 8) + xx, &random_siphash_key.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t WgPublicKeyHasher::operator()(const WgPublicKey&a) const {
|
size_t WgPublicKeyHasher::operator()(const WgPublicKey&a) const {
|
||||||
return siphash13_4u64(a.u64[0], a.u64[1], a.u64[2], a.u64[3], &random_siphash_key.key);
|
return (size_t)siphash13_4u64(a.u64[0], a.u64[1], a.u64[2], a.u64[3], &random_siphash_key.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This scrambles the initial 16 bytes of the packet with the
|
||||||
|
// last 8 bytes of the packet as a seed.
|
||||||
|
void WgPacketObfuscator::ScrambleUnscramble(uint8 *data, size_t data_size) {
|
||||||
|
uint64 last_uint64 = ReadLE64(data + data_size - 8);
|
||||||
|
uint64 a = siphash_u64_u32(last_uint64, (uint32)data_size, (siphash_key_t*)&key_[0]);
|
||||||
|
uint64 b = siphash_u64_u32(last_uint64, (uint32)data_size, (siphash_key_t*)&key_[2]);
|
||||||
|
a = ToLE64(a);
|
||||||
|
b = ToLE64(b);
|
||||||
|
if (data_size >= 24) {
|
||||||
|
((uint64*)data)[0] ^= a;
|
||||||
|
((uint64*)data)[1] ^= b;
|
||||||
|
} else {
|
||||||
|
uint64 d[2] = { a, b };
|
||||||
|
for (size_t i = 0; i < data_size - 8; i++)
|
||||||
|
data[i] ^= ((uint8*)d)[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t WgPacketObfuscator::InsertRandomBytesIntoPacket(uint8 *data, size_t data_size) {
|
||||||
|
assert(data_size >= 24);
|
||||||
|
// The bytes at offset 16 are used as a seed to the prng
|
||||||
|
uint64 master_key = siphash_u64_u32(Read64(data + 16), (uint32)data_size, &random_siphash_key.key);
|
||||||
|
uint32 random_bytes = master_key & 0xFF;
|
||||||
|
data[3] = (uint8)random_bytes;
|
||||||
|
for (uint32 i = 0; i < random_bytes; i += 8)
|
||||||
|
*(uint64*)(data + data_size + i) = siphash_u64_u32(master_key + i, i, &random_siphash_key.key);
|
||||||
|
data_size += random_bytes;
|
||||||
|
return data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WgPacketObfuscator::ObfuscatePacket(Packet *packet) {
|
||||||
|
uint8 *data = packet->data;
|
||||||
|
size_t data_size = packet->size;
|
||||||
|
|
||||||
|
// Too short packets can't be obfuscated
|
||||||
|
if (data_size < 8)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If the packet is type 1, 2 or 3, or a keepalive packet of type 4, add random bytes at
|
||||||
|
// the end. This is to make it harder to detect the protocol. Store the # of added bytes
|
||||||
|
// in the 3:rd byte of the packet.
|
||||||
|
uint32 packet_type = ReadLE32(data);
|
||||||
|
if ((packet_type == 4 && data_size <= 32) || packet_type < 4) {
|
||||||
|
if (packet_type != 4) {
|
||||||
|
// The 39:th and 43:rd bytes often have zero MSB because of curve25519 pubkey,
|
||||||
|
// so xor them with something in the header.
|
||||||
|
assert(data_size >= 44);
|
||||||
|
data[39] ^= data[12];
|
||||||
|
data[43] ^= data[12];
|
||||||
|
}
|
||||||
|
packet->size = data_size = InsertRandomBytesIntoPacket(data, data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scramble the header bytes of the packet
|
||||||
|
ScrambleUnscramble(data, data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WgPacketObfuscator::DeobfuscatePacket(Packet *packet) {
|
||||||
|
uint8 *data = packet->data;
|
||||||
|
size_t data_size = packet->size;
|
||||||
|
|
||||||
|
// Too short packets can't be obfuscated / deobfuscated
|
||||||
|
if (data_size < 8)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Unscramble the header bytes of the packet
|
||||||
|
ScrambleUnscramble(data, data_size);
|
||||||
|
|
||||||
|
// Check whether the packet type field says that we have
|
||||||
|
// extra bytes appended at the end.
|
||||||
|
if (data[0] <= 4) {
|
||||||
|
if (data[0] < 4 && data_size >= 44) {
|
||||||
|
// The 39:th and 43:rd bytes often have zero MSB because of curve25519 pubkey,
|
||||||
|
// so xor them with something in the header.
|
||||||
|
data[39] ^= data[12];
|
||||||
|
data[43] ^= data[12];
|
||||||
|
}
|
||||||
|
if (data[3] <= data_size) {
|
||||||
|
packet->size = (uint32)(data_size - data[3]);
|
||||||
|
data[3] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//>> > hashlib.sha256('TunSafe Header Obfuscation Key').hexdigest()
|
||||||
|
//'2444423e33eb5bb875961224c6441f54c5dea95a3a4e1139509ffa6992bdb278'
|
||||||
|
static const uint8 kHeaderObfuscationKey[32] = { 36, 68, 66, 62, 51, 235, 91, 184, 117, 150, 18, 36, 198, 68, 31, 84, 197, 222, 169, 90, 58, 78, 17, 57, 80, 159, 250, 105, 146, 189, 178, 120 };
|
||||||
|
|
||||||
|
void WgPacketObfuscator::SetKey(const uint8 *key, size_t len) {
|
||||||
|
enabled_ = (key != NULL);
|
||||||
|
if (key)
|
||||||
|
blake2s((uint8*)&key_, sizeof(key_), key, len, kHeaderObfuscationKey, sizeof(kHeaderObfuscationKey));
|
||||||
|
}
|
||||||
|
|
|
@ -272,10 +272,6 @@ struct WgAddrEntry {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScramblerSiphashKeys {
|
|
||||||
uint64 keys[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
union WgPublicKey {
|
union WgPublicKey {
|
||||||
uint8 bytes[WG_PUBLIC_KEY_LEN];
|
uint8 bytes[WG_PUBLIC_KEY_LEN];
|
||||||
uint64 u64[WG_PUBLIC_KEY_LEN / 8];
|
uint64 u64[WG_PUBLIC_KEY_LEN / 8];
|
||||||
|
@ -341,6 +337,32 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// This class is used for scrambing / unscrambling of wireguard UDP/TCP packets,
|
||||||
|
// including adding random bytes at the end of the non-data packets.
|
||||||
|
class WgPacketObfuscator {
|
||||||
|
public:
|
||||||
|
WgPacketObfuscator() : enabled_(false) {}
|
||||||
|
|
||||||
|
bool enabled() { return enabled_; }
|
||||||
|
void ObfuscatePacket(Packet *packet);
|
||||||
|
void DeobfuscatePacket(Packet *packet);
|
||||||
|
|
||||||
|
void SetKey(const uint8 *key, size_t len);
|
||||||
|
|
||||||
|
const uint8 *key() { return (uint8*)key_; }
|
||||||
|
|
||||||
|
static size_t InsertRandomBytesIntoPacket(uint8 *data, size_t data_size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ScrambleUnscramble(uint8 *data, size_t data_size);
|
||||||
|
|
||||||
|
// Whether packet obfuscation is enabled
|
||||||
|
bool enabled_;
|
||||||
|
|
||||||
|
// Siphash keys for packet scrambling
|
||||||
|
uint64 key_[4];
|
||||||
|
};
|
||||||
|
|
||||||
class WgDevice {
|
class WgDevice {
|
||||||
friend class WgPeer;
|
friend class WgPeer;
|
||||||
friend class WireguardProcessor;
|
friend class WireguardProcessor;
|
||||||
|
@ -359,9 +381,6 @@ public:
|
||||||
// Remove all peers
|
// Remove all peers
|
||||||
void RemoveAllPeers();
|
void RemoveAllPeers();
|
||||||
|
|
||||||
// Setup header obfuscation
|
|
||||||
void SetHeaderObfuscation(const char *key);
|
|
||||||
|
|
||||||
// Check whether Mac1 appears to be valid
|
// Check whether Mac1 appears to be valid
|
||||||
bool CheckCookieMac1(Packet *packet);
|
bool CheckCookieMac1(Packet *packet);
|
||||||
|
|
||||||
|
@ -385,6 +404,8 @@ public:
|
||||||
|
|
||||||
MultithreadedDelayedDelete *GetDelayedDelete() { return &delayed_delete_; }
|
MultithreadedDelayedDelete *GetDelayedDelete() { return &delayed_delete_; }
|
||||||
|
|
||||||
|
WgPacketObfuscator &packet_obfuscator() { return packet_obfuscator_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<WgPeer*, WgKeypair*> *LookupPeerInKeyIdLookup(uint32 key_id);
|
std::pair<WgPeer*, WgKeypair*> *LookupPeerInKeyIdLookup(uint32 key_id);
|
||||||
WgKeypair *LookupKeypairByKeyId(uint32 key_id);
|
WgKeypair *LookupKeypairByKeyId(uint32 key_id);
|
||||||
|
@ -441,9 +462,6 @@ private:
|
||||||
// Counter for generating new indices in |keypair_lookup_|
|
// Counter for generating new indices in |keypair_lookup_|
|
||||||
uint8 next_rng_slot_;
|
uint8 next_rng_slot_;
|
||||||
|
|
||||||
// Whether packet obfuscation is enabled
|
|
||||||
bool header_obfuscation_;
|
|
||||||
|
|
||||||
// Whether a private key has been setup for the device
|
// Whether a private key has been setup for the device
|
||||||
bool is_private_key_initialized_;
|
bool is_private_key_initialized_;
|
||||||
|
|
||||||
|
@ -456,8 +474,6 @@ private:
|
||||||
uint8 s_priv_[WG_PUBLIC_KEY_LEN];
|
uint8 s_priv_[WG_PUBLIC_KEY_LEN];
|
||||||
uint8 s_pub_[WG_PUBLIC_KEY_LEN];
|
uint8 s_pub_[WG_PUBLIC_KEY_LEN];
|
||||||
|
|
||||||
// Siphash keys for packet scrambling
|
|
||||||
ScramblerSiphashKeys header_obfuscation_key_;
|
|
||||||
|
|
||||||
uint8 precomputed_cookie_key_[WG_SYMMETRIC_KEY_LEN];
|
uint8 precomputed_cookie_key_[WG_SYMMETRIC_KEY_LEN];
|
||||||
uint8 precomputed_mac1_key_[WG_SYMMETRIC_KEY_LEN];
|
uint8 precomputed_mac1_key_[WG_SYMMETRIC_KEY_LEN];
|
||||||
|
@ -465,6 +481,8 @@ private:
|
||||||
uint64 random_number_input_[WG_HASH_LEN / 8 + 1];
|
uint64 random_number_input_[WG_HASH_LEN / 8 + 1];
|
||||||
uint32 random_number_output_[WG_HASH_LEN / 4];
|
uint32 random_number_output_[WG_HASH_LEN / 4];
|
||||||
|
|
||||||
|
WgPacketObfuscator packet_obfuscator_;
|
||||||
|
|
||||||
WgRateLimit rate_limiter_;
|
WgRateLimit rate_limiter_;
|
||||||
|
|
||||||
// For defering deletes until all worker threads are guaranteed not to use an object.
|
// For defering deletes until all worker threads are guaranteed not to use an object.
|
||||||
|
|
Loading…
Reference in a new issue