On 11/19/15 11:46 PM, David Mazieres wrote: > C5. Leave it to individual encryption specs to make TCP-SO work > automatically. For DH-based specs, there may be an easy trick. > However, for public-key-based specs--such as those relying on RSA > or post-quantum crypto--this would even for non-SO more than double > computational cost at passive openers and add an extra round trip > to client-speaks-first protocols. (This is what Bryan has been > advocating, at least for ECDH.)
You misrepresent what I'm advocating. I've already pointed out at least twice how tcpcrypt could readily be made to support public-key-based exchange and support SO without ever failing open, and without either doubling the computational cost or adding an extra round trip in the common case. To summarize one way of doing this cleanly: Assume TCP-ENO works more-or-less as currently specified, such that each endpoint picks 'p' and 'b' bits and the 'pb' combination serves as a priority that can be used for tiebreaking - BUT, the TCP-ENO protocol doesn't just give up (and either fail open or abandon) if both endpoints' pb values happen to end up equal. Instead, TCP-ENO simply passes the negotiated pair of pb values - e.g., as 'local_pb' and 'remote_pb' - to the negotiated protocol (e.g., USE-TLS or tcpcrypt), which can then decide how to use them. Maybe some negotiated protocols (e.g., USE-TLS) will still need to bail if local_pb == remote_pb, but let's say we want tcpcrypt to handle all cases gracefully. Each endpoint's public-key-based tcpcrypt key exchange follows something like this pseudocode: local_symkey := 0x00...00 // all-zero symmetric key of appropriate size remote_symkey := 0x00...00 if (local_pb >= remote_pb) { // active or equal role send local_pubkey } if (remote_pb >= local_pb) { // passive or equal role receive remote_pubkey local_symkey = pick_random_key() encrypt_and_send(remote_pubkey, local_symkey) } if (local_pb >= remote_pb) { // active or equal role remote_symkey = receive_and_decrypt(local_prikey) } master_local_to_remote := derive_master(local_symkey, remote_symkey) master_remote_to_local := derive_master(remote_symkey, local_symkey) Each endpoint then uses 'master_local_to_remote' to encrypt and append MACs to traffic it sends to the other endpoint, and 'master_remote_to_local' to decrypt and integrity-check traffic it receives. Once these master secrets are derived, everything else in the protocol can be entirely oblivious to whether the endpoints are operating in active/passive or symmetrical roles. Notice that whenever TCP-ENO's 2-bit tiebreaking mechanism succeeds and produces different values (local_pb != remote_pb), the above pseudocode yields exactly the same protocol exchange as the optimized one you like, namely: A -> B: SYN(ENO) B -> A: SYN-ACK(ENO) A -> B: (ENO) PKA B -> A: {NB}_PKA B -> A: data A -> B: data In this case, at each endpoint either local_symkey or remote_symkey will be an all-zero key, but that's OK because the other one is fresh and protected in transit by public-key encryption. And I think we all can agree that TCP-ENO's tiebreaking mechanism *should* work *almost* all the time in practice, given that SO is uncommon in the first place and even when it happens (intentionally or not) TCP-ENO still provides a 50-50 chance of successful tiebreaking via the low-order b bit. In the rare case that the tiebreaking mechanism doesn't succeed, all of the if statements in the above pseudocode will evaluate to true at both endpoints, yielding a perfectly operational symmetric version of the same key exchange. In this case, local_symkey and remote_symkey end up being nonzero at both endpoints, but everything still just works. This situation will incur that doubling of computational cost and perhaps an extra round trip, but I don't think we care about if this is expected to be such an uncommon case. Finally, notice that the above pseudocode doesn't add any code specific to SO - i.e., there are no SO-specific statements that we should worry is unlikely ever to be tested, apart from the conditionals themselves. This approach adds only one conditional that might not already be needed anyway in your asymetric-only version of the protocol, namely the second if (local_pb >= remote_pb) test. And it eliminates any role-specific conditionals you might currently have elsewhere in tcpcrypt after key exchange. So are there any other reasons that it would be extremely burdensome to avoid breaking SO and potentially introduce unnecessary fail-open risks? Bryan
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ Tcpinc mailing list Tcpinc@ietf.org https://www.ietf.org/mailman/listinfo/tcpinc