<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.23 (Ruby 3.2.3) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-guo-privacypass-token-binding-00" category="std" consensus="true" submissionType="IETF" xml:lang="en" version="3">
  <!-- xml2rfc v2v3 conversion 3.27.0 -->
  <front>
    <title abbrev="Privacy Pass Token Binding">Privacy Pass with Token Binding Extension</title>
    <seriesInfo name="Internet-Draft" value="draft-guo-privacypass-token-binding-00"/>
    <author initials="W." surname="Guo" fullname="Wei Guo">
      <organization>Huawei Technologies</organization>
      <address>
        <email>guowei90@huawei.com</email>
      </address>
    </author>
    <author initials="Y." surname="Li" fullname="Yong Li">
      <organization>Huawei Technologies</organization>
      <address>
        <email>Yong.Li1@huawei.com</email>
      </address>
    </author>
    <author initials="J." surname="Li" fullname="Ji Li">
      <organization>Huawei Technologies</organization>
      <address>
        <email>liji100@huawei.com</email>
      </address>
    </author>
    <author initials="L." surname="Xia" fullname="Liang Xia">
      <organization>Huawei Technologies</organization>
      <address>
        <email>frank.xialiang@huawei.com</email>
      </address>
    </author>
    <date year="2025" month="February" day="28"/>
    <area>General</area>
    <workgroup>Internet Engineering Task Force</workgroup>
    <keyword>keyword1</keyword>
    <keyword>keyword2</keyword>
    <keyword>keyword3</keyword>
    <abstract>
      <?line 60?>

<t>This document provides a token binding extension for the Privacy Pass protocol. This extension allows a Client to cryptographically bind a Privacy Pass token to its own generated one-time public key during the issuance flow, without exposing the public key to the Issuer. Later, when spending the token during the redemption flow, the Client must use the corresponding private key to generate a binding proof that the Origin needs to additionally verify except the token itself, where the proof generation can optionally support channel binding. This proof constrains the legitimate presenter of the token to be only the Client who holds the private key and further constrains the legitimate usage of the token to be only the Client's specific channel when channel binding is used in the proof generation, and thus can prevent token export and replay attacks. In addition, the token binding extension does not introduce additional cryptographic primitives, and only uses the primitives currently utilized in the issuance protocol to generate the one-time public-private keypair as well as generate and verify the binding proof.</t>
    </abstract>
  </front>
  <middle>
    <?line 64?>

<section anchor="intro">
      <name>Introduction</name>
      <t>Privacy Pass provides an anonymous authorization architecture based on privacy-preserving authentication mechanisms <xref target="RFC9576"/>, and it consists of the issuance protocol and the redemption protocol. In the issuance protocol <xref target="RFC9578"/>, a Client can interact with a token Issuer to obtain Privacy Pass tokens after completing some authentication successfully, where the tokens are generated by the Issuer using the Issuer Private Key. In the redemption protocol <xref target="RFC9577"/>, the Client holding such a token can prove to an Origin that it is authorized by the Issuer to access the Origin's protected resources, without allowing the Origin (even with the Issuer) to link it with the issuance flow.</t>
      <t>However, Privacy Pass tokens pertain to bearer tokens, and any party in possession of Privacy Pass tokens can also access to the protected resources. Therefore, attackers can take advantage of this by exporting Privacy Pass tokens from a user's machines or application connections, presenting them to the application server (the Origin), and impersonating the legitimate user. The token binding extension for the Privacy Pass protocol is to prevent such attacks by cryptographically binding a Privacy Pass token to the user agent (the Client) generated one-time public key and requiring the Client presenting the token to additionally prove possession of the corresponding private key.</t>
      <t>In addition, this extension does not introduce additional cryptographic primitives, and only uses the primitives (such as Schnorr NIZKP in <xref section="2.2" sectionFormat="of" target="RFC9497"/> and RSA signature in <xref target="RFC8017"/>) currently utilized in the issuance protocol to generate the one-time public-private keypair as well as generate and verify the binding proof. Specifically, we choose the Schnorr NIZKP to achieve token binding for both privately verifiable tokens and publicly verifiable tokens because of the following reasons: 1) the keypair of the Schnorr NIZKP can be generated from a secure seed, which is not supported by the RSA signature; 2) the keypair generation of the Schnorr NIZKP is much faster than that of the RSA signature. Because the keypair is only used one time, a more lightweight proving is to directly present the one-time private key to the Origin, which is so not a zero-knowledge proof, and its verification procedure needs to compute the corresponding one-time public key and verify the bound token.
<!-- at some point time and recovered from this seed at any time in the future -->
      </t>
      <t>At a high level, Privacy Pass with token binding extension proceeds as follows. First, a Client generates a one-time public-private keypair probably within a secure hardware module, such as a Trusted Platform Module (TPM) and a Trusted Execution Environment (TEE). Then, the client concatenates the token input and the public key to obtain a bound token input, blinds the bound token input, and generates a TokenRequest similar to Section <xref target="RFC9578" section="5.1" sectionFormat="bare"/> and Section <xref target="RFC9578" section="6.1" sectionFormat="bare"/> of <xref target="RFC9578"/>. After finalizing the issuance protocol successfully, the client will obtain a Privacy Pass bound token. Lastly, when spending the token, the client needs to use the private key to generate a binding proof, which is used to prove possession of the private key corresponding to the public key included in the bound token input. After receiving the token, the public key and the binding proof, the Origin not only needs to verify the token bound with the public key but also needs to verify the binding proof using the bound public key.</t>
      <t>In addition, if there is a channel (e.g., TLS <xref target="RFC5246"/> <xref target="RFC8446"/>, HPKE <xref target="RFC9180"/>) between the Client and the Origin, then a secret value exported from the channel can be used as an additional input in the Schnorr NIZK proof generation to support the property of channel binding, which guarantees that the token and the binding proof for one channel that obtained by an attacker cannot be used in another channel.</t>
      <t>As a result, if an attacker attempts to export and replay a Privacy Pass bound token, it also needs to use the Client's private key that corresponds to the token's bound public key. But this is hard to do if the private key is specially protected in a secure hardware module.</t>
    </section>
    <section anchor="terminology">
      <name>Terminology</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" 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>
      <?line -18?>

<t>Unless otherwise specified, this document encodes protocol messages in TLS notation from <xref section="3" sectionFormat="of" target="RFC8446"/>.</t>
      <t>This document uses terms "Origin", "Client", "Issuer", "Issuance", "Redemption", "Token challenge", "Token request", "Token response" and "Token" as defined in <xref target="RFC9576"/>, and also uses the terms "Issuer key", "Token redemption" as defined in <xref target="RFC9577"/> as well as the terms "Issuer Public Key", "Issuer Private Key" as defined in <xref target="RFC9578"/>.
<!-- Moreover, the following additional terms are used throughout this document. -->
      </t>
    </section>
    <section anchor="issuance-protocol-with-token-binding-extension">
      <name>Issuance Protocol with Token Binding Extension</name>
      <t>This section describes the issuance protocol with token binding extension, which includes two types of issuance protocol: one for privately verifiable tokens and another for publicly verifiable tokens.</t>
      <section anchor="binding_private">
        <name>Token Binding for Privately Verifiable Token Issuance</name>
        <t>This section uses notation described in <xref section="4.4" sectionFormat="of" target="RFC9497"/>, including SerializeElement, DeserializeElement, and DeserializeScalar.</t>
        <t>The constants <tt>Ne</tt> and <tt>Ns</tt> are defined in <xref section="4.4" sectionFormat="of" target="RFC9497"/>, and the constant <tt>Nk</tt> is defined in <xref section="8.2.1" sectionFormat="of" target="RFC9578"/>.</t>
        <section anchor="client-to-issuer-request">
          <name>Client-to-Issuer Request</name>
          <t>The Client first generates a context as follows:</t>
          <artwork><![CDATA[
client_context = SetupVOPRFClient("P384-SHA384", pkI)
]]></artwork>
          <t>Here, <tt>pkI</tt> denotes the Issuer Public Key defined in <xref section="5" sectionFormat="of" target="RFC9578"/>. "P384-SHA384" is the identifier corresponding to the OPRF(P-384, SHA-384) ciphersuite defined in <xref target="RFC9497"/>. SetupVOPRFClient is defined in <xref section="3.2" sectionFormat="of" target="RFC9497"/>.</t>
          <t>The Client then generates a random 32-byte <tt>nonce</tt> and creates a <tt>token_input</tt> as follows:</t>
          <artwork><![CDATA[
nonce = random(32)
challenge_digest = SHA256(challenge)
token_input = concat(0x8001, 
                     nonce, 
                     challenge_digest, 
                     token_key_id)
]]></artwork>
          <t>Here, the <tt>challenge</tt> is an opaque string, and might be provided by the redemption protocol described in <xref section="2.1" sectionFormat="of" target="RFC9577"/>. The 2 bytes value <tt>0x8001</tt> represents the token type of VOPRF(P-384, SHA-384) with Token Binding (P-384, SHA-384), where the latter ciphersuite (P-384, SHA-384) will be used for token binding. The <tt>token_key_id</tt> is a key identifier of the Issuer Public Key pkI, which is computed as described in <xref section="5.5" sectionFormat="of" target="RFC9578"/>.</t>
          <!-- The Client first generates an ephemeral seed from a long-term seed and the random ```nonce```, and then uses the ephemeral seed to derive an ephemeral public-private keypair (pkE, skE) in the group of elliptic curve P-384, where the long-term seed is probably protected by a secure hardware module, ```pkE``` and ```skE``` are of Ne-byte length and Ns-byte length, respectively, and the constants ```Ne = 49``` and ```Ns = 48``` are defined in {{Section 4.4 of RFC9497}}. A RECOMMENDED method for generating ephemeral keypairs is as follows: -->
