<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.2.8 -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
]>

<?rfc toc="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>

<rfc ipr="trust200902" docName="draft-schwartz-tls-lb-02" category="std">

  <front>
    <title abbrev="TLS-LB">TLS Metadata for Load Balancers</title>

    <author initials="B." surname="Schwartz" fullname="Benjamin M. Schwartz">
      <organization>Google LLC</organization>
      <address>
        <email>bemasc@google.com</email>
      </address>
    </author>

    <date year="2019" month="October" day="31"/>

    <area>sec</area>
    <workgroup>tls</workgroup>
    <keyword>Internet-Draft</keyword>

    <abstract>


<t>A load balancer that does not terminate TLS may wish to provide some information to the backend server, in addition to forwarding TLS data.  This draft proposes a protocol between load balancers and backends that enables secure, efficient delivery of TLS with additional information.  The need for such a protocol has recently become apparent in the context of split mode ESNI.</t>



    </abstract>


  </front>

  <middle>


<section anchor="conventions-and-definitions" title="Conventions and Definitions">

<t>The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL
NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”,
“MAY”, and “OPTIONAL” in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

<t>Data encodings are expressed in the TLS 1.3 presentation language, as defined in Section 3 of <xref target="TLS13"/>.</t>

</section>
<section anchor="background" title="Background">

<t>A load balancer is a server or bank of servers that acts as an intermediary between the client and a range of backend servers.  As the name suggests, a load balancer’s primary function is to ensure that client traffic is spread evenly across the available backend servers.  However load balancers also serve many other functions, such as identifying connections intended for different backends and forwarding them appropriately, or dropping connections that are deemed malicious.</t>

<t>A load balancer operates at a specific point in the protocol stack, forwarding e.g. IP packets, TCP streams, TLS contents, HTTP requests, etc.  Most relevant to this proposal are TCP and TLS load balancers.  TCP load balancers terminate the TCP connection with the client and establish a new TCP connection to the selected backend, bidirectionally copying the TCP contents between these two connections.  TLS load balancers additionally terminate the TLS connection, forwarding the plaintext to the backend server (typically inside a new TLS connection).  TLS load balancers must therefore hold the private keys for the domains they serve.</t>

<t>When a TCP load balancer forwards a TLS stream, the load balancer has no way to incorporate additional information into the stream.  Insertion of any additional data would cause the connection to fail.  However, the load-balancer and backend can share additional information if they agree to speak a new protocol.  The most popular protocol used for this purpose is currently the PROXY protocol <xref target="PROXY"/>, developed by HAPROXY.  This protocol prepends a plaintext collection of metadata (e.g. client IP address) onto the TCP socket.  The backend can parse this metadata, then pass the remainder of the stream to its TLS library.</t>

<t>The PROXY protocol is effective and widely used, but it offers no confidentiality or integrity protection, and therefore might not be suitable when the load balancer and backend communicate over the public internet.  It also does not offer a way for the backend to reply.</t>

</section>
<section anchor="goals" title="Goals">

<t><list style="symbols">
  <t>Enable TCP load balancers to forward metadata to the backend.</t>
  <t>Enable backends to reply.</t>
  <t>Reduce the need for TLS-terminating load balancers.</t>
  <t>Ensure confidentiality and integrity for all forwarded metadata.</t>
  <t>Enable split ESNI architectures.</t>
  <t>Prove to the backend that the load balancer intended to associate this metadata with this connection.</t>
  <t>Achieve good CPU and memory efficiency.</t>
  <t>Don’t impose additional latency.</t>
  <t>Support backends that receive a mixture of direct and load-balanced TLS.</t>
  <t>Enable simple and safe implementation.</t>
</list></t>

</section>
<section anchor="overview" title="Overview">

<t>The proposed protocol supports a two-way exchange between a load balancer and a backend server.  It works by prepending information to the TLS handshake:</t>

<figure title="Data flow diagram" anchor="diagram"><artwork><![CDATA[
     +-----------+ +-----------+ +-----------+
     | Backend A | | Backend B | | Backend C |
     +-----------+ +-----------+ +-----------+
                       \/   /\
4. EncryptedProxyData[ \/   /\  3. ClientHello (verbatim)
    got SNI info]      \/   /\  2. EncryptedProxyData[
5. ServerHello, etc.   \/   /\       SNI="secret.b",
                       \/   /\       client=2, etc.]
                       \/   /\
                  +---------------+
                  | Load balancer |
                  +---------------+
                       \/   /\
6. ServerHello, etc.   \/   /\  1. ClientHello[
   (verbatim)          \/   /\       ESNI=enc("secret.b")]
                       \/   /\
      +-----------+ +-----------+ +-----------+
      |  Client 1 | |  Client 2 | |  Client 3 |
      +-----------+ +-----------+ +-----------+
]]></artwork></figure>

</section>
<section anchor="encoding" title="Encoding">

<t>A ProxyExtension is identical in form to a standard TLS Extension (Section 4.2 of <xref target="TLS13"/>), with a new identifier space for the extension types.</t>

<figure><artwork><![CDATA[
struct {
  ProxyExtensionType extension_type;
  opaque extension_data<0..2^16-1>;
} ProxyExtension;
]]></artwork></figure>

<t>ProxyExtensions can be sent in an upstream (to the backend) or downstream (to the load balancer) direction</t>

<figure><artwork><![CDATA[
enum {
  upstream(0),
  downstream(1),
  (255)
} ProxyDataDirection;
]]></artwork></figure>

<t>The ProxyData contains a set of ProxyExtensions.</t>

<figure><artwork><![CDATA[
struct {
  ProxyDataDirection direction;
  ProxyExtension proxy_data<0..2^16-1>;
} ProxyData;
]]></artwork></figure>

<t>The EncryptedProxyData structure contains metadata associated with the original ClientHello (Section 4.1.2 of <xref target="TLS13"/>), encrypted with a pre-shared key that is configured out of band.</t>

<figure><artwork><![CDATA[
struct {
  opaque psk_identity<1..2^16-1>;
  opaque nonce<8..2^16-1>
  opaque encrypted_proxy_data<1..2^16-1>;
} EncryptedProxyData;
]]></artwork></figure>

<t><list style="symbols">
  <t><spanx style="verb">psk_identity</spanx>: The identity of a PSK previously agreed upon by the load balancer and the backend.  Including the PSK identity allows for updating the PSK without disruption.</t>
  <t><spanx style="verb">nonce</spanx>: Non-repeating initializer for the AEAD.  This prevents an attacker from observing whether the same ClientHello is marked with different metadata over time.</t>
  <t><spanx style="verb">encrypted_proxy_data</spanx>: <spanx style="verb">AEAD-Encrypt(key, nonce, additional_data, plaintext=ProxyData)</spanx>.  The key and AEAD function are agreed out of band and associated with <spanx style="verb">psk_identity</spanx>.  The <spanx style="verb">additional_data</spanx> is context-dependent.</t>
</list></t>

<t>When the load balancer receives a ClientHello, it serializes any relevant metadata into an upstream ProxyData, then encrypts it with the ClientHello as <spanx style="verb">additional_data</spanx> to produce the EncryptedProxyData.  The backend’s reply is a downstream ProxyData struct, also transmitted as an EncryptedProxyData, using the upstream EncryptedProxyData as <spanx style="verb">additional_data</spanx>.  Recipients in each case MUST verify that <spanx style="verb">ProxyData.direction</spanx> has the expected value, and discard the connection if it does not.</t>

<t>The downstream ProxyData SHOULD NOT contain any ProxyExtensionType values that were not present in the upstream ProxyData.</t>

</section>
<section anchor="defined-proxyextensions" title="Defined ProxyExtensions">

<t>Like a standard TLS Extension, a ProxyExtension is identified by a uint16 type number.  Load balancers MUST only include extensions that are registered for use in ProxyData.  Backends MUST ignore any extensions that they do not recognize.</t>

