CoAP Integration

libedhoc is transport-agnostic, but running EDHOC over CoAP (RFC 9528, Appendix A, and the combined EDHOC + OSCORE profile of RFC 9668) needs a little framing: prepending the connection identifier or the true flag to a message and extracting it again on receipt. These helpers are dependency-free byte manipulation and ship as part of the library core.

Header file: include/edhoc/coap.h

Connection identifiers

group EDHOC CoAP connection-id utilities

Compare EDHOC connection identifiers, e.g. to match the identifier extracted from an incoming CoAP message against the one selected for a session.

Functions

bool edhoc_coap_connection_id_equal(const struct edhoc_buffer *conn_id_1, const struct edhoc_buffer *conn_id_2)

Compare two connection identifiers for equality.

Parameters:
  • conn_id_1[in] First connection identifier.

  • conn_id_2[in] Second connection identifier.

Returns:

true if both encode the same connection identifier, else false.

Message framing

group EDHOC CoAP buffer utilities

Build and parse a CoAP payload that carries an EDHOC message optionally prepended with a flow indicator and/or a connection identifier (RFC 9528: A.2). The sender fills a edhoc_coap_prepended_fields and prepends what it needs; the receiver fills a edhoc_coap_extracted_fields and strips the prepended data before EDHOC processing. Each call picks up where the previous one left off, so calls in either direction compose.

Functions

int edhoc_coap_prepend_flow(struct edhoc_coap_prepended_fields *prepended_fields)

Prepend the forward-flow indicator before the EDHOC message.

Writes the CBOR simple value true (0xf5) that marks message 1 of the forward flow / a new EDHOC session (RFC 9528: A.2).

Note

Initialise the prepend buffer with designated initialisers before use:

struct edhoc_coap_prepended_fields prepended_fields = {
    .buffer = buffer,
    .capacity = ARRAY_SIZE(buffer),
};
Then prepend as needed, compose the EDHOC message into buffer + length with capacity - length bytes available, and add its length to length.

Parameters:

prepended_fields[inout] Prepend buffer.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_coap_prepend_connection_id(struct edhoc_coap_prepended_fields *prepended_fields, const struct edhoc_buffer *conn_id)

Prepend a connection identifier before the EDHOC message.

CBOR-encodes conn_id and writes it before the EDHOC message, as the CoAP client must do on the messages it sends (RFC 9528: A.2): the peer’s C_R in the forward flow, or C_I in the reverse flow.

Parameters:
  • prepended_fields[inout] Prepend buffer.

  • conn_id[in] Connection identifier to prepend.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_coap_extract_flow_info(struct edhoc_coap_extracted_fields *extracted_fields)

Detect and strip the flow indicator at the start of the payload.

Inspects the first unconsumed byte (RFC 9528: A.2):

  • an empty payload indicates the reverse flow (is_reverse_flow);

  • a leading CBOR true (0xf5) indicates the forward flow (is_forward_flow), which is then consumed;

  • otherwise no indicator is present and nothing is consumed.

Note

Initialise the extract buffer with designated initialisers before use:

struct edhoc_coap_extracted_fields extracted_fields = {
    .buffer = payload,
    .length = payload_length,
};

Parameters:

extracted_fields[inout] Extract buffer; the flow flags are set and the indicator consumed.

Return values:

EDHOC_SUCCESS – Success (indicator stripped, or none present / empty payload).

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_coap_extract_connection_id(struct edhoc_coap_extracted_fields *extracted_fields)

Extract and strip the prepended connection identifier.

CBOR-decodes the connection identifier at the first unconsumed byte into connection_id and consumes it, leaving the bare EDHOC message (RFC 9528: A.2).

Parameters:

extracted_fields[inout] Extract buffer; connection_id is set and the identifier consumed on success.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

struct edhoc_coap_prepended_fields
#include <coap.h>

Working buffer for building a CoAP payload to send.

Initialise buffer and capacity to the whole output buffer and leave length at zero. Every prepend call writes at buffer + length and advances length, so what it prepends lands after the data prepended before it and still before the EDHOC message. Compose the EDHOC message into the remaining space and add its length to length; the payload to send is then the first length bytes of buffer.

Public Members

uint8_t *buffer

Output buffer.

size_t capacity

Capacity of buffer in bytes.

size_t length

Bytes written so far.

struct edhoc_coap_extracted_fields
#include <coap.h>

Working buffer for parsing a received CoAP payload.

Initialise buffer and length to the received payload and leave consumed at zero. Every extract call reads at buffer + consumed and advances consumed. The bare EDHOC message is then buffer + consumed, of length - consumed bytes.

Public Members

const uint8_t *buffer

Received payload.

size_t length

Size of the received payload in bytes.

size_t consumed

Bytes read so far.

bool is_forward_flow

Forward flow: the CBOR true indicator was found (set by edhoc_coap_extract_flow_info).

bool is_reverse_flow

Reverse flow: the payload was empty (set by edhoc_coap_extract_flow_info).

struct edhoc_buffer connection_id

Connection identifier extracted by edhoc_coap_extract_connection_id. A view into buffer.