<t>The Client generates an ephemeral public-private keypair (pkE, skE) in the group of elliptic curve P-384, where <tt>pkE</tt> and <tt>skE</tt> are of Ne-byte length and Ns-byte length, respectively, and the constants <tt>Ne = 49</tt> and <tt>Ns = 48</tt> are defined in <xref section="4.4" sectionFormat="of" target="RFC9497"/>. A <bcp14>RECOMMENDED</bcp14> method for generating ephemeral keypairs is as follows:</t>
          <artwork><![CDATA[
seed = random(Ns)
ephemeral_seed = SHA384(concat(seed, nonce))
(skE, pkE) = DeriveKeyPair(ephemeral_seed, "PrivacyPassTokenBinding")
]]></artwork>
          <t>Here, the long-term <tt>seed</tt> is probably generated within a secure hardware module and can be used to protect multiple tokens (or a batch of tokens), and the DeriveKeyPair function is defined in <xref section="3.2.1" sectionFormat="of" target="RFC9497"/>.</t>
          <t>After that, the Client creates a <tt>bound_token_input</tt> and blinds it as follows:</t>
          <artwork><![CDATA[
binding_pkE = SerializeElement(pkE)
bound_token_input = concat(token_input, binding_pkE)
blind, blinded_element = client_context.Blind(bound_token_input)
blinded_msg = SerializeElement(blinded_element)
]]></artwork>
          <t>Here, the Blind function is defined in Section <xref target="RFC9497" section="3.3.1" sectionFormat="bare"/> and Section <xref target="RFC9497" section="3.3.2" sectionFormat="bare"/> of <xref target="RFC9497"/>. If the Blind function fails, the Client aborts the protocol. The Client stores the <tt>bound_token_input</tt>, <tt>blind</tt> and <tt>blinded_element</tt> values locally for use when finalizing the issuance protocol to produce a token (as described in <xref target="private_finalization"/>).</t>
          <t>The Client creates a TokenRequest structured as follows, where structure fields are defined in <xref section="5.1" sectionFormat="of" target="RFC9578"/>.</t>
          <artwork><![CDATA[
  struct {
      uint16_t token_type = 0x8001;
      uint8_t truncated_token_key_id;
      uint8_t blinded_msg[Ne];
  } TokenRequest;
]]></artwork>
          <t>The Client then generates an HTTP POST request to send to the Issuer Request URL, with the TokenRequest as the content. Please refer to <xref section="5.1" sectionFormat="of" target="RFC9578"/> for an example request.</t>
        </section>
        <section anchor="issuer-to-client-response">
          <name>Issuer-to-Client Response</name>
          <t>This section is the same as <xref section="5.2" sectionFormat="of" target="RFC9578"/>, except that the token type value is <tt>0x8001</tt>.</t>
        </section>
        <section anchor="private_finalization">
          <name>Finalization</name>
          <t>Upon receipt, the Client handles the response and, if successful, deserializes the values TokenResponse.evaluate_msg and TokenResponse.evaluate_proof, and obtains <tt>evaluated_element</tt> and <tt>proof</tt> as follows.</t>
          <artwork><![CDATA[
evaluated_element = DeserializeElement(TokenResponse.evaluate_msg)
c = DeserializeScalar(TokenResponse.evaluate_proof[0])
s = DeserializeScalar(TokenResponse.evaluate_proof[1])
proof = (c, s)
]]></artwork>
          <t>If deserialization of either value fails, the Client aborts the protocol. Otherwise, the Client processes the response as follows:</t>
          <artwork><![CDATA[
authenticator = client_context.Finalize(bound_token_input, 
                                        blind, 
                                        evaluated_element, 
                                        blinded_element, 
                                        proof)
]]></artwork>
          <t>Here, the Finalize function is defined in <xref section="3.3.2" sectionFormat="of" target="RFC9497"/>. If this succeeds, the Client creates a token as follows:</t>
          <artwork><![CDATA[
  struct {
      uint16_t token_type = 0x8001;
      uint8_t nonce[32];
      uint8_t challenge_digest[32];
      uint8_t token_key_id[32];
      uint8_t authenticator[Nk];
  } Token;
]]></artwork>
          <t>If the Finalize function fails, the Client aborts the protocol; otherwise it stores the token and its corresponding one-time public key <tt>binding_pkE</tt>.</t>
        </section>
      </section>
      <section anchor="binding_public">
        <name>Token Binding for Publicly Verifiable Token Issuance</name>
        <t>This section uses the SerializeElement notation defined in <xref section="4.3" sectionFormat="of" target="RFC9497"/>.</t>
        <t>The constant <tt>Nk</tt> is defined in <xref section="8.2.2" sectionFormat="of" target="RFC9578"/>.</t>
        <section anchor="client-to-issuer-request-1">
          <name>Client-to-Issuer Request</name>
          <t>The Client first generates a random 32-byte <tt>nonce</tt> and creates a <tt>token_input</tt> as follows:</t>
          <artwork><![CDATA[
nonce = random(32)
challenge_digest = SHA256(challenge)
token_input = concat(0x8002, 
                     nonce, 
                     challenge_digest, 
                     token_key_id)
]]></artwork>
          <t>Here, the <tt>challenge</tt> is an opaque string, and might be provided by the redemption protocol described in <xref section="2.1" sectionFormat="of" target="RFC9577"/>. The 2 bytes value <tt>0x8002</tt> represents the token type of Blind RSA (2048-bit) with Token Binding (P-256, SHA-256), where the latter ciphersuite (P-256, SHA-256) will be used for token binding. The <tt>token_key_id</tt> is a key identifier of the Issuer Public Key pkI, which is computed as described in <xref section="6.5" sectionFormat="of" target="RFC9578"/>.</t>
          <!-- The Client first generates an ephemeral seed from a long-term seed and the random ```nonce```, and then uses the ephemeral seed to derive an ephemeral public-private keypair (pkE, skE) in the group of elliptic curve P-256, where the long-term seed is probably protected by a secure hardware module, ```pkE``` and ```skE``` are of Ne-byte length and Ns-byte length, respectively, and the constants ```Ne = 33``` and ```Ns = 32``` are defined in {{Section 4.3 of RFC9497}}. A RECOMMENDED method for generating ephemeral keypairs is as follows: -->
<t>The Client generates an ephemeral public-private keypair (pkE, skE) in the group of elliptic curve P-256, where <tt>pkE</tt> and <tt>skE</tt> are of Ne-byte length and Ns-byte length, respectively, and the constants <tt>Ne = 33</tt> and <tt>Ns = 32</tt> are defined in <xref section="4.3" sectionFormat="of" target="RFC9497"/>. A <bcp14>RECOMMENDED</bcp14> method for generating ephemeral keypairs is as follows:</t>
          <artwork><![CDATA[
seed = random(Ns)
ephemeral_seed = SHA256(concat(seed, nonce))
(skE, pkE) = DeriveKeyPair(ephemeral_seed, "PrivacyPassTokenBinding")
]]></artwork>
          <t>Here, the long-term <tt>seed</tt> is probably generated within a secure hardware module and can be used to protect multiple tokens (or a batch of tokens), and the DeriveKeyPair function is defined in <xref section="3.2.1" sectionFormat="of" target="RFC9497"/>.</t>
          <t>After that, the Client creates a <tt>bound_token_input</tt> and blinds it as follows:</t>
          <artwork><![CDATA[
binding_pkE = SerializeElement(pkE)
bound_token_input = concat(token_input, binding_pkE)
blinded_msg, blind_inv = Blind(pkI, PrepareIdentity(bound_token_input))
]]></artwork>
          <t>Here, <tt>pkI</tt> denotes the Issuer Public Key defined in <xref section="6" sectionFormat="of" target="RFC9578"/>. The PrepareIdentity and Blind functions are defined in Section <xref target="RFC9474" section="4.1" sectionFormat="bare"/> and Section <xref target="RFC9474" section="4.2" sectionFormat="bare"/> of <xref target="RFC9474"/>, respectively. If the Blind function fails, the Client aborts the protocol. The Client stores the <tt>bound_token_input</tt> and <tt>blind_inv</tt> values locally for use when finalizing the issuance protocol to produce a token (as described in <xref target="public_finalization"/>).</t>
          <t>The Client creates a TokenRequest structured as follows, where structure fields are defined in <xref section="6.1" sectionFormat="of" target="RFC9578"/>.</t>
          <artwork><![CDATA[
  struct {
      uint16_t token_type = 0x8002;
      uint8_t truncated_token_key_id;
      uint8_t blinded_msg[Nk];
  } TokenRequest;
]]></artwork>
          <t>The Client then generates an HTTP POST request to send to the Issuer Request URL, with the TokenRequest as the content. Please refer to <xref section="6.1" sectionFormat="of" target="RFC9578"/> for an example request.</t>
        </section>
        <section anchor="issuer-to-client-response-1">
          <name>Issuer-to-Client Response</name>
          <t>This section is the same as <xref section="6.2" sectionFormat="of" target="RFC9578"/>, except that the token type value is <tt>0x8002</tt>.</t>
        </section>
        <section anchor="public_finalization">
          <name>Finalization</name>
          <t>Upon receipt, the Client handles the response and, if successful, processes the content as follows:</t>
          <artwork><![CDATA[
authenticator = 
  Finalize(pkI, PrepareIdentity(bound_token_input), blind_sig, blind_inv)
]]></artwork>
          <t>Here, the Finalize function is defined in <xref section="4.4" sectionFormat="of" target="RFC9474"/>. If this succeeds, the Client creates a token as follows:</t>
          <artwork><![CDATA[
  struct {
      uint16_t token_type = 0x8002;
      uint8_t nonce[32];
      uint8_t challenge_digest[32];
      uint8_t token_key_id[32];
      uint8_t authenticator[Nk];
  } Token;
]]></artwork>
          <t>If the Finalize function fails, the Client aborts the protocol; otherwise it stores the token and its corresponding one-time public key <tt>binding_pkE</tt>.</t>
        </section>
      </section>
    </section>
    <section anchor="redemption-protocol-with-token-binding-extension">
      <name>Redemption Protocol with Token Binding Extension</name>
      <t>This section describes the redemption protocol with token binding extension, which includes two types of redemption protocol: one for privately verifiable tokens and another for publicly verifiable tokens.</t>
      <section anchor="token-binding-for-privately-verifiable-token-redemption">
        <name>Token Binding for Privately Verifiable Token Redemption</name>
        <t>This section uses notation described in <xref section="4.4" sectionFormat="of" target="RFC9497"/>, including Generator, RandomScalar, HashToScalar, SerializeElement and DeserializeElement, and SerializeScalar and DeserializeScalar.</t>
        <!-- The constants Ne = 49 and Ns = 48 are defined in Section 4.4 of {{RFC9497}}. -->

<section anchor="private_token_binding_generation">
          <name>Token Binding Generation</name>
          <t>The Client first creates a <tt>proof_input</tt> as follows:</t>
          <artwork><![CDATA[
proof_input = concat(token, 
                     channel_binding_type, 
                     channel_binding_secret)
]]></artwork>
          <t>This document defines three variants for channel binding, and the following one-byte values will be used to distinguish between types:</t>
          <table anchor="ref-to-tab1">
            <name>Channel Binding Types</name>
            <thead>
              <tr>
                <th align="left">Type</th>
                <th align="left">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">no_channel_binding</td>
                <td align="left">0x00</td>
              </tr>
              <tr>
                <td align="left">tls_channel_binding</td>
                <td align="left">0x01</td>
              </tr>
              <tr>
                <td align="left">hpke_channel_binding</td>
                <td align="left">0x02</td>
              </tr>
            </tbody>
          </table>
          <t>The meaning of the above types and the corresponding <tt>channel_binding_secret</tt> are described as follows:</t>
          <ul spacing="normal">
            <li>
              <t>The "no_channel_binding" type means that no channel binding is used in the token binding generation, then the <tt>channel_binding_secret</tt> is a 0-byte value.</t>
            </li>
            <li>
              <t>The "tls_channel_binding" type means that a TLS channel binding is used in the token binding generation, then the <tt>channel_binding_secret</tt> is a 32-byte value. The computations of this secret are defined in <xref target="RFC5705"/> for TLS 1.2 and in <xref section="7.5" sectionFormat="of" target="RFC8446"/> for TLS 1.3, respectively, and the corresponding inputs are defined in <xref section="2" sectionFormat="of" target="RFC9266"/>. 
