# RFC-006: Key Retrieval Mechanisms **Author**: moonD4rk **Status**: Living Document **Created**: 2026-04-05 ## 1. Overview Chromium-based browsers encrypt sensitive data (passwords, cookies, credit cards) using a **master key**. The master key is stored differently on each platform: | Platform | Storage | Key Type | |----------|---------|----------| | macOS | macOS Keychain | Password string → PBKDF2 → AES-128 | | Windows | `Local State` JSON (DPAPI-encrypted) | Raw AES-256 key | | Linux | GNOME Keyring / KDE Wallet via D-Bus | Password string → PBKDF2 → AES-128 | Each platform may have multiple retrieval strategies. The `KeyRetriever` interface and `ChainRetriever` pattern abstract over these strategies, trying each in priority order until one succeeds. For Chromium encryption details (cipher versions, AES-CBC/GCM), see [RFC-003](003-chromium-encryption.md). Firefox manages its own keys via `key4.db` — see [RFC-005](005-firefox-encryption.md). ## 2. KeyRetriever Interface The interface takes a single `Hints` struct so caller intent is explicit rather than positional: ```go type Hints struct { KeychainLabel string // macOS Keychain account / Linux D-Bus Secret Service item label (e.g. "Chrome", "Chrome Safe Storage") WindowsABEKey string // Windows ABE browser key used by ABERetriever to locate the elevation-service COM interface (e.g. "chrome", "edge"). "" → ABE not applicable; ABERetriever returns (nil, nil) silently. LocalStatePath string // path to Local State JSON. Only used on Windows (DPAPI + ABE both read it). } ``` Each retriever reads only the field that applies to its platform; the others are ignored. Callers populate `Hints` from `BrowserConfig`: `KeychainLabel` is copied directly, `WindowsABEKey` is set to `cfg.Key` when `cfg.WindowsABE` is true. The return value is the **ready-to-use decryption key** — either the raw AES key (Windows) or the PBKDF2-derived key (macOS/Linux). `ChainRetriever` wraps multiple retrievers and tries them in order. The first successful result wins. If all fail, errors from every retriever are combined into a single error. **Caching**: the retriever chain is created once per process inside `newPlatformInjector` (see `browser/browser_{darwin,linux,windows}.go`) and shared across every Chromium browser and every profile. macOS retrievers additionally use `sync.Once` internally, so multi-profile browsers only trigger one keychain prompt or memory dump. ## 3. macOS Key Retrieval Chromium on macOS stores the encryption password in the user's login keychain under a browser-specific account name (e.g. `"Chrome"`, `"Brave"`, `"Microsoft Edge"`). ### 3.1 Retrieval Strategies **GcoredumpRetriever** — exploits **CVE-2025-24204** to extract keychain secrets from `securityd` process memory. Requires root. The exploit works because the `gcore` binary holds the `com.apple.system-task-ports.read` entitlement, bypassing TCC protections: 1. Find `securityd` PID via `sysctl` 2. Dump process memory via `gcore` 3. Parse heap regions via `vmmap`, scan `MALLOC_SMALL` regions for 24-byte key pattern 4. Try each candidate against `login.keychain-db` **KeychainPasswordRetriever** — unlocks `login.keychain-db` directly using the user's macOS login password (from `--keychain-pw` flag), powered by the [moond4rk/keychainbreaker](https://github.com/moond4rk/keychainbreaker) library which implements a full macOS Keychain file parser and decryptor in pure Go. Non-root, non-interactive. **SecurityCmdRetriever** — invokes `security find-generic-password -wa