mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-26 19:39:53 +03:00
Mayaqua: implement R-UDP version 2, powered by ChaCha20-Poly1305
This commit is contained in:
parent
2ea5c2a7b0
commit
6b08a451da
@ -2397,21 +2397,64 @@ void RUDPInterruptProc(RUDP_STACK *r)
|
|||||||
void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
|
void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
|
||||||
{
|
{
|
||||||
UCHAR *buf;
|
UCHAR *buf;
|
||||||
UINT buf_size;
|
UINT i, icmp_type, buf_size, padding_size;
|
||||||
UINT padding_size;
|
|
||||||
UINT i;
|
|
||||||
CRYPT *c;
|
|
||||||
UCHAR crypt_key_src[SHA1_SIZE * 2];
|
|
||||||
UCHAR crypt_key[SHA1_SIZE];
|
|
||||||
UINT icmp_type = 0;
|
|
||||||
UCHAR sign[SHA1_SIZE];
|
|
||||||
UCHAR iv[SHA1_SIZE + 1];
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (r == NULL || se == NULL || (data == NULL && data_size != 0))
|
if (r == NULL || se == NULL || (data == NULL && data_size != 0))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (se->BulkSendKey->Size == RUDP_BULK_KEY_SIZE_V2)
|
||||||
|
{
|
||||||
|
UCHAR *tmp, iv[RUDP_BULK_IV_SIZE_V2];
|
||||||
|
UINT size;
|
||||||
|
CIPHER *c;
|
||||||
|
|
||||||
|
padding_size = Rand32() % 31 + 1;
|
||||||
|
|
||||||
|
size = sizeof(UINT64) + data_size + padding_size;
|
||||||
|
|
||||||
|
// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
|
||||||
|
buf_size = RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + padding_size + RUDP_BULK_MAC_SIZE_V2;
|
||||||
|
buf = Malloc(buf_size);
|
||||||
|
|
||||||
|
// IV
|
||||||
|
Copy(iv, se->BulkNextIv_V2, RUDP_BULK_IV_SIZE_V2);
|
||||||
|
Copy(buf, iv, RUDP_BULK_IV_SIZE_V2);
|
||||||
|
|
||||||
|
// SEQ NO
|
||||||
|
WRITE_UINT64(buf + RUDP_BULK_IV_SIZE_V2, se->BulkNextSeqNo);
|
||||||
|
se->BulkNextSeqNo++;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
Copy(buf + RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64), data, data_size);
|
||||||
|
|
||||||
|
// Padding
|
||||||
|
for (i = 0;i < padding_size;i++)
|
||||||
|
{
|
||||||
|
buf[RUDP_BULK_IV_SIZE_V2 + sizeof(UINT64) + data_size + i] = (UCHAR)padding_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = sizeof(UINT64) + data_size + padding_size;
|
||||||
|
tmp = buf + RUDP_BULK_IV_SIZE_V2;
|
||||||
|
|
||||||
|
// Encryption
|
||||||
|
c = NewCipher("ChaCha20-Poly1305");
|
||||||
|
SetCipherKey(c, se->BulkSendKey->Data, true);
|
||||||
|
CipherProcessAead(c, iv, tmp + size, RUDP_BULK_MAC_SIZE_V2, tmp, tmp, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
|
||||||
|
FreeCipher(c);
|
||||||
|
|
||||||
|
// Next IV
|
||||||
|
Copy(se->BulkNextIv_V2, buf + sizeof(UINT64) + data_size + padding_size, RUDP_BULK_IV_SIZE_V2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UCHAR crypt_key_src[SHA1_SIZE * 2];
|
||||||
|
UCHAR crypt_key[SHA1_SIZE];
|
||||||
|
UCHAR sign[SHA1_SIZE];
|
||||||
|
UCHAR iv[SHA1_SIZE];
|
||||||
|
CRYPT *c;
|
||||||
|
|
||||||
padding_size = Rand32() % 31 + 1;
|
padding_size = Rand32() % 31 + 1;
|
||||||
|
|
||||||
buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size;
|
buf_size = SHA1_SIZE + SHA1_SIZE + sizeof(UINT64) + data_size + padding_size;
|
||||||
@ -2456,6 +2499,7 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
|
|||||||
|
|
||||||
// Next IV
|
// Next IV
|
||||||
Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE);
|
Copy(se->BulkNextIv, buf + buf_size - SHA1_SIZE, SHA1_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
if (r->Protocol == RUDP_PROTOCOL_ICMP)
|
if (r->Protocol == RUDP_PROTOCOL_ICMP)
|
||||||
{
|
{
|
||||||
@ -2465,6 +2509,7 @@ void RUDPBulkSend(RUDP_STACK *r, RUDP_SESSION *se, void *data, UINT data_size)
|
|||||||
{
|
{
|
||||||
icmp_type = se->Dns_TranId;
|
icmp_type = se->Dns_TranId;
|
||||||
}
|
}
|
||||||
|
|
||||||
RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
|
RUDPSendPacket(r, &se->YourIp, se->YourPort, buf, buf_size, icmp_type);
|
||||||
|
|
||||||
Free(buf);
|
Free(buf);
|
||||||
@ -2591,6 +2636,41 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verification signature (bulk packet)
|
// Verification signature (bulk packet)
|
||||||
|
if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
|
||||||
|
{
|
||||||
|
UCHAR *iv = p;
|
||||||
|
CIPHER *c;
|
||||||
|
|
||||||
|
// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
|
||||||
|
// IV
|
||||||
|
if (size < RUDP_BULK_IV_SIZE_V2)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iv = p;
|
||||||
|
p += RUDP_BULK_IV_SIZE_V2;
|
||||||
|
size -= RUDP_BULK_IV_SIZE_V2;
|
||||||
|
|
||||||
|
// Decrypt
|
||||||
|
if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = NewCipher("ChaCha20-Poly1305");
|
||||||
|
SetCipherKey(c, se->BulkRecvKey->Data, false);
|
||||||
|
size = CipherProcessAead(c, iv, p + size, RUDP_BULK_MAC_SIZE_V2, r->TmpBuf, p, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
|
||||||
|
FreeCipher(c);
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (se->UseHMac == false)
|
if (se->UseHMac == false)
|
||||||
{
|
{
|
||||||
Copy(sign, p, SHA1_SIZE);
|
Copy(sign, p, SHA1_SIZE);
|
||||||
@ -2610,6 +2690,7 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
|
|||||||
se->UseHMac = true;
|
se->UseHMac = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2617,14 +2698,9 @@ bool RUDPCheckSignOfRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
|
|||||||
// Process the received packet (bulk)
|
// Process the received packet (bulk)
|
||||||
bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
|
bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data, UINT recv_size)
|
||||||
{
|
{
|
||||||
UCHAR sign[SHA1_SIZE];
|
|
||||||
UCHAR sign2[SHA1_SIZE];
|
|
||||||
UCHAR *p;
|
UCHAR *p;
|
||||||
UCHAR *iv;
|
UCHAR *iv;
|
||||||
UINT size;
|
UINT size;
|
||||||
UCHAR keygen[SHA1_SIZE * 2];
|
|
||||||
UCHAR key[SHA1_SIZE];
|
|
||||||
CRYPT *c;
|
|
||||||
UCHAR padlen;
|
UCHAR padlen;
|
||||||
UINT64 seq_no;
|
UINT64 seq_no;
|
||||||
UCHAR *payload;
|
UCHAR *payload;
|
||||||
@ -2642,6 +2718,62 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (se->BulkRecvKey->Size == RUDP_BULK_KEY_SIZE_V2)
|
||||||
|
{
|
||||||
|
UINT ret;
|
||||||
|
CIPHER *c;
|
||||||
|
|
||||||
|
// Packet: IV + Encrypted(SEQ_NO + Data + padding) + MAC
|
||||||
|
// IV
|
||||||
|
if (size < RUDP_BULK_IV_SIZE_V2)
|
||||||
|
{
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
iv = p;
|
||||||
|
p += RUDP_BULK_IV_SIZE_V2;
|
||||||
|
size -= RUDP_BULK_IV_SIZE_V2;
|
||||||
|
|
||||||
|
// Decrypt
|
||||||
|
if (size < (RUDP_BULK_MAC_SIZE_V2 + 1))
|
||||||
|
{
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = NewCipher("ChaCha20-Poly1305");
|
||||||
|
SetCipherKey(c, se->BulkRecvKey->Data, false);
|
||||||
|
ret = CipherProcessAead(c, iv, p + size, RUDP_BULK_MAC_SIZE_V2, p, p, size - RUDP_BULK_MAC_SIZE_V2, NULL, 0);
|
||||||
|
FreeCipher(c);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size -= RUDP_BULK_MAC_SIZE_V2;
|
||||||
|
|
||||||
|
// padlen
|
||||||
|
padlen = p[size - 1];
|
||||||
|
if (padlen == 0)
|
||||||
|
{
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (size < padlen)
|
||||||
|
{
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size -= padlen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CRYPT *c;
|
||||||
|
UCHAR sign[SHA1_SIZE], sign2[SHA1_SIZE];
|
||||||
|
UCHAR key[SHA1_SIZE], keygen[SHA1_SIZE * 2];
|
||||||
|
|
||||||
// Validate the signature
|
// Validate the signature
|
||||||
if (se->UseHMac == false)
|
if (se->UseHMac == false)
|
||||||
{
|
{
|
||||||
@ -2663,9 +2795,6 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
|
|||||||
se->UseHMac = true;
|
se->UseHMac = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2713,6 +2842,7 @@ bool RUDPProcessBulkRecvPacket(RUDP_STACK *r, RUDP_SESSION *se, void *recv_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size -= padlen;
|
size -= padlen;
|
||||||
|
}
|
||||||
|
|
||||||
// SEQ NO
|
// SEQ NO
|
||||||
seq_no = READ_UINT64(p);
|
seq_no = READ_UINT64(p);
|
||||||
@ -3525,8 +3655,8 @@ RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your
|
|||||||
RUDP_SESSION *se;
|
RUDP_SESSION *se;
|
||||||
UCHAR key1[SHA1_SIZE];
|
UCHAR key1[SHA1_SIZE];
|
||||||
UCHAR key2[SHA1_SIZE];
|
UCHAR key2[SHA1_SIZE];
|
||||||
UCHAR bulk_send_key[SHA1_SIZE];
|
UCHAR bulk_send_key[RUDP_BULK_KEY_SIZE_MAX];
|
||||||
UCHAR bulk_recv_key[SHA1_SIZE];
|
UCHAR bulk_recv_key[RUDP_BULK_KEY_SIZE_MAX];
|
||||||
BUF *b;
|
BUF *b;
|
||||||
|
|
||||||
se = ZeroMalloc(sizeof(RUDP_SESSION));
|
se = ZeroMalloc(sizeof(RUDP_SESSION));
|
||||||
@ -3612,6 +3742,8 @@ RUDP_SESSION *RUDPNewSession(bool server_mode, IP *my_ip, UINT my_port, IP *your
|
|||||||
se->BulkRecvKey = NewSharedBuffer(bulk_recv_key, sizeof(bulk_recv_key));
|
se->BulkRecvKey = NewSharedBuffer(bulk_recv_key, sizeof(bulk_recv_key));
|
||||||
|
|
||||||
Rand(se->BulkNextIv, sizeof(se->BulkNextIv));
|
Rand(se->BulkNextIv, sizeof(se->BulkNextIv));
|
||||||
|
Rand(se->BulkNextIv_V2, sizeof(se->BulkNextIv_V2));
|
||||||
|
|
||||||
se->BulkNextSeqNo = 1;
|
se->BulkNextSeqNo = 1;
|
||||||
|
|
||||||
return se;
|
return se;
|
||||||
|
@ -576,6 +576,12 @@ struct IPBLOCK
|
|||||||
#define RUDP_TIMEOUT 12000 // Time-out of R-UDP communication
|
#define RUDP_TIMEOUT 12000 // Time-out of R-UDP communication
|
||||||
#define RUDP_DIRECT_CONNECT_TIMEOUT 5000 // R-UDP direct connection time-out
|
#define RUDP_DIRECT_CONNECT_TIMEOUT 5000 // R-UDP direct connection time-out
|
||||||
#define RUDP_MAX_SEGMENT_SIZE 512 // Maximum segment size
|
#define RUDP_MAX_SEGMENT_SIZE 512 // Maximum segment size
|
||||||
|
#define RUDP_BULK_KEY_SIZE_MAX 128 // Bulk key size Max
|
||||||
|
|
||||||
|
#define RUDP_BULK_KEY_SIZE_V2 32 // V2: Bulk key size
|
||||||
|
#define RUDP_BULK_IV_SIZE_V2 12 // V2: Bulk IV size
|
||||||
|
#define RUDP_BULK_MAC_SIZE_V2 16 // V2: Bulk MAC size
|
||||||
|
|
||||||
// Maximum R-UDP packet size
|
// Maximum R-UDP packet size
|
||||||
#define RUDP_MAX_PACKET_SIZE (RUDP_MAX_SEGMENT_SIZE + sizeof(UINT64) * RUDP_MAX_NUM_ACK + SHA1_SIZE * 2 + sizeof(UINT64) * 4 + sizeof(UINT) + 255)
|
#define RUDP_MAX_PACKET_SIZE (RUDP_MAX_SEGMENT_SIZE + sizeof(UINT64) * RUDP_MAX_NUM_ACK + SHA1_SIZE * 2 + sizeof(UINT64) * 4 + sizeof(UINT) + 255)
|
||||||
#define RUDP_MAX_NUM_ACK 64 // Maximum number of ACKs
|
#define RUDP_MAX_NUM_ACK 64 // Maximum number of ACKs
|
||||||
@ -664,6 +670,7 @@ struct RUDP_SESSION
|
|||||||
UINT64 BulkNextSeqNo; // Next SEQ NO to the bulk send
|
UINT64 BulkNextSeqNo; // Next SEQ NO to the bulk send
|
||||||
bool FlushBulkSendTube; // Flag to be Flush the bulk send Tube
|
bool FlushBulkSendTube; // Flag to be Flush the bulk send Tube
|
||||||
UINT64 BulkRecvSeqNoMax; // Highest sequence number received
|
UINT64 BulkRecvSeqNoMax; // Highest sequence number received
|
||||||
|
UCHAR BulkNextIv_V2[RUDP_BULK_IV_SIZE_V2]; // Next IV to the bulk send (version 2)
|
||||||
};
|
};
|
||||||
|
|
||||||
// NAT Traversal Server Information
|
// NAT Traversal Server Information
|
||||||
|
Loading…
Reference in New Issue
Block a user