mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-23 01:49:53 +03:00
Merge PR #794: Proto_OpenVPN.c: move encrypt and decrypt process into dedicated functions
This commit is contained in:
commit
8b7b45b301
@ -175,6 +175,94 @@ void OvsLog(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, char *na
|
|||||||
WriteServerLog(s->Cedar, prefix);
|
WriteServerLog(s->Cedar, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encrypt the data
|
||||||
|
UINT OvsEncrypt(CIPHER *cipher, MD *md, UCHAR *iv, UCHAR *dest, UCHAR *src, UINT size)
|
||||||
|
{
|
||||||
|
UINT dest_size, ret;
|
||||||
|
// Validate arguments
|
||||||
|
if (cipher == NULL || md == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypt
|
||||||
|
dest_size = CipherProcess(cipher, iv, dest + md->Size + cipher->IvSize, src, size);
|
||||||
|
if (dest_size == 0)
|
||||||
|
{
|
||||||
|
Debug("OvsEncrypt(): CipherProcess() failed!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the IV
|
||||||
|
Copy(dest + md->Size, iv, cipher->IvSize);
|
||||||
|
dest_size += cipher->IvSize;
|
||||||
|
|
||||||
|
// Calculate the HMAC
|
||||||
|
ret = MdProcess(md, dest, dest + md->Size, dest_size);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
Debug("OvsEncrypt(): MdProcess() failed!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest_size + ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt the data
|
||||||
|
UINT OvsDecrypt(CIPHER *cipher, MD *md, UCHAR *dest, UCHAR *src, UINT size)
|
||||||
|
{
|
||||||
|
UCHAR *hmac;
|
||||||
|
UCHAR *iv;
|
||||||
|
UCHAR hmac_test[128];
|
||||||
|
// Validate arguments
|
||||||
|
if (cipher == NULL || md == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < (md->Size + cipher->IvSize + sizeof(UINT)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HMAC
|
||||||
|
hmac = src;
|
||||||
|
src += md->Size;
|
||||||
|
size -= md->Size;
|
||||||
|
|
||||||
|
if (MdProcess(md, hmac_test, src, size) == 0)
|
||||||
|
{
|
||||||
|
Debug("OvsDecrypt(): MdProcess() failed!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Cmp(hmac_test, hmac, md->Size) != 0)
|
||||||
|
{
|
||||||
|
Debug("OvsDecrypt(): HMAC verification failed!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IV
|
||||||
|
iv = src;
|
||||||
|
src += cipher->IvSize;
|
||||||
|
size -= cipher->IvSize;
|
||||||
|
|
||||||
|
// Payload
|
||||||
|
if (size >= 1 && (cipher->BlockSize == 0 || (size % cipher->BlockSize) == 0))
|
||||||
|
{
|
||||||
|
// Decryption
|
||||||
|
UINT ret = CipherProcess(cipher, iv, dest, src, size);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
Debug("OvsDecrypt(): CipherProcess() failed!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Process the received packet
|
// Process the received packet
|
||||||
void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
|
void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
|
||||||
{
|
{
|
||||||
@ -285,56 +373,21 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
|
|||||||
OPENVPN_CHANNEL *c = se->Channels[recv_packet->KeyId];
|
OPENVPN_CHANNEL *c = se->Channels[recv_packet->KeyId];
|
||||||
if (c->Status == OPENVPN_CHANNEL_STATUS_ESTABLISHED)
|
if (c->Status == OPENVPN_CHANNEL_STATUS_ESTABLISHED)
|
||||||
{
|
{
|
||||||
UCHAR *data;
|
UINT size = OvsDecrypt(c->CipherDecrypt, c->MdRecv, s->TmpBuf, recv_packet->Data, recv_packet->DataSize);
|
||||||
UINT size;
|
if (size >= sizeof(UINT))
|
||||||
|
|
||||||
data = recv_packet->Data;
|
|
||||||
size = recv_packet->DataSize;
|
|
||||||
|
|
||||||
if (size >= (c->MdRecv->Size + c->CipherDecrypt->IvSize + sizeof(UINT)))
|
|
||||||
{
|
{
|
||||||
UCHAR *hmac;
|
UCHAR *data = s->TmpBuf;
|
||||||
UCHAR *iv;
|
|
||||||
UCHAR hmac_test[128];
|
|
||||||
|
|
||||||
// HMAC
|
|
||||||
hmac = data;
|
|
||||||
data += c->MdRecv->Size;
|
|
||||||
size -= c->MdRecv->Size;
|
|
||||||
|
|
||||||
// Confirmation of HMAC
|
|
||||||
MdProcess(c->MdRecv, hmac_test, data, size);
|
|
||||||
if (Cmp(hmac_test, hmac, c->MdRecv->Size) == 0)
|
|
||||||
{
|
|
||||||
// Update of last communication time
|
// Update of last communication time
|
||||||
se->LastCommTick = s->Now;
|
se->LastCommTick = s->Now;
|
||||||
|
|
||||||
// IV
|
// Seek buffer after the packet ID
|
||||||
iv = data;
|
|
||||||
data += c->CipherDecrypt->IvSize;
|
|
||||||
size -= c->CipherDecrypt->IvSize;
|
|
||||||
|
|
||||||
// Payload
|
|
||||||
if (size >= 1 && (c->CipherDecrypt->BlockSize == 0 || (size % c->CipherDecrypt->BlockSize) == 0))
|
|
||||||
{
|
|
||||||
UINT data_packet_id;
|
|
||||||
|
|
||||||
// Decryption
|
|
||||||
size = CipherProcess(c->CipherDecrypt, iv, s->TmpBuf, data, size);
|
|
||||||
|
|
||||||
data = s->TmpBuf;
|
|
||||||
|
|
||||||
if (size >= sizeof(UINT))
|
|
||||||
{
|
|
||||||
data_packet_id = READ_UINT(data);
|
|
||||||
|
|
||||||
data += sizeof(UINT);
|
data += sizeof(UINT);
|
||||||
size -= sizeof(UINT);
|
size -= sizeof(UINT);
|
||||||
|
|
||||||
if (size < sizeof(ping_signature) ||
|
if (size < sizeof(ping_signature) || Cmp(data, ping_signature, sizeof(ping_signature)) != 0)
|
||||||
Cmp(data, ping_signature, sizeof(ping_signature)) != 0)
|
|
||||||
{
|
{
|
||||||
// Receive a packet!!
|
// Receive a packet!
|
||||||
if (se->Ipc != NULL)
|
if (se->Ipc != NULL)
|
||||||
{
|
{
|
||||||
switch (se->Mode)
|
switch (se->Mode)
|
||||||
@ -342,7 +395,6 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
|
|||||||
case OPENVPN_MODE_L2: // Send an Ethernet packet to a session
|
case OPENVPN_MODE_L2: // Send an Ethernet packet to a session
|
||||||
IPCSendL2(se->Ipc, data, size);
|
IPCSendL2(se->Ipc, data, size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPENVPN_MODE_L3: // Send an IPv4 packet to a session
|
case OPENVPN_MODE_L3: // Send an IPv4 packet to a session
|
||||||
IPCSendIPv4(se->Ipc, data, size);
|
IPCSendIPv4(se->Ipc, data, size);
|
||||||
break;
|
break;
|
||||||
@ -352,13 +404,6 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Debug("HMAC Failed (c=%u)\n", c->KeyId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OvsFreePacket(recv_packet);
|
OvsFreePacket(recv_packet);
|
||||||
@ -1382,23 +1427,17 @@ UINT64 OvsNewServerSessionId(OPENVPN_SERVER *s)
|
|||||||
// Build and submit the OpenVPN data packet
|
// Build and submit the OpenVPN data packet
|
||||||
void OvsSendDataPacket(OPENVPN_CHANNEL *c, UCHAR key_id, UINT data_packet_id, void *data, UINT data_size)
|
void OvsSendDataPacket(OPENVPN_CHANNEL *c, UCHAR key_id, UINT data_packet_id, void *data, UINT data_size)
|
||||||
{
|
{
|
||||||
UCHAR uc;
|
|
||||||
UCHAR *encrypted_data;
|
UCHAR *encrypted_data;
|
||||||
UINT encrypted_size;
|
UINT encrypted_size;
|
||||||
UCHAR *dest_data;
|
UCHAR *dest_data;
|
||||||
UINT dest_size;
|
UINT dest_size;
|
||||||
UINT r;
|
|
||||||
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (c == NULL || data == NULL || data_size == 0)
|
if (c == NULL || data == NULL || data_size == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uc = ((OPENVPN_P_DATA_V1 << 3) & 0xF8) | (key_id & 0x07);
|
|
||||||
|
|
||||||
// Generate the data to be encrypted
|
// Generate the data to be encrypted
|
||||||
|
|
||||||
encrypted_size = sizeof(UINT) + data_size;
|
encrypted_size = sizeof(UINT) + data_size;
|
||||||
encrypted_data = ZeroMalloc(encrypted_size);
|
encrypted_data = ZeroMalloc(encrypted_size);
|
||||||
|
|
||||||
@ -1409,22 +1448,14 @@ void OvsSendDataPacket(OPENVPN_CHANNEL *c, UCHAR key_id, UINT data_packet_id, vo
|
|||||||
dest_data = Malloc(sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize + encrypted_size + 256);
|
dest_data = Malloc(sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize + encrypted_size + 256);
|
||||||
|
|
||||||
// Encrypt
|
// Encrypt
|
||||||
r = CipherProcess(c->CipherEncrypt, c->NextIv, dest_data + sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize,
|
dest_size = OvsEncrypt(c->CipherEncrypt, c->MdSend, c->NextIv, dest_data + sizeof(CHAR), encrypted_data, encrypted_size);
|
||||||
encrypted_data, encrypted_size);
|
dest_size += sizeof(UCHAR);
|
||||||
dest_size = sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize + r;
|
|
||||||
|
|
||||||
// Copy the IV
|
|
||||||
Copy(dest_data + sizeof(UCHAR) + c->MdSend->Size, c->NextIv, c->CipherEncrypt->IvSize);
|
|
||||||
|
|
||||||
// Calculate the HMAC
|
|
||||||
MdProcess(c->MdSend, dest_data + sizeof(UCHAR), dest_data + sizeof(UCHAR) + c->MdSend->Size,
|
|
||||||
dest_size - sizeof(UCHAR) - c->MdSend->Size);
|
|
||||||
|
|
||||||
// Update the NextIV
|
// Update the NextIV
|
||||||
Copy(c->NextIv, dest_data + dest_size - c->CipherEncrypt->IvSize, c->CipherEncrypt->IvSize);
|
Copy(c->NextIv, dest_data + dest_size - c->CipherEncrypt->IvSize, c->CipherEncrypt->IvSize);
|
||||||
|
|
||||||
// Op-code
|
// Op-code
|
||||||
dest_data[0] = uc;
|
dest_data[0] = ((OPENVPN_P_DATA_V1 << 3) & 0xF8) | (key_id & 0x07);
|
||||||
|
|
||||||
OvsSendPacketRawNow(c->Server, c->Session, dest_data, dest_size);
|
OvsSendPacketRawNow(c->Server, c->Session, dest_data, dest_size);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user