<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc SYSTEM 'rfc2629.dtd' []>
<rfc ipr="trust200902" category="info" docName="draft-ietf-tcpinc-api-00">
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<?rfc private=""?>
<?rfc topblock="yes"?>
<?rfc comments="no"?>
<front>
<title abbrev="tcpinc-api">Interface Extensions for TCP-ENO</title>

<author initials="A." surname="Bittau" fullname="Andrea Bittau">
<organization>Stanford University</organization>
<address>
<postal>
<street>353 Serra Mall, Room 288</street>
<city>Stanford, CA</city>
<code>94305</code>
<country>US</country>
<region></region>
</postal>
<phone></phone>
<email>bittau@cs.stanford.edu</email>
<uri></uri>
</address>
</author>
<author initials="D." surname="Boneh" fullname="Dan Boneh">
<organization>Stanford University</organization>
<address>
<postal>
<street>353 Serra Mall, Room 475</street>
<city>Stanford, CA</city>
<code>94305</code>
<country>US</country>
<region></region>
</postal>
<phone></phone>
<email>dabo@cs.stanford.edu</email>
<uri></uri>
</address>
</author>
<author initials="D." surname="Giffin" fullname="Daniel B. Giffin">
<organization>Stanford University</organization>
<address>
<postal>
<street>353 Serra Mall, Room 288</street>
<city>Stanford, CA</city>
<code>94305</code>
<country>US</country>
<region></region>
</postal>
<phone></phone>
<email>dbg@scs.stanford.edu</email>
<uri></uri>
</address>
</author>
<author initials="M." surname="Handley" fullname="Mark Handley">
<organization>University College London</organization>
<address>
<postal>
<street>Gower St.</street>
<city>London</city>
<code>WC1E 6BT</code>
<country>UK</country>
<region></region>
</postal>
<phone></phone>
<email>M.Handley@cs.ucl.ac.uk</email>
<uri></uri>
</address>
</author>
<author initials="D." surname="Mazieres" fullname="David Mazieres">
<organization>Stanford University</organization>
<address>
<postal>
<street>353 Serra Mall, Room 290</street>
<city>Stanford, CA</city>
<code>94305</code>
<country>US</country>
<region></region>
</postal>
<phone></phone>
<email>dm@uun.org</email>
<uri></uri>
</address>
</author>
<author initials="E." surname="Smith" fullname="Eric W. Smith">
<organization>Kestrel Institute</organization>
<address>
<postal>
<street>3260 Hillview Avenue</street>
<city>Palo Alto, CA</city>
<code>94304</code>
<country>US</country>
<region></region>
</postal>
<phone></phone>
<email>eric.smith@kestrel.edu</email>
<uri></uri>
</address>
</author>
<date year="2016" month="July" day="8"/>

<area>Internet</area>
<workgroup></workgroup>
<keyword>tcp</keyword>
<keyword>encryption</keyword>


<abstract>
<t>TCP-ENO negotiates encryption at the transport layer.  It also defines
a few parameters that are intended to be used or configured by
applications.  This document specifies operating system interfaces for
access to these TCP-ENO parameters.  We describe the interfaces in
terms of socket options, the de facto standard API for adjusting
per-connection behavior in TCP/IP, and sysctl, a popular mechanism for
setting global defaults.  Operating systems that lack socket or sysctl
functionality can implement similar interfaces in their native
frameworks, but should ideally adapt their interfaces from those
presented in this document.
</t>
</abstract>


</front>

<middle>

