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