Following up on my comment in the tcpinc meeting, I’m worried that both tcpinc 
proposals, as well as the TCP-ENO design, are baking in an assumption 
that there “need” to be asymmetric passive-active or A-B roles - and 
introducing a lot of complexity in the process - whereas a much simpler and 
cleaner alternative might be simply to remain more design-consistent with TCP 
by consistently treating the endpoints’ roles symmetrically.

A symmetric protocol definition certainly seems to be a feasible option for 
tcpcrypt, as discussed below, and as far as I can tell would only simplify the 
tcpcrypt protocol.  A symmetric definition might not really be an option for 
USE-TLS merely due to the goal of historical compatibility with (and reuse of) 
TLS, which does have asymmetry baked in fairly fundamentally.

Outlining how I envision tcpcrypt might be made purely symmetric, and what the 
implications are (i.e., how that would simplify the protocol):

- The most obvious simplicity benefit is that the protocol needs no special 
mechanisms in order to make TCP simultaneous open work.  In particular, the 
tie-breaking (or whatever else it should be named) feature definitely adds 
complexity, which could be eliminated entirely from tcpcrypt (and perhaps made 
optional in TCP-ENO).

- The tie-breaking mechanism obviously carries a risk of failure - i.e., if 
both sides choose the same role they have to “fail open” back to unencrypted 
communication.  Which I admit is not completely a deal-breaker since we’re 
talking about opportunistic encryption in the first place, but it still adds 
both protocol complexity and behavioral unpredictability that makes me sad.

- The first place role-asymmetry comes into the tcpcrypt spec itself is 
negotiation, section 3.3, where "the last spec identifier in the SYN segment of 
host B” is the winner.  It’s easy to create a symmetric but still deterministic 
version of this.  For example: (1) each endpoint sends in its ENO SYN packet a 
list of spec identifiers in ascending preference order; (2) from each list take 
the LAST spec-identifier that also appears in the other list; and (3) the 
spec-identifier chosen is the numerically largest of those two.  This approach 
has the nice properties that (a) whenever both parties happen to agree on the 
“most preferred” spec that they both support, they’ll always get that one; and 
(b) if they do disagree, they’ll tie-break by picking the one that is probably 
most “recent/modern” of the two, assuming spec-identifiers tend to get assigned 
over time from lower to higher numbers.  At any rate, no A/B roles needed to 
achieve consensus.

- Key exchange (sec 3.4): each party sends the other an init packet of 
identical form init = {INIT_MAGIC, sym-cipher-list, N_me, PK_i}, where “me” is 
A for the A->B message and is “B” for the B->A message.  They use the two 
sym-cipher-lists to pick one deterministically and symmetrically in the same 
fashion as for spec-identifier agreement above.  

- The two parties now compute two directional pre-master secrets (PMSs) and one 
undirectional PMS.  Party A computes its directional PMS_A based on param_A := 
{ “directional”, eno_A, eno_B, init_A, init_B }, and computes its other 
directional PMS_B based on param_B := { “directional”, eno_B, eno_A, init_B, 
init_A }.  Party B computes the same directional PMSes only with A and B 
swapped (i.e., each has a PMS_me_to_you and a PMS_you_to_me).  Both parties 
compute the undirected PMS, call it PMS_U, based on param_U := { “undirected”, 
min(eno_A, eno_B), max(eno_A, eno_B), min(init_A, init_B), max(init_A, init_B) 
}, for appropriate “min”/“max” functions representing pretty much any 
total-ordering (e.g., lexicographic order) on eno-lists and init-packets.  The 
tcpcrypt protocol itself will mainly (perhaps exclusively) use the directional 
PMSes, but the undirected PMS might be useful to provide an undirected session 
identifier (perhaps alongside directed session identifiers) to applications.

- Now the session secrets are similarly computed directionally but otherwise in 
the same way as they currently are: e.g., party A computes ss_AtoB[0] := 
PRK_AtoB and ss_BtoA[0] := PRK_BtoA; party B performs exactly the same 
computations but with A to B swapped.  ss_AtoB[i] is used form master keys 
mk_AtoB[j] which are used to encrypt and integrity-protect traffic flowing from 
A to B, while ss_BtoA[i] is used to form master keys mk_BtoA[j] which are used 
to encrypt and integrity-protect traffic flowing from B to A.  But again this 
is fully symmetric, so neither party knows or cares whether it is “A” or “B”; 
it just thinks of “me to you” and “you to me” session secrets and traffic flows.

- The re-keying mechanism and most of the rest of the tcpcrypt spec, as far as 
I can tell, is unaffected by a change to symmetric behavior (except obviously 
for the collapse of INIT1 and INIT2 into INIT, etc).

So again, it feels to me like this all would strictly simplify the protocol, 
make it more consistent with TCP’s symmetric design style, and would make TCP 
simultaneous open “just work” with no extra tie-breaking complexity or 
attendant risks of fail-open.  Is there an identifiable reason the current 
asymmetric behavior is necessary or even advantageous?

Thanks
Bryan


Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
Tcpinc mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/tcpinc

Reply via email to