<section anchor="introduction" title="Introduction">
<t>The TCP Encryption Negotiation Option (TCP-ENO)
<xref target="I-D.ietf-tcpinc-tcpeno"/> permits hosts to negotiate encryption of
a TCP connection.  One of TCP-ENO's use cases is to encrypt traffic
transparently, unbeknownst to legacy applications.  Transparent
encryption requires no changes to existing APIs.  However, other use
cases require applications to interact with TCP-ENO.  In particular:
</t>
<t>
<list style="symbols">
<t>Transparent encryption protects only against passive eavesdroppers.
Stronger security requires applications to authenticate a <spanx style="emph">Session
ID</spanx> value associated with each encrypted connection.</t>
<t>Applications that have been updated to authenticate Session IDs must
somehow advertise this fact to peers in a backward-compatible way.
TCP-ENO carries an &quot;application-aware&quot; bit for this purpose, as well
as a &quot;middleware&quot; bit, but these bits are not accessible through
existing interfaces.</t>
<t>Applications employing TCP's simultaneous open feature need a way to
configure a passive-role bit to break symmetry for TCP-ENO.</t>
<t>System administrators and applications may wish to set and examine
negotiation preferences, such as which encryption schemes (and
perhaps versions) to enable and disable.</t>
<t>Applications that perform their own encryption may wish to disable
TCP-ENO entirely.</t>
</list>
</t>
<t>The remainder of this document describes an API through which systems
can meet the above needs.  The API extensions relate back to
quantities defined by TCP-ENO.
</t>
</section>

<section anchor="api-extensions" title="API extensions">
<t>This section describes an API for per-connection options, followed by
a discussion of system-wide configuration options.
</t>

<section anchor="perconnection-options" title="Per-connection options">
<t><xref target="tab-sockopt"/> summarizes a set of options that TCP-ENO
implementations should provide on a per-socket basis.  For each
option, the table lists whether it is read-only (R) or read-write
(RW), as well as the type of the option's value.  Read-write options,
when read, always return the previously successfully written value or
the default if they have not been written.  Options of type <spanx style="verb">bytes</spanx>
consist of a variable-length array of bytes, while options of type
<spanx style="verb">int</spanx> consist of a small integer with the exact range indicated in
parentheses.  We discuss each option in more detail below.
</t>
<texttable anchor="tab-sockopt" title="Suggested per-connection options
">
<ttcol align="left">Option name</ttcol>
<ttcol align="left">RW</ttcol>
<ttcol align="left">Type</ttcol>

<c>TCP_ENO_ENABLED</c><c>RW</c><c>int (-1 - 1)</c>
<c>TCP_ENO_SESSID</c><c>R</c><c>bytes</c>
<c>TCP_ENO_NEGSPEC</c><c>R</c><c>int (32 - 127)</c>
<c>TCP_ENO_SPECS</c><c>RW</c><c>bytes</c>
<c>TCP_ENO_SELF_GOPT</c><c>RW</c><c>int (0 - 31)</c>
<c>TCP_ENO_PEER_GOPT</c><c>R</c><c>int (0 - 31)</c>
<c>TCP_ENO_ROLE</c><c>R</c><c>int (0 - 1)</c>
<c>TCP_ENO_LOCAL_NAME</c><c>R</c><c>bytes</c>
<c>TCP_ENO_PEER_NAME</c><c>R</c><c>bytes</c>
<c>TCP_ENO_RAW</c><c>RW</c><c>bytes</c>
<c>TCP_ENO_TRANSCRIPT</c><c>R</c><c>bytes</c>
</texttable>
<t>The socket options must return errors under certain circumstances.
These errors are mapped to three suggested error codes shown in
<xref target="tab-errors"/>.  Systems based on sockets already have constants for
these errors.  Non-socket systems should use existing error codes
corresponding to the same conditions.  <spanx style="verb">EINVAL</spanx> is the existing error
returned when attempting to set options or otherwise operate on a
closed socket.  <spanx style="verb">EISCONN</spanx> corresponds to calling connect a second
time, while <spanx style="verb">ENOTCONN</spanx> corresponds to requesting the peer address of
an unconnected socket.
</t>
<texttable anchor="tab-errors" title="Suggested error codes
">
<ttcol align="left">Symbol</ttcol>
<ttcol align="left">Description</ttcol>

