RFC Errata


Errata Search

 
Source of RFC  
Summary Table Full Records

Found 6 records.

Status: Reported (6)

RFC 9147, "The Datagram Transport Layer Security (DTLS) Protocol Version 1.3", April 2022

Source of RFC: tls (sec)

Errata ID: 8047
Status: Reported
Type: Technical
Publication Format(s) : TEXT, PDF, HTML

Reported By: David Benjamin
Date Reported: 2024-07-25

Section 8 says:

   As with TLS 1.3, DTLS 1.3 implementations send a KeyUpdate message to
   indicate that they are updating their sending keys.  As with other
   handshake messages with no built-in response, KeyUpdates MUST be
   acknowledged.  In order to facilitate epoch reconstruction
   (Section 4.2.2), implementations MUST NOT send records with the new
   keys or send a new KeyUpdate until the previous KeyUpdate has been
   acknowledged (this avoids having too many epochs in active use).

It should say:

   As with TLS 1.3, DTLS 1.3 implementations send a KeyUpdate message to
   indicate that they are updating their sending keys. As with other
   handshake messages with no built-in response, KeyUpdates MUST be
   acknowledged. Acknowledgements are used to both control
   retransmission and transition to the next epoch. Implementations MUST
   NOT send records with the new keys until the KeyUpdate and all
   preceding messages have been acknowledged. This facilitates epoch
   reconstruction (Section 4.2.2) and avoids too many epochs in active
   use, by ensuring the peer has processed the KeyUpdate and started
   receiving at the new epoch.

   A KeyUpdate message terminates the post-handshake stream in an epoch.
   After sending KeyUpdate in an epoch, implementations MUST NOT send
   any new post-handshake messages in that epoch. Note that, if the
   implementation has sent KeyUpdate but is waiting for an ACK, the next
   epoch is not yet active. In this case, subsequent post-handshake
   messages may not be sent until receiving the ACK.

Notes:

See https://mailarchive.ietf.org/arch/msg/tls/_ku3-YDcroNmG_QKZsYTtqYzC0M/ for discussion. This is option 7 from that discussion, as well as the fix for the other issue described at the top of https://mailarchive.ietf.org/arch/msg/tls/GYX_teYy5CTFiGCBgbQJQwv_Fj4/

Errata ID: 8048
Status: Reported
Type: Technical
Publication Format(s) : TEXT, PDF, HTML

Reported By: David Benjamin
Date Reported: 2024-07-26

Section 5.2 says:

   The first message each side transmits in each association always has
   message_seq = 0.  Whenever a new message is generated, the
   message_seq value is incremented by one.  When a message is
   retransmitted, the old message_seq value is reused, i.e., not
   incremented.  From the perspective of the DTLS record layer, the
   retransmission is a new record.  This record will have a new
   DTLSPlaintext.sequence_number value.

It should say:

   The first message each side transmits in each association always has
   message_seq = 0.  Whenever a new message is generated, the
   message_seq value is incremented by one.  Implementations MUST NOT
   allow message_seq to wrap, but instead MUST establish a new
   association, terminating the old association.  When a message is
   retransmitted, the old message_seq value is reused, i.e., not
   incremented.  From the perspective of the DTLS record layer, the
   retransmission is a new record.  This record will have a new
   DTLSPlaintext.sequence_number value.

Notes:

While pondering what to do about https://mailarchive.ietf.org/arch/msg/tls/6y8wTv8Q_IPM-PCcbCAmDOYg6bM/, I noticed that we don't say anything about message_seq wrapping. Since we don't reset that counter, it's not only possible for it to wrap, but for the peer to induce you to wrap it. This seems warrant some text. I borrowed the "MUST NOT allow ... to wrap, but instead ..." phrasing from Section 4.2.1.

Errata ID: 8050
Status: Reported
Type: Technical
Publication Format(s) : TEXT, PDF, HTML

Reported By: David Benjamin
Date Reported: 2024-07-26

Section 8 says:

   With a 128-bit key as in AES-128, rekeying 2^64 times has a high
   probability of key reuse within a given connection.  Note that even
   if the key repeats, the IV is also independently generated.  In order
   to provide an extra margin of security, sending implementations MUST
   NOT allow the epoch to exceed 2^48-1.  In order to allow this value
   to be changed later, receiving implementations MUST NOT enforce this
   rule.  If a sending implementation receives a KeyUpdate with
   request_update set to "update_requested", it MUST NOT send its own
   KeyUpdate if that would cause it to exceed these limits and SHOULD
   instead ignore the "update_requested" flag.  Note: this overrides the
   requirement in TLS 1.3 to always send a KeyUpdate in response to
   "update_requested".