<t>There are initially seven type numbers allocated:</t>

<figure><artwork><![CDATA[
enum {
  padding(0),
  client_address(1),
  destination_address(2),
  esni_inner(3),
  certificate_padding(4),
  overload(5),
  ratchet(6),
  (65535)
} ProxyExtensionType;
]]></artwork></figure>

<section anchor="padding" title="padding">

<t>The “padding” extension functions as described in <xref target="RFC7685"/>.  It is used here to avoid leaking information about the other extensions.  It can be used in upstream and downstream ProxyData.</t>

</section>
<section anchor="clientaddress" title="client_address">

<t>The “client_address” extension functions as described in <xref target="I-D.kinnear-tls-client-net-address"/>.  It conveys the client IP address observed by the load balancer.  Backends that make use of this extension SHOULD include an empty “client_address” extension in the downstream ProxyData.</t>

</section>
<section anchor="destinationaddress" title="destination_address">

<t>The “destination_address” extension is identical to the “client_address” extension, except that it contains the load balancer’s server IP address that received this connection.</t>

</section>
<section anchor="esniinner" title="esni_inner">

<t>The “esni_inner” extension is only sent upstream, and can only be used if the ClientHello contains the encrypted_server_name extension <xref target="ESNI"/>.  The <spanx style="verb">extension_data</spanx> is the ClientESNIInner (Section 5.1.1 of <xref target="ESNI"/>), which contains the true SNI and nonce.  This is useful when the load balancer knows the ESNI private key and the backend does not, i.e. split mode ESNI.</t>

</section>
<section anchor="certificatepadding" title="certificate_padding">

<t>The “certificate_padding” extension always contains a single uint32 value.  The upstream value conveys the padding granularity <spanx style="verb">G</spanx>, and the downstream value indicates the unpadded size of the Certificate struct (Section 4.4.2 of <xref target="TLS13"/>).</t>

<t>To pad the Handshake message (Section 4 of <xref target="TLS13"/>) containing the Certificate struct, the backend SHOULD select the smallest <spanx style="verb">length_of_padding</spanx> (Section 5.2 of <xref target="TLS13"/>) such that <spanx style="verb">Handshake.length + length_of_padding</spanx> is a multiple of <spanx style="verb">G</spanx>.</t>

<t>The load balancer SHOULD include this extension whenever it sends the “esni_inner” extension.</t>

<t>Padding certificates from many backends to the same length is important to avoid revealing which backend is responding to a ClientHello.  Load balancer operators SHOULD ensure that no backend has a unique certificate size after padding, and MAY set <spanx style="verb">G</spanx> large enough to make all responses have equal size.</t>

</section>
<section anchor="overload" title="overload">

<t>In the upstream ProxyData, the “overload” extension contains a single uint16 indicating the approximate proportion of connections that are being routed to this server as a fraction of 65535.  If there is only one server, load balancers SHOULD set the value to 65535.</t>

<t>In the downstream ProxyData, the value is an OverloadValue:</t>

<figure><artwork><![CDATA[
enum {
  accepted(0),
  overloaded(1),
  rejected(2),
  (255)
} OverloadState;
struct {
  OverloadState state;
  uint16 load;
  uint32 ttl;
} OverloadValue;
]]></artwork></figure>

<t>When <spanx style="verb">OverloadValue.state</spanx> is “accepted”, the backend is accepting connections normally.  The “overloaded” state indicates that the backend is accepting this connection, but would prefer not to receive additional connections.  A value of “rejected” indicates that the backend did not accept this connection.  When sending a “rejected” response, the backend SHOULD close the connection without sending a ServerHello.</t>

<t><spanx style="verb">OverloadValue.load</spanx> indicates the load fraction of the responding backend server, with 65535 indicating maximum load.</t>

<t>The load balancer SHOULD treat this information as valid for <spanx style="verb">OverloadValue.ttl</spanx> seconds, or until it receives another OverloadValue from that server.</t>

<t>Load balancers that have multiple available backends for an origin SHOULD avoid connecting to servers that are in the “overloaded” or “rejected” state.  When a connection is rejected, the load balancer MAY retry that connection by sending the ClientHello to a different backend server.  When multiple servers are in the “accepted” state, the load balancer MAY use <spanx style="verb">OverloadValue.load</spanx> to choose among them.</t>

<t>When there is a server in an unknown state (i.e. a new server or one whose last TTL has expired), the load balancer SHOULD direct at least one connection to it, in order to refresh its OverloadState.</t>

<t>If all servers are in the “overloaded” or “rejected” state, the load balancer SHOULD drop the connection.</t>

</section>
<section anchor="ratchet" title="ratchet">

<t>If the backend server is reachable without traversing the load balancer, and an adversary can observe packets on the link between the load balancer and the backend, then that adversary can execute a replay flooding attack, sending the backend server duplicate copies of observed EncryptedProxyData and ClientHello.  This attack can waste server resources on the Diffie-Hellman operations required to process the ClientHello, resulting in denial of service.</t>

<t>The “ratchet” extension reduces the impact of such an attack on the backend server by allowing the backend to reject these duplicates after decrypting the ProxyData.  (This decryption uses only a symmetric cipher, so it is expected to be much faster than typical Diffie-Hellman operations.)  Its upstream payload consists of a RatchetValue:</t>

<figure><artwork><![CDATA[
struct {
  uint64 index;
  uint64 floor;
} RatchetValue;
]]></artwork></figure>

<t>A RatchetValue is scoped to a single backend server and <spanx style="verb">psk_identity</spanx>.  Within that scope, the load balancer initializes <spanx style="verb">index</spanx> to a random value, and executes the following procedure:</t>

<t><list style="numbers">
  <t>For each new forwarded connection (to the same server under the same <spanx style="verb">psk_identity</spanx>), increment <spanx style="verb">index</spanx>.</t>
  <t>Set <spanx style="verb">floor</spanx> to the <spanx style="verb">index</spanx> of the earliest connection that has not yet been connected or closed.</t>
</list></t>

<t>The backend server initializes <spanx style="verb">floor</spanx> to the first <spanx style="verb">RatchetValue.floor</spanx> it receives (under a <spanx style="verb">psk_identity</spanx>), and then executes the following procedure for each incoming connection:</t>

<t><list style="numbers">
  <t>Define <spanx style="verb">a &gt;= b</spanx> if the most significant bit of <spanx style="verb">a - b</spanx> is 0.</t>
  <t>Let <spanx style="verb">newValue</spanx> be the RatchetValue in the ProxyData.</t>
  <t>If <spanx style="verb">newValue.index &lt; floor</spanx>, ignore the connection.</t>
  <t>If <spanx style="verb">newValue.floor &gt;= floor</spanx>, set <spanx style="verb">floor</spanx> to <spanx style="verb">newValue.floor</spanx>.</t>
  <t>OPTIONALLY, ignore the connection if <spanx style="verb">newValue.index</spanx> has been seen recently.  This can be implemented efficiently by keeping track of any <spanx style="verb">index</spanx> values greater than <spanx style="verb">floor</spanx> that appear to have been skipped.</t>
</list></t>

<t>With these measures in place, replays can be rejected without processing the ClientHello.</t>

<t>In principle, this replay protection fails after 2^64 connections when the <spanx style="verb">floor</spanx> value wraps.  On a backend server that averages 10^9 new connections per second, this would occur after 584 years.  To avoid this replay attack, load balancers and backends SHOULD establish a new PSK at least this often.</t>

<t>Backends that are making use of the “ratchet” extension SHOULD include an empty “ratchet” extension in their downstream ProxyData.</t>

</section>
</section>
<section anchor="protocol-wire-format" title="Protocol wire format">

<t>When forwarding a TLS stream over TCP, the load balancer SHOULD prepend a TLSPlaintext whose <spanx style="verb">content_type</spanx> is XX (proxy_header) and whose <spanx style="verb">fragment</spanx> is the EncryptedProxyData.</t>

