Protocol Flow

This page shows the canonical EDHOC handshake as it travels over CoAP. The diagram is reproduced from RFC 9528 and annotated with the libedhoc API calls the Initiator and Responder make at each step.

For a code-level walkthrough see Quick Start; for the API surface see EDHOC Messages.

CoAP + EDHOC message exchange

                         EDHOC API flow
                      ====================
Initiator                                                   Responder
|                                                                   |
| edhoc_context_init()                         edhoc_context_init() |
| edhoc_set_methods()                           edhoc_set_methods() |
| edhoc_set_cipher_suites()               edhoc_set_cipher_suites() |
| edhoc_set_connection_id()               edhoc_set_connection_id() |
| edhoc_bind_ead()                                 edhoc_bind_ead() |
| edhoc_bind_keys()                               edhoc_bind_keys() |
| edhoc_bind_crypto()                           edhoc_bind_crypto() |
| edhoc_bind_credentials()                 edhoc_bind_credentials() |
|                                                                   |
| edhoc_message_1_compose()                                         |
|                                                                   |
|                     Header: POST (Code=0.02)                      |
|                   Uri-Path: "/.well-known/edhoc"                  |
|          Content-Format: application/cid-edhoc+cbor-seq           |
|                  Payload: true, EDHOC message_1                   |
|                                                                   |
+--------------------------- POST --------------------------------->|
|                                                                   |
|                                         edhoc_message_1_process() |
|                                         edhoc_message_2_compose() |
|                                                                   |
|                      Header: 2.04 Changed                         |
|             Content-Format: application/edhoc+cbor-seq            |
|                     Payload: EDHOC message_2                      |
|                                                                   |
|<---------------------------- 2.04 --------------------------------+
|                                                                   |
| edhoc_message_2_process()                                         |
| edhoc_message_3_compose()                                         |
|                                                                   |
|                     Header: POST (Code=0.02)                      |
|                     Uri-Path: "/.well-known/edhoc"                |
|          Content-Format: application/cid-edhoc+cbor-seq           |
|                     Payload: C_R, EDHOC message_3                 |
|                                                                   |
+--------------------------- POST --------------------------------->|
|                                                                   |
|                                         edhoc_message_3_process() |
|                                         edhoc_message_4_compose() |
|                                                                   |
|                       Header: 2.04 Changed                        |
|             Content-Format: application/edhoc+cbor-seq            |
|                     Payload: EDHOC message_4                      |
|                                                                   |
|<---------------------------- 2.04 --------------------------------+
|                                                                   |
| edhoc_message_4_process()                                         |
|                                                                   |
| edhoc_export_oscore_session()       edhoc_export_oscore_session() |
| edhoc_export_key_update()               edhoc_export_key_update() |
| edhoc_export_oscore_session()       edhoc_export_oscore_session() |
| edhoc_context_deinit()                     edhoc_context_deinit() |
|                                                                   |

Notes

  • message_4 is optional; it is composed and processed only when the selected authentication method requires it or when the application asks for it explicitly.

  • The diagram shows a single PRK exporter round followed by a KEY_UPDATE and a second export — the second export is only needed if the application performs a key update.

  • The CoAP framing (POST to /.well-known/edhoc, application/edhoc+cbor-seq) follows RFC 9528 Appendix A.2; libedhoc itself only produces and consumes the inner CBOR-sequence payload.