TLS 1.3 Implementation Notes
July 7, 2026 · View on GitHub
1. Cipher Suites
A symmetric cipher suite defines a pair consisting of an AEAD algorithm and a hash algorithm used with HKDF. Cipher suite names follow the naming convention:
CipherSuite TLS_AEAD_HASH = VALUE;
+-----------+------------------------------------------------+
| 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 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} |
+------------------------------+-------------+
The corresponding AEAD algorithms AEAD_AES_128_GCM, AEAD_AES_256_GCM, and AEAD_AES_128_CCM are defined in [RFC5116]. AEAD_CHACHA20_POLY1305 is defined in [RFC8439]. AEAD_AES_128_CCM_8 is defined in [RFC6655]. The corresponding hash algorithms are defined in [SHS].
Although TLS 1.3 uses the same cipher suite space as previous TLS versions, TLS 1.3 cipher suites are defined differently: TLS 1.3 specifies only symmetric cipher suites, and they cannot be used with TLS 1.2. Likewise, cipher suites from TLS 1.2 and earlier cannot be used with TLS 1.3.
New cipher suite values are assigned by IANA.
II. Random Number Generation and Seeding
TLS requires a cryptographically secure pseudorandom number generator (CSPRNG). In most cases, the operating system provides appropriate facilities, such as /dev/urandom, which should be used unless there are other issues (for example, performance). It is recommended to use an existing CSPRNG implementation rather than developing a new one. Many suitable cryptographic libraries are already available under favorable licensing terms. If that is still not satisfactory, [RFC4086] provides guidance on generating random values.
TLS uses random values in public protocol fields, such as (1) the public random values in ClientHello and ServerHello, and (2) generating keying material. With proper use of a CSPRNG, this does not pose a security problem, because it is infeasible to determine the CSPRNG state from its output. However, if the CSPRNG is compromised, an attacker might use public output to determine the CSPRNG’s internal state and thereby predict keying material, as described in [CHECKOWAY]. Implementations can provide additional security against this class of attacks by using separate CSPRNGs to generate public and private values.
III. Certificates and Authentication
Implementations are responsible for validating certificate integrity and generally should support certificate revocation messages. In the absence of specific guidance from an application profile, certificates should always be validated to ensure that they are properly signed by a trusted certificate authority (CA). Trust anchors should be selected and added with great care. Users should be able to view information about certificates and trust anchors.
Applications should also enforce minimum and maximum key-size limits. For example, if a certificate path contains keys or signatures weaker than 2048-bit RSA or 224-bit ECDSA, it is not suitable for applications with relatively high security requirements.
IV. Implementation Pitfalls
Experience has shown that some parts of earlier TLS specifications were not easy to understand and were sources of interoperability and security issues. Many of these aspects have been clarified in this document, but this appendix contains a short list of important items to which implementers should pay particular attention.
TLS protocol issues:
-
Do you correctly handle handshake messages split across multiple TLS records (see Section 5.1)? Do you correctly handle edge cases such as a ClientHello split into several small fragments? Do you fragment handshake messages that exceed the maximum fragment size? In particular, the Certificate and CertificateRequest handshake messages may be large enough to require fragmentation.
-
Do you ignore the TLS record-layer version number in all unencrypted TLS records (see Appendix D)?
-
Have you ensured that, in all possible configurations supporting TLS 1.3 or later, all support for SSL, RC4, EXPORT ciphers, and MD5 (via the "signature_algorithms" extension) has been completely removed, and that attempts to use these obsolete features fail (see Appendix D)?
-
Do you correctly handle TLS extensions in ClientHellos, including unknown extensions?
-
When the Server requests a Client certificate but no suitable certificate is available, do you correctly send an empty Certificate message instead of omitting the entire message (see Section 4.4.2)?
-
When processing a plaintext fragment produced by AEAD-Decrypt and scanning backward from the end for the ContentType, do you avoid scanning past the beginning of the plaintext if the peer sends a malformed plaintext consisting entirely of zeros?
-
Do you correctly ignore unrecognized cipher suites (Section 4.1.2), hello extensions (Section 4.2), named groups (Section 4.2.7), key shares (Section 4.2.8), supported versions (Section 4.2.1), and signature algorithms (Section 4.2.3) in ClientHello?
-
As a Server, do you send a HelloRetryRequest to a Client that supports compatible (EC)DHE groups but could not predict the group in the "key_share" extension? As a Client, do you correctly handle a HelloRetryRequest sent by the Server?
Cryptographic details:
-
What countermeasures do you use to prevent timing attacks [TIMING]?
-
When using Diffie-Hellman key exchange, do you correctly preserve leading zero bytes in the negotiated key (see Section 7.4.1)?
-
Does your TLS Client check whether the Diffie-Hellman parameters sent by the Server are acceptable (see Section 4.2.8.1)?
-
When generating Diffie-Hellman private values, the ECDSA "k" parameter, and other security-critical values, do you use a strong and, most importantly, correctly seeded random number generator (see Appendix C.1)? Implementations are advised to implement "deterministic ECDSA" as specified in [RFC6979].
-
Do you pad Diffie-Hellman public key values and shared keys with zeros to the size of the group (see Section 4.2.8.1 and Section 7.4.1)?
-
Do you verify signatures after generating them to prevent RSA-CRT key leakage FW15?
V. Client Tracking Prevention
Clients should not reuse a ticket across multiple connections. Reusing a ticket allows a passive observer to correlate different connections. A Server that issues tickets should provide at least as many tickets as the number of connections the Client might use; for example, a web browser using HTTP/1.1 RFC7230 might establish six connections to the Server. The Server should issue a new ticket for each connection. This ensures that the Client can always use a new ticket when creating a new connection.
VI. Unauthenticated Operation
Previous versions of TLS provided explicitly unauthenticated cipher suites based on anonymous Diffie-Hellman algorithms. These modes have been deprecated in TLS 1.3. However, it is still possible to negotiate parameters that do not provide verifiable Server authentication in several ways, including:
-
Raw public keys [RFC7250].
-
Using the public key contained in a certificate, but without validating the certificate chain or any of its contents.
Used by themselves, both of these techniques are susceptible to man-in-the-middle attacks, and therefore the practices above are insecure. However, these connections can also be bound to an external authentication mechanism by mechanisms such as out-of-band validation of the Server public key, trust on first use, or channel binding (although channel binding is described in RFC5929, it is not defined for TLS 1.3). If no such mechanism is used, the connection cannot protect against active man-in-the-middle attacks; applications must not use TLS in this way without explicit configuration or a specific application profile.
Reference:
GitHub Repo:Halfrost-Field
Follow: halfrost · GitHub