<c>EINVAL</c><c>General error signifying bad parameters</c>
<c>EISCONN</c><c>Option no longer valid because connection established</c>
<c>ENOTCONN</c><c>Option not (yet) valid because no connection established</c>
</texttable>
<t>
<list style="hanging">
<t hangText="TCP_ENO_ENABLED">
<vspace />
When set to 0, completely disables TCP-ENO regardless of any other
socket option settings except <spanx style="verb">TCP_ENO_RAW</spanx>.  When set to 1, enables
TCP-ENO.  If set to -1, use a system-wide default determined at the
time of an <spanx style="verb">accept</spanx> or <spanx style="verb">connect</spanx> system call, as described in
<xref target="global-options"/>.  This option must return an error (<spanx style="verb">EISCONN</spanx>) after
a SYN segment has already been sent.</t>
<t hangText="TCP_ENO_SESSID">
<vspace />
Returns the session ID of the connection, as defined by the
encryption spec in use.  This option must return an error if
encryption is disabled (<spanx style="verb">EINVAL</spanx>), the connection is not yet
established (<spanx style="verb">ENOTCONN</spanx>), or the transport layer does not implement
the negotiated spec (<spanx style="verb">EINVAL</spanx>).</t>
<t hangText="TCP_ENO_NEGSPEC">
<vspace />
Returns a byte in which the lower 7 bits correspond to the spec
identifier of the negotiated encryption spec for the current
connection, and the high bit is 1 if there was suboption data present.
As defined by TCP-ENO, the negotiated spec is the last valid suboption
in host B's SYN segment.  This option must return an error if
encryption is disabled (<spanx style="verb">EINVAL</spanx>) or the connection is not yet
established (<spanx style="verb">ENOTCONN</spanx>).</t>
<t hangText="TCP_ENO_SPECS">
<vspace />
Allows the application to specify an ordered list of encryption
specs different from the system default list.  If the list is empty,
TCP-ENO is disabled for the connection.  Each byte in the list
specifies one suboption type from 0x20-0xff.  The list contains no
suboption data for variable-length suboptions, only the one-byte spec
identifier.  The high bit (<spanx style="verb">v</spanx>) in these bytes is ignored unless
future implementations of encryption specs assign it special meaning.
The order of the list matters only for the host playing the &quot;B&quot; role.
Implementations must return an error (<spanx style="verb">EISCONN</spanx>) if an application
attempts to set this option after the SYN segment has been sent.
Implementations should return an error (<spanx style="verb">EINVAL</spanx>) if any of the bytes
are below 0x20 or are not implemented by the TCP stack.</t>
<t hangText="TCP_ENO_SELF_GOPT">
<vspace />
The value is an integer from 0-31 specifying the 5-bit value of the
general suboption.  The default value should initially be 0, but the
low bit must be forced to 1 if the application configures the
connection for a passive open.</t>
<t hangText="TCP_ENO_PEER_GOPT">
<vspace />
The value is an integer from 0-31 reporting the value of the
general suboption in the peer's connection.</t>
<t hangText="TCP_ENO_ROLE">
<vspace />
The value is a bit (0 or 1).  TCP-ENO defines two roles, &quot;A&quot; and
&quot;B&quot;, for the two ends of a connection.  After a normal three-way
handshake, the active opener is &quot;A&quot; and the passive opener is &quot;B&quot;.
Simultaneous open uses the role-override bit to assign unique roles.
This option returns 0 when the local host has the &quot;A&quot; role, and 1 when
the local host has the &quot;B&quot; role.  This call must return an error
before the connection is established (<spanx style="verb">ENOTCONN</spanx>) or if TCP-ENO has
failed (<spanx style="verb">EINVAL</spanx>).</t>
<t hangText="TCP_ENO_LOCAL_NAME">
<vspace />
Returns the concatenation of the TCP_ENO_ROLE byte and the
TCP_ENO_SESSID.  This provides a unique name for the local end of the
connection.</t>
<t hangText="TCP_ENO_PEER_NAME">
<vspace />
Returns the concatenation of the negation of the TCP_ENO_ROLE byte
and the TCP_ENO_SESSID.  This is the same value as returned by
TCP_ENO_LOCAL_NAME on the other host, and hence provides a unique name
for the remote end of the connection.</t>
<t hangText="TCP_ENO_RAW">
<vspace />
This option is for use by library-level implementations of
encryption specs.  It allows applications to make use of the TCP-ENO
option, potentially including encryption specs not supported by the
transport layer, and then entirely bypass any TCP-level encryption so
as to encrypt above the transport layer.  The default value of this
option is a 0-byte vector, which disables RAW mode.  If the option is
set to any other value, it disables all other socket options described
in this section except for TCP_ENO_TRANSCRIPT.
<vspace/>

