5.2. <del> In order to support message loss, reordering, and message fragmentation, DTLS modifies the TLS 1.3 handshake header: </del>  The first message each side transmits in each association always has message_seq = 0.  Whenever a new message is generated, the When transmitting the handshake message, the sender divides the message into a series of N contiguous data ranges.  The ranges MUST <del> NOT overlap.  The sender then creates N handshake messages, all with the same message_seq value as the original handshake message.  Each new message is labeled with the fragment_offset (the number of bytes contained in previous fragments) and the fragment_length (the length of this fragment).  The length field in all messages is the same as the length field of the original message.  An unfragmented message is a degenerate case with fragment_offset=0 and fragment_length=length. Each handshake message fragment that is placed into a record MUST be delivered in a single UDP datagram. </del>  When a DTLS implementation receives a handshake message fragment corresponding to the next expected handshake message sequence number, it MUST process it, either by buffering it until it has the entire handshake message or by processing any in-order portions of the <del> message.  DTLS implementations MUST be able to handle overlapping fragment ranges.  This allows senders to retransmit handshake messages with smaller fragment sizes if the PMTU estimate changes. Senders MUST NOT change handshake message bytes upon retransmission. Receivers MAY check that retransmitted bytes are identical and SHOULD abort the handshake with an "illegal_parameter" alert if the value of a byte changes. </del>  Note that as with TLS, multiple handshake messages may be placed in the same DTLS record, provided that there is room and that they are 5.9. <del> CertificateVerify and Finished messages have the same format as in TLS 1.3.  Hash calculations include entire handshake messages, including DTLS-specific fields: message_seq, fragment_offset, and fragment_length.  However, in order to remove sensitivity to handshake message fragmentation, the CertificateVerify and the Finished messages MUST be computed as if each handshake message had been sent as a single fragment following the algorithm described in Section 4.4.3 and Section 4.4.4 of TLS13, respectively. 5.10. </del> Section 7.1 of TLS13 specifies that HKDF-Expand-Label uses a label prefix of "tls13 ".  For DTLS 1.3, that label SHALL be "dtls13". This ensures key separation between DTLS 1.3 and TLS 1.3.  Note that overall label size inside of one hash iteration because "DTLS" is one letter longer than "TLS". <del> 5.11. </del>  Note that Alert messages are not retransmitted at all, even when they occur in the context of a handshake.  However, a DTLS implementation alerts are not reliably transmitted; implementation SHOULD NOT depend on receiving alerts in order to signal errors or connection closure. <del> 5.12. </del>  If a DTLS client-server pair is configured in such a way that repeated connections happen on the same host/port quartet, then it is

