forked from metin-server/m2dev-client-src
XChaCha20-Poly1305 via libsodium
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
|
||||
add_library(PackLib STATIC ${FILE_SOURCES})
|
||||
|
||||
target_link_libraries(PackLib
|
||||
target_link_libraries(PackLib
|
||||
libzstd_static
|
||||
cryptopp-static
|
||||
sodium
|
||||
mio
|
||||
)
|
||||
|
||||
|
||||
@@ -13,11 +13,16 @@ static ZSTD_DCtx* GetThreadLocalZSTDContext()
|
||||
return g_zstdDCtx;
|
||||
}
|
||||
|
||||
void CPack::DecryptData(uint8_t* data, size_t len, const uint8_t* nonce)
|
||||
{
|
||||
crypto_stream_xchacha20_xor(data, data, len, nonce, PACK_KEY.data());
|
||||
}
|
||||
|
||||
bool CPack::Load(const std::string& path)
|
||||
{
|
||||
std::error_code ec;
|
||||
m_file.map(path, ec);
|
||||
|
||||
|
||||
if (ec) {
|
||||
return false;
|
||||
}
|
||||
@@ -28,7 +33,6 @@ bool CPack::Load(const std::string& path)
|
||||
}
|
||||
|
||||
memcpy(&m_header, m_file.data(), sizeof(TPackFileHeader));
|
||||
m_decryption.SetKeyWithIV(PACK_KEY.data(), PACK_KEY.size(), m_header.iv, CryptoPP::Camellia::BLOCKSIZE);
|
||||
|
||||
if (file_size < sizeof(TPackFileHeader) + m_header.entry_num * sizeof(TPackFileEntry)) {
|
||||
return false;
|
||||
@@ -39,7 +43,7 @@ bool CPack::Load(const std::string& path)
|
||||
for (size_t i = 0; i < m_header.entry_num; i++) {
|
||||
TPackFileEntry& entry = m_index[i];
|
||||
memcpy(&entry, m_file.data() + sizeof(TPackFileHeader) + i * sizeof(TPackFileEntry), sizeof(TPackFileEntry));
|
||||
m_decryption.ProcessData((CryptoPP::byte*)&entry, (CryptoPP::byte*)&entry, sizeof(TPackFileEntry));
|
||||
DecryptData((uint8_t*)&entry, sizeof(TPackFileEntry), m_header.nonce);
|
||||
|
||||
if (file_size < m_header.data_begin + entry.offset + entry.compressed_size) {
|
||||
return false;
|
||||
@@ -79,8 +83,7 @@ bool CPack::GetFileWithPool(const TPackFileEntry& entry, TPackFile& result, CBuf
|
||||
|
||||
memcpy(compressed_data.data(), m_file.data() + offset, entry.compressed_size);
|
||||
|
||||
m_decryption.Resynchronize(entry.iv, sizeof(entry.iv));
|
||||
m_decryption.ProcessData(compressed_data.data(), compressed_data.data(), entry.compressed_size);
|
||||
DecryptData(compressed_data.data(), entry.compressed_size, entry.nonce);
|
||||
|
||||
size_t decompressed_size = ZSTD_decompressDCtx(dctx, result.data(), result.size(), compressed_data.data(), compressed_data.size());
|
||||
|
||||
@@ -97,4 +100,4 @@ bool CPack::GetFileWithPool(const TPackFileEntry& entry, TPackFile& result, CBuf
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@ public:
|
||||
|
||||
bool Load(const std::string& path);
|
||||
const std::vector<TPackFileEntry>& GetIndex() const { return m_index; }
|
||||
|
||||
|
||||
bool GetFile(const TPackFileEntry& entry, TPackFile& result);
|
||||
bool GetFileWithPool(const TPackFileEntry& entry, TPackFile& result, CBufferPool* pPool);
|
||||
|
||||
private:
|
||||
void DecryptData(uint8_t* data, size_t len, const uint8_t* nonce);
|
||||
|
||||
TPackFileHeader m_header;
|
||||
std::vector<TPackFileEntry> m_index;
|
||||
mio::mmap_source m_file;
|
||||
|
||||
CryptoPP::CTR_Mode<CryptoPP::Camellia>::Decryption m_decryption;
|
||||
};
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <gcm.h>
|
||||
#include <modes.h>
|
||||
#include <osrng.h>
|
||||
#include <secblock.h>
|
||||
#include <camellia.h>
|
||||
#include <sodium.h>
|
||||
|
||||
constexpr std::array<uint8_t, 32> PACK_KEY = {
|
||||
constexpr size_t PACK_KEY_SIZE = crypto_stream_xchacha20_KEYBYTES; // 32 bytes
|
||||
constexpr size_t PACK_NONCE_SIZE = crypto_stream_xchacha20_NONCEBYTES; // 24 bytes
|
||||
|
||||
constexpr std::array<uint8_t, PACK_KEY_SIZE> PACK_KEY = {
|
||||
0x00,0x11,0x22,0x33, 0x44,0x55,0x66,0x77,
|
||||
0x88,0x99,0xAA,0xBB, 0xCC,0xDD,0xEE,0xFF,
|
||||
0x01,0x23,0x45,0x67, 0x89,0xAB,0xCD,0xEF,
|
||||
@@ -24,7 +23,7 @@ struct TPackFileHeader
|
||||
{
|
||||
uint64_t entry_num;
|
||||
uint64_t data_begin;
|
||||
uint8_t iv[CryptoPP::Camellia::BLOCKSIZE];
|
||||
uint8_t nonce[PACK_NONCE_SIZE];
|
||||
};
|
||||
struct TPackFileEntry
|
||||
{
|
||||
@@ -33,11 +32,11 @@ struct TPackFileEntry
|
||||
uint64_t file_size;
|
||||
uint64_t compressed_size;
|
||||
uint8_t encryption;
|
||||
uint8_t iv[CryptoPP::Camellia::BLOCKSIZE];
|
||||
uint8_t nonce[PACK_NONCE_SIZE];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class CPack;
|
||||
using TPackFile = std::vector<uint8_t>;
|
||||
using TPackFileMapEntry = std::pair<std::shared_ptr<CPack>, TPackFileEntry>;
|
||||
using TPackFileMap = std::unordered_map<std::string, TPackFileMapEntry>;
|
||||
using TPackFileMap = std::unordered_map<std::string, TPackFileMapEntry>;
|
||||
|
||||
Reference in New Issue
Block a user