<vspace/>
The value of the option is a raw ENO option contents (without the kind
and length) to be included in the host's SYN segment.  In raw mode,
the TCP layer considers negotiation successful when the two SYN
segments both contain a suboption with the same encryption spec value
<spanx style="verb">cs</spanx> &gt;= 0x20.  For an active opener in raw mode, the TCP layer
automatically sends a two-byte minimal ENO option when negotiation is
successful.  Note that raw mode performs no sanity checking on the <spanx style="verb">v</spanx>
bits or any suboption data, and hence provides slightly less
flexibility than a true TCP-level implementation.</t>
<t hangText="TCP_ENO_TRANSCRIPT">
<vspace />
Returns the negotiation transcript as specified by TCP-ENO.
Implementations must return an error if negotiation failed (<spanx style="verb">EINVAL</spanx>)
or has not yet completed (<spanx style="verb">ENOTCONN</spanx>).</t>
</list>
</t>
</section>

<section anchor="global-options" title="Global options">
<t>In addition to these per-socket options, implementations should use a
global configuration mechanism to allow administrators to configure a
default value for <spanx style="verb">TCP_ENO_SPECS</spanx>, as well as default behavior for
when <spanx style="verb">TCP_ENO_ENABLED</spanx> is -1.  These defaults can be system-wide, or
per network namespace on systems that provide network namespaces.
</t>
<t><xref target="tab-sysctls"/> provides a table of suggested parameters.  The type
<spanx style="verb">words</spanx> corresponds to a list of 16-bit unsigned words representing
TCP port numbers (similar to the <spanx style="verb">baddynamic</spanx> sysctls that, on some
operating systems, blacklist automatic assignment of particular port
numbers).
</t>
<texttable anchor="tab-sysctls" title="Suggested global parameters
">
<ttcol align="left">Name</ttcol>
<ttcol align="left">Type</ttcol>

