1# uOSCORE / uEDHOC
2
3This repository contains C implementations  for constrained (and non-constrained) devices of the IETF protocols:
4
5* [OSOCRE (RFC8613)](https://tools.ietf.org/html/rfc8613) and
6* [EDHOC (draft-ietf-lake-edhoc-12 )](https://datatracker.ietf.org/doc/html/draft-ietf-lake-edhoc-12).
7
8Main features of uOSCORE and uEDHOC are their independence from the OS, cryptographic engine and in the case of uEDHOC transport protocol. Additionally,  uOSCORE and uEDHOC use only stack memory (no heap).
9
10For more background and evaluation in terms of speed, RAM and flash requirements see our paper [The Cost of OSCORE and EDHOC for Constrained Devices](https://arxiv.org/pdf/2103.13832.pdf).
11
12## How to Build and Link
13
14* check the configurations in `makefile_config.mk` and adjust them if necessary
15* run `make`
16* link the static library `build/libuoscore-uedhoc.a` in your project
17
18## Project (Folder) Structure
19
20```
21.
22|---cddl_models/
23|---externals/
24|---inc/
25|---samples/
26|---scripts/
27|---src/
28|---test/
29|---test_vectors/
30```
31* The folder `cddl_models` contains CDDL models for all CBOR structures.
32* The folder `externals` contains the external libraries and tools as git submodules.
33* The folder `inc` contains all header file.
34* The folder `samples` contains some usage examples.
35* The folder `scripts` contains scripts for generatinc C code from CDDL models and converting the json formatted EDHOC test vectors to a C header
36* The folder `src` contains all source file.
37* The folder `test` contains automated tests.
38* The folder `test_vectors` contains tests vectors.
39
40## API and Usage Model
41
42#### uOSCORE
43
44The API of uOSCORE consists of three functions:
45* `oscore_context_init()`,
46*  `coap2oscore()` and
47*  `oscore2coap()`.
48
49`coap2oscore()` and `oscore2coap()` convert CoAP to OSCORE packets and vice versa. `oscore_context_init()` initializes the OSCORE security context.
50
51First, `oscore_context_init()` function needs to be called on the client and server side, then `coap2oscore()` and `oscore2coap()`  are called just before sending or receiving packets over the network.
52
53<img src="oscore_usage.svg" alt="drawing" width="600"/>
54
55
56#### uEDHOC
57
58The API of uEDHOC consists of four functions:
59*  `ephemeral_dh_key_gen()`
60* `edhoc_initiator_run()`,
61* `edhoc_responder_run()`,
62* `edhoc_exporter()`,
63
64`ephemeral_dh_key_gen()` is used to generate fresh ephemeral DH keys before running the protocol. This function requires a random seed suable for cryptographic purposes. `edhoc_initiator_run()` and `edhoc_responder_run() ` has to be called on the initiator and responder side respectively. They return the External Authorization data `EAD_x`,  the derived shared secret `PRK_4x3m` and the transcript hash `TH_4`.   `PRK_4x3m` and `TH_4` are used as inputs for `edhoc_exporter()` to derive application specific keys, e.g., OSCORE master secret and OSCORE master salt.
65
66The EDHOC protocol requires the exchange of three messages which is independent of the underlying message transport protocol. For example [appendix-A.3 in the EDHOC specification](https://datatracker.ietf.org/doc/html/draft-ietf-lake-edhoc-12#appendix-A.3) describes how  EDHOC can be transferred over CoAP, however CoAP is not mandatory. In order to be independent of the transport protocol uEDHOC uses two callback functions which need to be implemented by the user for handling the sending and receiving of messages. These functions are:
67
68```c
69/**
70 * @brief   The user should call inside this function its send function.
71 *
72 *
73 * @param   sock a pointer used to identify the rx chanel,
74 *          e.g. a socket handler
75 * @param   data pointer to the data to be send
76 * @param   data_len length of the data
77 */
78enum err tx(void *sock, uint8_t *data, uint32_t data_len);
79
80/**
81 * @brief   The user should call inside this function its receive
82 *          function and copy the received data in the buffer <data>.
83 *          The length of the buffer <data> must be
84 *          checked before copying into it by using <data_len>.
85 *          After copying the length of the received data should be written
86 *          in <data_len>.
87 *
88 *
89 * @param   sock a pointer used to identify the rx chanel,
90 *          e.g. a socket handler
91 * @param   data pointer to a buffer where the edhoc message must be copied
92 * @param   data_len length of the received data. When this function is
93 *          called inside EDHOC <data_len> is initialized with the actual
94 *          available length of the <data>.
95 */
96enum err rx(void *sock, uint8_t *data, uint32_t *data_len);
97```
98
99
100
101## Supported Cipher Suites
102
103##### uOSCORE
104
105| Algorithms                  |
106| --------------------------- |
107| AES-CCM-16-64-128,  SHA-256 |
108
109##### uEDHOC
110
111
112| Suit | Algorithms                                                                 |
113| ---- | -------------------------------------------------------------------------- |
114| 0    | AES-CCM-16-64-128, SHA-256, 8, X25519, EdDSA, AES-CCM-16-64-128, SHA-256   |
115| 1    | AES-CCM-16-128-128, SHA-256, 16, X25519, EdDSA, AES-CCM-16-64-128, SHA-256 |
116| 2    | AES-CCM-16-64-128, SHA-256, 8, P-256, ES256, AES-CCM-16-64-128, SHA-256    |
117| 3    | AES-CCM-16-128-128, SHA-256, 16, P-256, ES256, AES-CCM-16-64-128, SHA-256  |
118
119
120
121## Using the Samples
122
123The samples contained in `samples/` are supposed to enable the test and verification of a real OSCORE or EDHOC message exchange between two entities. There are samples that can be run on microcontrollers, e.g. NRF5x (using ZephyrOS) and samples that can be run on Linux systems.
124
125When using the samples for microcontroller , they have to be connected to an IPv6 network, which can be done with an IPv6 over BLE border router, using Bluetooth on the constrained devices. For further instructions on how to set up the border router on a Raspberry Pi, see [blerouter](externals/blerouter/README.MD).
126
127* **OSCORE Between a Microcontroller (e.g. nrf52832) as a Server and Linux Host as a Client**
128
129  The `oscore_device` samples suggest a use of a microcontroller, (e.g. nrf52832) as an OSCORE server and a Linux machine as an OSCORE client. Therefore setting up the network as described in [blerouter](externals/blerouter/README.MD) is required.
130  As this is a frequent error source: make sure that all addresses are set up correctly in the blerouter.sh script, the samples/oscore_linux/client/src/main.cpp file and the samples/oscore_device/server/prj.conf file.
131
132  * Configure and build OSCORE server on a microcontroller (nrf52832) using the Zephyr's build tool west
133
134    * open a terminal and cd to samples/oscore/device/server
135
136    ```bash
137    source <path to zephyr root>/zephyrproject/zephyr/zephyr-env.sh
138    west build -b=nrf52dk_nrf52832
139    west flash
140    ```
141
142    * The server is now reachable under the specified address and can be supplied with CoAP and OSCORE messages.
143
144  * On a Raspberry Pi start externals/blerouter
145
146    ```bash
147    sudo ./blerouter.sh -d OscoreServer
148    # if it works correctly you should see somthink like:
149    # [18:27:47] scanning for devices
150    # connect to D9:A4:16:41:CC:2D OscoreServer
151    # [18:27:54] connected with D9:A4:16:41:CC:2D OscoreServer
152    # [18:27:57] connected with D9:A4:16:41:CC:2D OscoreServer
153    # ...
154    ```
155
156
157
158  * Configure OSCORE Linux client
159
160    * open a terminal and cd to samples/oscore_linux/client
161
162    * run ```make``` and ```./build/oscore_linux_client to send CoAP and OSCORE messages to the OSCORE server
163
164* **OSCORE Between to Linux Hosts**
165
166  Adjust the IP address of the other party in  samples/oscore_linux/client and samples/oscore_linux/server and run them.
167
168* **EDHOC**
169
170  Two parties are involved in a EDHOC message exchange -- an initiator (typically client) and a responder (typically server). The `edhoc_device` samples suggest the communication between a microcontroller and a Linux machine, with the network set up as described in [blerouter](externals/blerouter/README.MD). However, there can also be two Linux machines or two microcontrollers performing the EDHOC exchange, with the latter case requiring a second RPi set up as border router and connected to the second microcontroller. The addresses have to be changed accordingly in the prj.conf files. The following describes the setup for the EDHOC exchange between microcontroller and linux machine.
171
172  * Microcontroller as initiator and Linux machine as responder
173
174      * open a terminal and cd to samples/edhoc_linux/responder
175      * make sure the IP addresses are correct
176      * run ```make``` and ```./build/responder``` to build and run
177      * the linux responder can now be supplied with an EDHOC requests
178      * cd to samples/edhoc_device/initiator
179
180      ```bash
181      source <path to zephyr root>/zephyrproject/zephyr/zephyr-env.sh
182      west build -b=nrf52dk_nrf52832
183      west flash
184      ```
185      * set up the border router as described here [blerouter](externals/blerouter/README.MD)
186
187      * the EDHOC message exchange should take place and the results should be printed on the linux machine - the message traffic can be captured and viewed using wireshark on the border router
188
189  * Linux machine as initiator and Microcontroller as responder
190
191    * open a terminal and cd to samples/edhoc_device/responder
192
193    ```bash
194    source <path to zephyr root>/zephyrproject/zephyr/zephyr-env.sh
195    west build -b=nrf52dk_nrf52832
196    west flash
197    ```
198
199    * set up the border router as described here [blerouter](externals/blerouter/README.MD)
200    * the Microcontroller can now be supplied with an EDHOC request
201    * cd to samples/edhoc_linux/initiator
202    * run ```make``` and ```./build/initiator``` to build and run
203    * the EDHOC message exchange should take place and the results should be printed on the linux machine - the message traffic can be captured and viewed using wireshark
204
205
206## Using Different Cryptographic Libraries or Hardware Accelerators
207
208The logic of uOSCORE and uEDHOC is independent form the cryptographic library, i.e., the cryptographic library can easily be exchanged by the user. For that the user needs to provide implementations for the functions specified in `crypto_wrapper.c`.
209
210