CoRE Working Group M. S. Lenders Internet-Draft Intended status: Standards Track M. Tiloca Expires: 1 May 2027 RISE AB 28 October 2026 Oblivious CoAP draft-lenders-core-oblivious-coap-01 Abstract In the Constrained Application Protocol (CoAP), protected requests allow the server to identify the client, also across different and unrelated data exchanges. This document defines Oblivious CoAP, which enables oblivious protected exchanges of CoAP messages for use cases where the identification of the client at the server is not desirable. Discussion Venues This note is to be removed before publishing as an RFC. Discussion of this document takes place on the Constrained RESTful Environments Working Group mailing list (core@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/core/. Source for this draft and an issue tracker can be found at https://gitlab.com/crimson84/draft-lenders-core-oblivious-coap. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 1 May 2027. Lenders & Tiloca Expires 1 May 2027 [Page 1] Internet-Draft Oblivious CoAP October 2026 Copyright Notice Copyright (c) 2026 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, as 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 are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1. Comparison to Oblivious HTTP . . . . . . . . . . . . . . 8 2.2. Comparison to OSCORE . . . . . . . . . . . . . . . . . . 8 3. Key Configuration . . . . . . . . . . . . . . . . . . . . . . 9 4. The OCoAP Option . . . . . . . . . . . . . . . . . . . . . . 11 5. Oblivious CoAP Request . . . . . . . . . . . . . . . . . . . 13 5.1. Request Construction at the Client . . . . . . . . . . . 14 5.2. Request Processing at the Server . . . . . . . . . . . . 17 6. Oblivious CoAP Response . . . . . . . . . . . . . . . . . . . 20 6.1. Response Construction at the Server . . . . . . . . . . . 21 6.2. Response Processing at the Client . . . . . . . . . . . . 24 7. Security Considerations . . . . . . . . . . . . . . . . . . . 28 7.1. Request Replays . . . . . . . . . . . . . . . . . . . . . 28 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 29 8.1. Media Type Registrations . . . . . . . . . . . . . . . . 29 8.2. CoAP Content-Formats Registry . . . . . . . . . . . . . . 30 8.3. CoAP Option Numbers Registry . . . . . . . . . . . . . . 31 8.4. OCoAP Flag Bits Registry . . . . . . . . . . . . . . . . 31 8.5. Expert Review Instructions . . . . . . . . . . . . . . . 32 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 33 9.1. Normative References . . . . . . . . . . . . . . . . . . 33 9.2. Informative References . . . . . . . . . . . . . . . . . 35 Appendix A. Change Log . . . . . . . . . . . . . . . . . . . . . 36 A.1. Since draft-lenders-core-oblivious-coap-00 . . . . . . . 36 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 36 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 39 Lenders & Tiloca Expires 1 May 2027 [Page 2] Internet-Draft Oblivious CoAP October 2026 1. Introduction As in HTTP [RFC9110][RFC9112], protected requests in the Constrained Application Protocol (CoAP) [RFC7252] can identify the client to the server. In HTTP, this can be prevented by using Oblivious HTTP [RFC9458]. Although the ability of the server to identify the client is typically not a problem in CoAP, there are use cases where the identification of the client might not be desirable. For example: * DNS over CoAP [RFC9953] clients might want to hide their identity in a similar way as offered by Oblivious DNS over HTTP [RFC9230]. * A vendor might want to provide anonymous diagnostic reporting or telemetry transmission for their devices. * Clients might want to securely perform anonymous queries at a well-known CoRE Resource Directory [RFC9176], for example to retrieve a number of proxy resources that are used to enable secure CoAP traffic with onion routing [I-D.amsuess-t2trg-onion-coap]. In these cases, even protecting CoAP messages with approaches based on CBOR Object Signing and Encryption (COSE) [RFC9052], such as Object Security for Constrained RESTful Environments (OSCORE) [RFC8613], is either not helpful or not efficient for hiding the client's identity from the server. In particular, such approaches require the client and the server to establish a long-term security context between each other (and potentially between themselves and multiple intermediary hops), which makes the same client identifiable by the server, also across different and unrelated data exchanges. Alternatively, the same client could use different identities to perform different runs of a full-fledged key establishment protocol for protecting different data exchanges with the server, which results in performance penalties. On the other hand, Oblivious HTTP uses Hybrid Public Key Encryption (HPKE) [RFC9180] via a trusted Oblivious Relay Resource (effectively a proxy) that is not colluding with the server, in order to hide the client's identity from the server and obfuscate the data exchange from the perspective of the Oblivious Relay Resource. This document defines Oblivious CoAP, which brings the advantages of such an oblivious exchange to CoAP. Lenders & Tiloca Expires 1 May 2027 [Page 3] Internet-Draft Oblivious CoAP October 2026 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. Readers are expected to be familiar with the terms and concepts related to CoAP [RFC7252], OSCORE [RFC8613], Concise Data Definition Language (CDDL) [RFC8610], Concise Binary Object Representation (CBOR) [RFC8949], CBOR sequences [RFC8742], and HPKE [RFC9180]. In addition, this document uses the following terms. Original CoAP Request: A CoAP request as specified in [RFC7252]. Original CoAP Response: A CoAP response as specified in [RFC7252]. Oblivious CoAP Request: An Original CoAP Request that is encapsulated in an HPKE-encrypted message, see Section 5. _Cmp._ "Encapsulated Request" in [RFC9458]. Oblivious CoAP Response: An Original CoAP Response that is encapsulated in an HPKE-encrypted message, see Section 6. _Cmp._ "Encapsulated Response" in [RFC9458]. Oblivious CoAP Client: An Oblivious CoAP Client originates Oblivious CoAP Requests. It is a client for both the Oblivious Gateway Resource and the Target Resource. When referring to a general CoAP Client as defined in [RFC7252], the term "CoAP Client" is used. Oblivious Proxy Resource: A forward-proxy as specified in Section 5.7.2 of [RFC7252] and acting as an intermediary between the Oblivious CoAP Client and a single Oblivious Gateway Resource. _Cmp._ "Oblivious Relay Resource" in [RFC9458]. Oblivious Gateway Resource: A CoAP resource as defined in Section 1.2 of [RFC7252] that can handle Oblivious CoAP Requests, dispatch the corresponding encapsulated Original CoAP Requests to a Target Resource, receive Original CoAP Responses therefrom, and encapsulate those responses in Oblivious CoAP Responses. _Cmp._ "Oblivious Gateway Resource" in [RFC9458]. Target Resource: The resource that is the target of the Original Lenders & Tiloca Expires 1 May 2027 [Page 4] Internet-Draft Oblivious CoAP October 2026 CoAP Request. It is typically not able to handle Oblivious CoAP Requests or Oblivious CoAP Responses, so Oblivious CoAP is transparent to it. However, it could still be able to handle otherwise encrypted requests and responses such as those protected with OSCORE [RFC8613]. _Cmp._ "Target Resource" in [RFC9458]. 2. Overview In the same spirit as Oblivious HTTP [RFC9458], an Oblivious CoAP Client needs to know the following: * Information to reach an Oblivious Gateway Resource, which in turn might include information about the Target Resource. * A key configuration, including: - The HPKE public key of the Oblivious Gateway Resource and the key identifier associated with that public key. - The set of HPKE algorithms to use with the Oblivious Gateway Resource. * Information to reach an Oblivious Proxy Resource that for all intent and purposes is a CoAP forward-proxy (see Section 5.7.2 of [RFC7252]), which forwards Oblivious CoAP Requests to the Oblivious Gateway Resource and returns the resulting Oblivious CoAP Responses to the Oblivious CoAP Client. With that information, the Oblivious CoAP Client is able to compose a protected Oblivious CoAP Request intended for the Oblivious Gateway Resource, send the Oblivious CoAP Request to the Oblivious Gateway Resource via the Oblivious Proxy Resource, and decrypt and verify the corresponding protected Oblivious CoAP Response composed by the Oblivious Gateway Resource. Since the Oblivious Proxy Resource does not indicate the client's addressing information in the forwarded Oblivious CoAP Request, the Oblivious Gateway Resource does not gain knowledge of the client's identity and is unable to associate different unrelated requests from the Oblivious CoAP Client, due to the use of different HPKE contexts across different and unrelated data exchanges. Furthermore, since the Oblivious Proxy Resource does not know the HPKE private key of the Oblivious Gateway Resource, the Oblivious Proxy Resource cannot create the HPKE context that is necessary for decrypting the Oblivious CoAP Requests and Responses that are sent to and from the Oblivious Gateway Resource. Lenders & Tiloca Expires 1 May 2027 [Page 5] Internet-Draft Oblivious CoAP October 2026 .--------------------------------. | Server | +---------+ +----------+ | +-------------+--------------+ | | Client | | Proxy | | | Gateway | Target | | | | | Resource | | | Resource | Resource | | +----+----+ +----+-----+ | +-----+-------+-------+------+ | | | `-------|---------------|--------' | Oblivious | | | | CoAP Request | | | +---------------->| Oblivious | | | | CoAP Request | | | +------------------->| Original | | | | CoAP Request | | | +-------------->| | | | | | | | Original | | | | CoAP Response | | | Oblivious |<--------------+ | | CoAP Response | | | Oblivious |<-------------------+ | | CoAP Response | | | |<----------------+ | | | | | | Figure 1: Overview of Oblivious CoAP Figure 1 provides an overview of the steps of Oblivious CoAP. Readers familiar with Oblivious HTTP will notice the strong similarities to Figure 1 of [RFC9458] and the steps described in Section 2 of [RFC9458]. Compared to the steps of Oblivious HTTP, there are only minor differences in the steps of Oblivious CoAP, which are outlined below. 1. The Oblivious CoAP Client (Client) composes the Original CoAP Request for a Target Resource, e.g., as described in [RFC7252] or [RFC8323]. 2. Using HPKE with a known key configuration (see Section 3) and according to the process described in Section 5.1, the Client produces a protected Oblivious CoAP Request from the Original CoAP Request. 3. The Client sends the Oblivious CoAP Request to the Oblivious Proxy Resource (Proxy Resource). 4. The Proxy Resource forwards the Oblivious CoAP Request to the Oblivious Gateway Resource (Gateway Resource). Lenders & Tiloca Expires 1 May 2027 [Page 6] Internet-Draft Oblivious CoAP October 2026 5. The Gateway Resource receives the Oblivious CoAP Request, processes it using HPKE with its key configuration, and obtains the Original CoAP Request as a result. 6. The Gateway Resource provides the Original CoAP Request to the Target Resource. The Gateway Resource and the Target Resource could be hosted at different servers or instead at the same server as shown in Figure 1, in which case the Target Resource could even be the same as the Gateway Resource. The following refers to the "server" as the CoAP endpoint at which both the Gateway Resource and the Target Resource are hosted. Once the Gateway Resource receives the Original CoAP Response from the Target Resource, it sends the response as a reply to the Client according to the following steps: 1. Using the receiving HPKE context generated from the Oblivious CoAP Request, the Gateway Resource composes an Oblivious CoAP Response from the Original CoAP Response and sends it to the Proxy Resource. 2. The Proxy Resource forwards the Oblivious CoAP Response back to the Client. 3. The Client receives the Oblivious CoAP Response, processes it using the sending HPKE context generated for the Oblivious CoAP Request, and produces the Original CoAP Response as a result. When a CoAP request/response is specifically an Oblivious CoAP Request/Response, it includes the OCoAP Option defined in Section 4. In addition to single data exchanges like the one discussed above, CoAP supports exchanges where one or more requests can lead to one or more responses. Non-exhaustively, these include: * The use of CoAP *Observe* [RFC7641], for a client to register its interest in receiving unsolicited notification responses from a server, following changes in the representation of a resource at the server. Effectively, this results in one long-standing request followed by multiple related responses. Lenders & Tiloca Expires 1 May 2027 [Page 7] Internet-Draft Oblivious CoAP October 2026 * The use of CoAP *block-wise transfer* [RFC7959] [RFC9177], for a client and a server to split a large "body" of data into different blocks, each of which is sent as the payload of one request or response. Effectively, this results in a sequence of requests/ responses that are related to the transfer of the same body of data from the client/server. To support these exchanges, Oblivious CoAP provides a way to process these multiple, related requests and responses using the same HPKE context, according to information conveyed by the OCoAP Option. 2.1. Comparison to Oblivious HTTP Similar to Oblivious HTTP [RFC9458], Oblivious CoAP has only limited applicability, as it requires support from a willing Oblivious Gateway Resource, which prevents Oblivious CoAP from being used in generic applications. Notably, however, the Oblivious Proxy Resource can be any CoAP forward-proxy that can reach the Oblivious Gateway Resource. In contrast to Oblivious HTTP, Oblivious CoAP does not use a signaling Content-Format, which would bloat the IANA Content-Format registry. Rather, in the same spirit of the OSCORE security protocol, which relies on the OSCORE Option (see [RFC8613]), Oblivious CoAP uses a signaling OCoAP Option (see Section 4), which also conveys information for the correct processing of multiple, related requests and responses using the same HPKE context (see Section 2). Oblivious CoAP is intentionally similar to Oblivious HTTP and usable with generic CoAP forward-proxies, in order to allow for potential Oblivious-CoAP-to-Oblivious-HTTP proxies. These are, however, application-specific and thus out of scope for this document. 2.2. Comparison to OSCORE The security protocol OSCORE [RFC8613] builds on COSE [RFC9052] and provides end-to-end protection of CoAP messages between a client and a server, also in the presence of (untrusted) intermediary proxies from which as much information as possible is hidden by encryption. In contrast to OSCORE, Oblivious CoAP has the advantage that the server cannot correlate two protected requests from the same client, unless that is desired by the client (see Section 5.1). Lenders & Tiloca Expires 1 May 2027 [Page 8] Internet-Draft Oblivious CoAP October 2026 Similar to OSCORE, which relies on the OSCORE Option, Oblivious CoAP relies on the OCoAP Option and thus avoids signaling an Oblivious- CoAP-related Content-Format, while hiding the Content-Format of the Original CoAP Request/Response by encrypting it when producing the Oblivious CoAP Request/Response. Since the key exchange and message protection are left to HPKE, the OCoAP Option can be even simpler: As the same HPKE context could be used to produce multiple, related Oblivious CoAP Requests/Responses (see Section 5.1), the OCoAP Option value identifies the HPKE context used and allows the two endpoints to count the Oblivious CoAP Requests/Responses produced with that context. When using Oblivious CoAP, a field of an Original CoAP Request/ Response is protected to achieve the same security level that is achieved by OSCORE when protecting that field (see Section 4 of [RFC8613]), which results in the same security and privacy implications as in OSCORE (see Sections 12.1 and 12.8 of [RFC8613]). For example, this applies to the protection of CoAP options, which occurs according to the same classes defined for OSCORE (see Section 4.1 of [RFC8613]). 3. Key Configuration A key configuration can be encoded as defined in Section 3 of [RFC9458]. A collection of such key configurations can be distributed using the media type "application/ohttp-keys", potentially through CoAP messages with the corresponding Content- Format registered in Section 8.2. Alternatively, a key configuration can be expressed in an extensible CBOR map [RFC8949] that includes the following elements: * key_id, with map key 0 encoded as a CBOR unsigned integer. The value of this element is a CBOR unsigned integer that encodes the key identifier of the HPKE public key of the Oblivious Gateway Resource. The key identifier is of 8-bit maximum length. * kem_id, with map key 1 encoded as a CBOR unsigned integer. The value of this element is a CBOR unsigned integer that encodes an HPKE Key Encapsulation Mechanism (KEM) identifier (see also Sections 7.1 and 11.1 of [RFC9180]). The HPKE KEM identifier is of 16-bit maximum length. * public_key, with map key 2 encoded as a CBOR unsigned integer. The value of this element is a CBOR byte string that encodes the HPKE public key of the Oblivious Gateway Resource. The length of the public key is Npk bytes. Lenders & Tiloca Expires 1 May 2027 [Page 9] Internet-Draft Oblivious CoAP October 2026 * A set of HPKE symmetric algorithms, with map key 3 encoded as a CBOR unsigned integer. The value of this element is a non-empty CBOR array whose elements are organized into consecutive pairs. Each pair consists of the following elements: - kdf_id, a CBOR unsigned integer that encodes an HPKE Key Derivation Function (KDF) identifier of 16-bit maximum length (see also Sections 7.2 and 11.2 of [RFC9180]). - aead_id, a CBOR unsigned integer that encodes an HPKE Authenticated Encryption with Additional Data (AEAD) identifier of 16-bit maximum length (see also Sections 7.3 and 11.3 of [RFC9180]). Figure 2 shows the CDDL notation [RFC8610] of the CBOR-encoded HPKE key configuration. Later specifications can extend the CBOR map via the $$ocoap-key-config extension point. max-uint8 = 0..255 max-uint16 = 0..65535 key_id = max-uint8 kem_id = max-uint16 kdf_id = max-uint16 aead_id = max-uint16 public_key = bstr hpke_symmetric_algorithm = ( kdf_id, aead_id, ) key_id_key = 0 kem_id_key = 1 public_key_key = 2 hpke_symmetric_algorithm_key = 3 ocoap-key-config = { $$ocoap-key-config } $$ocoap-key-config //= ( key_id_key => key_id, kem_id_key => kem_id, public_key_key => public_key, hpke_symmetric_algorithm_key => [ +hpke_symmetric_algorithm ], ) Figure 2: Format of the CBOR-encoded HPKE Key Configuration Lenders & Tiloca Expires 1 May 2027 [Page 10] Internet-Draft Oblivious CoAP October 2026 A collection of key configurations of type ocoap-key-config can be distributed using the media type "application/ocoap-keys+cbor-seq" registered in Section 8.1, potentially through CoAP messages with the corresponding Content-Format registered in Section 8.2. In particular, the media type "application/ocoap-keys+cbor-seq" denotes the binary encoding of a CBOR sequence [RFC8742], where each element of the sequence is a CBOR map representing a key configuration of type ocoap-key-config. An Oblivious CoAP Client that receives an "application/ocoap- keys+cbor-seq" object with encoding errors might be able to recover one or more key configurations. Differences in how key configurations are recovered might be exploited to segregate Clients, so Clients MUST discard incorrectly encoded key configuration collections. 4. The OCoAP Option Oblivious CoAP Requests and Responses include the Oblivious CoAP Option (OCoAP Option) defined in this section. The OCoAP Option has the properties summarized in Table 1, which extends Table 4 of [RFC7252]. The option is Critical, Safe-to-Forward, part of the Cache-Key, and not repeatable. +=====+===+===+===+===+=======+========+========+=========+ | No. | C | U | N | R | Name | Format | Length | Default | +=====+===+===+===+===+=======+========+========+=========+ | TBD | x | | | | OCoAP | (*) | 0-255 | (none) | +-----+---+---+---+---+-------+--------+--------+---------+ Table 1: The OCoAP Option. C=Critical, U=Unsafe, N=NoCacheKey, R=Repeatable (*) If the length of the option value is greater than 0, the OCoAP Option value has the format shown in Figure 3. The value of the non-empty OCoAP Option SHALL contain the OCoAP flag bits, the count parameter, and the id_ctx parameter as follows: 0 1 2 3 4 5 6 7 <--- n+1 bytes ---> +-+-+-+-+-+-+---+-------------------+-----------------+ |0 0 0 0 0|c| n | count | id_ctx (if any) | +-+-+-+-+-+-+---+-------------------+-----------------+ Figure 3: The Non-Empty OCoAP Option Value Lenders & Tiloca Expires 1 May 2027 [Page 11] Internet-Draft Oblivious CoAP October 2026 * The first byte, containing the OCoAP flag bits, encodes the following set of bits and the length of the count parameter in the option value: - The two least significant bits encode the unsigned integer n, which is the count length in bytes minus 1. - The third least significant bit c is the ID Context flag. It is set to 1 if and only if id_ctx is present in the option value. - The fourth-to-eighth least significant bits are reserved for future use. These bits SHALL be set to zero when not in use. According to this specification, if any of these bits are set to 1, the message is considered to be malformed and the processing of the OCoAP Option fails. The OCoAP flag bits are registered in the "OCoAP Flag Bits" registry defined in Section 8.4. * The following n+1 bytes encode the value of the count parameter as an unsigned integer in network byte order. In an Oblivious CoAP Request/Response, count is the number of Oblivious CoAP Requests/Responses that have been protected before the present one by using the same HPKE context. That is, count=0 marks the first Oblivious CoAP Request/Response protected with a given HPKE context. The Oblivious CoAP Client and the Oblivious Gateway Resource use two 32-bit unsigned integer counters to keep track of count, separately for the Oblivious CoAP Requests and the Oblivious CoAP Responses protected with a given HPKE context. Since n in the OCoAP Option value can be at most 3, this leaves enough room to represent the value of count as a 32-bit unsigned integer. * The remaining bytes encode the value of the id_ctx parameter, if the c flag is set (c=1). The value of id_ctx is an opaque identifier of the HPKE context used for processing the present Oblivious CoAP message. Note that id_ctx MUST be the last field of the OCoAP Option value if c=1, even in the case in which reserved bits are used and additional fields are added to it. If the OCoAP Option value is empty, i.e., its length is 0, then it is assumed that count=0 and c=0, i.e., the empty value is equivalent to the OCoAP Option value 0x0000. Lenders & Tiloca Expires 1 May 2027 [Page 12] Internet-Draft Oblivious CoAP October 2026 The length of the OCoAP Option value thus depends on the presence and length of count and id_ctx as specified in this section, and on the presence and length of additional parameters, as defined in future documents registering those parameters. The length of the OCoAP Option value MUST NOT exceed 255 bytes. To avoid the OCoAP Option value being larger than necessary, the following applies: * If the OCoAP flag bits consist of a single byte 0x00 and count=0, the sender endpoint SHOULD set the value of the OCoAP Option to empty. Otherwise, * The sender endpoint SHOULD use the shortest possible length for count. That is, a count value between 0 and 255 SHOULD be encoded in 1 byte (n=0), a count value between 256 and 65535 SHOULD be encoded in 2 bytes (n=1), and so on. The OCoAP Option is of Class I for OSCORE [RFC8613] and is accordingly processed by OCoAP (see Section 2.2). That is, the OCoAP Option is included in the associated data aad when processing an Oblivious CoAP Request/Response, consistent with what is recommended in Section 9.7.1 of [RFC9180] (see also Section 5.1 and Section 6.1 of the present document). 5. Oblivious CoAP Request An Oblivious CoAP Request uses the method POST or FETCH [RFC8132], includes the OCoAP Option (see Section 4), and conveys a payload. The format of the payload depends on the count value specified by the OCoAP Option. If count=0, including when the OCoAP Option has empty value, the payload is the concatenation of: * The key identifier key_id from the key configuration used to protect the Original CoAP Request (see Section 3), as an 8-bit unsigned integer. * The HPKE KEM identifier kem_id from the same key configuration, as a 16-bit unsigned integer. * One of the HPKE KDF identifiers kdf_id from the KDF-AEAD identifier pairs from the same key configuration, as a 16-bit unsigned integer. Lenders & Tiloca Expires 1 May 2027 [Page 13] Internet-Draft Oblivious CoAP October 2026 * The HPKE AEAD identifier aead_id that is paired with the kdf_id above in the KDF-AEAD identifier pairs from the same key configuration, as a 16-bit unsigned integer. * The encapsulated KEM shared secret enc that is produced when computing the HPKE context used to protect the Original CoAP Request. The length of enc is equal to Nenc bytes and is defined by the Encap() function of the HPKE KEM identified by kem_id (see Section 4 of [RFC9180]). * The HPKE ciphertext ct produced when protecting the Original CoAP Request. The length of ct can be derived by subtracting 7 bytes (for the enclosed identifiers) and Nenc bytes (for enc) from the CoAP payload length. This construct is equivalent to the Encapsulated Request structure defined in Section 4.1 of [RFC9458]. If count>0, the payload is the HPKE ciphertext ct produced when protecting the Original CoAP Request. 5.1. Request Construction at the Client To construct an Oblivious CoAP Request from the Original CoAP Request, the Oblivious CoAP Client (Client) first picks the following values from the key configuration used: * The key identifier key_id and the corresponding kem_id. * The public key public_key identified by key_id, i.e., the static public key of the Oblivious Gateway Resource. * A pair of KDF algorithm (identified by kdf_id) and AEAD algorithm (identified by aead_id) from the symmetric algorithm collection in the key configuration. Using those parameters, the Client performs the following steps: 1. If the Original CoAP Request is the first request in the data exchange, compute a sending HPKE context sctxt by invoking the HPKE procedure SetupBaseS(pkR, info) (see Section 5.1.1 of [RFC9180]), where: * pkR takes public_key. * info takes the concatenation of: the ASCII-encoded string of the label "ocoap_request", the byte 0x00, key_id as an 8-bit unsigned integer, kem_id as a 16-bit unsigned integer, kdf_id Lenders & Tiloca Expires 1 May 2027 [Page 14] Internet-Draft Oblivious CoAP October 2026 as a 16-bit unsigned integer, and aead_id as a 16-bit unsigned integer. All these unsigned integers are in network byte order. The procedure returns the sending HPKE context sctxt and an encapsulated KEM shared secret enc. Specifically, enc is the ephemeral public key of the Client when using a KEM that is based on Diffie-Hellman (DH) or Non-Interactive Key Exchange (NIKE) primitives, or a KEM ciphertext otherwise. Then, set the 32-bit unsigned integer counter i for sctxt to 0. Set the 32-bit unsigned integer counter j for sctxt to not initialized. The identifier id_rctxt of the receiving HPKE context is unknown at this point. In a typical single-request-single-response exchange, the Original CoAP Request in the exchange is trivially the first one. Within an extended data exchange, the first Original CoAP Request can be, for example, an original Observe registration request [RFC7641], or a request conveying/requesting the first block of a block-wise transfer [RFC7959] [RFC9177]. 2. Ensure that the CoAP options in the Original CoAP Request specify the URI of the Oblivious Gateway Resource to which the Oblivious Proxy Resource will have to forward the Oblivious CoAP Request. (In general, the Oblivious Gateway Resource will interpret such a URI in order to forward the recovered Original CoAP Request to the Target Resource.) To this end, the Client can specify the URI as a string in the Proxy-Uri Option, or by using the Proxy-Scheme Option together with the Uri-* options (see Section 5.10.2 of [RFC7252]). Alternatively, the Client can rely on the analogous options defined in [I-D.ietf-core-href], i.e., the Proxy-Cri Option conveying a Constrained Resource Identifier (CRI) equivalent to the URI, or the Proxy-Scheme-Number Option together with the Uri-* options. When applicable, the Client can specify the URI path of the URI by using the Uri-Path-Abbrev Option [I-D.ietf-core-uri-path-abbrev], consistent with the restrictions defined in Section 2.4 of [I-D.ietf-core-uri-path-abbrev]. Lenders & Tiloca Expires 1 May 2027 [Page 15] Internet-Draft Oblivious CoAP October 2026 Note that the URI path component and the URI query component are going to be encrypted when computing the Oblivious CoAP Request. Therefore, the CoAP server that receives the Oblivious CoAP Request can effectively rely only on the URI scheme and the URI authority component of the request URI, in order to identify the Oblivious Gateway Resource to which the Oblivious CoAP Request is addressed. 3. Compose an OCoAP Option such that: * count is set to the value of the counter i. * id_ctx is set to the identifier id_rctxt if that is known, or it is omitted otherwise. Then, encode the OCoAP Option value as defined in Section 4 and add the OCoAP Option to the Original CoAP Request. 4. Construct the associated data aad as the concatenation of: * key_id as an 8-bit unsigned integer, kem_id as a 16-bit unsigned integer, kdf_id as a 16-bit unsigned integer, and aead_id as a 16-bit unsigned integer. All these unsigned integers are in network byte order. * The CoAP options of Class I for OSCORE [RFC8613] that are present in the Original CoAP Request, which also include the OCoAP Option composed at Step 3. This set of options is encoded like the value of the CBOR byte string options in the aad_array of OSCORE (see Section 5.4 of [RFC8613]). That is, the Client needs to recalculate the Option Deltas of those options. 5. Construct the plaintext pt in the same manner as the plaintext is constructed in OSCORE (see Section 5.3 of [RFC8613]), i.e., as the concatenation of: * The 8-bit Code of the Original CoAP Request. * The CoAP options of Class E for OSCORE [RFC8613] that are present in the Original CoAP Request, with their Option Deltas recalculated accordingly. * If a payload is present in the Original CoAP Request, a one- byte Payload Marker 0xff (see Section 3 of [RFC7252]) followed by the payload of the Original CoAP Request. Lenders & Tiloca Expires 1 May 2027 [Page 16] Internet-Draft Oblivious CoAP October 2026 6. Invoke the Seal() method on sctxt (see Section 5.2 of [RFC9180]), providing the associated data aad from Step 4 as the first parameter and the plaintext pt from Step 5 as the second parameter. The Seal() method returns the ciphertext ct or an error on failure. If the method fails, the client MUST terminate this procedure. 7. Construct the Oblivious CoAP Request from the Original CoAP Request as follows: * Replace the Code with FETCH if the Original CoAP Request contains an Observe Option, or with POST otherwise. * Remove all the CoAP options of Class E for OSCORE [RFC8613] and recalculate the Option Deltas of the remaining CoAP options (including the OCoAP Option added at Step 3). * Add a Payload Marker if the Original CoAP Request had no payload. * Remove the payload, if present in the Original CoAP Request. * Add the payload defined in Section 5, consistent with the values in the previous steps of the present procedure. 8. Increment the counter i for sctxt by 1. Finally, the Client sends the Oblivious CoAP Request to the Oblivious Proxy Resource and retains the sending HPKE context sctxt. The Oblivious Proxy Resource then forwards the Oblivious CoAP Request to the Oblivious Gateway Resource (see Section 5.7 of [RFC7252]). 5.2. Request Processing at the Server When a CoAP server hosting an Oblivious Gateway Resource receives an Oblivious CoAP Request (i.e., a request that includes an OCoAP Option), the server performs the operations described in Section 5.1 in reverse, as defined below. 1. The server reads the value of the OCoAP Option, from which it determines the value of count and of the flag bit c. As per Section 4, the empty option value is equivalent to the option value 0x0000, i.e., count=0 and c=0. Lenders & Tiloca Expires 1 May 2027 [Page 17] Internet-Draft Oblivious CoAP October 2026 Then, the server refers to the key configuration associated with the Oblivious Gateway Resource addressed by the Oblivious CoAP Request and proceeds as follows. * If count>0 and c=1, retrieve ct as the payload of the Oblivious CoAP Request. Then, move to Step 2. * If count=0 and c=0, parse the payload of the Oblivious CoAP Request into: key_id, kem_id, kdf_id, aead_id, enc, and ct. In particular, the four identifiers have a well-known, fixed length, the HPKE KEM identified by kem_id implies the length of enc, and ct is the remainder of the payload after enc. If key_id does not identify an HPKE public key of the server that matches the HPKE KEM identified by kem_id, the server MUST reply with a 4.00 (Bad Request) error response and MUST terminate this procedure. Otherwise, the server retrieves skR, i.e., its HPKE private key associated with the HPKE public key identified by key_id. If kdf_id and aead_id do not identify a KDF and AEAD algorithm pair that the server is willing to use with skR, the server MUST reply with a 4.00 (Bad Request) error response and MUST terminate this procedure. Otherwise, move to Step 2. * If none of the above applies, the server MUST reply with a 4.02 (Bad Option) error response and MUST terminate this procedure. 2. The server proceeds as follows, depending on the value of count. * If count=0, compute a receiving HPKE context rctxt by invoking the HPKE procedure SetupBaseR(enc, skR, info) (see Section 5.1.1 of [RFC9180]), where: - The first parameter takes the encapsulated KEM shared secret enc retrieved from the payload of the Oblivious CoAP Request. - The second parameter takes the HPKE private key skR of the server. Lenders & Tiloca Expires 1 May 2027 [Page 18] Internet-Draft Oblivious CoAP October 2026 - The third parameter info takes the same as the info parameter of the SetupBaseS() when invoked by the Oblivious CoAP Client at Step 1 of Section 5.1. In particular, the four HPKE identifiers are retrieved from the payload of the Oblivious CoAP Request. The procedure returns the receiving HPKE context rctxt. The server generates a unique binary identifier id_ctx and stores rctxt as associated with id_ctx. Then, the server sets a 32-bit unsigned integer counter k for rctxt to 0. * If count>0, the server retrieves id_ctx from the OCoAP Option of the Oblivious CoAP Request and uses it to retrieve the receiving HPKE context rctxt associated with id_ctx. If the server does not successfully retrieve a receiving HPKE context, the server MUST reply with a 4.00 (Bad Request) error response and MUST terminate this procedure. 3. Construct the associated data aad as described at Step 4 of Section 5.1, with the difference that the CoAP options of Class I to consider are those that are present in the received Oblivious CoAP Request. 4. Invoke the Open() method of the previously computed HPKE context rctxt (see Section 5.2 of [RFC9180]), providing the associated data aad from Step 3 as the first parameter and the ciphertext ct retrieved from the payload of the Oblivious CoAP Request as the second parameter. The Open() method returns the plaintext pt or an error on failure. If the method fails, the server MUST reply with a 4.00 (Bad Request) error response, MUST discard the Oblivious CoAP Request, and MUST terminate this procedure. 5. Parse pt into: the 8-bit Code of the Original CoAP Request, the CoAP options of Class E for OSCORE that were present in the Original CoAP Request, the one-byte Payload Marker 0xff (if present), and, if the Payload Marker 0xff is found, the payload of the Original CoAP Request. If the parsing fails, the server MUST reply with a 4.00 (Bad Request) error response. Lenders & Tiloca Expires 1 May 2027 [Page 19] Internet-Draft Oblivious CoAP October 2026 6. Reconstruct the Original CoAP Request from the Oblivious CoAP Request as follows: * Replace the Code of the Oblivious CoAP Request with the Code from pt. * Remove the OCoAP Option from the Oblivious CoAP Request. * Add the CoAP options from pt and recalculate the Option Deltas of all the CoAP options in the updated option set. * Remove the Payload Marker 0xff and the payload from the Oblivious CoAP Request. * If the Payload Marker 0xff and a payload are present in pt, add those in the same order. Finally, the server provides the Original CoAP Request to the Target Resource and retains the receiving HPKE context rctxt. 6. Oblivious CoAP Response An Oblivious CoAP Response has Response Code 2.04 (Changed) or 2.05 (Content), includes the OCoAP Option (see Section 4), and conveys a payload. The format of the payload depends on the count value specified by the OCoAP Option. If count=0, including when the OCoAP Option has empty value, the payload is the concatenation of: * A server-generated response_nonce of length max(Nn, Nk) bytes. The Nn and Nk values correspond to parameters of the AEAD used in HPKE, as per Section 7.3 of [RFC9180] or the "HPKE AEAD Identifiers" IANA registry [IANA.HPKE-AEAD-Identifiers]. * The HPKE ciphertext ct produced when protecting the Original CoAP Response. The length of ct can be derived by subtracting max(Nn, Nk) bytes from the CoAP payload length. This construct is equivalent to the Encapsulated Response structure defined in Section 4.2 of [RFC9458]. If count>0, the payload is the HPKE ciphertext ct produced when protecting the Original CoAP Response. Lenders & Tiloca Expires 1 May 2027 [Page 20] Internet-Draft Oblivious CoAP October 2026 6.1. Response Construction at the Server To construct an Oblivious CoAP Response from the Original CoAP Response received from the Target Resource, the server uses the receiving HPKE context rctxt that was used to process the corresponding Oblivious CoAP Request (see Section 5.2). In particular, the server performs the following steps: 1. Retrieve the counter k for rctxt. If k>0, move to Step 7, otherwise move to Step 2. 2. Export a secret secret from rctxt, using the string "ocoap_response" as the exporter_context parameter for the Export interface of rctxt (see Section 5.3 of [RFC9180]). The length of secret is max(Nn, Nk), where Nn and Nk are the length of the AEAD nonce and key that are associated with rctxt. 3. Generate a random value of length max(Nn, Nk) bytes, called response_nonce. 4. Extract a pseudorandom key prk using the Extract function provided by the KDF algorithm associated with rctxt (see Section 4 of [RFC9180]). The ikm input to this function is secret from Step 2; the salt input is the concatenation of: the encapsulated KEM shared secret enc from the payload of the Original CoAP Request and response_nonce from Step 3. 5. Use the Expand function provided by the same KDF algorithm (see Section 4 of [RFC9180]) to create an AEAD key aead_key of length Nk bytes, i.e., the length of the keys used by the AEAD associated with rctxt. Generating aead_key uses the pseudorandom key prk from Step 4 as the prk parameter and the string "key" as the info parameter for the Expand function, respectively. Then, store aead_key in association with rctxt. 6. Use the same Expand function to create an AEAD Base IV aead_base_iv of length Nn bytes, i.e., the length of the nonces used by the AEAD associated with rctxt. Generating aead_base_iv uses the pseudorandom key prk from Step 4 as the prk parameter and the string "base_iv" as the info parameter for the Expand function, respectively. Then, store aead_base_iv in association with rctxt. Lenders & Tiloca Expires 1 May 2027 [Page 21] Internet-Draft Oblivious CoAP October 2026 7. Compose an OCoAP Option such that: * count is set to the value of the counter k of rctxt. * id_ctx is set to the identifier id_rctxt of rctxt if both of the following conditions apply, or it is omitted otherwise. - k=0. - The server anticipates that, after the present first Oblivious CoAP Response under construction, it might send further Oblivious CoAP Responses in this data exchange, hence using the same receiving HPKE context rctxt to construct those. For instance, this is the case when the data exchange is a registered observation [RFC7641] (i.e., the Oblivious CoAP Request was an original Observe registration request and later Observe notifications are expected to be sent), or when the data exchange is an active block-wise transfer [RFC7959] [RFC9177] (i.e., the server expects to send/ solicit further blocks to/from the Oblivious Client). Then, encode the OCoAP Option value as defined in Section 4 and add the OCoAP Option to the Original CoAP Response. 8. Construct the associated data aad as the concatenation of: * An 8-bit unsigned integer encoding the length in bytes of the value of the OCoAP Option from the Original CoAP Request to which the Oblivious CoAP Response replies. * The value of the OCoAP Option from that Original CoAP Request. * The CoAP options of Class I for OSCORE [RFC8613] that are present in the Original CoAP Response, which also include the OCoAP Option composed at Step 7. This set of options is encoded like the value of the CBOR byte string options in the aad_array of OSCORE (see Section 5.4 of [RFC8613]). That is, the server needs to recalculate the Option Deltas of those options. 9. Construct the plaintext pt in the same manner as the plaintext is constructed in OSCORE (see Section 5.3 of [RFC8613]), i.e., as the concatenation of: Lenders & Tiloca Expires 1 May 2027 [Page 22] Internet-Draft Oblivious CoAP October 2026 * The 8-bit Response Code of the Original CoAP Response. * The CoAP options of Class E for OSCORE [RFC8613] that are present in the Original CoAP Response, with their Option Deltas recalculated accordingly. * If a payload is present in the Original CoAP Response, a one- byte Payload Marker 0xff (see Section 3 of [RFC7252]) followed by the payload of the Original CoAP Response. 10. Compute the AEAD nonce aead_nonce of length Nn bytes, by XORing: * The aead_base_iv associated with rctxt; and * The value of the counter k of rctxt from Step 1, left-padded with 0 to the exact length of aead_base_iv. 11. Invoke the AEAD function Seal() of the AEAD associated with rctxt (see Section 4 of [RFC9180]), providing aead_key associated with rctxt as the first parameter, aead_nonce from Step 10 as the second parameter, the associated data aad from Step 8 as the third parameter, and the plaintext pt from Step 9 as the fourth parameter. The AEAD function Seal() returns the ciphertext ct or an error on failure. If the function fails, the server MUST reply with a 5.00 (Internal Server Error) response, MUST discard the Oblivious CoAP Request and the Original CoAP Response, and MUST terminate this procedure. 12. Construct the Oblivious CoAP Response from the Original CoAP Response as follows: * Replace the Response Code with 2.05 (Content) if the Original CoAP Response contains an Observe Option, or with 2.04 (Changed) otherwise. * Remove all the CoAP options of Class E for OSCORE [RFC8613] and recalculate the Option Deltas of the remaining CoAP options (which include the OCoAP Option added at Step 7). * Add a Payload Marker if the Original CoAP Response had no payload. * Remove the payload, if present in the Original CoAP Response. Lenders & Tiloca Expires 1 May 2027 [Page 23] Internet-Draft Oblivious CoAP October 2026 * Add the payload defined in Section 6, consistent with the values in the previous steps of the present procedure. 13. Increment the counter k for rctxt by 1. Finally, the server sends the Oblivious CoAP Response to the Oblivious Proxy Resource, which forwards it back to the Oblivious Client (see Section 5.7 of [RFC7252]) // TBD: Lost ACK responses could potentially trigger a new creation // of rctxt. Is that a problem? // // -- —Martine Lenders // I don't think it's a problem; it's actually good. Following the // lost ACK with piggybacked the first Oblivious CoAP Response to the // first Oblivious CoAP Request: i) If the Client retransmits the // same Oblivious CoAP Request, the server derives the same receiving // HPKE Context, but then it derives a different response_nonce, // hence the AEAD keying material will be different from the previous // HPKE context. ii) If the Client transmits a brand new Oblivious // CoAP Request, enc is different in the first place and the server // creates a totally different receiving HPKE context. // // -- —Marco Tiloca // Still, let's keep an eye out for computational overhead in actual // implementations. // // -- —Martine Lenders. If the server anticipates that it might send further Oblivious CoAP Responses in this data exchange (see also Step 7 above), the server retains the receiving HPKE context rctxt. Otherwise, the server discards rctxt. 6.2. Response Processing at the Client When the Oblivious CoAP Client (Client) receives an Oblivious CoAP Response (i.e., a response that includes an OCoAP Option), the Client retrieves the sending HPKE context sctxt that was used to construct the corresponding Oblivious CoAP Request. Then, the Client performs the operations described in Section 6.1 in reverse, as defined below. 1. The Client reads the value of the OCoAP Option, from which it determines the value of count and of the flag bit c. As per Section 4, the empty option value is equivalent to the option value 0x0000, i.e., count=0 and c=0. * If count>0 and c=0, retrieve ct as the payload of the Oblivious CoAP Response. Then, move to Step 6. Lenders & Tiloca Expires 1 May 2027 [Page 24] Internet-Draft Oblivious CoAP October 2026 * If count=0, parse the payload of the Oblivious CoAP Response into response_nonce and ct. In particular, the length of response_nonce is max(Nn, Nk), where Nn and Nk are the length of the AEAD key and nonce that are associated with sctxt, and ct is the remainder of the payload after response_nonce. Furthermore, if c=1, retrieve the binary identifier of the receiving HPKE context from the id_ctx field in the received OCoAP Option, and store it as the identifier id_rctxt for the construction of further Oblivious CoAP Requests with sctxt (see Step 3 of Section 5.1). Then, move to Step 2. * If none of the above applies, the Client MUST discard the Oblivious CoAP Response and MUST terminate this procedure. 2. Export the secret secret as described at Step 2 of Section 6.1, with the difference that sctxt is used instead of rctxt. 3. Extract a pseudorandom key prk using the Extract function provided by the KDF algorithm associated with sctxt (see Section 4 of [RFC9180]). The ikm input to this function is secret from Step 2; the salt input is the concatenation of: the encapsulated KEM shared secret enc from the payload of the Original CoAP Request and response_nonce from the payload of the received Oblivious CoAP Response. 4. Use the Expand function provided by the same KDF algorithm used in Step 3 to create the AEAD key aead_key of length Nk, i.e., the length of the keys used by the AEAD associated with sctxt. Generating aead_key uses the pseudorandom key prk from Step 3 and the string "key", as the prk parameter and the info parameter for the Expand function, respectively. Then, store aead_key in association with sctxt. 5. Use the same Expand function to create an AEAD Base IV aead_base_iv of length Nn bytes, i.e., the length of the nonces used by the AEAD associated with sctxt. Generating aead_base_iv uses the pseudorandom key prk from Step 3 and the string "base_iv" as the prk parameter and the info parameter for the Expand function, respectively. Lenders & Tiloca Expires 1 May 2027 [Page 25] Internet-Draft Oblivious CoAP October 2026 Then, store aead_base_iv in association with sctxt. 6. Construct the associated data aad as described at Step 8 of Section 6.1, with the difference that the CoAP options of Class I to consider are those that are present in the received Oblivious CoAP Response. 7. Compute the AEAD nonce aead_nonce of length Nn bytes, by XORing: * The aead_base_iv associated with sctxt; and * The value of the counter count retrieved at Step 1 from the OCoAP Option of the received Oblivious CoAP Response, left- padded with 0 to the exact length of aead_base_iv. 8. Invoke the AEAD function Open() of the AEAD associated with sctxt (see Section 4 of [RFC9180]), providing aead_key associated with sctxt as the first parameter, aead_nonce from Step 7 as the second parameter, the associated data aad from Step 6 as the third parameter, and the ciphertext ct from the payload of the received Oblivious CoAP Response as the fourth parameter. The AEAD function Open() returns the plaintext pt or an error on failure. If the function fails, the Client MUST discard the Oblivious CoAP Response and MUST terminate this procedure. 9. If the OCoAP Option value in the received Oblivious CoAP Response specifies count=0 and the counter j for sctxt is not initialized yet (see Section 5.1), then initialize j to 0, and move to Step 10. Otherwise, the Client MUST check whether it already used sctxt to decrypt a previous Oblivious CoAP Response whose OCoAP Option specified the same count as the present Oblivious CoAP Response: * If that is the case (i.e., a replay is detected), the Client MUST discard the Oblivious CoAP Response and MUST terminate this procedure. * Otherwise, if count specified in the OCoAP Option of the present Oblivious CoAP Response is such that count>j, then j takes the value of count. This keeps track of the most recent received Oblivious CoAP Response processed with sctxt, which allows the Client application to order such Oblivious CoAP Responses with respect to one another. Lenders & Tiloca Expires 1 May 2027 [Page 26] Internet-Draft Oblivious CoAP October 2026 This is analogous to what a CoAP client does for the replay- check and ordering of Observe notifications [RFC7641] when using OSCORE, by relying on the Partial IV of the OSCORE Option value and the local Notification Number (see Sections 4.1.3.5.2, 7.4.1, and 8.4.2 of [RFC8613]). 10. Parse pt into: the 8-bit Code of the Original CoAP Response, the CoAP options of Class E for OSCORE that were present in the Original CoAP Response, the one-byte Payload Marker 0xff (if present), and, if the Payload Marker 0xff is found, the payload of the Original CoAP Response. If the parsing fails, the Client MUST discard the Oblivious CoAP Response and MUST terminate this procedure. 11. Reconstruct the Original CoAP Response from the Oblivious CoAP Response as follows: * Replace the Response Code of the Oblivious CoAP Response with the Response Code from pt. * Remove the OCoAP Option from the Oblivious CoAP Response. * Add the CoAP options from pt and recalculate the Option Deltas of all the CoAP options in the updated option set. * Remove the Payload Marker 0xff and the payload from the Oblivious CoAP Response. * If the Payload Marker 0xff and a payload are present in pt, add those in the same order. The Client discards the sending HPKE context sctxt if any of the following applies, or retains it otherwise: * The OCoAP Option value of the received Oblivious CoAP Response specifies count=0 and c=0. * The Client will not send further Oblivious CoAP Requests and does not expect to receive further Oblivious CoAP Responses in this data exchange, which would require using sctxt. Lenders & Tiloca Expires 1 May 2027 [Page 27] Internet-Draft Oblivious CoAP October 2026 An example with such further Oblivious CoAP Requests/Responses is the case where the data exchange is a registered observation [RFC7641], hence the Client might send a cancellation request (see Section 3.6 of [RFC7641]) and could receive Observe notifications. Another example is the case where the data exchange is an active block-wise transfer [RFC7959] [RFC9177], hence the Client expects to send/receive further blocks to/from the server hosting the Oblivious Gateway Resource). 7. Security Considerations The security considerations that apply to this document are largely the same as those compiled in [RFC7252], [RFC8323], and [RFC9180] as well as in [RFC8613] and [RFC9458], if applicable to HPKE or CoAP. The following security considerations also apply. 7.1. Request Replays As with Oblivious HTTP [RFC9458], Oblivious CoAP Requests can be easily replayed by the Oblivious Proxy Resource or an external adversary. Two approaches can mitigate this issue: 1. As with Cacheable OSCORE [I-D.ietf-core-cacheable-oscore], the fact that the request was replayed can be disregarded if the received Oblivious CoAP Request uses a safe REST method (see Section 9.2.1 of [RFC9110]) and the server is able to verify that it is indeed safe to proceed with handling the request. 2. For non-safe Oblivious CoAP Requests and as a more general approach, the server can identify an Oblivious CoAP Request to be a replay, in which case it stops processing that request, unless handling that request is deemed appropriate. To practically detect replayed Oblivious CoAP Requests, the server can rely on the following information: * For the first Oblivious CoAP Request of a data exchange (i.e., with the OCoAP Option indicating count=0 and c=0), the server can rely on the encapsulated KEM shared secret enc conveyed in the request payload. That is, like in Oblivious HTTP (see Section 6.5 of [RFC9458]), the server can use enc in place of a nonce to uniquely identify the Oblivious CoAP Request and detect if it has been previously received. Lenders & Tiloca Expires 1 May 2027 [Page 28] Internet-Draft Oblivious CoAP October 2026 Specifically, the server can rely on enc as is when that is the DH/NIKE ephemeral public key of the Oblivious Client, or on a (hash-based) identifier of enc when that is a KEM ciphertext. * For follow-up Oblivious CoAP Requests throughout a data exchange, the server can rely on the counter count in the integrity-protected OCoAP Option of those requests, e.g., by evaluating it against a Replay Window paired with the receiving HPKE context rctxt. A protected Echo Option [RFC9175] can further increase replay protection, similar to how it is used with OSCORE. 8. IANA Considerations This document has the following actions for IANA. Note to RFC Editor: Please replace all occurrences of "[RFC-XXXX]" with the RFC number of this specification and delete this paragraph. 8.1. Media Type Registrations This document registers the media type "application/ocoap-keys+cbor- seq". This registration follows the procedures specified in [RFC6838]. * Type name: application * Subtype name: ocoap-keys+cbor-seq * Required parameters: N/A * Optional parameters: N/A * Encoding considerations: Must be encoded as a CBOR sequence [RFC8742] of CBOR maps [RFC8949]. Each of the CBOR maps is a key configuration for Oblivious CoAP encoded as defined in Section 3 of [RFC-XXXX]. * Security considerations: See Section 7 of [RFC-XXXX]. * Interoperability considerations: N/A * Published specification: [RFC-XXXX] Lenders & Tiloca Expires 1 May 2027 [Page 29] Internet-Draft Oblivious CoAP October 2026 * Applications that use this media type: Applications that need to describe, distribute, and store a CBOR-encoded representation of a key configuration for Oblivious CoAP (see Section 3 of [RFC- XXXX]). * Fragment identifier considerations: N/A * Additional information: N/A * Person & email address to contact for further information: CoRE WG mailing list (core@ietf.org) or IETF Applications and Real-Time Area (art@ietf.org) * Intended usage: COMMON * Restrictions on usage: None * Author/Change controller: IETF * Provisional registration: No 8.2. CoAP Content-Formats Registry IANA is asked to add the following entries to the "CoAP Content- Formats" registry [IANA.CoAP-Content-Formats] within the "Constrained RESTful Environments (CoRE) Parameters" registry group. Content Type: application/ohttp-keys Content Coding: - ID: TBD (value between 0 and 255) Reference: [RFC-XXXX] Content Type: application/ocoap-keys+cbor-seq Content Coding: - ID: TBD (value between 0 and 255) Reference: [RFC-XXXX] Note to RFC Editor: In the table above, please replace TBD with the registered Content-Format ID. Then, please delete this paragraph. Lenders & Tiloca Expires 1 May 2027 [Page 30] Internet-Draft Oblivious CoAP October 2026 8.3. CoAP Option Numbers Registry IANA is asked to add the following option number to the "CoAP Option Numbers" registry [IANA.CoAP-Option-Numbers] within the "Constrained RESTful Environments (CoRE) Parameters" registry group. +========+=======+============+ | Number | Name | Reference | +========+=======+============+ | TBD | OCoAP | [RFC-XXXX] | +--------+-------+------------+ Table 2: Registration in the CoAP Option Numbers Registry For the OCoAP Option, the preferred value range is 0-255. Note to RFC Editor: In the table above, please replace TBD with the registered option number. Then, please delete this paragraph and the previous paragraph. 8.4. OCoAP Flag Bits Registry This document establishes the "OCoAP Flag Bits" registry within the "Constrained RESTful Environments (CoRE) Parameters" registry group. The registration policy is "Expert Review" per [RFC8126]. "Expert Review" guidelines are provided in Section 8.5. The columns of this registry are: * Bit Position: This indicates the position of the bit in the set of OCoAP flag bits, starting at 0 for the most significant bit. The bit position must be an integer or a range of integers between 0 and 63 (inclusive). * Name: This is a descriptive name that enables easier reference to the item. The name MUST be unique. It is not used in the protocol. * Description: This contains a brief description of the use of the bit in this item. * Reference: This contains a pointer to the public specification for the item, if one exists. Lenders & Tiloca Expires 1 May 2027 [Page 31] Internet-Draft Oblivious CoAP October 2026 This registry is initially populated by the entries in Table 3. The entry with Bit Position of 0 is marked as "Reserved". It is expected that it will be specified in a future document and will be used to expand the space for the OCoAP flag bits in Section 4, so that entries 8-63 of the registry are defined. +==============+============+=======================+==============+ | Bit Position | Name | Description | Reference | +==============+============+=======================+==============+ | 0 | Reserved | | | +--------------+------------+-----------------------+--------------+ | 1 | Unassigned | | | +--------------+------------+-----------------------+--------------+ | 2 | Unassigned | | | +--------------+------------+-----------------------+--------------+ | 3 | Unassigned | | | +--------------+------------+-----------------------+--------------+ | 4 | Unassigned | | | +--------------+------------+-----------------------+--------------+ | 5 | ID Context | Set to 1 if the HPKE | Section 4 of | | | Flag | ID Context is present | [RFC-XXXX] | +--------------+------------+-----------------------+--------------+ | 6-7 | Count | Encodes the Count | Section 4 of | | | Length | length minus 1 | [RFC-XXXX] | +--------------+------------+-----------------------+--------------+ | 8-63 | Unassigned | | | +--------------+------------+-----------------------+--------------+ Table 3: OCoAP Flag Bits 8.5. Expert Review Instructions "Expert Review" is the registration policy defined for the IANA registry established in this document. This section gives some general guidelines for what the experts should be looking for, but 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: * Point squatting should be discouraged. Reviewers are encouraged to get sufficient information for registration requests to ensure that the usage solves a valid use case that could not be solved better in a different way, is not going to duplicate one that is already registered, and that the point is likely to be used in deployments. Lenders & Tiloca Expires 1 May 2027 [Page 32] Internet-Draft Oblivious CoAP October 2026 * Experts are expected to check the clarity of purpose and use of the requested code points. 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. 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. * Experts should block registrations for entries 8-63 until these points are defined (i.e., until the mechanism for the OCoAP flag bits expansion via bit 0 is specified). 9. References 9.1. Normative References [I-D.ietf-core-href] Bormann, C. and H. Birkholz, "Constrained Resource Identifiers", Work in Progress, Internet-Draft, draft- ietf-core-href-30, 21 November 2025, . [I-D.ietf-core-uri-path-abbrev] Amsüss, C. and M. Richardson, "URI Path abbreviation in CoAP", Work in Progress, Internet-Draft, draft-ietf-core- uri-path-abbrev-05, 6 July 2026, . [IANA.CoAP-Content-Formats] IANA, "CoAP Content-Formats", . [IANA.CoAP-Option-Numbers] IANA, "CoAP Option Numbers", . [IANA.HPKE-AEAD-Identifiers] IANA, "HPKE AEAD Identifiers", . Lenders & Tiloca Expires 1 May 2027 [Page 33] Internet-Draft Oblivious CoAP October 2026 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, . [RFC7252] Shelby, Z., Hartke, K., and C. Bormann, "The Constrained Application Protocol (CoAP)", RFC 7252, DOI 10.17487/RFC7252, June 2014, . [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, . [RFC8132] van der Stok, P., Bormann, C., and A. Sehgal, "PATCH and FETCH Methods for the Constrained Application Protocol (CoAP)", RFC 8132, DOI 10.17487/RFC8132, April 2017, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, June 2019, . [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, . [RFC8742] Bormann, C., "Concise Binary Object Representation (CBOR) Sequences", RFC 8742, DOI 10.17487/RFC8742, February 2020, . [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, . Lenders & Tiloca Expires 1 May 2027 [Page 34] Internet-Draft Oblivious CoAP October 2026 [RFC9180] Barnes, R., Bhargavan, K., Lipp, B., and C. Wood, "Hybrid Public Key Encryption", RFC 9180, DOI 10.17487/RFC9180, February 2022, . [RFC9458] Thomson, M. and C. A. Wood, "Oblivious HTTP", RFC 9458, DOI 10.17487/RFC9458, January 2024, . 9.2. Informative References [I-D.amsuess-t2trg-onion-coap] Amsüss, C., Tiloca, M., and R. Höglund, "Using onion routing with CoAP", Work in Progress, Internet-Draft, draft-amsuess-t2trg-onion-coap-04, 7 July 2025, . [I-D.ietf-core-cacheable-oscore] Amsüss, C. and M. Tiloca, "End-to-End Protected and Cacheable CoAP Responses using Group Object Security for Constrained RESTful Environments (Group OSCORE)", Work in Progress, Internet-Draft, draft-ietf-core-cacheable- oscore-02, 6 July 2026, . [RFC7641] Hartke, K., "Observing Resources in the Constrained Application Protocol (CoAP)", RFC 7641, DOI 10.17487/RFC7641, September 2015, . [RFC7959] Bormann, C. and Z. Shelby, Ed., "Block-Wise Transfers in the Constrained Application Protocol (CoAP)", RFC 7959, DOI 10.17487/RFC7959, August 2016, . [RFC8323] Bormann, C., Lemay, S., Tschofenig, H., Hartke, K., Silverajan, B., and B. Raymor, Ed., "CoAP (Constrained Application Protocol) over TCP, TLS, and WebSockets", RFC 8323, DOI 10.17487/RFC8323, February 2018, . [RFC9052] Schaad, J., "CBOR Object Signing and Encryption (COSE): Structures and Process", STD 96, RFC 9052, DOI 10.17487/RFC9052, August 2022, . Lenders & Tiloca Expires 1 May 2027 [Page 35] Internet-Draft Oblivious CoAP October 2026 [RFC9110] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022, . [RFC9112] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, June 2022, . [RFC9175] Amsüss, C., Preuß Mattsson, J., and G. Selander, "Constrained Application Protocol (CoAP): Echo, Request- Tag, and Token Processing", RFC 9175, DOI 10.17487/RFC9175, February 2022, . [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, . [RFC9177] Boucadair, M. and J. Shallow, "Constrained Application Protocol (CoAP) Block-Wise Transfer Options Supporting Robust Transmission", RFC 9177, DOI 10.17487/RFC9177, March 2022, . [RFC9230] Kinnear, E., McManus, P., Pauly, T., Verma, T., and C.A. Wood, "Oblivious DNS over HTTPS", RFC 9230, DOI 10.17487/RFC9230, June 2022, . [RFC9953] Lenders, M. S., Amsüss, C., Gündoğan, C., Schmidt, T. C., and M. Wählisch, "DNS over CoAP (DoC)", RFC 9953, DOI 10.17487/RFC9953, March 2026, . Appendix A. Change Log A.1. Since draft-lenders-core-oblivious-coap-00 (https://datatracker.ietf.org/doc/draft-lenders-core-oblivious- coap/00/) * Editorial fixes Acknowledgments The work on this document has been partly supported by Sweden's Innovation Agency VINNOVA and the Celtic-Next project CYPRESS, as well as by the Sovereign Tech Standards program. Lenders & Tiloca Expires 1 May 2027 [Page 36] Internet-Draft Oblivious CoAP October 2026 Index O T O Oblivious CoAP Client Section 1.1; Section 1.1, Paragraph 4.10.1; Section 1.1, Paragraph 4.12.1; Section 2, Paragraph 1; Section 2, Paragraph 2.3.1; Section 2, Paragraph 3; Section 2, Paragraph 4; Section 2, Paragraph 9.1.1; Section 3, Paragraph 8; Section 4, Paragraph 6.2.3; Section 5.1, Paragraph 1; Section 5.2, Paragraph 2.2.2.1.2.3.1; Section 6.2, Paragraph 1 Oblivious CoAP Request Section 1.1; Section 2, Paragraph 3; Section 2, Paragraph 4; Section 2, Paragraph 9.2.1; Section 2, Paragraph 9.3.1; Section 2, Paragraph 9.4.1; Section 2, Paragraph 9.5.1; Section 2, Paragraph 12.1.1; Section 2, Paragraph 12.3.1; Section 2, Paragraph 13; Section 2.2, Paragraph 3; Section 4, Paragraph 6.2.2; Section 4, Paragraph 12; Section 5, Paragraph 1; Section 5.1, Paragraph 1; Section 5.1, Paragraph 4.2.1; Section 5.1, Paragraph 4.2.6; Section 5.1, Paragraph 4.7.1; Section 5.1, Paragraph 5; Section 5.2, Paragraph 1; Section 5.2, Paragraph 2.1.2; Section 5.2, Paragraph 2.1.3.1.1; Section 5.2, Paragraph 2.1.3.2.1; Section 5.2, Paragraph 2.2.2.1.2.1.1; Section 5.2, Paragraph 2.2.2.1.2.3.1; Section 5.2, Paragraph 2.2.2.2.1; Section 5.2, Paragraph 2.3.1; Section 5.2, Paragraph 2.4.1; Section 5.2, Paragraph 2.4.3; Section 5.2, Paragraph 2.6.1; Section 5.2, Paragraph 2.6.2.1.1; Section 5.2, Paragraph 2.6.2.2.1; Section 5.2, Paragraph 2.6.2.4.1; Section 6.1, Paragraph 1; Section 6.1, Paragraph 2.7.2.2.2.2.2; Section 6.1, Paragraph 2.11.3; Section 6.2, Paragraph 1; Section 7.1, Paragraph 2.1.1; Section 7.1, Paragraph 2.2.1; Section 7.1, Paragraph 2.2.3.1.1 Oblivious CoAP Requests Section 1.1, Paragraph 4.10.1; Section 1.1, Paragraph 4.14.1; Section 1.1, Paragraph 4.16.1; Section 2, Paragraph 2.3.1; Section 2, Paragraph 5; Section 2.2, Paragraph 4; Section 4, Paragraph 1; Section 4, Paragraph 6.2.2; Section 4, Paragraph 6.2.3; Section 6.2, Paragraph 2.1.2.2.3; Section 6.2, Paragraph 4.2.1; Section 6.2, Paragraph 4.2.2; Section 7.1, Paragraph 1; Section 7.1, Paragraph 2.2.1; Section 7.1, Paragraph 2.2.2; Section 7.1, Paragraph 2.2.3.2.1 Oblivious CoAP Response Section 1.1; Section 2, Paragraph 3; Section 2, Paragraph 12.1.1; Section 2, Paragraph 12.2.1; Section 2, Paragraph 12.3.1; Section 6, Paragraph 1; Section 6.1, Paragraph 1; Section 6.1, Paragraph Lenders & Tiloca Expires 1 May 2027 [Page 37] Internet-Draft Oblivious CoAP October 2026 2.7.2.2.2.2.1; Section 6.1, Paragraph 2.8.2.1.1; Section 6.1, Paragraph 2.12.1; Section 6.1, Paragraph 3; Section 6.2, Paragraph 1; Section 6.2, Paragraph 2.1.2.1.1; Section 6.2, Paragraph 2.1.2.2.1; Section 6.2, Paragraph 2.1.2.3.1; Section 6.2, Paragraph 2.3.2; Section 6.2, Paragraph 2.6.1; Section 6.2, Paragraph 2.7.2.2.1; Section 6.2, Paragraph 2.8.1; Section 6.2, Paragraph 2.8.3; Section 6.2, Paragraph 2.9.1; Section 6.2, Paragraph 2.9.2; Section 6.2, Paragraph 2.9.3.1.1; Section 6.2, Paragraph 2.9.3.2.1; Section 6.2, Paragraph 2.10.2; Section 6.2, Paragraph 2.11.1; Section 6.2, Paragraph 2.11.2.1.1; Section 6.2, Paragraph 2.11.2.2.1; Section 6.2, Paragraph 2.11.2.4.1; Section 6.2, Paragraph 4.1.1 Oblivious CoAP Responses Section 1.1, Paragraph 4.14.1; Section 1.1, Paragraph 4.16.1; Section 2, Paragraph 2.3.1; Section 4, Paragraph 6.2.3; Section 6.1, Paragraph 2.7.2.2.2.2.1; Section 6.1, Paragraph 4; Section 6.2, Paragraph 2.9.3.2.1; Section 6.2, Paragraph 4.2.1 Oblivious Gateway Resource Section 1.1, Paragraph 4.10.1; Section 1.1, Paragraph 4.12.1; Section 1.1; Section 1.1, Paragraph 4.14.1; Section 2, Paragraph 2.1.1; Section 2, Paragraph 2.2.2.1.1; Section 2, Paragraph 2.2.2.2.1; Section 2, Paragraph 2.3.1; Section 2, Paragraph 3; Section 2, Paragraph 4; Section 2, Paragraph 5; Section 2, Paragraph 9.4.1; Section 2.1, Paragraph 1; Section 3, Paragraph 3.1.1; Section 3, Paragraph 3.3.1; Section 4, Paragraph 6.2.3; Section 5.1, Paragraph 2.2.1; Section 5.1, Paragraph 4.2.1; Section 5.1, Paragraph 4.2.2; Section 5.1, Paragraph 4.2.6; Section 5.1, Paragraph 5; Section 5.2, Paragraph 1; Section 5.2, Paragraph 2.1.2; Section 6.2, Paragraph 4.2.2 Oblivious Proxy Resource Section 1.1; Section 2, Paragraph 2.3.1; Section 2, Paragraph 3; Section 2, Paragraph 4; Section 2, Paragraph 5; Section 2, Paragraph 9.3.1; Section 2.1, Paragraph 1; Section 5.1, Paragraph 4.2.1; Section 5.1, Paragraph 5; Section 6.1, Paragraph 3; Section 7.1, Paragraph 1 Original CoAP Request Section 1.1; Section 1.1, Paragraph 4.6.1; Section 1.1, Paragraph 4.16.1; Section 2, Paragraph 9.1.1; Section 2, Paragraph 9.2.1; Section 2, Paragraph 9.5.1; Section 2, Paragraph 9.6.1; Section 2.2, Paragraph 3; Section 2.2, Paragraph 5; Section 5, Paragraph 3.1.1; Section 5, Paragraph 3.5.1; Section 5, Paragraph 3.6.1; Section 5, Paragraph 5; Section 5.1, Paragraph 1; Section 5.1, Paragraph 4.1.1; Section 5.1, Paragraph 4.1.7; Section 5.1, Paragraph 4.2.1; Section 5.1, Paragraph 4.2.2; Section 5.1, Paragraph 4.3.3; Section 5.1, Paragraph 4.4.2.2.1; Section 5.1, Paragraph 4.5.2.1.1; Section 5.1, Lenders & Tiloca Expires 1 May 2027 [Page 38] Internet-Draft Oblivious CoAP October 2026 Paragraph 4.5.2.2.1; Section 5.1, Paragraph 4.5.2.3.1; Section 5.1, Paragraph 4.7.1; Section 5.1, Paragraph 4.7.2.1.1; Section 5.1, Paragraph 4.7.2.3.1; Section 5.1, Paragraph 4.7.2.4.1; Section 5.2, Paragraph 2.5.1; Section 5.2, Paragraph 2.6.1; Section 5.2, Paragraph 3; Section 6.1, Paragraph 2.4.2; Section 6.1, Paragraph 2.8.2.1.1; Section 6.1, Paragraph 2.8.2.2.1; Section 6.2, Paragraph 2.3.2 Original CoAP Response Section 1.1; Section 1.1, Paragraph 4.8.1; Section 2, Paragraph 11; Section 2, Paragraph 12.1.1; Section 2, Paragraph 12.3.1; Section 6, Paragraph 3.2.1; Section 6, Paragraph 5; Section 6.1, Paragraph 1; Section 6.1, Paragraph 2.7.3; Section 6.1, Paragraph 2.8.2.3.1; Section 6.1, Paragraph 2.9.2.1.1; Section 6.1, Paragraph 2.9.2.2.1; Section 6.1, Paragraph 2.9.2.3.1; Section 6.1, Paragraph 2.11.3; Section 6.1, Paragraph 2.12.1; Section 6.1, Paragraph 2.12.2.1.1; Section 6.1, Paragraph 2.12.2.3.1; Section 6.1, Paragraph 2.12.2.4.1; Section 6.2, Paragraph 2.10.1; Section 6.2, Paragraph 2.11.1 T Target Resource Section 1.1, Paragraph 4.10.1; Section 1.1, Paragraph 4.14.1; Section 1.1; Section 1.1, Paragraph 4.16.1; Section 2, Paragraph 2.1.1; Section 2, Paragraph 9.1.1; Section 2, Paragraph 9.6.1; Section 2, Paragraph 10; Section 2, Paragraph 11; Section 5.1, Paragraph 4.2.2; Section 5.2, Paragraph 3; Section 6.1, Paragraph 1 Authors' Addresses Martine Sophie Lenders Email: ietf@lenders.berlin Marco Tiloca RISE AB Isafjordsgatan 22 SE-164 40 Kista Sweden Email: marco.tiloca@ri.se Lenders & Tiloca Expires 1 May 2027 [Page 39]