<!-- It is repeated here for convenience, where TLS-Exporter interface is defined in Section 7.5 of {{RFC8446}} and the context_value is a zero-length string defined in Section 2 of {{RFC9266}}. -->
<!-- ~~~
channel_binding_secret = TLS-Exporter("EXPORTER-Channel-Binding", context_value, 32)
~~~ -->
              </t>
            </li>
            <li>
              <t>The "hpke_channel_binding" type means that a HPKE channel binding is used in the token binding generation, then the <tt>channel_binding_secret</tt> is a 32-byte value. This secret is generated according to <xref section="5.3" sectionFormat="of" target="RFC9180"/>, and it is defined as follows, where the Context.Export interface is defined in <xref section="5.3" sectionFormat="of" target="RFC9180"/>.</t>
            </li>
          </ul>
          <artwork><![CDATA[
channel_binding_secret = Context.Export("EXPORTER-Channel-Binding", 32)
]]></artwork>
          <t>The Client then generates a <tt>binding_proof</tt> as follows, which is to prove possession of the private key <tt>skE</tt> corresponding to the previously bound public key <tt>pkE</tt>:</t>
          <artwork><![CDATA[
r = RandomScalar()
R = r * Generator()
serialized_R = SerializeElement(R)
challengeTranscript = I2OSP(len(serialized_R), 2) || serialized_R ||
                      I2OSP(len(proof_input), 2) || proof_input ||
                      "Challenge"
c = HashToScalar(challengeTranscript)
s = r - c * skE
binding_proof = (SerializeScalar(c), SerializeScalar(s))
]]></artwork>
          <t>Here, the HashToScalar function is based on SHA-384, and the private key <tt>skE</tt> <bcp14>MAY</bcp14> be recovered from the long-term <tt>seed</tt> and the Token.nonce as follows.</t>
          <artwork><![CDATA[
ephemeral_seed = SHA384(concat(seed, Token.nonce))
(skE, _) = DeriveKeyPair(ephemeral_seed, "PrivacyPassTokenBinding")
]]></artwork>
          <t>Here, the DeriveKeyPair function defined in <xref section="3.2.1" sectionFormat="of" target="RFC9497"/> is used to derive only <tt>skE</tt>.</t>
          <t>The Client creates a TokenBinding structured as follows:</t>
          <artwork><![CDATA[
  struct {
      uint8_t channel_binding_type;
      uint8_t binding_pkE[Ne];
      uint8_t binding_proof[Ns+Ns];
  } TokenBinding;
]]></artwork>
          <t>If the "no_channel_binding" type is used, then the token binding can also be generated in another more lightweight way without Schnorr NIZK proof generation and verification. Note that the keypair (skE, pkE) is only used once for a Privacy Pass bound token, so the Client can directly present the one-time private key <tt>skE</tt> to the Origin to prove possession of this key, and thus it is not a zero-knowledge proof. In this case, the first Ns-byte value of the <tt>binding_proof</tt> field is set to <tt>SerializeScalar(skE)</tt> and the second Ns-byte value of this field is set to all zero bytes, and the <tt>binding_pkE</tt> field is set to zero-length string since the one-time public key <tt>pkE</tt> can be recovered from the one-time private key <tt>skE</tt>.</t>
        </section>
        <section anchor="sending-token-and-token-binding">
          <name>Sending Token and Token Binding</name>
          <t>When used for Client authorization, the "PrivateToken" authentication scheme defines one parameter, "token", which contains the base64url-encoded Token structure. This document defines a new parameter, "token_binding", which contains the base64url-encoded TokenBinding structure. This document follows the default padding behavior described in <xref section="3.2" sectionFormat="of" target="RFC4648"/>, so the base64url value <bcp14>MUST</bcp14> include padding. The Client presents the Token structure and the TokenBinding structure to the Origin in a new HTTP request using the Authorization header field as follows:</t>
          <artwork><![CDATA[
Authorization: PrivateToken token="abc...", token_binding="def..."
]]></artwork>
        </section>
        <section anchor="token-and-token-binding-verification">
          <name>Token and Token Binding Verification</name>
          <t>Upon receipt, the Origin needs to verify both the token and the token binding, and if any one of verifications fails, this authorization request will be rejected.</t>
          <t>For the token type of VOPRF(P-384, SHA-384) with Token Binding (P-384, SHA-384) (0x8001), verifying a token requires creating a VOPRF context using the Issuer Private Key, evaluating the bound token input, and comparing the result against the token authenticator value.</t>
          <artwork><![CDATA[
server_context = SetupVOPRFServer("P384-SHA384", skI)
token_authenticator_input = 
  concat(Token.token_type, 
         Token.nonce, 
         Token.challenge_digest, 
         Token.token_key_id)
bound_token_authenticator_input = 
  concat(token_authenticator_input, TokenBinding.binding_pkE)
bound_token_authenticator = 
  server_context.Evaluate(bound_token_authenticator_input)
valid = (bound_token_authenticator == Token.authenticator)
]]></artwork>
          <t>Here, the SetupVOPRFServer and Evaluate functions are defined in Section <xref target="RFC9497" section="3.3.1" sectionFormat="bare"/> and Section <xref target="RFC9497" section="3.2" sectionFormat="bare"/> of <xref target="RFC9497"/>, respectively.</t>
          <t>Verifying a token binding requires checking that TokenBinding.binding_proof is a valid Schnorr NIZK proof using the TokenBinding.binding_pkE, where the HashToScalar function is based on SHA-384.</t>
          <artwork><![CDATA[
proof_verification_input = 
  concat(token,  
         TokenBinding.channel_binding_type, 
         expected_channel_binding_secret)
pkE = DeserializeElement(TokenBinding.binding_pkE)
c = DeserializeScalar(TokenBinding.binding_proof[0])
s = DeserializeScalar(TokenBinding.binding_proof[1])
R = (s * Generator()) + (c * pkE)
serialized_R = SerializeElement(R)
challengeTranscript = 
  I2OSP(len(serialized_R), 2) || serialized_R ||
  I2OSP(len(proof_verification_input), 2) || proof_verification_input ||
  "Challenge"
expectedC = HashToScalar(challengeTranscript)
valid = (expectedC == c)
]]></artwork>
          <t>If the "no_channel_binding" type is used and the token binding is generated without using Schnorr NIZKP, then a token binding is implicitly verified in the above token verification, where the <tt>binding_pkE</tt> is computed as follows.</t>
          <artwork><![CDATA[
skE = DeserializeScalar(TokenBinding.binding_proof[0])
pkE = skE * Generator()
binding_pkE = SerializeElement(pkE)
]]></artwork>
        </section>
      </section>
      <section anchor="token-binding-for-publicly-verifiable-token-redemption">
        <name>Token Binding for Publicly Verifiable Token Redemption</name>
        <t>This section uses notation described in <xref section="4.3" sectionFormat="of" target="RFC9497"/>, including Generator, RandomScalar, HashToScalar, SerializeElement and DeserializeElement, and SerializeScalar and DeserializeScalar.</t>
        <!-- The constants Ne = 33 and Ns = 32 are defined in {{Section 4.3 of RFC9497}}. -->

<section anchor="token-binding-generation">
          <name>Token Binding Generation</name>
          <t>The Client first creates a <tt>proof_input</tt> as follows:</t>
          <artwork><![CDATA[
proof_input = concat(token, 
                     channel_binding_type, 
                     channel_binding_secret)
]]></artwork>
          <t>Here, the <tt>channel_binding_type</tt> and the <tt>channel_binding_secret</tt> fields are defined in <xref target="private_token_binding_generation"/>.</t>
          <t>The Client then generates a <tt>binding_proof</tt> as follows, which is to prove possession of the private key <tt>skE</tt> corresponding to the previously bound public key <tt>pkE</tt>:</t>
          <artwork><![CDATA[
r = RandomScalar()
R = r * Generator()
serialized_R = SerializeElement(R)
challengeTranscript = I2OSP(len(serialized_R), 2) || serialized_R ||
                      I2OSP(len(proof_input), 2) || proof_input ||
                      "Challenge"
c = HashToScalar(challengeTranscript)
s = r - c * skE
binding_proof = (SerializeScalar(c), SerializeScalar(s))
]]></artwork>
          <t>Here, the HashToScalar function is based on SHA-256, and the private key <tt>skE</tt> <bcp14>MAY</bcp14> be recovered from the long-term <tt>seed</tt> and the Token.nonce as follows.</t>
          <artwork><![CDATA[
ephemeral_seed = SHA256(concat(seed, Token.nonce))
(skE, _) = DeriveKeyPair(ephemeral_seed, "PrivacyPassTokenBinding")
]]></artwork>
          <t>Here, the DeriveKeyPair function defined in <xref section="3.2.1" sectionFormat="of" target="RFC9497"/> is used to derive only <tt>skE</tt>.</t>
          <t>The Client creates a TokenBinding structured as follows:</t>
          <artwork><![CDATA[
  struct {
      uint8_t channel_binding_type;
      uint8_t binding_pkE[Ne];
      uint8_t binding_proof[Ns+Ns];
  } TokenBinding;
]]></artwork>
          <t>If the "no_channel_binding" type is used, then the token binding can also be generated by using the same lightweight way as in <xref target="private_token_binding_generation"/>, thus is omitted here.</t>
        </section>
        <section anchor="sending-token-and-token-binding-1">
          <name>Sending Token and Token Binding</name>
          <t>As an example, the Client presents the Token structure and the TokenBinding structure to the Origin in a new HTTP request using the Authorization header field as follows:</t>
          <artwork><![CDATA[
Authorization: PrivateToken token="abc...", token_binding="def..."
]]></artwork>
        </section>
        <section anchor="token-and-token-binding-verification-1">
          <name>Token and Token Binding Verification</name>
          <t>Upon receipt, the Origin needs to verify both the token and the token binding, and if any one of verifications fails, this authorization request will be rejected.</t>
          <t>For the token type of Blind RSA (2048-bit) with Token Binding (P-256, SHA-256) (0x8002), verifying a token requires checking that Token.authenticator is a valid RSA signature over the bound token input using the Issuer Public Key.</t>
          <artwork><![CDATA[
token_authenticator_input = 
  concat(Token.token_type, 
         Token.nonce, 
         Token.challenge_digest, 
         Token.token_key_id)
bound_token_authenticator_input = 
  concat(token_authenticator_input, TokenBinding.binding_pkE)
valid = RSASSA-PSS-VERIFY(pkI, 
                          bound_token_authenticator_input, 
                          Token.authenticator)
]]></artwork>
          <t>Here, the RSASSA-PSS-VERIFY function is defined in <xref section="8.1.2" sectionFormat="of" target="RFC8017"/>, using SHA-384 as the hash function, MGF1 with SHA-384 as the Probabilistic Signature Scheme (PSS) mask generation function (MGF), and a 48-byte salt length (sLen).</t>
          <t>Verifying a token binding requires checking that TokenBinding.binding_proof is a valid Schnorr NIZK proof using the TokenBinding.binding_pkE, where the HashToScalar function is based on SHA-256.</t>
          <artwork><![CDATA[
proof_verification_input = 
  concat(token, 
         TokenBinding.channel_binding_type, 
         expected_channel_binding_secret)
pkE = DeserializeElement(TokenBinding.binding_pkE)
c = DeserializeScalar(TokenBinding.binding_proof[0])
s = DeserializeScalar(TokenBinding.binding_proof[1])
R = (s * Generator()) + (c * pkE)
serialized_R = SerializeElement(R)
challengeTranscript = 
  I2OSP(len(serialized_R), 2) || serialized_R ||
  I2OSP(len(proof_verification_input), 2) || proof_verification_input ||
  "Challenge"
expectedC = HashToScalar(challengeTranscript)
valid = (expectedC == c)
]]></artwork>
          <t>If the "no_channel_binding" type is used and the token binding is generated without using Schnorr NIZKP, then a token binding is implicitly verified in the above token verification, where the <tt>binding_pkE</tt> is computed as follows.</t>
          <artwork><![CDATA[
skE = DeserializeScalar(TokenBinding.binding_proof[0])
pkE = skE * Generator()
binding_pkE = SerializeElement(pkE)
]]></artwork>
          <!-- # Security Considerations

This document does not introduce any new security considerations. -->

</section>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <!-- This document has no IANA actions. -->

