1 /*
2    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
3    file at the top-level directory of this distribution.
4 
5    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8    option. This file may not be copied, modified, or distributed
9    except according to those terms.
10 */
11 
12 #ifndef EDHOC_H
13 #define EDHOC_H
14 
15 #include <stdint.h>
16 
17 #include "edhoc/edhoc_method_type.h"
18 #include "edhoc/messages.h"
19 #include "edhoc/suites.h"
20 #include "edhoc/hkdf_info.h"
21 
22 #include "common/oscore_edhoc_error.h"
23 #include "common/byte_array.h"
24 #include "common/print_util.h"
25 
26 /*define EDHOC_BUF_SIZES_RPK in order to use smaller buffers and save some RAM if need when RPKs are used*/
27 //#define EDHOC_BUF_SIZES_RPK
28 //#define EDHOC_BUF_SIZES_C509_CERT
29 #define EDHOC_BUF_SIZES_X509_CERT
30 
31 #if defined EDHOC_BUF_SIZES_RPK
32 #define MSG_MAX_SIZE 100
33 #define CIPHERTEXT2_DEFAULT_SIZE 100
34 #define CIPHERTEXT3_DEFAULT_SIZE 100
35 #define A_2M_DEFAULT_SIZE 200
36 #define M_3_DEFAULT_SIZE 200
37 #define CRED_DEFAULT_SIZE 128
38 #define SGN_OR_MAC_DEFAULT_SIZE 128
39 #define ID_CRED_DEFAULT_SIZE 20
40 #define PRK_3AE_DEFAULT_SIZE 100
41 #define CERT_DEFAUT_SIZE 128
42 #define CONTEXT_MAC_DEFAULT_SIZE 200
43 #define INFO_DEFAULT_SIZE 250
44 #define SIGNATURE_STRUCT_DEFAULT_SIZE 300
45 #endif
46 
47 #if defined EDHOC_BUF_SIZES_C509_CERT
48 #define MSG_MAX_SIZE 255
49 #define CIPHERTEXT2_DEFAULT_SIZE 255
50 #define CIPHERTEXT3_DEFAULT_SIZE 255
51 #define CIPHERTEXT4_DEFAULT_SIZE 255
52 #define A_2M_DEFAULT_SIZE 512
53 #define M_3_DEFAULT_SIZE 512
54 #define CRED_DEFAULT_SIZE 255
55 #define SGN_OR_MAC_DEFAULT_SIZE 128
56 #define ID_CRED_DEFAULT_SIZE 255
57 #define PLAINTEXT_DEFAULT_SIZE 255
58 #define CERT_DEFAUT_SIZE 255
59 #define CONTEXT_MAC_DEFAULT_SIZE 200
60 #define INFO_DEFAULT_SIZE 250
61 #define SIGNATURE_STRUCT_DEFAULT_SIZE 300
62 #endif
63 
64 #if defined EDHOC_BUF_SIZES_X509_CERT
65 #define MSG_MAX_SIZE 700
66 #define PLAINTEXT_DEFAULT_SIZE 1580
67 #define CIPHERTEXT2_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE
68 #define CIPHERTEXT3_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE
69 #define CIPHERTEXT4_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE
70 #define A_2M_DEFAULT_SIZE 512
71 #define M_3_DEFAULT_SIZE 512
72 #define CRED_DEFAULT_SIZE 600
73 #define SGN_OR_MAC_DEFAULT_SIZE 128
74 #define ID_CRED_DEFAULT_SIZE 600
75 #define CERT_DEFAULT_SIZE 600
76 #define CONTEXT_MAC_DEFAULT_SIZE 1580
77 #define INFO_DEFAULT_SIZE 1580
78 #define SIGNATURE_STRUCT_DEFAULT_SIZE 1580
79 #endif
80 
81 #define SUITES_MAX 5
82 #define ERR_MSG_DEFAULT_SIZE 64
83 #define P_256_PRIV_KEY_DEFAULT_SIZE 32
84 #define P_256_PUB_KEY_COMPRESSED_SIZE 33
85 #define P_256_PUB_KEY_UNCOMPRESSED_SIZE 65
86 #define P_256_PUB_KEY_X_CORD_SIZE 32
87 #define PK_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE
88 #define C_R_DEFAULT_SIZE 16
89 #define C_I_DEFAULT_SIZE 16
90 #define G_Y_DEFAULT_SIZE P_256_PUB_KEY_X_CORD_SIZE
91 #define G_X_DEFAULT_SIZE P_256_PUB_KEY_X_CORD_SIZE
92 #define G_R_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE
93 #define G_I_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE
94 #define DATA_2_DEFAULT_SIZE                                                    \
95 	(C_I_DEFAULT_SIZE + G_Y_DEFAULT_SIZE + C_R_DEFAULT_SIZE)
96 #define TH2_INPUT_DEFAULT_SIZE                                                 \
97 	(G_Y_DEFAULT_SIZE + C_R_DEFAULT_SIZE + HASH_DEFAULT_SIZE)
98 #define TH34_INPUT_DEFAULT_SIZE                                                \
99 	(HASH_DEFAULT_SIZE + PLAINTEXT_DEFAULT_SIZE + CRED_DEFAULT_SIZE)
100 #define ECDH_SECRET_DEFAULT_SIZE 32
101 #define DERIVED_SECRET_DEFAULT_SIZE 32
102 #define AD_DEFAULT_SIZE 256
103 #define PRK_DEFAULT_SIZE 32
104 #define ASSOCIATED_DATA_DEFAULT_SIZE 64
105 #define KID_DEFAULT_SIZE 8
106 #define HASH_DEFAULT_SIZE 32
107 #define AEAD_KEY_DEFAULT_SIZE 16
108 #define MAC_DEFAULT_SIZE 16
109 #define AEAD_IV_DEFAULT_SIZE 13
110 #define SIGNATURE_DEFAULT_SIZE 64
111 #define TH_ENC_DEFAULT_SIZE 42
112 #define ENCODING_OVERHEAD 6
113 
114 #ifdef _WIN32
115 #define WEAK
116 #else
117 #define WEAK __attribute__((weak))
118 #endif
119 
120 struct other_party_cred {
121 	struct byte_array id_cred; /*ID_CRED_x of the other party*/
122 	struct byte_array cred; /*CBOR encoded credentials*/
123 	struct byte_array pk; /*authentication pub key of the other party */
124 	struct byte_array g; /*authentication static DH pub key of other party */
125 	struct byte_array ca; /*use only when authentication with certificates*/
126 	struct byte_array
127 		ca_pk; /*use only when authentication with certificates*/
128 };
129 
130 struct edhoc_responder_context {
131 	bool msg4; /*if true massage 4 will be send by the responder*/
132 	struct byte_array c_r; /*connection identifier of the responder*/
133 	struct byte_array suites_r;
134 	struct byte_array g_y; /*ephemeral dh public key*/
135 	struct byte_array y; /*ephemeral dh secret key*/
136 
137 	struct byte_array g_r; /* static DH pk -> use only with method 1 or 3*/
138 	struct byte_array r; /* static DH sk -> use only with method 1 or 3*/
139 	struct byte_array ead_2;
140 	struct byte_array ead_4;
141 	struct byte_array id_cred_r;
142 	struct byte_array cred_r;
143 	struct byte_array sk_r; /*sign key -use with method 0 and 2*/
144 	struct byte_array pk_r; /*coresp. pk to sk_r -use with method 0 and 2*/
145 	void *sock; /*pointer used as handler for sockets by tx/rx */
146 };
147 
148 struct edhoc_initiator_context {
149 	bool msg4; /*if true massage 4 will be send by the responder*/
150 	struct byte_array c_i; /*connection identifier of the initiator*/
151 	enum method_type method;
152 	//uint8_t corr;
153 	struct byte_array suites_i;
154 	struct byte_array ead_1;
155 	struct byte_array ead_3;
156 	struct byte_array id_cred_i;
157 	struct byte_array cred_i;
158 	struct byte_array g_x; /*ephemeral dh public key*/
159 	struct byte_array x; /*ephemeral dh secret key*/
160 	struct byte_array g_i; /* static DH pk -> use only with method 2 or 3*/
161 	struct byte_array i; /* static DH sk -> use only with method 2 or 3*/
162 	struct byte_array sk_i; /*sign key use with method 0 and 2*/
163 	struct byte_array pk_i; /*coresp. pk to sk_r -use with method 0 and 2*/
164 	void *sock; /*pointer used as handler for sockets by tx/rx */
165 };
166 
167 /**
168  * @brief   Generates public and private ephemeral DH keys from a random seed.
169  *
170  *          IMPORTANT!!! PROVIDE A GOOD RANDOM SEED!
171  *
172  * @param   curve DH curve to used
173  * @param   seed a random seed
174  * @param   sk pointer to a buffer where the secret key will be strored
175  * @param   pk pointer to a buffer where the public key will be strored
176  * @param   pk_size pointer to a variable with public key buffer size as input,
177  *          and public key length as output.
178 
179  */
180 enum err WEAK ephemeral_dh_key_gen(enum ecdh_alg alg, uint32_t seed,
181 				   uint8_t *sk, uint8_t *pk, uint32_t *pk_size);
182 
183 /**
184  * @brief   Executes the EDHOC protocol on the initiator side
185  * @param   c cointer to a structure containing initialization parameters
186  * @param   cred_r_array containing elements of type other_party_cred used for
187  *          the retrival of the other party (the responder) parameters at run
188  *          time
189  * @param   num_cred_r number of the elements in cred_r_array
190  * @param   err_msg in case that an error message is received its contend is
191  *          provided to the caller though the err_msg
192  * @param   ead_2 the received in msg2 additional data is provided to the
193  *          caller through ead_2
194  * @param   ead_2_len length of ead_2
195  * @param   prk_out the derived shared secret
196  * @param   prk_out_len length of prk_out
197  */
198 enum err edhoc_initiator_run(
199 	const struct edhoc_initiator_context *c,
200 	struct other_party_cred *cred_r_array, uint16_t num_cred_r,
201 	uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_2,
202 	uint32_t *ead_2_len, uint8_t *ead_4, uint32_t *ead_4_len,
203 	uint8_t *prk_out, uint32_t prk_out_len,
204 	enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len),
205 	enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len));
206 
207 /**
208  * @brief   Executes the EDHOC protocol on the initiator side
209  * @param   c cointer to a structure containing initialization parameters
210  * @param   cred_r_array containing elements of type other_party_cred used for
211  *          the retrival of the other party (the responder) parameters at run
212  *          time
213  * @param   num_cred_r number of the elements in cred_r_array
214  * @param   err_msg in case that an error message is received its contend is
215  *          provided to the caller though the err_msg
216  * @param   ead_2 the received in msg2 additional data is provided to the
217  *          caller through ead_2
218  * @param   ead_2_len length of ead_2
219  * @param   c_r_bytes connection identifier
220  * @param   c_r_bytes_len length of c_i_bytes
221  * @param   prk_out the derived shared secret
222  * @param   prk_out_len length of prk_out
223  */
224 enum err edhoc_initiator_run_extended(
225 	const struct edhoc_initiator_context *c,
226 	struct other_party_cred *cred_r_array, uint16_t num_cred_r,
227 	uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_2,
228 	uint32_t *ead_2_len, uint8_t *ead_4, uint32_t *ead_4_len,
229 	uint8_t *c_r_bytes, uint32_t *c_r_bytes_len, uint8_t *prk_out,
230 	uint32_t prk_out_len,
231 	enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len),
232 	enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len));
233 
234 /**
235  * @brief   Executes the EDHOC protocol on the responder side
236  * @param   c cointer to a structure containing initialization parameters
237  * @param   cred_i_array containing elements of type other_party_cred used for
238  *          the retrival of the other party (the initiator) parameters at run
239  *          time
240  * @param   num_cred_i number of the elements in cred_i_array
241  * @param   err_msg in case that an error message is received its contend is
242  *          provided to the caller though the err_msg
243  * @param   ead_1 the received in msg1 additional data is provided to the caller
244  *          through ead_1
245  * @param   ead_1_len length of ead_1
246  * @param   ead_3 the received in msg3 additional data is provided to the caller
247  *          through ead_3
248  * @param   ead_3_len length of ead_3
249  * @param   prk_out the derived shared secret
250  * @param   prk_out_len length of prk_out
251  */
252 enum err edhoc_responder_run(
253 	struct edhoc_responder_context *c,
254 	struct other_party_cred *cred_i_array, uint16_t num_cred_i,
255 	uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_1,
256 	uint32_t *ead_1_len, uint8_t *ead_3, uint32_t *ead_3_len,
257 	uint8_t *prk_out, uint32_t prk_out_len,
258 	enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len),
259 	enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len));
260 
261 /**
262  * @brief   Executes the EDHOC protocol on the responder side
263  * @param   c cointer to a structure containing initialization parameters
264  * @param   cred_i_array containing elements of type other_party_cred used for
265  *          the retrival of the other party (the initiator) parameters at run
266  *          time
267  * @param   num_cred_i number of the elements in cred_i_array
268  * @param   err_msg in case that an error message is received its contend is
269  *          provided to the caller though the err_msg
270  * @param   ead_1 the received in msg1 additional data is provided to the caller
271  *          through ead_1
272  * @param   ead_1_len length of ead_1
273  * @param   ead_3 the received in msg3 additional data is provided to the caller
274  *          through ead_3
275  * @param   ead_3_len length of ead_3
276  * @param   prk_out the derived shared secret
277  * @param   prk_out_len length of prk_out
278  * @param   client_pub_key public key of the initiator
279  * @param   client_pub_key_size length of client_pub_key
280  * @param   c_i_bytes connection identifier
281  * @param   c_i_bytes_len length of c_i_bytes
282  */
283 enum err edhoc_responder_run_extended(
284 	struct edhoc_responder_context *c,
285 	struct other_party_cred *cred_i_array, uint16_t num_cred_i,
286 	uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_1,
287 	uint32_t *ead_1_len, uint8_t *ead_3, uint32_t *ead_3_len,
288 	uint8_t *prk_out, uint32_t prk_out_len, uint8_t *client_pub_key,
289 	uint32_t *client_pub_key_size, uint8_t *c_i_bytes,
290 	uint32_t *c_i_bytes_len,
291 	enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len),
292 	enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len));
293 
294 /**
295  * @brief Computes PRK_exporter from PRK_out
296  *
297  * @param app_hash_alg 	the EDHOC hash algorithm
298  * @param prk_out 		the product of a successful EDHOC execution
299  * @param prk_out_len 	length of prk_out
300  * @param prk_exporter 	pointer where the prk_exporter value will be written
301  * @return enum err 0 or error code
302  */
303 enum err prk_out2exporter(enum hash_alg app_hash_alg, uint8_t *prk_out,
304 			  uint32_t prk_out_len, uint8_t *prk_exporter);
305 
306 /**
307  * @brief Updates PRK_out
308  *
309  * @param app_hash_alg 	the EDHOC hash algorithm
310  * @param prk_out 		the product of a successful EDHOC execution
311  * @param prk_out_len 	length of prk_out
312  * @param context		A context on which initiator and responder needs to
313  * 						agree in front
314  * @param context_len	length of context
315  * @param prk_out_new 	pointer where the prk_out_new value will be written
316  * @return enum err 0 or error code
317  */
318 enum err prk_out_update(enum hash_alg app_hash_alg, uint8_t *prk_out,
319 			uint32_t prk_out_len, uint8_t *context,
320 			uint32_t context_len, uint8_t *prk_out_new);
321 
322 enum export_label {
323 	OSCORE_MASTER_SECRET = 0,
324 	OSCORE_MASTER_SALT = 1,
325 };
326 
327 /**
328  * @brief 	Computes key material to be used within the application,
329  * 			e.g., OSCORE master secret or OSCORE master salt
330  *
331  * @param app_hash_alg		the application hash algorithm
332  * @param label				an uint value defined by the application
333  * @param prk_exporter		PRK computed with prk_out2exporter()
334  * @param prk_exporter_len 	length of prk_exporter
335  * @param out 				the result of the computation,
336  * 							e.g., OSCORE master secret or OSCORE master salt
337  * @param out_len 			length of out
338  * @return enum err 		0 or error code
339  */
340 enum err edhoc_exporter(enum hash_alg app_hash_alg, enum export_label label,
341 			uint8_t *prk_exporter, uint32_t prk_exporter_len,
342 			uint8_t *out, uint32_t out_len);
343 
344 #endif
345