Skip to content

3c.3 relay: unauthenticated obf discriminator is only ~21 bits (probabilistic probe-resistance; authenticated check via #37) #64

Description

@vxfemboy

Summary

The 3c.3 relay's Trojan-front discriminator decides tunnel-vs-decoy by deobfuscating the first framed message with the network obf_psk and checking it is a fresh Register. But yip_obf::deobfuscate is an unauthenticated keystream XOR (SipHash-CTR, "NOT an AEAD" per its own docs) — there is no MAC. So the "proof of obf_psk knowledge" reduces to a structural match on the recovered bytes: ptype == RDV_TYPE (8 bits) + Register tag 0x00 (8 bits) + a length field in a plausible range — only ~16–21 effective bits.

Impact

A blind prober (no obf_psk) sending a random frame over a completed TLS session lands a false Upgrade with probability ≈ 2⁻²¹ per connection. On that event the relay writes an obfuscated, rendezvous-shaped reply and enters run_tunnel — i.e. it emits the "tunnel behavior" the spec promises a non-holder never observes, instead of serving the decoy.

This contradicts design §6.1's original "a prober without obf_psk cannot forge a Register" (corrected to a probabilistic statement in the spec, referencing this issue).

Severity

Low in practice: each attempt costs a full real-cert TLS handshake, so ~10⁶ handshakes to unmask once, and the payoff is only "this endpoint answered non-decoy." But it means probe-resistance against a blind forger is probabilistic, not absolute.

Fix directions

Surfaced by the 3c.3 final whole-branch review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions