Skip to content

feat: Speck-FPE polymorphic stripper stubs for NATIVE_CALL #14

@scc-tw

Description

@scc-tw

Summary

Implement per-call-site polymorphic decode stubs for NATIVE_CALL, replacing the current single-point decode in handler_impls.hpp. Each stub performs inline Speck64/128 FPE decode with unique instruction layout, raising the cost of DBI/static-analysis attacks from O(1) to O(N).

Background

Currently, all NATIVE_CALL decode operations happen in one predictable location — the HandlerTraits<VmOpcode::NATIVE_CALL> handler. An attacker can hook platform_call once and capture plaintext arguments for every native call site.

The old doc 15 design proposed (a,b) affine encoding coefficients per call site (bridge/native_call_bridge_*.S). This design is obsolete — doc 16 replaced affine encoding with Speck-FPE (XEX mode). The placeholder files have been deleted.

Proposed Design (Speck-FPE stripper)

Compile time (SDK, per NATIVE_CALL site i)

  1. Generate per-site random parameters:

    • σ_i: GPR allocation permutation (which register holds which Speck state word)
    • J_i: junk instruction pattern (interleaved with real rounds)
    • M_i[27]: round constant XOR masks (obfuscate embedded constants)
    • layout_i: round unroll/interleave strategy
  2. Emit unique ASM stub containing:

    • Speck64/128 key schedule + 27 decrypt rounds inline (not a function call)
    • Rounds interleaved with junk instructions from J_i
    • Round keys masked by M_i (unmasked inline before use)
    • XEX tweak computation fused inline
    • ABI register setup at randomized position within the stub
    • Native CALL embedded mid-stub (not at a predictable offset)
    • Return value Speck encrypt inline (27 rounds, different junk pattern)

Runtime (per NATIVE_CALL)

  1. Handler passes (encoded_regs, insn_fpe_key) to stub_i
  2. stub_i performs FPE decode inline → plaintext in ABI registers
  3. Calls native function
  4. Re-encodes return value inline → passes back to handler

Security properties

Threat Without stripper With stripper
Memory dump FPE protected (doc 16 §7) Same
DBI single hook All calls captured (O(1)) Must find each stub (O(N))
Static pattern match One decode pattern N unique patterns
Automated deobfuscation Trivial Must solve per-stub register mapping + round interleaving

Does not change cryptographic guarantees — doc 16 security proofs (§7.1–7.8) are independent of stripper presence. This is defense-in-depth obfuscation, not a security boundary.

Plaintext exposure at native call boundary is a theoretical lower bound — the native function must receive plaintext arguments. Strippers make it harder to locate the decode, not to prevent it.

Dependencies

  • Requires LLVM Backend — SDK must emit per-site ASM stubs with instruction-level junk interleaving. SimpleBackend cannot do this.
  • Platforms: x86-64 (SysV + Win64), ARM64 (AAPCS64), x86-32 (cdecl + stdcall)

Deleted placeholders

The following v1 placeholder files (pure comments, zero code) were deleted in this cleanup. They described the obsolete doc 15 (a,b) affine design:

  • runtime/src/bridge/native_call_bridge_x86_64.S
  • runtime/src/bridge/native_call_bridge_arm64.S
  • runtime/src/entry_exit/vm_entry_x86_64.S
  • runtime/src/entry_exit/vm_entry_arm64.S
  • runtime/src/entry_exit/vm_exit_x86_64.S
  • runtime/src/entry_exit/vm_exit_arm64.S

References

  • Doc 16: Forward-Secrecy Extension (§5 ENTER_BASIC_BLOCK, §7 security proofs)
  • Doc 15: ISA Design v1 (§6.1–6.4 polymorphic bridge, §13.1 register randomization) — superseded by doc 16 for encoding, but bridge concept still relevant

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions