Exporters

After a successful handshake the EDHOC key schedule yields PRK_out, from which application keys are derived with the PRK exporter. Each exporter comes in two forms: a raw-bytes form (_raw) that writes the secret into a caller buffer, and a key-handle form that returns it as an opaque handle kept inside the crypto backend, so the bytes never leave it.

libedhoc also provides a dedicated export of the OSCORE Security Context (in both forms) — the Master Secret, Master Salt and Sender/Recipient IDs needed to establish OSCORE. A key update (RFC 9528, Section 4.4) rotates PRK_out from an application-supplied context — identical on both peers — so a later export gives fresh keys without a new handshake.

Header file: include/edhoc/edhoc.h

Exporter API

group EDHOC exporters API

Derive application keying material from a completed EDHOC session with the EDHOC_Exporter (RFC 9528: 4.2.1). Each exporter comes in two forms: a raw-bytes form (_raw) that writes the secret into a caller buffer, and a key-handle form that returns it as an opaque key reference kept inside the bound crypto backend, so the bytes never leave it (e.g. a TrustZone or secure element).

Permitted exporter labels (RFC 9528: 10.1) are:

Any other label is rejected with EDHOC_ERROR_NOT_PERMITTED. Labels 2 and 3 are open to every method: a session may yield a resumption key whatever it authenticated with (draft-ietf-lake-edhoc-psk: 6).

Functions

int edhoc_export(struct edhoc_context *edhoc_context, size_t label, const uint8_t *context, size_t context_length, enum edhoc_key_usage usage, void *key_id)

Export application keying material as a key handle.

  Returns the derived key as an opaque key handle. The derived length is
  set by \p usage: #EDHOC_KEY_USAGE_KDF yields the cipher suite hash
  length and #EDHOC_KEY_USAGE_AEAD the cipher suite AEAD key length.

Note

The returned handle is owned by the caller: the library neither tracks it nor releases it in edhoc_context_deinit(). Destroy it through the destroy_key entry of the bound edhoc_crypto vtable.

Parameters:
  • edhoc_context – [inout] EDHOC context.

  • label – EDHOC exporter label (RFC 9528: 10.1).

  • context – [in] Exporter context byte string (may be NULL when context_length is 0).

  • context_length – Size of the context buffer in bytes.

  • usage – Intended usage of the derived key; governs its type and length.

  • key_id – [out] Buffer holding a key handle (CONFIG_LIBEDHOC_KEY_ID_LEN bytes) that receives the derived key.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_export_raw(struct edhoc_context *edhoc_context, size_t label, const uint8_t *context, size_t context_length, uint8_t *secret, size_t secret_length)

Export application keying material as raw bytes.

  Derives \p secret_length bytes (RFC 9528: 4.2.1) and writes them to
  \p secret.
Parameters:
  • edhoc_context – [inout] EDHOC context.

  • label – EDHOC exporter label (RFC 9528: 10.1).

  • context – [in] Exporter context byte string (may be NULL when context_length is 0).

  • context_length – Size of the context buffer in bytes.

  • secret – [out] Buffer where the generated secret is to be written.

  • secret_length – Size of the secret buffer in bytes.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_export_resumption_psk(struct edhoc_context *edhoc_context, enum edhoc_key_usage usage, void *key_id)

Export the resumption PSK as a key handle.

  Derives rPSK (draft-ietf-lake-edhoc-psk: 6) with an empty exporter
  context. The derived length is set by \p usage, as in
  \ref edhoc_export().

Note

The returned handle is owned by the caller: the library neither tracks it nor releases it in edhoc_context_deinit(). Destroy it through the destroy_key entry of the bound edhoc_crypto vtable.

Parameters:
  • edhoc_context – [inout] EDHOC context.

  • usage – Intended usage of the derived key; governs its type and length.

  • key_id – [out] Buffer holding a key handle (CONFIG_LIBEDHOC_KEY_ID_LEN bytes) that receives the resumption PSK.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_export_resumption_psk_raw(struct edhoc_context *edhoc_context, uint8_t *psk, size_t psk_length)

Export the resumption PSK as raw bytes.

  Derives rPSK (draft-ietf-lake-edhoc-psk: 6) with an empty exporter
  context. That section names the cipher suite hash length, while its
  Appendix B.6 vector is 16 bytes long, so the length is left to the
  caller.
Parameters:
  • edhoc_context – [inout] EDHOC context.

  • psk – [out] Buffer where the resumption PSK is to be written.

  • psk_length – Size of the psk buffer in bytes.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_export_resumption_kid_raw(struct edhoc_context *edhoc_context, uint8_t *kid, size_t kid_length)

Export the resumption ‘kid’ as raw bytes.

  Derives rKID (draft-ietf-lake-edhoc-psk: 6) with an empty exporter
  context. rKID identifies the resumption PSK rather than keying it, so
  it has no key-handle form. Its default length is
  #EDHOC_EXPORTER_RESUMPTION_KID_DEFAULT_LEN.
Parameters:
  • edhoc_context – [inout] EDHOC context.

  • kid – [out] Buffer where the resumption ‘kid’ is to be written.

  • kid_length – Size of the kid buffer in bytes.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_export_key_update(struct edhoc_context *edhoc_context, const uint8_t *context, size_t context_length)

Perform key update for subsequent OSCORE Security Context exports.

  Implements RFC 9528: 4.4. EDHOC-KeyUpdate(context): rotates PRK_out so
  that later OSCORE exports derive fresh keying material bound to the
  application-supplied \p context byte string. It also re-arms the
  one-shot OSCORE export, so it is the only way to obtain a second
  security context from the same session.