<c>eno_specs</c><c>bytes</c>
<c>eno_enable_connect</c><c>int (0 - 1)</c>
<c>eno_enable_listen</c><c>int (0 - 1)</c>
<c>eno_bad_connect_ports</c><c>words</c>
<c>eno_bad_listen_ports</c><c>words</c>
</texttable>
<t><spanx style="verb">eno_specs</spanx> is simply a string of bytes, and provides the default
value for the <spanx style="verb">TCP_ENO_SPECS</spanx> socket option.  If <spanx style="verb">TCP_ENO_SPECS</spanx> is
non-empty, the remaining sysctls determine whether to attempt TCP-ENO
negotiation when the <spanx style="verb">TCP_ENO_ENABLED</spanx> option is -1 (the default),
using the following rules.
</t>
<t>
<list style="symbols">
<t>On active openers: If <spanx style="verb">eno_enable_connect</spanx> is 0, then TCP-ENO is
disabled.  If the remote port number is in <spanx style="verb">eno_bad_connect_ports</spanx>,
then TCP-ENO is disabled.  Otherwise, the host attempts to use
TCP-ENO.</t>
<t>On passive openers:  If <spanx style="verb">eno_enable_listen</spanx> is 0, then TCP-ENO is
disabled.  Otherwise, if the local port is in
<spanx style="verb">eno_bad_listen_ports</spanx>, then TCP-ENO is disabled.  Otherwise, if the
host receives an SYN segment with an ENO option containing
compatible encryption specs, it attempts negotiation.</t>
</list>
</t>
<t>Because initial deployment may run into issues with middleboxes or
incur slowdown for unnecessary double-encryption, sites may wish to
blacklist particular ports.  For example setting
<spanx style="verb">eno_bad_connect_ports</spanx> to 443,993 would disable ENO encryption on
outgoing connections to ports 443 and 993 (which use application-layer
encryption for HTTP and IMAP, respectively).  If the per-socket
<spanx style="verb">TCP_ENO_ENABLED</spanx> is not -1, it overrides the sysctl values.
</t>
<t>Similarly, on a server, setting <spanx style="verb">eno_bad_listen_ports</spanx> to 443 makes it
possible to disable TCP-ENO for incoming HTTPS connection without
modifying the web server to set <spanx style="verb">TCP_ENO_ENABLED</spanx> to 0.
</t>
</section>
</section>

<section anchor="example-api-mappings" title="Example API mappings">
<t><xref target="api-extensions"/> presented abstract APIs for per-connection and
global options.  One implementation strategy would be to map these
APIs to existing per-socket and global configuration mechanisms.  By
way of example, this section describes a way to map the per-connection
settings to BSD sockets options and global configuration to the Unix
<spanx style="verb">sysctl</spanx> interface.
</t>

<section anchor="socket-options-for-perconnection-settings" title="Socket options for per-connection settings">
<t>Systems with sockets can allow applications to configure TCP-ENO
through the same mechanism they use for other TCP connection
configuration such as <spanx style="verb">TCP_NODELAY</spanx> <xref target="RFC0896"/>, namely the
<spanx style="verb">getsockopt</spanx> and <spanx style="verb">setsockopt</spanx> system calls shown in <xref target="fig:sockopt"/>.
</t>

<figure anchor="fig:sockopt" align="center" title="Socket option API
"><artwork align="center" type="C">
int getsockopt(int socket, int level, int option_name,
               void *option_value, socklen_t *option_len);

int setsockopt(int socket, int level, int option_name,
               const void *option_value, socklen_t option_len);
</artwork></figure>
<t>Socket-based TCP-ENO implementations can define a set of new
<spanx style="verb">option_name</spanx> values accessible at <spanx style="verb">level</spanx> <spanx style="verb">IPPROTO_TCP</spanx> (generally
defined as 6, to match the IP protocol field), where each entry in
<xref target="tab-sockopt"/> corresponds to a unique <spanx style="verb">option_name</spanx> constant.
</t>
</section>

<section anchor="setting-systemwide-options-with-sysctl" title="Setting System-wide options with sysctl">
<t>User-level implementations of TCP-ENO can use a configuration file to
set global options.  However, such an approach may be awkward for
kernel-based implementations.  Instead, kernel-level implementations
can use the <spanx style="verb">sysctl</spanx> configuration tool.  With this approach, TCP-ENO
parameters should be placed alongside most TCP parameters.  For
example, on BSD derived systems a suitable name would be
<spanx style="verb">net.inet.tcp.eno.specs</spanx>, while on Linux a more appropriate name would
be <spanx style="verb">net.ipv4.tcp_eno_specs</spanx>.
</t>
</section>
</section>

