jiebi/CodeConvo huggingface dataset:
Code change:
17.6. This document registers the "message/mls" MIME media type in order to <del> allow other protocols (ex: HTTP RFC7540) to convey MLS messages. </del> <ins> allow other protocols (e.g., HTTP RFC7540) to convey MLS messages. </ins> message

Related discussion:
text: As NAME pointed out on the mailing list, this reference does not need to be normative.
Code change:
The above is necessary to protect against attacks that use datagrams with spoofed addresses or replayed datagrams to trigger attacks. <del> Note that there is no requirement to use of the anti-replay window </del> <ins> Note that there is no requirement for use of the anti-replay window </ins> mechanism defined in Section 4.1.2.6 of DTLS 1.2.  Both solutions, <del> the "anti-replay window" or "newer algorithm" will prevent address </del> <ins> the "anti-replay window" or "newer" algorithm, will prevent address </ins> updates from replay attacks while the latter will only apply to peer address updates and the former applies to any application layer traffic. <ins> Note that datagrams that pass the DTLS cryptographic verification procedures but do not trigger a change of peer address are still valid DTLS records and are still to be passed to the application. </ins> Application protocols that implement protection against these attacks depend on being aware of changes in peer addresses so that they can engage the necessary mechanisms.  When delivered such an event, an application layer-specific address validation mechanism can be <del> triggered, for example one that is based on successful exchange of </del> <ins> triggered, for example one that is based on successful exchange of a </ins> minimal amount of ping-pong traffic with the peer.  Alternatively, an DTLS-specific mechanism may be used, as described in I-D.tschofenig- tls-dtls-rrc.

Related discussion:
text: This is supposed to all be editorial stuff, and I split a couple changes out into separate commits in case they're not actually desired.
Code change:
the complete LwM2M model to a summary of how RD is used in there, with a reference to the current specification. <ins> impl-info: Add note about the type being WIP </ins> changes from -24 to -25 Large rework of section 7 (Security policies)

Related discussion:
text: ... as otherwise, code squatting again. See-Also: URL Thanks for the updates in the -26; they help a lot. I'm particularly happy to see the (default/example) "first-come-first-remembered" policy in § 7.5, which does a good job of documenting its properties (including potential deficiencies) and can be usable for many environments.  (I do have some suggestions for improvements to the specific wording in the section-by-section comments, but on the whole I like it.) It does lead in to a more general comment, though (which is not exactly new to the changes in the -26 though it is reflected in several of them): some aspects of the concept of "authorization" to appear in a directory, and the verification of authorization for the entire flow from client locating the RD server to final request at the discovered resource, are somewhat subtle.  (The new text discusses, e.g., "repeat the URI discovery step at the /.well-known/core resource of the indicated host to obtain the resource type information from an authorized source" and "a straightforward way to verify [discovered information] is to request it again from an authorized server, typically the one that hosts the target resource".)  The aspects I'm concerned about are not matters of a resource server being authorized to publish to a directory or a client deeming that a server is authorized to act as an RD (though both of those are also important), but seems to rather just be relating to the RD faithfully disseminating the information the RD retrieved from /.well-known/core discovery on the given server(s) (or otherwise learned via some other mechanism). In this sense the RD is just acting as a cache or efficiency aid, but the authoritative source of the information remains (in general) the server hosting the resource.  To be clear, I think the procedures that this document specifies are good and correct procedures for a client to perform, I'm just not sure whether "authorized" is the right term in these cases; "authoritative" might be more appropriate, in that the operation in question is to verify the information retrieved from the RD (which acts in some sense as an intermediary) at the more authoritative source.
Code change:
the complete LwM2M model to a summary of how RD is used in there, with a reference to the current specification. <ins> impl-info: Add note about the type being WIP </ins> changes from -24 to -25 Large rework of section 7 (Security policies)

Related discussion:
text: (On a tangent from that note, it seems that there is not necessarily any indication to a client that a server claiming to provide a given resource (whether discovered via RD or /.well-known/core) is actually authorized to provide such a resource and be trusted by the client.  But that's not really a property of RD, and rather the underlying CoRE mechanism and any provisioned trust database, so my thoughts about it seem out of scope for this document.) (It's not entirely clear to me what the reader is expected to do with the information about the previous formulation.) (It seems that something also needs to cause the RD to check the authorization of lookup clients to receive the information in question, which might be worth reiterating in this section.) I'm pretty sure the intent here is that only the subject names that are certified by the recognized authority(ies) are stored, in which case I'd suggest to s/all those/all such/. (I can understand why the "store the whole list" logic is used, though there may be some subtleties about name constraints on the (X.509) CAs used, which is why we typically don't recomment treating the entire list of names in the certificate as validated from a single operation, instead preferring "is this certificate authenticated for this specific name?" when the specific target name is available.) Should we talk about whether the lifetime of registration entries is related to the various lifetimes of these credentials/identifiers?  DTLS without resumption is perhaps an interesting case, in that keeping the DTLS association "live" just to be able to update the registration information seems impractical, so perhaps some fixed cap would be applied on the lifetime in that case.  If resumption is used, the resumption information (ticket or session state) has some finite lifetime that could be used to bound the lifetime of the registration. IIRC an OSCORE security context can also have an expiration time; certificates and JWT/CWT have expiration time as well (though the procedures in the first bullet point would effectively allow a "renewal" operation), but the validity period (if any) of a raw public key would have to be provisioned along with that key (or just have RPK be handled akin to DTLS without resumption, I guess). (Similar to my earlier parenthetical comment, the requirement for exact match of all subject name information is unusual.
Code change:
the complete LwM2M model to a summary of how RD is used in there, with a reference to the current specification. <ins> impl-info: Add note about the type being WIP </ins> changes from -24 to -25 Large rework of section 7 (Security policies)

Related discussion:
text: In effect this is a way of pinning the set of names that the CA has chosen to include in a single certificate, which is arguably a stronger requirement than needed but should not lead to any unauthorized access.)
Code change:
perform this process as part of packet processing, but this creates a timing signal that can be used by an attacker to learn when key updates happen and thus the value of the Key Phase bit in certain <del> packets.  Endpoints SHOULD instead defer the creation of the next set of receive packet protection keys until some time after a key update </del> <ins> packets.  Endpoints MAY instead defer the creation of the next set of receive packet protection keys until some time after a key update </ins> completes, up to three times the PTO; see old-keys-recv. Once generated, the next set of packet protection keys SHOULD be

Related discussion:
text: As concluded in Singapore.
When receiving a packet with an unexpected key phase, an implementation should compute the new keys: This creates a timing side-channel, since an attacker can modify the KEYPHASE bit, thereby making a peer compute the next key generation. The packet will be discarded, since the header is protected by the AEAD, but the fact that the key is computed on receipt of that packet is a side-channel that might be used to recover the header protection key. The way to avoid this side-channel is to pre-compute the N+1 key when rolling over keys from key phase N-1 to N. An implementation would then use the N+1 keys when receiving a packet with an unexpected KEYPHASE, in exactly the same way it would do decryption on a packet sent at key phase N. This however contradicts the text that claims that an implementation may choose to only keep two read keys at any given moment: Directly after a key update, an implementation would have to store (at least) 3 key generations: N-1 for a duration of 3 PTO, in order to be able to decrypt delayed / reordered packets, N, as well as the precomputed N+1 to avoid the timing side-channel described above. I don't think that storing 3 keys is a problem (I think NAME disagrees, I'll let him explain his reasoning himself), but the spec shouldn't pretend that it's possible to create an implementation that both isn't vulnerable to the timing side-channel and at the same time gracefully handles moderate amounts of reordering around a key update.
I think you are correct in pointing out that there is a timing side-channel, and that we need to fix the issue. OTOH, I disagree that requiring all endpoints to be capable of retaining 3 keys is not a good way of fixing the issue due to the following reasons. Firstly, I do not think we can justify why an endpoint needs to be capable of retaining that much keys, even though Key Update is expected to happen very rarely. The purpose of Key Update is to replace a key after extensive use, we would never be using a key that becomes weak just after couple of PTOs. Considering that, using 2 keys should be sufficient; 3 keys is likely a sign of a needlessly complex design.
Code change:
perform this process as part of packet processing, but this creates a timing signal that can be used by an attacker to learn when key updates happen and thus the value of the Key Phase bit in certain <del> packets.  Endpoints SHOULD instead defer the creation of the next set of receive packet protection keys until some time after a key update </del> <ins> packets.  Endpoints MAY instead defer the creation of the next set of receive packet protection keys until some time after a key update </ins> completes, up to three times the PTO; see old-keys-recv. Once generated, the next set of packet protection keys SHOULD be

Related discussion:
text: Let's compare the proposal of the 3-key design with a 2-key design (that allows the receiver to delay the installation of the next key for 3 PTO after since Key Update, which is ). In the 3-key design, the next key is installed when a Key Update happens. The old key is disposed 3 PTO after a Key Update, and the slot becomes NULL. Note also that an endpoint needs to retain a mapping between packet number and key phase to determine whether an incoming packet is to be decrypted using the oldest key or the newest key (those two key share the same KEY_PHASE bit on the wire). In the 2-key design, installation of the next key and the disposal of the old key happens at the same moment (i.e. 3 PTO after a Key Update). An endpoint would always retain 2 keys once the handshake is confirmed. There is no need for retaining a mapping between packet numbers and key phases. The oddity of the key phase bit directly maps to the decryption key. To me it seems that the latter is simpler. As stated above, there is no need for doing Key Update every 3 PTO, and therefore, assuming that we need to make a change due to the attack vector, I think we should simply allow endpoints delay the installation of the next key rather than changing the increasing the minimum state that an endpoint needs to be capable of maintaining.
I agree, there's not really a need to do key updates that frequently. However, I like the fact that we're currently defining a clear rule: An endpoint is allowed to update to N+1 as soon as it has received an acknowledgement for a packet sent at key phase N. You should still keep track of the packet number at which the key update happened, in order to check that the peer is not reusing the old key to encrypt packets after it already switched to new keys. Strictly speaking, this is not required for a working implementation, but it's a really easy check to catch a misbehaving peer (or detect an active attack).
Code change:
perform this process as part of packet processing, but this creates a timing signal that can be used by an attacker to learn when key updates happen and thus the value of the Key Phase bit in certain <del> packets.  Endpoints SHOULD instead defer the creation of the next set of receive packet protection keys until some time after a key update </del> <ins> packets.  Endpoints MAY instead defer the creation of the next set of receive packet protection keys until some time after a key update </ins> completes, up to three times the PTO; see old-keys-recv. Once generated, the next set of packet protection keys SHOULD be

Related discussion:
text: As I've mentioned in the discussion in , the reason I'm skeptical about delaying key updates by 3 PTO (and effectively dropping all packets with a higher key phase until this period is over) is that we're replacing a very clear definition by an approximate rule: the PTO is calculated locally, and depending on the network conditions, the two endpoints might have different opinions about the exact value of the PTO. An endpoint that wants to ensure that no packets are dropped due to the unavailability of keys would have no choice but to wait >> 3 PTO. While this should be well within the safety limits of the cipher suites we're using, not having a clear criterion seems to be a sign of suboptimal protocol design.
Perhaps we should state that an endpoint should precompute the key early but not update keys too frequently to prevent timing attacks and overhead. That is not necessarily a bad thing, but it is unfortunate that there is no clear definition. We could also say the idle timeout period. As long as we compute keys using SHA256 it might not be a concern, but computing keys too frequently could exhaust safety parameters on other potentially faster algorithms.
To clarify, the key phase bit is inside header protection, so the attacker in question is the peer?
NAME No, this is an on-path attack. Header protection is not authenticated, so an attacker can just flip bits in the header. Decrypting the packet will fail then, since the header is part of the authenticated data used in the AEAD. We have a timing side-channel as soon as we treat packets differently based on values in the unprotected header, before authenticating the packet. This is analogous to the .
Thanks for the extra explanation, I'm not sure that's a very good side-channel, but I agree it is one.
Does anyone have any ideas what kind of actual attack could take advantage of this? The attacker can only cause you to install your keys early once per key phase change. Assuming you hardly every change key phase, what then? I agree it's a way the unauthenticated attacker can change your state, but I don't think it's a big enough problem we need to worry about fixing.
That's a good question. I agree that this attack vector doesn't look very promising at first sight, but then again I'm always surprised what cryptanalysts can extract from a single bit. That depends.
Code change:
perform this process as part of packet processing, but this creates a timing signal that can be used by an attacker to learn when key updates happen and thus the value of the Key Phase bit in certain <del> packets.  Endpoints SHOULD instead defer the creation of the next set of receive packet protection keys until some time after a key update </del> <ins> packets.  Endpoints MAY instead defer the creation of the next set of receive packet protection keys until some time after a key update </ins> completes, up to three times the PTO; see old-keys-recv. Once generated, the next set of packet protection keys SHOULD be

