Re: [tcpinc] Eric Rescorla's Discuss on draft-ietf-tcpinc-tcpcrypt-09: (with DISCUSS and COMMENT)

"Black, David" <David.Black@dell.com> Mon, 20 November 2017 22:12 UTC

Return-Path: <David.Black@dell.com>
X-Original-To: tcpinc@ietfa.amsl.com
Delivered-To: tcpinc@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 4290C12EAB5; Mon, 20 Nov 2017 14:12:06 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.719
X-Spam-Level:
X-Spam-Status: No, score=-2.719 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=dell.com header.b=lQtvWG5I; dkim=fail (1024-bit key) reason="fail (message has been altered)" header.d=rsa.com header.b=k9BNVK6L
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ML2yI8CWadKX; Mon, 20 Nov 2017 14:12:02 -0800 (PST)
Received: from esa2.dell-outbound.iphmx.com (esa2.dell-outbound.iphmx.com [68.232.149.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 8F24C12EAA8; Mon, 20 Nov 2017 14:12:02 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=dell.com; i=@dell.com; q=dns/txt; s=smtpout; t=1511215922; x=1542751922; h=from:cc:to:subject:date:message-id:references: in-reply-to:mime-version; bh=KZtNOKhOFkUX1IWfjAc6YwDGUh9xR7K1RzplMEWDe2k=; b=lQtvWG5IYXuuETSyWfXqGRD3mry0tSV4XyhY9atdMJJkU01LP5kxSS4i SfUwVD+ZlptZiJy6OEUjzENm2SCjfWk2LALfwJF7nqMqOqmIqYwwN7kih M4ikSPN2etQzlNokS+FtO8Eq57RZKgygrraBtVy238qTGuPtBKFecVkrP c=;
IronPort-PHdr: =?us-ascii?q?9a23=3AoWPGfxfmUmkaX7KlxH4aNn2plGMj4u6mDksu8pMi?= =?us-ascii?q?zoh2WeGdxc27YBON2/xhgRfzUJnB7Loc0qyN4vCmATRIyK3CmUhKSIZLWR4BhJ?= =?us-ascii?q?detC0bK+nBN3fGKuX3ZTcxBsVIWQwt1Xi6NU9IBJS2PAWK8TW94jEIBxrwKxd+?= =?us-ascii?q?KPjrFY7OlcS30P2594HObwlSijewZbB/IA+qoQnNq8IbnZZsJqEtxxXTv3BGYf?= =?us-ascii?q?5WxWRmJVKSmxbz+MK994N9/ipTpvws6ddOXb31cKokQ7NYCi8mM30u683wqRbD?= =?us-ascii?q?VwqP6WACXWgQjxFFHhLK7BD+Xpf2ryv6qu9w0zSUMMHqUbw5Xymp4rx1QxH0li?= =?us-ascii?q?gIKz858HnWisNuiqJbvAmhrAF7z4LNfY2ZKOZycqbbcNgHR2ROQ9xRWjRBDI2i?= =?us-ascii?q?coUPE+QPM+VWr4b/u1QBogCzChOwCO7r0DJEmmP60bM83u88EQ/GxgsgH9cWvX?= =?us-ascii?q?jasdj1ML0dXvy2zKXQ0D7NYelZ2Sn86IfVfBwqvPaBU7xqfsrPyEkgChnJg0iU?= =?us-ascii?q?qYP/IzyV1f8AvHWF4OpkUeKjkXIoqwZ0ojW2wMonl4fHhoUQyl/e9CV5xp44Jd?= =?us-ascii?q?i/SE96e9GlHoBQuzucN4RoXsMuW25ouCcmyr0GpJ60ZzIGyJUgxxLHavyIbZSI?= =?us-ascii?q?4hz5WOaWOzd4i2ppeLOliBmu60is0Or8VtO70FtMsyFLkcHMu2gM2hHQ8MSLVP?= =?us-ascii?q?Vw8lm71TqS1w3e5ftILEQ3mKbDJZ4u3L09moYWvEnGHSL7l0H7jKGTe0gk5+en?= =?us-ascii?q?8frrb7D7qpOBLIB5jw7zP6otl8G/B+kzLxIAUHKB+eum0b3u5Uj5QLJXgfIoiq?= =?us-ascii?q?TZq5XaJdgDpq6+Hg9Vzp4v6xahADei19QVhWcILElfdx+IlYTmJk/BIPT8Dfum?= =?us-ascii?q?hFSsjStryOvBPr38BJXCM2bPnK3gfbZl605czQUywcpD6JJTD7ENOPPzWknvu9?= =?us-ascii?q?zEFhI0Mg+5z/z5BNhzyI8SQ3+DD6+WPa/ItVKF5fojI+yWa48UvDb9JeIl5/nr?= =?us-ascii?q?jXIhl1ESZ7ep3ZoKZ3yiA/lmJ1+WbmbvgtoaDGgFoA4+TOjwhFKeVj5TYm6+X7?= =?us-ascii?q?gg6TEjFIKmEYDDS5iwj7ybxii7EIFWanlHCl+SDXfoeZyIW+sQZyKKI89hlCAL?= =?us-ascii?q?WaG9S4A9zRGhqBX6yrp/LurI4SAYtIzs1MR75+HJkhEy7zN0BdyH026RV2F0gn?= =?us-ascii?q?8IRzgu0aB+v0N90ViD3LN5g/NGCdxT6elFUgAgNZ7T1+Z6Ecz9WhrdfteVT1ar?= =?us-ascii?q?WsmmDi0pTtIwxd8Bf19xFMmijh/Z3iqqGaQVmqeKBJMq7qLc0WL9J8Fny3bJzK?= =?us-ascii?q?MhlUUpQtNTNW26ga5y7xTTCJLRk0WYkaalab8R3C/T+2efw2qCpkZYUBR/UfaN?= =?us-ascii?q?YXdKS1HXppzD61jJSKWqAPxzPwhb4dSeJK4MYdrs2xEOaP7lOdnaK0j5tGa+Cx?= =?us-ascii?q?eOjueAZoXCYG4Gmj7BAU4KlBofu3uKKF5tKD2mpjeUJjhnHlGrK2/l7+hy4jvv?= =?us-ascii?q?YkYqzg3MRUlo3Lmd9hMRgbqXTPZFjeFMgzsotzghRAX15NnREdfV4lM5JKg=3D?=
X-IronPort-Anti-Spam-Filtered: true
X-IronPort-Anti-Spam-Result: =?us-ascii?q?A2GRAADtUBNah2Ka6ERbDgsBAQEBAQEBA?= =?us-ascii?q?QEBAQEHAQEBAQGCSiIigRRuJ4RimGSBfX6XMhsoCiWDOIFeAoR9QhUBAQEBAQE?= =?us-ascii?q?BAQEBAhABAQEKCwkIKC+COCQBDUghCwEBAQEBAQEBASMBAQEBAQEjAg0CFhkSA?= =?us-ascii?q?QEYAQEBAQIBGg0ZBxgGFAEECwIBCA4DAwECAQoWAQYHMhQJCAIEARIIiTlcCAE?= =?us-ascii?q?Pqis6gxAvhzcBAQEBAQEEAQEBAQEBAQEBAQEVAwWDNIEOKDAhgVaBZwGCdTaFB?= =?us-ascii?q?QYSBRkGB4MZgjKKOo5tiRYGAodwg2qZSYMzhz6FNIYUgn8CBAIEBQIagTo1ghh?= =?us-ascii?q?6g0KCIzYDEAwZgQ8/dwEBAQGJCSyCGQEBAQ?=
X-IPAS-Result: =?us-ascii?q?A2GRAADtUBNah2Ka6ERbDgsBAQEBAQEBAQEBAQEHAQEBAQG?= =?us-ascii?q?CSiIigRRuJ4RimGSBfX6XMhsoCiWDOIFeAoR9QhUBAQEBAQEBAQEBAhABAQEKC?= =?us-ascii?q?wkIKC+COCQBDUghCwEBAQEBAQEBASMBAQEBAQEjAg0CFhkSAQEYAQEBAQIBGg0?= =?us-ascii?q?ZBxgGFAEECwIBCA4DAwECAQoWAQYHMhQJCAIEARIIiTlcCAEPqis6gxAvhzcBA?= =?us-ascii?q?QEBAQEEAQEBAQEBAQEBAQEVAwWDNIEOKDAhgVaBZwGCdTaFBQYSBRkGB4MZgjK?= =?us-ascii?q?KOo5tiRYGAodwg2qZSYMzhz6FNIYUgn8CBAIEBQIagTo1ghh6g0KCIzYDEAwZg?= =?us-ascii?q?Q8/dwEBAQGJCSyCGQEBAQ?=
Received: from esa4.dell-outbound2.iphmx.com ([68.232.154.98]) by esa2.dell-outbound.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Nov 2017 16:12:00 -0600
From: "Black, David" <David.Black@dell.com>
Cc: "Black, David" <David.Black@dell.com>, tcpinc <tcpinc@ietf.org>, Kyle Rose <krose@krose.org>, "tcpinc-chairs@ietf.org" <tcpinc-chairs@ietf.org>, "The IESG" <iesg@ietf.org>, "draft-ietf-tcpinc-tcpcrypt@ietf.org" <draft-ietf-tcpinc-tcpcrypt@ietf.org>
Received: from mailuogwhop.emc.com ([168.159.213.141]) by esa4.dell-outbound2.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Nov 2017 04:11:59 +0600
Received: from maildlpprd05.lss.emc.com (maildlpprd05.lss.emc.com [10.253.24.37]) by mailuogwprd05.lss.emc.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.0) with ESMTP id vAKMBu18004319 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Nov 2017 17:11:58 -0500
X-DKIM: OpenDKIM Filter v2.4.3 mailuogwprd05.lss.emc.com vAKMBu18004319
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=rsa.com; s=jan2013; t=1511215918; bh=cEaevBj915GbNltXFqlwGsEtQ6s=; h=From:To:CC:Subject:Date:Message-ID:References:In-Reply-To: Content-Type:MIME-Version; b=k9BNVK6LiNyE5bA0DzcmpFi6KNGJX+01YJXHRi0x6FnmHxKNh7oQzNbl5gTaGlmQn eR08vfO9nIOW86IunydO29MOqlpfFvBlgW6YMWgrHD3I9UVXdFjaKAn2f4swsGSEhW y4uZZr9mnGrWFyEPkDGEcfmoVJW71saNA7VpRfsc=
X-DKIM: OpenDKIM Filter v2.4.3 mailuogwprd05.lss.emc.com vAKMBu18004319
Received: from mailusrhubprd51.lss.emc.com (mailusrhubprd51.lss.emc.com [10.106.48.24]) by maildlpprd05.lss.emc.com (RSA Interceptor); Mon, 20 Nov 2017 17:11:36 -0500
Received: from MXHUB318.corp.emc.com (MXHUB318.corp.emc.com [10.146.3.96]) by mailusrhubprd51.lss.emc.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.0) with ESMTP id vAKMBfoA028836 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=FAIL); Mon, 20 Nov 2017 17:11:42 -0500
Received: from MX307CL04.corp.emc.com ([fe80::849f:5da2:11b:4385]) by MXHUB318.corp.emc.com ([10.146.3.96]) with mapi id 14.03.0352.000; Mon, 20 Nov 2017 17:11:41 -0500
To: Eric Rescorla <ekr@rtfm.com>, Daniel B Giffin <dbg@scs.stanford.edu>
Thread-Topic: [tcpinc] Eric Rescorla's Discuss on draft-ietf-tcpinc-tcpcrypt-09: (with DISCUSS and COMMENT)
Thread-Index: AQHTWprePuW0lReuTEGF9kEkArM1jaMY2o+AgAJHWQCAAsH4LA==
Date: Mon, 20 Nov 2017 22:11:41 +0000
Message-ID: <CE03DB3D7B45C245BCA0D243277949362FD6E57E@MX307CL04.corp.emc.com>
References: <151036992713.398.18032326140786383584.idtracker@ietfa.amsl.com> <20171117121703.GE57159@scs.stanford.edu>, <CABcZeBMBnMB425pu5bc9kjuAqjRDnuVYQK=8P9vQBwURctCTZQ@mail.gmail.com>
In-Reply-To: <CABcZeBMBnMB425pu5bc9kjuAqjRDnuVYQK=8P9vQBwURctCTZQ@mail.gmail.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
Content-Type: multipart/alternative; boundary="_000_CE03DB3D7B45C245BCA0D243277949362FD6E57EMX307CL04corpem_"
MIME-Version: 1.0
X-Sentrion-Hostname: mailusrhubprd51.lss.emc.com
X-RSA-Classifications: public, GIS Solicitation
Archived-At: <https://mailarchive.ietf.org/arch/msg/tcpinc/i0Umq1eNwyQ7wEw1lu3KsBucANs>
Subject: Re: [tcpinc] Eric Rescorla's Discuss on draft-ietf-tcpinc-tcpcrypt-09: (with DISCUSS and COMMENT)
X-BeenThere: tcpinc@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: "Working group mailing list for TCP Increased Security \(tcpinc\)" <tcpinc.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tcpinc>, <mailto:tcpinc-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tcpinc/>
List-Post: <mailto:tcpinc@ietf.org>
List-Help: <mailto:tcpinc-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tcpinc>, <mailto:tcpinc-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 20 Nov 2017 22:12:06 -0000

Hmm - while I'm not sure whether this resumption crypto change should be made, I'm concerned by what may be "scope creep" here, courtesy of a use case difference from TLS that weakens reasoning by analogy across the two protocols.

TLS is predominantly a user-space library protocol that is used with load-balanced server clusters, including protocol offload engines. That creates opportunities to move TLS state around, e.g., across TCP connections.

In contrast, tcpcrypt is predominantly a kernel-space protocol whose state is intended to be bound to a single TCP connection. It's much harder and less common to extract the relevant kernel protocol state, although it's possible in principle.

If this change is not made, then at a minimum, some serious warnings about avoiding resumption key reuse are in order,  as beyond GCM, that is a serious threat to all stream ciphers.

Thanks, --David ... Sent from my Android not-so-smartphone.


-------- Original message --------
From: Eric Rescorla <ekr@rtfm.com>;
Date: 11/18/17 5:05 PM (GMT-06:00)
To: Daniel B Giffin <dbg@scs.stanford.edu>;
Cc: tcpinc <tcpinc@ietf.org>;, Kyle Rose <krose@krose.org>;, tcpinc-chairs@ietf.org, The IESG <iesg@ietf.org>;, draft-ietf-tcpinc-tcpcrypt@ietf.org
Subject: Re: [tcpinc] Eric Rescorla's Discuss on draft-ietf-tcpinc-tcpcrypt-09: (with DISCUSS and COMMENT)

Hi Daniel.

I won't have a chance to review this document until Monday, but I
wanted to respond not to the point about the reuse of ss[i], because I
think you (and others) may have understood me and thought this was
primarily about tickets versus session ids, which it is not.

At a high level, tcpcrypt establishes a master secret which is then
used to create a chain of resumption secrets ss[i]. Each ss[i] value
is intended only to be used for resumption once, in which case things
are fine. However, because the only input to the traffic keys is
ss[i], if you ever reuse ss[i], the result is catastrophic
(potentially leading to a complete loss of integrity if the cipher is
AES-GCM).

By contrast, TLS 1.3 has a similar design (the secrets are a tree, not
a chain) but because there is always a nonce exchange, and the nonces
are mixed into the traffic keys, so if you *do* reuse a secret, the
main impact is that the two connections in which you use the secret
are linkable (by the ticket ID), and of course that you don't have
FS. IKE PSK has a similar design, and I think it's clear that it's
less brittle than the design in tcpcrypt.

This is an orthogonal question to whether the IDs used for resumption
are lookup keys (like in tcpcrypt) or can be self-contained (TLS 1.3
allows both lookup keys and self-contained IDs). Although designs
where one side dictates the identifier are compatible with
self-encrypted tickets, the need not be used that way, and are
compatible with FS. See, for instance:
https://tools.ietf.org/html/draft-ietf-tls-tls13-21#section-8.1.

Assuming I understand the design of tcpcrypt correctly, it seems like
the reason for the choice not to have a nonce is that you don't have
room in the SYN, and you don't want to take another round trip in the
resumption case. However, I think you can improve on the situation
somewhat even within these constraints. Here's your Figure 9 from
ENO modified to include tcpcrypt as I understand it:

             (1) A -> B:  SYN      ENO<TCPCRYPT sid[i] part 1>
             (2) B -> A:  SYN-ACK  ENO<TCPCRYPT sid[i] part 2>
             (3) A -> B:  ACK      ENO<>

A can start sending encrypted traffic after sending (3) and B can
start sending encrypted traffic after receiving (3). Am I correct
so far?

Assuming I am correct, then it seems like (B) could send a nonce
in message (2) and A could send a nonce in message (3), like so:

             (1) A -> B:  SYN      ENO<TCPCRYPT sid[i] part 1>
             (2) B -> A:  SYN-ACK  ENO<TCPCRYPT sid[i] part 2, N_a>
             (3) A -> B:  ACK      ENO<TCPCRYPT N_b>

You could then derive the keys from ss[i], N_a, and N_b, and avoid
brittleness associated with ss[i] reuse. Of course, you should still
require that people not reuse ss[i], because that gives you FS, but
the consequences if people fail to do so would not be so dire.

-Ekr




On Fri, Nov 17, 2017 at 8:17 PM, Daniel B Giffin <dbg@scs.stanford.edu<mailto:dbg@scs.stanford.edu>> wrote:
Thanks for the helpful review, Ekr!

Eric Rescorla wrote:
> ----------------------------------------------------------------------
> DISCUSS:
> ----------------------------------------------------------------------
>
> https://mozphab-ietf.devsvcdev.mozaws.net/D3970
>
>    2^64 bytes in the underlying TCP datastream (which would cause the
>    "offset" field to wrap) before re-keying.
>
> In TLS and other WGs, we have adopted the practice of
> salting the nonce with a secret per-connection value to avoid
> large-scale surveillance attacks. Why did you opt to use a weaker
> construction. See:
> https://tlswg.github.io/tls13-spec/draft-ietf-tls-tls13.html#security-record-layer
> and https://eprint.iacr.org/2016/564.

Thanks again for pointing this out.  The next draft
implements a nonce-randomizing countermeasure.  I'll excerpt
the relevant changes.  First, what was before the frame
nonce is now called the frame ID:

   Lastly, a "frame ID" (used to construct the nonce for the AEAD
   algorithm) has this format:

                     byte
                        +------+------+------+------+
                      0 |       FRAME_ID_MAGIC      |
                        +------+------+------+------+
                      4 |                           |
                        +           offset          +
                      8 |                           |
                        +------+------+------+------+


Next, the traffic keys are extended by 12 bytes to provide
bits for nonce randomization.  This bit shows where the keys
come from:

   Given a session secret "ss[i]", the two sides compute a series of
   master keys as follows:

                 mk[0] = CPRF(ss[i], CONST_REKEY, K_LEN)
                 mk[j] = CPRF(mk[j-1], CONST_REKEY, K_LEN)

   The process of advancing through the series of master keys is
   described in Section 3.8.

   Finally, each master key "mk[j]" is used to generate traffic keys for
   protecting application data using authenticated encryption:

            k_ab[j] = CPRF(mk[j], CONST_KEY_A, ae_keylen + 12)
            k_ba[j] = CPRF(mk[j], CONST_KEY_B, ae_keylen + 12)

As before, "ae_keylen" depends on the negotiated AEAD
algorithm, e.g. 16 bytes for AES128-GCM.

The encryption operation is detailed in Section 3.6.  After
explaining the construction of the "plaintext" and
"associated data" values, it explains how the frame nonce is
formed:

   A "frame ID" value (see Section 4.2.3) is also constructed for the
   frame but not explicitly transmitted.  It contains an "offset" field
   whose integer value is the zero-indexed byte offset of the beginning
   of the current encryption frame in the underlying TCP datastream.
   (That is, the offset in the framing stream, not the plaintext
   application stream.)  Because it is strictly necessary for the
   security of the AEAD algorithms specified in this document, an
   implementation MUST NOT ever transmit distinct frames with the same
   frame ID value under the same encryption key.  In particular, a
   retransmitted TCP segment MUST contain the same payload bytes for the
   same TCP sequence numbers, and a host MUST NOT transmit more than
   2^64 bytes in the underlying TCP datastream (which would cause the
   "offset" field to wrap) before re-keying.

   With reference to the "AEAD Interface" described in Section 2 of
   [RFC5116], tcpcrypt invokes the AEAD algorithm with values taken from
   the traffic key "k_ab[j]" or "k_ba[j]" for some "j", according to the
   host's role as described in Section 3.3.

   First, the traffic key is divided into two parts:

        byte   0                        ae_keylen    ae_keylen + 11
               |                           |            |
               v                           v            v
             +----+----+--...--+----+----+----+--...--+----+
             |             K             |        NR       |
             +----+----+--...--+----+----+----+--...--+----+

             \_____________________________________________/
                              traffic key

   The first "ae_keylen" bytes of the traffic key provide the AEAD key
   "K", while the remaining 12 bytes provide a "nonce randomizer" value
   "NR".  The frame ID is then combined via bitwise exclusive-or with
   the nonce randomizer to yield "N", the AEAD nonce for the frame:

                            N = frame_ID xor NR

   The plaintext value serves as "P", and the associated data as "A".
   The output of the encryption operation, "C", is transmitted in the
   frame's "ciphertext" field.

This packaging of the key and nonce bits into one value is a
little bit awkward in the above excerpts (versus say the TLS
approach of doing two separate extractions to get the two
distinct values), but elsewhere in the spec it saves a lot
of complexity because the handling of a traffic key can be
explained without reference to the nonce randomizer.

Still, I'm open to other ways of describing this.

>
>    FIN flag set, it MUST immediately send a frame (with empty
>    application data if necessary) with "rekey = 1".
>
> I don't think that the algorithm in this section
> necessarily works properly, because you have to handle rekeys in
> sequence:
>
> Frame 1 [0:999]
> Frame 2 [1000:1999, rekey=1]
> Frame 3 [2000:2999, rekey=1]
>
> Now what happens if the frames are re-ordered so you get Frame 3 and
> then Frame 2. You will try to decrypt Frame 3 with generation 2 and
> Frame 2 with generation 3, neither of which will work (though you
> might be able to interpret the text loosely to have you try to decrypt
> Frame 2 with generation 2). Note that if you were to resequence before
> processing, this wouldn't happen.
>
> At minimum I think some clarification is needed here.

As Kyle explained, it works because tcpcrypt is now
contained by the TCP datastream.  But you may be remembering
the good old days when it was simply a segment rewriter!

> Given that you are allowing P-256 and point reuse, you
> should be requiring point validation. See:
> https://tlswg.github.io/tls13-spec/draft-ietf-tls-tls13.html#rfc.section.4.2.8.2
> https://tlswg.github.io/tls13-spec/draft-ietf-tls-tls13.html#elliptic-curve-diffie-hellman

Yes, thank you.  For the NIST curves, I have added:

        Implementations MUST validate these "pubkey" values according to the
  algorithm in [ieee1363] Section A.16.10.

But I see that TLS refers to ANSI X9.62 for validation, even
though it refers to IEEE1363 for DH computation.  Is there a
good reason not to stick with the one source?

Also, I guess there's no need to check on-the-curve if we
allow only compressed format, and it's not perfectly clear
to me whether we need to check group membership, but I'd
really rather not have all these details in this document if
there's a good way to cite it out.

Lastly, I've added this to section 3.3:

   If a host receives an ephemeral public key from its peer and a
   required key-validation step fails (see Section 5), it MUST abort the
   connection and raise an error condition distinct from the end-of-file
   condition.

