Upstream tarball 20080418
[amule.git] / src / RC4Encrypt.cpp
blobcf897ba5207acc2a1f3d40adfa82b1b874614d9e
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 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
27 #include "RC4Encrypt.h"
28 #include <common/MD5Sum.h>
30 #include <stdexcept>
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);
44 if (!m_encrypted) {
45 CMemFile::Append(buffer, n);
46 } else {
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.
58 int n = GetLength();
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: "));
64 m_encrypted = true;
67 void CRC4EncryptableBuffer::RC4Crypt( const uint8 *pachIn, uint8 *pachOut, uint32 nLen)
69 wxASSERT( m_hasKey && nLen > 0 );
71 if (m_hasKey) {
72 uint8 byX = m_key.byX;;
73 uint8 byY = m_key.byY;
74 uint8* pabyState = &m_key.abyState[0];;
75 uint8 byXorIndex;
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;
83 if (pachIn != NULL) {
84 pachOut[i] = pachIn[i] ^ pabyState[byXorIndex];
88 m_key.byX = byX;
89 m_key.byY = byY;
90 } else {
91 throw std::runtime_error(
92 "(CRC4EncryptableBuffer::RC4Crypt): "
93 "Encrypt() has been called without a previous call"
94 "to SetKey().");
98 uint8 *CRC4EncryptableBuffer::Detach()
100 int n = GetLength();
101 uint8 *ret = new uint8[n];
102 memcpy(ret, GetRawBuffer(), n);
103 ResetData();
104 m_encrypted = false;
105 return ret;
109 void CRC4EncryptableBuffer::SetKey(const MD5Sum& keyhash, bool bSkipDiscard)
111 wxASSERT(!m_hasKey);
112 if (!m_hasKey) {
113 m_hasKey = true;
114 RC4CreateKey( keyhash.GetRawHash(), 16, bSkipDiscard);
115 } else {
116 throw std::runtime_error( "(CRC4EncryptableBuffer::SetKey): SetKey() has been called twice.");
121 void CRC4EncryptableBuffer::RC4CreateKey(const uint8* pachKeyData, uint32 nLen, bool bSkipDiscard)
123 uint8 index1;
124 uint8 index2;
125 uint8* pabyState;
127 pabyState= &m_key.abyState[0];
128 for (int i = 0; i < 256; ++i) {
129 pabyState[i] = (uint8)i;
132 m_key.byX = 0;
133 m_key.byY = 0;
134 index1 = 0;
135 index2 = 0;
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);
143 if (!bSkipDiscard) {
144 RC4Crypt(NULL, NULL, 1024);
148 void CRC4EncryptableBuffer::ResetData()
150 m_encrypted = false;
151 // Should we clear the keys?
152 CMemFile::ResetData();