Related discussion:
text: If you create the new keys, try decrypt the packet, and then discard the keys (if decryption fails), the attacker has an unbounded number of tries. Obviously, this would also be a DoS vector, since computing new keys is more than order of magnitude more expensive than an AEAD operation (at least in my implementation). If you cache the new keys once they are computed, then the attacker indeed only has a single shot per key phase. However, then you might as precompute the new keys when installing the current key phase. The problem with that is that the spec currently suggests that you only ever need to keep state for 2 key generations at any given moment. This is incompatible with caching the keys for the next key phase, as I described above.
NAME But the current spec. also recommends to wait for 3 PTO before initiating the next Key Update. That would not change, and as we agree, nothing in practice requires us to do Key Updates every 3 PTO. I agree that an endpoint might still want to track the packet number at which key update happened. But even in such case, the simplicity of the 2-key design still exists, in sense that you'd only use it for detecting a suspicious peer. It's much straightforward and easier to test, because the rare case (of actually using 3 keys at the same time) never happens. To clarify, I am not saying that 3-key design is incorrect. My argument is that lack of clear signal is a non-issue (because there is no need to do a Key Update every 3 PTO or more frequently), and that therefore that argument cannot be used for prohibiting people to choose the 2-key design (which is simpler).
Isn't the middle ground here to pre-compute the N+1 key when the N-1 key is dropped, with the drop happening at the first of: 3xPTO after the N key was first successfully used First arrival of a packet which purports to be N+1 The attacker's ability at that point would be to cause any delayed N-1 packets to be dropped, but if we're presuming the ability to bit-flip, they can cause those packets to be invalid and dropped anyway.
NAME That certainly reduces the information being potentially exposed to the attacker to one bit per every key update.
Code change:
perform this process as part of packet processing, but this creates a timing signal that can be used by an attacker to learn when key updates happen and thus the value of the Key Phase bit in certain <del> packets.  Endpoints SHOULD instead defer the creation of the next set of receive packet protection keys until some time after a key update </del> <ins> packets.  Endpoints MAY instead defer the creation of the next set of receive packet protection keys until some time after a key update </ins> completes, up to three times the PTO; see old-keys-recv. Once generated, the next set of packet protection keys SHOULD be

Related discussion:
text: But no less than that for example when an attacker injects two packets slightly more frequent than every 3 PTO, with the only difference between the two packets being the value of the KEY_PHASE bit. In such an attack scenario, the attacker can tell which of the two packets caused the calculation of the updated key for every key update. Admittedly, the leak is tiny; but I am not sure if it is tiny enough that we can ignore.
To recap my comments at the mic: it's not clear to me what the attacker is learning here. Can someone expand on this?
Discussed in Montreal: NAME to work with NAME and NAME to work out the details
I'd like to second NAME comment at the mic. I don’t think this is an issue for which we need text. Without loss of generality, let’s assume that in the worst case an attacker learns the entire unprotected header bytes for every packet. (That is, that header protection does nothing overwhelmingly helpful.) Revisiting the header protection algorithm, it basically works as follows: where H’ and H are the protected and unprotected header bytes, respectively, and sample is known to the adversary. If we assume mask is the output of a PRP, and therefore both IND-CPA secure and KPA secure, an adversary learns nothing from known plaintext and ciphertext pairs. (The typical game-based IND-CPA security definition says that an adversary with access to an oracle for encrypting any message Mi of its choice has negligible probability in selecting b, upon giving the challenger M0 and M1 and receiving an encryption of Mb. Recovering the header protection key would break this assumption, as it would let the adversary encrypt M0 and M1 -- without the oracle -- and trivially match against M_b.) All that said, I think adding text describing that endpoints should precompute keys is fine. After all, it'd be nice if header protection worked as intended.
NAME and NAME to resolve their issue before we'll take it forward
Discussed in Singapore; proposal is to change SHOULD to MAY regarding pregeneration of next phase of keys.
Code change:
processing in the filter expression: Its only argument is an instance of "NodesType" (possibly taken from <del> a "filter-path" as in the example above).  The result is an instance </del> <ins> a "filter-query" as in the example above).  The result is an instance </ins> of "ValueType". If the argument contains a single node, the result is the value of

Related discussion:
text: XPath terminology is a bit weird, because XPath has a somewhat competing standard XQuery... XPath is based on DSSSL, which had a complex expression language for building paths in the XML trees that was based on the Scheme language. (Which is the experience that makes me hesitant just jumping headlong into another expression language...)
LGTM with that change. Thanks!