Skip to content

VM: SAVE_EPOCH/RESYNC incompatible with doc 16 forward-secrecy — defer to v2 #11

@scc-tw

Description

@scc-tw

Problem

Doc 16 rev.8 introduces per-instruction key ratcheting with forward secrecy (insn_fpe_key destroyed after each instruction via explicit_bzero). The SAVE_EPOCH / RESYNC opcodes (doc 15 §7, exception handling / timeline branching) fundamentally conflict with this model.

Four systemic risks identified

  1. Forward secrecy degradation: Saving insn_fpe_key in the shadow stack (heap) extends the key lifetime from ~nanoseconds (1 instruction) to the entire function call / epoch duration. Memory dump during this window recovers the historical key.

  2. State injection attack: Shadow stack in heap memory lacks integrity protection. Without AEAD, an attacker can overwrite saved_insn_fpe_key + encoded register snapshot with crafted values, injecting arbitrary register state at RESYNC time.

  3. State machine desync: Restoring registers without restoring enc_state (SipHash decryption chain) and bb_chain_state (BB forward-secrecy chain) causes the next instruction decryption to produce garbage. All three cryptographic state chains must be restored atomically.

  4. Fingerprint entanglement discontinuity: RESYNC injects historical register values into the current fingerprint chain, creating a discontinuity exploitable for chosen-plaintext analysis of Speck64/128.

Mathematical impossibility

Forward-secret checkpoints are impossible in pure software without hardware-isolated key storage (TPM/SGX/TrustZone). Any checkpoint that stores encrypted state and later decrypts it must have the decryption key in addressable memory during [T_save, T_restore]. A memory dump during this interval recovers the key.

Correct fix (v2, requires AEAD + hardware consideration)

  1. Derive snapshot_seal_key from per-execution RDRAND nonce (independent of main ratchet chain)
  2. SAVE_EPOCH: decode all regs to plaintext, pack full state (regs + enc_state + bb_chain_state + insn_fpe_key), AEAD encrypt with ChaCha20-Poly1305, store (nonce, ciphertext, tag) in shadow stack
  3. RESYNC: authenticate-then-decrypt, restore full state atomically, re-encode regs with restored insn_fpe_key
  4. Accept honest limitation: snapshot data from current execution is decryptable from dump (per-execution key from RDRAND prevents cross-execution compromise)

v1 decision

SAVE_EPOCH and RESYNC return DiagnosticCode::NotImplemented in v1. Exception handling in protected regions is not supported until v2.

CALL_VM / RET_VM (function calls) have the same architectural conflict but are required for v1. They use the AEAD snapshot protocol described above.

References

  • Doc 15 §7: Exception Handling (Timeline Branching)
  • Doc 16 rev.8 §4: Per-instruction key ratchet
  • Doc 16 rev.8 §7.1: Stack residue elimination theorem
  • Research doc 16 peer review rounds 4-7: forward secrecy analysis

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions