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
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Tcpinc mailing list [email protected] https://www.ietf.org/mailman/listinfo/tcpinc