This makes the handshake the same as TLS 1.3 (modulo the version numbers, which are conveniently different.
As discussed at the meeting. NAME PTAL.
This also LGTM. Let's do a brief consensus call before merging.

5.2.  <ins> DTLS uses the same Handshake messages as TLS 1.3.  However, prior to transmission they are converted to DTLSHandshake messages, which contain extra data needed to support message loss, reordering, and message fragmentation. In DTLS 1.3, the message transcript is computed over the original TLS 1.3-style Handshake messages without the message_seq, fragment_offset, and fragment_length values.  Note that this is a change from DTLS 1.2 where those values were included in the transcript. </ins> The first message each side transmits in each association always has message_seq = 0.  Whenever a new message is generated, the When transmitting the handshake message, the sender divides the message into a series of N contiguous data ranges.  The ranges MUST  <ins> NOT overlap.  The sender then creates N DTLSHandshake messages, all with the same message_seq value associated with the original handshake message.  Each new message is labeled with the fragment_offset (the number of bytes contained in previous fragments) and the fragment_length (the length of this fragment).  The length field in all messages is the same as the length field of the original message.  An unfragmented message is a degenerate case with fragment_offset=0 and fragment_length=length.  Each handshake message fragment that is placed into a record MUST be delivered in a single UDP datagram. </ins> When a DTLS implementation receives a handshake message fragment corresponding to the next expected handshake message sequence number, it MUST process it, either by buffering it until it has the entire handshake message or by processing any in-order portions of the  <ins> message.  The transcript consists of complete TLS Handshake messages (reassembled as necessary).  Note that this requires removing the message_seq, fragment_offset, and fragment_length fields to create the Handshake structure. DTLS implementations MUST be able to handle overlapping fragment ranges.  This allows senders to retransmit handshake messages with smaller fragment sizes if the PMTU estimate changes.  Senders MUST NOT change handshake message bytes upon retransmission.  Receivers MAY check that retransmitted bytes are identical and SHOULD abort the handshake with an "illegal_parameter" alert if the value of a byte changes. </ins> Note that as with TLS, multiple handshake messages may be placed in the same DTLS record, provided that there is room and that they are 5.9.  Section 7.1 of TLS13 specifies that HKDF-Expand-Label uses a label prefix of "tls13 ".  For DTLS 1.3, that label SHALL be "dtls13". This ensures key separation between DTLS 1.3 and TLS 1.3.  Note that overall label size inside of one hash iteration because "DTLS" is one letter longer than "TLS".  <ins> 5.10. </ins> Note that Alert messages are not retransmitted at all, even when they occur in the context of a handshake.  However, a DTLS implementation alerts are not reliably transmitted; implementation SHOULD NOT depend on receiving alerts in order to signal errors or connection closure.  <ins> 5.11. </ins> If a DTLS client-server pair is configured in such a way that repeated connections happen on the same host/port quartet, then it is


depend on receiving alerts in order to signal errors or connection closure.  5.11. If a DTLS client-server pair is configured in such a way that

It looks like a reasonable statement to make
In RFC6083bis (DTLS/SCTP) we are discussing when to terminate DTLS connections. RFC8446 says: "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." As far as I can see, the DTLS 1.3 draft does not say anything about closure alerts, which according to my understanding means that the above RFC 8446 text apply to DTLS 1.3 as well. However, this behaviour does not seem to make much sense for DTLS 1.3. As DTLS records can be received out of order, shouldn't the DTLS behavior be: "Any data sent after a closure alert MUST be ignored."
I do understand that ignoring data is a valid option for DTLS/UDP, which provides an unreliable server. However, when providing a reliable service like DTLS/SCTP, I don't think this is an option. Shouldn't you fail the connection under that condition?
NAME so we found this while working on clarifying the shutdown procedure. So the whole point is to ensure that data that has been committed to the DTLS/SCTP layer will be delivered in a controlled shutdown. We are targeting to have DTLS/SCTP behave like SCTP in regards to shutdown when the upper layer protocol request shutdown. For the improved procedure in DTLS/SCTP see URL and PR URL The point of needing this is so that when a peer has requested shutdown, and the DTLS/SCTP has learnt of that by receiving an DTLS close_notify, all data that was sent prior to that must be possible to process and not prevented by this TLS formulation. The DTLS connection state removal can in this case be triggered by the SCTP association shutdown completion or an SCTP abort. We want to be able to use the SCTP shutdown pending mechanism to catch any reordered data requested to be sent prior to DTLS close notify. This avoids new complex SCTP API to learn if the stack has ACKed all data prior to the transmission of the DTLS close notify. So if the SCTP stack fails to deliver the reordered data in time fashion then we will end up in an SCTP abort that the ULP can be informed of.
To try to generalize the behavior I expect to be possible with DTLS that is different from TLS. DTLS records may arrive after close notify due to reordering. These needs to be processed assuming that their sequence number indicate they being earlier than close notify. DTLS connection is not automatically terminated and keys discarded by having sent and received close notify. Instead either default timers or additional mechanism indicate that DTLS connection can be safely terminated and its stated deleted. For example for DTLS/SCTP a SCTP shutdown or SCTP Abort is such an additional indicator that state can be removed. Application termination is also such an additional indicator.
DTLS/SCTP behave like SCTP in regards to shutdown when the upper layer protocol request shutdown. For the improved procedure in DTLS/SCTP see and PR You could do the normal dance of delay the sending of the closenotify until all prior data has been acked at the SCTP level on the sender side and on the receiver side ensure that you process all data being buffered before processing the closenotify. Of course, you can rely on the SCTP SHUTDOWN procedure, but doesn't this only work if you have a one to one relation ship between the DTLS connection and the SCTP association? If I remember it correctly, you suggested to multiplex several DTLS connections on a single SCTP association. Maybe I misunderstood this.
So I want to make clear that this issue is a general one even if we realized it due to DTLS/SCTP work. TLS has an assumption of single stream in order delivery which doesn't hold for DTLS. Thus, DTLS spec needs to change that normative statement to something that makes sense for DTLS where out of order delivery of DTLS records has to be assumed to occur. Thus, I support John's proposal for reformulation because it makes sense and can be judged based on sequence numbers in the DTLS records. In relply to NAME "You could do the normal dance of delay the sending of the closenotify until all prior data has been acked at the SCTP level on the sender side and on the receiver side ensure that you process all data being buffered before processing the closenotify." Yes, but as you know the documented API to SCTP does not support determining when each user message has been non-renegable ACKed by the peer. Thus, API extensions are needed, or we for this use case to have a shutdown procedure that mimics STCP's behavior at shutdown with minimal extra delay, i.e. waiting for ACKs. So that is what we are targeting if that is impossible we will find another solution including requiring API extensions. "Of course, you can rely on the SCTP SHUTDOWN procedure, but doesn't this only work if you have a one to one relation ship between the DTLS connection and the SCTP association? If I remember it correctly, you suggested to multiplex several DTLS connections on a single SCTP association. Maybe I misunderstood this." We don't see that as an issue. As the DTLS/SCTP implementation that owns the DTLS sessions in cases there are two DTLS Connections open, the shutdown on SCTP level happens only when both of the DTLS connections have entered the necessary. But please review the PR for the DTLS/SCTP details: URL
You can use the sender dry event, it was specified for that purpose. So you will keep all DTLS connections alive until you shutdown the transport?
Just wondering... On the sender side you already have reference counting for keys to implement in the . So wouldn't it be a simple extension to add a way?
Regarding the suggested text change: How does the receiver now that a message received was sent after the close_notify was sent?
To my understanding that would be based on epoch + sequence number of the DTLS record. So any record with a lower extended sequence number than the close_notify alert message should be processed, with a higher discarded.
I agree that this is the semantics we want from the alert. Do we need to say something that specifically countermands the directive from RFC 8446 that essentially uses a time-based criterion in addition to this, though?Sufficient. I guess it has more impact on the implementations as you need to separate the received close and the actual final closing that discard the keys and state allowing to process the data.

depend on receiving alerts in order to signal errors or connection closure. <ins> Any data received with an epoch/sequence number pair after that of a valid received closure alert MUST be ignored.  Note: this is a change from TLS 1.3 which depends on the order of receipt rather than the epoch and sequence number. </ins> 5.11. If a DTLS client-server pair is configured in such a way that


covered by the cookie exchange during the handshake.  DTLS implementations MUST NOT update the address they send to in response to packets from a different address unless they first perform some <del> reachability test; no such test is defined in this specification. Even with such a test, an active on-path adversary can also black- hole traffic or create a reflection attack against third parties because a DTLS peer has no means to distinguish a genuine address update event (for example, due to a NAT rebinding) from one that is malicious.  This attack is of concern when there is a large asymmetry of request/response message sizes. </del>  With the exception of order protection and non-replayability, the security guarantees for DTLS 1.3 are the same as TLS 1.3.  While TLS

The DTLS 1.2 Connection ID draft (soon-to-be-RFC9146) section on "peer address update" and the text in DTLS 1.3 seems quite different. URL The "unless they first perform some reachability test" seems preferable to the soft text in soon-to-be-RFC9146, but DTLS 1.3 seems to be missing the DTLS 1.2 requirement on "The received datagram is "newer"". Feels spontanously like DTLS 1.2 and 1.3 should have similar requirements/guidance on "peer address update". FYI, I started writing some analysis of Peer Address Update in a draft that I intend to submit to T2TRG URL
Would be good to warn implementations that clients must not update the permanent server address based on the “Peer Address Update” mechanism. Using IP addresses instead of DNS names is not uncommon in e.g., IoT, DNS over DTLS (RFC 8094), and 3GPP DTLS interfaces. An client updating the permanent server address based on an MITM attack could be unable to recover.Would be good with a sentence or two on the problems changing the IP address of a gateway multiplexing a lot of DTLS connections with Connection ID. All the client and servers would have to send at least one record before the old IP address can be deactivated. Might take some time in a IoT deployment.
I tend to think we should at most provide warnings about how it's dangerous. NAME would you be willing to provide a quick PR?
In the interest of being done I opted for basically punting it to a future spec.
URL

covered by the cookie exchange during the handshake.  DTLS implementations MUST NOT update the address they send to in response to packets from a different address unless they first perform some  <ins> reachability test; no such test is defined in this specification and a future specification would need to specify a complete procedure for how and when to update addresses.  Even with such a test, an active on-path adversary can also black-hole traffic or create a reflection attack against third parties because a DTLS peer has no means to distinguish a genuine address update event (for example, due to a NAT rebinding) from one that is malicious.  This attack is of concern when there is a large asymmetry of request/response message sizes. </ins> With the exception of order protection and non-replayability, the security guarantees for DTLS 1.3 are the same as TLS 1.3.  While TLS


The DTLSCiphertext structure omits the superfluous version number field <del> DTLS adds an explicit epoch and sequence number in the record </del>  header.  This sequence number allows the recipient to correctly verify the DTLS MAC. 4.4.1. <del> DTLS records contain a sequence number to provide replay protection. Sequence number verification SHOULD be performed using the following sliding window procedure, borrowed from Section 3.4.3 of RFC4303. </del>  <del> The receiver packet counter for this session MUST be initialized to zero when the session is established.  For each received record, the </del>  receiver MUST verify that the record contains a sequence number that does not duplicate the sequence number of any other record received <del> during the life of this session.  This SHOULD be the first check </del>  applied to a packet after it has been matched to a session, to speed <del> rejection of duplicate records. </del>  Duplicates are rejected through the use of a sliding receive window. (How the window is implemented is a local matter, but the following size.) The "right" edge of the window represents the highest validated <del> sequence number value received on this session.  Records that contain </del>  sequence numbers lower than the "left" edge of the window are rejected.  Packets falling within the window are checked against a list of received packets within the window.  An efficient means for

I do understand that the text is consistent with the one in , but I think that it could benefit from some rework.

The DTLSCiphertext structure omits the superfluous version number field  <ins> DTLS adds an explicit epoch and sequence numbers in the record </ins> header.  This sequence number allows the recipient to correctly verify the DTLS MAC. 4.4.1.  <ins> Each DTLS record contains a sequence number to provide replay protection.  Sequence number verification SHOULD be performed using the following sliding window procedure, borrowed from Section 3.4.3 of RFC4303. </ins>  <ins> The received packet counter for a session MUST be initialized to zero when that session is established.  For each received record, the </ins> receiver MUST verify that the record contains a sequence number that does not duplicate the sequence number of any other record received  <ins> during the lifetime of the session.  This SHOULD be the first check </ins> applied to a packet after it has been matched to a session, to speed  <ins> up the rejection of duplicate records. </ins> Duplicates are rejected through the use of a sliding receive window. (How the window is implemented is a local matter, but the following size.) The "right" edge of the window represents the highest validated  <ins> sequence number value received on the session.  Records that contain </ins> sequence numbers lower than the "left" edge of the window are rejected.  Packets falling within the window are checked against a list of received packets within the window.  An efficient means for


If the HelloRetryRequest message is used, the initial ClientHello and the HelloRetryRequest are included in the calculation of the <del> Transcript-Hash.  The computation of the message hash for the </del>  HelloRetryRequest is done according to the description in Section 4.4.1 of I-D.ietf-tls-tls13.

"Transcript-Hash" is the name of the function. I belive it would be more appropriate to use the "transcript hash" term here.

If the HelloRetryRequest message is used, the initial ClientHello and the HelloRetryRequest are included in the calculation of the  <ins> transcript hash.  The computation of the message hash for the </ins> HelloRetryRequest is done according to the description in Section 4.4.1 of I-D.ietf-tls-tls13.


epoch and sequence number fields in the DTLSCiphertext structure have been reduced. <del> The DTLSCiphertext structure is a variable length header. </del>  Note that the DTLS 1.3 record layer is different from the DTLS 1.2 record layer. Identical to the encrypted_record field in a TLS 1.3 record. <del> 14 bit sequence number field. </del>  Identical to the length field in a TLS 1.3 record. (though they MUST be ACKed as usual). Endpoints MUST NOT send either of these messages if they did not <del> negotiate a connection ID. 10. Application data messages are carried by the record layer and are fragmented and encrypted based on the current connection state.  The messages are treated as transparent data to the record layer. </del>  <del> 11. </del>  Below is an example exchange for DTLS 1.3 using a single connection id in each direction. Note: The connection_id extension is defined in I-D.ietf-tls-dtls- connection-id, which is used in ClientHello and ServerHello messages. <del> 12. </del>  Security issues are discussed primarily in I-D.ietf-tls-tls13. DTLS client, such as the client certificate, less information is available to an on-path adversary. <del> 13. </del>  Since TLS 1.3 introduces a large number of changes to TLS 1.2, the list of changes from DTLS 1.2 to DTLS 1.3 is equally large.  For this Sequence numbers are encrypted. <del> 14. </del>  IANA is requested to allocate a new value in the "TLS ContentType" registry for the ACK message, defined in ack-msg, with content type

This pull request aims to address the open issues regarding sequence number encryption. The approach chosen follows the design used in QUIC.

epoch and sequence number fields in the DTLSCiphertext structure have been reduced.  <ins> The DTLSCiphertext structure has a variable length header. </ins> Note that the DTLS 1.3 record layer is different from the DTLS 1.2 record layer. Identical to the encrypted_record field in a TLS 1.3 record.  <ins> The DTLSCiphertext header is tightly bit-packed, as shown below: The low order two bits of the epoch. The low order 14 bits of the record sequence number. </ins> Identical to the length field in a TLS 1.3 record. (though they MUST be ACKed as usual). Endpoints MUST NOT send either of these messages if they did not  <ins> negotiate a connection ID.  If an implementation receives these messages when connection IDs were not negotiated, it MUST abort the connection with an unexpected_message alert. </ins>  <ins> 9.1. </ins> Below is an example exchange for DTLS 1.3 using a single connection id in each direction. Note: The connection_id extension is defined in I-D.ietf-tls-dtls- connection-id, which is used in ClientHello and ServerHello messages.  <ins> 10. Application data messages are carried by the record layer and are fragmented and encrypted based on the current connection state.  The messages are treated as transparent data to the record layer. 11. </ins> Security issues are discussed primarily in I-D.ietf-tls-tls13. DTLS client, such as the client certificate, less information is available to an on-path adversary.  <ins> 12. </ins> Since TLS 1.3 introduces a large number of changes to TLS 1.2, the list of changes from DTLS 1.2 to DTLS 1.3 is equally large.  For this Sequence numbers are encrypted.  <ins> 13. </ins> IANA is requested to allocate a new value in the "TLS ContentType" registry for the ACK message, defined in ack-msg, with content type


The DTLSCiphertext header is tightly bit-packed, as shown below:  The low order two bits of the epoch. <del> The low order 14 bits of the record sequence number. </del>  <del> Identical to the length field in a TLS 1.3 record. </del>  Variable length connection ID.  The connection ID concept is described in I-D.ietf-tls-dtls-connection-id.  An example can be found in connection-id-example.  As with previous versions of DTLS, multiple DTLSPlaintext and DTLSCiphertext records can be included in the same underlying transport datagram.

This is a bikeshed colour, but I think a good one. In the 5 bits that we have, we can pack two epoch bits (we only need one in practice, but let's leave that aside for the moment), and a bit each to signal presence of connection ID and length. That leaves one spare bit. I'm suggesting that we spend this on signaling the difference between an 8-bit and 16-bit sequence number. 16 bits is far more comfortable than 14, and 8 is probably enough for many use cases (saving a byte). That is, unless you were saving this for a spin bit and VEC. This doesn't do anything about , but I think that we can save a bit from the epoch. More on that later.
If epoch can be one bit - the you provided is quite convincing - then this proposal could coexist with .
Instead of , make the fixed prefix by picking one of the three reserved bits: This way the implicit Content Type allocation is halved to [48, 63] and we get back 16 codepoints.
I think that we can do better. I've just opened . That uses all the bits in that first octet, which would seem to be a regression, but there are two ways in which we could get another bit back. The first option is to drop the S-bit I propose and have sequence numbers be 16 bits always. I'd be sad that we lost the small optimization, but that isn't the end of the world. Perhaps a better option is to drop the second epoch bit. This seems like a bad idea because you potentially have multiple epochs inbound to a server during a 0-RTT handshake. In that case, you have to distinguish between ClientHello (001 or 0011 would work for that), 0-RTT (epoch 1), Handshake (epoch 2), and the ultimate Application Data (epoch 3). If you only have one bit of epoch, then 1 and 3 are indistinguishable. However, if you look at the way we handle 0-RTT in stacks, it might be OK to allow those late-arriving 0-RTT records to be dropped. For instance, NSS processes 0-RTT and handshake linearly. We don't read the Finished until we have the EndOfEarlyData, and as soon as we process the EOED, we stop accepting new 0-RTT. Part of the reason for this is that once we report handshake success, we don't provide any other signal to an application about the data it receives. So, for NSS, dropping 0-RTT when 1-RTT is available wouldn't change anything for us. The final option is to not worry about this. The codepoints are there to use. The number of public bits we have is small, and we don't need to signal content type in the clear any more. As I suggested in discussing tlswg/dtls-conn-id, perhaps the right answer is to backport the TLS 1.3 record format to DTLS 1.2 and use only one codepoint.
With regards to 1. Losing the ability to signal 8- v 16-bits sequence would be a bit of a shame, especially in constrained networks (NAME opinions?), but I agree with you it's not the end of the world and I'd be more than happy to immolate it to get one of the reserved bits back. In fact, one bit is sufficient to build a whole if we'd need to -- for spin bit, VEC, etc. I value that much more than a tiny optimisation. WRT 2. Your argument in favour of dropping the second epoch bit is pretty convincing, so personally I'd be OK with one-bit epoch. So, I guess we could have something like: and 16 bits sequence, always?
You haven't made a convincing case for an extension mechanism to my mind. And given the choice between having two sequence number lengths and extensions, I'd take the former every time.
The appalling amount of cycles we have been spending on devising how to do CID signalling in 1.2 is a very good argument in favour of having some kind of extension built in in 1.3. Next time we realise we missed something we won't have to struggle like Houdini. To me this is far more important than a small optimisation of undetermined benefit.
I don't think this is the right answer. Given that as soon as we can recognize the CID, we can make extensions without changing the header here, I agree with MTabout filling the bits.

The DTLSCiphertext header is tightly bit-packed, as shown below: <ins> The C bit is set if the connection ID is present. The L bit is set if the length is present. </ins> The low order two bits of the epoch.  <ins> The size of the sequence number.  0 means an 8-bit sequence number, 1 means 16-bit. </ins>  <ins> The low order 8 or 16 bits of the record sequence number.  This value is 16 bits if the S bit is set to 1, and 8 bits if the S bit is 0. </ins> Variable length connection ID.  The connection ID concept is described in I-D.ietf-tls-dtls-connection-id.  An example can be found in connection-id-example. <ins> Identical to the length field in a TLS 1.3 record. </ins> As with previous versions of DTLS, multiple DTLSPlaintext and DTLSCiphertext records can be included in the same underlying transport datagram.


transport like TCP that performs return-routability checks as part of the connection establishment.  With these exceptions, the DTLS message formats, flows, and logic are <del> the same as those of TLS 1.3.  DTLS implementations SHOULD not use the TLS 1.3 "compatibility mode" described in I-D.ietf-tls-tls13, Section D.4 and DTLS servers SHOULD ignore the "session_id" value generated by the client rather than sending ChangeCipherSpec messages.  Implementations MUST still ignore ChangeCipherSpec messages received during the handshake and at all other times SHOULD treat them as if they had failed to deprotect. </del>  5.1.

I split and reordered the paragragh to maintain the integrity of the "aside from these exceptions, this is TLS 1.3".

transport like TCP that performs return-routability checks as part of the connection establishment. <ins> DTLS implementations do not use the TLS 1.3 "compatibility mode" described in I-D.ietf-tls-tls13, Section D.4.  DTLS servers MUST NOT echo the "session_id" value from the client and endpoints MUST NOT send ChangeCipherSpec messages.  Note however that implementations MUST ignore ChangeCipherSpec messages received in unprotected records. </ins> With these exceptions, the DTLS message formats, flows, and logic are  <ins> the same as those of TLS 1.3. </ins> 5.1.


[sender]_application_traffic_secret for message protection, Implementations MAY include the length field at their discretion.  4.1. Implementations can distinguish the two header formats by examining

As I understand, the intent with the record header in AD business was so that DTLS 1.3 would inherit putting the entire header into the AD. However, TLS 1.3 defines the AD as: and DTLS 1.3 defines encryptedrecord as: If one takes the first half of the clause, it works out, but "record header" isn't defined formally. If one takes the second half, it suggests that is not in the AD and it's not clear how 's AD is defined at all. Probably worth clarifying this.

[sender]_application_traffic_secret for message protection, Implementations MAY include the length field at their discretion. <ins> The entire header value shown above is used as it appears on the wire as the additional data value for the AEAD function. </ins> 4.1. Implementations can distinguish the two header formats by examining


5.5.  DTLS messages are grouped into a series of message flights, according to the diagrams below. Note: The application data sent by the client is not included in the timeout and retransmission calculation. <del> 5.6. </del>  <del> 5.6.1. </del>  DTLS uses a simple timeout and retransmission scheme with the state machine shown in dtls-timeout-state-machine.  Because DTLS clients evidence of reordering or packet loss and retransmit their final flight immediately, shortcutting the retransmission timer. <del> 5.6.2. </del>  Though timer values are the choice of the implementation, mishandling of the timer can lead to serious congestion problems; for example, if timer to the initial value.  One situation where this might occur is when a rehandshake is used after substantial data transfer. <del> 5.7. </del>  CertificateVerify and Finished messages have the same format as in TLS 1.3.  Hash calculations include entire handshake messages, been sent as a single fragment following the algorithm described in Section 4.4.3 and Section 4.4.4 of TLS13, respectively. <del> 5.8. </del>  Note that Alert messages are not retransmitted at all, even when they occur in the context of a handshake.  However, a DTLS implementation a peer is persistently sending bad messages and terminate the local connection state after such misbehavior is detected. <del> 5.9. </del>  If a DTLS client-server pair is configured in such a way that repeated connections happen on the same host/port quartet, then it is

NAME
s'OK wi' me. The other thing to consider mentioning is that record shadowing (key compromise at epoch N allowing the attacker to send records that cause records at epoch >N to be dropped) isn't a concern because dropping records in DTLS is trivial.
NAME thoughts?

5.5. <ins> The DTLS 1.3 handshake has one important difference from the TLS 1.3 handshake: the EndOfEarlyData message is omitted both from the wire and the handshake transcript: because DTLS records have epochs, EndOfEarlyData is not necessary to determine when the early data is complete, and because DTLS is lossy, attackers can trivially mount the deletion attacks that EndOfEarlyData prevents in TLS.  Servers SHOULD aggressively age out the epoch 1 keys upon receiving the first epoch 1 record and SHOULD NOT accept epoch 1 data after the first epoch 3 record is received. 5.6. </ins> DTLS messages are grouped into a series of message flights, according to the diagrams below. Note: The application data sent by the client is not included in the timeout and retransmission calculation.  <ins> 5.7. </ins>  <ins> 5.7.1. </ins> DTLS uses a simple timeout and retransmission scheme with the state machine shown in dtls-timeout-state-machine.  Because DTLS clients evidence of reordering or packet loss and retransmit their final flight immediately, shortcutting the retransmission timer.  <ins> 5.7.2. </ins> Though timer values are the choice of the implementation, mishandling of the timer can lead to serious congestion problems; for example, if timer to the initial value.  One situation where this might occur is when a rehandshake is used after substantial data transfer.  <ins> 5.8. </ins> CertificateVerify and Finished messages have the same format as in TLS 1.3.  Hash calculations include entire handshake messages, been sent as a single fragment following the algorithm described in Section 4.4.3 and Section 4.4.4 of TLS13, respectively.  <ins> 5.9. </ins> Note that Alert messages are not retransmitted at all, even when they occur in the context of a handshake.  However, a DTLS implementation a peer is persistently sending bad messages and terminate the local connection state after such misbehavior is detected.  <ins> 5.10. </ins> If a DTLS client-server pair is configured in such a way that repeated connections happen on the same host/port quartet, then it is


%%% Connection ID Management enum { cid_immediate(0), cid_spare(1), (255) } ConnectionIdUsage; <del> Indicates the CID which the sender wishes the peer to use. </del>  <del> Indicates whether the new CID should be used immediately or is a spare.  If usage is set to "cid_immediate", then the new CID MUST be used immediately for all future records.  If it is set to "cid_spare", then either CID MAY be used. </del>  If the client and server have negotiated the "connection_id" extension, either side can request a new CID using the RequestConnectionId message. <del> %%% Connection ID Management struct { } RequestConnectionId; </del>  Endpoints SHOULD respond to RequestConnectionId by sending a <del> NewConnectionId with usage "cid_spare" as soon as possible.  Note that an endpoint MAY ignore requests, which it considers excessive (though they MUST be ACKed as usual). </del>  Endpoints MUST NOT send either of these messages if they did not negotiate a connection ID.  If an implementation receives these

messages, but also forbid having multiple ones outstanding. NAME NAME
A client that migrates to a new point of network attachment probably wants to use a new connection ID. But that attempt will result in linkability if the server doesn't also change. How do we manage that? One approach is to use the cid_immediate instruction. But clients need to be careful to include that instruction in every packet they send lest the server miss it. QUIC takes a different approach, which is to number all connection IDs combined with a ratchet. If connection ID N is used by one endpoint, its peer has to use connection ID N or greater on that same network path.
The QUIC DT on this subject has come up with a different design: you use a new connection ID when you observe a path change endpoints need to provide their peers enough connection IDs that they shouldn't run out when an endpoint stops using a connection ID, there is a new "retire connection ID" message that is used to signal that it is no longer needed endpoints that receive this "retire connection ID" are expected to replenish the supply of connection IDs at their peer
Point (1) is sort of implicit in the text, and I agree we should add it. Points (2)-(4) are about ensuring that the other side has enough CIDs. In QUIC, this is the server's job and there's no real way for the client to say that it doesn't have enough CIDs or tell the server how many. It can just say that it is done using some set of CIDs and this tells the server to send more, but the server has no idea how many. By contrast, the DTLS design is for the client to tell the server when it wants more CIDs and the server gets to retire them. ISTM that this is a more flexible design in that the server can change CIDs whenever it wants (e.g., for rekeying of the CID encryption key). IIRC much of the motivation for the design with QUIC was not to have to interlock with the ACK, and in this respect the situation here is the same as with the KeyUpdate, which is that the QUIC design has the advantage that it doesn't need to interlock with the ACK to know when things have change. But that doesn't apply here for the same reason as with . So I think my proposed resolution is just to add that you should change CIDs whenever you change paths and should request enough CIDs that you have a hot spare. I could imagine a way for the server to say what specific keys it wants to invalidate, but I'm not sure that's necessary. I do think we should enhance RequestConnectionId to have a count.
NAME
NAME
(Just noting my earlier thoughts here so they're saved somewhere) Overall, only concern is around the rate at which you can send additional connection IDs to the peer vs. the rate at which you retire them. My understanding is that they are all retired at once, but need to be provided independently. It seems like there could be situations, especially for a sender that needs to migrate rapidly (say away from and then back to some specific interface), where this leaves the sender without a CID to switch to. Allowing multiple CIDs in the messages as in looks like it generally resolves this. Also noting that infinite looping in response to peer changes is covered by the sequence number.
This mirrors an open topic of discussion in QUIC, and I assume that we'll want to take the lessons learned there and probably copy whatever the conclusion is. The problem is that the current design has a server remember all connection IDs that it ever minted. Over time, that might be infeasible for a server. It might be good to limit the number that are in use.
This isn't correct. In DTLS, as opposed to QUIC, new connection IDs may be marked as , in which case the peer is required to stop using any old CIDs immediately. The document could probably use some more text here, but the basic idea is that once a cid_immediate message has been ACKed, you know that any old CIDs are no longer valid.
This message appears to be lacking a codepoint. Also, is this a Handshake message? If so, does it enter the transcript (I assume not).

%%% Connection ID Management enum { cid_immediate(0), cid_spare(1), (255) } ConnectionIdUsage;  <ins> Indicates the set of CIDs which the sender wishes the peer to use. </ins>  <ins> Indicates whether the new CIDs should be used immediately or are spare.  If usage is set to "cid_immediate", then one of the new CID MUST be used immediately for all future records.  If it is set to "cid_spare", then either existing or new CID MAY be used. Endpoints SHOULD use receiver-provided CIDs in the order they were provided.  Endpoints MUST NOT have more than one NewConnectionId message outstanding. </ins> If the client and server have negotiated the "connection_id" extension, either side can request a new CID using the RequestConnectionId message.  <ins> %%% Connection ID Management struct { uint8 num_cids; } RequestConnectionId; The number of CIDs desired. </ins> Endpoints SHOULD respond to RequestConnectionId by sending a  <ins> NewConnectionId with usage "cid_spare" containing num_cid CIDs soon as possible.  Endpoints MUST NOT send a RequestConnectionId message when an existing request is still unfulfilled; this implies that endpoints needs to request new CIDs well in advance.  An endpoint MAY ignore requests, which it considers excessive (though they MUST be ACKed as usual). </ins> Endpoints MUST NOT send either of these messages if they did not negotiate a connection ID.  If an implementation receives these


The DTLS 1.3 protocol is intentionally based on the Transport Layer Security (TLS) 1.3 protocol and provides equivalent security <del> guarantees.  Datagram semantics of the underlying transport are preserved by the DTLS protocol. </del>  1. not a threat in their environment.  Clients MUST be prepared to do a cookie exchange with every handshake.  Unlike TLS implementations, DTLS implementations SHOULD NOT respond to invalid records by terminating the connection.

Suggested pull request related to issue
The Abstract states that: "The DTLS 1.3 protocol is intentionally based on the Transport Layer Security (TLS) 1.3 protocol and provides equivalent security guarantees." This is not true when it comes to Order protection/non-replayability which is states as a guarantee in Appendix E.2 of RFC 8446. DTLS does not provide order protection and may not provide replay protection. I suggested this statement "equivalent security guarantees" is deleted (or rewritten) in the abstract and that some short text describing this is added to the Security Considerations.
Fixed.

The DTLS 1.3 protocol is intentionally based on the Transport Layer Security (TLS) 1.3 protocol and provides equivalent security  <ins> guarantees with the exception of order protection/non-replayability. Datagram semantics of the underlying transport are preserved by the DTLS protocol. </ins> 1. not a threat in their environment.  Clients MUST be prepared to do a cookie exchange with every handshake. <ins> With the exception of order protection and non-replayability, the security guarantees for DTLS 1.3 are the same as TLS 1.3.  While TLS always provides order protection and non-replayability, DTLS does not provide order protection and may not provide replay protection. </ins> Unlike TLS implementations, DTLS implementations SHOULD NOT respond to invalid records by terminating the connection.


If the first byte is alert(21), handshake(22), or ack(proposed, 25), the record MUST be interpreted as a DTLSPlaintext record. <del> If the first byte is any other other value, then receivers MUST check to see if the leading bits of the first byte are 001.  If so, the implementation MUST process the record as DTLSCiphertext; the true content type will be inside the protected portion. </del>  Otherwise, the record MUST be rejected as if it had failed deprotection, as described in handling-invalid-records. of the Mask with the sequence number.  Decryption is accomplished by the same process. <del> In some (rare) cases the ciphertext may be less than 16 bytes.  This cannot happen with most of the DTLS AEAD algorithms because the authentication tag itself is 16 bytes, however some algorithms such as TLS_AES_128_CCM_8_SHA256 have a shorter authentication tag, and in combination with a short plaintext, the result might be less than 16 bytes.  In this case, implementations MUST pad the plaintext out (using the conventional record padding mechanism) in order to make a suitable-length ciphertext. </del>  Note that sequence number encryption is only applied to the DTLSCiphertext structure and not to the DTLSPlaintext structure, An attacker can use the server as an amplifier by sending connection initiation messages with a forged source of the victim. The server then sends its response to the victim machine, thus <del> flooding it.  Depending on the selected ciphersuite this response </del>  message can be quite large, as it is the case for a Certificate message. subsequently into a ClientHello message.  DTLS 1.2 on the other hand used a separate message, namely the HelloVerifyRequest, to pass a cookie to the client and did not utilize the extension mechanism. <del> For backwards compatibility reason the cookie field in the </del>  ClientHello is present in DTLS 1.3 but is ignored by a DTLS 1.3 compliant server implementation. the deletion attacks that EndOfEarlyData prevents in TLS.  Servers SHOULD aggressively age out the epoch 1 keys upon receiving the first epoch 2 record and SHOULD NOT accept epoch 1 data after the first <del> epoch 3 record is received. </del>  5.6. the SENDING state, where it retransmits the flight, resets the retransmit timer, and returns to the WAITING state. <del> The implementation reads a ACK from the peer: upon receiving an </del>  ACK for a partial flight (as mentioned in sending-acks), the implementation transitions to the SENDING state, where it retransmits the unacked portion of the flight, resets the value at each retransmission, up to no less than the RFC 6298 maximum of 60 seconds.  Application specific profiles, such as those used for the Internet of Things environment, may recommend longer timer <del> values.  Note that a 100 msec timer is recommend rather than the </del>  3-second RFC 6298 default in order to improve latency for time- sensitive applications.  Because DTLS only uses retransmission for handshake and not dataflow, the effect on congestion should be ServerHello, and HelloRetryRequest. epoch value (1) is used for messages protected using keys derived <del> from client_early_traffic_secret.  This includes early data sent by the client and the EndOfEarlyData message. </del>  epoch value (2) is used for messages protected using keys derived from [sender]_handshake_traffic_secret.  Messages transmitted not included in this category. epoch value (3) is used for payloads protected using keys derived <del> from the initial traffic_secret_0.  This may include handshake messages, such as post-handshake messages (e.g., a NewSessionTicket message). </del>  epoch value (4 to 2^16-1) is used for payloads protected using <del> keys from the traffic_secret_N (N>0). </del>  Using these reserved epoch values a receiver knows what cipher state has been used to encrypt and integrity protect a message.

I read through the draft and amassed a number of comments. This PR resolves the easy stuff. I'll send an email to the WG list with the more interesting ones shortly. Grammar fixes.The text describing sequence number encryption doesn't say how the receiver handles short ciphertexts. It's also phrased oddly. It says "In some (rare) cases the ciphertext may be less than 16 bytes", but the whole point of the text is to ensure it cannot be less than 16 bytes. Reword it. Whether there's a Certificate message is no longer a function of the ciphersuite, but of parameters in general. (With resumption that was already true.) The bits talking about epoch 1-3 so far before the definitions of those epochs should link to the section. Remove some remnants of EndOfEarlyData. They're still in the definition of the Handshake struct. I wasn't sure how to handle that since it was in the HandshakeType enum and we probably shouldn't call it RESERVED when it exists in TLS? Spell out [sender]applicationtrafficsecret since trafficsecret isn't defined.
This looks good to me.
These changes look good to me! NAME can you please have a look?

If the first byte is alert(21), handshake(22), or ack(proposed, 25), the record MUST be interpreted as a DTLSPlaintext record.  <ins> If the first byte is any other value, then receivers MUST check to see if the leading bits of the first byte are 001.  If so, the implementation MUST process the record as DTLSCiphertext; the true content type will be inside the protected portion. </ins> Otherwise, the record MUST be rejected as if it had failed deprotection, as described in handling-invalid-records. of the Mask with the sequence number.  Decryption is accomplished by the same process.  <ins> This procedure requires the ciphertext length be at least 16 bytes. Receivers MUST reject shorter records as if they had failed deprotection, as described in handling-invalid-records.  Senders MUST pad short plaintexts out (using the conventional record padding mechanism) in order to make a suitable-length ciphertext.  Note most of the DTLS AEAD algorithms have a 16-byte authentication tag and need no padding.  However, some algorithms such as TLS_AES_128_CCM_8_SHA256 have a shorter authentication tag and may require padding for short inputs. </ins> Note that sequence number encryption is only applied to the DTLSCiphertext structure and not to the DTLSPlaintext structure, An attacker can use the server as an amplifier by sending connection initiation messages with a forged source of the victim. The server then sends its response to the victim machine, thus  <ins> flooding it.  Depending on the selected parameters this response </ins> message can be quite large, as it is the case for a Certificate message. subsequently into a ClientHello message.  DTLS 1.2 on the other hand used a separate message, namely the HelloVerifyRequest, to pass a cookie to the client and did not utilize the extension mechanism.  <ins> For backwards compatibility reasons, the cookie field in the </ins> ClientHello is present in DTLS 1.3 but is ignored by a DTLS 1.3 compliant server implementation. the deletion attacks that EndOfEarlyData prevents in TLS.  Servers SHOULD aggressively age out the epoch 1 keys upon receiving the first epoch 2 record and SHOULD NOT accept epoch 1 data after the first  <ins> epoch 3 record is received.  (See dtls-epoch for the definitions of each epoch.) </ins> 5.6. the SENDING state, where it retransmits the flight, resets the retransmit timer, and returns to the WAITING state.  <ins> The implementation reads an ACK from the peer: upon receiving an </ins> ACK for a partial flight (as mentioned in sending-acks), the implementation transitions to the SENDING state, where it retransmits the unacked portion of the flight, resets the value at each retransmission, up to no less than the RFC 6298 maximum of 60 seconds.  Application specific profiles, such as those used for the Internet of Things environment, may recommend longer timer  <ins> values.  Note that a 100 msec timer is recommended rather than the </ins> 3-second RFC 6298 default in order to improve latency for time- sensitive applications.  Because DTLS only uses retransmission for handshake and not dataflow, the effect on congestion should be ServerHello, and HelloRetryRequest. epoch value (1) is used for messages protected using keys derived  <ins> from client_early_traffic_secret.  Note this epoch is skipped if the client does not offer early data. </ins> epoch value (2) is used for messages protected using keys derived from [sender]_handshake_traffic_secret.  Messages transmitted not included in this category. epoch value (3) is used for payloads protected using keys derived  <ins> from the initial [sender]_application_traffic_secret_0.  This may include handshake messages, such as post-handshake messages (e.g., a NewSessionTicket message). </ins> epoch value (4 to 2^16-1) is used for payloads protected using  <ins> keys from the [sender]_application_traffic_secret_N (N>0). </ins> Using these reserved epoch values a receiver knows what cipher state has been used to encrypt and integrity protect a message.


Implementations MAY include the length field at their discretion. The entire header value shown above is used as it appears on the wire <del> as the additional data value for the AEAD function. </del>  4.1.

I added this remark following my implementation experience of DTLS 1.2 CID followed by the work on the DTLS 1.3. We noticed this issue at the Prague IETF meeting (March 2019).

Implementations MAY include the length field at their discretion. The entire header value shown above is used as it appears on the wire  <ins> as the additional data value for the AEAD function.  Note that this design is different to the additional data calculation for DTLS 1.2 and for DTLS 1.2 with Connection ID. </ins> 4.1.


NOT respond with a HelloRetryRequest.  Restarting the handshake from scratch, without a cookie, allows the client to recover from a situation where it obtained a cookie that cannot be verified by the <del> server.  As described in Section 4.1.4 of TLS13, clients SHOULD also abort the handshake with an "unexpected_message" alert in response to any second HelloRetryRequest which was sent in the same connection (i.e., where the ClientHello was itself in response to a HelloRetryRequest). </del>  5.2.

This is an inconsistency between the TLS 1.3 text (which says "MUST" abort the handshake with an "unexpected_message" alert) and the text in this draft, which indicates a SHOULD.
I don't understand what this is trying to say. I think that it says that the client, having received a bad cookie will send its second ClientHello off into the void, only to have the handshake time out. Then, the client is expected to restart. This is probably right. The bad cookie indicates that something is badly wrong. Anything the server might send that would fix this wouldn't be authenticated and so might be exploited by an attack as a denial of service on the connection. However, I'm not sure if any client actually implements this restart.
Probably not, but I think this is just editorial. If you had some client-server type app then you might expect a retry (like Web clients do). Anyway, we shouldn't change the spec.
The text in DTLS 1.2 was a bit different, namely " If a server receives a ClientHello with an invalid cookie, it SHOULD treat it the same as a ClientHello with no cookie. This avoids race/deadlock conditions if the client somehow gets a bad cookie (e.g., because the server changes its cookie signing key). " I believe the DTLS 1.2 text was actually quite good. I suggest to re-use the DTLS 1.2 text again. The problem with the current text is that the Client will have to find out about the failed request via a timeout. While not common, it is not ideal either. If the current text does, however, prevent certain problems I am happy to leave it as is. I noticed that we incorrectly reference text from Section 4.1.4. of the TLS 1.3 RFC. In any case, I prepared a PR just in case: URL I also created a second PR to deal with the inconsistency with the TLS 1.3 spec, which I believe has to be addressed: URL
I don't believe that the bad cookie is a situation that needs to be handled in a different way than is described. Any server doing this uses a key identifier in its cookie. So, like ekr, I don't think that the design needs to be changed. I would prefer to say that the ClientHello with a bad cookie is simply discarded (as Internet background noise, if you will). If the intent of the text (prior to as proposed) is to say that it's now the client's problem to fix, I agree with that. The question was about what the text meant, so an editorial fix would be fine. I would go so far as to say:

NOT respond with a HelloRetryRequest.  Restarting the handshake from scratch, without a cookie, allows the client to recover from a situation where it obtained a cookie that cannot be verified by the  <ins> server. As described in Section 4.1.4 of TLS13, clients MUST abort the handshake with an "unexpected_message" alert in response to any second HelloRetryRequest which was sent in the same connection (i.e., where the ClientHello was itself in response to a HelloRetryRequest). </ins> 5.2.


TCP RFC0793 to allow for packet reordering.  (Note that the intention here is that implementers use the current guidance from the IETF for MSL, as specified in RFC0793 or successors not that they attempt to <del> interrogate the MSL that the system TCP stack is using.)  Until the handshake has completed, implementations MUST accept packets from the old epoch. </del>  Conversely, it is possible for records that are protected with the new epoch to be received prior to the completion of a handshake.  For

Deleted the following statement: "Until the handshake has completed, implementations MUST accept packets from the old epoch." because it appears to be redundant. Martin raised this issue in URL
I think that this is a vestige of renegotiation and can be removed. But we might want to say something more helpful about accepting 0-RTT and Handshake at the same time.
I think we should delete this sentence because it is redundant. We have already text in the same section saying the following: " Because DTLS records could be reordered, a record from epoch 1 may be received after epoch 2 has begun. In general, implementations SHOULD discard packets from earlier epochs, but if packet loss causes noticeable problems implementations MAY choose to retain keying material from previous epochs for up to the default MSL specified for TCP to allow for packet reordering. " NAME If you think there is someone else that should be said, we are happy to add it. Here is the PR: URL
Fixed.

TCP RFC0793 to allow for packet reordering.  (Note that the intention here is that implementers use the current guidance from the IETF for MSL, as specified in RFC0793 or successors not that they attempt to  <ins> interrogate the MSL that the system TCP stack is using.) </ins> Conversely, it is possible for records that are protected with the new epoch to be received prior to the completion of a handshake.  For


[sender]_application_traffic_secret for message protection, Implementations MAY include the length field at their discretion.  The entire header value shown above is used as it appears on the wire as the additional data value for the AEAD function.  Note that this design is different from the additional data calculation for DTLS 1.2 4.2.1. <del> Because DTLS records could be reordered, a record from epoch 1 may be received after epoch 2 has begun.  In general, implementations SHOULD discard packets from earlier epochs, but if packet loss causes noticeable problems implementations MAY choose to retain keying material from previous epochs for up to the default MSL specified for TCP RFC0793 to allow for packet reordering.  (Note that the intention here is that implementers use the current guidance from the IETF for MSL, as specified in RFC0793 or successors not that they attempt to interrogate the MSL that the system TCP stack is using.) </del>  Conversely, it is possible for records that are protected with the new epoch to be received prior to the completion of a handshake.  For does not duplicate the sequence number of any other record received during the lifetime of the session.  This check SHOULD happen after deprotecting the packet; otherwise the packet discard might itself <del> serve as a timing channel for the sequence number. </del>  Duplicates are rejected through the use of a sliding receive window. (How the window is implemented is a local matter, but the following DTLS implementations do not use the TLS 1.3 "compatibility mode" described in Section D.4 of TLS13.  DTLS servers MUST NOT echo the "session_id" value from the client and endpoints MUST NOT send <del> ChangeCipherSpec messages.  Note however that implementations MUST ignore ChangeCipherSpec messages received in unprotected records. </del>  With these exceptions, the DTLS message formats, flows, and logic are the same as those of TLS 1.3. DTLS 1.3, the client indicates its version preferences in the "supported_versions" extension (see Section 4.2.1 of TLS13) and the legacy_version field MUST be set to {254, 253}, which was the <del> version number for DTLS 1.2. </del>  Same as for TLS 1.3. transmitted separately, thus avoiding IP fragmentation. When transmitting the handshake message, the sender divides the <del> message into a series of N contiguous data ranges.  These ranges MUST NOT be larger than the maximum handshake fragment size and MUST jointly contain the entire handshake message.  The ranges MUST NOT overlap.  The sender then creates N handshake messages, all with the same message_seq value as the original handshake message.  Each new message is labeled with the fragment_offset (the number of bytes </del>  contained in previous fragments) and the fragment_length (the length of this fragment).  The length field in all messages is the same as the length field of the original message.  An unfragmented message is a degenerate case with fragment_offset=0 and fragment_length=length.  When a DTLS implementation receives a handshake message fragment, it MUST buffer it until it has the entire handshake message.  DTLS added to the handshake transcript.  Note that ACKs can still be sent in the same UDP datagram as handshake records. <del> %%% ACKs struct { uint64 record_numbers<0..2^16-1>; } ACK; </del>  a list of the records containing handshake messages in the current flight which the endpoint has received, in numerically increasing Note: The connection_id extension is defined in DTLS-CID, which is used in ClientHello and ServerHello messages.  10. Application data messages are carried by the record layer and are

NAME NAME
Well, clients can recover by tearing down the connection and starting over.
Sure, sure. I think this was in the context of a "single" connection. Perhaps it's not that important to clarify?
I'll add text.
I think the only comment that's left to be addressed is this: Perhaps what's missing is precisely that clarifying statement. Namely, that clients which find themselves in such a situation cannot recover.

[sender]_application_traffic_secret for message protection, Implementations MAY include the length field at their discretion. <ins> When expanded, the epoch and sequence number can be combined into an unpacked RecordNumber structure, as shown below: This 64-bit value is used in the ACK message as well as in the "record_sequence_number" input to the AEAD function. </ins> The entire header value shown above is used as it appears on the wire as the additional data value for the AEAD function.  Note that this design is different from the additional data calculation for DTLS 1.2 4.2.1.  <ins> Because DTLS records could be reordered, a record from epoch M may be received after epoch N (where N > M) has begun.  In general, implementations SHOULD discard packets from earlier epochs, but if packet loss causes noticeable problems implementations MAY choose to retain keying material from previous epochs for up to the default MSL specified for TCP RFC0793 to allow for packet reordering.  (Note that the intention here is that implementers use the current guidance from the IETF for MSL, as specified in RFC0793 or successors not that they attempt to interrogate the MSL that the system TCP stack is using.) </ins> Conversely, it is possible for records that are protected with the new epoch to be received prior to the completion of a handshake.  For does not duplicate the sequence number of any other record received during the lifetime of the session.  This check SHOULD happen after deprotecting the packet; otherwise the packet discard might itself  <ins> serve as a timing channel for the record number.  Note that decompressing the records number is still a potential timing channel for the record number, though a less powerful one than whether it was deprotected. </ins> Duplicates are rejected through the use of a sliding receive window. (How the window is implemented is a local matter, but the following DTLS implementations do not use the TLS 1.3 "compatibility mode" described in Section D.4 of TLS13.  DTLS servers MUST NOT echo the "session_id" value from the client and endpoints MUST NOT send  <ins> ChangeCipherSpec messages. </ins> With these exceptions, the DTLS message formats, flows, and logic are the same as those of TLS 1.3. DTLS 1.3, the client indicates its version preferences in the "supported_versions" extension (see Section 4.2.1 of TLS13) and the legacy_version field MUST be set to {254, 253}, which was the  <ins> version number for DTLS 1.2.  The version fields for DTLS 1.0 and DTLS 1.2 are 0xfeff and 0xfefd (to match the wire versions) but the version field for DTLS 1.3 is 0x0304. </ins> Same as for TLS 1.3. transmitted separately, thus avoiding IP fragmentation. When transmitting the handshake message, the sender divides the  <ins> message into a series of N contiguous data ranges.  The ranges MUST NOT overlap.  The sender then creates N handshake messages, all with the same message_seq value as the original handshake message.  Each new message is labeled with the fragment_offset (the number of bytes </ins> contained in previous fragments) and the fragment_length (the length of this fragment).  The length field in all messages is the same as the length field of the original message.  An unfragmented message is a degenerate case with fragment_offset=0 and fragment_length=length. <ins> Each range MUST be delivered in a single packet. </ins> When a DTLS implementation receives a handshake message fragment, it MUST buffer it until it has the entire handshake message.  DTLS added to the handshake transcript.  Note that ACKs can still be sent in the same UDP datagram as handshake records.  <ins> %%% ACKs struct { RecordNumber record_numbers<0..2^16-1>; } ACK; </ins> a list of the records containing handshake messages in the current flight which the endpoint has received, in numerically increasing Note: The connection_id extension is defined in DTLS-CID, which is used in ClientHello and ServerHello messages. <ins> If no CID is negotiated, then the receiver MUST reject any records it receives that contain a CID. </ins> 10. Application data messages are carried by the record layer and are


5.9.  Note that Alert messages are not retransmitted at all, even when they occur in the context of a handshake.  However, a DTLS implementation which would ordinarily issue an alert SHOULD generate a new alert a peer is persistently sending bad messages and terminate the local connection state after such misbehavior is detected. <del> 5.10. </del>  If a DTLS client-server pair is configured in such a way that repeated connections happen on the same host/port quartet, then it is

omit the trailing space because TLS 1.3 went right up to the limit.
No, no, DTLS also uses HKDR for Key Separation++
Hearing no objections, we're merging this change. I'll fix the HKDR->HKDF typo in a followup PR.
This is perfectly fine. Thanks for making the edit.

5.9. <ins> Section 7.1 of RFC8446 specifies that HKDR-Expand-Label uses a label prefix of "tls13 ".  For DTLS 1.3, that label SHALL be "dtls13". This ensures key separation between DTLS 1.3 and TLS 1.3.  Note that there is no trailing space; this is necessary in order to keep the overall label size inside of one hash iteration because "DTLS" is one letter longer than "TLS". 5.10. </ins> Note that Alert messages are not retransmitted at all, even when they occur in the context of a handshake.  However, a DTLS implementation which would ordinarily issue an alert SHOULD generate a new alert a peer is persistently sending bad messages and terminate the local connection state after such misbehavior is detected.  <ins> 5.11. </ins> If a DTLS client-server pair is configured in such a way that repeated connections happen on the same host/port quartet, then it is


5. <del> The Binding table is a special resource that gives access to the bindings on a endpoint.  This section defines a REST interface for Binding table resources.  The Binding table resource MUST support the Binding interface defined below.  The interface supports the link- format type. The if= column defines the Interface Description (if=) attribute value to be used in the CoRE Link Format for a resource conforming to that interface.  When this value appears in the if= attribute of a link, the resource MUST support the corresponding REST interface described in this section.  The resource MAY support additional functionality, which is out of scope for this specification. Although this interface description is intended to be used with the CoRE Link Format, it is applicable for use in any REST interface definition. The Methods column defines the REST methods supported by the interface, which are described in more detail below. The Binding interface is used to manipulate a binding table.  A request with a POST method and a content format of application/link- format simply appends new bindings to the table.  All links in the payload MUST have a relation type "boundto".  A GET request simply returns the current state of a binding table whereas a DELETE request empties the table.  Individual entries may be deleted from the table by specifying the resource path in a DELETE request. The following example shows requests for adding, retrieving and deleting bindings in a binding table. </del>  6. 8.1. <del> The specification registers the "binding" CoRE interface description link target attribute value as per RFC6690. </del>  core.bnd <del> Description: The binding interface is used to manipulate a binding table which describes the link bindings between source and destination resources for the purposes of synchronizing their content. </del>  Reference: This specification.  Note to RFC editor: please insert the RFC of this specification.

Binding Table now defined with URL instead of URL with support for GET and PUT. Examples updated to reflect GET and PUT instead of DELETE. Added a statement indicating PATCH support would be investigated IANA considerations updated for URL
Merging after email discussion with NAME
I created pull request with a rewrite of this section. Please review it and see if that fits what we wanted to do for the Binding Table. The amendments in the pull request text are copy-pasted below: Binding Table The Binding Table is a special resource that describes the bindings on an endpoint. An endpoint offering a representation of the Binding Table resource SHOULD indicate its presence and enable its discovery by advertising a link at "/.well-known/core" [RFC6690]. If so, the Binding Table resource MUST be discoverable by using the Resource Type (rt) 'URL'. The Methods column defines the REST methods supported by the Binding Table, which are described in more detail below. +---------------+----------+----------+----------------+ +---------------+----------+----------+----------------+ +---------------+----------+----------+----------------+ Table 4: Binding Table Description The REST methods GET and PUT are used to manipulate a Binding Table. A GET request simply returns the current state of a Binding Table. A request with a PUT method and a content format of application/link- format is used to clear the bindings to the table or replaces its entire contents. All links in the payload of a PUT rquest MUST have a relation type "boundto". (Editor's Note: Usage of the PATCH method for fine-grained addition and removal of individual bindings is under study.) The following example shows requests for discovering, retrieving and replacing bindings in a binding table. Req: GET /.well-URL (application/link-format) Res: 2.05 Content (application/link-format) ;URL;ct=40 Req: GET /bnd/ Res: 2.05 Content (application/link-format) ; rel=boundto;bind=obs;anchor=/a/fan,;bind="obs", ; rel=boundto;bind=obs;anchor=/a/light;bind="obs" Req: PUT /bnd/ (Content-Format: application/link-format) ; rel="boundto";anchor="/a/light";bind="obs";pmin="10";pmax="60" Res: 2.04 Changed Req: GET /bnd/ Res: 2.05 Content (application/link-format) ; rel="boundto";anchor="/a/light";bind="obs";pmin="10";pmax="60" Figure 2: Binding Table Example IANA Considerations Resource Type value 'URL' This specification registers a new Resource Type Link Target Attribute 'URL' in the Resource Type (rt=) registry established as per [RFC6690]. Attribute Value: URL Description: See Section 5. This attribute value is used to discover the resource representing a binding table, which describes the link bindings between source and destination resources for the purposes of synchronizing their content. Reference: This specification. Note to RFC editor: please insert the RFC of this specification. Notes: None
Merging after email discussion with NAME

5.  <ins> The Binding Table is a special resource that describes the bindings on an endpoint.  An endpoint offering a representation of the Binding Table resource SHOULD indicate its presence and enable its discovery by advertising a link at "/.well-known/core" RFC6690.  If so, the Binding Table resource MUST be discoverable by using the Resource Type (rt) 'core.bnd'. The Methods column defines the REST methods supported by the Binding Table, which are described in more detail below. The REST methods GET and PUT are used to manipulate a Binding Table. A GET request simply returns the current state of a Binding Table.  A request with a PUT method and a content format of application/link- format is used to clear the bindings to the table or replaces its entire contents.  All links in the payload of a PUT rquest MUST have a relation type "boundto". (Editor's Note: Usage of the PATCH method for fine-grained addition and removal of individual bindings is under study.) The following example shows requests for discovering, retrieving and replacing bindings in a binding table. </ins> 6. 8.1.  <ins> This specification registers a new Resource Type Link Target Attribute 'core.bnd' in the Resource Type (rt=) registry established as per RFC6690. </ins> core.bnd  <ins> Description: See binding_table.  This attribute value is used to discover the resource representing a binding table, which describes the link bindings between source and destination resources for the purposes of synchronizing their content. </ins> Reference: This specification.  Note to RFC editor: please insert the RFC of this specification.


This specification defines Link Bindings, which provide dynamic linking of state updates between resources, either on an endpoint or between endpoints, for systems using CoAP (RFC7252).  This <del> specification also defines Conditional Notification Attributes that work with Link Bindings or with CoAP Observe (RFC7641). </del>  Editor note are sent over the link to the other.  CoRE Link Format representations are used to configure, inspect, and maintain Link Bindings.  This specification additionally defines Conditional <del> Notification Attributes for use with Link Bindings and with CoRE Observe RFC7641. </del>  2. 3.1. <del> This specification defines Conditional Notification Attributes, which provide for fine-grained control of notification and state synchronization when using CoRE Observe RFC7641 or Link Bindings (see bindings).  Conditional Notification Attributes define the conditions </del>  that trigger a notification. When resource interfaces following this specification are made be used to observe any changes in a resource, and receive asynchronous notifications as a result.  A resource marked as Observable in its link description SHOULD support these Conditional <del> Notification Attributes. </del>  <del> The set of parameters defined here allow a client to control how often a client is interested in receiving notifications and how much a resource value should change for the new representation to be interesting. </del>  One or more Notification Attributes MAY be included as query parameters in an Observe request. <del> These attributes are defined below: </del>  Conditional Notification Attributes SHOULD be evaluated on all potential notifications from a resource, whether resulting from an internal server-driven sampling process or from external update <del> requests to the server. </del>  Note: In this draft, we assume that there are finite quantization effects in the internal or external updates to the value of a The Notification Band parameter can only be supported on resources with a scalar numeric value.  3.2. Pmin, pmax, st, gt, lt and band may be present in the same query. <del> Howver, they are not defined at multiple prioritization levels.  The </del>  server sends a notification whenever any of the parameter conditions are met, upon which it updates its last notification value and time to prepare for the next notification.  Only one notification occurs The use of the notification band minimum and maximum allow for a synchronization whenever a change in the resource value occurs. Theoretically this could occur in-line with the server internal <del> sample period for the determining the resource value.  Implementors SHOULD consider the resolution needed before updating the resource, e.g. updating the resource when a temperature sensor value changes by 0.001 degree versus 1 degree. </del>  The initiation of a Link Binding can be delegated from a client to a link state machine implementation, which can be an embedded client or regards to Link Bindings, as well as any errors that may arise with establishing Link Bindings in addition to established Link Bindings.  7. Consideration has to be given to what kinds of security credentials

OMA LwM2M added support for additional attributes that should be reflected back into the dynlink draft to avoid fragmentation. Those attributes are called Minimum Evaluation Period (epmin) and Maximum Evaluation Period (epmax). The current LwM2M Core Spec currently has this statement: "The behavior of all Attributes SHOULD follow [DynLink] except epmin and epmax, which are only defined in this specification." The goal would be to change that statement to: "The behavior of all Attributes SHOULD follow [DynLink]." Below is text to consider for the inclusion in the dynlink draft: "The "Minimum Evaluation Period" (epmin) and "Maximum Evaluation Period" (epmax) values can be used to configure the device to perform reporting evaluations. After the expiry of epmin, the device MAY immediately perform an evaluation per the "Notification Conditions" above. After the expiry of epmax, the device MUST perform an evaluation per the "Notification Conditions". If both the epmin and epmax attributes are defined, the epmin must be less than the epmax." These are the table entries from the LwM2M Core Specification: Minimum Evaluation Period Readable Resource Notes: The Minimum Evaluation Period Attribute indicates the minimum time in seconds the LwM2M Client MUST wait between two evaluations of reporting criteria. In the absence of this parameter, the Evaluation Minimum Period is not defined. Maximum Evaluation Period Resource Resource Instance Object Object Instance Readable Resource Notes: The Maximum Evaluation Period Attribute indicates the maximum time in seconds the LwM2M Client MAY wait between two evaluations of reporting criteria. When the Maximum Evaluation Period expires after the previous evaluation, a new evaluation MUST occur. In the absence of this parameter, the Maximum Evaluation Period is not defined.
NAME This seems like a good addition to the other conditional attributes we have. I do think some additional clarifications would be necessary. How should the CoAP endpoint (an origin server, or the LWM2M client) handle an incoming Observe request which contains epmin/epmax query parameters, but does not have any other attributes present?
NAME These values only have context when other conditional attributes are present such that a measurement must take place and report potentially generated. If no report would ever be generated, then these parameters that guide when a measurement takes place provide no value. Would you like me to capture the above text somewhere? How about in each table entry: "This value is ignored if other conditional attributes are not provided".
I'm not sure we should be "configuring the device" using query parameters on a GET/observe. But maybe the text above is not enough for me to understand what is being "configured".
Checking the content on the , I am wondering if epmin/epmax make sense from REST pov. Query parameters are used to operate on the state of a resource and not to modify the internal mechanisms nor behaviour of the sensor. Thus evaluation periods would be out of the scope of what a query parameter should do IMO. I'll copy this comment in the too if that's OK.
I equate the definition of epmin/epmax to pmin/pmax as they control when a notification report is/can be generated and have noting to do directly with the behavior of the sensor. pmin/pmax have nothing to do with the state of a resource but only when that state is evaluated/reported. epmin/epmax is similar.
Do you perhaps have an example that shows the effects of epmin/epmax?
In the dynlink call yesterday, Klaus showed an example of where the device wakes up every second to check the value of an observed resource. How does the device know to wake up every second to read that sensor? That is how the epmin and epmax values are used.
I have created pull request to address this issue. I did not create an example as I wasn't sure the format that we would wish that example represented. Let's discuss during the interim meeting.
Here is text to consider for the example: As an example of the use of the Conditional Control Attributes, we will detail an observation using pmin, pmax, gt, epmin and epmax. In this use case, we have a temperature sensor that will send a notification whenever the temperature goes above or below 100 degrees (gt>100). It cannot report more often than every 5 seconds (pmin=5). It must report at least every 60 seconds (pmax=60). In order to control how frequently the server measures the temperature sensor, the client configures the server to avoid measuring it more frequently than 5 seconds (epmin=5), but the server must measure it at least every 10 seconds (epmax=10). After a notification is generated (t=0), the device waits 5 seconds before another notification can be sent due to pmin. After that 5 seconds expires (t=5), the server decides to perform a measurement of the temperature sensor. If the temperature has not changed from its previous state (the temperature has remained above 100 or remained below 100), no notification is generated. The server must wait another 5 seconds (t=10) before doing another measurement of the temperature sensor due to the required expiry of the epmin. At that time (t=10), the server decides that it does not want to do a measurement of the temperature sensor (an implementation specific decision). After an additional 5 seconds (t=15), the server MUST perform a measurement of the temperature sensor due the expiry of epmax. If the temperature has changed (the temperature has gone above 100 or gone below 100), a notification is generated. If not, the server returns to the measurement cadence defined by the epmin and epmax attributes. If 60 seconds goes by prior to a notification, a notification is generated because of pmax.
This has been accepted into the draft, so the issue can be closed.

This specification defines Link Bindings, which provide dynamic linking of state updates between resources, either on an endpoint or between endpoints, for systems using CoAP (RFC7252).  This  <ins> specification also defines Conditional Notification and Control Attributes that work with Link Bindings or with CoAP Observe (RFC7641). </ins> Editor note are sent over the link to the other.  CoRE Link Format representations are used to configure, inspect, and maintain Link Bindings.  This specification additionally defines Conditional  <ins> Notification and Control Attributes for use with Link Bindings and with CoRE Observe RFC7641. </ins> 2. 3.1.  <ins> This specification defines Conditional Notification and Control Attributes, which provide for fine-grained control of notification and state synchronization when using CoRE Observe RFC7641 or Link Bindings (see bindings).  Conditional Notification Attributes define the conditions that trigger a notification.  Conditional Control Attributes define the cadence of the measurement of the conditions </ins> that trigger a notification. When resource interfaces following this specification are made be used to observe any changes in a resource, and receive asynchronous notifications as a result.  A resource marked as Observable in its link description SHOULD support these Conditional  <ins> Notification and Control Attributes. </ins>  <ins> The set of Notification Attributes defined here allow a client to control how often a client is interested in receiving notifications and how much a resource value should change for the new representation to be interesting.  The set of Control Attributes defined here allow a client to control how often the server performs a measurement of the conditions. </ins> One or more Notification Attributes MAY be included as query parameters in an Observe request.  <ins> Conditional Notification Attributes are defined below: One or more Control Attributes MAY be included as query parameters in an Observe request. Conditional Control Attributes are defined below: </ins> Conditional Notification Attributes SHOULD be evaluated on all potential notifications from a resource, whether resulting from an internal server-driven sampling process or from external update  <ins> requests to the server.  Conditional Control Attributes are used to configure the internal server-driven sampling process for performing measurements of the conditions of a resource. </ins> Note: In this draft, we assume that there are finite quantization effects in the internal or external updates to the value of a The Notification Band parameter can only be supported on resources with a scalar numeric value. <ins> 3.1.7. When present, the minimum evaluation period indicates the minimum time, in seconds, the client recommends to the server to wait between two consecutive measurements of the conditions of a resource since the client has no interest in the server doing more frequent measurements.  When the minimum evaluation period expires after the previous measurement, the server MAY immediately perform a new measurement.  In the absence of this parameter, the minimum evaluation period is not defined and thus not used by the server. The server MAY use pmin, if defined, as a guidance on the desired measurement cadence.  The minimum evaluation period MUST be greater than zero otherwise the receiver MUST return a CoAP error code 4.00 "Bad Request" (or equivalent). 3.1.8. When present, the maximum evaluation period indicates the maximum time, in seconds, the server MAY wait between two consecutive measurements of the conditions of a resource.  When the maximum evaluation period expires after the previous measurement, the server MUST immediately perform a new measurement.  In the absence of this parameter, the maximum evaluation period is not defined and thus not used by the server.  The maximum evaluation period MUST be greater than zero and MUST be greater than the minimum evaluation period parameter (if present) otherwise the receiver MUST return a CoAP error code 4.00 "Bad Request" (or equivalent). </ins> 3.2. Pmin, pmax, st, gt, lt and band may be present in the same query.  <ins> However, they are not defined at multiple prioritization levels.  The </ins> server sends a notification whenever any of the parameter conditions are met, upon which it updates its last notification value and time to prepare for the next notification.  Only one notification occurs The use of the notification band minimum and maximum allow for a synchronization whenever a change in the resource value occurs. Theoretically this could occur in-line with the server internal  <ins> sample period or the configuration of epmin and epmax values for determining the resource value.  Implementors SHOULD consider the resolution needed before updating the resource, e.g. updating the resource when a temperature sensor value changes by 0.001 degree versus 1 degree. </ins> The initiation of a Link Binding can be delegated from a client to a link state machine implementation, which can be an embedded client or regards to Link Bindings, as well as any errors that may arise with establishing Link Bindings in addition to established Link Bindings. <ins> When a server has multiple observations with different measurement cadences as defined by the epmin and epmax values, the server MAY evaluate all observations when performing the measurement of any one observation. </ins> 7. Consideration has to be given to what kinds of security credentials