It should say:

   With a 128-bit key as in AES-128, rekeying 2^64 times has a high
   probability of key reuse within a given connection.  Note that even
   if the key repeats, the IV is also independently generated.  In order
   to provide an extra margin of security, sending implementations MUST
   NOT allow the epoch to exceed 2^48-1.  If a sending implementation
   receives a KeyUpdate with request_update set to "update_requested",
   it MUST NOT send its own KeyUpdate if that would cause it to exceed
   these limits and SHOULD instead ignore the "update_requested" flag.
   Note: this overrides the requirement in TLS 1.3 to always send a
   KeyUpdate in response to "update_requested".

   Exceeding the above limit is not possible with the key update
   mechanisms defined in this document.  After the handshake, each epoch
   change consumes a message_seq value, which is limited to 2^16-1. Both
   sending and receiving implementations MAY instead enforce an epoch
   limit of 2^16-1.  In this case, the implementation MUST check for
   this limit, if reached, terminate the association. In some cases, it
   is otherwise possible for the epoch number to reach 2^16+1.

Notes:

See https://mailarchive.ietf.org/arch/msg/tls/6y8wTv8Q_IPM-PCcbCAmDOYg6bM/ for details. Strictly speaking, as noted in the corrected text, the maximum epoch value does not *quite* fit in 2^16. However, bumping the implementation's size just to accommodate two more epochs seems pointless.

The 2^16-1 value comes from the minimum number of messages in the sending side of a handshake, 2 (ClientHello + Finished as a client). Post-handshake, epochs begin at 3. From there, we can send at most 2^16-2 KeyUpdates, ending at epoch 2^16-2+3 = 2^16+1.

In particular, I believe NSS stores the epoch as 16-bit in DTLS 1.3. We plan to do so in BoringSSL as well. It is a natural choice because epochs are 16-bit in DTLS 1.2. Without this erratum, I believe NSS, and any other implementation making this choice, is non-compliant because the spec says the receiver "MUST NOT enforce this rule".

To that end, I've deleted that sentence because we cannot *actually* change this value. DTLS 1.3 tried, but failed, to enable a larger epoch space. Maybe we can try again in DTLS 1.4, or decide we don't care and properly revert to 16-bit.

Errata ID: 8051
Status: Reported
Type: Technical
Publication Format(s) : TEXT, PDF, HTML

Reported By: David Benjamin
Date Reported: 2024-07-26

Section 6.1 says:

   *  Epoch value (2) is used for messages protected using keys derived
      from [sender]_handshake_traffic_secret.  Messages transmitted
      during the initial handshake, such as EncryptedExtensions,
      CertificateRequest, Certificate, CertificateVerify, and Finished,
      belong to this category.  Note, however, that post-handshake
      messages are protected under the appropriate application traffic
      key and are not included in this category.

It should say:

   *  Epoch value (2) is used for messages protected using keys derived
      from [sender]_handshake_traffic_secret.  Messages transmitted
      during the handshake, such as EncryptedExtensions,
      CertificateRequest, Certificate, CertificateVerify, and Finished,
      belong to this category.  Note, however, that post-handshake
      messages are protected under the appropriate application traffic
      key and are not included in this category.

Notes:

The discussion of "initial handshake" appears to be a remnant of DTLS 1.2, where a single connection may have multiple handshakes via renegotiation. In (D)TLS 1.3, there is only one handshake per connection.

Looking to RFC 8446, the only references to "initial handshake" refer to resumption, talking about the handshake in the initial connection, vs the handshake in resumption connections. This reference is not trying to distinguish initial vs resumption handshakes, so the use of "initial handshake" is a bit confusing. I believe plain "handshake" is the right terminology.

NB: There are two other references to "initial handshake", one in the diagram in Section 8, and another in Section 11. I believe they too should be switched to "handshake".

Errata ID: 8066
Status: Reported
Type: Technical
Publication Format(s) : TEXT, PDF, HTML

Reported By: David Benjamin
Date Reported: 2024-08-06

Section 5 says:

   DTLS implementations do not use the TLS 1.3 "compatibility mode"
   described in Appendix D.4 of [TLS13].  DTLS servers MUST NOT echo the
   "legacy_session_id" value from the client and endpoints MUST NOT send
   ChangeCipherSpec messages.

   With these exceptions, the DTLS message formats, flows, and logic are
   the same as those of TLS 1.3.

