1// 2// This file is part of the aMule Project. 3// 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 ) 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. 10// 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. 15// 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 24// 25 26 27#include "RC4Encrypt.h" 28#include <common/MD5Sum.h> 29 30 31#include <stdexcept> 32 33CRC4EncryptableBuffer::CRC4EncryptableBuffer() : m_encrypted(false), m_hasKey(false), m_key() 34{ 35} 36 37 38CRC4EncryptableBuffer::~CRC4EncryptableBuffer() 39{ 40} 41 42void CRC4EncryptableBuffer::Append(const uint8* buffer, int n) 43{ 44 wxASSERT(!m_encrypted); 45 if (!m_encrypted) { 46 CMemFile::Append(buffer, n); 47 } else { 48 throw std::runtime_error( 49 "(CRC4EncryptableBuffer::Append): " 50 "Tryed to append data to an encrypted buffer."); 51 } 52} 53 54 55void CRC4EncryptableBuffer::Encrypt() 56{ 57 wxASSERT(!m_encrypted); 58 RC4Crypt(GetRawBuffer(), GetRawBuffer(), GetLength()); 59 m_encrypted = true; 60} 61 62void CRC4EncryptableBuffer::RC4Crypt( const uint8 *pachIn, uint8 *pachOut, uint32 nLen) 63{ 64 wxASSERT( m_hasKey && nLen > 0 ); 65 66 if (m_hasKey) { 67 uint8 byX = m_key.byX;; 68 uint8 byY = m_key.byY; 69 uint8* pabyState = &m_key.abyState[0];; 70 uint8 byXorIndex; 71 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; 77 78 if (pachIn != NULL) { 79 pachOut[i] = pachIn[i] ^ pabyState[byXorIndex]; 80 } 81 } 82 83 m_key.byX = byX; 84 m_key.byY = byY; 85 } else { 86 throw std::runtime_error( 87 "(CRC4EncryptableBuffer::RC4Crypt): " 88 "Encrypt() has been called without a previous call" 89 "to SetKey()."); 90 } 91} 92 93uint8 *CRC4EncryptableBuffer::Detach() 94{ 95 int n = GetLength(); 96 uint8 *ret = new uint8[n]; 97 memcpy(ret, GetRawBuffer(), n); 98 ResetData(); 99 m_encrypted = false; 100 return ret; 101} 102 103 104void CRC4EncryptableBuffer::SetKey(const MD5Sum& keyhash, bool bSkipDiscard) 105{ 106 wxASSERT(!m_hasKey); 107 if (!m_hasKey) { 108 m_hasKey = true; 109 RC4CreateKey( keyhash.GetRawHash(), 16, bSkipDiscard); 110 } else { 111 throw std::runtime_error( "(CRC4EncryptableBuffer::SetKey): SetKey() has been called twice."); 112 } 113} 114 115 116void CRC4EncryptableBuffer::RC4CreateKey(const uint8* pachKeyData, uint32 nLen, bool bSkipDiscard) 117{ 118 uint8 index1; 119 uint8 index2; 120 uint8* pabyState; 121 122 pabyState= &m_key.abyState[0]; 123 for (int i = 0; i < 256; ++i) { 124 pabyState[i] = (uint8)i; 125 } 126 127 m_key.byX = 0; 128 m_key.byY = 0; 129 index1 = 0; 130 index2 = 0; 131 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); 136 } 137 138 if (!bSkipDiscard) { 139 RC4Crypt(NULL, NULL, 1024); 140 } 141} 142 143void CRC4EncryptableBuffer::ResetData() 144{ 145 m_encrypted = false; 146 // Not touching the keys. 147 CMemFile::ResetData(); 148} 149 150void CRC4EncryptableBuffer::FullReset() 151{ 152 ResetData(); 153 m_hasKey = false; 154 memset(&m_key, 0, sizeof(RC4_Key_Struct)); 155} 156