RFC 8824
Static Context Header Compression (SCHC) for the Constrained Application Protocol (CoAP)
๐ RFC 8824: SCHC for CoAP, bestie!! ๐ฆ
Okay so babe, this one is Standards Track ๐ , which means it's an official Internet Standard and not just a vibe. It was written by A. Minaburo (Acklio), L. Toutain (IMT Atlantique), and R. Andreasen (Universidad de Buenos Aires) ๐ธ, and it was published in June 2021 ๐. It's an ISSN 2070-1721 document, and it doesn't obsolete or update any other RFCs, so it's a fresh start, no drama ๐ซถ.
The whole point? Shrinking CoAP headers so they can fit on tiny LPWAN devices ๐โจ. It builds on the SCHC framework from [RFC8724] and applies it to CoAP's flexible, variable-length headers. Ngl, the way it leans into CoAP's request/response asymmetry to make tighter Rules is kind of iconic ๐ง.
1. Introduction โจ
Okay so, CoAP [RFC7252] is a command/response protocol built for microcontrollers with tiny RAM and ROM, and it's designed around REST services ๐. The thing is, even though Constrained Devices were the main focus when CoAP was designed, a CoAP header is still too chunky for LPWANs (Low-Power Wide-Area Networks) ๐ญ. So applying Static Context Header Compression and fragmentation (SCHC) to CoAP headers is required if you want better performance or want to run CoAP over LPWAN tech ๐.
[RFC8724] is where the SCHC framework lives ๐ฆ. It has a header compression mechanism for LPWANs that runs on a static context. Section 5 of [RFC8724] explains where compression and decompression happen in the architecture ๐. Bestie, the big prerequisite is that both endpoints have to know the static context before anything gets sent ๐ซถ. How that context gets configured, provisioned, or exchanged is not this doc's job, so it's out of scope ๐.
CoAP is an application protocol, so CoAP compression means installing common Rules between the two SCHC instances ๐ . SCHC compression can happen at two levels: at IP and UDP in the LPWAN, and separately at the application level for CoAP ๐ธ. These two techniques can be independent, and they both follow the same principle described in [RFC8724] โจ. Different entities handle CoAP compression at different levels, so the SCHC Rules driving compression and decompression are different too ๐. [RFC8724] covers IP and UDP headers, and this document is the one that explains how to apply SCHC compression to CoAP headers ๐.
SCHC compresses and decompresses headers using contexts shared between Devices ๐ง. The SCHC context holds multiple Rules, and each Rule can match header fields to specific values or ranges of values ๐. If a Rule matches, the matched header fields get replaced by the RuleID plus the Compression Residue, which holds the leftover bits from compression ๐ฅ. So different Rules can correspond to different protocol headers in the packets a Device expects to send or receive ๐.
A Rule describes the packet's entire header as an ordered list of Field Descriptors, see Section 7 of [RFC8724] ๐. Each description has the Field ID (FID), Field Length (FL), and Field Position (FP), plus a Direction Indicator (DI) (upstream, downstream, or bidirectional) and some associated Target Values (TVs) ๐ . The DI is used during compression to pick the best TV for the FID when those values differ by transmission direction, so yes, a field can be described more than once ๐ฆ.
Each header Field Descriptor is paired with a Matching Operator (MO) ๐ธ. The Rule gets selected if all the MOs fit the TVs for all the fields in the incoming header ๐ซถ. A Rule cannot be selected if the message has a field the SCHC compressor doesn't know about ๐.
When that happens, a Compression/Decompression Action (CDA) tied to each field tells the compressor how to compress and decompress that field ๐. Compression mostly comes down to one of four actions ๐:
- send the field value (value-sent),
- send nothing (not-sent),
- send some Least Significant Bits (LSBs) of the field, or
- send an index (mapping-sent).
After compression there may still be some bits to send, and these are called "Compression Residue" ๐.
SCHC is a general mechanism used with different protocols, and the exact Rules depend on the protocol and the application ๐. Section 10 of [RFC8724] describes the compression scheme for IPv6 and UDP headers, and this document is the one targeting CoAP header compression with SCHC โจ.
1.1. Terminology ๐
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here ๐. Bestie, that capitals rule is important, so only the all-caps versions count as the real deal ๐.
Part 1 of 7 is done, bestie! ๐ฆ Say "next" and I'll keep going with Section 2 ๐ซถ๐
2. SCHC Applicability to CoAP โจ
Okay so, SCHC compression for CoAP headers MAY be done alongside the lower layers (IPv6/UDP) or totally on its own ๐ซถ. The SCHC adaptation layers from Section 5 of [RFC8724] can be used the way Figures 1, 2, and 3 show ๐ฆ.
Figure 1 is giving "one Rule does it all" ๐ . A single Rule compresses the whole header stack from IPv6 all the way to CoAP. The Device and the Network Gateway (NGW) both do SCHC C/D (SCHC Compression/Decompression, see [RFC8724]) โจ. The app talking to the Device doesn't do SCHC C/D at all, so it's not involved ๐ธ.
(Device) (NGW) (App)
+--------+ +--------+
| CoAP | | CoAP |
+--------+ +--------+
| UDP | | UDP |
+--------+ +----------------+ +--------+
| IPv6 | | IPv6 | | IPv6 |
+--------+ +--------+-------+ +--------+
| SCHC | | SCHC | | | |
+--------+ +--------+ + + +
| LPWAN | | LPWAN | | | |
+--------+ +--------+-------+ +--------+
((((LPWAN)))) ------ Internet ------
Figure 1: Compression/Decompression at the LPWAN Boundary
So in Figure 1, SCHC header compression happens above Layer 2 in the Device and the NGW ๐ง. The SCHC layer gets non-encrypted packets and can apply compression Rules to all the headers in the stack ๐. On the other side, the NGW gets the SCHC packet and rebuilds the headers using the Rule and the Compression Residue ๐ฅ. After decompression, the NGW forwards the IPv6 packet toward the destination ๐. The same thing happens the other way when a non-encrypted packet shows up at the NGW ๐. Thanks to IP forwarding based on the IPv6 prefix, the NGW knows which Device it is and compresses headers using that Device's Rules ๐.
In Figure 2, SCHC compression happens in the CoAP layer, so the CoAP header gets compressed independently of the other layers ๐. The RuleID, Compression Residue, and CoAP payload are encrypted with a mechanism such as DTLS ๐. Only the other end (App) can decipher the info ๐. If needed, the layers below use SCHC to compress the header as defined in [RFC8724] (shown with dotted lines in the figure) โจ.
This use case needs an end-to-end context initialization between the Device and the application ๐ฆ. The context initialization is out of scope for this document ๐ .
(Device) (NGW) (App)
+--------+ +--------+
| CoAP | | CoAP |
+--------+ +--------+
| SCHC | | SCHC |
+--------+ +--------+
| DTLS | | DTLS |
+--------+ +--------+
. udp . . udp .
.......... .................. ..........
. ipv6 . . ipv6 . . ipv6 .
.......... .................. ..........
. schc . . schc . . . .
.......... .......... . . .
. lpwan . . lpwan . . . .
.......... .................. ..........
((((LPWAN)))) ------ Internet ------
Figure 2: Standalone CoAP End-to-End Compression/Decompression
Figure 3 is the OSCORE era ๐ธ. It shows Object Security for Constrained RESTful Environments (OSCORE) [RFC8613] in action. Here SCHC needs two Rules to compress the CoAP header ๐. The first Rule focuses on the Inner header. The result of that first compression then gets encrypted with OSCORE ๐. After that, a second Rule compresses the Outer header, including the OSCORE options ๐.
(Device) (NGW) (App)
+--------+ +--------+
| CoAP | | CoAP |
| Inner | | Inner |
+--------+ +--------+
| SCHC | | SCHC |
| Inner | | Inner |
+--------+ +--------+
| CoAP | | CoAP |
| Outer | | Outer |
+--------+ +--------+
| SCHC | | SCHC |
| Outer | | Outer |
+--------+ +--------+
. udp . . udp .
.......... .................. ..........
. ipv6 . . ipv6 . . ipv6 .
.......... .................. ..........
. schc . . schc . . . .
.......... .......... . . .
. lpwan . . lpwan . . . .
.......... .................. ..........
((((LPWAN)))) ------ Internet ------
Figure 3: OSCORE Compression/Decompression
When there are several SCHC instances, like in Figures 2 and 3, the Rules may come from different provisioning domains ๐.
This document focuses on CoAP compression, which is what the dashed boxes in the previous figures represent ๐.
3. CoAP Headers Compressed with SCHC
Using SCHC over the CoAP header is the same deal as with IP and UDP. It uses the same description and compression/decompression techniques explained in [RFC8724] ๐. For CoAP, the SCHC Rules description uses the direction information to optimize compression, which cuts down how many Rules you need to compress headers โจ. The Field Descriptor MAY define both request/response headers and TVs in the same Rule, using the DI to show which header type it is ๐ฆ.
Like with other header compression protocols, if the compressor can't find a correct Rule for a header, the packet MUST be sent uncompressed. It uses the RuleID dedicated to this purpose, and the Compression Residue is the complete header of the packet ๐ โโ๏ธ. See Section 6 of [RFC8724] ๐ธ.
3.1. Differences between CoAP and UDP/IP Compression
CoAP compression is different from IPv6 and UDP compression in a few ways ๐ :
- The CoAP message format is asymmetric, so the headers differ for a request or a response ๐. For example, the Uri-Path option is mandatory in the request, but it might not be in the response. A request might contain an Accept option, and the response might include a Content-Format option ๐. With IPv6 and UDP, the returning path just swaps the values of some fields in the header ๐ง. But every direction has the same fields (for example, source and destination address fields) ๐.
[RFC8724] defines the use of a DI in the Field Descriptor. That lets one Rule process a message header differently depending on the direction ๐.
- Even when a field is "symmetric" (found in both directions), the values in each direction are different ๐ฅ. The compression may use a "match-mapping" MO to limit the range of expected values in a particular direction and shrink the Compression Residue's size ๐. Through the DI, a Field Descriptor in the Rules splits the possible field value into two parts, one for each direction โจ. For instance, if a client only sends Confirmable (CON) requests [RFC7252], the Type can be elided by compression, and the answer may use one single bit to carry either the ACK or Reset (RST) type ๐. The field Code works the same way: the 0.0X code format value in the request and the Y.ZZ code format in the response ๐ฆ.
- In SCHC, the Rule defines each header field's length, so SCHC doesn't have to send it ๐ . In IPv6 and UDP headers, the fields have a fixed size that's known by definition ๐ธ. Some CoAP header fields have variable lengths, though, and the Rule description specifies that ๐. For example, in a Uri-Path or Uri-Query, the Token size may vary from 0 to 8 bytes, and CoAP options use the Type-Length-Value encoding format ๐.
When doing SCHC compression of a variable-length field, Section 7.4.2 of [RFC8724] offers the option of defining a function for the Field Length in the Field Descriptor, so the length is known before compression ๐ง. If the Field Length is unknown, the Rule sets it as a variable, and SCHC sends the compressed field's length in the Compression Residue ๐.
- A field can show up several times in the CoAP headers ๐. This is usually true for elements of a URI (path or queries) ๐ฅ. The SCHC specification [RFC8724] lets a FID appear several times in the Rule and uses the Field Position (FP) to identify the correct instance, which clears up the MO's ambiguity ๐.
- Field Lengths defined in CoAP can be too large for LPWAN traffic constraints โจ. This is especially true for the Message ID field and the Token field ๐ฆ. SCHC uses different MOs to do the compression, so see Section 7.4 of [RFC8724] ๐ . In this case, SCHC can apply the Most Significant Bits (MSBs) MO to cut down the information carried on LPWANs ๐ธ.
4. Compression of CoAP Header Fields
This section talks about compressing the different CoAP header fields ๐. CoAP compression with SCHC follows the information in Section 7.1 of [RFC8724] ๐.
4.1. CoAP Version Field
The CoAP version is bidirectional and MUST be elided during SCHC compression, since it always contains the same value ๐ซถ. In the future, or if a new version of CoAP gets defined, new Rules will be needed to avoid ambiguities between versions ๐ฎ.
4.2. CoAP Type Field
CoAP [RFC7252] has four types of messages: two requests (CON, NON), one response (ACK), and one empty message (RST) ๐ฆ.
The SCHC compression scheme SHOULD elide this field if, for instance, a client is only sending Non-confirmable (NON) messages or only CON messages โจ. For the RST message, SCHC may use a dedicated Rule ๐ธ. For other usages, SCHC can use a "match-mapping" MO ๐ .
The rewrite below picks up at Section 5 and works through Section 6.3. It covers the CoAP options, the Uri-Path and Uri-Query handling, and the extensions for Block, Observe and No-Response. The original's requirement keywords, tables, examples and citations are kept exactly as written.
4.3. CoAP Code Field ๐
Okay so the Code field ๐ tells you which Request Method CoAP is using. It's defined in an IANA registry [RFC7252], and compressing it works the same way as compressing the Type field. If the Device has a specific role, SCHC can split the code values into two Field Descriptors: one for the request codes in class 0, and one for the response values. SCHC uses the DI to find the right value in the packet. Literally so smart ๐ง โจ
If the Device only does CoAP client stuff, SCHC compression can shrink the request code down to just the set of requests the client can handle. Lowkey genius ๐
For values we already know, SCHC can use a "match-mapping" MO. And if SCHC can't compress the Code field, it just sends the values in the Compression Residue. No stress ๐ซถ
4.4. CoAP Message ID Field ๐ฆ
SCHC can compress the Message ID field using the "MSB" MO together with the "LSB" CDA. See Section 7.4 of [RFC8724]. Bestie, check that one out ๐ธ
4.5. CoAP Token Fields ๐ง
CoAP sets up the Token with two CoAP fields: the Token Length, which lives in the mandatory header, and the Token Value, which comes right after the mandatory CoAP header. It's giving two-part energy ๐
SCHC treats the Token Length like any other header field. If the value never changes, the size can be stored in the TV and elided during transmission. Otherwise, SCHC sends the Token Length in the Compression Residue. โจ
For the Token Value, SCHC MUST NOT send it as variable-length data in the Compression Residue, because that would get confusing with the Token Length. So SCHC MUST use the Token Length value to set the size of the Compression Residue. SCHC has a special function called "tkl" that the Rule MUST use to complete the Field Descriptor. When decompressing, this function gives back the value from the Token Length field. Not me being all about the precision ๐ญ๐
- CoAP Options ๐
CoAP puts options after the basic header, and they're ordered by option number. See [RFC7252]. Each Option instance uses the format Delta-Type (D-T), Length (L), Value (V). The SCHC Rule builds the description of the option using the following:
- in the FID: the option number, built from the D-T;
- in the TV: the option value; and
- for the Option Length: the information in Sections 7.4.1 and 7.4.2 of [RFC8724].
When the Option Length has a well-known size, the Rule can keep that length value, so SCHC compression doesn't send it. Otherwise, SCHC compression carries the length of the Compression Residue, along with the Compression Residue value. ๐
CoAP requests and responses don't carry the same options. So compression Rules can reflect that asymmetry by tagging the DI. Iconic behaviour, honestly ๐
Note that length coding is different for CoAP options and for SCHC variable size Compression Residue. Don't mix them up, bestie ๐
The following sections show how SCHC compresses some specific CoAP options.
If CoAP introduces a new option, the SCHC Rules MAY be updated, and the new FID description MUST be assigned so it can be compressed. Otherwise, if no Rule describes this new option, SCHC compression doesn't happen, and SCHC sends the CoAP header uncompressed. โจ
5.1. CoAP Content and Accept Options ๐ธ
If the client expects a single value, it can be stored in the TV and elided during transmission. Otherwise, if the client expects several possible values, a "match-mapping" MO SHOULD be used to keep the Compression Residue small. If not, SCHC has to send the option value in the Compression Residue, either fixed or variable length. ๐ฆ
5.2. CoAP Option Max-Age, Uri-Host, and Uri-Port Fields ๐
These three fields get compressed the same way. When the values of these options are known, SCHC can elide these fields. If the option uses well-known values, SCHC can use a "match-mapping" MO. Otherwise, SCHC uses the "value-sent" MO, and the Compression Residue sends these options' values. ๐
5.3. CoAP Option Uri-Path and Uri-Query Fields ๐ง
Uri-Path and Uri-Query are repeatable options, which means they can show up several times in the CoAP header with different values. The SCHC Rule description uses the FP to tell the different instances in the path apart. Main character energy in the path ๐
To compress repeatable field values, SCHC can use a "match-mapping" MO to shrink variable paths or queries. In these cases, you can regroup several elements into a single entry to squeeze out more compression. The numbering of elements doesn't change, and the first matching element sets the MO comparison. ๐
In Table 1, SCHC can use a single bit in the Compression Residue to code one of the two paths. If regrouping weren't allowed, 2 bits in the Compression Residue would be needed. SCHC sends the third path element as a variable size in the Compression Residue. โจ
+==========+=====+====+====+==========+=========+==============+
| Field | FL | FP | DI | TV | MO | CDA |
+==========+=====+====+====+==========+=========+==============+
| Uri-Path | | 1 | Up | ["/a/b", | match- | mapping-sent |
| | | | | "/c/d"] | mapping | |
+----------+-----+----+----+----------+---------+--------------+
| Uri-Path | var | 3 | Up | | ignore | value-sent |
+----------+-----+----+----+----------+---------+--------------+
Table 1: Complex Path Example
The length of Uri-Path and Uri-Query might be known when the Rule is defined. Either way, SCHC MUST set the Field Length to a variable value. The Compression Residue size is expressed in bytes. ๐ธ
SCHC compression can use the MSB MO on a Uri-Path or Uri-Query element. Just be careful with the length, though, because the MSB value is in bits, and the size MUST always be a multiple of 8 bits. ๐
The length sent at the start of a variable-length Compression Residue tells you the LSB's size in bytes. ๐
For example, for a CORECONF path /c/X6?k=eth0, the Rule description can look like this (Table 2):
+===========+=====+====+====+======+=========+============+
| Field | FL | FP | DI | TV | MO | CDA |
+===========+=====+====+====+======+=========+============+
| Uri-Path | | 1 | Up | "c" | equal | not-sent |
+-----------+-----+----+----+------+---------+------------+
| Uri-Path | var | 2 | Up | | ignore | value-sent |
+-----------+-----+----+----+------+---------+------------+
| Uri-Query | var | 1 | Up | "k=" | MSB(16) | LSB |
+-----------+-----+----+----+------+---------+------------+
Table 2: CORECONF URI Compression
Table 2 shows the Rule description for a Uri-Path and a Uri-Query. SCHC compresses the first part of the Uri-Path with a "not-sent" CDA. Then SCHC sends the second element of the Uri-Path with its length (i.e., 0x2 "X6"), followed by the query option (i.e., 0x4 "eth0"). ๐ฆ
5.3.1. Variable Number of Path or Query Elements ๐
SCHC fixes the number of Uri-Path or Uri-Query elements in a Rule when the Rule is created. If the number varies, SCHC SHOULD do one of the following:
- create several Rules to cover all the possibilities, or
- create a Rule that defines several entries for Uri-Path to cover the longest path, and send a Compression Residue with a length of 0 to show that a Uri-Path entry is empty.
However, this adds 4 bits to the variable Compression Residue size. See Section 7.4.2 of [RFC8724]. Plan accordingly, bestie ๐ง
5.4. CoAP Option Size1, Size2, Proxy-URI, and Proxy-Scheme Fields โญ
The SCHC Rule description MAY define sending some field values by setting the TV to "not-sent", the MO to "ignore", and the CDA to "value-sent". A Rule MAY also use a "match-mapping" MO when there are different options for the same FID. Otherwise, the Rule sets the TV to the value, the MO to "equal", and the CDA to "not-sent". ๐
5.5. CoAP Option ETag, If-Match, If-None-Match, Location-Path, and Location-Query Fields ๐ญ
A Rule entry can't store the values of these fields. The Rule description MUST always send these values in the Compression Residue. No exceptions, periodt ๐
- SCHC Compression of CoAP Extensions ๐
6.1. Block ๐
When a packet uses a Block option [RFC7959], SCHC compression MUST send its content in the Compression Residue. The SCHC Rule describes an empty TV with the MO set to "ignore" and the CDA set to "value-sent". The Block option allows fragmentation at the CoAP level that's compatible with SCHC fragmentation. Both fragmentation mechanisms are complementary, and the node can use them for the same packet as needed. โจ
6.2. Observe ๐ฆ
[RFC7641] defines the Observe Option. The SCHC Rule description won't define the TV, but it sets the MO to "ignore" and the CDA to "value-sent". SCHC doesn't limit the maximum size for this option (3 bytes). To reduce the transmission size, either the Device implementation MAY limit the delta between two consecutive values, or a proxy can modify the increment. ๐ธ
Since the Observe Option MAY use a RST message to tell a server that the client doesn't need the Observe response, a specific SCHC Rule SHOULD exist to allow that message to be compressed with the RST type. ๐ง
6.3. No-Response ๐
[RFC7967] defines a No-Response option that limits the responses a server makes to a request. Different behaviours exist when using this option to limit those responses. If both ends know the value, the SCHC Rule describes a TV with this value, the MO set to "equal", and the CDA set to "not-sent". ๐
Otherwise, if the value changes over time, the SCHC Rule sets the MO to "ignore" and the CDA to "value-sent". The Rule MAY also use a "match-mapping" MO to compress this option. ๐
6.4. OSCORE ๐
okay bestie, OSCORE [RFC8613] is the one that gives CoAP messages end-to-end protection ๐ and this section is all about how SCHC Rules can compress OSCORE-protected messages. we're literally compressing encrypted stuff, so it's giving main character energy ๐
so the OSCORE option value has its own little encoding, defined in Section 6.1 of [RFC8613]. the first byte is the boss ๐: it holds flags that tell you what's inside the option. the three most significant bits are reserved and always set to 0 ๐ง, then bit h says whether the kid context field is there, bit k says whether a kid field is there, and the three least significant bits, n, tell you how long the piv (Partial Initialization Vector) field is, in bytes. when n = 0, no piv is present. check out the layout ๐
0 1 2 3 4 5 6 7 <--------- n bytes ------------->
+-+-+-+-+-+-+-+-+---------------------------------
|0 0 0|h|k| n | Partial IV (if any) ...
+-+-+-+-+-+-+-+-+---------------------------------
| | |
|<-- CoAP -->|<------ CoAP OSCORE_piv ------> |
OSCORE_flags
<- 1 byte -> <------ s bytes ----->
+------------+----------------------+-----------------------+
| s (if any) | kid context (if any) | kid (if any) ... |
+------------+----------------------+-----------------------+
| | |
| <------ CoAP OSCORE_kidctx ------>|<-- CoAP OSCORE_kid -->|
Figure 4: OSCORE Option
the flag byte is followed by the piv field, the kid context field, and then the kid field, in that order ๐. and if the kid context field is present, its length in bytes is written in the first byte, which the figure calls "s" ๐ธ
now, to compress this well, the Rule has to know about the OSCORE option and the fields inside it โจ. conceptually there are up to four distinct pieces of info in there: the flag bits, the piv, the kid context, and the kid. so the SCHC Rule splits the OSCORE option into four Field Descriptors so it can compress each one:
CoAP OSCORE_flagsCoAP OSCORE_pivCoAP OSCORE_kidctxCoAP OSCORE_kid
and yes, Figure 4 shows the OSCORE option format with those four fields layered right on top ๐ฆ. quick note: the CoAP OSCORE_kidctx field directly includes the size octet, s ๐ซถ
7. Examples of CoAP Header Compression ๐ง
7.1. Mandatory Header with CON Message ๐
okay so in this first scenario ๐ญ, the SCHC compressor on the NGW side gets a POST message from an Internet client, and the Device immediately acknowledges it. it's a whole little conversation ๐ฌ Table 3 lays out the SCHC Rule descriptions for this one ๐
+===================================================================+
|RuleID 1 |
+==========+===+==+==+======+===============+===============+=======+
| Field | FL|FP|DI| TV | MO | CDA | Sent |
| | | | | | | | [bits]|
+==========+===+==+==+======+===============+===============+=======+
|CoAP |2 |1 |Bi|01 | equal | not-sent | |
|version | | | | | | | |
+----------+---+--+--+------+---------------+---------------+=======+
|CoAP Type |2 |1 |Dw|CON | equal | not-sent | |
+----------+---+--+--+------+---------------+---------------+=======+
|CoAP Type |2 |1 |Up|[ACK, | match-mapping | matching-sent |T |
| | | | |RST] | | | |
+----------+---+--+--+------+---------------+---------------+=======+
|CoAP TKL |4 |1 |Bi|0 | equal | not-sent | |
+----------+---+--+--+------+---------------+---------------+=======+
|CoAP Code |8 |1 |Bi|[0.00,| match-mapping | matching-sent |CC CCC |
| | | | |... | | | |
| | | | |5.05] | | | |
+----------+---+--+--+------+---------------+---------------+=======+
|CoAP MID |16 |1 |Bi|0000 | MSB(7) | LSB |MID |
+----------+---+--+--+------+---------------+---------------+=======+
|CoAP Uri- |var|1 |Dw|path | equal 1 | not-sent | |
|Path | | | | | | | |
+----------+---+--+--+------+---------------+---------------+=======+
Table 3: CoAP Context to Compress Header without Token
in this example, SCHC compression elides the version and Token Length fields, and honestly that's such a flex ๐ the 25 Method and Response Codes defined in [RFC7252] get shrunk down to just 5 bits using a "match-mapping" MO โจ the Uri-Path has a single element, which is indicated in the TV and then elided with the CDA "not-sent" ๐
so SCHC compression ends up sending only the Type, a mapped code, and the least significant bits of the Message ID (that's 9 bits in the example above) ๐
โ ๏ธ bestie, heads up: a client sitting in an Application Server that's sending a request to a server in the Device may not get compressed through this Rule ๐ the reason is that the MID might not start with 7 bits equal to 0. the fix is that a CoAP proxy placed before SCHC C/D can rewrite the Message ID so it fits the value and matches the Rule ๐ซถ
this is the glow-up we needed ๐
7.2. OSCORE Compression
okay so OSCORE is all about end-to-end encryption for CoAP messages, bestie ๐ The goal is to hide the message as much as possible while still letting proxies do their thing. That's the whole vibe.
Conceptually, the CoAP message gets split into an Inner Plaintext and an Outer OSCORE message ๐ฆ The Inner Plaintext holds the sensitive stuff that proxies don't need. It's still part of the message, so it stays encrypted until it reaches its final destination. The Outer Message is basically a shell that looks like a regular CoAP message. It carries every option and piece of info that proxies and caches need. Figure 5 below shows this split.
Original CoAP Packet
+-+-+---+-------+---------------+
|v|t|TKL| code | Message ID |
+-+-+---+-------+---------------+....+
| Token |
+-------------------------------.....+
| Options (IEU) |
. .
. .
+------+-------------------+
| 0xFF |
+------+------------------------+
| |
| Payload |
| |
+-------------------------------+
/ \
/ \
/ \
/ \
Outer Header v v Plaintext
+-+-+---+--------+---------------+ +-------+
|v|t|TKL|new code| Message ID | | code |
+-+-+---+--------+---------------+....+ +-------+-----......+
| Token | | Options (E) |
+--------------------------------.....+ +-------+------.....+
| Options (IU) | | 0xFF |
. . +-------+-----------+
. OSCORE Option . | |
+------+-------------------+ | Payload |
| 0xFF | | |
+------+ +-------------------+
Figure 5: CoAP Packet Split into OSCORE Outer Header and Plaintext
Figure 5 shows the packet format for the OSCORE Outer header and Plaintext.
CoAP sorts its options into three classes, and each one gets a different kind of protection from the protocol ๐
- Class E: Encrypted options moved to the Inner Plaintext.
- Class I: Integrity-protected options included in the Additional Authenticated Data (AAD) for the encryption of the Plaintext, but otherwise left untouched in the Outer Message.
- Class U: Unprotected options left untouched in the Outer Message.
These classes point out that the Outer option contains the OSCORE option and that the message is OSCORE protected ๐ฅ This option carries the info needed to retrieve the Security Context, and the endpoint uses that Security Context to decrypt the message correctly.
In the Outer header, the original code gets hidden and swapped for a default dummy value ๐ As seen in Sections 4.1.3.5 and 4.2 of [RFC8613], the message code becomes POST for requests and Changed for responses when CoAP is not using the Observe Option. If CoAP does use Observe, the OSCORE message code becomes FETCH for requests and Content for responses.
The first byte of the Plaintext holds the original packet code. After that comes the message code, the class E options, and, if there is one, the original message payload, preceded by its payload marker.
Next, an Authenticated Encryption with Associated Data (AEAD) algorithm encrypts the Plaintext โจ This integrity-protects the Security Context parameters and, eventually, any class I options from the Outer header. The resulting ciphertext becomes the new payload of the OSCORE message, as shown in Figure 6.
As defined in [RFC5116], this ciphertext is the encrypted Plaintext's concatenation of the Authentication Tag. Note that Inner Compression only affects the Plaintext before encryption. The Authentication Tag is fixed in length and uncompressed, so it counts as part of the cost of protection ๐ง
Outer Header
+-+-+---+--------+---------------+
|v|t|TKL|new code| Message ID |
+-+-+---+--------+---------------+....+
| Token |
+--------------------------------.....+
| Options (IU) |
. .
. OSCORE Option .
+------+-------------------+
| 0xFF |
+------+---------------------------+
| |
| Ciphertext: Encrypted Inner |
| Header and Payload |
| + Authentication Tag |
| |
+----------------------------------+
Figure 6: OSCORE Message
The SCHC compression scheme compresses both the Plaintext before encryption and the resulting OSCORE message after encryption ๐ See Figure 7.
The OSCORE message turns into a segmented process, where SCHC compression runs independently in two stages. Each stage has its own set of Rules: the Inner SCHC Rules and the Outer SCHC Rules. This way, compression is applied to all fields of the original CoAP message ๐
Outer Message OSCORE Plaintext
+-+-+---+--------+---------------+ +-------+
|v|t|TKL|new code| Message ID | | code |
+-+-+---+--------+---------------+....+ +-------+-----......+
| Token | | Options (E) |
+--------------------------------.....+ +-------+------.....+
| Options (IU) | | 0xFF |
. . +-------+-----------+
. OSCORE Option . | |
+------+-------------------+ | Payload |
| 0xFF | | |
+------+------------+ +-------------------+
| Ciphertext |<---------\ |
| | | v
+-------------------+ | +-----------------+
| | | Inner SCHC |
v | | Compression |
+-----------------+ | +-----------------+
| Outer SCHC | | |
| Compression | | v
+-----------------+ | +-------+
| | |RuleID |
v | +-------+-----------+
+--------+ +------------+ |Compression Residue|
|RuleID' | | Encryption | <-- +----------+--------+
+--------+-----------+ +------------+ | |
|Compression Residue'| | Payload |
+-----------+--------+ | |
| Ciphertext | +-------------------+
| |
+--------------------+
Figure 7: OSCORE Compression Diagram
Note that since the corresponding endpoint can only decrypt the Inner part of the message, this endpoint will also have to implement Inner SCHC Compression/Decompression. No skipping that step, bestie ๐ซถ
7.3. Example OSCORE Compression
okay this section is the fun part ๐ It walks through a GET request and its Content response, going from a Device-based CoAP client to a cloud-based CoAP server. It also sketches a possible set of Rules for Inner SCHC Compression and Outer SCHC Compression. Then it dumps the results and compares SCHC + OSCORE performance with SCHC + CoAP performance. The whole thing gives us an approximation of the cost of security with SCHC-OSCORE ๐ฅ
Our first CoAP message is the GET request in Figure 8.
Original message:
=================
0x4101000182bb74656d7065726174757265
Header:
0x4101
01 Ver
00 CON
0001 TKL
00000001 Request Code 1 "GET"
0x0001 = mid
0x82 = token
Options:
0xbb74656d7065726174757265
Option 11: URI_PATH
Value = temperature
Original message length: 17 bytes
Figure 8: CoAP GET Request
Its matching response is the Content response in Figure 9 โจ
Original message:
=================
0x6145000182ff32332043
Header:
0x6145
01 Ver
10 ACK
0001 TKL
01000101 Successful Response Code 69 "2.05 Content"
0x0001 = mid
0x82 = token
0xFF Payload marker
Payload:
0x32332043
Original message length: 10 bytes
Figure 9: CoAP Content Response
The SCHC Rules for Inner Compression cover all the fields already present in a regular CoAP message. The methods described in Section 4 apply to these fields. Table 4 gives an example ๐
+===================================================================+
|RuleID 0 |
+========+==+==+==+===========+===============+==============+======+
| Field |FL|FP|DI| TV | MO | CDA | Sent |
| | | | | | | |[bits]|
+========+==+==+==+===========+===============+==============+======+
|CoAP |8 |1 |Up|1 | equal | not-sent | |
|Code | | | | | | | |
+--------+--+--+--+-----------+---------------+--------------+======+
|CoAP |8 |1 |Dw|[69,132] | match-mapping | mapping-sent |c |
|Code | | | | | | | |
+--------+--+--+--+-----------+---------------+--------------+======+
|CoAP | |1 |Up|temperature| equal | not-sent | |
|Uri-Path| | | | | | | |
+--------+--+--+--+-----------+---------------+--------------+======+
Table 4: Inner SCHC Rule
Figure 10 shows the Plaintext we get for the example GET request ๐ง The packet goes through Inner Compression and encryption up to the payload, and the Outer OSCORE message then adds the result of that Inner process.
________________________________________________________
| |
| OSCORE Plaintext |
| |
| 0x01bb74656d7065726174757265 (13 bytes) |
| |
| 0x01 Request Code GET |
| |
| bb74656d7065726174757265 Option 11: URI_PATH |
| Value = temperature |
|________________________________________________________|
okay so the next bit is where the sauce really is โจ we're still in the OSCORE example, and now the plaintext gets squeezed before it gets locked up ๐๐
|
|
| Inner SCHC Compression
|
v
_________________________________
| |
| Compressed Plaintext |
| |
| 0x00 |
| |
| RuleID = 0x00 (1 byte) |
| (No Compression Residue) |
|_________________________________|
|
| AEAD Encryption
| (piv = 0x04)
v
_________________________________________________
| |
| encrypted_plaintext = 0xa2 (1 byte) |
| tag = 0xc54fe1b434297b62 (8 bytes) |
| |
| ciphertext = 0xa2c54fe1b434297b62 (9 bytes) |
|_________________________________________________|
Figure 10: Plaintext Compression and Encryption for GET Request
so in this case the original message has no payload ๐, which means the plaintext shrinks all the way down to just 1 byte, the RuleID ๐. The AEAD algorithm keeps that length in its first output and gives you a fixed-size tag ๐ฆ. SCHC can't compress the tag, so the OSCORE message has to carry it uncompressed. Integrity protection adds overhead to the total message length, which limits how much compression you can get. That's the price of adding security to the exchange ๐
Figure 11 shows the process for the example Content response. The Compression Residue here is 1 bit long ๐ธ Since SCHC adds padding after the payload, the misalignment makes the hex code of the payload look different from the original, even though SCHC still can't compress the tag. The tag bytes cost something and limit SCHC's performance, but they're what bring security to the transmission ๐ซถ
________________________________________________________
| |
| OSCORE Plaintext |
| |
| 0x45ff32332043 (6 bytes) |
| |
| 0x45 Successful Response Code 69 "2.05 Content" |
| |
| ff Payload marker |
| |
| 32332043 Payload |
|________________________________________________________|
|
|
| Inner SCHC Compression
|
v
_________________________________________________
| |
| Compressed Plaintext |
| |
| 0x001919902180 (6 bytes) |
| |
| 00 RuleID |
| |
| 0b0 (1 bit match-mapping Compression Residue) |
| 0x32332043 >> 1 (shifted payload) |
| 0b0000000 Padding |
|_________________________________________________|
|
| AEAD Encryption
| (piv = 0x04)
v
_________________________________________________________
| |
| encrypted_plaintext = 0x10c6d7c26cc1 (6 bytes) |
| tag = 0xe9aef3f2461e0c29 (8 bytes) |
| |
| ciphertext = 0x10c6d7c26cc1e9aef3f2461e0c29 (14 bytes) |
|_________________________________________________________|
Figure 11: Plaintext Compression and Encryption for Content Response
The Outer SCHC Rule (Table 5) must process the OSCORE options fields ๐ง Figures 12 and 13 show a dump of the OSCORE messages generated from the example messages. They include the Inner Compressed ciphertext in the payload, and these are the messages that have to be compressed via the Outer SCHC Compression scheme ๐
Table 5 shows a possible set of Outer Rule items to compress the Outer header ๐
+===================================================================+
|RuleID 0 |
+===============+===+==+==+================+=======+=========+======+
| Field | FL|FP|DI| TV | MO | CDA | Sent |
| | | | | | | |[bits]|
+===============+===+==+==+================+=======+=========+======+
|CoAP version |2 |1 |Bi| 01 |equal |not-sent | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP Type |2 |1 |Up| 0 |equal |not-sent | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP Type |2 |1 |Dw| 2 |equal |not-sent | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP TKL |4 |1 |Bi| 1 |equal |not-sent | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP Code |8 |1 |Up| 2 |equal |not-sent | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP Code |8 |1 |Dw| 68 |equal |not-sent | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP MID |16 |1 |Bi| 0000 |MSB(12)|LSB |MMMM |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP Token |tkl|1 |Bi| 0x80 |MSB(5) |LSB |TTT |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP |8 |1 |Up| 0x09 |equal |not-sent | |
|OSCORE_flags | | | | | | | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP OSCORE_piv|var|1 |Up| 0x00 |MSB(4) |LSB |PPPP |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP OSCORE_kid|var|1 |Up| 0x636c69656e70 |MSB(52)|LSB |KKKK |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP |var|1 |Bi| b'' |equal |not-sent | |
|OSCORE_kidctx | | | | | | | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP |8 |1 |Dw| b'' |equal |not-sent | |
|OSCORE_flags | | | | | | | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP OSCORE_piv|var|1 |Dw| b'' |equal |not-sent | |
+---------------+---+--+--+----------------+-------+---------+======+
|CoAP OSCORE_kid|var|1 |Dw| b'' |equal |not-sent | |
+---------------+---+--+--+----------------+-------+---------+======+
Table 5: Outer SCHC Rule
Protected message:
==================
0x4102000182d8080904636c69656e74ffa2c54fe1b434297b62
(25 bytes)
Header:
0x4102
01 Ver
00 CON
0001 TKL
00000010 Request Code 2 "POST"
0x0001 = mid
0x82 = token
Options:
0xd8080904636c69656e74 (10 bytes)
Option 21: OBJECT_SECURITY
Value = 0x0904636c69656e74
09 = 000 0 1 001 flag byte
h k n
04 piv
636c69656e74 kid
0xFF Payload marker
Payload:
0xa2c54fe1b434297b62 (9 bytes)
Figure 12: Protected and Inner SCHC Compressed GET Request
Protected message:
==================
0x6144000182d008ff10c6d7c26cc1e9aef3f2461e0c29
(22 bytes)
Header:
0x6144
01 Ver
10 ACK
0001 TKL
01000100 Successful Response Code 68 "2.04 Changed"
0x0001 = mid
0x82 = token
Options:
0xd008 (2 bytes)
Option 21: OBJECT_SECURITY
Value = b''
0xFF Payload marker
Payload:
0x10c6d7c26cc1e9aef3f2461e0c29 (14 bytes)
Figure 13: Protected and Inner SCHC Compressed Content Response
Now for the flag bits ๐ฉ A few SCHC compression methods are handy here, depending on the application. The simplest option is to fix the flags to one value, pairing an MO of "equal" with a CDA of "not-sent". That definition saves the most bits, but it can cost you flexibility. Otherwise, SCHC could use a "match-mapping" MO to pick from several configurations for the exchange. If neither works for you, the SCHC description may use an "MSB" MO to mask off the three hard-coded most significant bits ๐
Heads up: fixing a flag bit limits which CoAP options you can use in the exchange, because those option choices depend on specific options. So choose wisely, bestie ๐
The piv field is a great candidate for masking some bits off with an "MSB" MO and an "LSB" CDA โจ This SCHC description could shine in applications where messages are infrequent, like LPWAN technologies. Just know that compressing the sequence numbers may reduce how many sequence numbers you can use in an exchange. Once the sequence number goes past that maximum value, the OSCORE keys need to be re-established ๐
The size, s, that is included in the kid context field MAY be masked off with an "LSB" CDA. The rest of the field could have more bits masked off, or the whole field could be fixed with a MO of "equal" and a CDA of "not-sent". The same goes for the kid field ๐ฆ
The Outer Rule of Table 5 is applied to the example GET request and Content response. Figures 14 and 15 show the resulting messages ๐
Compressed message:
==================
0x001489458a9fc3686852f6c4 (12 bytes)
0x00 RuleID
1489 Compression Residue
458a9fc3686852f6c4 Padded payload
Compression Residue:
0b 0001 010 0100 0100 (15 bits -> 2 bytes with padding)
mid tkn piv kid
Payload
0xa2c54fe1b434297b62 (9 bytes)
Compressed message length: 12 bytes
Figure 14: SCHC-OSCORE Compressed GET Request
Compressed message:
==================
0x0014218daf84d983d35de7e48c3c1852 (16 bytes)
0x00 RuleID
14 Compression Residue
218daf84d983d35de7e48c3c1852 Padded payload
Compression Residue:
0b0001 010 (7 bits -> 1 byte with padding)
mid tkn
Payload
0x10c6d7c26cc1e9aef3f2461e0c29 (14 bytes)
Compressed message length: 16 bytes
Figure 15: SCHC-OSCORE Compressed Content Response
In contrast ๐ comparing these results with what you'd get by SCHC-compressing the original CoAP messages without OSCORE protection means compressing the CoAP messages according to the SCHC Rule in Table 6 ๐ง
Okay so here's the wrap-up of the whole thing ๐ Table 6 is basically the cheat sheet for the no-OSCORE setup, and then we get the lil "about 10 bytes" flex when OSCORE shows up ๐ฆ
+===================================================================+
|RuleID 1 |
+========+===+==+==+===========+===============+=============+======+
| Field | FL|FP|DI| TV | MO | CDA | Sent |
| | | | | | | |[bits]|
+========+===+==+==+===========+===============+=============+======+
|CoAP |2 |1 |Bi|01 | equal |not-sent | |
|version | | | | | | | |
+--------+---+--+--+-----------+---------------+-------------+======+
|CoAP |2 |1 |Up|0 | equal |not-sent | |
|Type | | | | | | | |
+--------+---+--+--+-----------+---------------+-------------+======+
|CoAP |2 |1 |Dw|2 | equal |not-sent | |
|Type | | | | | | | |
+--------+---+--+--+-----------+---------------+-------------+======+
|CoAP TKL|4 |1 |Bi|1 | equal |not-sent | |
+--------+---+--+--+-----------+---------------+-------------+======+
|CoAP |8 |1 |Up|2 | equal |not-sent | |
|Code | | | | | | | |
+--------+---+--+--+-----------+---------------+-------------+======+
|CoAP |8 |1 |Dw|[69,132] | match-mapping |mapping-sent |C |
|Code | | | | | | | |
+--------+---+--+--+-----------+---------------+-------------+======+
|CoAP MID|16 |1 |Bi|0000 | MSB(12) |LSB |MMMM |
+--------+---+--+--+-----------+---------------+-------------+======+
|CoAP |tkl|1 |Bi|0x80 | MSB(5) |LSB |TTT |
|Token | | | | | | | |
+--------+---+--+--+-----------+---------------+-------------+======+
|CoAP | |1 |Up|temperature| equal |not-sent | |
|Uri-Path| | | | | | | |
+--------+---+--+--+-----------+---------------+-------------+======+
Table 6: SCHC-CoAP Rule (No OSCORE)
The Rule in Table 6 gives us the SCHC compression results in Figure 16 for the request and Figure 17 for the response ๐
Compressed message:
==================
0x0114
0x01 = RuleID
Compression Residue:
0b00010100 (1 byte)
Compressed message length: 2 bytes
Figure 16: CoAP GET Compressed without OSCORE
Compressed message:
==================
0x010a32332043
0x01 = RuleID
Compression Residue:
0b00001010 (1 byte)
Payload
0x32332043
Compressed message length: 6 bytes
Figure 17: CoAP Content Compressed without OSCORE
Look at that glow-up ๐ธ The gap between SCHC + OSCORE and regular SCHC + CoAP is about 10 bytes, so it's not a huge deal, just a little extra.
8. IANA Considerations โจ
Good news bestie: this document has no IANA actions ๐ Nothing to register here, so you can chill.
9. Security Considerations ๐ฅ
Okay, this section is serious, so let's get into it ๐ Using SCHC header compression on CoAP header fields only changes how the header info is represented. SCHC header compression by itself doesn't raise or lower the overall security level of the communication. When the connection doesn't use a security protocol (OSCORE, DTLS, etc.), you need a Layer 2 security mechanism to protect the SCHC messages, no excuses ๐ค
If an LPWAN is your Layer 2 technology, the SCHC security considerations in [RFC8724] still apply. If you're using some other Layer 2 protocol, then a cryptographic integrity-protection mechanism to protect the SCHC headers is REQUIRED. That integrity protection is what keeps the properties that [RFC8724] relies upon working, so it's not optional ๐
When SCHC is used with OSCORE, the security considerations in [RFC8613] keep applying ๐ฆ
When SCHC is used with the OSCORE Outer headers, you have to pick the Initialization Vector (IV) size in the Compression Residue very carefully ๐ง There's a trade-off here: a longer "MSB" MO prefix gives you better compression efficiency, but the Device then has to renew its key material more often, otherwise the IV grows into something that can't be compressed anymore. Key renewal takes several message exchanges and a lot of energy-heavy computation, and the best balance depends on the specifics of the Device and how it's actually used ๐
If an attacker can slip a corrupted SCHC-compressed packet onto a link, they can launch DoS attacks by making the decompressor burn through resources. But honestly, an attacker who can inject packets at the link layer can do way more damaging stuff, so that's the bigger problem ๐ญ
SCHC compression produces variable-length Compression Residues for some CoAP fields. In the compressed header, the length field that gets sent is not the length of the original header field, but the length of the Compression Residue actually being transmitted ๐ If a corrupted packet reaches the decompressor with a longer or shorter length than the original compressed representation had, the SCHC decompression procedures will catch the error and drop the packet.
SCHC header compression Rules MUST remain tightly coupled between the compressor and the decompressor. If the compression Rules get out of sync, a Compression Residue might be decompressed differently at the receiver than the initial message that was submitted to compression procedures. So any time the context Rules get updated on an OSCORE endpoint, that endpoint MUST trigger OSCORE key re-establishment. Other message-protection mechanisms may need similar procedures to signal Rule updates. โ ๏ธ
10. Normative References ๐
[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>.
[RFC5116] McGrew, D., "An Interface and Algorithms for Authenticated
Encryption", RFC 5116, DOI 10.17487/RFC5116, January 2008,
<https://www.rfc-editor.org/info/rfc5116>.
[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>.
[RFC7641] Hartke, K., "Observing Resources in the Constrained
Application Protocol (CoAP)", RFC 7641,
DOI 10.17487/RFC7641, September 2015,
<https://www.rfc-editor.org/info/rfc7641>.
[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>.
[RFC7967] Bhattacharyya, A., Bandyopadhyay, S., Pal, A., and T.
Bose, "Constrained Application Protocol (CoAP) Option for
No Server Response", RFC 7967, DOI 10.17487/RFC7967,
August 2016, <https://www.rfc-editor.org/info/rfc7967>.
[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>.
[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>.
[RFC8724] Minaburo, A., Toutain, L., Gomez, C., Barthel, D., and JC.
Zรบรฑiga, "SCHC: Generic Framework for Static Context Header
Compression and Fragmentation", RFC 8724,
DOI 10.17487/RFC8724, April 2020,
<https://www.rfc-editor.org/info/rfc8724>.
Acknowledgements ๐
The authors want to give a huge shoutout (in alphabetical order) to Christian Amsuss, Dominique Barthel, Carsten Bormann, Theresa Enghardt, Thomas Fossati, Klaus Hartke, Benjamin Kaduk, Francesca Palombini, Alexander Pelov, Gรถran Selander, and รric Vyncke ๐ซถ
Authors' Addresses ๐ธ
Ana Minaburo
Acklio
1137A avenue des Champs Blancs
35510 Cesson-Sevigne Cedex
France
Email: ana@ackl.io
Laurent Toutain
Institut MINES TELECOM; IMT Atlantique
CS 17607
2 rue de la Chataigneraie
35576 Cesson-Sevigne Cedex
France
Email: Laurent.Toutain@imt-atlantique.fr
Ricardo Andreasen
Universidad de Buenos Aires
Av. Paseo Colon 850
C1063ACV Ciudad Autonoma de Buenos Aires
Argentina
Email: randreasen@fi.uba.ar
๐ฆ where this page comes from
- ietf: rfc8824 2021-06
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms