Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SoftEtherVPN/SoftEtherVPN_Stable.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cedar/UdpAccel.c')
-rw-r--r--src/Cedar/UdpAccel.c320
1 files changed, 219 insertions, 101 deletions
diff --git a/src/Cedar/UdpAccel.c b/src/Cedar/UdpAccel.c
index a9597bf7..dc9b0c33 100644
--- a/src/Cedar/UdpAccel.c
+++ b/src/Cedar/UdpAccel.c
@@ -350,7 +350,7 @@ void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b)
return;
}
- UdpAccelSend(a, b->Buf, b->Size, b->Compressed, a->MaxUdpPacketSize, b->PriorityQoS);
+ UdpAccelSend(a, b->Buf, b->Size, b->Compressed ? 1 : 0, a->MaxUdpPacketSize, b->PriorityQoS);
}
// Calculate the best MSS
@@ -382,7 +382,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
if (a->PlainTextMode == false)
{
// IV
- ret -= UDP_ACCELERATION_PACKET_IV_SIZE;
+ ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
}
// Cookie
@@ -403,7 +403,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
if (a->PlainTextMode == false)
{
// Verify
- ret -= UDP_ACCELERATION_PACKET_IV_SIZE;
+ ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
}
// Ethernet header (communication packets)
@@ -419,12 +419,12 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
}
// Send
-void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UINT max_size, bool high_priority)
+void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT max_size, bool high_priority)
{
UCHAR tmp[UDP_ACCELERATION_TMP_BUF_SIZE];
UCHAR *buf;
UINT size;
- UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE];
+ UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
UINT64 ui64;
USHORT us;
UCHAR c;
@@ -448,27 +448,40 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
// IV
if (a->PlainTextMode == false)
{
- // IV
- Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE);
+ if (a->Version == 2)
+ {
+ // Version 2.0
+ // IV
+ Copy(buf, a->NextIv_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
+
+ buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
+ size += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
+ }
+ else
+ {
+ // Version 1.0
+ // IV
+ Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
- buf += UDP_ACCELERATION_PACKET_IV_SIZE;
- size += UDP_ACCELERATION_PACKET_IV_SIZE;
+ buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
+ size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
- // Calculate the key
- UdpAccelCalcKey(key, a->MyKey, a->NextIv);
+ // Calculate the key
+ UdpAccelCalcKey(key, a->MyKey, a->NextIv);
- if (false)
- {
- char tmp1[256];
- char tmp2[256];
- char tmp3[256];
- BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey));
- BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE);
- BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
- Debug("My Key : %s\n"
- "IV : %s\n"
- "Comm Key: %s\n",
- tmp1, tmp2, tmp3);
+ if (false)
+ {
+ char tmp1[256];
+ char tmp2[256];
+ char tmp3[256];
+ BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey));
+ BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
+ BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
+ Debug("My Key : %s\n"
+ "IV : %s\n"
+ "Comm Key: %s\n",
+ tmp1, tmp2, tmp3);
+ }
}
}
@@ -496,8 +509,8 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
buf += sizeof(USHORT);
size += sizeof(USHORT);
- // Compress Flag
- c = (compressed ? 1 : 0);
+ // Flag
+ c = flag;
Copy(buf, &c, sizeof(UCHAR));
buf += sizeof(UCHAR);
size += sizeof(UCHAR);
@@ -512,37 +525,74 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
if (a->PlainTextMode == false)
{
- static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE] = {0};
- CRYPT *c;
-
- current_size = UDP_ACCELERATION_PACKET_IV_SIZE + sizeof(UINT) + sizeof(UINT64) * 2 +
- sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_IV_SIZE;
-
- if (current_size < max_size)
+ if (a->Version == 2)
{
+ // Ver 2
// Padding
- UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE];
- UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE);
- pad_size = rand() % pad_size;
+ current_size = UDP_ACCELERATION_PACKET_IV_SIZE_V2 + sizeof(UINT) + sizeof(UINT64) * 2 +
+ sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
- Zero(pad, sizeof(pad));
- Copy(buf, pad, pad_size);
- buf += pad_size;
- size += pad_size;
+ if (current_size < max_size)
+ {
+ UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE];
+ UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE);
+ pad_size = rand() % pad_size;
+ Zero(pad, sizeof(pad));
+ Copy(buf, pad, pad_size);
+ buf += pad_size;
+ size += pad_size;
+ }
+
+ // Encryption by RFC 8439: ChaCha20-Poly1305-IETF Encryption with AEAD
+ Aead_ChaCha20Poly1305_Ietf_Encrypt(tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2,
+ tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2,
+ size - UDP_ACCELERATION_PACKET_IV_SIZE_V2,
+ a->MyKey_V2,
+ a->NextIv_V2,
+ NULL, 0);
+
+ // Next Iv
+ Copy(a->NextIv_V2,
+ tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2 + size - UDP_ACCELERATION_PACKET_IV_SIZE_V2 - UDP_ACCELERATION_PACKET_IV_SIZE_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
+
+ // MAC
+ size += UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
}
+ else
+ {
+ // Ver 1
+ static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE_V1] = {0};
+ CRYPT *c;
- // Verify
- Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE);
- buf += UDP_ACCELERATION_PACKET_IV_SIZE;
- size += UDP_ACCELERATION_PACKET_IV_SIZE;
+ current_size = UDP_ACCELERATION_PACKET_IV_SIZE_V1 + sizeof(UINT) + sizeof(UINT64) * 2 +
+ sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_IV_SIZE_V1;
+
+ if (current_size < max_size)
+ {
+ // Padding
+ UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE];
+ UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE);
+ pad_size = rand() % pad_size;
+
+ Zero(pad, sizeof(pad));
+ Copy(buf, pad, pad_size);
+ buf += pad_size;
+ size += pad_size;
+ }
+
+ // Verify
+ Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
+ buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
+ size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
- // Encryption
- c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE);
- Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, size - UDP_ACCELERATION_PACKET_IV_SIZE);
- FreeCrypt(c);
+ // Encryption
+ c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1);
+ Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V1, tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V1, size - UDP_ACCELERATION_PACKET_IV_SIZE_V1);
+ FreeCrypt(c);
- // Next Iv
- Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE, UDP_ACCELERATION_PACKET_IV_SIZE);
+ // Next Iv
+ Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE_V1, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
+ }
}
// Send
@@ -667,7 +717,7 @@ bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive)
// Process the received packet
BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port)
{
- UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE];
+ UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
UCHAR *iv;
CRYPT *c;
UINT64 my_tick, your_tick;
@@ -676,6 +726,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
UINT pad_size;
UCHAR *verify;
bool compress_flag;
+ UCHAR raw_flag;
BLOCK *b = NULL;
UINT cookie;
// Validate arguments
@@ -686,36 +737,66 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (a->PlainTextMode == false)
{
- // IV
- if (size < UDP_ACCELERATION_PACKET_IV_SIZE)
+ if (a->Version == 2)
{
- return NULL;
- }
- iv = buf;
- buf += UDP_ACCELERATION_PACKET_IV_SIZE;
- size -= UDP_ACCELERATION_PACKET_IV_SIZE;
+ // Version 2.0
+ // IV
+ if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V2)
+ {
+ return NULL;
+ }
+ iv = buf;
+ buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
+ size -= UDP_ACCELERATION_PACKET_IV_SIZE_V2;
- // Calculate the key
- UdpAccelCalcKey(key, a->YourKey, iv);
+ if (size < AEAD_CHACHA20_POLY1305_MAC_SIZE)
+ {
+ return NULL;
+ }
- if (false)
- {
- char tmp1[256];
- char tmp2[256];
- char tmp3[256];
- BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey));
- BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE);
- BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
- Debug("Your Key: %s\n"
- "IV : %s\n"
- "Comm Key: %s\n",
- tmp1, tmp2, tmp3);
+ // Decryption by RFC 8439: ChaCha20-Poly1305-IETF Encryption with AEAD
+ if (Aead_ChaCha20Poly1305_Ietf_Decrypt(buf, buf, size, a->YourKey_V2,
+ iv, NULL, 0) == false)
+ {
+ return NULL;
+ }
+
+ size -= AEAD_CHACHA20_POLY1305_MAC_SIZE;
}
+ else
+ {
+ // Version 1.0
+ // IV
+ if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
+ {
+ return NULL;
+ }
+ iv = buf;
+ buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
+ size -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
+
+ // Calculate the key
+ UdpAccelCalcKey(key, a->YourKey, iv);
+
+ if (false)
+ {
+ char tmp1[256];
+ char tmp2[256];
+ char tmp3[256];
+ BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey));
+ BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
+ BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
+ Debug("Your Key: %s\n"
+ "IV : %s\n"
+ "Comm Key: %s\n",
+ tmp1, tmp2, tmp3);
+ }
- // Decryption
- c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE);
- Encrypt(c, buf, buf, size);
- FreeCrypt(c);
+ // Decryption
+ c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1);
+ Encrypt(c, buf, buf, size);
+ FreeCrypt(c);
+ }
}
// Cookie
@@ -759,12 +840,20 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
buf += sizeof(USHORT);
size -= sizeof(USHORT);
- // compress_flag
+ // flag
if (size < sizeof(UCHAR))
{
return NULL;
}
- compress_flag = *((UCHAR *)buf);
+ if (a->ReadRawFlagMode == false)
+ {
+ compress_flag = *((UCHAR *)buf);
+ }
+ else
+ {
+ raw_flag = *((UCHAR *)buf);
+ }
+
buf += sizeof(UCHAR);
size -= sizeof(UCHAR);
@@ -783,26 +872,29 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (a->PlainTextMode == false)
{
- // padding
- if (size < UDP_ACCELERATION_PACKET_IV_SIZE)
+ if (a->Version == 1)
{
- return false;
- }
- pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE;
- buf += pad_size;
- size -= pad_size;
+ // padding
+ if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
+ {
+ return false;
+ }
+ pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V1;
+ buf += pad_size;
+ size -= pad_size;
- // verify
- if (size != UDP_ACCELERATION_PACKET_IV_SIZE)
- {
- return NULL;
- }
+ // verify
+ if (size != UDP_ACCELERATION_PACKET_IV_SIZE_V1)
+ {
+ return NULL;
+ }
- verify = buf;
+ verify = buf;
- if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE) == false)
- {
- return NULL;
+ if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE_V1) == false)
+ {
+ return NULL;
+ }
}
}
@@ -819,7 +911,11 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (inner_size >= 1)
{
- b = NewBlock(Clone(inner_data, inner_size), inner_size, compress_flag ? -1 : 0);
+ b = NewBlock(Clone(inner_data, inner_size), inner_size, a->ReadRawFlagMode == false ? (compress_flag ? -1 : 0) : 0);
+ if (a->ReadRawFlagMode)
+ {
+ b->RawFlagRetUdpAccel = raw_flag;
+ }
}
if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick)
@@ -851,15 +947,15 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
// Calculate the key
void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv)
{
- UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE + UDP_ACCELERATION_PACKET_IV_SIZE];
+ UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE_V1 + UDP_ACCELERATION_PACKET_IV_SIZE_V1];
// Validate arguments
if (key == NULL || common_key == NULL || iv == NULL)
{
return;
}
- Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE);
- Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE, iv, UDP_ACCELERATION_PACKET_IV_SIZE);
+ Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
+ Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE_V1, iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
HashSha1(key, tmp, sizeof(tmp));
}
@@ -887,7 +983,9 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
}
IPToStr(tmp, sizeof(tmp), client_ip);
- Debug("UdpAccelInitServer: client_ip=%s, client_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, client_port,
+ Debug("UdpAccelInitServer: ver=%u, client_ip=%s, client_port=%u, server_cookie=%u, client_cookie=%u\n",
+ a->Version,
+ tmp, client_port,
a->MyCookie, a->YourCookie);
if (IsIP6(client_ip) != a->IsIPv6)
@@ -895,7 +993,14 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
return false;
}
- Copy(a->YourKey, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE);
+ if (a->Version == 2)
+ {
+ Copy(a->YourKey_V2, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
+ }
+ else
+ {
+ Copy(a->YourKey, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
+ }
Copy(&a->YourIp, client_ip, sizeof(IP));
Copy(&a->YourIp2, client_ip_2, sizeof(IP));
@@ -919,14 +1024,22 @@ bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *server_key, IP *server_ip, UINT ser
}
IPToStr(tmp, sizeof(tmp), server_ip);
- Debug("UdpAccelInitClient: server_ip=%s, server_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, server_port, server_cookie, client_cookie);
+ Debug("UdpAccelInitClient: ver = %u, server_ip=%s, server_port=%u, server_cookie=%u, client_cookie=%u\n",
+ a->Version, tmp, server_port, server_cookie, client_cookie);
if (IsIP6(server_ip) != a->IsIPv6)
{
return false;
}
- Copy(a->YourKey, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE);
+ if (a->Version == 2)
+ {
+ Copy(a->YourKey_V2, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
+ }
+ else
+ {
+ Copy(a->YourKey, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
+ }
Copy(&a->YourIp, server_ip, sizeof(IP));
Copy(&a->YourIp2, server_ip_2, sizeof(IP));
@@ -1008,6 +1121,8 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->NoNatT = no_nat_t;
+ a->Version = 1;
+
a->NatT_TranId = Rand64();
@@ -1021,6 +1136,8 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->UdpSock = s;
Rand(a->MyKey, sizeof(a->MyKey));
Rand(a->YourKey, sizeof(a->YourKey));
+ Rand(a->MyKey_V2, sizeof(a->MyKey_V2));
+ Rand(a->YourKey_V2, sizeof(a->YourKey_V2));
Copy(&a->MyIp, ip, sizeof(IP));
a->MyPort = s->LocalPort;
@@ -1035,6 +1152,7 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->RecvBlockQueue = NewQueue();
Rand(a->NextIv, sizeof(a->NextIv));
+ Rand(a->NextIv_V2, sizeof(a->NextIv_V2));
do
{