clean crypto and rc4

This commit is contained in:
Sky Johnson 2025-09-06 18:48:40 -05:00
parent 4feb3ef685
commit 53a84d3ca7
9 changed files with 204 additions and 206 deletions

View File

@ -21,7 +21,7 @@
#include "Mutex.h"
#include "opcodemgr.h"
#include "misc.h"
#include "crypto/Crypto.h"
#include "crypto/crypto.h"
#include "zlib.h"
#include "timer.h"

View File

@ -1,30 +0,0 @@
// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#include "Crypto.h"
#include <iostream>
#include "../common/packet_dump.h"
using namespace std;
void test();
int64 Crypto::RSADecrypt(uchar* text, int16 size){
int64 ret = 0;
uchar* buffer = new uchar[8];
for(int i=7;i>=0;i--)
buffer[7-i] = text[i];
memcpy(&ret, buffer, 8);
safe_delete_array(buffer);
return ret;
}
void Crypto::RC4Decrypt(uchar* text, int32 size){
MCrypto.lock();
client->Cypher(text, size);
MCrypto.unlock();
}
void Crypto::RC4Encrypt(uchar* text, int32 size){
MCrypto.lock();
server->Cypher(text, size);
MCrypto.unlock();
}

View File

@ -1,49 +0,0 @@
// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#ifndef _CRYPTO_H
#define _CRYPTO_H
#include <string>
#include <mutex>
#include "RC4.h"
#include "../common/types.h"
using namespace std;
class Crypto {
public:
~Crypto(){ safe_delete(client); safe_delete(server); }
Crypto() { rc4_key = 0; encrypted = false; client = 0; server = 0; };
static int64 RSADecrypt(uchar* text, int16 size);
void RC4Encrypt(uchar* text, int32 size);
void RC4Decrypt(uchar* text, int32 size);
int64 getRC4Key() { return rc4_key; }
void setRC4Key(int64 key) {
rc4_key = key;
if(key > 0){
encrypted = true;
client = new RC4(~key);
server = new RC4(key);
uchar temp[20];
client->Cypher(temp, 20);
server->Cypher(temp, 20);
}
else{
encrypted = false;
safe_delete(client);
safe_delete(server);
}
}
bool isEncrypted(){ return encrypted; }
void setEncrypted(bool in_val){ encrypted = in_val; }
private:
RC4* server;
RC4* client;
bool encrypted;
int64 rc4_key;
mutex MCrypto;
};
#endif

View File

@ -1,76 +0,0 @@
// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#include "RC4.h"
#include <string.h>
static bool g_bInitStateInitialized = false;
static uchar g_byInitState[256];
RC4::RC4(int64 nKey)
{
if( !g_bInitStateInitialized )
{
for(int16 i = 0; i < 256; i++ )
g_byInitState[i] = i;
}
Init(nKey);
}
RC4::~RC4()
{
}
void RC4::Init(int64 nKey)
{
memcpy(m_state, g_byInitState, 256);
m_x = 0;
m_y = 0;
ulong dwKeyIndex = 0;
ulong dwStateIndex = 0;
uchar* pKey = (uchar*)&nKey;
for(int16 i = 0; i < 256; i++ )
{
ulong dwTemp = m_state[i];
dwStateIndex += pKey[dwKeyIndex] + dwTemp;
dwStateIndex &= 0xFF;
m_state[i] = m_state[dwStateIndex];
m_state[dwStateIndex] = (uchar)dwTemp;
dwKeyIndex++;
dwKeyIndex &= 7;
}
}
// A = m_state[X + 1]
// B = m_state[Y + A]
// C ^= m_state[(A + B)]
// X = 20
// Y = ?
// C = 0
// m_state[(A + B)] = Cypher Byte
void RC4::Cypher(uchar* pBuffer, int32 nLength)
{
int32 nOffset = 0;
uchar byKey1 = m_x;
uchar byKey2 = m_y;
if( nLength > 0 )
{
do
{
byKey1++;
uchar byKeyVal1 = m_state[byKey1];
byKey2 += byKeyVal1;
uchar byKeyVal2 = m_state[byKey2];
m_state[byKey1] = byKeyVal2;
m_state[byKey2] = byKeyVal1;
pBuffer[nOffset++] ^= m_state[(byKeyVal1 + byKeyVal2) & 0xFF];
} while( nOffset < nLength );
}
m_x = byKey1;
m_y = byKey2;
}

View File