Parameters:
  • edhoc_context – [inout] EDHOC context.

  • context – [in] Buffer containing the key-update context.

  • context_length – Size of the context buffer in bytes.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_export_oscore_context(struct edhoc_context *edhoc_context, void *master_secret_key_id, uint8_t *master_salt, size_t master_salt_length, uint8_t *sender_id, size_t sender_id_size, size_t *sender_id_length, uint8_t *recipient_id, size_t recipient_id_size, size_t *recipient_id_length)

Export the OSCORE security context with the master secret as a handle.

  Derives the OSCORE Master Secret (RFC 9528: A.1, exporter label 0) and
  returns it as an opaque AEAD key handle of the cipher suite AEAD key
  length; the Master Salt (exporter label 1) is returned as raw bytes
  and the OSCORE Sender and Recipient IDs are copied out.

Note

The returned handle is owned by the caller: the library neither tracks it nor releases it in edhoc_context_deinit(). Destroy it through the destroy_key entry of the bound edhoc_crypto vtable.

Note

C_I and C_R become the OSCORE Recipient IDs, so RFC 9528: 3.3.3 forbids them being equal. Such a session is rejected with EDHOC_ERROR_NOT_PERMITTED; only re-running EDHOC with distinct identifiers helps.

Note

A session yields one security context. A further export returns EDHOC_ERROR_BAD_STATE until edhoc_export_key_update() rotates PRK_out.

Parameters:
  • edhoc_context – [inout] EDHOC context.

  • master_secret_key_id – [out] Buffer holding a key handle (CONFIG_LIBEDHOC_KEY_ID_LEN bytes) that receives the master secret.

  • master_salt – [out] Buffer where the exported master salt is to be written.

  • master_salt_length – Size of the master_salt buffer in bytes.

  • sender_id – [out] Buffer where the exported sender id is to be written.

  • sender_id_size – Size of the sender_id buffer in bytes.

  • sender_id_length – [out] On success, the number of bytes that make up the sender id.

  • recipient_id – [out] Buffer where the exported recipient id is to be written.

  • recipient_id_size – Size of the recipient_id buffer in bytes.

  • recipient_id_length – [out] On success, the number of bytes that make up the recipient id.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

int edhoc_export_oscore_context_raw(struct edhoc_context *edhoc_context, uint8_t *master_secret, size_t master_secret_length, uint8_t *master_salt, size_t master_salt_length, uint8_t *sender_id, size_t sender_id_size, size_t *sender_id_length, uint8_t *recipient_id, size_t recipient_id_size, size_t *recipient_id_length)

Export the OSCORE security context as raw bytes.

  Derives the OSCORE Master Secret and Master Salt (exporter labels 0
  and 1) as raw bytes and copies out the OSCORE Sender and Recipient
  IDs.

Note

C_I and C_R become the OSCORE Recipient IDs, so RFC 9528: 3.3.3 forbids them being equal. Such a session is rejected with EDHOC_ERROR_NOT_PERMITTED; only re-running EDHOC with distinct identifiers helps.

Note

A session yields one security context. A further export returns EDHOC_ERROR_BAD_STATE until edhoc_export_key_update() rotates PRK_out.

Parameters:
  • edhoc_context – [inout] EDHOC context.

  • master_secret – [out] Buffer where the exported master secret is to be written.

  • master_secret_length – Size of the master_secret buffer in bytes.

  • master_salt – [out] Buffer where the exported master salt is to be written.

  • master_salt_length – Size of the master_salt buffer in bytes.

  • sender_id – [out] Buffer where the exported sender id is to be written.

  • sender_id_size – Size of the sender_id buffer in bytes.

  • sender_id_length – [out] On success, the number of bytes that make up the sender id.

  • recipient_id – [out] Buffer where the exported recipient id is to be written.

  • recipient_id_size – Size of the recipient_id buffer in bytes.

  • recipient_id_length – [out] On success, the number of bytes that make up the recipient id.

Return values:

EDHOC_SUCCESS – Success.

Returns:

Negative error code on failure (EDHOC error codes).

Exporter labels

The permitted exporter labels and the private-use range are defined in include/edhoc/values.h.

group EDHOC exporter labels

RFC 9528: 10.1. EDHOC Exporter Label Registry.

Defines

EDHOC_PRK_EXPORTER_PRIVATE_LABEL_MINIMUM

Minimum value for EDHOC exporter label for private usage.

EDHOC_PRK_EXPORTER_PRIVATE_LABEL_MAXIMUM

Maximum value for EDHOC exporter label for private usage.

EDHOC_EXPORTER_LABEL_OSCORE_MASTER_SECRET

OSCORE Master Secret, for edhoc_export and edhoc_export_raw.

EDHOC_EXPORTER_LABEL_OSCORE_MASTER_SALT

OSCORE Master Salt, for edhoc_export and edhoc_export_raw.

EDHOC_EXPORTER_LABEL_RESUMPTION_PSK

Resumption PSK, for edhoc_export_resumption_psk and edhoc_export_resumption_psk_raw.

draft-ietf-lake-edhoc-psk: 10.2 suggests 2, pending IANA assignment.

EDHOC_EXPORTER_LABEL_RESUMPTION_KID

Resumption ‘kid’, for edhoc_export_resumption_kid_raw.

draft-ietf-lake-edhoc-psk: 10.2 suggests 3, pending IANA assignment.

EDHOC_EXPORTER_RESUMPTION_KID_DEFAULT_LEN

Default length of the resumption ‘kid’ (draft-ietf-lake-edhoc-psk: 6).