Revert stream M2Pack archive support
Some checks are pending
build / Windows Build (push) Waiting to run

This commit is contained in:
server
2026-04-15 19:06:59 +02:00
parent 0b852faf0e
commit 49e8eac809
2 changed files with 65 additions and 168 deletions

View File

@@ -4,6 +4,7 @@
#include <chrono>
#include <cstring>
#include <zstd.h>
#include "EterBase/Debug.h"
@@ -37,44 +38,6 @@ bool ReadPod(const uint8_t* bytes, std::size_t size, std::size_t& offset, T& out
return true;
}
bool IsSupportedM2PackVersion(uint32_t version)
{
return version == M2PACK_VERSION_AEAD || version == M2PACK_VERSION_STREAM;
}
bool VerifyM2PackHash(
std::string_view stage,
const uint8_t* input,
std::size_t inputSize,
const std::array<uint8_t, M2PACK_HASH_SIZE>& expected,
const char* path)
{
std::array<uint8_t, M2PACK_HASH_SIZE> actual {};
const auto hashStart = std::chrono::steady_clock::now();
crypto_generichash(
actual.data(),
actual.size(),
input,
inputSize,
nullptr,
0);
RecordPackProfileStage(
"m2p",
stage,
inputSize,
actual.size(),
static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - hashStart).count()));
if (memcmp(actual.data(), expected.data(), actual.size()) != 0)
{
TraceError("CM2Pack: %s mismatch for '%s'", std::string(stage).c_str(), path);
return false;
}
return true;
}
}
bool CM2Pack::Load(const std::string& path)
@@ -103,7 +66,7 @@ bool CM2Pack::Load(const std::string& path)
return false;
}
if (!IsSupportedM2PackVersion(m_header.version))
if (m_header.version != 1)
{
TraceError("CM2Pack::Load: unsupported version %u in '%s'", m_header.version, path.c_str());
return false;
@@ -207,54 +170,26 @@ bool CM2Pack::ValidateManifest()
for (uint32_t i = 0; i < manifest_header.entry_count; ++i)
{
TM2PackManifestEntryFixed fixed {};
if (!ReadPod(m_manifest_bytes.data(), m_manifest_bytes.size(), offset, fixed))
{
return false;
}
if (offset + fixed.path_size > m_manifest_bytes.size())
{
return false;
}
TM2PackEntry entry;
uint16_t pathSize = 0;
if (m_header.version == M2PACK_VERSION_AEAD)
{
TM2PackManifestEntryFixed fixed {};
if (!ReadPod(m_manifest_bytes.data(), m_manifest_bytes.size(), offset, fixed))
{
return false;
}
pathSize = fixed.path_size;
entry.compression = fixed.compression;
entry.data_offset = fixed.data_offset;
entry.original_size = fixed.original_size;
entry.stored_size = fixed.stored_size;
memcpy(entry.nonce.data(), fixed.nonce, entry.nonce.size());
memcpy(entry.plaintext_hash.data(), fixed.plaintext_hash, entry.plaintext_hash.size());
}
else if (m_header.version == M2PACK_VERSION_STREAM)
{
TM2PackManifestEntryFixedV2 fixed {};
if (!ReadPod(m_manifest_bytes.data(), m_manifest_bytes.size(), offset, fixed))
{
return false;
}
pathSize = fixed.path_size;
entry.compression = fixed.compression;
entry.data_offset = fixed.data_offset;
entry.original_size = fixed.original_size;
entry.stored_size = fixed.stored_size;
memcpy(entry.nonce.data(), fixed.nonce, entry.nonce.size());
memcpy(entry.payload_hash.data(), fixed.payload_hash, entry.payload_hash.size());
memcpy(entry.plaintext_hash.data(), fixed.plaintext_hash, entry.plaintext_hash.size());
}
else
{
return false;
}
if (offset + pathSize > m_manifest_bytes.size())
{
return false;
}
entry.path.assign(reinterpret_cast<const char*>(m_manifest_bytes.data() + offset), pathSize);
offset += pathSize;
entry.path.assign(reinterpret_cast<const char*>(m_manifest_bytes.data() + offset), fixed.path_size);
offset += fixed.path_size;
entry.compression = fixed.compression;
entry.data_offset = fixed.data_offset;
entry.original_size = fixed.original_size;
entry.stored_size = fixed.stored_size;
memcpy(entry.nonce.data(), fixed.nonce, entry.nonce.size());
memcpy(entry.plaintext_hash.data(), fixed.plaintext_hash, entry.plaintext_hash.size());
const uint64_t payload_begin = sizeof(TM2PackHeader);
const uint64_t payload_end = m_header.manifest_offset;
@@ -296,66 +231,17 @@ bool CM2Pack::DecryptEntryPayload(const TM2PackEntry& entry, std::vector<uint8_t
}
decrypted.resize(entry.stored_size);
const auto decryptStart = std::chrono::steady_clock::now();
std::size_t written = entry.stored_size;
if (m_header.version == M2PACK_VERSION_AEAD)
{
unsigned long long aeadWritten = 0;
if (crypto_aead_xchacha20poly1305_ietf_decrypt(
decrypted.data(),
&aeadWritten,
nullptr,
ciphertext,
entry.stored_size,
reinterpret_cast<const unsigned char*>(entry.path.data()),
entry.path.size(),
entry.nonce.data(),
GetM2PackActiveMasterKey().data()) != 0)
{
if (pPool)
{
pPool->Release(std::move(decrypted));
}
return false;
}
written = static_cast<std::size_t>(aeadWritten);
RecordPackProfileStage(
"m2p",
"aead_decrypt",
entry.stored_size,
written,
static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - decryptStart).count()));
}
else if (m_header.version == M2PACK_VERSION_STREAM)
{
if (!decrypted.empty())
{
crypto_stream_xchacha20_xor(
decrypted.data(),
ciphertext,
entry.stored_size,
entry.nonce.data(),
GetM2PackActiveMasterKey().data());
}
RecordPackProfileStage(
"m2p",
"stream_decrypt",
entry.stored_size,
written,
static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - decryptStart).count()));
if (!VerifyM2PackHash("payload_hash", decrypted.data(), decrypted.size(), entry.payload_hash, entry.path.c_str()))
{
if (pPool)
{
pPool->Release(std::move(decrypted));
}
return false;
}
}
else
unsigned long long written = 0;
if (crypto_aead_xchacha20poly1305_ietf_decrypt(
decrypted.data(),
&written,
nullptr,
ciphertext,
entry.stored_size,
reinterpret_cast<const unsigned char*>(entry.path.data()),
entry.path.size(),
entry.nonce.data(),
GetM2PackActiveMasterKey().data()) != 0)
{
if (pPool)
{
@@ -363,8 +249,15 @@ bool CM2Pack::DecryptEntryPayload(const TM2PackEntry& entry, std::vector<uint8_t
}
return false;
}
RecordPackProfileStage(
"m2p",
"aead_decrypt",
entry.stored_size,
written,
static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - decryptStart).count()));
decrypted.resize(written);
decrypted.resize(static_cast<std::size_t>(written));
return true;
}
@@ -422,12 +315,32 @@ bool CM2Pack::GetFileWithPool(const TM2PackEntry& entry, std::vector<uint8_t>& r
return false;
}
if (ShouldVerifyM2PackPlaintextHash())
if (!ShouldVerifyM2PackPlaintextHash())
{
if (!VerifyM2PackHash("plaintext_hash", result.data(), result.size(), entry.plaintext_hash, entry.path.c_str()))
{
return false;
}
return true;
}
std::array<uint8_t, M2PACK_HASH_SIZE> plain_hash {};
const auto hashStart = std::chrono::steady_clock::now();
crypto_generichash(
plain_hash.data(),
plain_hash.size(),
result.data(),
result.size(),
nullptr,
0);
RecordPackProfileStage(
"m2p",
"plaintext_hash",
result.size(),
plain_hash.size(),
static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - hashStart).count()));
if (memcmp(plain_hash.data(), entry.plaintext_hash.data(), plain_hash.size()) != 0)
{
TraceError("CM2Pack::GetFileWithPool: plaintext hash mismatch for '%s'", entry.path.c_str());
return false;
}
return true;

