RFC 8449
Record Size Limit Extension for TLS
Record Size Limit Extension for TLS π
Okay bestie, this is RFC 8449, and it's a Standards Track document from the IETF, so it's the real deal, not a draft we're just vibing with π M. Thomson at Mozilla wrote it, and it came out in August 2018. It updates RFC 6066 and doesn't obsolete anything. Its ISSN is 2070-1721 β¨
Abstract β¨
This is an extension to Transport Layer Security (TLS) that lets endpoints negotiate the maximum size of protected records each one will send to the other π¦
It replaces the maximum fragment length extension from RFC 6066 π
Status of This Memo π
This is an Internet Standards Track document π₯
It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community. It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). More info on Internet Standards is in Section 2 of RFC 7841 π
For the current status, any errata, and how to give feedback, check https://www.rfc-editor.org/info/rfc8449 π«Ά
Copyright Notice Β©οΈ
Copyright (c) 2018 IETF Trust and the persons identified as the document authors. All rights reserved π
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they were in effect on the date of publication. Please actually read these, because they spell out your rights and restrictions π
If you pull Code Components out of this document, they have to include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions. They're also provided without warranty, as described in the Simplified BSD License β
Table of Contents π§
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Conventions and Definitions . . . . . . . . . . . . . . . . . 3
3. Limitations of the "max_fragment_length" Extension . . . . . 3
4. The "record_size_limit" Extension . . . . . . . . . . . . . . 4
4.1. Record Expansion Limits . . . . . . . . . . . . . . . . . 6
5. Deprecating "max_fragment_length" . . . . . . . . . . . . . . 6
6. Security Considerations . . . . . . . . . . . . . . . . . . . 7
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 7
8. References . . . . . . . . . . . . . . . . . . . . . . . . . 7
8.1. Normative References . . . . . . . . . . . . . . . . . . 7
8.2. Informative References . . . . . . . . . . . . . . . . . 8
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 8
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 8
1. Introduction πΈ
Implementing Transport Layer Security (TLS) [TLS] or Datagram TLS (DTLS) [DTLS] on constrained devices can be a whole challenge π But recent improvements in how cryptographic algorithms are designed and implemented have made TLS accessible to some super limited devices (see, for example, [RFC7925]) β¨
Receiving big protected records is especially rough for a device with limited operating memory π TLS versions 1.2 [RFC5246] and earlier let senders generate records 16384 octets in size, plus any expansion from compression and protection up to 2048 octets (though it's usually only 16 octets). TLS 1.3 shrinks that expansion allowance to 256 octets. Setting aside up to 18K of memory for ciphertext is more than some implementations can handle π
An Authentication Encryption with Additional Data (AEAD) cipher (see [RFC5116]) API needs the entire record to be present before it can decrypt and authenticate it. Other ciphers can't produce authenticated data until the whole record is there either. Processing records piece by piece exposes endpoints to the risk of forged data π©
The "max_fragment_length" extension [RFC6066] was designed to let constrained clients negotiate a lower record size. However, "max_fragment_length" has several design problems (see Section 3) π©
This document defines a record_size_limit extension (Section 4) π It replaces "max_fragment_length" [RFC6066], which this document deprecates. The record_size_limit extension is valid in all versions of TLS π
A smaller protected record size is just one of many problems a constrained implementation might need to solve. The record_size_limit extension only addresses the memory allocation problem. It does not address limits on code size, processing capability, or bandwidth capacity π«Ά
2. Conventions and Definitions π
Okay so the BCP 14 key words in this document are "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL". They're interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here π₯
3. Limitations of the "max_fragment_length" Extension π¦
The "max_fragment_length" extension has several limitations, and they make it unsuitable for use π
A client that has no constraints stopping it from accepting a large record can't use "max_fragment_length" without risking a reduction in record size. The maximum value the extension permits is 2^12, which is much smaller than the maximum record size of 2^14 the protocol permits π
For large data transfers, small record sizes can seriously affect performance π Every record costs something extra, both in the octets for record headers and in the expansion from encryption. Processing more records also adds computational overhead, and that overhead gets amortized much better with larger record sizes β¨ So clients that can receive large records might not want to risk slowing things down by offering the extension, especially if the extension is rarely needed π
This wouldn't be an issue if a codepoint were available, or could be added, for fragments of 2^14 octets. However, RFC 6066 requires that servers abort the handshake with an illegal_parameter alert if they receive the extension with a value they don't understand. That makes it impossible to add new values to the extension without risking failed connection attempts π
Adding new values is basically a no-go right now, because any new value could make a server kill the handshake. Yikes π¨
A server that negotiates "max_fragment_length" is required to echo the value the client selected. The server can't request a lower limit than the one the client offered. That's a big problem if a server is more constrained than the clients it serves π₯Ί
The "max_fragment_length" extension is also a bad fit when the capabilities of client and server are asymmetric. Constraints on record size are often receiver constraints π―
Compare that to an implementation that can send data incrementally. Encryption doesn't have the same atomicity requirement, and some ciphers can be encrypted and sent progressively. So an endpoint might be willing to send records larger than the limit it advertises for the records it receives π
If these disincentives are enough to stop clients from deploying the "max_fragment_length" extension, then constrained servers are unable to limit record sizes π©
Part 1 of 2 done, the plot thickens π§
4. The "record_size_limit" Extension β¨
okay bestie, this is the main event π
The ExtensionData of the "record_size_limit" extension is just one uint16:
uint16 RecordSizeLimit;
The RecordSizeLimit value is the biggest record (in octets) that an endpoint is willing to receive π It's used to cap how big the records get when you're encoding application data and the protected handshake message into records. Lowkey the whole point. π¦
When this extension is negotiated, an endpoint MUST NOT generate a protected record with plaintext larger than the RecordSizeLimit value it got from its peer. Unprotected messages don't count toward this limit, so they're not subject to it. πΈ
This value is the length of a protected record's plaintext. It includes the content type and any padding added in TLS 1.3, so it's the complete length of TLSInnerPlaintext π§ In TLS 1.2 and earlier, the limit covers all the input to compression and encryption, which is the data that ends up as TLSCiphertext.fragment. Padding added during encryption, like the padding a block cipher adds, is not counted here (see Section 4.1) π
An endpoint that handles every record size can advertise any limit up to the protocol-defined maximum record size. For TLS 1.2 and earlier, that max is 2^14 octets. TLS 1.3 uses 2^14+1 octets. Anything higher is reserved for future versions of the protocol that might allow bigger records π So an endpoint MUST NOT send a value higher than the protocol-defined maximum record size, unless a future version or extension explicitly allows it. A server MUST NOT enforce this restriction, because a client might advertise a higher limit that's enabled by an extension or version the server doesn't understand. A client MAY abort the handshake with an "illegal_parameter" alert if the record_size_limit extension includes a value greater than the maximum record size allowed by the negotiated protocol version and extensions π
Even if a peer gives you a bigger record size limit, an endpoint MUST NOT send records larger than the protocol-defined limit, unless a future TLS version or extension explicitly allows it. Not even if your bestie says it's fine π
The record size limit only applies to records sent toward the endpoint that advertises it. An endpoint can send records bigger than the limit it advertises as its own limit β¨ If a TLS endpoint gets a record larger than its advertised limit, it MUST generate a fatal "record_overflow" alert. If a DTLS endpoint gets one, it MAY either generate a fatal "record_overflow" alert or just discard the record π¦
Endpoints SHOULD advertise the "record_size_limit" extension, even if they don't need to limit record sizes at all. For clients, this lets servers advertise a limit whenever they want. For servers, this lets clients know their limit will actually be respected π«Ά If the extension isn't negotiated, endpoints can send records of any size the protocol or other negotiated extensions allow π
Endpoints MUST NOT send a "record_size_limit" extension with a value smaller than 64. If an endpoint receives a smaller value, it MUST treat that as a fatal error and generate an "illegal_parameter" alert. Not a vibe π
In TLS 1.3, the server sends the "record_size_limit" extension in the EncryptedExtensions message π
During renegotiation or resumption, the record size limit gets renegotiated too. Records are subject to the limits that were set in the handshake that produced the keys protecting them. This means the extension might not be negotiated when a connection is renegotiated or resumed, iykyk πΈ
The Path Maximum Transmission Unit (PMTU) in DTLS also limits record size. The record size limit does not affect PMTU discovery, and it SHOULD be set independently. The record size limit is fixed during the handshake, so it should be set based on constraints at the endpoint and not on the current network environment. PMTU, on the other hand, is determined by the network path and can change over time π§ See [PMTU] and Section 4.1.1.1 of [DTLS] for more detail on PMTU discovery.
PMTU controls the size of UDP datagrams, which limits record size, but it doesn't stop records from being smaller. An endpoint that sends small records can still fit multiple records in a single UDP datagram π¦β¨
4.1. Record Expansion Limits π
The size limit in the "record_size_limit" extension doesn't account for expansion from compression or record protection. A constrained device is expected to disable compression so its record sizes don't jump around unpredictably π Stream ciphers and existing AEAD ciphers don't allow variable expansion, but block ciphers do.
In TLS 1.2, block ciphers add anywhere from 1 to 256 octets of padding. When a limit lower than the protocol-defined limit is advertised, a second limit applies to records that use block ciphers. An endpoint MUST NOT add padding to a record that would make the protected record bigger than a protected record containing the maximum amount of plaintext plus the minimum permitted amount of padding. Yikes, that's a mouthful, but it's just the rule that keeps things tidy π
For example, TLS_RSA_WITH_AES_128_CBC_SHA has 16-octet blocks and a 20-octet MAC. With a record size limit of 256, a record of that length would need a minimum of 11 octets of padding (for [RFC5246], where the MAC is covered by encryption), or 15 octets if the "encrypt_then_mac" extension [RFC7366] is negotiated. With this limit, a record with 250 octets of plaintext could be padded to the same length by adding at most 17 octets of padding, or 21 octets with "encrypt_then_mac" π
An implementation that always adds the minimum amount of padding will always comply with this requirement. Minimum padding, maximum slay π
5. Deprecating "max_fragment_length" π₯
The "record_size_limit" extension replaces the "max_fragment_length" extension [RFC6066]. A server that supports "record_size_limit" MUST ignore a "max_fragment_length" that appears in a ClientHello if both extensions appear. A client MUST treat receipt of both "max_fragment_length" and "record_size_limit" as a fatal error, and it SHOULD generate an "illegal_parameter" alert. So basically, pick one, periodt π
Clients that depend on having a small record size MAY keep advertising "max_fragment_length" πΈ
6. Security Considerations π¨
Very small record sizes might generate additional work for senders and receivers, which can limit throughput and increase exposure to denial of service. Tiny records are not the move, friends. ππ₯
7. IANA Considerations π·
This document registers the "record_size_limit" extension in the "TLS ExtensionType Values" registry established in [RFC5246]. The "record_size_limit" extension has been assigned a code point of 28. The IANA registry [TLS-REGISTRY] lists this extension as "Recommended" (i.e., "Y") and indicates that it may appear in the ClientHello (CH) or EncryptedExtensions (EE) messages in TLS 1.3 [TLS] β¨
In the same registry, "max_fragment_length" has been changed to not recommended (i.e., "N") π«Ά
8. References π
8.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security
(TLS) Protocol Version 1.2", RFC 5246,
DOI 10.17487/RFC5246, August 2008,
<https://www.rfc-editor.org/info/rfc5246>.
[RFC6066] Eastlake 3rd, D., "Transport Layer Security (TLS)
Extensions: Extension Definitions", RFC 6066,
DOI 10.17487/RFC6066, January 2011,
<https://www.rfc-editor.org/info/rfc6066>.
[RFC7366] Gutmann, P., "Encrypt-then-MAC for Transport Layer
Security (TLS) and Datagram Transport Layer Security
(DTLS)", RFC 7366, DOI 10.17487/RFC7366, September 2014,
<https://www.rfc-editor.org/info/rfc7366>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
<https://www.rfc-editor.org/info/rfc8446>.
8.2. Informative References
[DTLS] Rescorla, E. and N. Modadugu, "Datagram Transport Layer
Security Version 1.2", RFC 6347, DOI 10.17487/RFC6347,
January 2012, <https://www.rfc-editor.org/info/rfc6347>.
[PMTU] McCann, J., Deering, S., Mogul, J., and R. Hinden, Ed.,
"Path MTU Discovery for IP version 6", STD 87, RFC 8201,
DOI 10.17487/RFC8201, July 2017,
<https://www.rfc-editor.org/info/rfc8201>.
[RFC5116] McGrew, D., "An Interface and Algorithms for Authenticated
Encryption", RFC 5116, DOI 10.17487/RFC5116, January 2008,
<https://www.rfc-editor.org/info/rfc5116>.
[RFC7925] Tschofenig, H., Ed. and T. Fossati, "Transport Layer
Security (TLS) / Datagram Transport Layer Security (DTLS)
Profiles for the Internet of Things", RFC 7925,
DOI 10.17487/RFC7925, July 2016,
<https://www.rfc-editor.org/info/rfc7925>.
[TLS-REGISTRY]
Salowey, J. and S. Turner, "IANA Registry Updates for TLS
and DTLS", RFC 8447, DOI 10.17487/RFC8447, August 2018,
<https://www.rfc-editor.org/info/rfc8447>.
Acknowledgments π«Ά
Thomas Pornin and Hannes Tschofenig provided significant input to this document. Alan DeKok identified an issue with the interaction between record size limits and PMTU. Thank you, legends π
Author's Address π
Martin Thomson Mozilla
Email: martin.thomson@gmail.com
π¦ where this page comes from
- ietf: rfc8449 2018-08
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms