aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2019-07-12 20:42:49 +0200
committerShauren <shauren.trinity@gmail.com>2019-07-14 19:20:45 +0200
commit74a801182a39358d62b596642c82c5f6c6e242e9 (patch)
tree1cbc1428e87cb63618fb1edd4d87d945797032af /src/common
parent0e4c5697704359f648be4eab52eeb739528eb9d2 (diff)
Core/PacketIO: Updated packet encryption to 8.2
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Cryptography/AES.cpp55
-rw-r--r--src/common/Cryptography/AES.h (renamed from src/common/Cryptography/Authentication/PacketCrypt.cpp)35
-rw-r--r--src/common/Cryptography/Authentication/PacketCrypt.h43
-rw-r--r--src/common/Cryptography/Authentication/WorldPacketCrypt.cpp59
-rw-r--r--src/common/Cryptography/Authentication/WorldPacketCrypt.h22
-rw-r--r--src/common/Cryptography/RSA.cpp2
6 files changed, 127 insertions, 89 deletions
diff --git a/src/common/Cryptography/AES.cpp b/src/common/Cryptography/AES.cpp
new file mode 100644
index 00000000000..cd9ff29f79f
--- /dev/null
+++ b/src/common/Cryptography/AES.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008-2019 TrinityCore <https://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AES.h"
+
+Trinity::Crypto::AES::AES(bool encrypting) : _ctx(EVP_CIPHER_CTX_new())
+{
+ EVP_CIPHER_CTX_init(_ctx);
+ EVP_CipherInit_ex(_ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr, encrypting ? 1 : 0);
+}
+
+Trinity::Crypto::AES::~AES()
+{
+ EVP_CIPHER_CTX_free(_ctx);
+}
+
+void Trinity::Crypto::AES::Init(uint8 const* key)
+{
+ EVP_CipherInit_ex(_ctx, nullptr, nullptr, key, nullptr, -1);
+}
+
+bool Trinity::Crypto::AES::Process(uint8 const* iv, uint8* data, std::size_t length, uint8* tag)
+{
+ if (!EVP_CipherInit_ex(_ctx, nullptr, nullptr, nullptr, iv, -1))
+ return false;
+
+ int outLen;
+ if (!EVP_CipherUpdate(_ctx, data, &outLen, data, length))
+ return false;
+
+ if (!EVP_CIPHER_CTX_encrypting(_ctx) && !EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_SET_TAG, 12, tag))
+ return false;
+
+ if (!EVP_CipherFinal_ex(_ctx, data + outLen, &outLen))
+ return false;
+
+ if (EVP_CIPHER_CTX_encrypting(_ctx) && !EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_GET_TAG, 12, tag))
+ return false;
+
+ return true;
+}
diff --git a/src/common/Cryptography/Authentication/PacketCrypt.cpp b/src/common/Cryptography/AES.h
index 3d5a565a9e7..edb096ae69e 100644
--- a/src/common/Cryptography/Authentication/PacketCrypt.cpp
+++ b/src/common/Cryptography/AES.h
@@ -15,25 +15,30 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "PacketCrypt.h"
+#ifndef Trinity_AES_h__
+#define Trinity_AES_h__
-PacketCrypt::PacketCrypt(uint32 rc4InitSize)
- : _clientDecrypt(rc4InitSize), _serverEncrypt(rc4InitSize), _initialized(false)
-{
-}
+#include "Define.h"
+#include <openssl/evp.h>
-void PacketCrypt::DecryptRecv(uint8* data, size_t len)
+namespace Trinity
+{
+namespace Crypto
+{
+class TC_COMMON_API AES
{
- if (!_initialized)
- return;
+public:
+ AES(bool encrypting);
+ ~AES();
- _clientDecrypt.UpdateData(len, data);
-}
+ void Init(uint8 const* key);
-void PacketCrypt::EncryptSend(uint8* data, size_t len)
-{
- if (!_initialized)
- return;
+ bool Process(uint8 const* iv, uint8* data, std::size_t length, uint8* tag);
- _serverEncrypt.UpdateData(len, data);
+private:
+ EVP_CIPHER_CTX* _ctx;
+};
}
+}
+
+#endif // Trinity_AES_h__
diff --git a/src/common/Cryptography/Authentication/PacketCrypt.h b/src/common/Cryptography/Authentication/PacketCrypt.h
deleted file mode 100644
index d1e891f5ce0..00000000000
--- a/src/common/Cryptography/Authentication/PacketCrypt.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008-2019 TrinityCore <https://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _PACKETCRYPT_H
-#define _PACKETCRYPT_H
-
-#include "Cryptography/ARC4.h"
-
-class BigNumber;
-
-class TC_COMMON_API PacketCrypt
-{
- public:
- PacketCrypt(uint32 rc4InitSize);
- virtual ~PacketCrypt() { }
-
- virtual void Init(BigNumber* K) = 0;
- void DecryptRecv(uint8* data, size_t length);
- void EncryptSend(uint8* data, size_t length);
-
- bool IsInitialized() const { return _initialized; }
-
- protected:
- ARC4 _clientDecrypt;
- ARC4 _serverEncrypt;
- bool _initialized;
-};
-
-#endif // _PACKETCRYPT_H
diff --git a/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp b/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp
index 04ee142cb40..af1ac4cfdc6 100644
--- a/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp
+++ b/src/common/Cryptography/Authentication/WorldPacketCrypt.cpp
@@ -17,42 +17,53 @@
*/
#include "WorldPacketCrypt.h"
-#include "Cryptography/HmacHash.h"
-#include "Cryptography/BigNumber.h"
-
+#include <array>
#include <cstring>
-WorldPacketCrypt::WorldPacketCrypt() : PacketCrypt(SHA_DIGEST_LENGTH)
+WorldPacketCrypt::WorldPacketCrypt() : _clientDecrypt(false), _serverEncrypt(true), _clientCounter(0), _serverCounter(0), _initialized(false)
{
}
-void WorldPacketCrypt::Init(BigNumber* K)
+void WorldPacketCrypt::Init(uint8 const* key)
{
- uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0x08, 0xF1, 0x95, 0x9F, 0x47, 0xE5, 0xD2, 0xDB, 0xA1, 0x3D, 0x77, 0x8F, 0x3F, 0x3E, 0xE7, 0x00 };
- uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0x40, 0xAA, 0xD3, 0x92, 0x26, 0x71, 0x43, 0x47, 0x3A, 0x31, 0x08, 0xA6, 0xE7, 0xDC, 0x98, 0x2A };
- Init(K, ServerEncryptionKey, ServerDecryptionKey);
+ _clientDecrypt.Init(key);
+ _serverEncrypt.Init(key);
+ _initialized = true;
}
-void WorldPacketCrypt::Init(BigNumber* k, uint8 const* serverKey, uint8 const* clientKey)
+struct WorldPacketCryptIV
{
- HmacSha1 serverEncryptHmac(SEED_KEY_SIZE, (uint8*)serverKey);
- uint8 *encryptHash = serverEncryptHmac.ComputeHash(k);
-
- HmacSha1 clientDecryptHmac(SEED_KEY_SIZE, (uint8*)clientKey);
- uint8 *decryptHash = clientDecryptHmac.ComputeHash(k);
-
- _clientDecrypt.Init(decryptHash);
- _serverEncrypt.Init(encryptHash);
+ WorldPacketCryptIV(uint64 counter, uint32 magic)
+ {
+ memcpy(Value.data(), &counter, sizeof(uint64));
+ memcpy(Value.data() + sizeof(uint64), &magic, sizeof(uint32));
+ }
- // Drop first 1024 bytes, as WoW uses ARC4-drop1024.
- uint8 syncBuf[1024];
- memset(syncBuf, 0, 1024);
+ std::array<uint8, 12> Value;
+};
- _serverEncrypt.UpdateData(1024, syncBuf);
+bool WorldPacketCrypt::DecryptRecv(uint8* data, size_t len, uint8* tag)
+{
+ if (_initialized)
+ {
+ WorldPacketCryptIV iv{ _clientCounter, 0x544E4C43 };
+ if (!_clientDecrypt.Process(iv.Value.data(), data, len, tag))
+ return false;
+ }
- memset(syncBuf, 0, 1024);
+ ++_clientCounter;
+ return true;
+}
- _clientDecrypt.UpdateData(1024, syncBuf);
+bool WorldPacketCrypt::EncryptSend(uint8* data, size_t len, uint8* tag)
+{
+ if (_initialized)
+ {
+ WorldPacketCryptIV iv{ _serverCounter, 0x52565253 };
+ if (!_serverEncrypt.Process(iv.Value.data(), data, len, tag))
+ return false;
+ }
- _initialized = true;
+ ++_serverCounter;
+ return true;
}
diff --git a/src/common/Cryptography/Authentication/WorldPacketCrypt.h b/src/common/Cryptography/Authentication/WorldPacketCrypt.h
index acb403a026e..155d741fdea 100644
--- a/src/common/Cryptography/Authentication/WorldPacketCrypt.h
+++ b/src/common/Cryptography/Authentication/WorldPacketCrypt.h
@@ -19,17 +19,27 @@
#ifndef _WORLDPACKETCRYPT_H
#define _WORLDPACKETCRYPT_H
-#include "PacketCrypt.h"
+#include "Cryptography/AES.h"
class BigNumber;
-class TC_COMMON_API WorldPacketCrypt : public PacketCrypt
+class TC_COMMON_API WorldPacketCrypt
{
- public:
- WorldPacketCrypt();
+public:
+ WorldPacketCrypt();
- void Init(BigNumber* K) override;
- void Init(BigNumber* k, uint8 const* serverKey, uint8 const* clientKey);
+ void Init(uint8 const* key);
+ bool DecryptRecv(uint8* data, size_t length, uint8* tag);
+ bool EncryptSend(uint8* data, size_t length, uint8* tag);
+
+ bool IsInitialized() const { return _initialized; }
+
+protected:
+ Trinity::Crypto::AES _clientDecrypt;
+ Trinity::Crypto::AES _serverEncrypt;
+ uint64 _clientCounter;
+ uint64 _serverCounter;
+ bool _initialized;
};
#endif // _WORLDPACKETCRYPT_H
diff --git a/src/common/Cryptography/RSA.cpp b/src/common/Cryptography/RSA.cpp
index 3885e17d71c..97a406f690c 100644
--- a/src/common/Cryptography/RSA.cpp
+++ b/src/common/Cryptography/RSA.cpp
@@ -117,7 +117,7 @@ bool Trinity::Crypto::RSA::Sign(int32 hashType, uint8 const* dataHash, std::size
uint32 signatureLength = 0;
int result = RSA_sign(hashType, dataHash, dataHashLength, output, &signatureLength, _rsa);
std::reverse(output, output + GetOutputSize());
- return result != -1;
+ return result != 0;
}
namespace Trinity