RFC 9668
Using Ephemeral Diffie-Hellman Over COSE (EDHOC) with the Constrained Application Protocol (CoAP) and Object Security for Constrained RESTful Environments (OSCORE)
RFC 9668: Using Ephemeral Diffie-Hellman Over COSE (EDHOC) with the Constrained Application Protocol (CoAP) and Object Security for Constrained RESTful Environments (OSCORE) ๐
- Stream: Internet Engineering Task Force (IETF) ๐
- Number: 9668
- Authors: F. Palombini (Ericsson AB), M. Tiloca (RISE AB), R. Hรถglund (RISE AB), S. Hristozov (Eriptic), G. Selander (Ericsson) ๐ง
- Category: Standards Track ๐
- ISSN: 2070-1721
- Date: November 2024 ๐
- Obsoletes/Updates: the header doesn't list any RFCs this one obsoletes or updates ๐ซถ
Abstract
okay so the lightweight authenticated key exchange protocol EDHOC can run over CoAP, and two peers can use it to set up a Security Context for OSCORE ๐ฆ. This doc goes into how that works and adds a bunch of extra, optional mechanisms ๐ . The big one is an optimization that squishes the EDHOC exchange together with the first OSCORE transaction ๐ฅ. The payoff is fewer round trips needed to set up an OSCORE Security Context and finish an OSCORE transaction using it. Iconic, honestly ๐.
Status of This Memo
This is an Internet Standards Track document. โจ
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 7841. ๐ธ
Info about the current status of this doc, any errata, and how to send feedback is at https://www.rfc-editor.org/info/rfc9668. ๐
Copyright Notice
Copyright (c) 2024 IETF Trust and the persons identified as the document authors. All rights reserved. ๐
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, since they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Revised BSD License. ๐
Table of Contents ๐บ๏ธ
1. Introduction
1.1. Terminology
2. EDHOC Overview
3. EDHOC Combined with OSCORE
3.1. EDHOC Option
3.2. Client Processing
3.2.1. Processing of the EDHOC + OSCORE Request
3.2.2. Supporting Block-Wise Transfers
3.3. Server Processing
3.3.1. Processing of the EDHOC + OSCORE Request
3.3.2. Supporting Block-Wise Transfers
3.4. Example of the EDHOC + OSCORE Request
4. Use of EDHOC Connection Identifiers with OSCORE
4.1. Additional Processing of EDHOC Messages
4.1.1. Initiator Processing of Message 1
4.1.2. Responder Processing of Message 2
4.1.3. Initiator Processing of Message 2
5. Extension and Consistency of Application Profiles
6. Web Linking
7. Security Considerations
8. IANA Considerations
8.1. CoAP Option Numbers Registry
8.2. Target Attributes Registry
8.3. EDHOC Authentication Credential Types Registry
8.4. Expert Review Instructions
9. References
9.1. Normative References
9.2. Informative References
Acknowledgments
Authors' Addresses
1. Introduction โจ
EDHOC [RFC9528] is a lightweight authenticated key exchange protocol, and it's built specifically for constrained scenarios ๐ธ. EDHOC messages can be carried over the Constrained Application Protocol (CoAP) [RFC7252], and they can be used to establish a Security Context for Object Security for Constrained RESTful Environments (OSCORE) [RFC8613]. ๐ฆ
This document covers how to use EDHOC with CoAP and OSCORE, and it specifies a number of additional and optional mechanisms ๐. One of them is an optimization that combines the EDHOC execution with the first OSCORE transaction (see Section 3) ๐ฅ. This gets you a minimum of two round trips to set up the OSCORE Security Context and complete an OSCORE transaction. Picture an Internet of Things (IoT) device getting configured in a network for the first time, e.g., ๐ง.
This optimization is a big deal ๐ because the number of message exchanges can seriously affect how long it takes to deliver the first OSCORE request when certain radio technologies are involved ๐ .
Without this optimization, hitting that minimum of two round trips just isn't possible ๐. The optimization is what makes it work, because message_3 of the EDHOC protocol can be made relatively small (see Section 1.2 of [RFC9528]). That leaves room for extra OSCORE-protected CoAP data within target MTU sizes โจ.
The minimum of two round trips can be achieved only if the default forward message flow of EDHOC is used. That means a CoAP client acts as the EDHOC Initiator and a CoAP server acts as the EDHOC Responder ๐. The performance advantage of this optimization can be lost when it's combined with Block-wise transfers [RFC7959] that rely on specific parameter values and block sizes ๐ญ.
Also, this doc defines a number of parameters that correspond to different information elements of an EDHOC application profile (see Section 6) ๐. These parameters can be specified as target attributes in the link to an EDHOC resource associated with that application profile. That means CoAP clients get enhanced discovery of such a resource, which is honestly so helpful ๐ซถ.
1.1. Terminology
Okay, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are read as BCP 14 [RFC2119] [RFC8174] describes. They only count when they appear in all capitals, just like here ๐.
The reader is expected to already know the terms and concepts from CoAP [RFC7252], Concise Binary Object Representation (CBOR) [RFC8949], OSCORE [RFC8613], and EDHOC [RFC9528] ๐.
2. EDHOC Overview ๐ธ
okay bestie, this section is not normative ๐ so it's just a friendly recap of what's in [RFC9528] (specifically Appendix A.2 of [RFC9528]). Think of it as the baseline we build on in the enhancements coming up next โจ
The EDHOC protocol in [RFC9528] lets two peers agree on a cryptographic secret in a mutually-authenticated way, and it gets forward secrecy by using Diffie-Hellman ephemeral keys ๐ The two peers are called the "Initiator" and the "Responder". Whoever sends the first EDHOC message_1 is the Initiator, and whoever receives it is the Responder ๐
After successful processing of EDHOC message_3, both peers agree on a cryptographic secret that can be used to derive further security material and establish an OSCORE Security Context [RFC8613]. The Responder can also send an optional EDHOC message_4 so the Initiator gets key confirmation, e.g., in deployments where no protected application message is sent from the Responder to the Initiator ๐ฆ
Appendix A.2 of [RFC9528] explains how to transfer EDHOC over CoAP ๐ง The EDHOC data (the EDHOC message, possibly with a prepended connection identifier) rides along in the payload of CoAP requests and responses. The default forward message flow has the CoAP client acting as Initiator and the CoAP server acting as Responder (see Appendix A.2.1 of [RFC9528]). Or you can flip the roles with the reverse message flow (see Appendix A.2.2 of [RFC9528]). For the rest of this document, EDHOC messages are considered to be transferred over CoAP ๐
Figure 1 shows a successful run of EDHOC, with a CoAP client and a CoAP server running EDHOC as Initiator and Responder, respectively. It's basically an upgraded Figure 10 from Appendix A.2.1 of [RFC9528] ๐ It highlights when the two peers do EDHOC verification and set up the OSCORE Security Context, and it adds a round of OSCORE-protected CoAP messages after EDHOC is done ๐
So here's the flow. The client sends a POST request to a reserved EDHOC resource at the server, by default at the Uri-Path /.well-known/edhoc. The request payload is the CBOR simple value true (0xf5) concatenated with EDHOC message_1, which also includes the EDHOC connection identifier C_I of the client, encoded as per Section 3.3 of [RFC9528]. The request has Content-Format application/cid-edhoc+cbor-seq ๐
That kicks off the EDHOC execution at the server, which replies with a 2.04 (Changed) response. The response payload is EDHOC message_2, which includes the EDHOC connection identifier C_R of the server, encoded as per Section 3.3 of [RFC9528]. The response has Content-Format application/edhoc+cbor-seq โจ
Finally, the client sends a POST request to that same EDHOC resource it used for message_1. The request payload is the EDHOC connection identifier C_R, encoded as per Section 3.3 of [RFC9528], concatenated with EDHOC message_3. The request has Content-Format application/cid-edhoc+cbor-seq ๐ซถ
Once this exchange happens, and after the verifications specified in the EDHOC protocol succeed, the client and server can derive an OSCORE Security Context as defined in Appendix A.1 of [RFC9528]. Then they can use OSCORE to protect their communications as per [RFC8613] ๐ฅ Heads up: the EDHOC connection identifier C_R is used as the OSCORE Sender ID of the client (see Appendix A.1 of [RFC9528]). So C_R gets transported in the 'kid' field of the OSCORE option of the OSCORE Request (see Section 6.1 of [RFC8613]) ๐
CoAP client CoAP server
(EDHOC Initiator) (EDHOC Responder)
| |
| |
| ----------------- EDHOC Request -----------------> |
| Header: 0.02 (POST) |
| Uri-Path: "/.well-known/edhoc" |
| Content-Format: application/cid-edhoc+cbor-seq |
| Payload: true, EDHOC message_1 |
| |
| <---------------- EDHOC Response------------------ |
| Header: 2.04 (Changed) |
| Content-Format: application/edhoc+cbor-seq |
| Payload: EDHOC message_2 |
| |
EDHOC verification |
| |
| ----------------- EDHOC Request -----------------> |
| Header: 0.02 (POST) |
| Uri-Path: "/.well-known/edhoc" |
| Content-Format: application/cid-edhoc+cbor-seq |
| Payload: C_R, EDHOC message_3 |
| |
| EDHOC verification
| +
| OSCORE Sec Ctx
| Derivation
| |
| <---------------- EDHOC Response------------------ |
| Header: 2.04 (Changed) |
| Content-Format: application/edhoc+cbor-seq |
| Payload: EDHOC message_4 |
| |
OSCORE Sec Ctx |
Derivation |
| |
| ---------------- OSCORE Request -----------------> |
| Header: 0.02 (POST) |
| OSCORE: { ... ; kid: C_R } |
| Payload: OSCORE-protected data |
| |
| <--------------- OSCORE Response ----------------- |
| Header: 2.04 (Changed) |
| OSCORE: { ... } |
| Payload: OSCORE-protected data |
| |
Figure 1: Sequential Flow of EDHOC and OSCORE with the Optional
message_4 Included
The sequential flow of EDHOC and OSCORE (where EDHOC runs first and OSCORE is used after) takes three round trips to complete, as shown in Figure 1 โณ
Section 3 defines an optimization for combining EDHOC with the first OSCORE transaction. This is the glow-up ๐ฆ It reduces the number of round trips required to set up an OSCORE Security Context and complete an OSCORE transaction using that Security Context โจ
3. EDHOC Combined with OSCORE ๐
okay so this section is about squishing the EDHOC handshake and the very first OSCORE transaction together ๐ so the two peers only need the absolute minimum of two round trips. no cap, that's the whole glow-up โจ
this only works if the default forward message flow of EDHOC is in use ๐ฆ so the client is the Initiator and the server is the Responder. with reversed roles (the reverse message flow of EDHOC) it's a no-go, sorry bestie ๐
when you're running the sequential flow from Section 2, the client already has everything it needs to derive the OSCORE Security Context right after receiving EDHOC message_2 and before sending EDHOC message_3 ๐ง so, lowkey, the client can send EDHOC message_3 and the follow-up OSCORE Request together. semantically that means two REST requests at once, as you can see in Figure 2 ๐
CoAP client CoAP server
(EDHOC Initiator) (EDHOC Responder)
| |
| ------------------ EDHOC Request -----------------> |
| Header: 0.02 (POST) |
| Uri-Path: "/.well-known/edhoc" |
| Content-Format: application/cid-edhoc+cbor-seq |
| Payload: true, EDHOC message_1 |
| |
| <----------------- EDHOC Response------------------ |
| Header: 2.04 (Changed) |
| Content-Format: application/edhoc+cbor-seq |
| Payload: EDHOC message_2 |
| |
EDHOC verification |
+ |
OSCORE Sec Ctx |
Derivation |
| |
| -------------- EDHOC + OSCORE Request ------------> |
| Header: 0.02 (POST) |
| OSCORE: { ... ; kid: C_R } |
| Payload: EDHOC message_3 + OSCORE-protected data |
| |
| EDHOC verification
| +
| OSCORE Sec Ctx
| Derivation
| |
| <--------------- OSCORE Response ------------------ |
| Header: 2.04 (Changed) |
| OSCORE: { ... } |
| Payload: OSCORE-protected data |
| |
Figure 2: EDHOC and OSCORE Combined
so the special approach here is to send one single EDHOC + OSCORE request ๐ธ carrying the pair (C_R, EDHOC message_3) inside one OSCORE-protected CoAP message. ๐
the EDHOC + OSCORE request is built from two parts, glued together into one CoAP message. the steps for processing it, and for the two parts inside it, live in Sections 3.2.1 and 3.3.1 ๐ซถ
- the OSCORE Request from Figure 1 ๐ in this case it's also aimed at a protected resource, with the right CoAP method and options for that resource.
- the EDHOC data, which is the pair (C_R, EDHOC message_3) needed to finish the EDHOC session, sent like this:
- C_R is the OSCORE Sender ID of the client, so it rides in the
kidfield of the OSCORE option (see Section 6.1 of [RFC8613]) ๐ unlike the sequential workflow in Figure 1, C_R does NOT go in the payload of the EDHOC + OSCORE request. - EDHOC message_3 goes in the payload and gets prepended to the OSCORE Request's payload ๐ why? because message_3 can be too big for a CoAP option, like when there's a big public key certificate chain in the ID_CRED_I field (see Section 3.5.3 of [RFC9528]), or a large External Authorization Data in the EAD_3 field (see Section 3.8 of [RFC9528]) ๐ญ
- C_R is the OSCORE Sender ID of the client, so it rides in the
the rest of this section explains how to carry this data in the EDHOC + OSCORE request and what order to process it in. the signal that this approach is in use is the EDHOC option (Section 3.1) included in the request โจ the client side processing is in Section 3.2, and the server side is in Section 3.3.
3.1. EDHOC Option
okay this section defines the EDHOC option ๐ฆ a CoAP request uses it to say "hey, my payload carries both an EDHOC message_3 AND OSCORE-protected data, all mixed together" ๐
the EDHOC option has the properties in Table 1, which extends Table 4 of [RFC7252]. it's Critical, Safe-to-Forward, and part of the Cache-Key. it MUST occur at most once and MUST be empty. if any value does get sent, the recipient MUST ignore it. (future documents might update the definition by expanding its semantics and specifying admitted values.) the option is only meant for CoAP requests and it's Class U for OSCORE [RFC8613] ๐ธ
+=====+===+===+===+===+=======+========+========+=========+
| No. | C | U | N | R | Name | Format | Length | Default |
+=====+===+===+===+===+=======+========+========+=========+
| 21 | x | | | | EDHOC | Empty | 0 | (none) |
+-----+---+---+---+---+-------+--------+--------+---------+
Table 1: The EDHOC Option. C=Critical, U=Unsafe,
N=NoCacheKey, R=Repeatable
so if the EDHOC option is present, the message payload also holds EDHOC data ๐ง that has to be pulled out and processed as Section 3.3 says BEFORE the rest of the message gets processed. order matters, bestie ๐
Figure 3 shows an example CoAP message over UDP that has both the EDHOC data and the OSCORE ciphertext, signalled with the new EDHOC option ๐
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Ver| T | TKL | Code | Message ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Token (if any, TKL bytes) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Observe Option| OSCORE Option ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EDHOC Option | Other Options (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| Payload ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 3: Example of a CoAP Message Containing the Combined EDHOC
and OSCORE Data, Signalled by the EDHOC Option and Transported
over UDP
3.2. Client Processing
this section covers what the client does ๐
3.2.1. Processing of the EDHOC + OSCORE Request
okay, so the client builds an EDHOC + OSCORE request in these steps ๐ฆ
Step 1. Compose EDHOC message_3 into EDHOC_MSG_3 as per Section 5.4.2 of [RFC9528] ๐ธ
Step 2. Establish the new OSCORE Security Context and use it to encrypt the original CoAP request as per Section 8.1 of [RFC8613] ๐ง
Note that the OSCORE ciphertext is NOT computed over EDHOC message_3, because message_3 isn't protected by OSCORE. so the result of this step is just the OSCORE Request from Figure 1 ๐
Step 3. Build COMB_PAYLOAD as the concatenation of EDHOC_MSG_3 and OSCORE_PAYLOAD, in the order COMB_PAYLOAD = EDHOC_MSG_3 | OSCORE_PAYLOAD, where | means byte string concatenation and:
- EDHOC_MSG_3 is the binary encoding of EDHOC message_3 from Step 1. per Section 5.4.1 of [RFC9528], EDHOC message_3 is one CBOR data item CIPHERTEXT_3, which is a CBOR byte string. so EDHOC_MSG_3 is the binary encoding of CIPHERTEXT_3 ๐
- OSCORE_PAYLOAD is the OSCORE ciphertext of the OSCORE-protected CoAP request from Step 2 ๐
Step 4. Compose the EDHOC + OSCORE request: it's the OSCORE-protected CoAP request from Step 2, but with the payload swapped for COMB_PAYLOAD from Step 3 โจ
Note that the new payload includes EDHOC message_3 but NOT the EDHOC connection identifier C_R. since the client is the EDHOC Initiator, C_R is the OSCORE Sender ID of the client, which is already the value of thekidfield in the OSCORE option of the Step 2 request. so C_R becomes the value of thekidfield of the EDHOC + OSCORE request ๐ซถ
Step 5. Include the new EDHOC option from Section 3.1 in the EDHOC + OSCORE request ๐
The application/cid-edhoc+cbor-seq media type does NOT apply to this message, whose media type is unnamed. ๐ญ
Step 6. Send the EDHOC + OSCORE request to the server ๐
with the same server, the client SHOULD NOT have multiple simultaneous outstanding interactions (see Section 4.7 of [RFC7252]) where they consist of an EDHOC + OSCORE request and their EDHOC data pertains to the EDHOC session with the same connection identifier C_R ๐
there's an exception, though ๐ clients running under particular time constraints over particularly unreliable networks might want to finish EDHOC fast by sending multiple simultaneous EDHOC + OSCORE requests. Section 7 talks about it, and it has no impact on security โจ
3.2.2. Supporting Block-Wise Transfers ๐
okay so bestie, if Block-wise transfers [RFC7959] are supported, the client is allowed to chop up the first CoAP application request into blocks ๐งฉ, and then each block gets protected as an original message with OSCORE, as defined in Section 4.1.3.4.1 of [RFC8613]. the way that's giving main character energy ๐
so the OSCORE processing in Step 2 of Section 3.2.1 happens on each inner block of that first request โจ. and there's some extra stuff that goes on too ๐
- the client gets an additional step between Steps 2 and 3 of Section 3.2.1 ๐
Step 2.1. if the OSCORE-protected request from Step 2 is carrying a non-first inner block of the first CoAP application request (aka the Block1 option processed at Step 2 had NUM different than 0), then the client skips the following steps and sends the OSCORE-protected request to the server ๐. and the big deal here is that the client MUST NOT include the EDHOC option in that OSCORE-protected request ๐ โโ๏ธ. no EDHOC option, no cap!
- the client also gets an additional step between Steps 3 and 4 of Section 3.2.1 ๐ธ
Step 3.1. if the size of COMB_PAYLOAD goes over MAX_UNFRAGMENTED_SIZE (see Section 4.1.3.4.2 of [RFC8613]), the client MUST stop processing the request and MUST abandon the Block-wise transfer ๐ญ. then it can keep going by switching over to the sequential workflow shown in Figure 1 ๐ฆ. so the client first sends EDHOC message_3 prepended by the EDHOC connection identifier C_R, encoded as per Section 3.3 of [RFC9528] ๐ง. then it sends the OSCORE-protected CoAP request once the EDHOC execution is completed ๐ซถ.
ngl the performance perks of the EDHOC + OSCORE request can get lost when you combine it with Block-wise transfers that rely on specific parameter values and block sizes ๐. the application policies at the CoAP client get to decide when and how to detect that the perk is gone ๐. and if that happens, they can also decide whether to tweak the parameter values and block sizes, or just fall back to the sequential workflow of EDHOC ๐.
3.3. Server Processing ๐
okay the server side, let's gooo ๐ฅ. this section is all about what the server does.
3.3.1. Processing of the EDHOC + OSCORE Request โจ
so to process a request that has the EDHOC option (aka an EDHOC + OSCORE request), the server MUST perform the following steps ๐ .
Step 1. Check that the EDHOC + OSCORE request includes the OSCORE option and that the request payload has the format defined at Step 3 of Section 3.2.1 for COMB_PAYLOAD ๐. if that's NOT the case, the server MUST stop processing the request and MUST reply with a 4.00 (Bad Request) error response ๐ โโ๏ธ.
Step 2. Pull EDHOC message_3 out of the COMB_PAYLOAD payload of the EDHOC + OSCORE request, as the first element EDHOC_MSG_3 (see Step 3 of Section 3.2.1) ๐งฉ.
Step 3. Grab the value of the 'kid' field from the OSCORE option of the EDHOC + OSCORE request (that's the OSCORE Sender ID of the client) and use it as the EDHOC connection identifier C_R ๐ฆ.
Step 4. Retrieve the correct EDHOC session using the connection identifier C_R from Step 3 ๐.
If the application profile used in the EDHOC session says that EDHOC message_4 shall be sent, the server MUST stop the EDHOC processing and consider it failed due to a client error ๐.
Otherwise, do the EDHOC processing on the EDHOC message_3 extracted at Step 2, as per Section 5.4.3 of [RFC9528], based on the protocol state of the retrieved EDHOC session ๐ธ.
The application profile used in the EDHOC session is the same one associated with the EDHOC resource where the server got the request carrying EDHOC message_1 that started the session ๐. this matters if the server has multiple EDHOC resources that might refer to different application profiles ๐.
Step 5. Establish a new OSCORE Security Context associated with the client, as per Appendix A.1 of [RFC9528], using the EDHOC output from Step 4 ๐.
Step 6. Extract the OSCORE ciphertext from the COMB_PAYLOAD payload of the EDHOC + OSCORE request as the second element OSCORE_PAYLOAD (see Step 3 of Section 3.2.1) ๐ง.
Step 7. Rebuild the OSCORE-protected CoAP request as the EDHOC + OSCORE request, where the payload is replaced with the OSCORE ciphertext extracted at Step 6 ๐ง. then remove the EDHOC option ๐๏ธ.
Step 8. Decrypt and verify the OSCORE-protected CoAP request rebuilt at Step 7, as per Section 8.2 of [RFC8613], using the OSCORE Security Context established at Step 5 ๐.
When the decrypted request gets checked for any critical CoAP options (like it does during regular CoAP processing), the presence of an EDHOC option MUST be regarded as an unprocessed critical option, unless some further mechanism processes it ๐จ.
Step 9. Deliver the CoAP request resulting from Step 8 to the application ๐.
if Steps 4 (EDHOC processing) and 8 (OSCORE processing) are both successfully completed, the server MUST reply with an OSCORE-protected response (see Section 5.4.3 of [RFC9528]) ๐. the usage of EDHOC message_4 defined in Section 5.5 of [RFC9528] is NOT applicable to the approach in this document ๐.
if Step 4 (EDHOC processing) fails, the server aborts the session as per Section 5.4.3 of [RFC9528] and responds with an EDHOC error message with error code 1, formatted as defined in Section 6.2 of [RFC9528] ๐ญ. the server MUST NOT establish a new OSCORE Security Context from the present EDHOC session with the client ๐ โโ๏ธ. the CoAP response carrying the EDHOC error message is NOT protected with OSCORE ๐. as per Section 9.5 of [RFC9528], the server has to make sure the error message does not reveal sensitive information ๐คซ. and the CoAP response carrying the EDHOC error message MUST have Content-Format set to application/edhoc+cbor-seq, registered in Section 10.9 of [RFC9528] ๐.
if Step 4 (EDHOC processing) is successfully completed but Step 8 (OSCORE processing) fails, the same OSCORE error handling as defined in Section 8.2 of [RFC8613] applies ๐งฏ.
3.3.2. Supporting Block-Wise Transfers ๐งธ
if Block-wise transfers [RFC7959] are supported, the server takes the additional step below, before any other step in Section 3.3.1 ๐ช.
Step 0. If a Block option is present in the request, process the Outer Block options according to [RFC7959] until all blocks of the request have been received (see Section 4.1.3.4 of [RFC8613]) ๐ฆ.
3.4. Example of the EDHOC + OSCORE Request ๐ท
Figure 4 shows an example of an EDHOC + OSCORE request transported over UDP ๐ฆ. in particular, the example assumes that:
- The OSCORE Partial IV in use is 0, consistent with the first request protected with the new OSCORE Security Context ๐.
- The OSCORE Sender ID of the client is 0x01 ๐.
As per Section 3.3.3 of [RFC9528], this straightforwardly corresponds to the EDHOC connection identifier C_R 0x01 ๐.
As per Section 3.3.2 of [RFC9528], when using the sequential flow shown in Figure 1, the same C_R with a value of 0x01 would be encoded on the wire as the CBOR integer 1 (0x01 in CBOR encoding) and prepended to EDHOC message_3 in the payload of the second EDHOC request ๐ง.
this results in the following components shown in Figure 4 โจ:
OSCORE option value: 0x090001 (3 bytes)
EDHOC option value: - (0 bytes)
EDHOC message_3: 0x52d5535f3147e85f1cfacd9e78abf9e0a81bbf (19 bytes)
OSCORE ciphertext: 0x612f1092f1776f1c1668b3825e (13 bytes)
0x44025d1f ; CoAP 4-byte Header
00003974 ; Token
93 090001 ; OSCORE Option
c0 ; EDHOC Option
ff 52d5535f3147e85f1cfacd9e78abf9e0a81bbf
612f1092f1776f1c1668b3825e
(46 bytes)
Figure 4: Example of a Protected CoAP Request Combining EDHOC and OSCORE Data ๐
4. Use of EDHOC Connection Identifiers with OSCORE ๐
the OSCORE Sender/Recipient IDs are the EDHOC connection identifiers (see Section 3.3.3 of [RFC9528]) ๐ซถ. this applies to the optimized workflow defined in Section 3 of this document too โจ.
note that the value of the 'kid' field in the OSCORE option of the EDHOC + OSCORE request is BOTH the server's Recipient ID (aka the client's Sender ID) AND the EDHOC connection identifier C_R of the server at Step 3 of Section 3.3.1 ๐.
4.1. Additional Processing of EDHOC Messages ๐ฆ
when using EDHOC to establish an OSCORE Security Context, the client and server MUST perform the following additional steps during an EDHOC execution, extending Section 5 of [RFC9528] ๐ฅ.
4.1.1. Initiator Processing of Message 1 ๐ธ
the Initiator picks an EDHOC connection identifier C_I like this ๐งฉ.
the Initiator MUST choose a C_I that is NOT used in any current EDHOC session as this peer's EDHOC connection identifier, and NOT the Recipient ID in a current OSCORE Security Context where the ID Context is not present ๐ โโ๏ธ.
the chosen C_I SHOULD NOT be the Recipient ID of any current OSCORE Security Context ๐. ngl this is the bit that lets the Responder always omit the 'kid context' in the OSCORE option of its messages sent to the Initiator, when protecting those with an OSCORE Security Context where C_I is the Responder's OSCORE Sender ID, unless the two peers concurrently use alternative methods to establish OSCORE Security Contexts (see Section 6.1 of [RFC8613]) ๐ .
4.1.2. Responder Processing of Message 2 ๐ง
the Responder picks an EDHOC connection identifier C_R like this ๐ท.
the Responder MUST choose a C_R that is none of the following ๐:
- used in any current EDHOC session as this peer's EDHOC connection identifier,
- equal to the EDHOC connection identifier C_I specified in the EDHOC message_1 of the present EDHOC session, or
- the Recipient ID in a current OSCORE Security Context where the ID Context is not present.
the chosen C_R SHOULD NOT be the Recipient ID of any current OSCORE Security Context ๐. for a reason similar to the one in Section 4.1.1 with C_I, this lets the Initiator always omit the 'kid context' in the OSCORE option of its messages sent to the Responder, when protecting those with an OSCORE Security Context where C_R is the Initiator's OSCORE Sender ID (see Section 6.1 of [RFC8613]) ๐ฆ.
4.1.3. Initiator Processing of Message 2 ๐
if the EDHOC connection identifier C_I is equal to the EDHOC connection identifier C_R specified in EDHOC message_2, then the Initiator MUST abort the session and reply with an EDHOC error message with error code 1, formatted as defined in Section 6.2 of [RFC9528] ๐จ.
5. Extension and Consistency of Application Profiles โจ
Okay so, bestie, an application profile can carry this extra info, and the client and server both check it against some consistency rules. ๐
If the server supports the EDHOC + OSCORE request inside an EDHOC execution that started at a certain EDHOC resource, then the application profile for that resource SHOULD explicitly say it supports the EDHOC + OSCORE request. ๐
Now, if the application profile says the server supports the optional EDHOC message_4 (see Section 5.5 of [RFC9528]), the optimized workflow based on the EDHOC + OSCORE request is still on the table. ๐ฆ The catch is that the server is not going to send EDHOC message_4, because it doesn't apply to the optimized workflow (see Section 3.3.1). ๐ฅบ
And if the application profile says the server shall send EDHOC message_4, then the application profile MUST NOT specify support for the EDHOC + OSCORE request. ๐ Like, why would the client even try the optimized workflow when it's going to bomb? No point, periodt. ๐ (see Section 3.3.1)
6. Web Linking ๐ธ
Section 10.10 of [RFC9528] registers the resource type "core.edhoc". ๐ง You can use it as a target attribute in a web link [RFC8288] pointing to an EDHOC resource, for example with a link-format document [RFC6690]. This is how clients find out that EDHOC resources exist on a server, and they can even filter on the resource type. ๐
The application profile tied to an EDHOC resource tells you how EDHOC can be used through that resource. A client can learn about the profile, for example by grabbing its info elements when it discovers the EDHOC resources on the server. ๐ฅ That means the client can find the EDHOC resources whose profile fits it best, like ones with EDHOC cipher suites or authentication methods the client also supports or prefers. It's giving main character energy. โจ
So basically, while a client is discovering an EDHOC resource, it can grab relevant info from that resource's application profile at the same time. Discovery can happen through direct interaction with the server, or through the CoRE Resource Directory [RFC9176], where the server may have registered links to its resources. ๐
To make all this work, this section defines a bunch of parameters. Each one can optionally show up as a target attribute with the same name in the link to the EDHOC resource, or as a filter criterion in the client's discovery request. When you put these parameters in a link to an EDHOC resource, the target attribute rt="core.edhoc" MUST be included, and the same consistency rules from Section 5 for the matching application profile info elements MUST be followed. ๐
Here are the parameters:
'ed-i': If present, this says the server supports the EDHOC Initiator role, which is the reverse message flow of EDHOC. ๐ A value MUST NOT be given to this parameter, and any present value MUST be ignored by the recipient. ๐
'ed-r': If present, this says the server supports the EDHOC Responder role, which is the forward message flow of EDHOC. โก๏ธ A value MUST NOT be given to this parameter, and any present value MUST be ignored by the recipient. ๐
'ed-method': This specifies an authentication method the server supports. This parameter MUST specify a single value, taken from the 'Value' column of the "EDHOC Method Type" registry defined in Section 10.3 of [RFC9528]. ๐ It MAY occur multiple times, with each occurrence specifying one authentication method.
'ed-csuite': This specifies an EDHOC cipher suite the server supports. This parameter MUST specify a single value, taken from the 'Value' column of the "EDHOC Cipher Suites" registry defined in Section 10.2 of [RFC9528]. ๐ง It MAY occur multiple times, with each occurrence specifying a cipher suite.
'ed-cred-t': This specifies a type of authentication credential the server supports. This parameter MUST specify a single value, taken from the 'Value' column of the "EDHOC Authentication Credential Types" Registry defined in Section 8.3 of this document. ๐ It MAY occur multiple times, with each occurrence specifying a type of authentication credential.
'ed-idcred-t': This specifies a type of identifier the server supports for identifying authentication credentials. This parameter MUST specify a single value, taken from the 'Label' column of the "COSE Header Parameters" registry [COSE.Header.Parameters]. ๐ท๏ธ It MAY occur multiple times, with each occurrence specifying a type of identifier for authentication credentials.
Note that the values in the 'Label' column of the "COSE Header Parameters" registry are strongly typed. ๐ง CoRE Link Format, on the other hand, is weakly typed, so it doesn't tell apart things like the string value "-10" and the integer value -10. ๐ตโ๐ซ So if responses come back in CoRE Link Format, string values that look like an integer are not supported. Because of that, such values MUST NOT be used in the 'ed-idcred-t' parameter. ๐ซ
'ed-ead': This specifies the server's support for an External Authorization Data (EAD) item (see Section 3.8 of [RFC9528]). ๐ซ This parameter MUST specify a single value, taken from the 'Label' column of the "EDHOC External Authorization Data" registry defined in Section 10.5 of [RFC9528]. It MAY occur multiple times, with each occurrence specifying the ead_label of an EAD item the server supports.
'ed-comb-req': If present, this says the server supports the EDHOC + OSCORE request defined in Section 3. ๐ A value MUST NOT be given to this parameter, and any present value MUST be ignored by the recipient. ๐
Future documents may update the definition of 'ed-i', 'ed-r', and 'ed-comb-req' by expanding their semantics and specifying what values they can take. ๐ฎ
Figure 5 shows how a client discovers one EDHOC resource at a server and grabs info elements from the matching application profile. The CoRE Link Format notation from Section 5 of [RFC6690] is used. ๐
REQ: GET /.well-known/core
RES: 2.05 Content
</sensors/temp>;osc,
</sensors/light>;if=sensor,
</.well-known/edhoc>;rt=core.edhoc;ed-csuite=0;ed-csuite=2;
ed-method=0;ed-cred-t=0;ed-cred-t=1;ed-idcred-t=4;
ed-i;ed-r;ed-comb-req
Figure 5: The Web Link
7. Security Considerations ๐
The same security considerations from OSCORE [RFC8613] and EDHOC [RFC9528] hold for this document. โจ On top of that, the following considerations apply. ๐
Section 3.2.1 specifies that a client SHOULD NOT have multiple outstanding EDHOC + OSCORE requests pertaining to the same EDHOC session. ๐ฌ Even if a client didn't follow this, it wouldn't affect security. The server would still refuse to process different instances of the same EDHOC message_3 more than once in the same EDHOC session (see Section 5.1 of [RFC9528]), and it would still enforce replay protection of the OSCORE-protected request (see Sections 7.4 and 8.2 of [RFC8613]). ๐ก๏ธ
When using the optimized workflow in Figure 2, a minimum of 128-bit security against online brute-force attacks is achieved after the client receives and successfully verifies the first OSCORE-protected response (see Sections 9.1 and 9.4 of [RFC9528]). ๐ฅ For example, if EDHOC is used with method 3 (see Section 3.2 of [RFC9528]) and cipher suite 2 (see Section 3.6 of [RFC9528]), then the following holds:
- The Initiator is authenticated with 128-bit security against online attacks. ๐ As per Section 9.1 of [RFC9528], this comes from combining the strength of the 64-bit Message Authentication Code (MAC) in EDHOC message_3 with the 64-bit MAC in the Authenticated Encryption with Associated Data (AEAD) of the first OSCORE-protected CoAP request as rebuilt at Step 7 of Section 3.3.1.
- The Responder is authenticated with 128-bit security against online attacks. ๐ As per Section 9.1 of [RFC9528], this comes from combining the strength of the 64-bit MAC in EDHOC message_2 with the 64-bit MAC in the AEAD of the first OSCORE-protected CoAP response.
With reference to the sequential workflow in Figure 1, the OSCORE request might have to go through access-control checks at the server before it's actually executed to access the target protected resource. ๐ช The same MUST hold when the optimized workflow in Figure 2 is used, i.e., when using the EDHOC + OSCORE request.
That is, the rebuilt OSCORE-protected application request from Step 7 in Section 3.3.1 MUST undergo the same access-control checks that would be performed on a traditional OSCORE-protected application request sent individually as shown in Figure 1. ๐ซถ
To make that happen, validated info for access-control checks (for example, an access token issued by a trusted party) has to be available at the server before it starts processing the rebuilt OSCORE-protected application request. ๐๏ธ That info may have been provided to the server separately, before the EDHOC execution even started, or it may come as External Authorization Data during the EDHOC execution (see Section 3.8 of [RFC9528]).
So, a successful completion of the EDHOC protocol and the following derivation of the OSCORE Security Context at the server do not play a role in deciding whether the rebuilt OSCORE-protected request is authorized to access the target protected resource at the server. ๐ โโ๏ธ Not the vibe, lowkey a big deal. โ ๏ธ
8. IANA Considerations ๐
This document has the following actions for IANA. ๐งพ
8.1. CoAP Option Numbers Registry ๐
IANA has registered the following option number in the "CoAP Option Numbers" registry within the "Constrained RESTful Environments (CoRE) Parameters" registry group. ๐
+========+=======+===========+
| Number | Name | Reference |
+========+=======+===========+
| 21 | EDHOC | RFC 9668 |
+--------+-------+-----------+
Table 2: Registration in
the "CoAP Option Numbers"
Registry
8.2. Target Attributes Registry ๐
okay so IANA registered these entries in the "Target Attributes" registry [CORE.Target.Attributes] inside the "Constrained RESTful Environments (CoRE) Parameters" registry group, as per [RFC9423] ๐ . For every entry, the Change Controller is IETF and the reference is RFC 9668. slay ๐ซถ
+================+=============================================+
| Attribute Name | Brief Description |
+================+=============================================+
| ed-i | Hint: support for the EDHOC Initiator role |
+----------------+---------------------------------------------+
| ed-r | Hint: support for the EDHOC Responder role |
+----------------+---------------------------------------------+
| ed-method | A supported authentication method for EDHOC |
+----------------+---------------------------------------------+
| ed-csuite | A supported cipher suite for EDHOC |
+----------------+---------------------------------------------+
| ed-cred-t | A supported type of authentication |
| | credential for EDHOC |
+----------------+---------------------------------------------+
| ed-idcred-t | A supported type of authentication |
| | credential identifier for EDHOC |
+----------------+---------------------------------------------+
| ed-ead | A supported External Authorization Data |
| | (EAD) item for EDHOC |
+----------------+---------------------------------------------+
| ed-comb-req | Hint: support for the EDHOC + OSCORE |
| | request |
+----------------+---------------------------------------------+
Table 3: Registrations in the "Target Attributes" Registry
8.3. EDHOC Authentication Credential Types Registry โจ
bestie, IANA made the "EDHOC Authentication Credential Types" registry inside the "Ephemeral Diffie-Hellman Over COSE (EDHOC)" registry group, which is defined in [RFC9528] ๐ง
The registration policy is either "Private Use", "Standards Action with Expert Review", or "Specification Required" per [RFC8126]. "Expert Review" guidelines are provided in Section 8.4.
All assignments according to "Standards Action with Expert Review" are made on a "Standards Action" basis per Section 4.9 of [RFC8126], with "Expert Review" additionally required per Section 4.5 of [RFC8126]. The procedure for early IANA allocation of "standards track code points" defined in [RFC7120] also applies. When that procedure is used, IANA will ask the designated expert(s) to approve the early allocation before registration. In addition, working group chairs are encouraged to consult the expert(s) early during the process outlined in Section 3.1 of [RFC7120] ๐ธ
The columns of this registry are:
- Value: This field contains the value used to identify the type of authentication credential. These values MUST be unique. The value can be an unsigned integer or a negative integer. Different ranges of values use different registration policies:
- Integer values from -24 to 23 are designated as "Standards Action With Expert Review".
- Integer values from -65536 to -25 and from 24 to 65535 are designated as "Specification Required".
- Integer values smaller than -65536 and greater than 65535 are marked as "Private Use".
- Description: This field contains a short description of the type of authentication credential.
- Reference: This field contains a pointer to the public specification for the type of authentication credential.
+=======+============================================+===========+
| Value | Description | Reference |
+=======+============================================+===========+
| 0 | CBOR Web Token (CWT) containing a COSE_Key | [RFC8392] |
| | in a 'cnf' claim and possibly other | |
| | claims. CWT is defined in RFC 8392. | |
+-------+--------------------------------------------+-----------+
| 1 | CWT Claims Set (CCS) containing a COSE_Key | [RFC8392] |
| | in a 'cnf' claim and possibly other | |
| | claims. CCS is defined in RFC 8392. | |
+-------+--------------------------------------------+-----------+
| 2 | X.509 certificate | [RFC5280] |
+-------+--------------------------------------------+-----------+
Table 4: Initial Entries in the "EDHOC Authentication
Credential Types" Registry
8.4. Expert Review Instructions ๐
"Standards Action with Expert Review" and "Specification Required" are two of the registration policies defined for the IANA registry established in Section 8.3. This section gives some general guidelines for what the experts should be looking for. However, they are being designated as experts for a reason, so they should be given substantial latitude ๐
Expert reviewers should take into consideration the following points:
- Clarity and correctness of registrations. Experts are expected to check the clarity of purpose and use of the requested entries. Experts need to make sure that registered identifiers indicate a type of authentication credential whose format and encoding is clearly defined in the corresponding specification. Identifiers of types of authentication credentials that do not meet these objectives of clarity and completeness must not be registered.
- Point squatting should be discouraged. Reviewers are encouraged to get sufficient information for registration requests to ensure that the usage is not going to duplicate one that is already registered and that the point is likely to be used in deployments. The zones tagged as "Private Use" are intended for testing purposes and closed environments. Code points in other ranges should not be assigned for testing.
- Specifications are required for the "Standards Action With Expert Review" range of point assignment. Specifications should exist for "Specification Required" ranges, but early assignment before a specification is available is considered to be permissible. When specifications are not provided, the description provided needs to have sufficient information to identify what the point is being used for.
- Experts should take into account the expected usage of fields when approving point assignment. Documents published via Standards Action can also register points outside the Standards Action range. The length of the encoded value should be weighed against how many code points of that length are left, the size of device it will be used on, and the number of code points left that encode to that size. ๐งฎ
9. References ๐
9.1. Normative References
[CORE.Target.Attributes] IANA, "Target Attributes", <https://www.iana.org/assignments/core-parameters>.
[COSE.Header.Parameters] IANA, "COSE Header Parameters", <https://www.iana.org/assignments/cose>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
[RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008, <https://www.rfc-editor.org/info/rfc5280>.
[RFC6690] Shelby, Z., "Constrained RESTful Environments (CoRE) Link Format", RFC 6690, DOI 10.17487/RFC6690, August 2012, <https://www.rfc-editor.org/info/rfc6690>.
[RFC7120] Cotton, M., "Early IANA Allocation of Standards Track Code Points", BCP 100, RFC 7120, DOI 10.17487/RFC7120, January 2014, <https://www.rfc-editor.org/info/rfc7120>.
[RFC7252] Shelby, Z., Hartke, K., and C. Bormann, "The Constrained Application Protocol (CoAP)", RFC 7252, DOI 10.17487/RFC7252, June 2014, <https://www.rfc-editor.org/info/rfc7252>.
[RFC7959] Bormann, C. and Z. Shelby, Ed., "Block-Wise Transfers in the Constrained Application Protocol (CoAP)", RFC 7959, DOI 10.17487/RFC7959, August 2016, <https://www.rfc-editor.org/info/rfc7959>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8288] Nottingham, M., "Web Linking", RFC 8288, DOI 10.17487/RFC8288, October 2017, <https://www.rfc-editor.org/info/rfc8288>.
[RFC8392] Jones, M., Wahlstroem, E., Erdtman, S., and H. Tschofenig, "CBOR Web Token (CWT)", RFC 8392, DOI 10.17487/RFC8392, May 2018, <https://www.rfc-editor.org/info/rfc8392>.
[RFC8613] Selander, G., Mattsson, J., Palombini, F., and L. Seitz, "Object Security for Constrained RESTful Environments (OSCORE)", RFC 8613, DOI 10.17487/RFC8613, July 2019, <https://www.rfc-editor.org/info/rfc8613>.
[RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, <https://www.rfc-editor.org/info/rfc8949>.
[RFC9176] Amsรผss, C., Ed., Shelby, Z., Koster, M., Bormann, C., and P. van der Stok, "Constrained RESTful Environments (CoRE) Resource Directory", RFC 9176, DOI 10.17487/RFC9176, April 2022, <https://www.rfc-editor.org/info/rfc9176>.
[RFC9528] Selander, G., Preuร Mattsson, J., and F. Palombini, "Ephemeral Diffie-Hellman Over COSE (EDHOC)", RFC 9528, DOI 10.17487/RFC9528, March 2024, <https://www.rfc-editor.org/info/rfc9528>.
9.2. Informative References
[RFC9423] Bormann, C., "Constrained RESTful Environments (CoRE) Target Attributes Registry", RFC 9423, DOI 10.17487/RFC9423, April 2024, <https://www.rfc-editor.org/info/rfc9423>.
Acknowledgments ๐ซถ
The authors sincerely thank Christian Amsรผss, Emmanuel Baccelli, Carsten Bormann, Roman Danyliw, Esko Dijk, Joel Halpern, Wes Hardaker, Klaus Hartke, John Preuร Mattsson, David Navarro, Shuping Peng, Jim Schaad, Jรผrgen Schรถnwรคlder, John Scudder, Orie Steele, Gunter Van de Velde, Maliลกa Vuฤiniฤ, and Paul Wouters for their feedback and comments.
The work on this document has been partly supported by the Sweden's Innovation Agency VINNOVA and the Celtic-Next project CRITISEC, and by the H2020 project SIFIS-Home (Grant agreement 952652). ๐
Authors' Addresses โจ
okay bestie, this is the last stop ๐ the squad behind RFC 9668, all five of them, with where to find each one ๐ซถ
Francesca Palombini is at Ericsson AB ๐ฆ
Francesca Palombini
Ericsson AB
Torshamnsgatan 23
SE-164 40 Kista
Sweden
Email: francesca.palombini@ericsson.com
Marco Tiloca is at RISE AB ๐ธ
Marco Tiloca
RISE AB
Isafjordsgatan 22
SE-164 40 Kista
Sweden
Email: marco.tiloca@ri.se
Rikard Hรถglund is also at RISE AB, same building, same street address ๐ง
Rikard Hรถglund
RISE AB
Isafjordsgatan 22
SE-164 40 Kista
Sweden
Email: rikard.hoglund@ri.se
Stefan Hristozov is at Eriptic, and the listing only gives an email for him ๐
Stefan Hristozov
Eriptic
Email: stefan.hristozov@eriptic.com
Gรถran Selander is at Ericsson ๐
Gรถran Selander
Ericsson
Email: goran.selander@ericsson.com
That's the whole crew, periodt ๐ โจ
๐ฆ where this page comes from
- ietf: rfc9668 2024-11
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms