From 6bbf2d9311b47a8a15c17d9fe11828ee623d98e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Sat, 5 Apr 2025 18:25:20 +0200 Subject: [PATCH] refactor: prepare `DBWrapper` for obfuscation key change Since `FastRandomContext` delegates to `GetRandBytes` anyway, we can simplify new key generation to a Write/Read combo, unifying the flow of enabling obfuscation via `Read`. The comments were also adjusted to clarify that the `m_obfuscation` field affects the behavior of `Read` and `Write` methods. These changes are meant to simplify the diffs for the riskier optimization commits later. --- src/dbwrapper.cpp | 40 +++++++--------------------------------- src/dbwrapper.h | 6 ++---- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 45f806705b4..f92c9b4cf62 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -249,24 +249,15 @@ CDBWrapper::CDBWrapper(const DBParams& params) LogPrintf("Finished database compaction of %s\n", fs::PathToString(params.path)); } - // The base-case obfuscation key, which is a noop. - m_obfuscation = std::vector(Obfuscation::KEY_SIZE, '\000'); - - bool key_exists = Read(OBFUSCATION_KEY_KEY, m_obfuscation); - - if (!key_exists && params.obfuscate && IsEmpty()) { - // Initialize non-degenerate obfuscation if it won't upset - // existing, non-obfuscated data. - std::vector new_key = CreateObfuscation(); - - // Write `new_key` so we don't obfuscate the key with itself - Write(OBFUSCATION_KEY_KEY, new_key); - m_obfuscation = new_key; - - LogPrintf("Wrote new obfuscation key for %s: %s\n", fs::PathToString(params.path), HexStr(m_obfuscation)); + m_obfuscation = std::vector(Obfuscation::KEY_SIZE, '\000'); // Needed for unobfuscated Read()/Write() below + if (!Read(OBFUSCATION_KEY_KEY, m_obfuscation) && params.obfuscate && IsEmpty()) { + // Generate, write and read back the new obfuscation key, making sure we don't obfuscate the key itself + Write(OBFUSCATION_KEY_KEY, FastRandomContext{}.randbytes(Obfuscation::KEY_SIZE)); + Read(OBFUSCATION_KEY_KEY, m_obfuscation); + LogInfo("Wrote new obfuscation key for %s: %s", fs::PathToString(params.path), HexStr(m_obfuscation)); } + LogInfo("Using obfuscation key for %s: %s", fs::PathToString(params.path), HexStr(m_obfuscation)); - LogPrintf("Using obfuscation key for %s: %s\n", fs::PathToString(params.path), HexStr(m_obfuscation)); } CDBWrapper::~CDBWrapper() @@ -311,23 +302,6 @@ size_t CDBWrapper::DynamicMemoryUsage() const return parsed.value(); } -// Prefixed with null character to avoid collisions with other keys -// -// We must use a string constructor which specifies length so that we copy -// past the null-terminator. -const std::string CDBWrapper::OBFUSCATION_KEY_KEY("\000obfuscate_key", 14); - -/** - * Returns a string (consisting of 8 random bytes) suitable for use as an - * obfuscating XOR key. - */ -std::vector CDBWrapper::CreateObfuscation() const -{ - std::vector ret(Obfuscation::KEY_SIZE); - GetRandBytes(ret); - return ret; -} - std::optional CDBWrapper::ReadImpl(std::span key) const { leveldb::Slice slKey(CharCast(key.data()), key.size()); diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 88684cab175..0935320ecac 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -190,10 +190,8 @@ private: //! a key used for optional XOR-obfuscation of the database std::vector m_obfuscation; - //! the key under which the obfuscation key is stored - static const std::string OBFUSCATION_KEY_KEY; - - std::vector CreateObfuscation() const; + //! obfuscation key storage key, null-prefixed to avoid collisions + inline static const std::string OBFUSCATION_KEY_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0 //! path to filesystem storage const fs::path m_path;