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