<section anchor="examples" title="Examples">
<t>This section provides examples of how applications might authenticate
session IDs.  Authentication requires exchanging messages over the TCP
connection, and hence is not backwards compatible with existing
application protocols.  To fall back to opportunistic encryption in
the event that both applications have not been updated to authenticate
the session ID, TCP-ENO provides the application-aware bits.  To
signal it has been upgraded to support application-level
authentication, an application should set <spanx style="verb">TCP_ENO_SELF_AWARE</spanx> to 1
before opening a connection.  An application should then check that
<spanx style="verb">TCP_ENO_PEER_AWARE</spanx> is non-zero before attempting to send
authenticators that would otherwise be misinterpreted as application
data.
</t>

<section anchor="cookiebased-authentication" title="Cookie-based authentication">
<t>In cookie-based authentication, a client and server both share a
cryptographically strong random or pseudo-random secret known as a
&quot;cookie&quot;.  Such a cookie is preferably at least 128 bits long.  To
authenticate a session ID using a cookie, each host computes and sends
the following value to the other side:
</t>

<figure align="center"><artwork align="center">
authenticator = PRF(cookie, local-name)
</artwork></figure>
<t>Here <spanx style="verb">PRF</spanx> is a pseudo-random function such as HMAC-SHA-256
<xref target="RFC6234"/>.  <spanx style="verb">local-name</spanx> is the result of the <spanx style="verb">TCP_ENO_LOCAL_NAME</spanx>
socket option.  Each side must verify that the other side's
authenticator is correct.  To do so, software obtains the remote
host's local name via the <spanx style="verb">TCP_ENO_PEER_NAME</spanx> socket option.  Assuming
the authenticators are correct, applications can rely on the TCP-layer
encryption for resistance against active network attackers.
</t>
<t>Note that if the same cookie is used in other contexts besides session
ID authentication, appropriate domain separation must be employed,
such as prefixing <spanx style="verb">local-name</spanx> with a unique prefix to ensure
<spanx style="verb">authenticator</spanx> cannot be used out of context.
</t>
</section>

<section anchor="signaturebased-authentication" title="Signature-based authentication">
<t>In signature-based authentication, one or both endpoints of a
connection possess a private signature key the public half of which is
known to or verifiable by the other endpoint.  To authenticate itself,
the host with a private key computes the following signature:
</t>

<figure align="center"><artwork align="center">
authenticator = Sign(PrivKey, local-name)
</artwork></figure>
<t>The other end verifies this value using the corresponding public key.
Whichever side validates an authenticator in this way knows that the
other side belongs to a host that possesses the appropriate signature
key.
</t>
<t>Once again, if the same signature key is used in other contexts
besides session ID authentication, appropriate domain separation
should be employed, such as prefixing <spanx style="verb">local-name</spanx> with a unique
prefix to ensure <spanx style="verb">authenticator</spanx> cannot be used out of context.
</t>
</section>
</section>

<section anchor="security-considerations" title="Security considerations">
<t>The TCP-ENO specification discusses several important security
considerations that this document incorporates by reference.  The most
important one, which bears reiterating, is that until and unless a
session ID has been authenticated, TCP-ENO is vulnerable to an active
network attacker, through either a downgrade or active
man-in-the-middle attack.
</t>
<t>Because of this vulnerability to active network attackers, it is
critical that implementations return appropriate errors for socket
options when TCP-ENO is not enabled.  Equally critical is that
applications must never use these socket options without checking for
errors.
</t>
<t>Applications with high security requirements that rely on TCP-ENO for
security must either fail or fall back to application-layer encryption
if TCP-ENO fails or session IDs authentication fails.
</t>
</section>

<section anchor="acknowledgments" title="Acknowledgments">
<t>This work was funded by DARPA CRASH under contract #N66001-10-2-4088.
</t>
</section>

</middle>
<back>
<references title="Normative References">
<?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml3/reference.I-D.draft-ietf-tcpinc-tcpeno-01.xml"?>
</references>
<references title="Informative References">
<?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.0896.xml"?>
<?rfc include="http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6234.xml"?>
</references>

</back>
</rfc>
