RFC 8446
RFC 8446
RFC 8446
0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head
profile="http://dublincore.org/documents/2008/08/04/dc-html/">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="robots" content="index,follow">
<meta name="creator" content="rfcmarkup version 1.129c">
<link rel="schema.DC" href="http://purl.org/dc/elements/1.1/">
<meta name="DC.Relation.Replaces" content="rfc5077">
<meta name="DC.Relation.Replaces" content="rfc5246">
<meta name="DC.Relation.Replaces" content="rfc6961">
<meta name="DC.Identifier" content="urn:ietf:rfc:8446">
<meta name="DC.Date.Issued" content="August, 2018">
<meta name="DC.Creator" content="Eric Rescorla <ekr@rtfm.com>">
<meta name="DC.Description.Abstract" content="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. This document updates RFCs 4492,
5705, and 6066 and it obsoletes RFCs 5077, 5246, and 6961. This
document also specifies new requirements for TLS 1.2 implementations.">
<meta name="DC.Title" content="The Transport Layer Security (TLS) Protocol Version
1.3">
<style type="text/css">
@media only screen
and (min-width: 992px)
and (max-width: 1199px) {
body { font-size: 14pt; }
div.content { width: 96ex; margin: 0 auto; }
}
@media only screen
and (min-width: 768px)
and (max-width: 991px) {
body { font-size: 14pt; }
div.content { width: 96ex; margin: 0 auto; }
}
@media only screen
and (min-width: 480px)
and (max-width: 767px) {
body { font-size: 11pt; }
div.content { width: 96ex; margin: 0 auto; }
}
@media only screen
and (max-width: 479px) {
body { font-size: 8pt; }
div.content { width: 96ex; margin: 0 auto; }
}
@media only screen
and (min-device-width : 375px)
and (max-device-width : 667px) {
body { font-size: 9.5pt; }
div.content { width: 96ex; margin: 0; }
}
@media only screen
and (min-device-width: 1200px) {
body { font-size: 10pt; margin: 0 4em; }
div.content { width: 96ex; margin: 0; }
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
font-weight: bold;
line-height: 0pt;
display: inline;
white-space: pre;
font-family: monospace;
font-size: 1em;
font-weight: bold;
}
pre {
font-size: 1em;
margin-top: 0px;
margin-bottom: 0px;
}
.pre {
white-space: pre;
font-family: monospace;
}
.header{
font-weight: bold;
}
.newpage {
page-break-before: always;
}
.invisible {
text-decoration: none;
color: white;
}
a.selflink {
color: black;
text-decoration: none;
}
@media print {
body {
font-family: monospace;
font-size: 10.5pt;
}
h1, h2, h3, h4, h5, h6 {
font-size: 1em;
}
a:link, a:visited {
color: inherit;
text-decoration: none;
}
.noprint {
display: none;
}
}
@media screen {
.grey, .grey a:link, .grey a:visited {
color: #777;
}
.docinfo {
background-color: #EEE;
}
.top {
border-top: 7px solid #EEE;
}
.bgwhite { background-color: white; }
.bgred { background-color: #F44; }
.bggrey { background-color: #666; }
.bgbrown { background-color: #840; }
.bgorange { background-color: #FA0; }
.bgyellow { background-color: #EE0; }
.bgmagenta{ background-color: #F4F; }
.bgblue { background-color: #66F; }
.bgcyan { background-color: #4DD; }
.bggreen { background-color: #4F4; }
<script type="text/javascript"><!--
function addHeaderTags() {
var spans = document.getElementsByTagName("span");
for (var i=0; i < spans.length; i++) {
var elem = spans[i];
if (elem) {
var level = elem.getAttribute("class");
if (level == "h1" || level == "h2" || level == "h3" || level ==
"h4" || level == "h5" || level == "h6") {
elem.innerHTML = "<"+level+">"+elem.innerHTML+"</"+level+">";
}
}
}
}
var legend_html = "Colour legend:<br /> <table>
<tr><td>Unknown:</td> <td><span class='cplate
bgwhite'> </span></td></tr> <tr><td>Draft:</td>
<td><span class='cplate bgred'> </span></td></tr>
<tr><td>Informational:</td> <td><span class='cplate
bgorange'> </span></td></tr>
<tr><td>Experimental:</td> <td><span class='cplate
bgyellow'> </span></td></tr> <tr><td>Best Common
Practice:</td> <td><span class='cplate
bgmagenta'> </span></td></tr> <tr><td>Proposed
Standard:</td> <td><span class='cplate
bgblue'> </span></td></tr> <tr><td>Draft Standard
(old designation):</td> <td><span class='cplate
bgcyan'> </span></td></tr> <tr><td>Internet
Standard:</td> <td><span class='cplate
bggreen'> </span></td></tr> <tr><td>Historic:</td>
<td><span class='cplate bggrey'> </span></td></tr>
<tr><td>Obsolete:</td> <td><span class='cplate
bgbrown'> </span></td></tr> </table>";
function showElem(id) {
var elem = document.getElementById(id);
elem.innerHTML = eval(id+"_html");
elem.style.visibility='visible';
}
function hideElem(id) {
var elem = document.getElementById(id);
elem.style.visibility='hidden';
elem.innerHTML = "";
}
// -->
</script>
</head>
<body onload="addHeaderTags()">
<div class="content">
<div style="height: 13px;">
<div onmouseover="this.style.cursor='pointer';" onclick="showElem('legend');"
onmouseout="hideElem('legend')" style="height: 6px; position: absolute;" class="pre
noprint docinfo bgblue" title="Click for colour legend.">
</div>
<div id="legend" class="docinfo noprint pre legend" style="position:absolute;
top: 4px; left: 4ex; visibility:hidden; background-color: white; padding: 4px 9px
5px 7px; border: solid #345 1px; " onmouseover="showElem('legend');"
onmouseout="hideElem('legend');">
</div>
</div>
<span class="pre noprint docinfo top">[<a href="https://tools.ietf.org/html/"
title="Document search and retrieval page">Docs</a>] [<a
href="https://tools.ietf.org/rfc/rfc8446.txt" title="Plaintext version of this
document">txt</a>|<a href="https://tools.ietf.org/pdf/rfc8446" title="PDF version
of this document">pdf</a>] [<a href="https://tools.ietf.org/html/draft-ietf-tls-
tls13" title="draft-ietf-tls-tls13">draft-ietf-tls-...</a>] [<a
href="https://datatracker.ietf.org/doc/rfc8446" title="IESG Datatracker information
for this document">Tracker</a>] [<a href="https://tools.ietf.org/rfcdiff?
difftype=--hwdiff&url2=rfc8446" title="Inline diff (wdiff)">Diff1</a>] [<a
href="https://tools.ietf.org/rfcdiff?url2=rfc8446" title="Side-by-side
diff">Diff2</a>] [<a href="https://datatracker.ietf.org/ipr/search/?
rfc=8446&submit=rfc" title="IPR disclosures related to this document">IPR</a>]
[<a href="https://www.rfc-editor.org/errata_search.php?
rfc=8446">Errata</a>]</span><br>
<span class="pre noprint docinfo">
</span><br>
<span class="pre noprint docinfo">
PROPOSED STANDARD</span><br>
<span class="pre noprint docinfo">
<span style="color: #C00;">Errata Exist</span></span><br>
<pre>Internet Engineering Task Force (IETF) E. Rescorla
Request for Comments: 8446 Mozilla
Obsoletes: <a href="https://tools.ietf.org/html/rfc5077">5077</a>, <a
href="https://tools.ietf.org/html/rfc5246">5246</a>, <a
href="https://tools.ietf.org/html/rfc6961">6961</a>
August 2018
Updates: <a href="https://tools.ietf.org/html/rfc5705">5705</a>, <a
href="https://tools.ietf.org/html/rfc6066">6066</a>
Category: Standards Track
ISSN: 2070-1721
Abstract
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.
Copyright (c) 2018 IETF Trust and the persons identified as the
document authors. All rights reserved.
<a href="#section-1">1</a>.
Introduction ....................................................<a href="#page-
6">6</a>
<a href="#section-1.1">1.1</a>. Conventions and
Terminology ................................<a href="#page-7">7</a>
<a href="#section-1.2">1.2</a>. Major Differences from TLS
1.2 .............................<a href="#page-8">8</a>
<a href="#section-1.3">1.3</a>. Updates Affecting TLS
1.2 ..................................<a href="#page-9">9</a>
<a href="#section-2">2</a>. Protocol
Overview ..............................................<a href="#page-10">10</a>
<a href="#section-2.1">2.1</a>. Incorrect DHE
Share .......................................<a href="#page-14">14</a>
<a href="#section-2.2">2.2</a>. Resumption and Pre-Shared Key
(PSK) .......................<a href="#page-15">15</a>
<a href="#section-2.3">2.3</a>. 0-RTT
Data ................................................<a href="#page-17">17</a>
<a href="#section-3">3</a>. Presentation
Language ..........................................<a href="#page-19">19</a>
<a href="#section-3.1">3.1</a>. Basic Block
Size ..........................................<a href="#page-19">19</a>
<a href="#section-3.2">3.2</a>.
Miscellaneous .............................................<a href="#page-
20">20</a>
<a href="#section-3.3">3.3</a>.
Numbers ...................................................<a href="#page-
20">20</a>
<a href="#section-3.4">3.4</a>.
Vectors ...................................................<a href="#page-
20">20</a>
<a href="#section-3.5">3.5</a>.
Enumerateds ...............................................<a href="#page-
21">21</a>
<a href="#section-3.6">3.6</a>. Constructed
Types .........................................<a href="#page-22">22</a>
<a href="#section-3.7">3.7</a>.
Constants .................................................<a href="#page-
23">23</a>
<a href="#section-3.8">3.8</a>.
Variants ..................................................<a href="#page-
23">23</a>
<a href="#section-4">4</a>. Handshake
Protocol .............................................<a href="#page-24">24</a>
<a href="#section-4.1">4.1</a>. Key Exchange
Messages .....................................<a href="#page-25">25</a>
<a href="#section-4.1.1">4.1.1</a>. Cryptographic
Negotiation ..........................<a href="#page-26">26</a>
<a href="#section-4.1.2">4.1.2</a>. Client
Hello .......................................<a href="#page-27">27</a>
<a href="#section-4.1.3">4.1.3</a>. Server
Hello .......................................<a href="#page-31">31</a>
<a href="#section-4.1.4">4.1.4</a>. Hello Retry
Request ................................<a href="#page-33">33</a>
<a href="#section-4.2">4.2</a>.
Extensions ................................................<a href="#page-
35">35</a>
<a href="#section-4.2.1">4.2.1</a>. Supported
Versions .................................<a href="#page-39">39</a>
<a href="#section-4.2.2">4.2.2</a>.
Cookie .............................................<a href="#page-40">40</a>
<a href="#section-4.2.3">4.2.3</a>. Signature
Algorithms ...............................<a href="#page-41">41</a>
<a href="#section-4.2.4">4.2.4</a>. Certificate
Authorities ............................<a href="#page-45">45</a>
<a href="#section-4.2.5">4.2.5</a>. OID
Filters ........................................<a href="#page-45">45</a>
<a href="#section-4.2.6">4.2.6</a>. Post-Handshake Client Authentication
...............<a href="#page-47">47</a>
<a href="#section-4.2.7">4.2.7</a>. Supported
Groups ...................................<a href="#page-47">47</a>
<a href="#section-4.2.8">4.2.8</a>. Key
Share ..........................................<a href="#page-48">48</a>
<a href="#section-4.2.9">4.2.9</a>. Pre-Shared Key Exchange
Modes ......................<a href="#page-51">51</a>
<a href="#section-4.2.10">4.2.10</a>. Early Data
Indication .............................<a href="#page-52">52</a>
<a href="#section-4.2.11">4.2.11</a>. Pre-Shared Key
Extension ..........................<a href="#page-55">55</a>
<a href="#section-4.3">4.3</a>. Server
Parameters .........................................<a href="#page-59">59</a>
<a href="#section-4.3.1">4.3.1</a>. Encrypted
Extensions ...............................<a href="#page-60">60</a>
<a href="#section-4.3.2">4.3.2</a>. Certificate
Request ................................<a href="#page-60">60</a>
<a href="#section-4.4">4.4</a>. Authentication
Messages ...................................<a href="#page-61">61</a>
<a href="#section-4.4.1">4.4.1</a>. The Transcript
Hash ................................<a href="#page-63">63</a>
<a href="#section-4.4.2">4.4.2</a>.
Certificate ........................................<a href="#page-64">64</a>
<a href="#section-4.4.3">4.4.3</a>. Certificate
Verify .................................<a href="#page-69">69</a>
<a href="#section-4.4.4">4.4.4</a>.
Finished ...........................................<a href="#page-71">71</a>
<a href="#section-4.5">4.5</a>. End of Early
Data .........................................<a href="#page-72">72</a>
This document defines TLS version 1.3. While TLS 1.3 is not directly
compatible with previous versions, all versions of TLS incorporate a
versioning mechanism which allows clients and servers to
interoperably negotiate a common version if one is supported by both
peers.
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
<a href="https://tools.ietf.org/html/bcp14">BCP 14</a> [<a
href="https://tools.ietf.org/html/rfc2119" title=""Key words for use in RFCs
to Indicate Requirement Levels"">RFC2119</a>] [<a
href="https://tools.ietf.org/html/rfc8174" title=""Ambiguity of Uppercase vs
Lowercase in RFC 2119 Key Words"">RFC8174</a>] when, and only when, they
appear in all
capitals, as shown here.
server: The endpoint that did not initiate the TLS connection.
- A zero round-trip time (0-RTT) mode was added, saving a round trip
at connection setup for some application data, at the cost of
certain security properties.
- Static RSA and Diffie-Hellman cipher suites have been removed; all
public-key based key exchange mechanisms now provide forward
secrecy.
- The key derivation functions have been redesigned. The new design
allows easier analysis by cryptographers due to their improved key
separation properties. The HMAC-based Extract-and-Expand Key
Derivation Function (HKDF) is used as an underlying primitive.
- Elliptic curve algorithms are now in the base spec, and new
signature algorithms, such as EdDSA, are included. TLS 1.3
removed point format negotiation in favor of a single point format
for each curve.
- PSK-only
Key ^ ClientHello
Exch | + key_share*
| + signature_algorithms*
| + psk_key_exchange_modes*
v + pre_shared_key* -------->
ServerHello ^ Key
+ key_share* | Exch
+ pre_shared_key* v
{EncryptedExtensions} ^ Server
{CertificateRequest*} v Params
{Certificate*} ^
{CertificateVerify*} | Auth
{Finished} v
<-------- [Application Data*]
^ {Certificate*}
Auth | {CertificateVerify*}
v {Finished} -------->
[Application Data] <-------> [Application Data]
Upon receiving the server's messages, the client responds with its
Authentication messages, namely Certificate and CertificateVerify (if
requested), and Finished.
At this point, the handshake is complete, and the client and server
derive the keying material required by the record layer to exchange
application-layer data protected through authenticated encryption.
Application Data MUST NOT be sent prior to sending the Finished
message, except as specified in <a href="#section-2.3">Section 2.3</a>. Note
that while the
server may send Application Data prior to receiving the client's
Authentication messages, any data sent at that point is, of course,
being sent to an unauthenticated peer.
<span class="grey">Rescorla Standards Track
[Page 13]</span></pre>
<hr class="noprint" style="width: 96ex;" align="left"><!--NewPage--><pre
class="newpage"><a name="page-14" id="page-14" href="#page-14" class="invisible">
</a>
<span class="grey"><a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>
TLS August 2018</span>
Client Server
ClientHello
+ key_share -------->
HelloRetryRequest
<-------- + key_share
ClientHello
+ key_share -------->
ServerHello
+ key_share
{EncryptedExtensions}
{CertificateRequest*}
{Certificate*}
{CertificateVerify*}
{Finished}
<-------- [Application Data*]
{Certificate*}
{CertificateVerify*}
{Finished} -------->
[Application Data] <-------> [Application Data]
Although TLS PSKs can be established out of band, PSKs can also be
established in a previous connection and then used to establish a new
connection ("session resumption" or "resuming" with a PSK). Once a
handshake has completed, the server can send the client a PSK
identity that corresponds to a unique key derived from the initial
handshake (see <a href="#section-4.6.1">Section 4.6.1</a>). The client can then
use that PSK
identity in future handshakes to negotiate the use of the associated
PSK. If the server accepts the PSK, then the security context of the
new connection is cryptographically tied to the original connection
and the key derived from the initial handshake is used to bootstrap
the cryptographic state instead of a full handshake. In TLS 1.2 and
below, this functionality was provided by "session IDs" and "session
tickets" [<a href="https://tools.ietf.org/html/rfc5077" title=""Transport
Layer Security (TLS) Session Resumption without Server-Side
State"">RFC5077</a>]. Both mechanisms are obsoleted in TLS 1.3.
Client Server
Initial Handshake:
ClientHello
+ key_share -------->
ServerHello
+ key_share
{EncryptedExtensions}
{CertificateRequest*}
{Certificate*}
{CertificateVerify*}
{Finished}
<-------- [Application Data*]
{Certificate*}
{CertificateVerify*}
{Finished} -------->
<-------- [NewSessionTicket]
[Application Data] <-------> [Application Data]
Subsequent Handshake:
ClientHello
+ key_share*
+ pre_shared_key -------->
ServerHello
+ pre_shared_key
+ key_share*
{EncryptedExtensions}
{Finished}
<-------- [Application Data*]
{Finished} -------->
[Application Data] <-------> [Application Data]
When PSKs are provisioned out of band, the PSK identity and the KDF
hash algorithm to be used with the PSK MUST also be provisioned.
Client Server
ClientHello
+ early_data
+ key_share*
+ psk_key_exchange_modes
+ pre_shared_key
(Application Data*) -------->
ServerHello
+ pre_shared_key
+ key_share*
{EncryptedExtensions}
+ early_data*
{Finished}
<-------- [Application Data*]
(EndOfEarlyData)
{Finished} -------->
[Application Data] <-------> [Application Data]
IMPORTANT NOTE: The security properties for 0-RTT data are weaker
than those for other kinds of TLS data. Specifically:
T T';
The basic numeric data type is an unsigned byte (uint8). All larger
numeric data types are constructed from a fixed-length series of
bytes concatenated as described in <a href="#section-3.1">Section 3.1</a> and
are also unsigned.
The following numeric types are predefined.
uint8 uint16[2];
uint8 uint24[3];
uint8 uint32[4];
uint8 uint64[8];
T T'[n];
T T'<floor..ceiling>;
opaque mandatory<300..400>;
/* length field is two bytes, cannot be empty */
uint16 longer<0..800>;
/* zero to 400 16-bit unsigned integers */
In the following example, Taste will consume two bytes in the data
stream but can only assume the values 1, 2, or 4 in the current
version of the protocol.
struct {
T1 f1;
T2 f2;
...
Tn fn;
} T;
The fields within a structure may be qualified using the type's name,
with a syntax much like that available for enumerateds. For example,
T.f2 refers to the second field of the previous declaration.
Fields and variables may be assigned a fixed value using "=", as in:
struct {
T1 f1 = 8; /* T.f1 must always be 8 */
T2 f2;
} T;
struct {
T1 f1;
T2 f2;
....
Tn fn;
select (E) {
case e1: Te1 [[fe1]];
case e2: Te2 [[fe2]];
....
case en: Ten [[fen]];
};
} Tv;
For example:
struct {
uint16 number;
opaque string<0..10>; /* variable length */
} V1;
struct {
uint32 number;
opaque string[10]; /* fixed length */
} V2;
struct {
VariantTag type;
select (VariantRecord.type) {
case apple: V1;
case orange: V2;
};
} VariantRecord;
enum {
client_hello(1),
server_hello(2),
new_session_ticket(4),
end_of_early_data(5),
encrypted_extensions(8),
certificate(11),
certificate_request(13),
certificate_verify(15),
finished(20),
key_update(24),
message_hash(254),
(255)
} HandshakeType;
struct {
HandshakeType msg_type; /* handshake type */
uint24 length; /* remaining bytes in message */
select (Handshake.msg_type) {
case client_hello: ClientHello;
case server_hello: ServerHello;
case end_of_early_data: EndOfEarlyData;
case encrypted_extensions: EncryptedExtensions;
case certificate_request: CertificateRequest;
case certificate: Certificate;
case certificate_verify: CertificateVerify;
case finished: Finished;
case new_session_ticket: NewSessionTicket;
case key_update: KeyUpdate;
};
} Handshake;
If the server does not select a PSK, then the first three of these
options are entirely orthogonal: the server independently selects a
cipher suite, an (EC)DHE group and key share for key establishment,
and a signature algorithm/certificate pair to authenticate itself to
the client. If there is no overlap between the received
"supported_groups" and the groups supported by the server, then the
server MUST abort the handshake with a "handshake_failure" or an
"insufficient_security" alert.
If the server selects an (EC)DHE group and the client did not offer a
compatible "key_share" extension in the initial ClientHello, the
server MUST respond with a HelloRetryRequest (<a href="#section-4.1.4">Section
4.1.4</a>) message.
uint16 ProtocolVersion;
opaque Random[32];
struct {
ProtocolVersion legacy_version = 0x0303; /* TLS v1.2 */
Random random;
opaque legacy_session_id<0..32>;
CipherSuite cipher_suites<2..2^16-2>;
opaque legacy_compression_methods<1..2^8-1>;
Extension extensions<8..2^16-1>;
} ClientHello;
<span class="grey">Rescorla Standards Track
[Page 28]</span></pre>
<hr class="noprint" style="width: 96ex;" align="left"><!--NewPage--><pre
class="newpage"><a name="page-29" id="page-29" href="#page-29" class="invisible">
</a>
<span class="grey"><a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>
TLS August 2018</span>
struct {
ProtocolVersion legacy_version = 0x0303; /* TLS v1.2 */
Random random;
opaque legacy_session_id_echo<0..32>;
CipherSuite cipher_suite;
uint8 legacy_compression_method = 0;
Extension extensions<6..2^16-1>;
} ServerHello;
CF 21 AD 74 E5 9A 61 11 BE 1D 8C 02 1E 65 B8 91
C2 A2 11 16 7A BB 8C 5E 07 9E 09 E2 C8 A8 33 9C
If negotiating TLS 1.2, TLS 1.3 servers MUST set the last 8 bytes of
their Random value to the bytes:
44 4F 57 4E 47 52 44 01
If negotiating TLS 1.1 or below, TLS 1.3 servers MUST, and TLS 1.2
servers SHOULD, set the last 8 bytes of their ServerHello.Random
value to the bytes:
44 4F 57 4E 47 52 44 00
A client which receives a cipher suite that was not offered MUST
abort the handshake. Servers MUST ensure that they negotiate the
same cipher suite when receiving a conformant updated ClientHello (if
the server selects the cipher suite as the first step in the
negotiation, then this will happen automatically). Upon receiving
the ServerHello, clients MUST check that the cipher suite supplied in
the ServerHello is the same as that in the HelloRetryRequest and
otherwise abort the handshake with an "illegal_parameter" alert.
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
enum {
server_name(0), /* <a
href="https://tools.ietf.org/html/rfc6066">RFC 6066</a> */
max_fragment_length(1), /* <a
href="https://tools.ietf.org/html/rfc6066">RFC 6066</a> */
status_request(5), /* <a
href="https://tools.ietf.org/html/rfc6066">RFC 6066</a> */
supported_groups(10), /* <a
href="https://tools.ietf.org/html/rfc8422">RFC 8422</a>, 7919 */
signature_algorithms(13), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
use_srtp(14), /* <a
href="https://tools.ietf.org/html/rfc5764">RFC 5764</a> */
heartbeat(15), /* <a
href="https://tools.ietf.org/html/rfc6520">RFC 6520</a> */
application_layer_protocol_negotiation(16), /* <a
href="https://tools.ietf.org/html/rfc7301">RFC 7301</a> */
signed_certificate_timestamp(18), /* <a
href="https://tools.ietf.org/html/rfc6962">RFC 6962</a> */
client_certificate_type(19), /* <a
href="https://tools.ietf.org/html/rfc7250">RFC 7250</a> */
server_certificate_type(20), /* <a
href="https://tools.ietf.org/html/rfc7250">RFC 7250</a> */
padding(21), /* <a
href="https://tools.ietf.org/html/rfc7685">RFC 7685</a> */
pre_shared_key(41), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
early_data(42), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
supported_versions(43), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
cookie(44), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
psk_key_exchange_modes(45), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
certificate_authorities(47), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
oid_filters(48), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
post_handshake_auth(49), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
signature_algorithms_cert(50), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
key_share(51), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
(65535)
} ExtensionType;
Here:
- "extension_type" identifies the particular extension type.
The table below indicates the messages where a given extension may
appear, using the following notation: CH (ClientHello),
SH (ServerHello), EE (EncryptedExtensions), CT (Certificate),
CR (CertificateRequest), NST (NewSessionTicket), and
HRR (HelloRetryRequest). If an implementation receives an extension
which it recognizes and which is not specified for the message in
which it appears, it MUST abort the handshake with an
"illegal_parameter" alert.
+--------------------------------------------------+-------------+
| Extension | TLS 1.3 |
+--------------------------------------------------+-------------+
| server_name [<a href="https://tools.ietf.org/html/rfc6066"
title=""Transport Layer Security (TLS) Extensions: Extension
Definitions"">RFC6066</a>] | CH, EE |
| | |
| max_fragment_length [<a href="https://tools.ietf.org/html/rfc6066"
title=""Transport Layer Security (TLS) Extensions: Extension
Definitions"">RFC6066</a>] | CH, EE |
| | |
| status_request [<a href="https://tools.ietf.org/html/rfc6066"
title=""Transport Layer Security (TLS) Extensions: Extension
Definitions"">RFC6066</a>] | CH, CR, CT |
| | |
| supported_groups [<a href="https://tools.ietf.org/html/rfc7919"
title=""Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for
Transport Layer Security (TLS)"">RFC7919</a>] | CH,
EE |
| | |
| signature_algorithms (<a href="https://tools.ietf.org/html/rfc8446">RFC
8446</a>) | CH, CR |
| | |
| use_srtp [<a href="https://tools.ietf.org/html/rfc5764" title=""Datagram
Transport Layer Security (DTLS) Extension to Establish Keys for the Secure Real-
time Transport Protocol (SRTP)"">RFC5764</a>] |
CH, EE |
| | |
| heartbeat [<a href="https://tools.ietf.org/html/rfc6520"
title=""Transport Layer Security (TLS) and Datagram Transport Layer Security
(DTLS) Heartbeat Extension"">RFC6520</a>] |
CH, EE |
| | |
| application_layer_protocol_negotiation [<a
href="https://tools.ietf.org/html/rfc7301" title=""Transport Layer Security
(TLS) Application-Layer Protocol Negotiation Extension"">RFC7301</a>] |
CH, EE |
| | |
| signed_certificate_timestamp [<a href="https://tools.ietf.org/html/rfc6962"
title=""Certificate Transparency"">RFC6962</a>] | CH, CR, CT |
| | |
| client_certificate_type [<a href="https://tools.ietf.org/html/rfc7250"
title=""Using Raw Public Keys in Transport Layer Security (TLS) and Datagram
Transport Layer Security (DTLS)"">RFC7250</a>] | CH, EE |
| | |
| server_certificate_type [<a href="https://tools.ietf.org/html/rfc7250"
title=""Using Raw Public Keys in Transport Layer Security (TLS) and Datagram
Transport Layer Security (DTLS)"">RFC7250</a>] | CH, EE |
| | |
| padding [<a href="https://tools.ietf.org/html/rfc7685" title=""A
Transport Layer Security (TLS) ClientHello Padding Extension"">RFC7685</a>]
| CH |
| | |
| key_share (<a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>)
| CH, SH, HRR |
| | |
| pre_shared_key (<a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>)
| CH, SH |
| | |
| psk_key_exchange_modes (<a href="https://tools.ietf.org/html/rfc8446">RFC
8446</a>) | CH |
| | |
| early_data (<a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>)
| CH, EE, NST |
| | |
| cookie (<a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>)
| CH, HRR |
| | |
| supported_versions (<a href="https://tools.ietf.org/html/rfc8446">RFC
8446</a>) | CH, SH, HRR |
| | |
| certificate_authorities (<a href="https://tools.ietf.org/html/rfc8446">RFC
8446</a>) | CH, CR |
| | |
| oid_filters (<a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>)
| CR |
| | |
| post_handshake_auth (<a href="https://tools.ietf.org/html/rfc8446">RFC
8446</a>) | CH |
| | |
| signature_algorithms_cert (<a href="https://tools.ietf.org/html/rfc8446">RFC
8446</a>) | CH, CR |
+--------------------------------------------------+-------------+
In TLS 1.3, unlike TLS 1.2, extensions are negotiated for each
handshake even when in resumption-PSK mode. However, 0-RTT
parameters are those negotiated in the previous handshake; mismatches
may require rejecting 0-RTT (see <a href="#section-4.2.10">Section 4.2.10</a>).
There are subtle (and not so subtle) interactions that may occur in
this protocol between new features and existing features which may
result in a significant reduction in overall security. The following
considerations should be taken into account when designing new
extensions:
- Some cases where a server does not agree to an extension are error
conditions (e.g., the handshake cannot continue), and some are
simply refusals to support particular features. In general, error
alerts should be used for the former and a field in the server
extension response for the latter.
struct {
select (Handshake.msg_type) {
case client_hello:
ProtocolVersion versions<2..254>;
A server which negotiates a version of TLS prior to TLS 1.3 MUST set
ServerHello.version and MUST NOT send the "supported_versions"
extension. A server which negotiates TLS 1.3 MUST respond by sending
a "supported_versions" extension containing the selected version
value (0x0304). It MUST set the ServerHello.legacy_version field to
0x0303 (TLS 1.2). Clients MUST check for this extension prior to
processing the rest of the ServerHello (although they will have to
struct {
opaque cookie<1..2^16-1>;
} Cookie;
enum {
/* RSASSA-PKCS1-v1_5 algorithms */
rsa_pkcs1_sha256(0x0401),
rsa_pkcs1_sha384(0x0501),
rsa_pkcs1_sha512(0x0601),
/* ECDSA algorithms */
ecdsa_secp256r1_sha256(0x0403),
ecdsa_secp384r1_sha384(0x0503),
ecdsa_secp521r1_sha512(0x0603),
/* EdDSA algorithms */
ed25519(0x0807),
ed448(0x0808),
/* Legacy algorithms */
rsa_pkcs1_sha1(0x0201),
ecdsa_sha1(0x0203),
struct {
SignatureScheme supported_signature_algorithms<2..2^16-2>;
} SignatureSchemeList;
Note that TLS 1.2 defines this extension differently. TLS 1.3
implementations willing to negotiate TLS 1.2 MUST behave in
accordance with the requirements of [<a
href="https://tools.ietf.org/html/rfc5246" title=""The Transport Layer
Security (TLS) Protocol Version 1.2"">RFC5246</a>] when negotiating that
version. In particular:
opaque DistinguishedName<1..2^16-1>;
struct {
DistinguishedName authorities<3..2^16-1>;
} CertificateAuthoritiesExtension;
struct {
opaque certificate_extension_oid<1..2^8-1>;
opaque certificate_extension_values<0..2^16-1>;
} OIDFilter;
struct {
OIDFilter filters<0..2^16-1>;
} OIDFilterExtension;
struct {} PostHandshakeAuth;
Note: In versions of TLS prior to TLS 1.3, this extension was named
"elliptic_curves" and only contained elliptic curve groups. See
[<a href="https://tools.ietf.org/html/rfc8422" title=""Elliptic Curve
Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) Versions 1.2
and Earlier"">RFC8422</a>] and [<a href="https://tools.ietf.org/html/rfc7919"
title=""Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for
Transport Layer Security (TLS)"">RFC7919</a>]. This extension was also used
to negotiate
ECDSA curves. Signature algorithms are now negotiated independently
(see <a href="#section-4.2.3">Section 4.2.3</a>).
enum {
struct {
NamedGroup named_group_list<2..2^16-1>;
} NamedGroupList;
struct {
NamedGroup group;
opaque key_exchange<1..2^16-1>;
} KeyShareEntry;
struct {
KeyShareEntry client_shares<0..2^16-1>;
} KeyShareClientHello;
struct {
NamedGroup selected_group;
} KeyShareHelloRetryRequest;
struct {
KeyShareEntry server_share;
} KeyShareServerHello;
Peers MUST validate each other's public key Y by ensuring that 1 < Y
< p-1. This check ensures that the remote peer is properly behaved
and isn't forcing the local system into a small subgroup.
<span class="grey">Rescorla Standards Track
[Page 50]</span></pre>
<hr class="noprint" style="width: 96ex;" align="left"><!--NewPage--><pre
class="newpage"><a name="page-51" id="page-51" href="#page-51" class="invisible">
</a>
<span class="grey"><a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>
TLS August 2018</span>
ECDHE parameters for both clients and servers are encoded in the
opaque key_exchange field of a KeyShareEntry in a KeyShare structure.
struct {
uint8 legacy_form = 4;
opaque X[coordinate_length];
opaque Y[coordinate_length];
} UncompressedPointRepresentation;
For X25519 and X448, the contents of the public value are the byte
string inputs and outputs of the corresponding functions defined in
[<a href="https://tools.ietf.org/html/rfc7748" title=""Elliptic Curves for
Security"">RFC7748</a>]: 32 bytes for X25519 and 56 bytes for X448.
struct {
PskKeyExchangeMode ke_modes<1..255>;
} PskKeyExchangeModes;
Any future values that are allocated must ensure that the transmitted
protocol messages unambiguously identify which mode was selected by
the server; at present, this is indicated by the presence of the
"key_share" in the ServerHello.
When a PSK is used and early data is allowed for that PSK, the client
can send Application Data in its first flight of messages. If the
client opts to do so, it MUST supply both the "pre_shared_key" and
"early_data" extensions.
struct {} Empty;
struct {
select (Handshake.msg_type) {
case new_session_ticket: uint32 max_early_data_size;
case client_hello: Empty;
case encrypted_extensions: Empty;
};
} EarlyDataIndication;
The parameters for the 0-RTT data (version, symmetric cipher suite,
Application-Layer Protocol Negotiation (ALPN) [<a
href="https://tools.ietf.org/html/rfc7301" title=""Transport Layer Security
(TLS) Application-Layer Protocol Negotiation Extension"">RFC7301</a>]
protocol,
etc.) are those associated with the PSK in use. For externally
provisioned PSKs, the associated values are those provisioned along
with the key. For PSKs established via a NewSessionTicket message,
the associated values are those which were negotiated in the
connection which established the PSK. The PSK used to encrypt the
early data MUST be the first PSK listed in the client's
"pre_shared_key" extension.
0-RTT messages sent in the first flight have the same (encrypted)
content types as messages of the same type sent in other flights
(handshake and application_data) but are protected under different
keys. After receiving the server's Finished message, if the server
has accepted early data, an EndOfEarlyData message will be sent to
indicate the key change. This message will be encrypted with the
0-RTT traffic keys.
In order to accept early data, the server MUST have accepted a PSK
cipher suite and selected the first key offered in the client's
"pre_shared_key" extension. In addition, it MUST verify that the
following values are the same as those associated with the
selected PSK:
If any of these checks fail, the server MUST NOT respond with the
extension and must discard all the first-flight data using one of the
first two mechanisms listed above (thus falling back to 1-RTT or
2-RTT). If the client attempts a 0-RTT handshake but the server
rejects it, the server will generally not have the 0-RTT record
protection keys and must instead use trial decryption (either with
the 1-RTT handshake keys or by looking for a cleartext ClientHello in
the case of a HelloRetryRequest) to find the first non-0-RTT message.
struct {
opaque identity<1..2^16-1>;
uint32 obfuscated_ticket_age;
} PskIdentity;
opaque PskBinderEntry<32..255>;
struct {
PskIdentity identities<7..2^16-1>;
PskBinderEntry binders<33..2^16-1>;
} OfferedPsks;
struct {
select (Handshake.msg_type) {
case client_hello: OfferedPsks;
case server_hello: uint16 selected_identity;
};
} PreSharedKeyExtension;
The client's view of the age of a ticket is the time since the
receipt of the NewSessionTicket message. Clients MUST NOT attempt to
use tickets which have ages greater than the "ticket_lifetime" value
which was provided with the ticket. The "obfuscated_ticket_age"
field of each PskIdentity contains an obfuscated version of the
ticket age formed by taking the age in milliseconds and adding the
"ticket_age_add" value that was included with the ticket (see
<a href="#section-4.6.1">Section 4.6.1</a>), modulo 2^32. This addition
prevents passive
observers from correlating connections unless tickets are reused.
Note that the "ticket_lifetime" field in the NewSessionTicket message
is in seconds but the "obfuscated_ticket_age" is in milliseconds.
Because ticket lifetimes are restricted to a week, 32 bits is enough
to represent any plausible age, even in milliseconds.
The PSK binder value forms a binding between a PSK and the current
handshake, as well as a binding between the handshake in which the
PSK was generated (if via a NewSessionTicket message) and the current
handshake. Each entry in the binders list is computed as an HMAC
over a transcript hash (see <a href="#section-4.4.1">Section 4.4.1</a>)
containing a partial
ClientHello up to and including the PreSharedKeyExtension.identities
field. That is, it includes all of the ClientHello but not the
binders list itself. The length fields for the message (including
the overall length, the length of the extensions block, and the
length of the "pre_shared_key" extension) are all set as if binders
of the correct lengths were present.
Transcript-Hash(Truncate(ClientHello1))
Clients are permitted to "stream" 0-RTT data until they receive the
server's Finished, only then sending the EndOfEarlyData message,
followed by the rest of the handshake. In order to avoid deadlocks,
when accepting "early_data", servers MUST process the client's
ClientHello and then immediately send their flight of messages,
rather than waiting for the client's EndOfEarlyData message before
sending its ServerHello.
struct {
Extension extensions<0..2^16-1>;
} EncryptedExtensions;
struct {
opaque certificate_request_context<0..2^8-1>;
Extension extensions<2..2^16-1>;
} CertificateRequest;
Servers which are authenticating with a PSK MUST NOT send the
CertificateRequest message in the main handshake, though they MAY
send it in post-handshake authentication (see <a href="#section-4.6.2">Section
4.6.2</a>) provided
that the client has sent the "post_handshake_auth" extension (see
<a href="#section-4.2.6">Section 4.2.6</a>).
The following table defines the Handshake Context and MAC Base Key
for each scenario:
+-----------+-------------------------+-----------------------------+
| Mode | Handshake Context | Base Key |
+-----------+-------------------------+-----------------------------+
| Server | ClientHello ... later | server_handshake_traffic_ |
| | of EncryptedExtensions/ | secret |
| | CertificateRequest | |
| | | |
| Client | ClientHello ... later | client_handshake_traffic_ |
| | of server | secret |
| | Finished/EndOfEarlyData | |
| | | |
| Post- | ClientHello ... client | client_application_traffic_ |
| Handshake | Finished + | secret_N |
| | CertificateRequest | |
+-----------+-------------------------+-----------------------------+
The client MUST send a Certificate message if and only if the server
has requested client authentication via a CertificateRequest message
(<a href="#section-4.3.2">Section 4.3.2</a>). If the server requests client
authentication but no
suitable certificate is available, the client MUST send a Certificate
message containing no certificates (i.e., with the "certificate_list"
field having length 0). A Finished message MUST be sent regardless
of whether the Certificate message is empty.
enum {
X509(0),
RawPublicKey(2),
(255)
} CertificateType;
struct {
select (certificate_type) {
case RawPublicKey:
/* From <a href="https://tools.ietf.org/html/rfc7250">RFC 7250</a>
ASN.1_subjectPublicKeyInfo */
opaque ASN1_subjectPublicKeyInfo<1..2^24-1>;
case X509:
opaque cert_data<1..2^24-1>;
};
Extension extensions<0..2^16-1>;
} CertificateEntry;
struct {
opaque certificate_request_context<0..2^8-1>;
CertificateEntry certificate_list<0..2^24-1>;
} Certificate;
A server MAY request that a client present an OCSP response with its
certificate by sending an empty "status_request" extension in its
CertificateRequest message. If the client opts to send an OCSP
response, the body of its "status_request" extension MUST be a
CertificateStatus structure as defined in [<a
href="https://tools.ietf.org/html/rfc6066" title=""Transport Layer Security
(TLS) Extensions: Extension Definitions"">RFC6066</a>].
- The certificate MUST allow the key to be used for signing (i.e.,
the digitalSignature bit MUST be set if the Key Usage extension is
present) with a signature scheme indicated in the client's
"signature_algorithms"/"signature_algorithms_cert" extensions (see
<a href="#section-4.2.3">Section 4.2.3</a>).
If the client does not send any certificates (i.e., it sends an empty
Certificate message), the server MAY at its discretion either
continue the handshake without client authentication or abort the
handshake with a "certificate_required" alert. Also, if some aspect
of the certificate chain was unacceptable (e.g., it was not signed by
a known, trusted CA), the server MAY at its discretion either
continue the handshake (considering the client unauthenticated) or
abort the handshake.
struct {
SignatureScheme algorithm;
opaque signature<0..2^16-1>;
} CertificateVerify;
2020202020202020202020202020202020202020202020202020202020202020
2020202020202020202020202020202020202020202020202020202020202020
544c5320312e332c207365727665722043657274696669636174655665726966
79
00
0101010101010101010101010101010101010101010101010101010101010101
On the sender side, the process for computing the signature field of
the CertificateVerify message takes as input:
Once a side has sent its Finished message and has received and
validated the Finished message from its peer, it may begin to send
and receive Application Data over the connection. There are two
settings in which it is permitted to send data prior to receiving the
peer's Finished:
2. Servers MAY send data after sending their first flight, but
because the handshake is not yet complete, they have no assurance
of either the peer's identity or its liveness (i.e., the
ClientHello might have been replayed).
The key used to compute the Finished message is computed from the
Base Key defined in <a href="#section-4.4">Section 4.4</a> using HKDF (see <a
href="#section-7.1">Section 7.1</a>).
Specifically:
finished_key =
HKDF-Expand-Label(BaseKey, "finished", "", Hash.length)
struct {
opaque verify_data[Hash.length];
} Finished;
verify_data =
HMAC(finished_key,
Transcript-Hash(Handshake Context,
Certificate*, CertificateVerify*))
Note: Alerts and any other non-handshake record types are not
handshake messages and are not included in the hash computations.
struct {} EndOfEarlyData;
TLS also allows other messages to be sent after the main handshake.
These messages use a handshake content type and are encrypted under
the appropriate application traffic key.
At any time after the server has received the client Finished
message, it MAY send a NewSessionTicket message. This message
creates a unique association between the ticket value and a secret
PSK derived from the resumption master secret (see <a href="#section-7">Section
7</a>).
The client MAY use this PSK for future handshakes by including the
ticket value in the "pre_shared_key" extension in its ClientHello
(<a href="#section-4.2.11">Section 4.2.11</a>). Servers MAY send multiple
tickets on a single
connection, either immediately after each other or after specific
events (see <a href="#appendix-C.4">Appendix C.4</a>). For instance, the server
might send a new
ticket after post-handshake authentication in order to encapsulate
the additional client authentication state. Multiple tickets are
useful for clients for a variety of purposes, including:
Any ticket MUST only be resumed with a cipher suite that has the same
KDF hash algorithm as that used to establish the original connection.
Clients MUST only resume if the new SNI value is valid for the server
certificate presented in the original session and SHOULD only resume
if the SNI value matches the one used in the original session. The
latter is a performance optimization: normally, there is no reason to
expect that different servers covered by a single certificate would
be able to accept each other's tickets; hence, attempting resumption
in that case would waste a single-use ticket. If such an indication
is provided (externally or by any other means), clients MAY resume
with a different SNI value.
struct {
uint32 ticket_lifetime;
uint32 ticket_age_add;
opaque ticket_nonce<0..255>;
opaque ticket<1..2^16-1>;
Extension extensions<0..2^16-2>;
} NewSessionTicket;
ticket: The value of the ticket to be used as the PSK identity. The
ticket itself is an opaque label. It MAY be either a database
lookup key or a self-encrypted and self-authenticated value.
HKDF-Expand-Label(resumption_master_secret,
"resumption", ticket_nonce, Hash.length)
enum {
update_not_requested(0), update_requested(1), (255)
} KeyUpdateRequest;
struct {
KeyUpdateRequest request_update;
} KeyUpdate;
Both sender and receiver MUST encrypt their KeyUpdate messages with
the old keys. Additionally, both sides MUST enforce that a KeyUpdate
with the old key is received before accepting any messages encrypted
with the new key. Failure to do so may allow message truncation
attacks.
enum {
invalid(0),
change_cipher_spec(20),
alert(21),
handshake(22),
application_data(23),
(255)
} ContentType;
struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;
This document describes TLS 1.3, which uses the version 0x0304. This
version value is historical, deriving from the use of 0x0301 for
TLS 1.0 and 0x0300 for SSL 3.0. In order to maximize backward
compatibility, a record containing an initial ClientHello SHOULD have
version 0x0301 (reflecting TLS 1.0) and a record containing a second
ClientHello or a ServerHello MUST have version 0x0303 (reflecting
TLS 1.2). When negotiating prior versions of TLS, endpoints follow
the procedure and requirements provided in <a href="#appendix-D">Appendix D</a>.
struct {
opaque content[TLSPlaintext.length];
ContentType type;
uint8 zeros[length_of_padding];
} TLSInnerPlaintext;
struct {
ContentType opaque_type = application_data; /* 23 */
ProtocolVersion legacy_record_version = 0x0303; /* TLS v1.2 */
uint16 length;
opaque encrypted_record[TLSCiphertext.length];
} TLSCiphertext;
I.e.,
additional_data = TLSCiphertext.opaque_type ||
TLSCiphertext.legacy_record_version ||
TLSCiphertext.length
The AEAD output consists of the ciphertext output from the AEAD
encryption operation. The length of the plaintext is greater than
the corresponding TLSPlaintext.length due to the inclusion of
TLSInnerPlaintext.type and any padding supplied by the sender. The
length of the AEAD output will generally be larger than the
plaintext, but by an amount that varies with the AEAD algorithm.
AEADEncrypted =
AEAD-Encrypt(write_key, nonce, additional_data, plaintext)
In order to decrypt and verify, the cipher takes as input the key,
nonce, additional data, and the AEADEncrypted value. The output is
either the plaintext or an error indicating that the decryption
failed. There is no separate integrity check. Symbolically,
plaintext of encrypted_record =
AEAD-Decrypt(peer_write_key, nonce,
additional_data, AEADEncrypted)
Because the size of sequence numbers is 64-bit, they should not wrap.
If a TLS implementation would need to wrap a sequence number, it MUST
either rekey (<a href="#section-4.6.3">Section 4.6.3</a>) or terminate the
connection.
Each AEAD algorithm will specify a range of possible lengths for the
per-record nonce, from N_MIN bytes to N_MAX bytes of input [<a
href="https://tools.ietf.org/html/rfc5116" title=""An Interface and Algorithms
for Authenticated Encryption"">RFC5116</a>].
The length of the TLS per-record nonce (iv_length) is set to the
larger of 8 bytes and N_MIN for the AEAD algorithm (see <a
href="https://tools.ietf.org/html/rfc5116#section-4">[RFC5116],
Section 4</a>). An AEAD algorithm where N_MAX is less than 8 bytes
MUST NOT be used with TLS. The per-record nonce for the AEAD
construction is formed as follows:
All encrypted TLS records can be padded to inflate the size of the
TLSCiphertext. This allows the sender to hide the size of the
traffic from an observer.
The presence of padding does not change the overall record size
limitations: the full encoded TLSInnerPlaintext MUST NOT exceed 2^14
+ 1 octets. If the maximum fragment length is reduced -- as, for
example, by the record_size_limit extension from [<a
href="https://tools.ietf.org/html/rfc8449" title=""Record Size Limit Extension
for TLS"">RFC8449</a>] -- then
the reduced limit applies to the full plaintext, including the
content type and padding.
Selecting a padding policy that suggests when and how much to pad is
a complex topic and is beyond the scope of this specification. If
the application-layer protocol on top of TLS has its own padding, it
may be preferable to pad Application Data TLS records within the
application layer. Padding for encrypted Handshake or Alert records
must still be handled at the TLS layer, though. Later documents may
define padding selection algorithms or define a padding policy
request mechanism through TLS extensions or some other means.
Note: TLS defines two generic alerts (see <a href="#section-6">Section 6</a>) to
use upon
failure to parse a message. Peers which receive a message which
cannot be parsed according to the syntax (e.g., have a length
extending beyond the message boundary or contain an out-of-range
length) MUST terminate the connection with a "decode_error" alert.
Peers which receive a message which is syntactically correct but
semantically invalid (e.g., a DHE share of p - 1, or an invalid enum)
MUST terminate the connection with an "illegal_parameter" alert.
enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
record_overflow(22),
handshake_failure(40),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
protocol_version(70),
insufficient_security(71),
internal_error(80),
inappropriate_fallback(86),
user_canceled(90),
missing_extension(109),
unsupported_extension(110),
unrecognized_name(112),
bad_certificate_status_response(113),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),
(255)
} AlertDescription;
struct {
AlertLevel level;
AlertDescription description;
} Alert;
The client and the server must share knowledge that the connection is
ending in order to avoid a truncation attack.
close_notify: This alert notifies the recipient that the sender will
not send any more messages on this connection. Any data received
after a closure alert has been received MUST be ignored.
Either party MAY initiate a close of its write side of the connection
by sending a "close_notify" alert. Any data received after a closure
alert has been received MUST be ignored. If a transport-level close
is received prior to a "close_notify", the receiver cannot know that
all the data that was sent has been received.
Each party MUST send a "close_notify" alert before closing its write
side of the connection, unless it has already sent some error alert.
This does not have any effect on its read side of the connection.
Note that this is a change from versions of TLS prior to TLS 1.3 in
which implementations were required to react to a "close_notify" by
discarding pending writes and sending an immediate "close_notify"
alert of their own. That previous requirement could cause truncation
in the read side. Both parties need not wait to receive a
"close_notify" alert before closing their read side of the
connection, though doing so would introduce the possibility of
truncation.
If the application protocol using TLS provides that any data may be
carried over the underlying transport after the TLS connection is
closed, the TLS implementation MUST receive a "close_notify" alert
before indicating end-of-data to the application layer. No part of
this standard should be taken to dictate the manner in which a usage
profile for TLS manages its data transport, including when
connections are opened or closed.
The TLS handshake establishes one or more input secrets which are
combined to create the actual working keying material, as detailed
below. The key derivation process incorporates both the input
secrets and the handshake transcript. Note that because the
handshake transcript includes the random values from the Hello
messages, any given handshake will have different traffic secrets,
even if the same input secrets are used, as is the case when the same
PSK is used for multiple connections.
struct {
uint16 length = Length;
opaque label<7..255> = "tls13 " + Label;
opaque context<0..255> = Context;
} HkdfLabel;
Note: With common hash functions, any label longer than 12 characters
requires an additional iteration of the hash function to compute.
The labels in this specification have all been chosen to fit within
this limit.
Keys are derived from two input secrets using the HKDF-Extract and
Derive-Secret functions. The general pattern for adding a new secret
is to use HKDF-Extract with the Salt being the current secret state
and the Input Keying Material (IKM) being the new secret to be added.
In this version of TLS 1.3, the two input secrets are:
- HKDF-Extract is drawn as taking the Salt argument from the top and
the IKM argument from the left, with its output to the bottom and
the name of the output on the right.
0
|
v
PSK -> HKDF-Extract = Early Secret
|
+-----> Derive-Secret(., "ext binder" | "res binder", "")
| = binder_key
|
+-----> Derive-Secret(., "c e traffic", ClientHello)
| = client_early_traffic_secret
|
+-----> Derive-Secret(., "e exp master", ClientHello)
| = early_exporter_master_secret
v
Derive-Secret(., "derived", "")
|
v
(EC)DHE -> HKDF-Extract = Handshake Secret
|
+-----> Derive-Secret(., "c hs traffic",
| ClientHello...ServerHello)
| = client_handshake_traffic_secret
|
+-----> Derive-Secret(., "s hs traffic",
| ClientHello...ServerHello)
| = server_handshake_traffic_secret
v
Derive-Secret(., "derived", "")
|
v
0 -> HKDF-Extract = Master Secret
|
+-----> Derive-Secret(., "c ap traffic",
| ClientHello...server Finished)
| = client_application_traffic_secret_0
|
+-----> Derive-Secret(., "s ap traffic",
| ClientHello...server Finished)
| = server_application_traffic_secret_0
|
+-----> Derive-Secret(., "exp master",
| ClientHello...server Finished)
| = exporter_master_secret
|
+-----> Derive-Secret(., "res master",
ClientHello...client Finished)
= resumption_master_secret
The general pattern here is that the secrets shown down the left side
of the diagram are just raw entropy without context, whereas the
secrets down the right side include Handshake Context and therefore
can be used to derive working keys without additional context. Note
that the different calls to Derive-Secret may take different Messages
arguments, even with the same secret. In a 0-RTT exchange,
Derive-Secret is called with four distinct transcripts; in a
1-RTT-only exchange, it is called with three distinct transcripts.
Once all the values which are to be derived from a given secret have
been computed, that secret SHOULD be erased.
application_traffic_secret_N+1 =
HKDF-Expand-Label(application_traffic_secret_N,
"traffic upd", "", Hash.length)
- A secret value
+-------------------+---------------------------------------+
| Record Type | Secret |
+-------------------+---------------------------------------+
| 0-RTT Application | client_early_traffic_secret |
| | |
| Handshake | [<a href="#ref-
sender">sender</a>]_handshake_traffic_secret |
| | |
| Application Data | [<a href="#ref-
sender">sender</a>]_application_traffic_secret_N |
+-------------------+---------------------------------------+
- The ECDH shared secret is the result of applying the ECDH scalar
multiplication function to the secret key (into scalar input) and
the peer's public key (into u-coordinate point input). The output
is used raw, with no processing.
provides the same or a stronger guarantee. The "at most once per
server instance" guarantee is a minimum requirement; servers SHOULD
limit 0-RTT replays further when feasible.
The second class of attack cannot be prevented at the TLS layer and
MUST be dealt with by any application. Note that any application
whose clients implement any kind of retry behavior already needs to
implement some sort of anti-replay defense.
If the tickets are not self-contained but rather are database keys,
and the corresponding PSKs are deleted upon use, then connections
established using PSKs enjoy forward secrecy. This improves security
for all 0-RTT data and PSK usage when PSK is used without (EC)DHE.
The server MUST derive the storage key only from validated sections
of the ClientHello. If the ClientHello contains multiple PSK
identities, then an attacker can create multiple ClientHellos with
different binder values for the less-preferred identity on the
assumption that the server will not verify it (as recommended by
<a href="#section-4.2.11">Section 4.2.11</a>). I.e., if the client sends PSKs A
and B but the
server prefers A, then the attacker can change the binder for B
without affecting the binder for A. If the binder for B is part of
the storage key, then this ClientHello will not appear as a
duplicate, which will cause the ClientHello to be accepted, and may
cause side effects such as replay cache pollution, although any 0-RTT
data will not be decryptable because it will use different keys. If
the validated binder or the ClientHello.random is used as the storage
key, then this attack is not possible.
Note: If the client's clock is running much faster than the server's,
then a ClientHello may be received that is outside the window in the
future, in which case it might be accepted for 1-RTT, causing a
client retry, and then acceptable later for 0-RTT. This is another
variant of the second form of attack described in <a href="#section-8">Section
8</a>.
Because the ClientHello indicates the time at which the client sent
it, it is possible to efficiently determine whether a ClientHello was
likely sent reasonably recently and only accept 0-RTT for such a
ClientHello, otherwise falling back to a 1-RTT handshake. This is
necessary for the ClientHello storage mechanism described in
<a href="#section-8.2">Section 8.2</a> because otherwise the server needs to
store an unlimited
number of ClientHellos, and is a useful optimization for self-
contained single-use tickets because it allows efficient rejection of
ClientHellos which cannot be used for 0-RTT.
This value can be encoded in the ticket, thus avoiding the need to
keep state for each outstanding ticket. The server can determine the
client's view of the age of the ticket by subtracting the ticket's
"ticket_age_add" value from the "obfuscated_ticket_age" parameter in
the client's "pre_shared_key" extension. The server can determine
the expected_arrival_time of the ClientHello as:
All implementations MUST send and use these extensions when offering
applicable features:
- TLS Cipher Suites registry: values with the first byte in the
range 0-254 (decimal) are assigned via Specification Required
[<a href="https://tools.ietf.org/html/rfc8126" title=""Guidelines for
Writing an IANA Considerations Section in RFCs"">RFC8126</a>]. Values with
the first byte 255 (decimal) are reserved
for Private Use [<a href="https://tools.ietf.org/html/rfc8126"
title=""Guidelines for Writing an IANA Considerations Section in
RFCs"">RFC8126</a>].
- IANA has updated this registry to include a "TLS 1.3" column which
lists the messages in which the extension may appear. This column
has been initially populated from the table in <a href="#section-4.2">Section
4.2</a>, with
any extension not listed there marked as "-" to indicate that it
is not used by TLS 1.3.
START <----+
Send ClientHello | | Recv HelloRetryRequest
[K_send = early data] | |
v |
/ WAIT_SH ----+
| | Recv ServerHello
| | K_recv = handshake
Can | V
send | WAIT_EE
early | | Recv EncryptedExtensions
data | +--------+--------+
| Using | | Using certificate
| PSK | v
| | WAIT_CERT_CR
| | Recv | | Recv CertificateRequest
| | Certificate | v
| | | WAIT_CERT
| | | | Recv Certificate
| | v v
| | WAIT_CV
| | | Recv CertificateVerify
| +> WAIT_FINISHED <+
| | Recv Finished
\ | [Send EndOfEarlyData]
| K_send = handshake
| [Send Certificate [+ CertificateVerify]]
Can send | Send Finished
app data --> | K_send = K_recv = application
after here v
CONNECTED
Note that with the transitions as shown above, clients may send
alerts that derive from post-ServerHello messages in the clear or
with the early data keys. If clients need to send such alerts, they
SHOULD first rekey to the handshake keys if possible.
START <-----+
Recv ClientHello | | Send HelloRetryRequest
v |
RECVD_CH ----+
| Select parameters
v
NEGOTIATED
| Send ServerHello
| K_send = handshake
| Send EncryptedExtensions
| [Send CertificateRequest]
Can send | [Send Certificate + CertificateVerify]
app data | Send Finished
after --> | K_send = application
here +--------+--------+
No 0-RTT | | 0-RTT
| |
K_recv = handshake | | K_recv = early data
[Skip decrypt errors] | +------> WAIT_EOED -+
| | Recv | | Recv EndOfEarlyData
| | early data | | K_recv = handshake
| +------------+ |
| |
+> WAIT_FLIGHT2 <--------+
|
+--------+--------+
No auth | | Client auth
| |
| v
| WAIT_CERT
| Recv | | Recv Certificate
| empty | v
| Certificate | WAIT_CV
| | | Recv
| v | CertificateVerify
+-> WAIT_FINISHED <---+
| Recv Finished
| K_recv = application
v
CONNECTED
enum {
invalid(0),
change_cipher_spec(20),
alert(21),
handshake(22),
application_data(23),
heartbeat(24), /* <a href="https://tools.ietf.org/html/rfc6520">RFC
6520</a> */
(255)
} ContentType;
struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;
struct {
opaque content[TLSPlaintext.length];
ContentType type;
uint8 zeros[length_of_padding];
} TLSInnerPlaintext;
struct {
ContentType opaque_type = application_data; /* 23 */
ProtocolVersion legacy_record_version = 0x0303; /* TLS v1.2 */
uint16 length;
opaque encrypted_record[TLSCiphertext.length];
} TLSCiphertext;
enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure_RESERVED(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
inappropriate_fallback(86),
user_canceled(90),
no_renegotiation_RESERVED(100),
missing_extension(109),
unsupported_extension(110),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),
(255)
} AlertDescription;
struct {
AlertLevel level;
AlertDescription description;
} Alert;
enum {
hello_request_RESERVED(0),
client_hello(1),
server_hello(2),
hello_verify_request_RESERVED(3),
new_session_ticket(4),
end_of_early_data(5),
hello_retry_request_RESERVED(6),
encrypted_extensions(8),
certificate(11),
server_key_exchange_RESERVED(12),
certificate_request(13),
server_hello_done_RESERVED(14),
certificate_verify(15),
client_key_exchange_RESERVED(16),
finished(20),
certificate_url_RESERVED(21),
certificate_status_RESERVED(22),
supplemental_data_RESERVED(23),
key_update(24),
message_hash(254),
(255)
} HandshakeType;
struct {
HandshakeType msg_type; /* handshake type */
uint24 length; /* bytes in message */
select (Handshake.msg_type) {
case client_hello: ClientHello;
case server_hello: ServerHello;
case end_of_early_data: EndOfEarlyData;
case encrypted_extensions: EncryptedExtensions;
case certificate_request: CertificateRequest;
case certificate: Certificate;
case certificate_verify: CertificateVerify;
case finished: Finished;
case new_session_ticket: NewSessionTicket;
case key_update: KeyUpdate;
};
} Handshake;
uint16 ProtocolVersion;
opaque Random[32];
uint8 CipherSuite[2]; /* Cryptographic suite selector */
struct {
ProtocolVersion legacy_version = 0x0303; /* TLS v1.2 */
Random random;
opaque legacy_session_id<0..32>;
CipherSuite cipher_suites<2..2^16-2>;
opaque legacy_compression_methods<1..2^8-1>;
Extension extensions<8..2^16-1>;
} ClientHello;
struct {
ProtocolVersion legacy_version = 0x0303; /* TLS v1.2 */
Random random;
opaque legacy_session_id_echo<0..32>;
CipherSuite cipher_suite;
uint8 legacy_compression_method = 0;
Extension extensions<6..2^16-1>;
} ServerHello;
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
enum {
server_name(0), /* <a
href="https://tools.ietf.org/html/rfc6066">RFC 6066</a> */
max_fragment_length(1), /* <a
href="https://tools.ietf.org/html/rfc6066">RFC 6066</a> */
status_request(5), /* <a
href="https://tools.ietf.org/html/rfc6066">RFC 6066</a> */
supported_groups(10), /* <a
href="https://tools.ietf.org/html/rfc8422">RFC 8422</a>, 7919 */
signature_algorithms(13), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
use_srtp(14), /* <a
href="https://tools.ietf.org/html/rfc5764">RFC 5764</a> */
heartbeat(15), /* <a
href="https://tools.ietf.org/html/rfc6520">RFC 6520</a> */
application_layer_protocol_negotiation(16), /* <a
href="https://tools.ietf.org/html/rfc7301">RFC 7301</a> */
signed_certificate_timestamp(18), /* <a
href="https://tools.ietf.org/html/rfc6962">RFC 6962</a> */
client_certificate_type(19), /* <a
href="https://tools.ietf.org/html/rfc7250">RFC 7250</a> */
server_certificate_type(20), /* <a
href="https://tools.ietf.org/html/rfc7250">RFC 7250</a> */
padding(21), /* <a
href="https://tools.ietf.org/html/rfc7685">RFC 7685</a> */
RESERVED(40), /* Used but never
assigned */
pre_shared_key(41), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
early_data(42), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
supported_versions(43), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
cookie(44), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
psk_key_exchange_modes(45), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
RESERVED(46), /* Used but never
assigned */
certificate_authorities(47), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
oid_filters(48), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
post_handshake_auth(49), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
signature_algorithms_cert(50), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
key_share(51), /* <a
href="https://tools.ietf.org/html/rfc8446">RFC 8446</a> */
(65535)
} ExtensionType;
struct {
NamedGroup group;
opaque key_exchange<1..2^16-1>;
} KeyShareEntry;
struct {
KeyShareEntry client_shares<0..2^16-1>;
} KeyShareClientHello;
struct {
NamedGroup selected_group;
} KeyShareHelloRetryRequest;
struct {
KeyShareEntry server_share;
} KeyShareServerHello;
struct {
uint8 legacy_form = 4;
opaque X[coordinate_length];
opaque Y[coordinate_length];
} UncompressedPointRepresentation;
struct {
PskKeyExchangeMode ke_modes<1..255>;
} PskKeyExchangeModes;
struct {} Empty;
struct {
select (Handshake.msg_type) {
case new_session_ticket: uint32 max_early_data_size;
case client_hello: Empty;
case encrypted_extensions: Empty;
};
} EarlyDataIndication;
struct {
opaque identity<1..2^16-1>;
uint32 obfuscated_ticket_age;
} PskIdentity;
opaque PskBinderEntry<32..255>;
struct {
PskIdentity identities<7..2^16-1>;
PskBinderEntry binders<33..2^16-1>;
} OfferedPsks;
struct {
select (Handshake.msg_type) {
case client_hello: OfferedPsks;
case server_hello: uint16 selected_identity;
};
} PreSharedKeyExtension;
struct {
select (Handshake.msg_type) {
case client_hello:
ProtocolVersion versions<2..254>;
struct {
opaque cookie<1..2^16-1>;
} Cookie;
<span class="grey">Rescorla Standards Track
[Page 128]</span></pre>
<hr class="noprint" style="width: 96ex;" align="left"><!--NewPage--><pre
class="newpage"><a name="page-129" id="page-129" href="#page-129"
class="invisible"> </a>
<span class="grey"><a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>
TLS August 2018</span>
enum {
/* RSASSA-PKCS1-v1_5 algorithms */
rsa_pkcs1_sha256(0x0401),
rsa_pkcs1_sha384(0x0501),
rsa_pkcs1_sha512(0x0601),
/* ECDSA algorithms */
ecdsa_secp256r1_sha256(0x0403),
ecdsa_secp384r1_sha384(0x0503),
ecdsa_secp521r1_sha512(0x0603),
/* EdDSA algorithms */
ed25519(0x0807),
ed448(0x0808),
/* Legacy algorithms */
rsa_pkcs1_sha1(0x0201),
ecdsa_sha1(0x0203),
struct {
SignatureScheme supported_signature_algorithms<2..2^16-2>;
} SignatureSchemeList;
enum {
unallocated_RESERVED(0x0000),
struct {
NamedGroup named_group_list<2..2^16-1>;
} NamedGroupList;
opaque DistinguishedName<1..2^16-1>;
struct {
DistinguishedName authorities<3..2^16-1>;
} CertificateAuthoritiesExtension;
struct {
opaque certificate_extension_oid<1..2^8-1>;
opaque certificate_extension_values<0..2^16-1>;
} OIDFilter;
struct {
OIDFilter filters<0..2^16-1>;
} OIDFilterExtension;
struct {} PostHandshakeAuth;
struct {
Extension extensions<0..2^16-1>;
} EncryptedExtensions;
struct {
opaque certificate_request_context<0..2^8-1>;
Extension extensions<2..2^16-1>;
} CertificateRequest;
<span class="grey">Rescorla Standards Track
[Page 131]</span></pre>
<hr class="noprint" style="width: 96ex;" align="left"><!--NewPage--><pre
class="newpage"><a name="page-132" id="page-132" href="#page-132"
class="invisible"> </a>
<span class="grey"><a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>
TLS August 2018</span>
enum {
X509(0),
OpenPGP_RESERVED(1),
RawPublicKey(2),
(255)
} CertificateType;
struct {
select (certificate_type) {
case RawPublicKey:
/* From <a href="https://tools.ietf.org/html/rfc7250">RFC 7250</a>
ASN.1_subjectPublicKeyInfo */
opaque ASN1_subjectPublicKeyInfo<1..2^24-1>;
case X509:
opaque cert_data<1..2^24-1>;
};
Extension extensions<0..2^16-1>;
} CertificateEntry;
struct {
opaque certificate_request_context<0..2^8-1>;
CertificateEntry certificate_list<0..2^24-1>;
} Certificate;
struct {
SignatureScheme algorithm;
opaque signature<0..2^16-1>;
} CertificateVerify;
struct {
opaque verify_data[Hash.length];
} Finished;
struct {
uint32 ticket_lifetime;
uint32 ticket_age_add;
opaque ticket_nonce<0..255>;
opaque ticket<1..2^16-1>;
Extension extensions<0..2^16-2>;
} NewSessionTicket;
struct {} EndOfEarlyData;
enum {
update_not_requested(0), update_requested(1), (255)
} KeyUpdateRequest;
struct {
KeyUpdateRequest request_update;
} KeyUpdate;
A symmetric cipher suite defines the pair of the AEAD algorithm and
hash algorithm to be used with HKDF. Cipher suite names follow the
naming convention:
+-----------+------------------------------------------------+
| Component | Contents |
+-----------+------------------------------------------------+
| TLS | The string "TLS" |
| | |
| AEAD | The AEAD algorithm used for record protection |
| | |
| HASH | The hash algorithm used with HKDF |
| | |
| VALUE | The two-byte ID assigned for this cipher suite |
+-----------+------------------------------------------------+
This specification defines the following cipher suites for use with
TLS 1.3.
+------------------------------+-------------+
| Description | Value |
+------------------------------+-------------+
| TLS_AES_128_GCM_SHA256 | {0x13,0x01} |
| | |
| TLS_AES_256_GCM_SHA384 | {0x13,0x02} |
| | |
| TLS_CHACHA20_POLY1305_SHA256 | {0x13,0x03} |
| | |
| TLS_AES_128_CCM_SHA256 | {0x13,0x04} |
| | |
| TLS_AES_128_CCM_8_SHA256 | {0x13,0x05} |
+------------------------------+-------------+
Although TLS 1.3 uses the same cipher suite space as previous
versions of TLS, TLS 1.3 cipher suites are defined differently, only
specifying the symmetric ciphers, and cannot be used for TLS 1.2.
Similarly, cipher suites for TLS 1.2 and lower cannot be used with
TLS 1.3.
The TLS protocol cannot prevent many common security mistakes. This
appendix provides several recommendations to assist implementors.
[<a href="#ref-TLS13-TRACES" title=""Example Handshake Traces for TLS
1.3"">TLS13-TRACES</a>] provides test vectors for TLS 1.3 handshakes.
TLS uses random values (1) in public protocol fields such as the
public Random values in the ClientHello and ServerHello and (2) to
generate keying material. With a properly functioning CSPRNG, this
does not present a security problem, as it is not feasible to
determine the CSPRNG state from its output. However, with a broken
CSPRNG, it may be possible for an attacker to use the public output
to determine the CSPRNG internal state and thereby predict the keying
material, as documented in [<a href="#ref-CHECKOWAY" title=""A Systematic
Analysis of the Juniper Dual EC Incident"">CHECKOWAY</a>]. Implementations
can provide
extra security against this form of attack by using separate CSPRNGs
to generate public and private values.
- Have you ensured that all support for SSL, RC4, EXPORT ciphers,
and MD5 (via the "signature_algorithms" extension) is completely
removed from all possible configurations that support TLS 1.3 or
later, and that attempts to use these obsolete capabilities fail
correctly (see <a href="#appendix-D">Appendix D</a>)?
Cryptographic details:
- Does your TLS client check that the Diffie-Hellman parameters sent
by the server are acceptable (see <a href="#section-4.2.8.1">Section
4.2.8.1</a>)?
TLS 1.x and SSL 3.0 use compatible ClientHello messages. Servers can
also handle clients trying to use future versions of TLS as long as
the ClientHello format remains compatible and there is at least one
protocol version supported by both the client and the server.
A TLS 1.3 client who wishes to negotiate with servers that do not
support TLS 1.3 will send a normal TLS 1.3 ClientHello containing
0x0303 (TLS 1.2) in ClientHello.legacy_version but with the correct
version(s) in the "supported_versions" extension. If the server does
not support TLS 1.3, it will respond with a ServerHello containing an
older version number. If the client agrees to use this version, the
negotiation will proceed as appropriate for the negotiated protocol.
A client using a ticket for resumption SHOULD initiate the connection
using the version that was previously negotiated.
Note that 0-RTT data is not compatible with older servers and
SHOULD NOT be sent absent knowledge that the server supports TLS 1.3.
See <a href="#appendix-D.3">Appendix D.3</a>.
Some legacy server implementations are known to not implement the TLS
specification properly and might abort connections upon encountering
TLS extensions or versions which they are not aware of.
Interoperability with buggy servers is a complex topic beyond the
scope of this document. Multiple connection attempts may be required
in order to negotiate a backward-compatible connection; however, this
practice is vulnerable to downgrade attacks and is NOT RECOMMENDED.
Note that earlier versions of TLS did not clearly specify the record
layer version number value in all cases
(TLSPlaintext.legacy_record_version). Servers will receive various
TLS 1.x versions in this field, but its value MUST always be ignored.
When put together, these changes make the TLS 1.3 handshake resemble
TLS 1.2 session resumption, which improves the chance of successfully
connecting through middleboxes. This "compatibility mode" is
partially negotiated: the client can opt to provide a session ID or
not, and the server has to echo it. Either side can send
Old versions of TLS permitted the use of very low strength ciphers.
Ciphers with a strength less than 112 bits MUST NOT be offered or
negotiated for any version of TLS for any reason.
Implementations MUST NOT send any records with a version less than
0x0300. Implementations SHOULD NOT accept any records with a version
less than 0x0300 (but may inadvertently do so if the record version
number is ignored completely).
Secrecy of the session keys: The shared session keys should be known
only to the communicating parties and not to the attacker (see
[<a href="#ref-CK01" title=""Analysis of Key-Exchange Protocols and
Their Use for Building Secure Channels"">CK01</a>], Definition 1, part 2).
Note that in a unilaterally
authenticated connection, the attacker can establish its own
session keys with the server, but those session keys are distinct
from those established by the client.
The external PSK and resumption PSK bootstrap from a long-term shared
secret into a unique per-connection set of short-term session keys.
This secret may have been established in a previous handshake. If
PSK with (EC)DHE key establishment is used, these session keys will
also be forward secret. The resumption PSK has been designed so that
the resumption master secret computed by connection N and needed to
form connection N+1 is separate from the traffic keys used by
The PSK binder value forms a binding between a PSK and the current
handshake, as well as between the session where the PSK was
established and the current session. This binding transitively
includes the original handshake transcript, because that transcript
is digested into the values which produce the resumption master
secret. This requires that both the KDF used to produce the
resumption master secret and the MAC used to compute the binder be
collision resistant. See <a href="#appendix-E.1.1">Appendix E.1.1</a> for more
on this. Note: The
binder does not cover the binder values from other PSKs, though they
are included in the Finished MAC.
For all handshake modes, the Finished MAC (and, where present, the
signature) prevents downgrade attacks. In addition, the use of
certain bytes in the random nonces as described in <a href="#section-
4.1.3">Section 4.1.3</a>
allows the detection of downgrade to previous TLS versions. See
[<a href="#ref-BBFGKZ16" title=""Downgrade Resilience in Key-Exchange
Protocols"">BBFGKZ16</a>] for more details on TLS 1.3 and downgrade.
TLS does not provide security for handshakes which take place after
the peer's long-term secret (signature key or external PSK) is
compromised. It therefore does not provide post-compromise security
[<a href="#ref-CCG16" title=""On Post-compromise
Security"">CCG16</a>], sometimes also referred to as backward or future
secrecy.
This is in contrast to KCI resistance, which describes the security
guarantees that a party has after its own long-term secret has been
compromised.
TLS does not provide any specific defenses against this form of
attack but does include a padding mechanism for use by applications:
The plaintext protected by the AEAD function consists of content plus
variable-length padding, which allows the application to produce
arbitrary-length encrypted records as well as padding-only cover
traffic to conceal the difference between periods of transmission and
periods of silence. Because the padding is encrypted alongside the
actual content, an attacker cannot directly determine the length of
the padding but may be able to measure it indirectly by the use of
timing channels exposed during record processing (i.e., seeing how
long it takes to process a record or trickling in records to see
<span class="grey">Rescorla Standards Track
[Page 148]</span></pre>
<hr class="noprint" style="width: 96ex;" align="left"><!--NewPage--><pre
class="newpage"><a name="page-149" id="page-149" href="#page-149"
class="invisible"> </a>
<span class="grey"><a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>
TLS August 2018</span>
Application protocols MUST NOT use 0-RTT data without a profile that
defines its use. That profile needs to identify which messages or
interactions are safe to use with 0-RTT and how to handle the
situation when the server rejects 0-RTT and falls back to 1-RTT.
Although TLS 1.3 does not use RSA key transport and so is not
directly susceptible to Bleichenbacher-type attacks [<a href="#ref-Blei98"
title=""Chosen Ciphertext Attacks against Protocols Based on RSA Encryption
Standard PKCS #1"">Blei98</a>], if TLS
1.3 servers also support static RSA in the context of previous
versions of TLS, then it may be possible to impersonate the server
for TLS 1.3 connections [<a href="#ref-JSS15" title=""On the Security of
TLS 1.3 and QUIC Against Weaknesses in PKCS#1 v1.5 Encryption"">JSS15</a>].
TLS 1.3 implementations can prevent
this attack by disabling support for static RSA across all versions
of TLS. In principle, implementations might also be able to separate
certificates with different keyUsage bits for static RSA decryption
and RSA signature, but this technique relies on clients refusing to
accept signatures using keys in certificates that do not have the
digitalSignature bit set, and many clients do not enforce this
restriction.
Contributors
Martin Abadi
University of California, Santa Cruz
abadi@cs.ucsc.edu
Christopher Allen
(co-editor of TLS 1.0)
Alacrity Ventures
ChristopherA@AlacrityManagement.com
Richard Barnes
Cisco
rlb@ipv.sx
Steven M. Bellovin
Columbia University
smb@cs.columbia.edu
David Benjamin
Google
davidben@google.com
Benjamin Beurdouche
INRIA & Microsoft Research
benjamin.beurdouche@ens.fr
Karthikeyan Bhargavan
(editor of [<a href="https://tools.ietf.org/html/rfc7627" title=""Transport
Layer Security (TLS) Session Hash and Extended Master Secret
Extension"">RFC7627</a>])
INRIA
karthikeyan.bhargavan@inria.fr
Simon Blake-Wilson
(co-author of [<a href="https://tools.ietf.org/html/rfc4492"
title=""Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
Security (TLS)"">RFC4492</a>])
BCI
sblakewilson@bcisse.com
Nelson Bolyard
(co-author of [<a href="https://tools.ietf.org/html/rfc4492"
title=""Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
Security (TLS)"">RFC4492</a>])
Sun Microsystems, Inc.
nelson@bolyard.com
Ran Canetti
IBM
canetti@watson.ibm.com
Matt Caswell
OpenSSL
matt@openssl.org
Stephen Checkoway
University of Illinois at Chicago
sfc@uic.edu
Pete Chown
Skygate Technology Ltd
pc@skygate.co.uk
Katriel Cohn-Gordon
University of Oxford
me@katriel.co.uk
Cas Cremers
University of Oxford
cas.cremers@cs.ox.ac.uk
Antoine Delignat-Lavaud
(co-author of [<a href="https://tools.ietf.org/html/rfc7627"
title=""Transport Layer Security (TLS) Session Hash and Extended Master Secret
Extension"">RFC7627</a>])
INRIA
antdl@microsoft.com
Tim Dierks
(co-author of TLS 1.0, co-editor of TLS 1.1 and 1.2)
Independent
tim@dierks.org
Roelof DuToit
Symantec Corporation
roelof_dutoit@symantec.com
Taher Elgamal
Securify
taher@securify.com
Pasi Eronen
Nokia
pasi.eronen@nokia.com
Cedric Fournet
Microsoft
fournet@microsoft.com
Anil Gangolli
anil@busybuddha.org
David M. Garrett
dave@nulldereference.com
Illya Gerasymchuk
Independent
illya@iluxonchik.me
Alessandro Ghedini
Cloudflare Inc.
alessandro@cloudflare.com
Matthew Green
Johns Hopkins University
mgreen@cs.jhu.edu
Jens Guballa
ETAS
jens.guballa@etas.com
Felix Guenther
TU Darmstadt
mail@felixguenther.info
Vipul Gupta
(co-author of [<a href="https://tools.ietf.org/html/rfc4492"
title=""Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
Security (TLS)"">RFC4492</a>])
Sun Microsystems Laboratories
vipul.gupta@sun.com
Chris Hawk
(co-author of [<a href="https://tools.ietf.org/html/rfc4492"
title=""Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
Security (TLS)"">RFC4492</a>])
Corriente Networks LLC
chris@corriente.net
Kipp Hickman
Alfred Hoenes
David Hopwood
Independent Consultant
david.hopwood@blueyonder.co.uk
Marko Horvat
MPI-SWS
mhorvat@mpi-sws.org
Jonathan Hoyland
Royal Holloway, University of London
jonathan.hoyland@gmail.com
Subodh Iyengar
Facebook
subodh@fb.com
Benjamin Kaduk
Akamai Technologies
kaduk@mit.edu
Hubert Kario
Red Hat Inc.
hkario@redhat.com
Phil Karlton
(co-author of SSL 3.0)
Leon Klingele
Independent
mail@leonklingele.de
Paul Kocher
(co-author of SSL 3.0)
Cryptography Research
paul@cryptography.com
Hugo Krawczyk
IBM
hugokraw@us.ibm.com
Adam Langley
(co-author of [<a href="https://tools.ietf.org/html/rfc7627"
title=""Transport Layer Security (TLS) Session Hash and Extended Master Secret
Extension"">RFC7627</a>])
Google
agl@google.com
Olivier Levillain
ANSSI
olivier.levillain@ssi.gouv.fr
Xiaoyin Liu
University of North Carolina at Chapel Hill
xiaoyin.l@outlook.com
Ilari Liusvaara
Independent
ilariliusvaara@welho.com
Atul Luykx
K.U. Leuven
atul.luykx@kuleuven.be
Colm MacCarthaigh
Amazon Web Services
colm@allcosts.net
Carl Mehner
USAA
carl.mehner@usaa.com
Jan Mikkelsen
Transactionware
janm@transactionware.com
Bodo Moeller
(co-author of [<a href="https://tools.ietf.org/html/rfc4492"
title=""Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
Security (TLS)"">RFC4492</a>])
Google
bodo@acm.org
Kyle Nekritz
Facebook
knekritz@fb.com
Erik Nygren
Akamai Technologies
erik+ietf@nygren.org
Magnus Nystrom
Microsoft
mnystrom@microsoft.com
Kazuho Oku
DeNA Co., Ltd.
kazuhooku@gmail.com
Kenny Paterson
Royal Holloway, University of London
kenny.paterson@rhul.ac.uk
Christopher Patton
University of Florida
cjpatton@ufl.edu
Alfredo Pironti
(co-author of [<a href="https://tools.ietf.org/html/rfc7627"
title=""Transport Layer Security (TLS) Session Hash and Extended Master Secret
Extension"">RFC7627</a>])
INRIA
alfredo.pironti@inria.fr
Andrei Popov
Microsoft
andrei.popov@microsoft.com
Marsh Ray
(co-author of [<a href="https://tools.ietf.org/html/rfc7627"
title=""Transport Layer Security (TLS) Session Hash and Extended Master Secret
Extension"">RFC7627</a>])
Microsoft
maray@microsoft.com
Robert Relyea
Netscape Communications
relyea@netscape.com
Kyle Rose
Akamai Technologies
krose@krose.org
Jim Roskind
Amazon
jroskind@amazon.com
Michael Sabin
Joe Salowey
Tableau Software
joe@salowey.net
Rich Salz
Akamai
rsalz@akamai.com
David Schinazi
Apple Inc.
dschinazi@apple.com
Sam Scott
Royal Holloway, University of London
me@samjs.co.uk
Thomas Shrimpton
University of Florida
teshrim@ufl.edu
Dan Simon
Microsoft, Inc.
dansimon@microsoft.com
Brian Smith
Independent
brian@briansmith.org
Brian Sniffen
Akamai Technologies
ietf@bts.evenmere.org
Nick Sullivan
Cloudflare Inc.
nick@cloudflare.com
Bjoern Tackmann
University of California, San Diego
btackmann@eng.ucsd.edu
Tim Taubert
Mozilla
ttaubert@mozilla.com
Martin Thomson
Mozilla
mt@mozilla.com
Hannes Tschofenig
Arm Limited
Hannes.Tschofenig@arm.com
Sean Turner
sn3rd
sean@sn3rd.com
Steven Valdez
Google
svaldez@google.com
Filippo Valsorda
Cloudflare Inc.
filippo@cloudflare.com
Victor Vasiliev
Google
vasilvv@google.com
Hoeteck Wee
Ecole Normale Superieure, Paris
hoeteck@alum.mit.edu
Tom Weinstein
David Wong
NCC Group
david.wong@nccgroup.trust
Christopher A. Wood
Apple Inc.
cawood@apple.com
Tim Wright
Vodafone
timothy.wright@vodafone.com
Peter Wu
Independent
peter@lekensteyn.nl
Kazu Yamamoto
Internet Initiative Japan Inc.
kazu@iij.ad.jp
Author's Address
Eric Rescorla
Mozilla
Email: ekr@rtfm.com
</pre><br>
<span class="noprint"><small><small>Html markup produced by rfcmarkup 1.129c,
available from
<a
href="https://tools.ietf.org/tools/rfcmarkup/">https://tools.ietf.org/tools/rfcmark
up/</a>
</small></small></span>
</div>
</body></html>