Contiki-NG
Loading...
Searching...
No Matches
edhoc-msgs.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024, RISE Research Institutes of Sweden AB
3 * Copyright (c) 2020, Industrial Systems Institute (ISI), Patras, Greece
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the copyright holder nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 */
31
32/**
33 * \file
34 * EDHOC message serialization and parsing API
35 *
36 * \author
37 * Lidia Pocero <pocero@isi.gr>, Peter A Jonsson, Rikard Höglund, Marco Tiloca, Niclas Finne <niclas.finne@ri.se>, Nicolas Tsiftes <nicolas.tsiftes@ri.se>
38 */
39#ifndef _EDHOC_MSGS_H__
40#define _EDHOC_MSGS_H__
41
42#include <stdint.h>
43#include <stddef.h>
44#include "edhoc-key-storage.h"
45#include "edhoc-config.h"
46#include "edhoc-error.h"
47#include "lib/cbor.h"
48
49
50typedef struct edhoc_ead_data {
51 int32_t ead_label; /* RFC 9528: EAD label is integer, negative = critical */
52 const uint8_t *ead_value; /* Optional EAD value (byte string) */
53 size_t ead_value_sz; /* Size of EAD value */
54} edhoc_ead_data_t;
55
56typedef struct edhoc_msg_1 {
57 uint8_t method;
58 uint8_t suites_i[EDHOC_SUITES_MAX_COUNT];
59 uint8_t suites_i_num;
60 const uint8_t *g_x;
61 const uint8_t *c_i;
62 size_t c_i_sz;
63 edhoc_ead_data_t uad;
64} edhoc_msg_1_t;
65
66typedef struct edhoc_msg_2 {
67 uint8_t *gy_ciphertext_2;
68 size_t gy_ciphertext_2_sz;
69} edhoc_msg_2_t;
70
71typedef struct edhoc_msg_3 {
72 uint8_t *ciphertext_3;
73 size_t ciphertext_3_sz;
74} edhoc_msg_3_t;
75
76#define EDHOC_MSG_ERR_CODE_RESERVED_FOR_SUCCESS 0
77#define EDHOC_MSG_ERR_CODE_UNSPECIFIED_ERROR 1
78#define EDHOC_MSG_ERR_CODE_WRONG_CIPHER_SUITE 2
79#define EDHOC_MSG_ERR_CODE_UNKNOWN_CREDENTIAL_SELECTION 3
80#define EDHOC_MSG_ERR_CODE_RESERVED 23
81
82typedef struct edhoc_msg_error {
83 uint8_t err_code;
84 union {
85 struct {
86 const char *err_info;
87 size_t err_info_sz;
88 } tstr;
89 struct {
90 uint8_t suites[EDHOC_SUITES_MAX_COUNT];
91 uint8_t suites_num;
92 } suites;
93 } info;
94} edhoc_msg_error_t;
95
96static inline uint8_t
97edhoc_msg_error_get_code(const edhoc_msg_error_t *msg)
98{
99 return msg->err_code;
100}
101
102static inline const char *
103edhoc_msg_error_get_info(const edhoc_msg_error_t *msg)
104{
105 return msg->info.tstr.err_info;
106}
107
108static inline size_t
109edhoc_msg_error_get_info_sz(const edhoc_msg_error_t *msg)
110{
111 return msg->err_code == EDHOC_MSG_ERR_CODE_UNSPECIFIED_ERROR
112 ? msg->info.tstr.err_info_sz
113 : 0;
114}
115
116static inline const uint8_t *
117edhoc_msg_error_get_suites(const edhoc_msg_error_t *msg)
118{
119 return msg->info.suites.suites;
120}
121
122static inline const uint8_t
123edhoc_msg_error_get_suites_num(const edhoc_msg_error_t *msg)
124{
125 return msg->err_code == EDHOC_MSG_ERR_CODE_WRONG_CIPHER_SUITE
126 ? msg->info.suites.suites_num
127 : 0;
128}
129
130/**
131 * \brief Print EDHOC message 1 contents for debugging
132 * \param msg input message 1 structure to print
133 */
134void print_msg_1(edhoc_msg_1_t *msg);
135
136/**
137 * \brief Print EDHOC message 2 contents for debugging
138 * \param msg input message 2 structure to print
139 */
140void print_msg_2(edhoc_msg_2_t *msg);
141
142/**
143 * \brief Print EDHOC message 3 contents for debugging
144 * \param msg input message 3 structure to print
145 */
146void print_msg_3(edhoc_msg_3_t *msg);
147
148/**
149 * \brief Serialize EDHOC message 1 to CBOR format
150 * \param msg input message 1 structure to serialize
151 * \param buffer output buffer for serialized data
152 * \param buffer_sz input size of output buffer
153 * \param suite_array input whether to encode suites as array (unused)
154 * \return size of serialized data on success, 0 on failure
155 */
156size_t edhoc_serialize_msg_1(edhoc_msg_1_t *msg, unsigned char *buffer, size_t buffer_sz, bool suite_array);
157
158/**
159 * \brief Serialize EDHOC error message to CBOR format
160 * \param msg input error message structure to serialize
161 * \param buffer output buffer for serialized data
162 * \param buffer_sz input size of output buffer
163 * \return size of serialized data on success, 0 on failure
164 */
165size_t edhoc_serialize_err(const edhoc_msg_error_t *msg, unsigned char *buffer, size_t buffer_sz);
166
167/**
168 * \brief Deserialize EDHOC message 1 from CBOR data
169 * \param msg output message 1 structure
170 * \param buffer input CBOR data to parse
171 * \param buff_sz input size of CBOR data
172 * \return EDHOC_SUCCESS on success, error code on failure
173 */
174edhoc_error_t edhoc_deserialize_msg_1(edhoc_msg_1_t *msg, unsigned char *buffer, size_t buff_sz);
175
176/**
177 * \brief Deserialize EDHOC message 2 from CBOR data
178 * \param msg output message 2 structure
179 * \param buffer input CBOR data to parse
180 * \param buff_sz input size of CBOR data
181 * \return EDHOC_SUCCESS on success, error code on failure
182 */
183edhoc_error_t edhoc_deserialize_msg_2(edhoc_msg_2_t *msg, unsigned char *buffer, size_t buff_sz);
184
185/**
186 * \brief Deserialize EDHOC message 3 from CBOR data
187 * \param msg output message 3 structure
188 * \param buffer input CBOR data to parse
189 * \param buff_sz input size of CBOR data
190 * \return EDHOC_SUCCESS on success, error code on failure
191 */
192edhoc_error_t edhoc_deserialize_msg_3(edhoc_msg_3_t *msg, unsigned char *buffer, size_t buff_sz);
193
194/**
195 * \brief Deserialize EDHOC error message from CBOR data
196 * \param msg output error message structure
197 * \param data input CBOR data to parse
198 * \param data_size input size of CBOR data
199 * \return \c true if the data could be parsed as an EDHOC error message,
200 * or \c false on error.
201 */
202bool edhoc_deserialize_err(edhoc_msg_error_t *msg, const uint8_t *data,
203 size_t data_size);
204
205/**
206 * \brief Get authentication key by Key ID (KID)
207 * \param kid input key identifier bytes
208 * \param kid_sz input key identifier length
209 * \param key output pointer to retrieved authentication key
210 * \return EDHOC_SUCCESS on success, error code on failure
211 *
212 * Searches the key repository for a key matching the provided KID.
213 */
214edhoc_error_t edhoc_get_auth_key_from_kid(uint8_t *kid, uint8_t kid_sz, cose_key_t **key);
215
216/**
217 * \brief Parse ID_CRED_X from CBOR data and extract authentication key
218 * \param reader input CBOR reader state positioned at ID_CRED_X data
219 * \param id_cred_x output buffer to store parsed ID_CRED_X (can be NULL)
220 * \param id_cred_x_buffer_size input size of id_cred_x buffer
221 * \param key output parsed authentication key information
222 * \return size of ID_CRED_X data on success, negative error code on failure
223 *
224 * Parses ID_CRED_X in three supported formats:
225 * - Compact encoding: bare KID value
226 * - Map format: {4: KID}
227 * - Full credential inclusion: complete COSE key structure
228 * Populates the key structure with authentication information.
229 */
230int8_t edhoc_get_key_id_cred_x(cbor_reader_state_t *reader, uint8_t *id_cred_x, size_t id_cred_x_buffer_size, cose_key_t *key);
231
232/**
233 * \brief Parse signature data from CBOR reader
234 * \param reader input CBOR reader state positioned at signature data
235 * \param sign output pointer to signature data (points into reader buffer)
236 * \return signature size in bytes on success, 0 on failure
237 *
238 * Reads and validates signature data from CBOR stream. The returned pointer
239 * references data within the reader's buffer and remains valid until the
240 * reader is reinitialized or goes out of scope.
241 */
242uint8_t edhoc_get_sign(cbor_reader_state_t *reader, uint8_t **sign);
243
244/**
245 * \brief Parse Additional Data (AD) from CBOR reader
246 * \param reader input CBOR reader state positioned at AD data
247 * \param ad output buffer to store parsed AD
248 * \param ad_buffer_size input size of ad buffer
249 * \return AD size in bytes on success, 0 on failure
250 *
251 * Reads Additional Data from CBOR stream and copies it to the provided buffer.
252 * Validates that the AD size does not exceed buffer or protocol limits.
253 */
254uint8_t edhoc_get_ad(cbor_reader_state_t *reader, uint8_t *ad, size_t ad_buffer_size);
255
256/**
257 * \brief Process and validate EAD (External Authorization Data) items
258 * \param ead_data input EAD data structure containing label and value
259 * \return EDHOC_SUCCESS on success, EDHOC_ERR_CRITICAL_EAD_UNSUPPORTED if critical EAD cannot be processed, other error code on failure
260 *
261 * Processes EAD items according to RFC 9528 Section 6:
262 * - Critical EAD items (negative ead_label) that cannot be processed trigger an error
263 * - Non-critical EAD items (non-negative ead_label) can be ignored
264 * Applications should implement custom handlers for recognized EAD labels.
265 */
266edhoc_error_t edhoc_process_ead_item(const edhoc_ead_data_t *ead_data);
267
268/**
269 * \brief Write EDHOC byte identifier according to RFC 9528 rules
270 * \param state output CBOR writer state
271 * \param bytes input identifier bytes to write
272 * \param len input length of identifier
273 *
274 * Writes byte identifiers following RFC 9528 optimization: single-byte
275 * identifiers that coincide with CBOR integer encoding (0x00-0x17, 0x20-0x37)
276 * are written as integers, others as byte strings.
277 */
278void edhoc_write_byte_identifier(cbor_writer_state_t *state, const uint8_t *bytes, size_t len);
279
280/**
281 * \brief Read byte identifier from CBOR reader
282 *
283 * Reads byte identifiers following RFC 9528 optimization. Returns pointer to
284 * the identifier bytes and sets size to the length.
285 */
286const uint8_t *edhoc_read_byte_identifier(cbor_reader_state_t *reader, size_t *size);
287
288
289#endif
CBOR API.
EDHOC configuration file.
Error handling module header for EDHOC.
edhoc_error_t
Unified error type for EDHOC operations.
Definition edhoc-error.h:60
EDHOC key storage - Implementation of key storage for managing DH-static authentication key pairs.
struct cose_key cose_key_t
KEY length in bytes.
edhoc_error_t edhoc_deserialize_msg_1(edhoc_msg_1_t *msg, unsigned char *buffer, size_t buff_sz)
Deserialize EDHOC message 1 from CBOR data.
Definition edhoc-msgs.c:299
void print_msg_3(edhoc_msg_3_t *msg)
Print EDHOC message 3 contents for debugging.
Definition edhoc-msgs.c:77
void edhoc_write_byte_identifier(cbor_writer_state_t *state, const uint8_t *bytes, size_t len)
Write EDHOC byte identifier according to RFC 9528 rules.
Definition edhoc-msgs.c:108
size_t edhoc_serialize_err(const edhoc_msg_error_t *msg, unsigned char *buffer, size_t buffer_sz)
Serialize EDHOC error message to CBOR format.
Definition edhoc-msgs.c:201
void print_msg_1(edhoc_msg_1_t *msg)
Print EDHOC message 1 contents for debugging.
Definition edhoc-msgs.c:51
const uint8_t * edhoc_read_byte_identifier(cbor_reader_state_t *reader, size_t *size)
Read byte identifier from CBOR reader.
Definition edhoc-msgs.c:85
uint8_t edhoc_get_ad(cbor_reader_state_t *reader, uint8_t *ad, size_t ad_buffer_size)
Parse Additional Data (AD) from CBOR reader.
Definition edhoc-msgs.c:734
void print_msg_2(edhoc_msg_2_t *msg)
Print EDHOC message 2 contents for debugging.
Definition edhoc-msgs.c:69
edhoc_error_t edhoc_deserialize_msg_3(edhoc_msg_3_t *msg, unsigned char *buffer, size_t buff_sz)
Deserialize EDHOC message 3 from CBOR data.
Definition edhoc-msgs.c:425
edhoc_error_t edhoc_get_auth_key_from_kid(uint8_t *kid, uint8_t kid_sz, cose_key_t **key)
Get authentication key by Key ID (KID).
Definition edhoc-msgs.c:462
size_t edhoc_serialize_msg_1(edhoc_msg_1_t *msg, unsigned char *buffer, size_t buffer_sz, bool suite_array)
Serialize EDHOC message 1 to CBOR format.
Definition edhoc-msgs.c:177
uint8_t edhoc_get_sign(cbor_reader_state_t *reader, uint8_t **sign)
Parse signature data from CBOR reader.
Definition edhoc-msgs.c:709
edhoc_error_t edhoc_deserialize_msg_2(edhoc_msg_2_t *msg, unsigned char *buffer, size_t buff_sz)
Deserialize EDHOC message 2 from CBOR data.
Definition edhoc-msgs.c:388
edhoc_error_t edhoc_process_ead_item(const edhoc_ead_data_t *ead_data)
Process and validate EAD (External Authorization Data) items.
Definition edhoc-msgs.c:765
bool edhoc_deserialize_err(edhoc_msg_error_t *msg, const uint8_t *data, size_t data_size)
Deserialize EDHOC error message from CBOR data.
Definition edhoc-msgs.c:227
int8_t edhoc_get_key_id_cred_x(cbor_reader_state_t *reader, uint8_t *id_cred_x, size_t id_cred_x_buffer_size, cose_key_t *key)
Parse ID_CRED_X from CBOR data and extract authentication key.
Definition edhoc-msgs.c:670
#define EDHOC_SUITES_MAX_COUNT
The max number of suites.
Structure of the internal state of a CBOR reader.
Definition cbor.h:130
Structure of the internal state of a CBOR writer.
Definition cbor.h:119