2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
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
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.
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
27 #include "RC4Encrypt.h"
28 #include <common/MD5Sum.h>
32 CRC4EncryptableBuffer::CRC4EncryptableBuffer() : m_encrypted(false), m_hasKey(false), m_key()
37 CRC4EncryptableBuffer::~CRC4EncryptableBuffer()
41 void CRC4EncryptableBuffer::Append(const uint8
* buffer
, int n
)
43 wxASSERT(!m_encrypted
);
45 CMemFile::Append(buffer
, n
);
47 throw std::runtime_error(
48 "(CRC4EncryptableBuffer::Append): "
49 "Tryed to append data to an encrypted buffer.");
54 void CRC4EncryptableBuffer::Encrypt()
56 wxASSERT(!m_encrypted
);
57 // This is not optimal. At all.
59 std::vector
<byte
> orig_buffer(n
);
60 memcpy(&(orig_buffer
[0]), GetRawBuffer(), n
);
61 RC4Crypt(&(orig_buffer
[0]), GetRawBuffer(), n
);
62 //DumpMem(orig_buffer, n, wxT("Orig buffer: "));
63 //DumpMem(GetRawBuffer() ,n, wxT("Encrypted buffer: "));
67 void CRC4EncryptableBuffer::RC4Crypt( const uint8
*pachIn
, uint8
*pachOut
, uint32 nLen
)
69 wxASSERT( m_hasKey
&& nLen
> 0 );
72 uint8 byX
= m_key
.byX
;;
73 uint8 byY
= m_key
.byY
;
74 uint8
* pabyState
= &m_key
.abyState
[0];;
77 for (uint32 i
= 0; i
< nLen
; ++i
) {
78 byX
= (byX
+ 1) % 256;
79 byY
= (pabyState
[byX
] + byY
) % 256;
80 std::swap(pabyState
[byX
], pabyState
[byY
]);
81 byXorIndex
= (pabyState
[byX
] + pabyState
[byY
]) % 256;
84 pachOut
[i
] = pachIn
[i
] ^ pabyState
[byXorIndex
];
91 throw std::runtime_error(
92 "(CRC4EncryptableBuffer::RC4Crypt): "
93 "Encrypt() has been called without a previous call"
98 uint8
*CRC4EncryptableBuffer::Detach()
101 uint8
*ret
= new uint8
[n
];
102 memcpy(ret
, GetRawBuffer(), n
);
109 void CRC4EncryptableBuffer::SetKey(const MD5Sum
& keyhash
, bool bSkipDiscard
)
114 RC4CreateKey( keyhash
.GetRawHash(), 16, bSkipDiscard
);
116 throw std::runtime_error( "(CRC4EncryptableBuffer::SetKey): SetKey() has been called twice.");
121 void CRC4EncryptableBuffer::RC4CreateKey(const uint8
* pachKeyData
, uint32 nLen
, bool bSkipDiscard
)
127 pabyState
= &m_key
.abyState
[0];
128 for (int i
= 0; i
< 256; ++i
) {
129 pabyState
[i
] = (uint8
)i
;
137 for (int i
= 0; i
< 256; ++i
) {
138 index2
= (pachKeyData
[index1
] + pabyState
[i
] + index2
) % 256;
139 std::swap(pabyState
[i
], pabyState
[index2
]);
140 index1
= (uint8
)((index1
+ 1) % nLen
);
144 RC4Crypt(NULL
, NULL
, 1024);
148 void CRC4EncryptableBuffer::ResetData()
151 // Should we clear the keys?
152 CMemFile::ResetData();