@ -1,21 +0,0 @@
// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#ifndef _EQ2_RC4_H
#define _EQ2_RC4_H
#include "../common/types.h"
class RC4
{
public:
RC4(int64 nKey);
~RC4();
void Init(int64 nKey);
void Cypher(uchar* pData, int32 nLen);
private:
uchar m_state[256];
uchar m_x;
uchar m_y;
};
#endif

View File

@ -0,0 +1,53 @@
// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#include "crypto.h"
#include <algorithm>
#include <array>
#include <cstring>
#include <mutex>
int64 Crypto::RSADecrypt(uchar* text, int16 size) noexcept
{
int64 ret = 0;
std::array<uchar, 8> buffer{};
for (int i = 7; i >= 0; --i) {
buffer[7 - i] = text[i];
}
std::memcpy(&ret, buffer.data(), 8);
return ret;
}
void Crypto::RC4Decrypt(uchar* text, int32 size) noexcept
{
const std::lock_guard<std::mutex> lock(m_crypto_mutex);
client->Cypher(text, size);
}
void Crypto::RC4Encrypt(uchar* text, int32 size) noexcept
{
const std::lock_guard<std::mutex> lock(m_crypto_mutex);
server->Cypher(text, size);
}
void Crypto::setRC4Key(int64 key) noexcept
{
rc4_key = key;
if (key > 0) {
encrypted = true;
client = std::make_unique<RC4>(~key);
server = std::make_unique<RC4>(key);
std::array<uchar, 20> temp{};
client->Cypher(temp.data(), 20);
server->Cypher(temp.data(), 20);
} else {
encrypted = false;
client.reset();
server.reset();
}
}

View File

@ -0,0 +1,35 @@
// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#pragma once
#include <memory>
#include <mutex>
#include <array>
#include "rc4.h"
#include "../types.h"
class Crypto
{
public:
Crypto() noexcept = default;
~Crypto() = default;
static int64 RSADecrypt(uchar* text, int16 size) noexcept;
void RC4Encrypt(uchar* text, int32 size) noexcept;
void RC4Decrypt(uchar* text, int32 size) noexcept;
[[nodiscard]] int64 getRC4Key() const noexcept { return rc4_key; }
void setRC4Key(int64 key) noexcept;
[[nodiscard]] bool isEncrypted() const noexcept { return encrypted; }
void setEncrypted(bool in_val) noexcept { encrypted = in_val; }
private:
std::unique_ptr<RC4> server{};
std::unique_ptr<RC4> client{};
bool encrypted{false};
int64 rc4_key{0};
std::mutex m_crypto_mutex{};
};

View File

@ -0,0 +1,64 @@
// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#include "rc4.h"
#include <algorithm>
#include <cstring>
#include <numeric>
static constexpr std::array<uchar, 256> get_init_state() noexcept
{
std::array<uchar, 256> state{};
std::iota(state.begin(), state.end(), 0);
return state;
}
static const auto g_init_state = get_init_state();
RC4::RC4(int64 key) noexcept
{
Init(key);
}
void RC4::Init(int64 key) noexcept
{
m_state = g_init_state;
m_x = 0;
m_y = 0;
ulong key_index = 0;
ulong state_index = 0;
const auto* key_ptr = reinterpret_cast<const uchar*>(&key);
for (int16 i = 0; i < 256; ++i) {
const ulong temp = m_state[i];
state_index += key_ptr[key_index] + temp;
state_index &= 0xFF;
m_state[i] = m_state[state_index];
m_state[state_index] = static_cast<uchar>(temp);
key_index++;
key_index &= 7;
}
}
void RC4::Cypher(uchar* data, int32 length) noexcept
{
uchar key1 = m_x;
uchar key2 = m_y;
for (int32 i = 0; i < length; ++i) {
++key1;
const uchar key_val1 = m_state[key1];
key2 += key_val1;
const uchar key_val2 = m_state[key2];
m_state[key1] = key_val2;
m_state[key2] = key_val1;
data[i] ^= m_state[(key_val1 + key_val2) & 0xFF];
}
m_x = key1;
m_y = key2;
}

View File

@ -0,0 +1,22 @@
// Copyright (C) 2007-2025 EQ2EMulator
// Licensed under GPL v3
#pragma once
#include "../types.h"
#include <array>
class RC4
{
public:
explicit RC4(int64 key) noexcept;
~RC4() = default;
void Init(int64 key) noexcept;
void Cypher(uchar* data, int32 length) noexcept;
private:
std::array<uchar, 256> m_state{};
uchar m_x{};
uchar m_y{};
};