security: derive a per-file salt for temporary-file encryption (H3)#17
Merged
Conversation
Temporary-file encryption derived the AES-XTS tweak (and the CTR IV for a sub-block tail) from a cluster-global base IV and the buffer's block position. The block position resets to zero in every new BufFile, so two different temporary files encrypted identical plaintext blocks under the same (key, tweak): an equality oracle across files for the XTS body and a two-time pad for any CTR tail. Core now assigns each BufFile a 16-byte salt and passes it to the temporary-file encryption hooks, which mix it into the tweak/IV ahead of the block position. A private temp file gets a random salt; a fileset based BufFile (shared by parallel workers) derives its salt deterministically from the fileset identity and name so the writer and every reader agree without communicating it. Temporary keys are per-boot and never persisted, so there is no on-disk compatibility concern. Applies to the PostgreSQL 16/17/18 core patch (0002) and the extension. - patches: add crypt_salt to struct BufFile, fill it at create/open, and extend the TempFileCryptHook signature with the salt. - open_pg_tde_tempfile.c: mix the salt into the XTS tweak / CTR IV. - test: two identical spilling sorts must now produce distinct ciphertext, with an encryption-off control and a parallel shared-fileset round trip. - docs: note per-file uniqueness in the encryption architecture page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
H3 (High): temporary-file IV/tweak reuse across BufFiles
Problem
Temporary-file encryption derived the AES-XTS tweak (and the CTR IV for a sub-block tail) from a cluster-global base IV and the buffer's block position. The block position resets to zero in every new
BufFile, so two different temporary files encrypted identical plaintext blocks under the same(key, tweak):Fix
Core assigns each
BufFilea 16-byte salt and passes it to the temporary-file encryption hooks, which mix it into the tweak/IV ahead of the block position:BufFileCreateTemp): a random salt (pg_strong_random), unique and never shared.BufFileCreateFileSet/BufFileOpenFileSet, e.g. parallel workers sharing a hash-join spill): the salt is derived deterministically from the fileset identity(creator_pid, number)and the BufFile name, so the writer and every reader arrive at the same salt without communicating it.Temporary keys are per-boot and never persisted, so there is no on-disk compatibility concern.
Changes
0002(PG16/17/18): addcrypt_salttostruct BufFile, fill it at create/open, and extend theTempFileCryptHooksignature with the salt. Onlybuffile.candtempfile_crypt.hhunks change; the other four hunks are byte-identical to what was committed.src/open_pg_tde_tempfile.c: mix the salt into the XTS tweak / CTR IV.t/temp_file_encryption.pl: two identical spilling sorts must now produce distinct ciphertext, with an encryption-off control and a parallel shared-fileset round trip.Validation
verify-gate.sh3/3 (gate off = stock PostgreSQL, gate on = hooks load); fullmeson testsuite green.temp_file_encryption.pl9/9 subtests, including the H3 distinctness property and the parallel shared-fileset round trip.pgindentandperltidyclean.Note: a full PG17 build currently trips over an unrelated
0001base-drift (path_is_safe_for_extractionnow exists both in the REL_17_STABLE tip and in0001, a redefinition). This PR's0002never touchespath.c, applies cleanly, and itsbuffile.c/tempfile_crypt.hedits are byte-identical to the compiled-clean PG16/PG18.🤖 Generated with Claude Code