<t>Following this proxy header, the load balancer MUST send the full contents of the TCP stream, exactly as received from the client.  The backend will observe the proxy header, immediately followed by a TLSPlaintext containing the ClientHello.  The backend will decrypt the EncryptedProxyData using the ClientHello as associated data, and process the ClientHello and the remainder of the stream as standard TLS.</t>

<t>Similarly, the backend SHOULD reply with the downstream EncryptedProxyData in a proxy header, followed by the normal TLS stream, beginning with a TLSPlaintext frame containing the ServerHello.  If the downstream ProxyHeader is not present, has an unrecognized version number, or produces an error, the load balancer SHOULD proxy the rest of the stream regardless.</t>

</section>
<section anchor="security-considerations" title="Security considerations">

<section anchor="integrity" title="Integrity">

<t>This protocol is intended to provide both parties with a strong guarantee of integrity for the metadata they receive.  For example, an active attacker cannot take metadata intended for one stream and attach it to another, because each stream will have a unique ClientHello, and the metadata is bound to the ClientHello by AEAD.</t>

<t>One exception to this protection is in the case of an attacker who deliberately reissues identical ClientHello messages.  An attacker who reuses a ClientHello can also reuse the metadata associated with it, if they can first observe the EncryptedProxyData transferred between the load balancer and the backend.  This could be used by an attacker to reissue data originally generated by a true client (e.g. as part of a 0-RTT replay attack), or it could be used by a group of adversaries who are willing to share a single set of client secrets while initiating different sessions, in order to reuse metadata that they find helpful.</t>

<t>Backends that are sensitive to this attack SHOULD implement the “ratchet” mechanism in <xref target="ratchet"/>, including the optional defenses.</t>

</section>
<section anchor="confidentiality" title="Confidentiality">

<t>This protocol is intended to maintain confidentiality of the metadata transferred between the load balancer and backend, especially the ESNI plaintext and the client IP address.  An observer between the client and the load balancer does not observe this protocol at all, and an observer between the load balancer and backend observes only ciphertext.</t>

<t>However, an adversary who can monitor both of these links can easily observe that a connection from the client to the load balancer is shortly followed by a connection from the load balancer to a backend, with the same ClientHello.  This reveals which backend server the client intended to visit.  In many cases, the choice of backend server could be the sensitive information that ESNI is intended to protect.</t>

</section>
<section anchor="fingerprinting" title="Fingerprinting">

<t>Connections to different domains might be distinguishable by the cleartext contents of the ServerHello, such as <spanx style="verb">cipher_suite</spanx> and <spanx style="verb">server_share.group</spanx>.  Load balancer operators with ESNI support SHOULD provide backend operators with a list of cipher suites and groups to support, and a preference order, to avoid different backends having distinctive behaviors.</t>

</section>
</section>
<section anchor="iana-considerations" title="IANA Considerations">

<t>IANA will be directed to add the following allocation to the TLS ContentType registry:</t>

<texttable>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>DTLS-OK</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>XX</c>
      <c>proxy_header</c>
      <c>N</c>
      <c>This document</c>
</texttable>

<t>IANA will be directed to create a new “TLS ProxyExtensionType Values” registry on the TLS Extensions page.  Values less than 0x8000 will be subject to the “RFC Required” registration procedure, and the rest will be “First Come First Served”.  To avoid codepoint exhaustion, proxy developers SHOULD pack all their nonstandard information into a single ProxyExtension.</t>

</section>


  </middle>

  <back>

    <references title='Normative References'>





<reference  anchor="RFC2119" target='https://www.rfc-editor.org/info/rfc2119'>
<front>
<title>Key words for use in RFCs to Indicate Requirement Levels</title>
<author initials='S.' surname='Bradner' fullname='S. Bradner'><organization /></author>
<date year='1997' month='March' />
<abstract><t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t></abstract>
</front>
<seriesInfo name='BCP' value='14'/>
<seriesInfo name='RFC' value='2119'/>
<seriesInfo name='DOI' value='10.17487/RFC2119'/>
</reference>



