1 /*
2  * Copyright (c) 2022 Eriptic Technologies.
3  *
4  * SPDX-License-Identifier: Apache-2.0 or MIT
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9 #include <zephyr/debug/thread_analyzer.h>
10 
11 #include <edhoc.h>
12 
13 #include "edhoc_test_vectors_p256_v15.h"
14 #include "latency.h"
15 
16 uint8_t I_prk_exporter_buf[32];
17 struct byte_array I_prk_exporter = { .ptr = I_prk_exporter_buf,
18 				     .len = sizeof(I_prk_exporter_buf) };
19 
20 uint8_t I_master_secret_buf[16];
21 struct byte_array I_master_secret = { .ptr = I_master_secret_buf,
22 				      .len = sizeof(I_master_secret_buf) };
23 
24 uint8_t I_master_salt_buf[8];
25 struct byte_array I_master_salt = { .ptr = I_master_salt_buf,
26 				    .len = sizeof(I_master_salt_buf) };
27 
28 uint8_t I_PRK_out_buf[32];
29 struct byte_array I_PRK_out = { .ptr = I_PRK_out_buf,
30 				.len = sizeof(I_PRK_out_buf) };
31 
32 uint8_t I_err_msg_buf[0];
33 struct byte_array I_err_msg = { .ptr = I_err_msg_buf,
34 				.len = sizeof(I_err_msg_buf) };
35 /******************************************************************************/
36 
37 uint8_t R_prk_exporter_buf[32];
38 struct byte_array R_prk_exporter = { .ptr = R_prk_exporter_buf,
39 				     .len = sizeof(R_prk_exporter_buf) };
40 
41 uint8_t R_master_secret_buf[16];
42 struct byte_array R_master_secret = { .ptr = R_master_secret_buf,
43 				      .len = sizeof(R_master_secret_buf) };
44 
45 uint8_t R_master_salt_buf[8];
46 struct byte_array R_master_salt = { .ptr = R_master_salt_buf,
47 				    .len = sizeof(R_master_salt_buf) };
48 
49 uint8_t R_PRK_out_buf[32];
50 struct byte_array R_PRK_out = { .ptr = R_PRK_out_buf,
51 				.len = sizeof(R_PRK_out_buf) };
52 
53 uint8_t R_err_msg_buf[0];
54 struct byte_array R_err_msg = { .ptr = R_err_msg_buf,
55 				.len = sizeof(R_err_msg_buf) };
56 
57 /* size of stack area used by each thread */
58 #define STACKSIZE 7500
59 /* scheduling priority used by each thread */
60 #define PRIORITY 7
61 K_THREAD_STACK_DEFINE(thread_initiator_stack_area, STACKSIZE);
62 static struct k_thread thread_initiator_data;
63 K_THREAD_STACK_DEFINE(thread_responder_stack_area, STACKSIZE);
64 static struct k_thread thread_responder_data;
65 
66 /*semaphores*/
67 K_SEM_DEFINE(tx_initiator_completed, 0, 1);
68 K_SEM_DEFINE(tx_responder_completed, 0, 1);
69 
70 /*message exchange buffer*/
71 uint8_t msg_exchange_buf[1024];
72 uint32_t msg_exchange_buf_len = sizeof(msg_exchange_buf);
73 
semaphore_give(struct k_sem * sem)74 void semaphore_give(struct k_sem *sem)
75 {
76 	k_sem_give(sem);
77 }
78 
semaphore_take(struct k_sem * sem,uint8_t * data,uint32_t * data_len)79 enum err semaphore_take(struct k_sem *sem, uint8_t *data, uint32_t *data_len)
80 {
81 	if (k_sem_take(sem, K_FOREVER) != 0) {
82 		PRINT_MSG("Cannot receive a message!\n");
83 	} else {
84 		if (msg_exchange_buf_len > *data_len) {
85 			return buffer_to_small;
86 		} else {
87 			memcpy(data, msg_exchange_buf, *data_len);
88 			*data_len = msg_exchange_buf_len;
89 		}
90 	}
91 	return ok;
92 }
93 
copy_message(uint8_t * data,uint32_t data_len)94 enum err copy_message(uint8_t *data, uint32_t data_len)
95 {
96 	if (data_len > sizeof(msg_exchange_buf)) {
97 		PRINT_MSG("msg_exchange_buf to small\n");
98 		return buffer_to_small;
99 	} else {
100 		memcpy(msg_exchange_buf, data, data_len);
101 		msg_exchange_buf_len = data_len;
102 	}
103 	return ok;
104 }
105 
tx_initiator(void * sock,struct byte_array * data)106 enum err tx_initiator(void *sock, struct byte_array *data)
107 {
108 	enum err r = copy_message(data->ptr, data->len);
109 	if (r != ok) {
110 		return r;
111 	}
112 	semaphore_give(&tx_initiator_completed);
113 	return ok;
114 }
115 
tx_responder(void * sock,struct byte_array * data)116 enum err tx_responder(void *sock, struct byte_array *data)
117 {
118 	//PRINTF("tx_responder data len: %d\n", data->len);
119 	enum err r = copy_message(data->ptr, data->len);
120 	if (r != ok) {
121 		return r;
122 	}
123 	//PRINTF("msg_exchange_buf_len: %d\n",msg_exchange_buf_len);
124 	semaphore_give(&tx_responder_completed);
125 	return ok;
126 }
127 
rx_initiator(void * sock,struct byte_array * data)128 enum err rx_initiator(void *sock, struct byte_array *data)
129 {
130 	PRINTF("msg_exchange_buf_len: %d\n", msg_exchange_buf_len);
131 	return semaphore_take(&tx_responder_completed, data->ptr, &data->len);
132 }
rx_responder(void * sock,struct byte_array * data)133 enum err rx_responder(void *sock, struct byte_array *data)
134 {
135 	return semaphore_take(&tx_initiator_completed, data->ptr, &data->len);
136 }
ead_process(void * params,struct byte_array * ead13)137 enum err ead_process(void *params, struct byte_array *ead13)
138 {
139 	return ok;
140 }
141 
142 /**
143  * @brief			A thread in which an Initiator instance is executed
144  *
145  * @param vec_num 	Test vector number
146  * @param dummy2 	unused
147  * @param dummy3 	unused
148  */
thread_initiator(void * vec_num,void * dummy2,void * dummy3)149 void thread_initiator(void *vec_num, void *dummy2, void *dummy3)
150 {
151 	ARG_UNUSED(dummy2);
152 	ARG_UNUSED(dummy3);
153 
154 	PRINT_MSG("Initiator thread started!\n");
155 	int vec_num_i = *((int *)vec_num) - 1;
156 
157 	enum err r;
158 
159 	struct other_party_cred cred_r;
160 	struct edhoc_initiator_context c_i;
161 
162 	c_i.sock = NULL;
163 	c_i.c_i.len = test_vectors[vec_num_i].c_i_len;
164 	c_i.c_i.ptr = (uint8_t *)test_vectors[vec_num_i].c_i;
165 	c_i.method = (enum method_type) * test_vectors[vec_num_i].method;
166 	c_i.suites_i.len = test_vectors[vec_num_i].SUITES_I_len;
167 	c_i.suites_i.ptr = (uint8_t *)test_vectors[vec_num_i].SUITES_I;
168 	c_i.ead_1.len = test_vectors[vec_num_i].ead_1_len;
169 	c_i.ead_1.ptr = (uint8_t *)test_vectors[vec_num_i].ead_1;
170 	c_i.ead_3.len = test_vectors[vec_num_i].ead_3_len;
171 	c_i.ead_3.ptr = (uint8_t *)test_vectors[vec_num_i].ead_3;
172 	c_i.id_cred_i.len = test_vectors[vec_num_i].id_cred_i_len;
173 	c_i.id_cred_i.ptr = (uint8_t *)test_vectors[vec_num_i].id_cred_i;
174 	c_i.cred_i.len = test_vectors[vec_num_i].cred_i_len;
175 	c_i.cred_i.ptr = (uint8_t *)test_vectors[vec_num_i].cred_i;
176 	c_i.g_x.len = test_vectors[vec_num_i].g_x_raw_len;
177 	c_i.g_x.ptr = (uint8_t *)test_vectors[vec_num_i].g_x_raw;
178 	c_i.x.len = test_vectors[vec_num_i].x_raw_len;
179 	c_i.x.ptr = (uint8_t *)test_vectors[vec_num_i].x_raw;
180 	c_i.g_i.len = test_vectors[vec_num_i].g_i_raw_len;
181 	c_i.g_i.ptr = (uint8_t *)test_vectors[vec_num_i].g_i_raw;
182 	c_i.i.len = test_vectors[vec_num_i].i_raw_len;
183 	c_i.i.ptr = (uint8_t *)test_vectors[vec_num_i].i_raw;
184 	c_i.sk_i.len = test_vectors[vec_num_i].sk_i_raw_len;
185 	c_i.sk_i.ptr = (uint8_t *)test_vectors[vec_num_i].sk_i_raw;
186 	c_i.pk_i.len = test_vectors[vec_num_i].pk_i_raw_len;
187 	c_i.pk_i.ptr = (uint8_t *)test_vectors[vec_num_i].pk_i_raw;
188 
189 	cred_r.id_cred.len = test_vectors[vec_num_i].id_cred_r_len;
190 	cred_r.id_cred.ptr = (uint8_t *)test_vectors[vec_num_i].id_cred_r;
191 	cred_r.cred.len = test_vectors[vec_num_i].cred_r_len;
192 	cred_r.cred.ptr = (uint8_t *)test_vectors[vec_num_i].cred_r;
193 	cred_r.g.len = test_vectors[vec_num_i].g_r_raw_len;
194 	cred_r.g.ptr = (uint8_t *)test_vectors[vec_num_i].g_r_raw;
195 	cred_r.pk.len = test_vectors[vec_num_i].pk_r_raw_len;
196 	cred_r.pk.ptr = (uint8_t *)test_vectors[vec_num_i].pk_r_raw;
197 	cred_r.ca.len = test_vectors[vec_num_i].ca_r_len;
198 	cred_r.ca.ptr = (uint8_t *)test_vectors[vec_num_i].ca_r;
199 	cred_r.ca_pk.len = test_vectors[vec_num_i].ca_r_pk_len;
200 	cred_r.ca_pk.ptr = (uint8_t *)test_vectors[vec_num_i].ca_r_pk;
201 
202 	struct cred_array cred_r_array = { .len = 1, .ptr = &cred_r };
203 
204 	r = edhoc_initiator_run(&c_i, &cred_r_array, &I_err_msg, &I_PRK_out,
205 				tx_initiator, rx_initiator, ead_process);
206 	if (r != ok) {
207 		goto end;
208 	}
209 
210 	PRINT_ARRAY("I_PRK_out", I_PRK_out.ptr, I_PRK_out.len);
211 
212 	r = prk_out2exporter(SHA_256, &I_PRK_out, &I_prk_exporter);
213 	if (r != ok) {
214 		goto end;
215 	}
216 	PRINT_ARRAY("I_prk_exporter", I_prk_exporter.ptr, I_prk_exporter.len);
217 
218 	r = edhoc_exporter(SHA_256, OSCORE_MASTER_SECRET, &I_prk_exporter,
219 			   &I_master_secret);
220 	if (r != ok) {
221 		goto end;
222 	}
223 	PRINT_ARRAY("OSCORE Master Secret", I_master_secret.ptr,
224 		    I_master_secret.len);
225 
226 	r = edhoc_exporter(SHA_256, OSCORE_MASTER_SALT, &I_prk_exporter,
227 			   &I_master_salt);
228 	if (r != ok) {
229 		goto end;
230 	}
231 	PRINT_ARRAY("OSCORE Master Salt", I_master_salt.ptr, I_master_salt.len);
232 
233 #ifdef REPORT_STACK_USAGE
234 	thread_analyzer_print();
235 #endif
236 
237 	return;
238 end:
239 	PRINTF("An error has occurred. Error code: %d\n", r);
240 }
241 
242 /**
243  * @brief			A thread in which a Responder instance is executed
244  *
245  * @param vec_num 	Test vector number
246  * @param dummy2 	unused
247  * @param dummy3 	unused
248  */
thread_responder(void * vec_num,void * dummy2,void * dummy3)249 void thread_responder(void *vec_num, void *dummy2, void *dummy3)
250 {
251 	ARG_UNUSED(dummy2);
252 	ARG_UNUSED(dummy3);
253 
254 	PRINT_MSG("Responder thread started!\n");
255 	enum err r;
256 	int vec_num_i = *((int *)vec_num) - 1;
257 
258 	/* test vector inputs */
259 	struct other_party_cred cred_i;
260 	struct edhoc_responder_context c_r;
261 
262 	c_r.sock = NULL;
263 	c_r.c_r.ptr = (uint8_t *)test_vectors[vec_num_i].c_r;
264 	c_r.c_r.len = test_vectors[vec_num_i].c_r_len;
265 	c_r.suites_r.len = test_vectors[vec_num_i].SUITES_R_len;
266 	c_r.suites_r.ptr = (uint8_t *)test_vectors[vec_num_i].SUITES_R;
267 	c_r.ead_2.len = test_vectors[vec_num_i].ead_2_len;
268 	c_r.ead_2.ptr = (uint8_t *)test_vectors[vec_num_i].ead_2;
269 	c_r.ead_4.len = test_vectors[vec_num_i].ead_4_len;
270 	c_r.ead_4.ptr = (uint8_t *)test_vectors[vec_num_i].ead_4;
271 	c_r.id_cred_r.len = test_vectors[vec_num_i].id_cred_r_len;
272 	c_r.id_cred_r.ptr = (uint8_t *)test_vectors[vec_num_i].id_cred_r;
273 	c_r.cred_r.len = test_vectors[vec_num_i].cred_r_len;
274 	c_r.cred_r.ptr = (uint8_t *)test_vectors[vec_num_i].cred_r;
275 	c_r.g_y.len = test_vectors[vec_num_i].g_y_raw_len;
276 	c_r.g_y.ptr = (uint8_t *)test_vectors[vec_num_i].g_y_raw;
277 	c_r.y.len = test_vectors[vec_num_i].y_raw_len;
278 	c_r.y.ptr = (uint8_t *)test_vectors[vec_num_i].y_raw;
279 	c_r.g_r.len = test_vectors[vec_num_i].g_r_raw_len;
280 	c_r.g_r.ptr = (uint8_t *)test_vectors[vec_num_i].g_r_raw;
281 	c_r.r.len = test_vectors[vec_num_i].r_raw_len;
282 	c_r.r.ptr = (uint8_t *)test_vectors[vec_num_i].r_raw;
283 	c_r.sk_r.len = test_vectors[vec_num_i].sk_r_raw_len;
284 	c_r.sk_r.ptr = (uint8_t *)test_vectors[vec_num_i].sk_r_raw;
285 	c_r.pk_r.len = test_vectors[vec_num_i].pk_r_raw_len;
286 	c_r.pk_r.ptr = (uint8_t *)test_vectors[vec_num_i].pk_r_raw;
287 
288 	cred_i.id_cred.len = test_vectors[vec_num_i].id_cred_i_len;
289 	cred_i.id_cred.ptr = (uint8_t *)test_vectors[vec_num_i].id_cred_i;
290 	cred_i.cred.len = test_vectors[vec_num_i].cred_i_len;
291 	cred_i.cred.ptr = (uint8_t *)test_vectors[vec_num_i].cred_i;
292 	cred_i.g.len = test_vectors[vec_num_i].g_i_raw_len;
293 	cred_i.g.ptr = (uint8_t *)test_vectors[vec_num_i].g_i_raw;
294 	cred_i.pk.len = test_vectors[vec_num_i].pk_i_raw_len;
295 	cred_i.pk.ptr = (uint8_t *)test_vectors[vec_num_i].pk_i_raw;
296 	cred_i.ca.len = test_vectors[vec_num_i].ca_i_len;
297 	cred_i.ca.ptr = (uint8_t *)test_vectors[vec_num_i].ca_i;
298 	cred_i.ca_pk.len = test_vectors[vec_num_i].ca_i_pk_len;
299 	cred_i.ca_pk.ptr = (uint8_t *)test_vectors[vec_num_i].ca_i_pk;
300 
301 	struct cred_array cred_i_array = { .len = 1, .ptr = &cred_i };
302 	r = edhoc_responder_run(&c_r, &cred_i_array, &R_err_msg, &R_PRK_out,
303 				tx_responder, rx_responder, ead_process);
304 	if (r != ok) {
305 		goto end;
306 	}
307 
308 	PRINT_ARRAY("R_PRK_out", R_PRK_out.ptr, R_PRK_out.len);
309 
310 	r = prk_out2exporter(SHA_256, &R_PRK_out, &R_prk_exporter);
311 	if (r != ok) {
312 		goto end;
313 	}
314 	PRINT_ARRAY("R_prk_exporter", R_prk_exporter.ptr, R_prk_exporter.len);
315 
316 	r = edhoc_exporter(SHA_256, OSCORE_MASTER_SECRET, &R_prk_exporter,
317 			   &R_master_secret);
318 	if (r != ok) {
319 		goto end;
320 	}
321 	PRINT_ARRAY("OSCORE Master Secret", R_master_secret.ptr,
322 		    R_master_secret.len);
323 
324 	r = edhoc_exporter(SHA_256, OSCORE_MASTER_SALT, &R_prk_exporter,
325 			   &R_master_salt);
326 	if (r != ok) {
327 		goto end;
328 	}
329 	PRINT_ARRAY("OSCORE Master Salt", R_master_salt.ptr, R_master_salt.len);
330 
331 #ifdef REPORT_STACK_USAGE
332 	thread_analyzer_print();
333 #endif
334 
335 	return;
336 end:
337 	PRINTF("An error has occurred. Error code: %d\n", r);
338 }
339 
test_initiator_responder_interaction(int vec_num)340 int test_initiator_responder_interaction(int vec_num)
341 {
342 	PRINT_MSG("start initiator_responder_interaction\n");
343 
344 	/*initiator thread*/
345 	k_tid_t initiator_tid = k_thread_create(
346 		&thread_initiator_data, thread_initiator_stack_area,
347 		K_THREAD_STACK_SIZEOF(thread_initiator_stack_area),
348 		thread_initiator, (void *)&vec_num, NULL, NULL, PRIORITY, 0,
349 		K_NO_WAIT);
350 
351 	/*responder thread*/
352 	k_tid_t responder_tid = k_thread_create(
353 		&thread_responder_data, thread_responder_stack_area,
354 		K_THREAD_STACK_SIZEOF(thread_responder_stack_area),
355 		thread_responder, (void *)&vec_num, NULL, NULL, PRIORITY, 0,
356 		K_NO_WAIT);
357 
358 	k_thread_start(&thread_initiator_data);
359 	k_thread_start(&thread_responder_data);
360 
361 	if (0 != k_thread_join(&thread_initiator_data, K_FOREVER)) {
362 		PRINT_MSG("initiator thread stalled! Aborting.");
363 		k_thread_abort(initiator_tid);
364 	}
365 	if (0 != k_thread_join(&thread_responder_data, K_FOREVER)) {
366 		PRINT_MSG("responder thread stalled! Aborting.");
367 		k_thread_abort(responder_tid);
368 	}
369 
370 	PRINT_MSG("threads completed\n");
371 
372 	/* check if Initiator and Responder computed the same values */
373 
374 	zassert_mem_equal__(I_PRK_out.ptr, R_PRK_out.ptr, R_PRK_out.len,
375 			    "wrong prk_out");
376 
377 	zassert_mem_equal__(I_prk_exporter.ptr, R_prk_exporter.ptr,
378 			    R_prk_exporter.len, "wrong prk_exporter");
379 
380 	zassert_mem_equal__(I_master_secret.ptr, R_master_secret.ptr,
381 			    R_master_secret.len, "wrong master_secret");
382 
383 	zassert_mem_equal__(I_master_salt.ptr, R_master_salt.ptr,
384 			    R_master_salt.len, "wrong master_salt");
385 	return 0;
386 }
387 
t_initiator_responder_interaction1()388 void t_initiator_responder_interaction1()
389 {
390 	MEASURE_LATENCY(test_initiator_responder_interaction(1));
391 }
392 
t_initiator_responder_interaction2()393 void t_initiator_responder_interaction2()
394 {
395 	MEASURE_LATENCY(test_initiator_responder_interaction(2));
396 }