Upstream tarball 9807
[amule.git] / src / EncryptedDatagramSocket.cpp
blobe551774aaa35b7ccff50a35a1c2344616f260d79
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 /* Basic Obfusicated Handshake Protocol UDP:
27 see EncryptedStreamSocket.h
29 ****************************** ED2K Packets
31 -Keycreation Client <-> Clinet:
32 - Client A (Outgoing connection):
33 Sendkey: Md5(<UserHashClientB 16><IPClientA 4><MagicValue91 1><RandomKeyPartClientA 2>) 23
34 - Client B (Incomming connection):
35 Receivekey: Md5(<UserHashClientB 16><IPClientA 4><MagicValue91 1><RandomKeyPartClientA 2>) 23
36 - Note: The first 1024 Bytes will be _NOT_ discarded for UDP keys to safe CPU time
38 - Handshake
39 -> The handshake is encrypted - except otherwise noted - by the Keys created above
40 -> Padding is cucrently not used for UDP meaning that PaddingLen will be 0, using PaddingLens up to 16 Bytes is acceptable however
41 Client A: <SemiRandomNotProtocolMarker 7 Bits[Unencrypted]><ED2K Marker 1Bit = 1><RandomKeyPart 2[Unencrypted]><MagicValue 4><PaddingLen 1><RandomBytes PaddingLen%16>
43 - Additional Comments:
44 - For obvious reasons the UDP handshake is actually no handshake. If a different Encryption method (or better a different Key) is to be used this has to be negotiated in a TCP connection
45 - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header byte. This is a compromiss, turning in complete randomness (and nice design) but gaining a lower CPU usage
46 - Kad/Ed2k Marker are only indicators, which possibility could be tried first, and should not be trusted
48 ****************************** Server Packets
50 -Keycreation Client <-> Server:
51 - Client A (Outgoing connection client -> server):
52 Sendkey: Md5(<BaseKey 4><MagicValueClientServer 1><RandomKeyPartClientA 2>) 7
53 - Client B (Incomming connection):
54 Receivekey: Md5(<BaseKey 4><MagicValueServerClient 1><RandomKeyPartClientA 2>) 7
55 - Note: The first 1024 Bytes will be _NOT_ discarded for UDP keys to safe CPU time
57 - Handshake
58 -> The handshake is encrypted - except otherwise noted - by the Keys created above
59 -> Padding is cucrently not used for UDP meaning that PaddingLen will be 0, using PaddingLens up to 16 Bytes is acceptable however
60 Client A: <SemiRandomNotProtocolMarker 1[Unencrypted]><RandomKeyPart 2[Unencrypted]><MagicValue 4><PaddingLen 1><RandomBytes PaddingLen%16>
62 - Overhead: 8 Bytes per UDP Packet
64 - Security for Basic Obfusication:
65 - Random looking packets, very limited protection against passive eavesdropping single packets
67 - Additional Comments:
68 - For obvious reasons the UDP handshake is actually no handshake. If a different Encryption method (or better a different Key) is to be used this has to be negotiated in a TCP connection
69 - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header byte. This is a compromiss, turning in complete randomness (and nice design) but gaining a lower CPU usage
71 ****************************** KAD Packets
73 -Keycreation Client <-> Client:
74 - Client A (Outgoing connection):
75 Sendkey: Md5(<KadID 16><RandomKeyPartClientA 2>) 18
76 - Client B (Incomming connection):
77 Receivekey: Md5(<KadID 16><RandomKeyPartClientA 2>) 18
78 - Note: The first 1024 Bytes will be _NOT_ discarded for UDP keys to safe CPU time
80 - Handshake
81 -> The handshake is encrypted - except otherwise noted - by the Keys created above
82 -> Padding is cucrently not used for UDP meaning that PaddingLen will be 0, using PaddingLens up to 16 Bytes is acceptable however
83 Client A: <SemiRandomNotProtocolMarker 7 Bits[Unencrypted]><Kad Marker 1Bit = 0><RandomKeyPart 2[Unencrypted]><MagicValue 4><PaddingLen 1><RandomBytes PaddingLen%16><ReceiverVerifyKey 2><SenderVerifyKey 2>
85 - Overhead: 12 Bytes per UDP Packet
87 - Additional Comments:
88 - For obvious reasons the UDP handshake is actually no handshake. If a different Encryption method (or better a different Key) is to be used this has to be negotiated in a TCP connection
89 - SemiRandomNotProtocolMarker is a Byte which has a value unequal any Protocol header byte. This is a compromiss, turning in complete randomness (and nice design) but gaining a lower CPU usage
90 - Kad/Ed2k Marker are only indicators, which possibility could be tried first, and should not be trusted
93 #include "EncryptedDatagramSocket.h"
94 #include "amule.h"
95 #include "Logger.h"
96 #include "Preferences.h"
97 #include "RC4Encrypt.h"
98 #include "./kademlia/kademlia/Prefs.h"
99 #include "./kademlia/kademlia/Kademlia.h"
100 #include "RandomFunctions.h"
101 #include "Statistics.h"
103 #include <protocol/Protocols.h>
104 #include <common/MD5Sum.h>
106 // random generator
107 #include "CryptoPP_Inc.h" // Needed for Crypto functions
109 #define CRYPT_HEADER_WITHOUTPADDING 8
110 #define MAGICVALUE_UDP 91
111 #define MAGICVALUE_UDP_SYNC_CLIENT 0x395F2EC1
112 #define MAGICVALUE_UDP_SYNC_SERVER 0x13EF24D5
113 #define MAGICVALUE_UDP_SERVERCLIENT 0xA5
114 #define MAGICVALUE_UDP_CLIENTSERVER 0x6B
116 CEncryptedDatagramSocket::CEncryptedDatagramSocket( wxIPaddress &address, wxSocketFlags flags, const CProxyData *proxyData) : CDatagramSocketProxy(address, flags, proxyData)
121 CEncryptedDatagramSocket::~CEncryptedDatagramSocket()
126 int CEncryptedDatagramSocket::DecryptReceivedClient(uint8_t *bufIn, int bufLen, uint8_t **bufOut, uint32_t ip, uint32_t *receiverVerifyKey, uint32_t *senderVerifyKey)
128 int result = bufLen;
129 *bufOut = bufIn;
131 if (receiverVerifyKey == NULL || senderVerifyKey == NULL) {
132 wxFAIL;
133 return result;
136 *receiverVerifyKey = 0;
137 *senderVerifyKey = 0;
139 if (result <= CRYPT_HEADER_WITHOUTPADDING /*|| !thePrefs.IsClientCryptLayerSupported()*/) {
140 return result;
143 switch (bufIn[0]) {
144 case OP_EMULEPROT:
145 case OP_KADEMLIAPACKEDPROT:
146 case OP_KADEMLIAHEADER:
147 case OP_UDPRESERVEDPROT1:
148 case OP_UDPRESERVEDPROT2:
149 case OP_PACKEDPROT:
150 return result; // no encrypted packet (see description on top)
151 default:
155 // might be an encrypted packet, try to decrypt
156 CRC4EncryptableBuffer receivebuffer;
157 uint32_t value = 0;
158 // check the marker bit which type this packet could be and which key to test first, this is only an indicator since old clients have it set random
159 // see the header for marker bits explanation
160 uint8_t currentTry = ((bufIn[0] & 0x03) == 3) ? 1 : (bufIn[0] & 0x03);
161 uint8_t tries;
162 if (Kademlia::CKademlia::GetPrefs() == NULL) {
163 // if kad never run, no point in checking anything except for ed2k encryption
164 tries = 1;
165 currentTry = 1;
166 } else {
167 tries = 3;
169 bool kadRecvKeyUsed = false;
170 bool kad = false;
171 do {
172 receivebuffer.FullReset();
173 tries--;
174 MD5Sum md5;
176 if (currentTry == 0) {
177 // kad packet with NodeID as key
178 kad = true;
179 kadRecvKeyUsed = false;
180 if (Kademlia::CKademlia::GetPrefs()) {
181 uint8_t keyData[18];
182 Kademlia::CKademlia::GetPrefs()->GetKadID().StoreCryptValue((uint8_t *)&keyData);
183 memcpy(keyData + 16, bufIn + 1, 2); // random key part sent from remote client
184 md5.Calculate(keyData, sizeof(keyData));
186 } else if (currentTry == 1) {
187 // ed2k packet
188 kad = false;
189 kadRecvKeyUsed = false;
190 uint8_t keyData[23];
191 md4cpy(keyData, thePrefs::GetUserHash().GetHash());
192 keyData[20] = MAGICVALUE_UDP;
193 PokeUInt32(keyData + 16, ip);
194 memcpy(keyData + 21, bufIn + 1, 2); // random key part sent from remote client
195 md5.Calculate(keyData, sizeof(keyData));
196 } else if (currentTry == 2) {
197 // kad packet with ReceiverKey as key
198 kad = true;
199 kadRecvKeyUsed = true;
200 if (Kademlia::CKademlia::GetPrefs()) {
201 uint8_t keyData[6];
202 PokeUInt32(keyData, Kademlia::CPrefs::GetUDPVerifyKey(ip));
203 memcpy(keyData + 4, bufIn + 1, 2); // random key part sent from remote client
204 md5.Calculate(keyData, sizeof(keyData));
206 } else {
207 wxFAIL;
210 receivebuffer.SetKey(md5, true);
211 receivebuffer.RC4Crypt(bufIn + 3, (uint8_t*)&value, sizeof(value));
212 ENDIAN_SWAP_I_32(value);
214 currentTry = (currentTry + 1) % 3;
215 } while (value != MAGICVALUE_UDP_SYNC_CLIENT && tries > 0); // try to decrypt as ed2k as well as kad packet if needed (max 3 rounds)
217 if (value == MAGICVALUE_UDP_SYNC_CLIENT) {
218 // yup this is an encrypted packet
219 // // debugoutput notices
220 // // the following cases are "allowed" but shouldn't happen given that there is only our implementation yet
221 // if (bKad && (pbyBufIn[0] & 0x01) != 0)
222 // DebugLog(_T("Received obfuscated UDP packet from clientIP: %s with wrong key marker bits (kad packet, ed2k bit)"), ipstr(dwIP));
223 // else if (bKad && !bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) != 0)
224 // DebugLog(_T("Received obfuscated UDP packet from clientIP: %s with wrong key marker bits (kad packet, nodeid key, recvkey bit)"), ipstr(dwIP));
225 // else if (bKad && bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) == 0)
226 // DebugLog(_T("Received obfuscated UDP packet from clientIP: %s with wrong key marker bits (kad packet, recvkey key, nodeid bit)"), ipstr(dwIP));
228 uint8_t padLen;
229 receivebuffer.RC4Crypt(bufIn + 7, (uint8_t*)&padLen, 1);
230 result -= CRYPT_HEADER_WITHOUTPADDING;
232 if (result <= padLen) {
233 //DebugLogError(_T("Invalid obfuscated UDP packet from clientIP: %s, Paddingsize (%u) larger than received bytes"), ipstr(dwIP), byPadLen);
234 return bufLen; // pass through, let the Receivefunction do the errorhandling on this junk
237 if (padLen > 0) {
238 receivebuffer.RC4Crypt(NULL, NULL, padLen);
241 result -= padLen;
243 if (kad) {
244 if (result <= 8) {
245 //DebugLogError(_T("Obfuscated Kad packet with mismatching size (verify keys missing) received from clientIP: %s"), ipstr(dwIP));
246 return bufLen; // pass through, let the Receivefunction do the errorhandling on this junk;
248 // read the verify keys
249 receivebuffer.RC4Crypt(bufIn + CRYPT_HEADER_WITHOUTPADDING + padLen, (uint8_t*)receiverVerifyKey, 4);
250 receivebuffer.RC4Crypt(bufIn + CRYPT_HEADER_WITHOUTPADDING + padLen + 4, (uint8_t*)senderVerifyKey, 4);
251 ENDIAN_SWAP_I_32(*receiverVerifyKey);
252 ENDIAN_SWAP_I_32(*senderVerifyKey);
253 result -= 8;
256 *bufOut = bufIn + (bufLen - result);
258 receivebuffer.RC4Crypt((uint8_t*)*bufOut, (uint8_t*)*bufOut, result);
259 theStats::AddDownOverheadCrypt(bufLen - result);
260 return result; // done
261 } else {
262 //DebugLogWarning(_T("Obfuscated packet expected but magicvalue mismatch on UDP packet from clientIP: %s"), ipstr(dwIP));
263 return bufLen; // pass through, let the Receivefunction do the errorhandling on this junk
267 // Encrypt packet. Key used:
268 // pachClientHashOrKadID != NULL -> pachClientHashOrKadID
269 // pachClientHashOrKadID == NULL && bKad && nReceiverVerifyKey != 0 -> nReceiverVerifyKey
270 // else -> ASSERT
271 int CEncryptedDatagramSocket::EncryptSendClient(uint8_t **buf, int bufLen, const uint8_t *clientHashOrKadID, bool kad, uint32_t receiverVerifyKey, uint32_t senderVerifyKey)
273 wxASSERT(theApp->GetPublicIP() != 0 || kad);
274 wxASSERT(thePrefs::IsClientCryptLayerSupported());
275 wxASSERT(clientHashOrKadID != NULL || receiverVerifyKey != 0);
276 wxASSERT((receiverVerifyKey == 0 && senderVerifyKey == 0) || kad);
278 uint8_t padLen = 0; // padding disabled for UDP currently
279 const uint32_t cryptHeaderLen = padLen + CRYPT_HEADER_WITHOUTPADDING + (kad ? 8 : 0);
280 uint32_t cryptedLen = bufLen + cryptHeaderLen;
281 uint8_t *cryptedBuffer = new uint8_t[cryptedLen];
282 bool kadRecvKeyUsed = false;
284 uint16_t randomKeyPart = GetRandomUint16();
285 CRC4EncryptableBuffer sendbuffer;
286 MD5Sum md5;
287 if (kad) {
288 if ((clientHashOrKadID == NULL || CMD4Hash(clientHashOrKadID).IsEmpty()) && receiverVerifyKey != 0) {
289 kadRecvKeyUsed = true;
290 uint8_t keyData[6];
291 PokeUInt32(keyData, receiverVerifyKey);
292 PokeUInt16(keyData+4, randomKeyPart);
293 md5.Calculate(keyData, sizeof(keyData));
294 //DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by ReceiverKey (%u)"), nReceiverVerifyKey) );
296 else if (clientHashOrKadID != NULL && !CMD4Hash(clientHashOrKadID).IsEmpty()) {
297 uint8_t keyData[18];
298 md4cpy(keyData, clientHashOrKadID);
299 PokeUInt16(keyData+16, randomKeyPart);
300 md5.Calculate(keyData, sizeof(keyData));
301 //DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by Hash/NodeID %s"), md4str(pachClientHashOrKadID)) );
303 else {
304 wxFAIL;
305 return bufLen;
307 } else {
308 uint8_t keyData[23];
309 md4cpy(keyData, clientHashOrKadID);
310 PokeUInt32(keyData+16, theApp->GetPublicIP());
311 PokeUInt16(keyData+21, randomKeyPart);
312 keyData[20] = MAGICVALUE_UDP;
313 md5.Calculate(keyData, sizeof(keyData));
316 sendbuffer.SetKey(md5, true);
318 // create the semi random byte encryption header
319 uint8_t semiRandomNotProtocolMarker = 0;
320 int i;
321 for (i = 0; i < 128; i++) {
322 semiRandomNotProtocolMarker = GetRandomUint8();
323 semiRandomNotProtocolMarker = kad ? (semiRandomNotProtocolMarker & 0xFE) : (semiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit
324 if (kad) {
325 semiRandomNotProtocolMarker = kadRecvKeyUsed ? ((semiRandomNotProtocolMarker & 0xFE) | 0x02) : (semiRandomNotProtocolMarker & 0xFC); // set the ed2k/kad and nodeid/reckey markerbit
326 } else {
327 semiRandomNotProtocolMarker = (semiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit
330 bool bOk = false;
331 switch (semiRandomNotProtocolMarker) { // not allowed values
332 case OP_EMULEPROT:
333 case OP_KADEMLIAPACKEDPROT:
334 case OP_KADEMLIAHEADER:
335 case OP_UDPRESERVEDPROT1:
336 case OP_UDPRESERVEDPROT2:
337 case OP_PACKEDPROT:
338 break;
339 default:
340 bOk = true;
343 if (bOk) {
344 break;
348 if (i >= 128) {
349 // either we have _real_ bad luck or the randomgenerator is a bit messed up
350 wxFAIL;
351 semiRandomNotProtocolMarker = 0x01;
354 cryptedBuffer[0] = semiRandomNotProtocolMarker;
355 PokeUInt16(cryptedBuffer + 1, randomKeyPart);
357 uint32_t magicValue = ENDIAN_SWAP_32(MAGICVALUE_UDP_SYNC_CLIENT);
358 sendbuffer.RC4Crypt((uint8_t*)&magicValue, cryptedBuffer + 3, 4);
359 sendbuffer.RC4Crypt((uint8_t*)&padLen, cryptedBuffer + 7, 1);
361 for (int j = 0; j < padLen; j++) {
362 uint8_t byRand = (uint8_t)rand(); // they actually don't really need to be random, but it doesn't hurt either
363 sendbuffer.RC4Crypt((uint8_t*)&byRand, cryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + j, 1);
366 if (kad) {
367 ENDIAN_SWAP_I_32(receiverVerifyKey);
368 ENDIAN_SWAP_I_32(senderVerifyKey);
369 sendbuffer.RC4Crypt((uint8_t*)&receiverVerifyKey, cryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + padLen, 4);
370 sendbuffer.RC4Crypt((uint8_t*)&senderVerifyKey, cryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + padLen + 4, 4);
373 sendbuffer.RC4Crypt(*buf, cryptedBuffer + cryptHeaderLen, bufLen);
374 delete [] *buf;
375 *buf = cryptedBuffer;
377 theStats::AddUpOverheadCrypt(cryptedLen - bufLen);
378 return cryptedLen;
381 int CEncryptedDatagramSocket::DecryptReceivedServer(
382 uint8* pbyBufIn,
383 int nBufLen, uint8 **ppbyBufOut,
384 uint32 dwBaseKey,
385 uint32 /*dbgIP*/)
387 int nResult = nBufLen;
388 *ppbyBufOut = pbyBufIn;
390 if (nResult <= CRYPT_HEADER_WITHOUTPADDING || !thePrefs::IsServerCryptLayerUDPEnabled() || dwBaseKey == 0) {
391 return nResult;
394 if(pbyBufIn[0] == OP_EDONKEYPROT) {
395 return nResult; // no encrypted packet (see description on top)
398 // might be an encrypted packet, try to decrypt
399 uint8 achKeyData[7];
400 PokeUInt32(achKeyData, dwBaseKey);
401 achKeyData[4] = MAGICVALUE_UDP_SERVERCLIENT;
402 memcpy(achKeyData + 5, pbyBufIn + 1, 2); // random key part sent from remote server
404 CRC4EncryptableBuffer receivebuffer;
405 MD5Sum md5(achKeyData, sizeof(achKeyData));
406 receivebuffer.SetKey(md5,true);
408 uint32 dwValue;
409 receivebuffer.RC4Crypt(pbyBufIn + 3, (uint8*)&dwValue, sizeof(dwValue));
410 ENDIAN_SWAP_I_32(dwValue);
411 if (dwValue == MAGICVALUE_UDP_SYNC_SERVER){
412 // yup this is an encrypted packet
413 //DEBUG_ONLY( DebugLog(_T("Received obfuscated UDP packet from ServerIP: %s"), ipstr(dbgIP)) );
414 uint8 byPadLen;
415 receivebuffer.RC4Crypt(pbyBufIn + 7, (uint8*)&byPadLen, 1);
416 byPadLen &= 15;
417 nResult -= CRYPT_HEADER_WITHOUTPADDING;
419 if (nResult <= byPadLen){
420 //DebugLogError(_T("Invalid obfuscated UDP packet from ServerIP: %s, Paddingsize (%u) larger than received bytes"), ipstr(dbgIP), byPadLen);
421 return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
424 if (byPadLen > 0) {
425 receivebuffer.RC4Crypt(NULL, NULL, byPadLen);
428 nResult -= byPadLen;
429 *ppbyBufOut = pbyBufIn + (nBufLen - nResult);
430 receivebuffer.RC4Crypt((uint8*)*ppbyBufOut, (uint8*)*ppbyBufOut, nResult);
432 theStats::AddDownOverheadCrypt(nBufLen - nResult);
433 return nResult; // done
434 } else {
435 //DebugLogWarning(_T("Obfuscated packet expected but magicvalue mismatch on UDP packet from ServerIP: %s"), ipstr(dbgIP));
436 return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
440 int CEncryptedDatagramSocket::EncryptSendServer(uint8** ppbyBuf, int nBufLen, uint32 dwBaseKey) {
441 wxASSERT( thePrefs::IsServerCryptLayerUDPEnabled() );
442 wxASSERT( dwBaseKey != 0 );
444 uint16 nRandomKeyPart = GetRandomUint16();
446 uint8 achKeyData[7];
447 PokeUInt32(achKeyData, dwBaseKey);
448 achKeyData[4] = MAGICVALUE_UDP_CLIENTSERVER;
449 PokeUInt16(achKeyData + 5, nRandomKeyPart);
450 MD5Sum md5(achKeyData, sizeof(achKeyData));
451 CRC4EncryptableBuffer sendbuffer;
452 sendbuffer.SetKey(md5, true);
454 // create the semi random byte encryption header
455 uint8 bySemiRandomNotProtocolMarker = 0;
456 int i;
458 for (i = 0; i < 128; i++){
459 bySemiRandomNotProtocolMarker = GetRandomUint8();
460 if (bySemiRandomNotProtocolMarker != OP_EDONKEYPROT) { // not allowed values
461 break;
465 if (i >= 128){
466 // either we have _real_ bad luck or the randomgenerator is a bit messed up
467 wxFAIL;
468 bySemiRandomNotProtocolMarker = 0x01;
471 uint8 byPadLen = 0; // padding disabled for UDP currently
472 uint32 nCryptedLen = nBufLen + byPadLen + CRYPT_HEADER_WITHOUTPADDING;
473 uint8* pachCryptedBuffer = new uint8[nCryptedLen];
475 pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker;
476 PokeUInt16(pachCryptedBuffer + 1, nRandomKeyPart);
478 uint32 dwMagicValue = ENDIAN_SWAP_32(MAGICVALUE_UDP_SYNC_SERVER);
479 sendbuffer.RC4Crypt((uint8*)&dwMagicValue, pachCryptedBuffer + 3, 4);
481 sendbuffer.RC4Crypt((uint8*)&byPadLen, pachCryptedBuffer + 7, 1);
483 for (int j = 0; j < byPadLen; j++){
484 uint8 byRand = (uint8)rand(); // they actually dont really need to be random, but it doesn't hurts either
485 sendbuffer.RC4Crypt((uint8*)&byRand, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + j, 1);
487 sendbuffer.RC4Crypt(*ppbyBuf, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen, nBufLen);
488 delete[] *ppbyBuf;
489 *ppbyBuf = pachCryptedBuffer;
491 theStats::AddUpOverheadCrypt(nCryptedLen - nBufLen);
492 return nCryptedLen;