Object Security for Constrained RESTful Environments (OSCORE)
updates
- rfc-7252 — The Constrained Application Protocol (CoAP)
Extracted elements (31)
OSCORE defines a stateless header compression mechanism for COSE objects because standard COSE is designed for a large number of stateless use cases and produces larger-than-necessary overhead for a stateful security protocol. Compression removes redundant information, significantly reducing per-packet overhead on constrained networks.
Responses without a Partial IV reuse the nonce from the corresponding request. This is intentional to reduce message overhead for the common case of a single response, while still providing all required security properties since the response is cryptographically bound to the request via the AAD.
The Outer Code is always masked to POST (0.02) for requests and Changed (2.04) for responses because the true CoAP method and response code must be hidden from proxies. This prevents intermediaries from eavesdropping on or manipulating the request type (e.g., converting GET to DELETE).
OSCORE can be transported over HTTP using an 'OSCORE' HTTP header field and a new content type. HTTP-to-CoAP and CoAP-to-HTTP proxy operations are supported; conceptually, HTTP messages are first mapped to CoAP and then OSCORE-processed, though implementations may translate directly.
Outer Block options introduced by proxies are neither encrypted nor integrity protected, allowing a malicious proxy to inject block fragments indefinitely. Inner Block options (applied before OSCORE processing) provide end-to-end integrity for each segment, which is the preferred mechanism for constrained environments.
A Partial IV MUST be included in all Observe notifications (both successful and error), except the first where it MAY be omitted. Every new Observe registration request MUST use a new Partial IV. A client MUST consider the notification with the highest Partial IV as the freshest.
A server SHALL verify that the Sender Sequence Number in the received 'Partial IV' has not been received before (replay protection). If verification fails, the server SHALL stop processing and MAY respond with 4.01 (Unauthorized). The operation of validating the Partial IV and updating the replay window MUST be atomic.
An AEAD nonce MUST NOT be used more than once per AEAD key. When processing requests concurrently, reading and incrementing the Sender Sequence Number MUST be atomic to preserve (key, nonce) uniqueness.
An endpoint that reuses an existing security context after losing mutable state (e.g., after a reboot) MUST NOT reuse a previous Sender Sequence Number and MUST NOT accept previously received messages.
Applications supporting both OSCORE and Block-wise transfers MUST specify a MAX_UNFRAGMENTED_SIZE security policy. Messages exceeding this size SHOULD be fragmented by the sending endpoint using Inner Block options rather than relying on unprotected Outer Block options.
Endpoints MUST NOT change the Sender/Recipient ID when an endpoint changes roles between client and server, ensuring the set of AEAD keys remains unchanged across role transitions.
HKDF SHA-256 is mandatory to implement. The HKDF MUST be one of the HMAC-based HKDF algorithms defined for COSE. AES-CCM-16-64-128 is mandatory to implement as the AEAD algorithm.
Nested OSCORE is not supported: if OSCORE processing detects an OSCORE option already present in the original CoAP message, processing SHALL be stopped.
The CoAP Code SHALL be Class E (encrypted and integrity protected) to prevent intermediaries from eavesdropping or changing the method (e.g., GET to DELETE). The Outer Code is set to 0.02 (POST) for requests and 2.04 (Changed) for responses, masking the true method from proxies.
The Sender Sequence Number SHALL be less than 2^40. If it reaches the maximum, the endpoint MUST NOT process any more messages with that Sender Context and SHOULD acquire a new security context before the limit is reached.
To ensure unique Sender Keys, the quartet (Master Secret, Master Salt, ID Context, Sender ID) MUST be unique across all security contexts. Specifically, (ID Context, Sender ID) SHALL be unique for the same Master Secret and Master Salt pair.
OSCORE encrypts the URI path, query, payload, and most options, but leaves the IP addresses, CoAP Token, and Outer options (Uri-Host, Uri-Port) visible to observers. An on-path attacker can perform traffic analysis based on message timing, size, and frequency even though content is encrypted.
OSCORE classifies CoAP message fields into Class E (encrypted and integrity protected, transported in the COSE ciphertext), Class I (integrity protected only, included in AAD), and Class U (unprotected, visible to proxies). There are currently no Class I options defined; all unknown options default to Class E.
OSCORE uses a Security Context composed of a Common Context, a Sender Context, and a Recipient Context. The Common Context holds the AEAD algorithm, HKDF algorithm, Master Secret, Master Salt, ID Context, and Common IV. Sender and Recipient Contexts hold the respective ID, key, and (for senders) Sender Sequence Number or (for the server) Replay Window.
The OSCORE option (CoAP option number 9) is Critical, safe to forward, part of the cache key, and not repeatable. It carries compressed COSE object metadata: OSCORE flag bits, Partial IV, Sender ID ('kid'), and optionally an ID Context ('kid context'). If all flag bits are zero the option value SHALL be empty.
IANA created the 'OSCORE Flag Bits' registry for the flag bits in the first byte of the OSCORE option value. Bits 0–4 are assigned (n bits 0–2 for Partial IV length, k for kid, h for kid context); bits 5–7 are reserved. New entries require Expert Review.
IANA registered OSCORE as CoAP option number 9 in the CoAP Option Numbers registry (Critical, safe to forward, part of cache key, not repeatable, format (*), length 0-255).
IANA registered the 'kid context' parameter (label 10, value type bstr) in the COSE Header Parameters registry. This parameter carries the ID Context in OSCORE request COSE objects to help the server select the correct security context when multiple contexts share the same Sender ID.
IANA registered the 'OSCORE' HTTP header field in the Message Headers registry and a new media type 'application/oscore' (content-format 10001) in the CoAP Content-Formats registry for carrying OSCORE messages over HTTP.
OSCORE provides end-to-end protection of CoAP messages across intermediary nodes such as CoAP-to-HTTP proxies, which previously required DTLS/TLS termination at the proxy. Proxies that terminate transport-layer security can eavesdrop on, manipulate, inject, delete, or reorder messages; OSCORE prevents this by protecting the application layer.
The Master Secret must be a uniformly random byte string. Compromise of the Master Secret allows an attacker to derive all session keys and decrypt all communications. The security context establishment mechanism is out of scope for OSCORE itself and must be handled by a separate key establishment protocol or out-of-band provisioning.
Key derivation uses HKDF with an 'info' CBOR array containing: id (Sender ID, Recipient ID, or empty for Common IV), id_context (bstr or nil), alg_aead (int/tstr), type ('Key' or 'IV'), and L (output length in bytes). For default AES-CCM-16-64-128, L=16 for keys and L=13 for Common IV.
The Additional Authenticated Data (AAD) is built from a CBOR array 'aad_array' containing: oscore_version (uint, MUST be 1), algorithms (array containing alg_aead), request_kid (bstr), request_piv (bstr), and options (bstr encoding Class I options). The AAD fed to AEAD is the COSE Enc_structure wrapping external_aad.
The AEAD nonce is constructed by (1) left-padding the Partial IV to 5 bytes, (2) left-padding the sender's ID (ID_PIV) to nonce-length minus 6 bytes, (3) prepending the 1-byte size S of ID_PIV, and (4) XOR-ing the concatenated result with the Common IV. Only AEAD algorithms with nonces ≥ 7 bytes are supported.
The OSCORE option value is a compact byte sequence: a 1-byte flag field (bits: h=kid-context present, k=kid present, n=Partial IV length in 3 LSBs), followed by n bytes of Partial IV, then 1-byte length s + s bytes of 'kid context' if h=1, then remaining bytes for 'kid' if k=1. Bits 5–7 of the flag byte are reserved and SHALL be zero; a set reserved bit renders the message malformed.
The OSCORE plaintext is formatted as a partial CoAP message containing: 1-byte Code of the original CoAP message, all Class E (Inner) options encoded with deltas relative to previously included Class E options, and if payload is present, a 0xFF payload marker followed by the payload.