<t>This document defines two new token types "0x8001" and "0x8002" with the following contents, and requests that IANA add the two values to the "Privacy Pass Token Types" Registry defined in <xref section="6.2" sectionFormat="of" target="RFC9577"/>.</t>
      <t>Note that Token Binding, Ne, Ns are newly added fields, where the latter two <bcp14>MUST</bcp14> be provided if Token Binding is Y, or not applicable (N/A) otherwise.</t>
      <section anchor="token-type-voprfp-384-sha-384-with-token-binding-p-384-sha-384">
        <name>Token Type VOPRF(P-384, SHA-384) with Token Binding (P-384, SHA-384)</name>
        <t>Value: 0x8001</t>
        <t>Name: VOPRF(P-384, SHA-384) with Token Binding (P-384, SHA-384)</t>
        <t>Token Structure: As defined in <xref target="binding_private"/>.</t>
        <t>Token Key Encoding: Serialized using SerializeElement (<xref section="2.1" sectionFormat="of" target="RFC9497"/>).</t>
        <t>TokenChallenge Structure: As defined in <xref section="2.1" sectionFormat="of" target="RFC9577"/>.</t>
        <t>Publicly Verifiable: N</t>
        <t>Public Metadata: N</t>
        <t>Private Metadata: N</t>
        <t>Nk: 48</t>
        <t>Nid: 32</t>
        <t>Token Binding: Y</t>
        <t>Ne: 49</t>
        <t>Ns: 48</t>
        <t>Change controller: IETF</t>
        <t>Reference: This document, <xref target="binding_private"/></t>
        <t>Notes: None</t>
      </section>
      <section anchor="token-type-blind-rsa-2048-bit-with-token-binding-p-256-sha-256">
        <name>Token Type Blind RSA (2048-bit) with Token Binding (P-256, SHA-256)</name>
        <t>Value: 0x8002</t>
        <t>Name: Blind RSA (2048-bit) with Token Binding (P-256, SHA-256)</t>
        <t>Token Structure: As defined in <xref target="binding_public"/>.</t>
        <t>Token Key Encoding: Serialized as a DER-encoded SubjectPublicKeyInfo (SPKI) object using the RSASSA-PSS OID <xref target="RFC5756"/>.</t>
        <t>TokenChallenge Structure: As defined in <xref section="2.1" sectionFormat="of" target="RFC9577"/>.</t>
        <t>Publicly Verifiable: Y</t>
        <t>Public Metadata: N</t>
        <t>Private Metadata: N</t>
        <t>Nk: 256</t>
        <t>Nid: 32</t>
        <t>Token Binding: Y</t>
        <t>Ne: 33</t>
        <t>Ns: 32</t>
        <t>Change controller: IETF</t>
        <t>Reference: This document, <xref target="binding_public"/></t>
        <t>Notes: None</t>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <reference anchor="RFC9576">
        <front>
          <title>The Privacy Pass Architecture</title>
          <author fullname="A. Davidson" initials="A." surname="Davidson"/>
          <author fullname="J. Iyengar" initials="J." surname="Iyengar"/>
          <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
          <date month="June" year="2024"/>
          <abstract>
            <t>This document specifies the Privacy Pass architecture and requirements for its constituent protocols used for authorization based on privacy-preserving authentication mechanisms. It describes the conceptual model of Privacy Pass and its protocols, its security and privacy goals, practical deployment models, and recommendations for each deployment model, to help ensure that the desired security and privacy goals are fulfilled.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9576"/>
        <seriesInfo name="DOI" value="10.17487/RFC9576"/>
      </reference>
      <reference anchor="RFC9578">
        <front>
          <title>Privacy Pass Issuance Protocols</title>
          <author fullname="S. Celi" initials="S." surname="Celi"/>
          <author fullname="A. Davidson" initials="A." surname="Davidson"/>
          <author fullname="S. Valdez" initials="S." surname="Valdez"/>
          <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
          <date month="June" year="2024"/>
          <abstract>
            <t>This document specifies two variants of the two-message issuance protocol for Privacy Pass tokens: one that produces tokens that are privately verifiable using the Issuer Private Key and one that produces tokens that are publicly verifiable using the Issuer Public Key. Instances of "issuance protocol" and "issuance protocols" in the text of this document are used interchangeably to refer to the two variants of the Privacy Pass issuance protocol.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9578"/>
        <seriesInfo name="DOI" value="10.17487/RFC9578"/>
      </reference>
      <reference anchor="RFC9577">
        <front>
          <title>The Privacy Pass HTTP Authentication Scheme</title>
          <author fullname="T. Pauly" initials="T." surname="Pauly"/>
          <author fullname="S. Valdez" initials="S." surname="Valdez"/>
          <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
          <date month="June" year="2024"/>
          <abstract>
            <t>This document defines an HTTP authentication scheme for Privacy Pass, a privacy-preserving authentication mechanism used for authorization. The authentication scheme specified in this document can be used by Clients to redeem Privacy Pass tokens with an Origin. It can also be used by Origins to challenge Clients to present Privacy Pass tokens.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9577"/>
        <seriesInfo name="DOI" value="10.17487/RFC9577"/>
      </reference>
      <reference anchor="RFC9497">
        <front>
          <title>Oblivious Pseudorandom Functions (OPRFs) Using Prime-Order Groups</title>
          <author fullname="A. Davidson" initials="A." surname="Davidson"/>
          <author fullname="A. Faz-Hernandez" initials="A." surname="Faz-Hernandez"/>
          <author fullname="N. Sullivan" initials="N." surname="Sullivan"/>
          <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
          <date month="December" year="2023"/>
          <abstract>
            <t>An Oblivious Pseudorandom Function (OPRF) is a two-party protocol between a client and a server for computing the output of a Pseudorandom Function (PRF). The server provides the PRF private key, and the client provides the PRF input. At the end of the protocol, the client learns the PRF output without learning anything about the PRF private key, and the server learns neither the PRF input nor output. An OPRF can also satisfy a notion of 'verifiability', called a VOPRF. A VOPRF ensures clients can verify that the server used a specific private key during the execution of the protocol. A VOPRF can also be partially oblivious, called a POPRF. A POPRF allows clients and servers to provide public input to the PRF computation. This document specifies an OPRF, VOPRF, and POPRF instantiated within standard prime-order groups, including elliptic curves. This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9497"/>
        <seriesInfo name="DOI" value="10.17487/RFC9497"/>
      </reference>
      <reference anchor="RFC8017">
        <front>
          <title>PKCS #1: RSA Cryptography Specifications Version 2.2</title>
          <author fullname="K. Moriarty" initials="K." role="editor" surname="Moriarty"/>
          <author fullname="B. Kaliski" initials="B." surname="Kaliski"/>
          <author fullname="J. Jonsson" initials="J." surname="Jonsson"/>
          <author fullname="A. Rusch" initials="A." surname="Rusch"/>
          <date month="November" year="2016"/>
          <abstract>
            <t>This document provides recommendations for the implementation of public-key cryptography based on the RSA algorithm, covering cryptographic primitives, encryption schemes, signature schemes with appendix, and ASN.1 syntax for representing keys and for identifying the schemes.</t>
            <t>This document represents a republication of PKCS #1 v2.2 from RSA Laboratories' Public-Key Cryptography Standards (PKCS) series. By publishing this RFC, change control is transferred to the IETF.</t>
            <t>This document also obsoletes RFC 3447.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="8017"/>
        <seriesInfo name="DOI" value="10.17487/RFC8017"/>
      </reference>
      <reference anchor="RFC5246">
        <front>
          <title>The Transport Layer Security (TLS) Protocol Version 1.2</title>
          <author fullname="T. Dierks" initials="T." surname="Dierks"/>
          <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
          <date month="August" year="2008"/>
          <abstract>
            <t>This document specifies Version 1.2 of the Transport Layer Security (TLS) protocol. The TLS protocol provides communications security over the Internet. The protocol allows client/server applications to communicate in a way that is designed to prevent eavesdropping, tampering, or message forgery. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="5246"/>
        <seriesInfo name="DOI" value="10.17487/RFC5246"/>
      </reference>
      <reference anchor="RFC8446">
        <front>
          <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
          <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
          <date month="August" year="2018"/>
          <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="RFC9180">
        <front>
          <title>Hybrid Public Key Encryption</title>
          <author fullname="R. Barnes" initials="R." surname="Barnes"/>
          <author fullname="K. Bhargavan" initials="K." surname="Bhargavan"/>
          <author fullname="B. Lipp" initials="B." surname="Lipp"/>
          <author fullname="C. Wood" initials="C." surname="Wood"/>
          <date month="February" year="2022"/>
          <abstract>
            <t>This document describes a scheme for hybrid public key encryption (HPKE). This scheme provides a variant of public key encryption of arbitrary-sized plaintexts for a recipient public key. It also includes three authenticated variants, including one that authenticates possession of a pre-shared key and two optional ones that authenticate possession of a key encapsulation mechanism (KEM) private key. HPKE works for any combination of an asymmetric KEM, key derivation function (KDF), and authenticated encryption with additional data (AEAD) encryption function. Some authenticated variants may not be supported by all KEMs. We provide instantiations of the scheme using widely used and efficient primitives, such as Elliptic Curve Diffie-Hellman (ECDH) key agreement, HMAC-based key derivation function (HKDF), and SHA2.</t>
            <t>This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9180"/>
        <seriesInfo name="DOI" value="10.17487/RFC9180"/>
      </reference>
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S." surname="Bradner"/>
          <date month="March" year="1997"/>
          <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">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B." surname="Leiba"/>
          <date month="May" year="2017"/>
          <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="RFC9474">
        <front>
          <title>RSA Blind Signatures</title>
          <author fullname="F. Denis" initials="F." surname="Denis"/>
          <author fullname="F. Jacobs" initials="F." surname="Jacobs"/>
          <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
          <date month="October" year="2023"/>
          <abstract>
            <t>This document specifies an RSA-based blind signature protocol. RSA blind signatures were first introduced by Chaum for untraceable payments. A signature that is output from this protocol can be verified as an RSA-PSS signature.</t>
            <t>This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9474"/>
        <seriesInfo name="DOI" value="10.17487/RFC9474"/>
      </reference>
      <reference anchor="RFC5705">
        <front>
          <title>Keying Material Exporters for Transport Layer Security (TLS)</title>
          <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
          <date month="March" year="2010"/>
          <abstract>
            <t>A number of protocols wish to leverage Transport Layer Security (TLS) to perform key establishment but then use some of the keying material for their own purposes. This document describes a general mechanism for allowing that. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="5705"/>
        <seriesInfo name="DOI" value="10.17487/RFC5705"/>
      </reference>
      <reference anchor="RFC9266">
        <front>
          <title>Channel Bindings for TLS 1.3</title>
          <author fullname="S. Whited" initials="S." surname="Whited"/>
          <date month="July" year="2022"/>
          <abstract>
            <t>This document defines a channel binding type, tls-exporter, that is compatible with TLS 1.3 in accordance with RFC 5056, "On the Use of Channel Bindings to Secure Channels". Furthermore, it updates the default channel binding to the new binding for versions of TLS greater than 1.2. This document updates RFCs 5801, 5802, 5929, and 7677.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="9266"/>
        <seriesInfo name="DOI" value="10.17487/RFC9266"/>
      </reference>
      <reference anchor="RFC4648">
        <front>
          <title>The Base16, Base32, and Base64 Data Encodings</title>
          <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
          <date month="October" year="2006"/>
          <abstract>
            <t>This document describes the commonly used base 64, base 32, and base 16 encoding schemes. It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="4648"/>
        <seriesInfo name="DOI" value="10.17487/RFC4648"/>
      </reference>
      <reference anchor="RFC5756">
        <front>
          <title>Updates for RSAES-OAEP and RSASSA-PSS Algorithm Parameters</title>
          <author fullname="S. Turner" initials="S." surname="Turner"/>
          <author fullname="D. Brown" initials="D." surname="Brown"/>
          <author fullname="K. Yiu" initials="K." surname="Yiu"/>
          <author fullname="R. Housley" initials="R." surname="Housley"/>
          <author fullname="T. Polk" initials="T." surname="Polk"/>
          <date month="January" year="2010"/>
          <abstract>
            <t>This document updates RFC 4055. It updates the conventions for using the RSA Encryption Scheme - Optimal Asymmetric Encryption Padding (RSAES-OAEP) key transport algorithm in the Internet X.509 Public Key Infrastructure (PKI). Specifically, it updates the conventions for algorithm parameters in an X.509 certificate's subjectPublicKeyInfo field. [STANDARDS-TRACK]</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="5756"/>
        <seriesInfo name="DOI" value="10.17487/RFC5756"/>
      </reference>
    </references>
    <?line 601?>

<!-- # Acknowledgements
{:numbered="false"}

The authors would like to thank... -->



  </back>
  <!-- ##markdown-source:
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
BwZ82wfUeQAA

-->

</rfc>