> You should probably also be requiring Curve25519 output validation.

I think you're saying we should check that the DH result is
not zero?

No harm, I suppose, but I'm going to try to get guidance on
whether it's necessary.

> You still seem to need to specify an MTI symmetric algorithm.

There's a table of the requirements in "6. AEAD Algorithms."
But you're not the only one who had trouble finding it, so I
wonder what's going on ...

> ----------------------------------------------------------------------
> COMMENT:
> ----------------------------------------------------------------------
>
>
> The design of session resumption here essentially precludes doing
> tcpcrypt resumption across servers (as one does with TLS) because you
> need extremely tight control of ss[i] or you have catastrophic
> results. Was this a deliberate choice by the WG?

I think it's a choice to keep key material in the kernel and
to have control over forward secrecy.

>
>    suboption containing the TEP identifier and "v = 0".  In order to
>    propose session resumption (described further below) with a
>    particular TEP, a host sends a variable-length suboption containing
>
> It would be clearer if you explained resumption here.
>
>           PRK = Extract(N_A, eno-transcript | Init1 | Init2 | ES)
> What is the rationale for providing N_A as the salt to HKDF-Extract, given that
> you also supply N_A in the Init1 message?

I'm not qualified to say.  I agree it seems "redundant", but
it appears to achieve what it needs to.  Perhaps we can find
a more satisfying answer for you ...

>    session resumption such that a given pre-session key "ss[0]" is only
>    used for either passive or active opens at the same host, not both.
> This seems like it probably needs some more emphasis, as failure to follow this
> instruction results in GCM compromise.

For our reference, here's the paragraph in question:

   A session secret may not be used to secure more than one TCP
   connection.  To prevent this, a host MUST NOT resume with a session
   secret if it has ever enabled encryption in the past with the same
   secret, in either role.  In the event that two hosts simultaneously
   send SYN segments to each other that propose resumption with the same
   session secret but the two segments are not part of a simultaneous
   open, both connections will have to revert to fresh key-exchange.  To
   avoid this limitation, implementations MAY choose to implement
   session resumption such that a given pre-session key "ss[0]" is only
   used for either passive or active opens at the same host, not both.

It seems like the straightforward implementation is to mark
a session secret "used" as soon as a resume succeeds.  The
only downside is that you could be forced to do fresh key
exchange in the case of bad timing (if you try to connect to
the host at the same time it connects to you), so the last
sentence here gives you a way to avoid that ever happening
(with I guess the downside of having to store two session
secrets for the same host).  Does it seem that this
paragraph is somehow risking a dangerous implementation?

> It would probably be useful to explain why you opted for this design rather
> than having nonces, which would remove the need for such strict ss[i]
> management. I assume the reason is that you want to save the round trip?

If I understand the question, I think the choice here is
mostly to prioritize forward secrecy.  Perhaps we can find a
way to make this more clear in Security Considerations.

>    connection; but if it aborts, the implementation MUST raise an error
>    condition distinct from the end-of-file condition.
>
> Note that this interacts badly with the rekey issue I raise below.

It's not clear exactly what you mean, but perhaps this is
another concern that is moot because of the reliable-ordered
receipt of frames?  In any case (and with relevance to some
other discussion in this thread), due to other comments we
have improved the guidance on what to do in the case of
encryption failure:

                     [...] The output of this operation is either a
   plaintext value "P" or the special symbol FAIL.  In the latter case,
   the implementation SHOULD abort the connection and raise an error
   condition distinct from the end-of-file condition.  But if none of
   the TCP segment(s) containing the frame have been acknowledged and
   retransmission could potentially result in a valid frame, an
   implementation MAY instead drop these segments.

>
>    format", and MUST accept values encoded in "compressed",
>    "uncompressed" or "hybrid" formats.
>
> Why are you allowing multiple formats here? Generally, if you're going to
> encourage compressed, you want to just require it.

That makes sense.  I'm changing this to:

   Implementations MUST encode these "pubkey" values in "compressed
   format".

Thanks again for all the useful comments.

daniel