<reference  anchor="RFC8174" target='https://www.rfc-editor.org/info/rfc8174'>
<front>
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
<author initials='B.' surname='Leiba' fullname='B. Leiba'><organization /></author>
<date year='2017' month='May' />
<abstract><t>RFC 2119 specifies common key words that may be used in protocol  specifications.  This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the  defined special meanings.</t></abstract>
</front>
<seriesInfo name='BCP' value='14'/>
<seriesInfo name='RFC' value='8174'/>
<seriesInfo name='DOI' value='10.17487/RFC8174'/>
</reference>



<reference  anchor="TLS13" target='https://www.rfc-editor.org/info/rfc8446'>
<front>
<title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
<author initials='E.' surname='Rescorla' fullname='E. Rescorla'><organization /></author>
<date year='2018' month='August' />
<abstract><t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol.  TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t><t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961.  This document also specifies new requirements for TLS 1.2 implementations.</t></abstract>
</front>
<seriesInfo name='RFC' value='8446'/>
<seriesInfo name='DOI' value='10.17487/RFC8446'/>
</reference>



<reference  anchor="RFC7685" target='https://www.rfc-editor.org/info/rfc7685'>
<front>
<title>A Transport Layer Security (TLS) ClientHello Padding Extension</title>
<author initials='A.' surname='Langley' fullname='A. Langley'><organization /></author>
<date year='2015' month='October' />
<abstract><t>This memo describes a Transport Layer Security (TLS) extension that can be used to pad ClientHello messages to a desired size.</t></abstract>
</front>
<seriesInfo name='RFC' value='7685'/>
<seriesInfo name='DOI' value='10.17487/RFC7685'/>
</reference>



<reference anchor="I-D.kinnear-tls-client-net-address">
<front>
<title>TLS Client Network Address Extension</title>

<author initials='E' surname='Kinnear' fullname='Eric Kinnear'>
    <organization />
</author>

<author initials='T' surname='Pauly' fullname='Tommy Pauly'>
    <organization />
</author>

<author initials='C' surname='Wood' fullname='Christopher Wood'>
    <organization />
</author>

<date month='March' day='11' year='2019' />

<abstract><t>This document describes a TLS 1.3 extension that can be by clients to request their public network address from a server.  This information can be used for a variety of purposes, including: NAT detection, ASN identification, and privacy-driven transport protocol features.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-kinnear-tls-client-net-address-00' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-kinnear-tls-client-net-address-00.txt' />
</reference>



<reference anchor="ESNI">
<front>
<title>Encrypted Server Name Indication for TLS 1.3</title>

<author initials='E' surname='Rescorla' fullname='Eric Rescorla'>
    <organization />
</author>

<author initials='K' surname='Oku' fullname='Kazuho Oku'>
    <organization />
</author>

<author initials='N' surname='Sullivan' fullname='Nick Sullivan'>
    <organization />
</author>

<author initials='C' surname='Wood' fullname='Christopher Wood'>
    <organization />
</author>

<date month='July' day='8' year='2019' />

<abstract><t>This document defines a simple mechanism for encrypting the Server Name Indication for TLS 1.3.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-ietf-tls-esni-04' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-ietf-tls-esni-04.txt' />
</reference>




    </references>

    <references title='Informative References'>

<reference anchor="PROXY" target="https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt">
  <front>
    <title>The PROXY protocol</title>
    <author initials="W." surname="Tarreau" fullname="Willy Tarreau">
      <organization>HAProxy Technologies</organization>
    </author>
    <date year="2017" month="March"/>
  </front>
</reference>


    </references>


<section anchor="acknowledgements" title="Acknowledgements">

<t>This is an elaboration of an idea proposed by Eric Rescorla during the development of ESNI.  Thanks to David Schinazi, David Benjamin, and Piotr Sikora for suggesting important improvements.</t>

</section>


  </back>

<!-- ##markdown-source:
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
8AtPcBL509H/AUIm5LdbSAAA

-->

</rfc>

