Skip to content

KeePassCore.Security.Memory roadmap

src/KeePassCore.Security.Memory, net10.0, standalone, meant to become a NuGet package (version shared with the other projects until the KeePass Core v4 release). Doc: src/KeePassCore.Security.Memory/README.md.

Goal and rules

  • Protect secrets held in process memory (against memory dumps, swap, crash reports and other processes of the same user) on every OS. Replaces the in-process use of DPAPI (ProtectedMemory) in the lib.
  • Not a persistent data protection API: the key is random, per process, never written anywhere.
  • Every OS protection is best-effort and reported (SecureMemoryFlags); an allocation never fails only because e.g. RLIMIT_MEMLOCK is exhausted.

Done

  • One crypto path for all OSes: AES-256-GCM, random per-process 256-bit key, layout nonce (12) || tag (16) || ciphertext, nonce = random 32-bit prefix + 64-bit counter.
  • Key storage per OS (Platform/*PlatformMemory.cs):
  • Linux: memfd_secret, fallback mmap + mlock + MADV_DONTDUMP + MADV_WIPEONFORK;
  • Windows: VirtualAlloc + VirtualLock + WER exclusion, key additionally wrapped with CryptProtectMemory (unwrapped only during an operation);
  • macOS: mlock + minherit(VM_INHERIT_NONE);
  • fallback: unmanaged memory, no OS protection.
  • Public API: EncryptedBuffer (long-lived secrets), SecureBuffer (short-lived plaintext, at least one page each), MemoryProtection.Default / IMemoryProtector, ProcessHardening.Apply() (opt-in: no core dumps, deny debugger / /proc/pid/mem).
  • Checks: tests/KeePassCore.Security.Memory.Tests. Verified on Linux (kernel 7.x): the key is mapped as /secretmem, VmFlags lo dd; hardening makes /proc/<pid>/mem root-owned.
  • src/SecureString (the former C++ prototype) deleted.
  • Memory protection of the lib: ProtectedBinary (hence ProtectedString) stores protected values as EncryptedBuffer; the Argon2 block memory uses SecureBuffer (see the lib roadmap).

To do

  1. Run on real Windows and macOS. The code builds but has never run there. In particular the Windows process DACL D:P(A;;GA;;;SY)(A;;0x00101001;;;OW) (SYSTEM: full access; owner: only synchronize, query limited information, terminate).
  2. CI matrix Windows / Linux / macOS for the tests (platform-specific tests skip elsewhere, so each implementation is only covered when the suite runs on its OS).
  3. Used by the WinForms app for ProcessHardening (replacement of AuxProtectProcessWithDacl, see the app roadmap).
  4. Publish the NuGet package; 4.0.0 once all three OSes are verified.

Decision log

Decision Why
AES-256-GCM everywhere, only the key storage differs One crypto path to review and test
Best-effort protections, reported Never fail an allocation because of OS limits; callers can check
ProcessHardening is opt-in Irreversible and blocks debuggers
Out of scope (as upstream KeePass): root / Administrator, malware as the same user, plaintext in managed strings https://keepass.info/help/base/security.html