Repository navigation
perf(core): cache unlock-time master key to skip per-save Argon2id (#397) - #412
Open
mashfromband wants to merge 1 commit into
Open
mashfromband wants to merge 1 commit into
mashfromband wants to merge 1 commit into
Conversation
PasswordBox::save re-ran the deliberately-heavy Argon2id KDF (64 MiB / t=3 / p=4, hundreds of ms) on every mutation even though the box is already unlocked and the plaintext payload is resident in memory. Retain the derived MasterKey while unlocked and reuse it on save. The cache is tagged with the exact KDF inputs it was derived from. save always writes the current default params to the header, so it reuses the cached key only when the tags match those defaults + salt; otherwise it re-derives (first save after create, or a box opened with older cost params being re-keyed for crypto-agility) and refreshes the cache. The cache never affects the on-disk format or FILE_VERSION. Security: the MasterKey is ZeroizeOnDrop; lock() drops the cache (zeroizing it) and Drop tears it down, consistent with #391's secret scrubbing. Holding the key while unlocked adds no meaningful exposure since the decrypted payload already lives in memory during that window. Closes #397
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was previously deployed
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.
概要 / Closes #397
PasswordBox::saveは毎 mutation ごとに Argon2id フル導出(KDF_MEMORY_KIB=65536=64MiB,time_cost=3,parallelism=4、実測数百 ms 級)を実行していた。既にアンロック済み(平文 payload がメモリ常駐)状態でのセーブなので、鍵再導出のセキュリティ利得は乏しく、1 操作あたり数百 ms のブロッキング UX コストだけが残っていた。アンロック中に導出済みの
MasterKeyをPasswordBoxにキャッシュし、saveで再利用する。実装
PasswordBoxにcached_key: Option<CachedMasterKey>を追加。CachedMasterKeyは鍵と導出に用いた KDF 入力(salt / memory_kib / time_cost / parallelism)をタグ付けして保持する。open(): ヘッダの(crypto-agility を尊重した)パラメータで導出した鍵をそのパラメータでタグ付けしてキャッシュ。create(): 初回saveが導出+キャッシュ。save():master_key_for_saveが「キャッシュのタグがこれから書き込むヘッダのパラメータ(現行デフォルト)+ salt と一致する場合のみ再利用」。不一致なら再導出しキャッシュを更新。lock(): キャッシュをNoneに(MasterKeyはZeroizeOnDropなのでドロップ=ゼロ化)。セキュリティ判断(鍵をメモリ保持する是非)
MasterKeyはZeroize + ZeroizeOnDrop。lock()でキャッシュを破棄(ゼロ化)、PasswordBoxのDropでも鍵フィールドがドロップされゼロ化。再導出時の旧鍵もOption置換で即ドロップ=ゼロ化。saveは常に現行デフォルトのヘッダを書き、そのパラメータで導出した鍵で暗号化する必要がある。旧パラメータのファイルを開いた箱はキャッシュのタグが不一致になり、再導出(=再キー) されるため、オンディスクのヘッダと暗号文が乖離しない。次回以降の save は fast-path に戻る。FILE_VERSIONに不変: キャッシュは純粋にメモリ内最適化。ファイルフォーマットへの影響なし。lock()でキャッシュ破棄 → 次のopen()で必ず再導出。テスト(
cargo test -p passshare-coregreen / 全 53 tests)open_caches_key_matching_fresh_derivation: キャッシュ鍵が新規導出とバイト一致(再利用が導出と等価)。save_reuses_cached_key_verbatim: キャッシュを別パスワード由来の鍵で汚染 →saveが引数を無視してキャッシュ鍵で暗号化することを証明(= 実際にキャッシュ参照している)。save_rederives_when_cached_params_mismatch: パラメータ不一致タグ時は再導出され、正しいパスワードで復号可能・キャッシュがデフォルトへ更新(crypto-agility 再キー)。repeated_saves_stay_decryptable: 連続 save(fast-path)でも毎回再オープン復号可能(ヘッダと暗号文が乖離しない)。lock_clears_cached_master_key:lock()でキャッシュがゼロ化・破棄される。注記
現状コードベースにマスターパスワード変更フローは存在せず、
saveの全呼び出し元はアンロック時と同一パスワードを渡す。将来パスワード変更 API を追加する場合は変更時に再導出(キャッシュ無効化)が必要である旨をコメントに明記済み。