View File

@@ -19,8 +19,6 @@ constexpr std::size_t M2PACK_SIGNATURE_SIZE = 64;
constexpr std::size_t M2PACK_KEY_SIZE = crypto_aead_xchacha20poly1305_ietf_KEYBYTES;
constexpr std::size_t M2PACK_NONCE_SIZE = crypto_aead_xchacha20poly1305_ietf_NPUBBYTES;
constexpr std::size_t M2PACK_PUBLIC_KEY_SIZE = crypto_sign_PUBLICKEYBYTES;
constexpr uint32_t M2PACK_VERSION_AEAD = 1;
constexpr uint32_t M2PACK_VERSION_STREAM = 2;
#pragma pack(push, 1)
struct TM2PackHeader
@@ -53,19 +51,6 @@ struct TM2PackManifestEntryFixed
uint8_t nonce[M2PACK_NONCE_SIZE];
uint8_t plaintext_hash[M2PACK_HASH_SIZE];
};
struct TM2PackManifestEntryFixedV2
{
uint16_t path_size;
uint8_t compression;
uint8_t flags;
uint64_t data_offset;
uint64_t original_size;
uint64_t stored_size;
uint8_t nonce[M2PACK_NONCE_SIZE];
uint8_t payload_hash[M2PACK_HASH_SIZE];
uint8_t plaintext_hash[M2PACK_HASH_SIZE];
};
#pragma pack(pop)
struct TM2PackEntry
@@ -76,7 +61,6 @@ struct TM2PackEntry
uint64_t original_size = 0;
uint64_t stored_size = 0;
std::array<uint8_t, M2PACK_NONCE_SIZE> nonce {};
std::array<uint8_t, M2PACK_HASH_SIZE> payload_hash {};
std::array<uint8_t, M2PACK_HASH_SIZE> plaintext_hash {};
};