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

Open
opened 2026-07-14 00:59:29 +00:00 by vxfemboy · 0 comments
vxfemboy commented 2026-07-14 00:59:29 +00:00 (Migrated from github.com)

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

  • Authenticated discrimination: a MAC over the first frame. Signed registrations (#37) naturally provide this — the relay would verify a signature, not a structural match — collapsing the forge probability to cryptographic negligibility. Strongly related to #37.
  • Or an explicit relay-side challenge/response before any non-decoy byte is emitted.
  • Interim: tightening the structural check (exact expected length, fixed sub-structure) lowers but does not eliminate the false-positive rate.

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

## 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 - **Authenticated discrimination:** a MAC over the first frame. **Signed registrations (#37)** naturally provide this — the relay would verify a signature, not a structural match — collapsing the forge probability to cryptographic negligibility. Strongly related to #37. - Or an explicit relay-side challenge/response before any non-decoy byte is emitted. - Interim: tightening the structural check (exact expected length, fixed sub-structure) lowers but does not eliminate the false-positive rate. Surfaced by the 3c.3 final whole-branch review.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
femboy/yip#64
No description provided.