fix(vault): replace hand-rolled XOR+HMAC with real AES-GCM (#302) - #1714
fix(vault): replace hand-rolled XOR+HMAC with real AES-GCM (#302)#1714aaniya22 wants to merge 2 commits into
Conversation
utksh1
left a comment
There was a problem hiding this comment.
Moving from hand-rolled crypto to AES-GCM is the right direction, but this revision regresses existing vault behavior:\n\n1. Preserve compatibility with the current vault key contract and keep the existing fingerprint/diagnostics behavior intact.\n2. Do not remove unrelated dependencies from backend/requirements.txt (for example httpx / openai) as part of this PR.\n3. Keep the crypto migration focused and regression-safe.\n\nPlease revise this to preserve current diagnostics/contracts while upgrading the crypto implementation.
- VaultCrypto now uses AES-256-GCM for authenticated encryption instead of a custom XOR keystream + HMAC scheme, closing a crib-dragging vulnerability on plaintext longer than one keystream block - Key material is SHA-256 hashed to a fixed 32 bytes, so any input key length works safely for AES-256 - Ciphertext from the old XOR+HMAC format is now rejected loudly on decrypt (raises ValueError) rather than silently producing garbage - Consolidated a duplicate test_vault.py (one had been added at testing/backend/test_vault.py, colliding with the existing file at testing/backend/unit/test_vault.py) and merged in new regression tests: long-plaintext round-trip, nonce non-determinism, tamper detection, wrong-key rejection, and old-format rejection
eb7c31b to
463d43b
Compare
upstream/main already has an equivalent (and more complete) AES-GCM |
|
Closing this because the author confirmed the AES-GCM vault change is already present on main and there is no meaningful diff left to merge. |
Description
VaultCryptopreviously encrypted secrets using a hand-rolled scheme: a SHA-256-derived keystream XOR'd against the plaintext, authenticated with a separate HMAC. Because the keystream was cycled to cover plaintexts longer than one block, any secret over 32 bytes reused keystream bytes — a crib-dragging vulnerability if an attacker could influence or guess part of the plaintext.This PR replaces that scheme with AES-256-GCM (via the
cryptographylibrary):ValueError) rather than silently producing garbage.test_vault.py(one had been added attesting/backend/test_vault.py, colliding with the existing file attesting/backend/unit/test_vault.py) and merged in new regression tests: long-plaintext round-trip, nonce non-determinism, tamper detection, wrong-key rejection, and old-format rejection.Note: this is a breaking change for data at rest — secrets encrypted under the old format cannot be decrypted with the new code and must be re-encrypted as part of deploying this change.
Related Issues
Closes #302
Type of Change
How Has This Been Tested?
Ran the full backend suite (
python -m pytest testing/backend -v). All 6 tests intesting/backend/unit/test_vault.pypass, covering:32 unrelated failures exist elsewhere in the suite (plugin/tooling integration tests, e.g.
test_phase2_plugins.py,test_phase3_plugins.py,test_plugins.py). Verified these fail identically on unmodifiedmain, so they're pre-existing environment/tooling issues (likely missing external CLI tools) unrelated to this change.To reproduce:
python -m pytest testing/backend/unit/test_vault.py -vChecklist