It should say:

   DTLS implementations do not use the TLS 1.3 "compatibility mode"
   described in Appendix D.4 of [TLS13].  DTLS endpoints MUST NOT send
   ChangeCipherSpec messages when negotiating DTLS 1.3.

   Additionally, the "legacy_session_id_echo" field of the ServerHello
   message, described in Section 4.1.3 of [TLS13], MUST be empty in DTLS
   1.3.  DTLS 1.3 servers MUST NOT echo the "legacy_session_id" value
   from the ClientHello.  DTLS 1.3 clients MUST abort the handshake with
   an "illegal_parameter" alert if the field is not empty.  This applies
   even if the "legacy_session_id" field of the ClientHello is non-empty
   due to a cached session ID set by a pre-DTLS 1.3 server (see Section
   5.3).

   With these exceptions, the DTLS message formats, flows, and logic are
   the same as those of TLS 1.3.

Notes:

DTLS 1.3's continuity with DTLS 1.2 makes this a little subtle. First, a DTLS-1.3-capable endpoint may well need to send ChangeCipherSpec if it negotiates DTLS 1.3, so add a small clarification here.

More importantly, the changes described here do more than disable the provisions of Appendix D.4. Compatibility mode is only half-negotiated in TLS 1.3, with the ServerHello provisions being unconditional from Section 4.1.3 of RFC 8446:

legacy_session_id_echo: The contents of the client's
legacy_session_id field. Note that this field is echoed even if
the client's value corresponded to a cached pre-TLS 1.3 session
which the server has chosen not to resume. A client which
receives a legacy_session_id_echo field that does not match what
it sent in the ClientHello MUST abort the handshake with an
"illegal_parameter" alert.

In particular, even if we disable the provisions of D.4, a DTLS 1.3 client may still send a non-empty legacy_session_id if it is offering a DTLS 1.2 session. That means matching legacy_session_id and always being empty aren't *quite* the same.

The old text overrode 4.1.3's server text (though without citing the section) but not the client text. Leaving the client text as-is will lead to an interop problem in the 1.2 resumption case above, so let's make that clearer. Best also to cite the section we're overriding.

Errata ID: 8067
Status: Reported
Type: Technical
Publication Format(s) : TEXT, PDF, HTML

Reported By: David Benjamin
Date Reported: 2024-08-08

Section 5.3 says:

   legacy_session_id:  Versions of TLS and DTLS before version 1.3
      supported a "session resumption" feature, which has been merged
      with pre-shared keys (PSK) in version 1.3.  A client which has a
      cached session ID set by a pre-DTLS 1.3 server SHOULD set this
      field to that value.  Otherwise, it MUST be set as a zero-length
      vector (i.e., a zero-valued single byte length field).

It should say:

   legacy_session_id:  Versions of TLS and DTLS before version 1.3
      supported a "session resumption" feature, which has been merged
      with pre-shared keys (PSK) in version 1.3.  A client which has a
      cached session set by a pre-DTLS 1.3 server SHOULD set this
      field according to that session.  Otherwise, it MUST be set as a
      zero-length vector (i.e., a zero-valued single byte length field).

Notes:

The old text is written as if only ID-based DTLS 1.2 sessions (as opposed to ticket-based DTLS 1.2 sessions) require filling in legacy_session_id. This is not quite true. (D)TLS 1.2 ticket sessions (usually!) also fill in legacy_session_id, but to a random value. See the second paragraph of Section 3.4 of RFC 5077. This is needed because a (D)TLS 1.2 server still indicates resumption by echoing the session ID.

I say usually because RFC 5077 unhelpfully makes this behavior optional for the client. The client may instead leave session ID empty, in which case the ServerHello is ambiguous on whether resumption happened! Instead, the client must detect resumption based on whether ServerHello is followed by ChangeCipherSpec (resumption) or more cleartext handshake messages (full handshake). This is a mess for the state machine and, as far as I know, no one does this. (Except for RFC 4851. That was a mistake.) Moreover, this alternative does not work for DTLS, where ChangeCipherSpec is not sequenced relative to handshake messages. Although I cannot find any text that says this. It seems DTLS 1.2 implementors needed to figure that out for themselves.

Given this mess, I've opted to just be vague and say "set this field according to that session". We can't really say "that value" because, in the ticket case, you synthesize one. I'd also rather not wade into the mess that is this behavior being de jure optional, but de facto required, for DTLS 1.2.

This errata also applies to https://www.rfc-editor.org/errata/eid8066. In the replacement text, "cached session ID" should say "cached session".

Report New Errata



Advanced Search