2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 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>
33 CRC4EncryptableBuffer::CRC4EncryptableBuffer() : m_encrypted(false), m_hasKey(false), m_key()
38 CRC4EncryptableBuffer::~CRC4EncryptableBuffer()
42 void CRC4EncryptableBuffer::Append(const uint8
* buffer
, int n
)
44 wxASSERT(!m_encrypted
);
46 CMemFile::Append(buffer
, n
);
48 throw std::runtime_error(
49 "(CRC4EncryptableBuffer::Append): "
50 "Tryed to append data to an encrypted buffer.");
55 void CRC4EncryptableBuffer::Encrypt()
57 wxASSERT(!m_encrypted
);
58 RC4Crypt(GetRawBuffer(), GetRawBuffer(), GetLength());
62 void CRC4EncryptableBuffer::RC4Crypt( const uint8
*pachIn
, uint8
*pachOut
, uint32 nLen
)
64 wxASSERT( m_hasKey
&& nLen
> 0 );
67 uint8 byX
= m_key
.byX
;;
68 uint8 byY
= m_key
.byY
;
69 uint8
* pabyState
= &m_key
.abyState
[0];;
72 for (uint32 i
= 0; i
< nLen
; ++i
) {
73 byX
= (byX
+ 1) % 256;
74 byY
= (pabyState
[byX
] + byY
) % 256;
75 std::swap(pabyState
[byX
], pabyState
[byY
]);
76 byXorIndex
= (pabyState
[byX
] + pabyState
[byY
]) % 256;
79 pachOut
[i
] = pachIn
[i
] ^ pabyState
[byXorIndex
];
86 throw std::runtime_error(
87 "(CRC4EncryptableBuffer::RC4Crypt): "
88 "Encrypt() has been called without a previous call"
93 uint8
*CRC4EncryptableBuffer::Detach()
96 uint8
*ret
= new uint8
[n
];
97 memcpy(ret
, GetRawBuffer(), n
);
104 void CRC4EncryptableBuffer::SetKey(const MD5Sum
& keyhash
, bool bSkipDiscard
)
109 RC4CreateKey( keyhash
.GetRawHash(), 16, bSkipDiscard
);
111 throw std::runtime_error( "(CRC4EncryptableBuffer::SetKey): SetKey() has been called twice.");
116 void CRC4EncryptableBuffer::RC4CreateKey(const uint8
* pachKeyData
, uint32 nLen
, bool bSkipDiscard
)
122 pabyState
= &m_key
.abyState
[0];
123 for (int i
= 0; i
< 256; ++i
) {
124 pabyState
[i
] = (uint8
)i
;
132 for (int i
= 0; i
< 256; ++i
) {
133 index2
= (pachKeyData
[index1
] + pabyState
[i
] + index2
) % 256;
134 std::swap(pabyState
[i
], pabyState
[index2
]);
135 index1
= (uint8
)((index1
+ 1) % nLen
);
139 RC4Crypt(NULL
, NULL
, 1024);
143 void CRC4EncryptableBuffer::ResetData()
146 // Not touching the keys.
147 CMemFile::ResetData();
150 void CRC4EncryptableBuffer::FullReset()
154 memset(&m_key
, 0, sizeof(RC4_Key_Struct
));